mem.isa revision 5222
1// -*- mode:c++ -*- 2 3// Copyright .AN) 2007 MIPS Technologies, Inc. All Rights Reserved 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 38//////////////////////////////////////////////////////////////////// 39// 40// Memory-format instructions 41// 42 43output header {{ 44 /** 45 * Base class for general Mips memory-format instructions. 46 */ 47 class Memory : public MipsStaticInst 48 { 49 protected: 50 51 /// Memory request flags. See mem_req_base.hh. 52 unsigned memAccessFlags; 53 /// Pointer to EAComp object. 54 const StaticInstPtr eaCompPtr; 55 /// Pointer to MemAcc object. 56 const StaticInstPtr memAccPtr; 57 58 /// Displacement for EA calculation (signed). 59 int32_t disp; 60 61 /// Constructor 62 Memory(const char *mnem, MachInst _machInst, OpClass __opClass, 63 StaticInstPtr _eaCompPtr = nullStaticInstPtr, 64 StaticInstPtr _memAccPtr = nullStaticInstPtr) 65 : MipsStaticInst(mnem, _machInst, __opClass), 66 memAccessFlags(0), eaCompPtr(_eaCompPtr), memAccPtr(_memAccPtr), 67 disp(sext<16>(OFFSET)) 68 { 69 } 70 71 std::string 72 generateDisassembly(Addr pc, const SymbolTable *symtab) const; 73 74 public: 75 76 const StaticInstPtr &eaCompInst() const { return eaCompPtr; } 77 const StaticInstPtr &memAccInst() const { return memAccPtr; } 78 79 unsigned memAccFlags() { return memAccessFlags; } 80 }; 81 82 /** 83 * Base class for a few miscellaneous memory-format insts 84 * that don't interpret the disp field 85 */ 86 class MemoryNoDisp : public Memory 87 { 88 protected: 89 /// Constructor 90 MemoryNoDisp(const char *mnem, ExtMachInst _machInst, OpClass __opClass, 91 StaticInstPtr _eaCompPtr = nullStaticInstPtr, 92 StaticInstPtr _memAccPtr = nullStaticInstPtr) 93 : Memory(mnem, _machInst, __opClass, _eaCompPtr, _memAccPtr) 94 { 95 } 96 97 std::string 98 generateDisassembly(Addr pc, const SymbolTable *symtab) const; 99 }; 100}}; 101 102 103output decoder {{ 104 std::string 105 Memory::generateDisassembly(Addr pc, const SymbolTable *symtab) const 106 { 107 return csprintf("%-10s %c%d, %d(r%d)", mnemonic, 108 flags[IsFloating] ? 'f' : 'r', RT, disp, RS); 109 } 110 111 std::string 112 MemoryNoDisp::generateDisassembly(Addr pc, const SymbolTable *symtab) const 113 { 114 return csprintf("%-10s %c%d, r%d(r%d)", mnemonic, 115 flags[IsFloating] ? 'f' : 'r', 116 flags[IsFloating] ? FD : RD, 117 RS, RT); 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 */ 126 uint64_t getMemData(%(CPU_exec_context)s *xc, Packet *packet) { 127 switch (packet->getSize()) 128 { 129 case 1: 130 return packet->get<uint8_t>(); 131 132 case 2: 133 return packet->get<uint16_t>(); 134 135 case 4: 136 return packet->get<uint32_t>(); 137 138 case 8: 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 } 147 } 148 149 150}}; 151 152def template LoadStoreDeclare {{ 153 /** 154 * Static instruction class for "%(mnemonic)s". 155 */ 156 class %(class_name)s : public %(base_class)s 157 { 158 protected: 159 160 /** 161 * "Fake" effective address computation class for "%(mnemonic)s". 162 */ 163 class EAComp : public %(base_class)s 164 { 165 public: 166 /// Constructor 167 EAComp(ExtMachInst machInst); 168 169 %(BasicExecDeclare)s 170 }; 171 172 /** 173 * "Fake" memory access instruction class for "%(mnemonic)s". 174 */ 175 class MemAcc : public %(base_class)s 176 { 177 public: 178 /// Constructor 179 MemAcc(ExtMachInst machInst); 180 181 %(BasicExecDeclare)s 182 }; 183 184 public: 185 186 /// Constructor. 187 %(class_name)s(ExtMachInst machInst); 188 189 %(BasicExecDeclare)s 190 191 %(InitiateAccDeclare)s 192 193 %(CompleteAccDeclare)s 194 195 %(MemAccSizeDeclare)s 196 }; 197}}; 198 199 200def template InitiateAccDeclare {{ 201 Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const; 202}}; 203 204 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 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; 230 } 231}}; 232 233 234def template MemAccConstructor {{ 235 inline %(class_name)s::MemAcc::MemAcc(ExtMachInst machInst) 236 : %(base_class)s("%(mnemonic)s (MemAcc)", machInst, %(op_class)s) 237 { 238 %(constructor)s; 239 } 240}}; 241 242 243def template LoadStoreConstructor {{ 244 inline %(class_name)s::%(class_name)s(ExtMachInst machInst) 245 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, 246 new EAComp(machInst), new MemAcc(machInst)) 247 { 248 %(constructor)s; 249 } 250}}; 251 252 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 289 %(fp_enable_check)s; 290 if(fault != NoFault) 291 return fault; 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 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 313 Fault fault = NoFault; 314 315 if (this->isFloating()) { 316 %(fp_enable_check)s; 317 318 if(fault != NoFault) 319 return fault; 320 } 321 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; 330 331 // NOTE: Write back data using execute or completeAcc templates 332 333 return fault; 334 } 335}}; 336 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 345 if (this->isFloating()) { 346 %(fp_enable_check)s; 347 348 if(fault != NoFault) 349 return fault; 350 } 351 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 } 360 361 if (fault == NoFault) { 362 %(op_wb)s; 363 } 364 365 return fault; 366 } 367}}; 368 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 377 if (this->isFloating()) { 378 %(fp_enable_check)s; 379 380 if(fault != NoFault) 381 return fault; 382 } 383 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 403 if (this->isFloating()) { 404 %(fp_enable_check)s; 405 406 if(fault != NoFault) 407 return fault; 408 } 409 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 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 436def template StoreMemAccExecute {{ 437 Fault 438 %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc, 439 Trace::InstRecord *traceData) const 440 { 441 Addr EA; 442 Fault fault = NoFault; 443 444 %(fp_enable_check)s; 445 %(op_decl)s; 446 %(op_rd)s; 447 448 EA = xc->getEA(); 449 450 if (fault == NoFault) { 451 %(memacc_code)s; 452 } 453 454 if (fault == NoFault) { 455 fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA, 456 memAccessFlags, NULL); 457 // @NOTE: Need to Call Complete Access to Set Trace Data 458 //if (traceData) { traceData->setData(Mem); } 459 } 460 461 return fault; 462 } 463}}; 464 465def template StoreCondMemAccExecute {{ 466 Fault 467 %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc, 468 Trace::InstRecord *traceData) const 469 { 470 Addr EA; 471 Fault fault = NoFault; 472 uint64_t write_result = 0; 473 474 %(fp_enable_check)s; 475 %(op_decl)s; 476 %(op_rd)s; 477 EA = xc->getEA(); 478 479 if (fault == NoFault) { 480 %(memacc_code)s; 481 } 482 483 if (fault == NoFault) { 484 fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA, 485 memAccessFlags, &write_result); 486 if (traceData) { traceData->setData(Mem); } 487 } 488 489 if (fault == NoFault) { 490 %(postacc_code)s; 491 } 492 493 if (fault == NoFault) { 494 %(op_wb)s; 495 } 496 497 return fault; 498 } 499}}; 500 501def template StoreExecute {{ 502 Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, 503 Trace::InstRecord *traceData) const 504 { 505 Addr EA; 506 Fault fault = NoFault; 507 508 %(fp_enable_check)s; 509 %(op_decl)s; 510 %(op_rd)s; 511 %(ea_code)s; 512 513 if (fault == NoFault) { 514 %(memacc_code)s; 515 } 516 517 if (fault == NoFault) { 518 fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA, 519 memAccessFlags, NULL); 520 if (traceData) { traceData->setData(Mem); } 521 } 522 523 if (fault == NoFault) { 524 %(postacc_code)s; 525 } 526 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 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 580 %(fp_enable_check)s; 581 %(op_decl)s; 582 %(op_rd)s; 583 %(ea_code)s; 584 585 if (fault == NoFault) { 586 %(memacc_code)s; 587 } 588 589 if (fault == NoFault) { 590 fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA, 591 memAccessFlags, &write_result); 592 if (traceData) { traceData->setData(Mem); } 593 } 594 595 if (fault == NoFault) { 596 %(postacc_code)s; 597 } 598 599 if (fault == NoFault) { 600 %(op_wb)s; 601 } 602 603 return fault; 604 } 605}}; 606 607def template StoreInitiateAcc {{ 608 Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc, 609 Trace::InstRecord *traceData) const 610 { 611 Addr EA; 612 Fault fault = NoFault; 613 614 %(fp_enable_check)s; 615 %(op_decl)s; 616 %(op_rd)s; 617 %(ea_code)s; 618 619 if (fault == NoFault) { 620 %(memacc_code)s; 621 } 622 623 if (fault == NoFault) { 624 fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA, 625 memAccessFlags, NULL); 626 if (traceData) { traceData->setData(Mem); } 627 } 628 629 return fault; 630 } 631}}; 632 633 634def template StoreCompleteAcc {{ 635 Fault %(class_name)s::completeAcc(Packet *pkt, 636 %(CPU_exec_context)s *xc, 637 Trace::InstRecord *traceData) const 638 { 639 Fault fault = NoFault; 640 641 %(fp_enable_check)s; 642 %(op_dest_decl)s; 643 644 if (fault == NoFault) { 645 %(postacc_code)s; 646 } 647 648 if (fault == NoFault) { 649 %(op_wb)s; 650 651 if (traceData) { traceData->setData(getMemData(xc, pkt)); } 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 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; 690 %(op_dest_decl)s; 691 692 uint64_t write_result = pkt->req->getExtraData(); 693 694 if (fault == NoFault) { 695 %(postacc_code)s; 696 } 697 698 if (fault == NoFault) { 699 %(op_wb)s; 700 } 701 702 return fault; 703 } 704}}; 705 706 707def template MiscMemAccExecute {{ 708 Fault %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc, 709 Trace::InstRecord *traceData) const 710 { 711 Addr EA; 712 Fault fault = NoFault; 713 714 %(fp_enable_check)s; 715 %(op_decl)s; 716 %(op_rd)s; 717 EA = xc->getEA(); 718 719 if (fault == NoFault) { 720 %(memacc_code)s; 721 } 722 723 return NoFault; 724 } 725}}; 726 727def template MiscExecute {{ 728 Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, 729 Trace::InstRecord *traceData) const 730 { 731 Addr EA; 732 Fault fault = NoFault; 733 734 %(fp_enable_check)s; 735 %(op_decl)s; 736 %(op_rd)s; 737 %(ea_code)s; 738 739 if (fault == NoFault) { 740 %(memacc_code)s; 741 } 742 743 return NoFault; 744 } 745}}; 746 747def template MiscInitiateAcc {{ 748 Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc, 749 Trace::InstRecord *traceData) const 750 { 751 panic("Misc instruction does not support split access method!"); 752 return NoFault; 753 } 754}}; 755 756 757def template MiscCompleteAcc {{ 758 Fault %(class_name)s::completeAcc(Packet *pkt, 759 %(CPU_exec_context)s *xc, 760 Trace::InstRecord *traceData) const 761 { 762 panic("Misc instruction does not support split access method!"); 763 764 return NoFault; 765 } 766}}; 767 768 769def template MiscMemAccSize {{ 770 int %(class_name)s::memAccSize(%(CPU_exec_context)s *xc) 771 { 772 panic("Misc instruction does not support split access method!"); 773 return 0; 774 } 775}}; 776 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 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'] 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'] 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 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' 836 837 memacc_code = decl_code + memacc_code 838 839 (header_output, decoder_output, decode_block, exec_output) = \ 840 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 841 decode_template = ImmNopCheckDecode, 842 exec_template_base = 'Load') 843}}; 844 845def format StoreUnalignedMemory(memacc_code, ea_code = {{ EA = (Rs + disp) & ~3; }}, 846 mem_flags = [], inst_flags = []) {{ 847 decl_code = 'uint32_t mem_word = 0;\n' 848 decl_code += 'uint32_t unaligned_addr = Rs + disp;\n' 849 decl_code += 'uint32_t byte_offset = unaligned_addr & 3;\n' 850 decl_code += '#if BYTE_ORDER == BIG_ENDIAN\n' 851 decl_code += '\tbyte_offset ^= 3;\n' 852 decl_code += '#endif\n' 853 decl_code += 'fault = xc->read(EA, (uint32_t&)mem_word, memAccessFlags);\n' 854 #decl_code += 'xc->readFunctional(EA,(uint32_t&)mem_word);' 855 memacc_code = decl_code + memacc_code + '\nMem = mem_word;\n' 856 857 (header_output, decoder_output, decode_block, exec_output) = \ 858 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 859 exec_template_base = 'Store') 860}}; 861 862def format Prefetch(ea_code = {{ EA = Rs + disp; }}, 863 mem_flags = [], pf_flags = [], inst_flags = []) {{ 864 pf_mem_flags = mem_flags + pf_flags + ['NO_FAULT'] 865 pf_inst_flags = inst_flags + ['IsMemRef', 'IsLoad', 866 'IsDataPrefetch', 'MemReadOp'] 867 868 (header_output, decoder_output, decode_block, exec_output) = \ 869 LoadStoreBase(name, Name, ea_code, 870 'xc->prefetch(EA, memAccessFlags);', 871 pf_mem_flags, pf_inst_flags, exec_template_base = 'Misc') 872 873}}; 874 875def format StoreCond(memacc_code, postacc_code, 876 ea_code = {{ EA = Rs + disp; }}, 877 mem_flags = [], inst_flags = []) {{ 878 (header_output, decoder_output, decode_block, exec_output) = \ 879 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 880 postacc_code, exec_template_base = 'StoreCond') 881}}; 882