mem.isa revision 9573
1// -*- mode:c++ -*- 2 3// Copyright (c) 2010 ARM Limited 4// All rights reserved 5// 6// The license below extends only to copyright in the software and shall 7// not be construed as granting a license to any other intellectual 8// property including but not limited to intellectual property relating 9// to a hardware implementation of the functionality of the software 10// licensed hereunder. You may use the software subject to the license 11// terms below provided that you ensure that this notice is replicated 12// unmodified and in its entirety in all distributions of the software, 13// modified or unmodified, in source code or in binary form. 14// 15// Copyright (c) 2007-2008 The Florida State University 16// All rights reserved. 17// 18// Redistribution and use in source and binary forms, with or without 19// modification, are permitted provided that the following conditions are 20// met: redistributions of source code must retain the above copyright 21// notice, this list of conditions and the following disclaimer; 22// redistributions in binary form must reproduce the above copyright 23// notice, this list of conditions and the following disclaimer in the 24// documentation and/or other materials provided with the distribution; 25// neither the name of the copyright holders nor the names of its 26// contributors may be used to endorse or promote products derived from 27// this software without specific prior written permission. 28// 29// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 30// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 31// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 32// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 33// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 34// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 35// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 36// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 37// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 38// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 39// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 40// 41// Authors: Stephen Hines 42 43 44def template PanicExecute {{ 45 Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, 46 Trace::InstRecord *traceData) const 47 { 48 panic("Execute function executed when it shouldn't be!\n"); 49 return NoFault; 50 } 51}}; 52 53def template PanicInitiateAcc {{ 54 Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc, 55 Trace::InstRecord *traceData) const 56 { 57 panic("InitiateAcc function executed when it shouldn't be!\n"); 58 return NoFault; 59 } 60}}; 61 62def template PanicCompleteAcc {{ 63 Fault %(class_name)s::completeAcc(PacketPtr pkt, 64 %(CPU_exec_context)s *xc, 65 Trace::InstRecord *traceData) const 66 { 67 panic("CompleteAcc function executed when it shouldn't be!\n"); 68 return NoFault; 69 } 70}}; 71 72 73def template SwapExecute {{ 74 Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, 75 Trace::InstRecord *traceData) const 76 { 77 Addr EA; 78 Fault fault = NoFault; 79 80 %(op_decl)s; 81 uint64_t memData = 0; 82 %(op_rd)s; 83 %(ea_code)s; 84 85 if (%(predicate_test)s) 86 { 87 %(preacc_code)s; 88 89 if (fault == NoFault) { 90 fault = writeMemAtomic(xc, traceData, Mem, EA, memAccessFlags, 91 &memData); 92 } 93 94 if (fault == NoFault) { 95 %(postacc_code)s; 96 } 97 98 if (fault == NoFault) { 99 %(op_wb)s; 100 } 101 } else { 102 xc->setPredicate(false); 103 } 104 105 return fault; 106 } 107}}; 108 109def template SwapInitiateAcc {{ 110 Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc, 111 Trace::InstRecord *traceData) const 112 { 113 Addr EA; 114 Fault fault = NoFault; 115 116 %(op_decl)s; 117 uint64_t memData = 0; 118 %(op_rd)s; 119 %(ea_code)s; 120 121 if (%(predicate_test)s) 122 { 123 %(preacc_code)s; 124 125 if (fault == NoFault) { 126 fault = writeMemTiming(xc, traceData, Mem, EA, memAccessFlags, 127 &memData); 128 } 129 } else { 130 xc->setPredicate(false); 131 } 132 133 return fault; 134 } 135}}; 136 137def template SwapCompleteAcc {{ 138 Fault %(class_name)s::completeAcc(PacketPtr pkt, 139 %(CPU_exec_context)s *xc, 140 Trace::InstRecord *traceData) const 141 { 142 Fault fault = NoFault; 143 144 %(op_decl)s; 145 %(op_rd)s; 146 147 if (%(predicate_test)s) 148 { 149 // ARM instructions will not have a pkt if the predicate is false 150 getMem(pkt, Mem, traceData); 151 uint64_t memData = Mem; 152 153 %(postacc_code)s; 154 155 if (fault == NoFault) { 156 %(op_wb)s; 157 } 158 } 159 160 return fault; 161 } 162}}; 163 164def template LoadExecute {{ 165 Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, 166 Trace::InstRecord *traceData) const 167 { 168 Addr EA; 169 Fault fault = NoFault; 170 171 %(op_decl)s; 172 %(op_rd)s; 173 %(ea_code)s; 174 175 if (%(predicate_test)s) 176 { 177 if (fault == NoFault) { 178 fault = readMemAtomic(xc, traceData, EA, Mem, memAccessFlags); 179 %(memacc_code)s; 180 } 181 182 if (fault == NoFault) { 183 %(op_wb)s; 184 } 185 } else { 186 xc->setPredicate(false); 187 } 188 189 return fault; 190 } 191}}; 192 193def template NeonLoadExecute {{ 194 template <class Element> 195 Fault %(class_name)s<Element>::execute( 196 %(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const 197 { 198 Addr EA; 199 Fault fault = NoFault; 200 201 %(op_decl)s; 202 %(mem_decl)s; 203 %(op_rd)s; 204 %(ea_code)s; 205 206 MemUnion memUnion; 207 uint8_t *dataPtr = memUnion.bytes; 208 209 if (%(predicate_test)s) 210 { 211 if (fault == NoFault) { 212 fault = xc->readMem(EA, dataPtr, %(size)d, memAccessFlags); 213 %(memacc_code)s; 214 } 215 216 if (fault == NoFault) { 217 %(op_wb)s; 218 } 219 } else { 220 xc->setPredicate(false); 221 } 222 223 return fault; 224 } 225}}; 226 227def template StoreExecute {{ 228 Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, 229 Trace::InstRecord *traceData) const 230 { 231 Addr EA; 232 Fault fault = NoFault; 233 234 %(op_decl)s; 235 %(op_rd)s; 236 %(ea_code)s; 237 238 if (%(predicate_test)s) 239 { 240 if (fault == NoFault) { 241 %(memacc_code)s; 242 } 243 244 if (fault == NoFault) { 245 fault = writeMemAtomic(xc, traceData, Mem, EA, 246 memAccessFlags, NULL); 247 } 248 249 if (fault == NoFault) { 250 %(op_wb)s; 251 } 252 } else { 253 xc->setPredicate(false); 254 } 255 256 return fault; 257 } 258}}; 259 260def template NeonStoreExecute {{ 261 template <class Element> 262 Fault %(class_name)s<Element>::execute( 263 %(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const 264 { 265 Addr EA; 266 Fault fault = NoFault; 267 268 %(op_decl)s; 269 %(mem_decl)s; 270 %(op_rd)s; 271 %(ea_code)s; 272 273 MemUnion memUnion; 274 uint8_t *dataPtr = memUnion.bytes; 275 276 if (%(predicate_test)s) 277 { 278 if (fault == NoFault) { 279 %(memacc_code)s; 280 } 281 282 if (fault == NoFault) { 283 fault = xc->writeMem(dataPtr, %(size)d, EA, 284 memAccessFlags, NULL); 285 } 286 287 if (fault == NoFault) { 288 %(op_wb)s; 289 } 290 } else { 291 xc->setPredicate(false); 292 } 293 294 return fault; 295 } 296}}; 297 298def template StoreExExecute {{ 299 Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, 300 Trace::InstRecord *traceData) const 301 { 302 Addr EA; 303 Fault fault = NoFault; 304 305 %(op_decl)s; 306 %(op_rd)s; 307 %(ea_code)s; 308 309 if (%(predicate_test)s) 310 { 311 if (fault == NoFault) { 312 %(memacc_code)s; 313 } 314 315 uint64_t writeResult; 316 317 if (fault == NoFault) { 318 fault = writeMemAtomic(xc, traceData, Mem, EA, memAccessFlags, 319 &writeResult); 320 } 321 322 if (fault == NoFault) { 323 %(postacc_code)s; 324 } 325 326 if (fault == NoFault) { 327 %(op_wb)s; 328 } 329 } else { 330 xc->setPredicate(false); 331 } 332 333 return fault; 334 } 335}}; 336 337def template StoreExInitiateAcc {{ 338 Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc, 339 Trace::InstRecord *traceData) const 340 { 341 Addr EA; 342 Fault fault = NoFault; 343 344 %(op_decl)s; 345 %(op_rd)s; 346 %(ea_code)s; 347 348 if (%(predicate_test)s) 349 { 350 if (fault == NoFault) { 351 %(memacc_code)s; 352 } 353 354 if (fault == NoFault) { 355 fault = writeMemTiming(xc, traceData, Mem, EA, memAccessFlags, 356 NULL); 357 } 358 } else { 359 xc->setPredicate(false); 360 } 361 362 return fault; 363 } 364}}; 365 366def template StoreInitiateAcc {{ 367 Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc, 368 Trace::InstRecord *traceData) const 369 { 370 Addr EA; 371 Fault fault = NoFault; 372 373 %(op_decl)s; 374 %(op_rd)s; 375 %(ea_code)s; 376 377 if (%(predicate_test)s) 378 { 379 if (fault == NoFault) { 380 %(memacc_code)s; 381 } 382 383 if (fault == NoFault) { 384 fault = writeMemTiming(xc, traceData, Mem, EA, memAccessFlags, 385 NULL); 386 } 387 } else { 388 xc->setPredicate(false); 389 } 390 391 return fault; 392 } 393}}; 394 395def template NeonStoreInitiateAcc {{ 396 template <class Element> 397 Fault %(class_name)s<Element>::initiateAcc( 398 %(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const 399 { 400 Addr EA; 401 Fault fault = NoFault; 402 403 %(op_decl)s; 404 %(mem_decl)s; 405 %(op_rd)s; 406 %(ea_code)s; 407 408 if (%(predicate_test)s) 409 { 410 MemUnion memUnion; 411 if (fault == NoFault) { 412 %(memacc_code)s; 413 } 414 415 if (fault == NoFault) { 416 fault = xc->writeMem(memUnion.bytes, %(size)d, EA, 417 memAccessFlags, NULL); 418 } 419 } else { 420 xc->setPredicate(false); 421 } 422 423 return fault; 424 } 425}}; 426 427def template LoadInitiateAcc {{ 428 Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc, 429 Trace::InstRecord *traceData) const 430 { 431 Addr EA; 432 Fault fault = NoFault; 433 434 %(op_src_decl)s; 435 %(op_rd)s; 436 %(ea_code)s; 437 438 if (%(predicate_test)s) 439 { 440 if (fault == NoFault) { 441 fault = readMemTiming(xc, traceData, EA, Mem, memAccessFlags); 442 } 443 } else { 444 xc->setPredicate(false); 445 } 446 447 return fault; 448 } 449}}; 450 451def template NeonLoadInitiateAcc {{ 452 template <class Element> 453 Fault %(class_name)s<Element>::initiateAcc( 454 %(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const 455 { 456 Addr EA; 457 Fault fault = NoFault; 458 459 %(op_decl)s; 460 %(mem_decl)s; 461 %(op_rd)s; 462 %(ea_code)s; 463 464 MemUnion memUnion; 465 uint8_t *dataPtr = memUnion.bytes; 466 467 if (%(predicate_test)s) 468 { 469 if (fault == NoFault) { 470 fault = xc->readMem(EA, dataPtr, %(size)d, memAccessFlags); 471 } 472 } else { 473 xc->setPredicate(false); 474 } 475 476 return fault; 477 } 478}}; 479 480def template LoadCompleteAcc {{ 481 Fault %(class_name)s::completeAcc(PacketPtr pkt, 482 %(CPU_exec_context)s *xc, 483 Trace::InstRecord *traceData) const 484 { 485 Fault fault = NoFault; 486 487 %(op_decl)s; 488 %(op_rd)s; 489 490 if (%(predicate_test)s) 491 { 492 // ARM instructions will not have a pkt if the predicate is false 493 getMem(pkt, Mem, traceData); 494 495 if (fault == NoFault) { 496 %(memacc_code)s; 497 } 498 499 if (fault == NoFault) { 500 %(op_wb)s; 501 } 502 } 503 504 return fault; 505 } 506}}; 507 508def template NeonLoadCompleteAcc {{ 509 template <class Element> 510 Fault %(class_name)s<Element>::completeAcc( 511 PacketPtr pkt, %(CPU_exec_context)s *xc, 512 Trace::InstRecord *traceData) const 513 { 514 Fault fault = NoFault; 515 516 %(mem_decl)s; 517 %(op_decl)s; 518 %(op_rd)s; 519 520 if (%(predicate_test)s) 521 { 522 // ARM instructions will not have a pkt if the predicate is false 523 MemUnion &memUnion = *(MemUnion *)pkt->getPtr<uint8_t>(); 524 525 if (fault == NoFault) { 526 %(memacc_code)s; 527 } 528 529 if (fault == NoFault) { 530 %(op_wb)s; 531 } 532 } 533 534 return fault; 535 } 536}}; 537 538def template StoreCompleteAcc {{ 539 Fault %(class_name)s::completeAcc(PacketPtr pkt, 540 %(CPU_exec_context)s *xc, 541 Trace::InstRecord *traceData) const 542 { 543 return NoFault; 544 } 545}}; 546 547def template NeonStoreCompleteAcc {{ 548 template <class Element> 549 Fault %(class_name)s<Element>::completeAcc( 550 PacketPtr pkt, %(CPU_exec_context)s *xc, 551 Trace::InstRecord *traceData) const 552 { 553 return NoFault; 554 } 555}}; 556 557def template StoreExCompleteAcc {{ 558 Fault %(class_name)s::completeAcc(PacketPtr pkt, 559 %(CPU_exec_context)s *xc, 560 Trace::InstRecord *traceData) const 561 { 562 Fault fault = NoFault; 563 564 %(op_decl)s; 565 %(op_rd)s; 566 567 if (%(predicate_test)s) 568 { 569 uint64_t writeResult = pkt->req->getExtraData(); 570 %(postacc_code)s; 571 572 if (fault == NoFault) { 573 %(op_wb)s; 574 } 575 } 576 577 return fault; 578 } 579}}; 580 581def template RfeDeclare {{ 582 /** 583 * Static instruction class for "%(mnemonic)s". 584 */ 585 class %(class_name)s : public %(base_class)s 586 { 587 public: 588 589 /// Constructor. 590 %(class_name)s(ExtMachInst machInst, 591 uint32_t _base, int _mode, bool _wb); 592 593 %(BasicExecDeclare)s 594 595 %(InitiateAccDeclare)s 596 597 %(CompleteAccDeclare)s 598 }; 599}}; 600 601def template SrsDeclare {{ 602 /** 603 * Static instruction class for "%(mnemonic)s". 604 */ 605 class %(class_name)s : public %(base_class)s 606 { 607 public: 608 609 /// Constructor. 610 %(class_name)s(ExtMachInst machInst, 611 uint32_t _regMode, int _mode, bool _wb); 612 613 %(BasicExecDeclare)s 614 615 %(InitiateAccDeclare)s 616 617 %(CompleteAccDeclare)s 618 }; 619}}; 620 621def template SwapDeclare {{ 622 /** 623 * Static instruction class for "%(mnemonic)s". 624 */ 625 class %(class_name)s : public %(base_class)s 626 { 627 public: 628 629 /// Constructor. 630 %(class_name)s(ExtMachInst machInst, 631 uint32_t _dest, uint32_t _op1, uint32_t _base); 632 633 %(BasicExecDeclare)s 634 635 %(InitiateAccDeclare)s 636 637 %(CompleteAccDeclare)s 638 }; 639}}; 640 641def template LoadStoreDImmDeclare {{ 642 /** 643 * Static instruction class for "%(mnemonic)s". 644 */ 645 class %(class_name)s : public %(base_class)s 646 { 647 public: 648 649 /// Constructor. 650 %(class_name)s(ExtMachInst machInst, 651 uint32_t _dest, uint32_t _dest2, 652 uint32_t _base, bool _add, int32_t _imm); 653 654 %(BasicExecDeclare)s 655 656 %(InitiateAccDeclare)s 657 658 %(CompleteAccDeclare)s 659 }; 660}}; 661 662def template StoreExDImmDeclare {{ 663 /** 664 * Static instruction class for "%(mnemonic)s". 665 */ 666 class %(class_name)s : public %(base_class)s 667 { 668 public: 669 670 /// Constructor. 671 %(class_name)s(ExtMachInst machInst, 672 uint32_t _result, uint32_t _dest, uint32_t _dest2, 673 uint32_t _base, bool _add, int32_t _imm); 674 675 %(BasicExecDeclare)s 676 677 %(InitiateAccDeclare)s 678 679 %(CompleteAccDeclare)s 680 }; 681}}; 682 683def template LoadStoreImmDeclare {{ 684 /** 685 * Static instruction class for "%(mnemonic)s". 686 */ 687 class %(class_name)s : public %(base_class)s 688 { 689 public: 690 691 /// Constructor. 692 %(class_name)s(ExtMachInst machInst, 693 uint32_t _dest, uint32_t _base, bool _add, int32_t _imm); 694 695 %(BasicExecDeclare)s 696 697 %(InitiateAccDeclare)s 698 699 %(CompleteAccDeclare)s 700 }; 701}}; 702 703def template StoreExImmDeclare {{ 704 /** 705 * Static instruction class for "%(mnemonic)s". 706 */ 707 class %(class_name)s : public %(base_class)s 708 { 709 public: 710 711 /// Constructor. 712 %(class_name)s(ExtMachInst machInst, 713 uint32_t _result, uint32_t _dest, uint32_t _base, 714 bool _add, int32_t _imm); 715 716 %(BasicExecDeclare)s 717 718 %(InitiateAccDeclare)s 719 720 %(CompleteAccDeclare)s 721 }; 722}}; 723 724def template StoreDRegDeclare {{ 725 /** 726 * Static instruction class for "%(mnemonic)s". 727 */ 728 class %(class_name)s : public %(base_class)s 729 { 730 public: 731 732 /// Constructor. 733 %(class_name)s(ExtMachInst machInst, 734 uint32_t _dest, uint32_t _dest2, 735 uint32_t _base, bool _add, 736 int32_t _shiftAmt, uint32_t _shiftType, 737 uint32_t _index); 738 739 %(BasicExecDeclare)s 740 741 %(InitiateAccDeclare)s 742 743 %(CompleteAccDeclare)s 744 }; 745}}; 746 747def template StoreRegDeclare {{ 748 /** 749 * Static instruction class for "%(mnemonic)s". 750 */ 751 class %(class_name)s : public %(base_class)s 752 { 753 public: 754 755 /// Constructor. 756 %(class_name)s(ExtMachInst machInst, 757 uint32_t _dest, uint32_t _base, bool _add, 758 int32_t _shiftAmt, uint32_t _shiftType, 759 uint32_t _index); 760 761 %(BasicExecDeclare)s 762 763 %(InitiateAccDeclare)s 764 765 %(CompleteAccDeclare)s 766 }; 767}}; 768 769def template LoadDRegDeclare {{ 770 /** 771 * Static instruction class for "%(mnemonic)s". 772 */ 773 class %(class_name)s : public %(base_class)s 774 { 775 public: 776 777 /// Constructor. 778 %(class_name)s(ExtMachInst machInst, 779 uint32_t _dest, uint32_t _dest2, 780 uint32_t _base, bool _add, 781 int32_t _shiftAmt, uint32_t _shiftType, 782 uint32_t _index); 783 784 %(BasicExecDeclare)s 785 786 %(InitiateAccDeclare)s 787 788 %(CompleteAccDeclare)s 789 }; 790}}; 791 792def template LoadRegDeclare {{ 793 /** 794 * Static instruction class for "%(mnemonic)s". 795 */ 796 class %(class_name)s : public %(base_class)s 797 { 798 public: 799 800 /// Constructor. 801 %(class_name)s(ExtMachInst machInst, 802 uint32_t _dest, uint32_t _base, bool _add, 803 int32_t _shiftAmt, uint32_t _shiftType, 804 uint32_t _index); 805 806 %(BasicExecDeclare)s 807 808 %(InitiateAccDeclare)s 809 810 %(CompleteAccDeclare)s 811 }; 812}}; 813 814def template LoadImmDeclare {{ 815 /** 816 * Static instruction class for "%(mnemonic)s". 817 */ 818 class %(class_name)s : public %(base_class)s 819 { 820 public: 821 822 /// Constructor. 823 %(class_name)s(ExtMachInst machInst, 824 uint32_t _dest, uint32_t _base, bool _add, int32_t _imm); 825 826 %(BasicExecDeclare)s 827 828 %(InitiateAccDeclare)s 829 830 %(CompleteAccDeclare)s 831 }; 832}}; 833 834def template InitiateAccDeclare {{ 835 Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const; 836}}; 837 838def template CompleteAccDeclare {{ 839 Fault completeAcc(PacketPtr, %(CPU_exec_context)s *, Trace::InstRecord *) const; 840}}; 841 842def template RfeConstructor {{ 843 inline %(class_name)s::%(class_name)s(ExtMachInst machInst, 844 uint32_t _base, int _mode, bool _wb) 845 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, 846 (IntRegIndex)_base, (AddrMode)_mode, _wb) 847 { 848 %(constructor)s; 849 if (!(condCode == COND_AL || condCode == COND_UC)) { 850 for (int x = 0; x < _numDestRegs; x++) { 851 _srcRegIdx[_numSrcRegs++] = _destRegIdx[x]; 852 } 853 } 854#if %(use_uops)d 855 uops = new StaticInstPtr[1 + %(use_wb)d + %(use_pc)d]; 856 int uopIdx = 0; 857 uops[uopIdx] = new %(acc_name)s(machInst, _base, _mode, _wb); 858 uops[uopIdx]->setDelayedCommit(); 859#if %(use_wb)d 860 uops[++uopIdx] = new %(wb_decl)s; 861 uops[uopIdx]->setDelayedCommit(); 862#endif 863#if %(use_pc)d 864 uops[++uopIdx] = new %(pc_decl)s; 865#endif 866 uops[uopIdx]->setLastMicroop(); 867#endif 868 } 869}}; 870 871def template SrsConstructor {{ 872 inline %(class_name)s::%(class_name)s(ExtMachInst machInst, 873 uint32_t _regMode, int _mode, bool _wb) 874 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, 875 (OperatingMode)_regMode, (AddrMode)_mode, _wb) 876 { 877 %(constructor)s; 878 if (!(condCode == COND_AL || condCode == COND_UC)) { 879 for (int x = 0; x < _numDestRegs; x++) { 880 _srcRegIdx[_numSrcRegs++] = _destRegIdx[x]; 881 } 882 } 883#if %(use_uops)d 884 assert(numMicroops >= 2); 885 uops = new StaticInstPtr[numMicroops]; 886 uops[0] = new %(acc_name)s(machInst, _regMode, _mode, _wb); 887 uops[0]->setDelayedCommit(); 888 uops[1] = new %(wb_decl)s; 889 uops[1]->setLastMicroop(); 890#endif 891 } 892}}; 893 894def template SwapConstructor {{ 895 inline %(class_name)s::%(class_name)s(ExtMachInst machInst, 896 uint32_t _dest, uint32_t _op1, uint32_t _base) 897 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, 898 (IntRegIndex)_dest, (IntRegIndex)_op1, (IntRegIndex)_base) 899 { 900 %(constructor)s; 901 if (!(condCode == COND_AL || condCode == COND_UC)) { 902 for (int x = 0; x < _numDestRegs; x++) { 903 _srcRegIdx[_numSrcRegs++] = _destRegIdx[x]; 904 } 905 } 906 } 907}}; 908 909def template LoadStoreDImmConstructor {{ 910 inline %(class_name)s::%(class_name)s(ExtMachInst machInst, 911 uint32_t _dest, uint32_t _dest2, 912 uint32_t _base, bool _add, int32_t _imm) 913 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, 914 (IntRegIndex)_dest, (IntRegIndex)_dest2, 915 (IntRegIndex)_base, _add, _imm) 916 { 917 %(constructor)s; 918 if (!(condCode == COND_AL || condCode == COND_UC)) { 919 for (int x = 0; x < _numDestRegs; x++) { 920 _srcRegIdx[_numSrcRegs++] = _destRegIdx[x]; 921 } 922 } 923#if %(use_uops)d 924 assert(numMicroops >= 2); 925 uops = new StaticInstPtr[numMicroops]; 926 uops[0] = new %(acc_name)s(machInst, _dest, _dest2, _base, _add, _imm); 927 uops[0]->setDelayedCommit(); 928 uops[1] = new %(wb_decl)s; 929 uops[1]->setLastMicroop(); 930#endif 931 } 932}}; 933 934def template StoreExDImmConstructor {{ 935 inline %(class_name)s::%(class_name)s(ExtMachInst machInst, 936 uint32_t _result, uint32_t _dest, uint32_t _dest2, 937 uint32_t _base, bool _add, int32_t _imm) 938 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, 939 (IntRegIndex)_result, 940 (IntRegIndex)_dest, (IntRegIndex)_dest2, 941 (IntRegIndex)_base, _add, _imm) 942 { 943 %(constructor)s; 944 if (!(condCode == COND_AL || condCode == COND_UC)) { 945 for (int x = 0; x < _numDestRegs; x++) { 946 _srcRegIdx[_numSrcRegs++] = _destRegIdx[x]; 947 } 948 } 949#if %(use_uops)d 950 assert(numMicroops >= 2); 951 uops = new StaticInstPtr[numMicroops]; 952 uops[0] = new %(acc_name)s(machInst, _result, _dest, _dest2, 953 _base, _add, _imm); 954 uops[0]->setDelayedCommit(); 955 uops[1] = new %(wb_decl)s; 956 uops[1]->setLastMicroop(); 957#endif 958 } 959}}; 960 961def template LoadStoreImmConstructor {{ 962 inline %(class_name)s::%(class_name)s(ExtMachInst machInst, 963 uint32_t _dest, uint32_t _base, bool _add, int32_t _imm) 964 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, 965 (IntRegIndex)_dest, (IntRegIndex)_base, _add, _imm) 966 { 967 %(constructor)s; 968 if (!(condCode == COND_AL || condCode == COND_UC)) { 969 for (int x = 0; x < _numDestRegs; x++) { 970 _srcRegIdx[_numSrcRegs++] = _destRegIdx[x]; 971 } 972 } 973#if %(use_uops)d 974 assert(numMicroops >= 2); 975 uops = new StaticInstPtr[numMicroops]; 976 uops[0] = new %(acc_name)s(machInst, _dest, _base, _add, _imm); 977 uops[0]->setDelayedCommit(); 978 uops[1] = new %(wb_decl)s; 979 uops[1]->setLastMicroop(); 980#endif 981 } 982}}; 983 984def template StoreExImmConstructor {{ 985 inline %(class_name)s::%(class_name)s(ExtMachInst machInst, 986 uint32_t _result, uint32_t _dest, uint32_t _base, 987 bool _add, int32_t _imm) 988 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, 989 (IntRegIndex)_result, (IntRegIndex)_dest, 990 (IntRegIndex)_base, _add, _imm) 991 { 992 %(constructor)s; 993 if (!(condCode == COND_AL || condCode == COND_UC)) { 994 for (int x = 0; x < _numDestRegs; x++) { 995 _srcRegIdx[_numSrcRegs++] = _destRegIdx[x]; 996 } 997 } 998#if %(use_uops)d 999 assert(numMicroops >= 2); 1000 uops = new StaticInstPtr[numMicroops]; 1001 uops[0] = new %(acc_name)s(machInst, _result, _dest, 1002 _base, _add, _imm); 1003 uops[0]->setDelayedCommit(); 1004 uops[1] = new %(wb_decl)s; 1005 uops[1]->setLastMicroop(); 1006#endif 1007 } 1008}}; 1009 1010def template StoreDRegConstructor {{ 1011 inline %(class_name)s::%(class_name)s(ExtMachInst machInst, 1012 uint32_t _dest, uint32_t _dest2, uint32_t _base, bool _add, 1013 int32_t _shiftAmt, uint32_t _shiftType, uint32_t _index) 1014 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, 1015 (IntRegIndex)_dest, (IntRegIndex)_dest2, 1016 (IntRegIndex)_base, _add, 1017 _shiftAmt, (ArmShiftType)_shiftType, 1018 (IntRegIndex)_index) 1019 { 1020 %(constructor)s; 1021 if (!(condCode == COND_AL || condCode == COND_UC)) { 1022 for (int x = 0; x < _numDestRegs; x++) { 1023 _srcRegIdx[_numSrcRegs++] = _destRegIdx[x]; 1024 } 1025 } 1026#if %(use_uops)d 1027 assert(numMicroops >= 2); 1028 uops = new StaticInstPtr[numMicroops]; 1029 uops[0] = new %(acc_name)s(machInst, _dest, _dest2, _base, _add, 1030 _shiftAmt, _shiftType, _index); 1031 uops[0]->setDelayedCommit(); 1032 uops[1] = new %(wb_decl)s; 1033 uops[1]->setLastMicroop(); 1034#endif 1035 } 1036}}; 1037 1038def template StoreRegConstructor {{ 1039 inline %(class_name)s::%(class_name)s(ExtMachInst machInst, 1040 uint32_t _dest, uint32_t _base, bool _add, 1041 int32_t _shiftAmt, uint32_t _shiftType, uint32_t _index) 1042 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, 1043 (IntRegIndex)_dest, (IntRegIndex)_base, _add, 1044 _shiftAmt, (ArmShiftType)_shiftType, 1045 (IntRegIndex)_index) 1046 { 1047 %(constructor)s; 1048 if (!(condCode == COND_AL || condCode == COND_UC)) { 1049 for (int x = 0; x < _numDestRegs; x++) { 1050 _srcRegIdx[_numSrcRegs++] = _destRegIdx[x]; 1051 } 1052 } 1053#if %(use_uops)d 1054 assert(numMicroops >= 2); 1055 uops = new StaticInstPtr[numMicroops]; 1056 uops[0] = new %(acc_name)s(machInst, _dest, _base, _add, 1057 _shiftAmt, _shiftType, _index); 1058 uops[0]->setDelayedCommit(); 1059 uops[1] = new %(wb_decl)s; 1060 uops[1]->setLastMicroop(); 1061#endif 1062 } 1063}}; 1064 1065def template LoadDRegConstructor {{ 1066 inline %(class_name)s::%(class_name)s(ExtMachInst machInst, 1067 uint32_t _dest, uint32_t _dest2, uint32_t _base, bool _add, 1068 int32_t _shiftAmt, uint32_t _shiftType, uint32_t _index) 1069 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, 1070 (IntRegIndex)_dest, (IntRegIndex)_dest2, 1071 (IntRegIndex)_base, _add, 1072 _shiftAmt, (ArmShiftType)_shiftType, 1073 (IntRegIndex)_index) 1074 { 1075 %(constructor)s; 1076 if (!(condCode == COND_AL || condCode == COND_UC)) { 1077 for (int x = 0; x < _numDestRegs; x++) { 1078 _srcRegIdx[_numSrcRegs++] = _destRegIdx[x]; 1079 } 1080 } 1081#if %(use_uops)d 1082 assert(numMicroops >= 2); 1083 uops = new StaticInstPtr[numMicroops]; 1084 if ((_dest == _index) || (_dest2 == _index)) { 1085 IntRegIndex wbIndexReg = INTREG_UREG0; 1086 uops[0] = new MicroUopRegMov(machInst, INTREG_UREG0, _index); 1087 uops[0]->setDelayedCommit(); 1088 uops[1] = new %(acc_name)s(machInst, _dest, _dest2, _base, _add, 1089 _shiftAmt, _shiftType, _index); 1090 uops[1]->setDelayedCommit(); 1091 uops[2] = new %(wb_decl)s; 1092 uops[2]->setLastMicroop(); 1093 } else { 1094 IntRegIndex wbIndexReg = index; 1095 uops[0] = new %(acc_name)s(machInst, _dest, _dest2, _base, _add, 1096 _shiftAmt, _shiftType, _index); 1097 uops[0]->setDelayedCommit(); 1098 uops[1] = new %(wb_decl)s; 1099 uops[1]->setLastMicroop(); 1100 } 1101#endif 1102 } 1103}}; 1104 1105def template LoadRegConstructor {{ 1106 inline %(class_name)s::%(class_name)s(ExtMachInst machInst, 1107 uint32_t _dest, uint32_t _base, bool _add, 1108 int32_t _shiftAmt, uint32_t _shiftType, uint32_t _index) 1109 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, 1110 (IntRegIndex)_dest, (IntRegIndex)_base, _add, 1111 _shiftAmt, (ArmShiftType)_shiftType, 1112 (IntRegIndex)_index) 1113 { 1114 %(constructor)s; 1115 bool conditional M5_VAR_USED = false; 1116 if (!(condCode == COND_AL || condCode == COND_UC)) { 1117 conditional = true; 1118 for (int x = 0; x < _numDestRegs; x++) { 1119 _srcRegIdx[_numSrcRegs++] = _destRegIdx[x]; 1120 } 1121 } 1122#if %(use_uops)d 1123 assert(numMicroops >= 2); 1124 uops = new StaticInstPtr[numMicroops]; 1125 if (_dest == INTREG_PC && !isFloating()) { 1126 IntRegIndex wbIndexReg = index; 1127 uops[0] = new %(acc_name)s(machInst, INTREG_UREG0, _base, _add, 1128 _shiftAmt, _shiftType, _index); 1129 uops[0]->setDelayedCommit(); 1130 uops[1] = new %(wb_decl)s; 1131 uops[1]->setDelayedCommit(); 1132 uops[2] = new MicroUopRegMov(machInst, INTREG_PC, INTREG_UREG0); 1133 uops[2]->setFlag(StaticInst::IsControl); 1134 uops[2]->setFlag(StaticInst::IsIndirectControl); 1135 if (conditional) 1136 uops[2]->setFlag(StaticInst::IsCondControl); 1137 else 1138 uops[2]->setFlag(StaticInst::IsUncondControl); 1139 uops[2]->setLastMicroop(); 1140 } else if(_dest == _index) { 1141 IntRegIndex wbIndexReg = INTREG_UREG0; 1142 uops[0] = new MicroUopRegMov(machInst, INTREG_UREG0, _index); 1143 uops[0]->setDelayedCommit(); 1144 uops[1] = new %(acc_name)s(machInst, _dest, _base, _add, 1145 _shiftAmt, _shiftType, _index); 1146 uops[1]->setDelayedCommit(); 1147 uops[2] = new %(wb_decl)s; 1148 uops[2]->setLastMicroop(); 1149 } else { 1150 IntRegIndex wbIndexReg = index; 1151 uops[0] = new %(acc_name)s(machInst, _dest, _base, _add, 1152 _shiftAmt, _shiftType, _index); 1153 uops[0]->setDelayedCommit(); 1154 uops[1] = new %(wb_decl)s; 1155 uops[1]->setLastMicroop(); 1156 1157 } 1158#else 1159 if (_dest == INTREG_PC && !isFloating()) { 1160 flags[IsControl] = true; 1161 flags[IsIndirectControl] = true; 1162 if (conditional) 1163 flags[IsCondControl] = true; 1164 else 1165 flags[IsUncondControl] = true; 1166 } 1167#endif 1168 } 1169}}; 1170 1171def template LoadImmConstructor {{ 1172 inline %(class_name)s::%(class_name)s(ExtMachInst machInst, 1173 uint32_t _dest, uint32_t _base, bool _add, int32_t _imm) 1174 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, 1175 (IntRegIndex)_dest, (IntRegIndex)_base, _add, _imm) 1176 { 1177 %(constructor)s; 1178 bool conditional M5_VAR_USED = false; 1179 if (!(condCode == COND_AL || condCode == COND_UC)) { 1180 conditional = true; 1181 for (int x = 0; x < _numDestRegs; x++) { 1182 _srcRegIdx[_numSrcRegs++] = _destRegIdx[x]; 1183 } 1184 } 1185#if %(use_uops)d 1186 assert(numMicroops >= 2); 1187 uops = new StaticInstPtr[numMicroops]; 1188 if (_dest == INTREG_PC && !isFloating()) { 1189 uops[0] = new %(acc_name)s(machInst, INTREG_UREG0, _base, _add, 1190 _imm); 1191 uops[0]->setDelayedCommit(); 1192 uops[1] = new %(wb_decl)s; 1193 uops[1]->setDelayedCommit(); 1194 uops[2] = new MicroUopRegMov(machInst, INTREG_PC, INTREG_UREG0); 1195 uops[2]->setFlag(StaticInst::IsControl); 1196 uops[2]->setFlag(StaticInst::IsIndirectControl); 1197 if (conditional) 1198 uops[2]->setFlag(StaticInst::IsCondControl); 1199 else 1200 uops[2]->setFlag(StaticInst::IsUncondControl); 1201 if (_base == INTREG_SP && _add && _imm == 4 && %(is_ras_pop)s) 1202 uops[2]->setFlag(StaticInst::IsReturn); 1203 uops[2]->setLastMicroop(); 1204 } else { 1205 uops[0] = new %(acc_name)s(machInst, _dest, _base, _add, _imm); 1206 uops[0]->setDelayedCommit(); 1207 uops[1] = new %(wb_decl)s; 1208 uops[1]->setLastMicroop(); 1209 } 1210#else 1211 if (_dest == INTREG_PC && !isFloating()) { 1212 flags[IsControl] = true; 1213 flags[IsIndirectControl] = true; 1214 if (conditional) 1215 flags[IsCondControl] = true; 1216 else 1217 flags[IsUncondControl] = true; 1218 } 1219#endif 1220 } 1221}}; 1222 1223