mem.isa (4675:598d4c33c38d) mem.isa (5222:bb733a878f85)
1// -*- mode:c++ -*-
2
1// -*- mode:c++ -*-
2
3// Copyright (c) 2006 The Regents of The University of Michigan
4// All rights reserved.
5//
6// Redistribution and use in source and binary forms, with or without
7// modification, are permitted provided that the following conditions are
8// met: redistributions of source code must retain the above copyright
9// notice, this list of conditions and the following disclaimer;
10// redistributions in binary form must reproduce the above copyright
11// notice, this list of conditions and the following disclaimer in the
12// documentation and/or other materials provided with the distribution;
13// neither the name of the copyright holders nor the names of its
14// contributors may be used to endorse or promote products derived from
15// this software without specific prior written permission.
16//
17// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28//
29// Authors: Steve Reinhardt
30// Korey Sewell
3// Copyright .AN) 2007 MIPS Technologies, Inc. All Rights Reserved
31
4
5// This software is part of the M5 simulator.
6
7// THIS IS A LEGAL AGREEMENT. BY DOWNLOADING, USING, COPYING, CREATING
8// DERIVATIVE WORKS, AND/OR DISTRIBUTING THIS SOFTWARE YOU ARE AGREEING
9// TO THESE TERMS AND CONDITIONS.
10
11// Permission is granted to use, copy, create derivative works and
12// distribute this software and such derivative works for any purpose,
13// so long as (1) the copyright notice above, this grant of permission,
14// and the disclaimer below appear in all copies and derivative works
15// made, (2) the copyright notice above is augmented as appropriate to
16// reflect the addition of any new copyrightable work in a derivative
17// work (e.g., Copyright .AN) <Publication Year> Copyright Owner), and (3)
18// the name of MIPS Technologies, Inc. ($B!H(BMIPS$B!I(B) is not used in any
19// advertising or publicity pertaining to the use or distribution of
20// this software without specific, written prior authorization.
21
22// THIS SOFTWARE IS PROVIDED $B!H(BAS IS.$B!I(B MIPS MAKES NO WARRANTIES AND
23// DISCLAIMS ALL WARRANTIES, WHETHER EXPRESS, STATUTORY, IMPLIED OR
24// OTHERWISE, INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
25// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND
26// NON-INFRINGEMENT OF THIRD PARTY RIGHTS, REGARDING THIS SOFTWARE.
27// IN NO EVENT SHALL MIPS BE LIABLE FOR ANY DAMAGES, INCLUDING DIRECT,
28// INDIRECT, INCIDENTAL, CONSEQUENTIAL, SPECIAL, OR PUNITIVE DAMAGES OF
29// ANY KIND OR NATURE, ARISING OUT OF OR IN CONNECTION WITH THIS AGREEMENT,
30// THIS SOFTWARE AND/OR THE USE OF THIS SOFTWARE, WHETHER SUCH LIABILITY
31// IS ASSERTED ON THE BASIS OF CONTRACT, TORT (INCLUDING NEGLIGENCE OR
32// STRICT LIABILITY), OR OTHERWISE, EVEN IF MIPS HAS BEEN WARNED OF THE
33// POSSIBILITY OF ANY SUCH LOSS OR DAMAGE IN ADVANCE.
34
35//Authors: Steve Reinhardt
36// Korey L. Sewell
37
32////////////////////////////////////////////////////////////////////
33//
34// Memory-format instructions
35//
36
37output header {{
38 /**
39 * Base class for general Mips memory-format instructions.

--- 72 unchanged lines hidden (view full) ---

112 }
113
114}};
115
116output exec {{
117 /** return data in cases where there the size of data is only
118 known in the packet
119 */
38////////////////////////////////////////////////////////////////////
39//
40// Memory-format instructions
41//
42
43output header {{
44 /**
45 * Base class for general Mips memory-format instructions.

--- 72 unchanged lines hidden (view full) ---

118 }
119
120}};
121
122output exec {{
123 /** return data in cases where there the size of data is only
124 known in the packet
125 */
120 uint64_t getStoreData(%(CPU_exec_context)s *xc, Packet *packet) {
126 uint64_t getMemData(%(CPU_exec_context)s *xc, Packet *packet) {
121 switch (packet->getSize())
122 {
127 switch (packet->getSize())
128 {
123 case 8:
129 case 1:
124 return packet->get<uint8_t>();
125
130 return packet->get<uint8_t>();
131
126 case 16:
132 case 2:
127 return packet->get<uint16_t>();
128
133 return packet->get<uint16_t>();
134
129 case 32:
135 case 4:
130 return packet->get<uint32_t>();
131
136 return packet->get<uint32_t>();
137
132 case 864:
138 case 8:
133 return packet->get<uint64_t>();
134
135 default:
136 std::cerr << "bad store data size = " << packet->getSize() << std::endl;
137
138 assert(0);
139 return 0;
140 }

--- 58 unchanged lines hidden (view full) ---

199def template CompleteAccDeclare {{
200 Fault completeAcc(Packet *, %(CPU_exec_context)s *, Trace::InstRecord *) const;
201}};
202
203def template MemAccSizeDeclare {{
204 int memAccSize(%(CPU_exec_context)s *xc);
205}};
206
139 return packet->get<uint64_t>();
140
141 default:
142 std::cerr << "bad store data size = " << packet->getSize() << std::endl;
143
144 assert(0);
145 return 0;
146 }

--- 58 unchanged lines hidden (view full) ---

205def template CompleteAccDeclare {{
206 Fault completeAcc(Packet *, %(CPU_exec_context)s *, Trace::InstRecord *) const;
207}};
208
209def template MemAccSizeDeclare {{
210 int memAccSize(%(CPU_exec_context)s *xc);
211}};
212
213
214def template MiscMemAccSize {{
215 int %(class_name)s::memAccSize(%(CPU_exec_context)s *xc)
216 {
217 panic("Misc instruction does not support split access method!");
218 return 0;
219 }
220}};
221
207def template EACompConstructor {{
208 /** TODO: change op_class to AddrGenOp or something (requires
209 * creating new member of OpClass enum in op_class.hh, updating
210 * config files, etc.). */
211 inline %(class_name)s::EAComp::EAComp(ExtMachInst machInst)
212 : %(base_class)s("%(mnemonic)s (EAComp)", machInst, IntAluOp)
213 {
214 %(constructor)s;

--- 23 unchanged lines hidden (view full) ---

238def template EACompExecute {{
239 Fault
240 %(class_name)s::EAComp::execute(%(CPU_exec_context)s *xc,
241 Trace::InstRecord *traceData) const
242 {
243 Addr EA;
244 Fault fault = NoFault;
245
222def template EACompConstructor {{
223 /** TODO: change op_class to AddrGenOp or something (requires
224 * creating new member of OpClass enum in op_class.hh, updating
225 * config files, etc.). */
226 inline %(class_name)s::EAComp::EAComp(ExtMachInst machInst)
227 : %(base_class)s("%(mnemonic)s (EAComp)", machInst, IntAluOp)
228 {
229 %(constructor)s;

--- 23 unchanged lines hidden (view full) ---

253def template EACompExecute {{
254 Fault
255 %(class_name)s::EAComp::execute(%(CPU_exec_context)s *xc,
256 Trace::InstRecord *traceData) const
257 {
258 Addr EA;
259 Fault fault = NoFault;
260
261 if (this->isFloating()) {
262 %(fp_enable_check)s;
263
264 if(fault != NoFault)
265 return fault;
266 }
267
268 %(op_decl)s;
269 %(op_rd)s;
270 %(ea_code)s;
271
272 // NOTE: Trace Data is written using execute or completeAcc templates
273 if (fault == NoFault) {
274 xc->setEA(EA);
275 }
276
277 return fault;
278 }
279}};
280
281def template LoadStoreFPEACompExecute {{
282 Fault
283 %(class_name)s::EAComp::execute(%(CPU_exec_context)s *xc,
284 Trace::InstRecord *traceData) const
285 {
286 Addr EA;
287 Fault fault = NoFault;
288
246 %(fp_enable_check)s;
289 %(fp_enable_check)s;
290 if(fault != NoFault)
291 return fault;
247 %(op_decl)s;
248 %(op_rd)s;
249 %(ea_code)s;
250
251 // NOTE: Trace Data is written using execute or completeAcc templates
252 if (fault == NoFault) {
253 xc->setEA(EA);
254 }
255
256 return fault;
257 }
258}};
259
292 %(op_decl)s;
293 %(op_rd)s;
294 %(ea_code)s;
295
296 // NOTE: Trace Data is written using execute or completeAcc templates
297 if (fault == NoFault) {
298 xc->setEA(EA);
299 }
300
301 return fault;
302 }
303}};
304
305
260def template LoadMemAccExecute {{
261 Fault
262 %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc,
263 Trace::InstRecord *traceData) const
264 {
265 Addr EA;
306def template LoadMemAccExecute {{
307 Fault
308 %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc,
309 Trace::InstRecord *traceData) const
310 {
311 Addr EA;
312
266 Fault fault = NoFault;
267
313 Fault fault = NoFault;
314
315 if (this->isFloating()) {
316 %(fp_enable_check)s;
317
318 if(fault != NoFault)
319 return fault;
320 }
321
268 %(op_decl)s;
269 %(op_rd)s;
270
271 EA = xc->getEA();
272
273 fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags);
274
275 %(memacc_code)s;

--- 7 unchanged lines hidden (view full) ---

283
284def template LoadExecute {{
285 Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
286 Trace::InstRecord *traceData) const
287 {
288 Addr EA;
289 Fault fault = NoFault;
290
322 %(op_decl)s;
323 %(op_rd)s;
324
325 EA = xc->getEA();
326
327 fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags);
328
329 %(memacc_code)s;

--- 7 unchanged lines hidden (view full) ---

337
338def template LoadExecute {{
339 Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
340 Trace::InstRecord *traceData) const
341 {
342 Addr EA;
343 Fault fault = NoFault;
344
291 %(fp_enable_check)s;
345 if (this->isFloating()) {
346 %(fp_enable_check)s;
347
348 if(fault != NoFault)
349 return fault;
350 }
351
292 %(op_decl)s;
293 %(op_rd)s;
294 %(ea_code)s;
295
296 if (fault == NoFault) {
297 fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags);
298 %(memacc_code)s;
299 }

--- 9 unchanged lines hidden (view full) ---

309
310def template LoadInitiateAcc {{
311 Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
312 Trace::InstRecord *traceData) const
313 {
314 Addr EA;
315 Fault fault = NoFault;
316
352 %(op_decl)s;
353 %(op_rd)s;
354 %(ea_code)s;
355
356 if (fault == NoFault) {
357 fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags);
358 %(memacc_code)s;
359 }

--- 9 unchanged lines hidden (view full) ---

369
370def template LoadInitiateAcc {{
371 Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
372 Trace::InstRecord *traceData) const
373 {
374 Addr EA;
375 Fault fault = NoFault;
376
317 %(fp_enable_check)s;
377 if (this->isFloating()) {
378 %(fp_enable_check)s;
379
380 if(fault != NoFault)
381 return fault;
382 }
383
318 %(op_src_decl)s;
319 %(op_rd)s;
320 %(ea_code)s;
321
322 if (fault == NoFault) {
323 fault = xc->read(EA, (uint%(mem_acc_size)d_t &)Mem, memAccessFlags);
324 }
325
326 return fault;
327 }
328}};
329
330def template LoadCompleteAcc {{
331 Fault %(class_name)s::completeAcc(Packet *pkt,
332 %(CPU_exec_context)s *xc,
333 Trace::InstRecord *traceData) const
334 {
335 Fault fault = NoFault;
336
384 %(op_src_decl)s;
385 %(op_rd)s;
386 %(ea_code)s;
387
388 if (fault == NoFault) {
389 fault = xc->read(EA, (uint%(mem_acc_size)d_t &)Mem, memAccessFlags);
390 }
391
392 return fault;
393 }
394}};
395
396def template LoadCompleteAcc {{
397 Fault %(class_name)s::completeAcc(Packet *pkt,
398 %(CPU_exec_context)s *xc,
399 Trace::InstRecord *traceData) const
400 {
401 Fault fault = NoFault;
402
337 %(fp_enable_check)s;
403 if (this->isFloating()) {
404 %(fp_enable_check)s;
405
406 if(fault != NoFault)
407 return fault;
408 }
409
338 %(op_decl)s;
339 %(op_rd)s;
340
341 Mem = pkt->get<typeof(Mem)>();
342
343 if (fault == NoFault) {
344 %(memacc_code)s;
345 }
346
347 if (fault == NoFault) {
348 %(op_wb)s;
349 }
350
351 return fault;
352 }
353}};
354
355
410 %(op_decl)s;
411 %(op_rd)s;
412
413 Mem = pkt->get<typeof(Mem)>();
414
415 if (fault == NoFault) {
416 %(memacc_code)s;
417 }
418
419 if (fault == NoFault) {
420 %(op_wb)s;
421 }
422
423 return fault;
424 }
425}};
426
427
356
357def template LoadStoreMemAccSize {{
358 int %(class_name)s::memAccSize(%(CPU_exec_context)s *xc)
359 {
360 // Return the memory access size in bytes
361 return (%(mem_acc_size)d / 8);
362 }
363}};
364

--- 91 unchanged lines hidden (view full) ---

456 if (fault == NoFault) {
457 %(op_wb)s;
458 }
459
460 return fault;
461 }
462}};
463
428def template LoadStoreMemAccSize {{
429 int %(class_name)s::memAccSize(%(CPU_exec_context)s *xc)
430 {
431 // Return the memory access size in bytes
432 return (%(mem_acc_size)d / 8);
433 }
434}};
435

--- 91 unchanged lines hidden (view full) ---

527 if (fault == NoFault) {
528 %(op_wb)s;
529 }
530
531 return fault;
532 }
533}};
534
535
536def template StoreFPExecute {{
537 Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
538 Trace::InstRecord *traceData) const
539 {
540 Addr EA;
541 Fault fault = NoFault;
542
543 %(fp_enable_check)s;
544 if(fault != NoFault)
545 return fault;
546 %(op_decl)s;
547 %(op_rd)s;
548 %(ea_code)s;
549
550 if (fault == NoFault) {
551 %(memacc_code)s;
552 }
553
554 if (fault == NoFault) {
555 fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
556 memAccessFlags, NULL);
557 if (traceData) { traceData->setData(Mem); }
558 }
559
560 if (fault == NoFault) {
561 %(postacc_code)s;
562 }
563
564 if (fault == NoFault) {
565 %(op_wb)s;
566 }
567
568 return fault;
569 }
570}};
571
464def template StoreCondExecute {{
465 Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
466 Trace::InstRecord *traceData) const
467 {
468 Addr EA;
469 Fault fault = NoFault;
470 uint64_t write_result = 0;
471

--- 63 unchanged lines hidden (view full) ---

535
536 if (fault == NoFault) {
537 %(postacc_code)s;
538 }
539
540 if (fault == NoFault) {
541 %(op_wb)s;
542
572def template StoreCondExecute {{
573 Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
574 Trace::InstRecord *traceData) const
575 {
576 Addr EA;
577 Fault fault = NoFault;
578 uint64_t write_result = 0;
579

--- 63 unchanged lines hidden (view full) ---

643
644 if (fault == NoFault) {
645 %(postacc_code)s;
646 }
647
648 if (fault == NoFault) {
649 %(op_wb)s;
650
543 if (traceData) { traceData->setData(getStoreData(xc, pkt)); }
651 if (traceData) { traceData->setData(getMemData(xc, pkt)); }
544 }
545
546 return fault;
547 }
548}};
549
652 }
653
654 return fault;
655 }
656}};
657
658
659def template StoreCompleteAcc {{
660 Fault %(class_name)s::completeAcc(Packet *pkt,
661 %(CPU_exec_context)s *xc,
662 Trace::InstRecord *traceData) const
663 {
664 Fault fault = NoFault;
665
666 %(op_dest_decl)s;
667
668 if (fault == NoFault) {
669 %(postacc_code)s;
670 }
671
672 if (fault == NoFault) {
673 %(op_wb)s;
674
675 if (traceData) { traceData->setData(getMemData(xc, pkt)); }
676 }
677
678 return fault;
679 }
680}};
681
550def template StoreCondCompleteAcc {{
551 Fault %(class_name)s::completeAcc(Packet *pkt,
552 %(CPU_exec_context)s *xc,
553 Trace::InstRecord *traceData) const
554 {
555 Fault fault = NoFault;
556
557 %(fp_enable_check)s;

--- 87 unchanged lines hidden (view full) ---

645def format LoadMemory(memacc_code, ea_code = {{ EA = Rs + disp; }},
646 mem_flags = [], inst_flags = []) {{
647 (header_output, decoder_output, decode_block, exec_output) = \
648 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
649 decode_template = ImmNopCheckDecode,
650 exec_template_base = 'Load')
651}};
652
682def template StoreCondCompleteAcc {{
683 Fault %(class_name)s::completeAcc(Packet *pkt,
684 %(CPU_exec_context)s *xc,
685 Trace::InstRecord *traceData) const
686 {
687 Fault fault = NoFault;
688
689 %(fp_enable_check)s;

--- 87 unchanged lines hidden (view full) ---

777def format LoadMemory(memacc_code, ea_code = {{ EA = Rs + disp; }},
778 mem_flags = [], inst_flags = []) {{
779 (header_output, decoder_output, decode_block, exec_output) = \
780 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
781 decode_template = ImmNopCheckDecode,
782 exec_template_base = 'Load')
783}};
784
785
653def format StoreMemory(memacc_code, ea_code = {{ EA = Rs + disp; }},
654 mem_flags = [], inst_flags = []) {{
655 (header_output, decoder_output, decode_block, exec_output) = \
656 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
657 exec_template_base = 'Store')
658}};
659
660def format LoadIndexedMemory(memacc_code, ea_code = {{ EA = Rs + Rt; }},
661 mem_flags = [], inst_flags = []) {{
786def format StoreMemory(memacc_code, ea_code = {{ EA = Rs + disp; }},
787 mem_flags = [], inst_flags = []) {{
788 (header_output, decoder_output, decode_block, exec_output) = \
789 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
790 exec_template_base = 'Store')
791}};
792
793def format LoadIndexedMemory(memacc_code, ea_code = {{ EA = Rs + Rt; }},
794 mem_flags = [], inst_flags = []) {{
795 inst_flags += ['IsIndexed']
662 (header_output, decoder_output, decode_block, exec_output) = \
663 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
664 decode_template = ImmNopCheckDecode,
665 exec_template_base = 'Load')
666}};
667
668def format StoreIndexedMemory(memacc_code, ea_code = {{ EA = Rs + Rt; }},
669 mem_flags = [], inst_flags = []) {{
796 (header_output, decoder_output, decode_block, exec_output) = \
797 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
798 decode_template = ImmNopCheckDecode,
799 exec_template_base = 'Load')
800}};
801
802def format StoreIndexedMemory(memacc_code, ea_code = {{ EA = Rs + Rt; }},
803 mem_flags = [], inst_flags = []) {{
804 inst_flags += ['IsIndexed']
670 (header_output, decoder_output, decode_block, exec_output) = \
671 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
672 exec_template_base = 'Store')
673}};
674
805 (header_output, decoder_output, decode_block, exec_output) = \
806 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
807 exec_template_base = 'Store')
808}};
809
810def format LoadFPIndexedMemory(memacc_code, ea_code = {{ EA = Rs + Rt; }},
811 mem_flags = [], inst_flags = []) {{
812 inst_flags += ['IsIndexed', 'IsFloating']
813 (header_output, decoder_output, decode_block, exec_output) = \
814 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
815 decode_template = ImmNopCheckDecode,
816 exec_template_base = 'Load')
817}};
818
819def format StoreFPIndexedMemory(memacc_code, ea_code = {{ EA = Rs + Rt; }},
820 mem_flags = [], inst_flags = []) {{
821 inst_flags += ['IsIndexed', 'IsFloating']
822 (header_output, decoder_output, decode_block, exec_output) = \
823 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
824 exec_template_base = 'Store')
825}};
826
827
675def format LoadUnalignedMemory(memacc_code, ea_code = {{ EA = (Rs + disp) & ~3; }},
676 mem_flags = [], inst_flags = []) {{
677 decl_code = 'uint32_t mem_word = Mem.uw;\n'
678 decl_code += 'uint32_t unalign_addr = Rs + disp;\n'
679 decl_code += 'uint32_t byte_offset = unalign_addr & 3;\n'
680 decl_code += '#if BYTE_ORDER == BIG_ENDIAN\n'
681 decl_code += '\tbyte_offset ^= 3;\n'
682 decl_code += '#endif\n'

--- 46 unchanged lines hidden ---
828def format LoadUnalignedMemory(memacc_code, ea_code = {{ EA = (Rs + disp) & ~3; }},
829 mem_flags = [], inst_flags = []) {{
830 decl_code = 'uint32_t mem_word = Mem.uw;\n'
831 decl_code += 'uint32_t unalign_addr = Rs + disp;\n'
832 decl_code += 'uint32_t byte_offset = unalign_addr & 3;\n'
833 decl_code += '#if BYTE_ORDER == BIG_ENDIAN\n'
834 decl_code += '\tbyte_offset ^= 3;\n'
835 decl_code += '#endif\n'

--- 46 unchanged lines hidden ---