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