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 override; 586 Fault initiateAcc(ExecContext *, Trace::InstRecord *) const override; 587 Fault completeAcc(PacketPtr, ExecContext *, 588 Trace::InstRecord *) const override; 589 }; 590}}; 591 592def template SrsDeclare {{ 593 /** 594 * Static instruction class for "%(mnemonic)s". 595 */ 596 class %(class_name)s : public %(base_class)s 597 { 598 public: 599 600 /// Constructor. 601 %(class_name)s(ExtMachInst machInst, 602 uint32_t _regMode, int _mode, bool _wb); 603 604 Fault execute(ExecContext *, Trace::InstRecord *) const override; 605 Fault initiateAcc(ExecContext *, Trace::InstRecord *) const override; 606 Fault completeAcc(PacketPtr, ExecContext *, 607 Trace::InstRecord *) const override; 608 }; 609}}; 610 611def template SwapDeclare {{ 612 /** 613 * Static instruction class for "%(mnemonic)s". 614 */ 615 class %(class_name)s : public %(base_class)s 616 { 617 public: 618 619 /// Constructor. 620 %(class_name)s(ExtMachInst machInst, 621 uint32_t _dest, uint32_t _op1, uint32_t _base); 622 623 Fault execute(ExecContext *, Trace::InstRecord *) const override; 624 Fault initiateAcc(ExecContext *, Trace::InstRecord *) const override; 625 Fault completeAcc(PacketPtr, ExecContext *, 626 Trace::InstRecord *) const override; 627 }; 628}}; 629 630def template LoadStoreDImmDeclare {{ 631 /** 632 * Static instruction class for "%(mnemonic)s". 633 */ 634 class %(class_name)s : public %(base_class)s 635 { 636 public: 637 638 /// Constructor. 639 %(class_name)s(ExtMachInst machInst, 640 uint32_t _dest, uint32_t _dest2, 641 uint32_t _base, bool _add, int32_t _imm); 642 643 Fault execute(ExecContext *, Trace::InstRecord *) const override; 644 Fault initiateAcc(ExecContext *, Trace::InstRecord *) const override; 645 Fault completeAcc(PacketPtr, ExecContext *, 646 Trace::InstRecord *) const override; 647 }; 648}}; 649 650def template StoreExDImmDeclare {{ 651 /** 652 * Static instruction class for "%(mnemonic)s". 653 */ 654 class %(class_name)s : public %(base_class)s 655 { 656 public: 657 658 /// Constructor. 659 %(class_name)s(ExtMachInst machInst, 660 uint32_t _result, uint32_t _dest, uint32_t _dest2, 661 uint32_t _base, bool _add, int32_t _imm); 662 663 Fault execute(ExecContext *, Trace::InstRecord *) const override; 664 Fault initiateAcc(ExecContext *, Trace::InstRecord *) const override; 665 Fault completeAcc(PacketPtr, ExecContext *, 666 Trace::InstRecord *) const override; 667 }; 668}}; 669 670def template LoadStoreImmDeclare {{ 671 /** 672 * Static instruction class for "%(mnemonic)s". 673 */ 674 class %(class_name)s : public %(base_class)s 675 { 676 public: 677 678 /// Constructor. 679 %(class_name)s(ExtMachInst machInst, 680 uint32_t _dest, uint32_t _base, bool _add, int32_t _imm); 681 682 Fault execute(ExecContext *, Trace::InstRecord *) const override; 683 Fault initiateAcc(ExecContext *, Trace::InstRecord *) const override; 684 Fault completeAcc(PacketPtr, ExecContext *, 685 Trace::InstRecord *) const override; 686 687 void 688 annotateFault(ArmFault *fault) override 689 { 690 %(fa_code)s 691 } 692 }; 693}}; 694 695def template StoreExImmDeclare {{ 696 /** 697 * Static instruction class for "%(mnemonic)s". 698 */ 699 class %(class_name)s : public %(base_class)s 700 { 701 public: 702 703 /// Constructor. 704 %(class_name)s(ExtMachInst machInst, 705 uint32_t _result, uint32_t _dest, uint32_t _base, 706 bool _add, int32_t _imm); 707 708 Fault execute(ExecContext *, Trace::InstRecord *) const override; 709 Fault initiateAcc(ExecContext *, Trace::InstRecord *) const override; 710 Fault completeAcc(PacketPtr, ExecContext *, 711 Trace::InstRecord *) const override; 712 }; 713}}; 714 715def template StoreDRegDeclare {{ 716 /** 717 * Static instruction class for "%(mnemonic)s". 718 */ 719 class %(class_name)s : public %(base_class)s 720 { 721 public: 722 723 /// Constructor. 724 %(class_name)s(ExtMachInst machInst, 725 uint32_t _dest, uint32_t _dest2, 726 uint32_t _base, bool _add, 727 int32_t _shiftAmt, uint32_t _shiftType, 728 uint32_t _index); 729 730 Fault execute(ExecContext *, Trace::InstRecord *) const override; 731 Fault initiateAcc(ExecContext *, Trace::InstRecord *) const override; 732 Fault completeAcc(PacketPtr, ExecContext *, 733 Trace::InstRecord *) const override; 734 }; 735}}; 736 737def template StoreRegDeclare {{ 738 /** 739 * Static instruction class for "%(mnemonic)s". 740 */ 741 class %(class_name)s : public %(base_class)s 742 { 743 public: 744 745 /// Constructor. 746 %(class_name)s(ExtMachInst machInst, 747 uint32_t _dest, uint32_t _base, bool _add, 748 int32_t _shiftAmt, uint32_t _shiftType, 749 uint32_t _index); 750 751 Fault execute(ExecContext *, Trace::InstRecord *) const override; 752 Fault initiateAcc(ExecContext *, Trace::InstRecord *) const override; 753 Fault completeAcc(PacketPtr, ExecContext *, 754 Trace::InstRecord *) const override; 755 756 void 757 annotateFault(ArmFault *fault) override 758 { 759 %(fa_code)s 760 } 761 }; 762}}; 763 764def template LoadDRegDeclare {{ 765 /** 766 * Static instruction class for "%(mnemonic)s". 767 */ 768 class %(class_name)s : public %(base_class)s 769 { 770 public: 771 772 /// Constructor. 773 %(class_name)s(ExtMachInst machInst, 774 uint32_t _dest, uint32_t _dest2, 775 uint32_t _base, bool _add, 776 int32_t _shiftAmt, uint32_t _shiftType, 777 uint32_t _index); 778 779 Fault execute(ExecContext *, Trace::InstRecord *) const override; 780 Fault initiateAcc(ExecContext *, Trace::InstRecord *) const override; 781 Fault completeAcc(PacketPtr, ExecContext *, 782 Trace::InstRecord *) const override; 783 }; 784}}; 785 786def template LoadRegDeclare {{ 787 /** 788 * Static instruction class for "%(mnemonic)s". 789 */ 790 class %(class_name)s : public %(base_class)s 791 { 792 public: 793 794 /// Constructor. 795 %(class_name)s(ExtMachInst machInst, 796 uint32_t _dest, uint32_t _base, bool _add, 797 int32_t _shiftAmt, uint32_t _shiftType, 798 uint32_t _index); 799 800 Fault execute(ExecContext *, Trace::InstRecord *) const override; 801 Fault initiateAcc(ExecContext *, Trace::InstRecord *) const override; 802 Fault completeAcc(PacketPtr, ExecContext *, 803 Trace::InstRecord *) const override; 804 805 void 806 annotateFault(ArmFault *fault) override 807 { 808 %(fa_code)s 809 } 810 }; 811}}; 812 813def template LoadImmDeclare {{ 814 /** 815 * Static instruction class for "%(mnemonic)s". 816 */ 817 class %(class_name)s : public %(base_class)s 818 { 819 public: 820 821 /// Constructor. 822 %(class_name)s(ExtMachInst machInst, 823 uint32_t _dest, uint32_t _base, bool _add, int32_t _imm); 824 825 Fault execute(ExecContext *, Trace::InstRecord *) const override; 826 Fault initiateAcc(ExecContext *, Trace::InstRecord *) const override; 827 Fault completeAcc(PacketPtr, ExecContext *, 828 Trace::InstRecord *) const override; 829 830 void 831 annotateFault(ArmFault *fault) override 832 { 833 %(fa_code)s 834 } 835 }; 836}}; 837 838def template RfeConstructor {{ 839 %(class_name)s::%(class_name)s(ExtMachInst machInst, 840 uint32_t _base, int _mode, bool _wb) 841 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, 842 (IntRegIndex)_base, (AddrMode)_mode, _wb) 843 { 844 %(constructor)s; 845 if (!(condCode == COND_AL || condCode == COND_UC)) { 846 for (int x = 0; x < _numDestRegs; x++) { 847 _srcRegIdx[_numSrcRegs++] = _destRegIdx[x]; 848 } 849 } 850#if %(use_uops)d 851 uops = new StaticInstPtr[1 + %(use_wb)d + %(use_pc)d]; 852 int uopIdx = 0; 853 uops[uopIdx] = new %(acc_name)s(machInst, _base, _mode, _wb); 854 uops[uopIdx]->setDelayedCommit(); 855#if %(use_wb)d 856 uops[++uopIdx] = new %(wb_decl)s; 857 uops[uopIdx]->setDelayedCommit(); 858#endif 859#if %(use_pc)d 860 uops[++uopIdx] = new %(pc_decl)s; 861#endif 862 uops[0]->setFirstMicroop(); 863 uops[uopIdx]->setLastMicroop(); 864#endif 865 } 866}}; 867 868def template SrsConstructor {{ 869 %(class_name)s::%(class_name)s(ExtMachInst machInst, 870 uint32_t _regMode, int _mode, bool _wb) 871 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, 872 (OperatingMode)_regMode, (AddrMode)_mode, _wb) 873 { 874 %(constructor)s; 875 if (!(condCode == COND_AL || condCode == COND_UC)) { 876 for (int x = 0; x < _numDestRegs; x++) { 877 _srcRegIdx[_numSrcRegs++] = _destRegIdx[x]; 878 } 879 } 880#if %(use_uops)d 881 assert(numMicroops >= 2); 882 uops = new StaticInstPtr[numMicroops]; 883 uops[0] = new %(acc_name)s(machInst, _regMode, _mode, _wb); 884 uops[0]->setDelayedCommit(); 885 uops[0]->setFirstMicroop(); 886 uops[1] = new %(wb_decl)s; 887 uops[1]->setLastMicroop(); 888#endif 889 } 890}}; 891 892def template SwapConstructor {{ 893 %(class_name)s::%(class_name)s(ExtMachInst machInst, 894 uint32_t _dest, uint32_t _op1, uint32_t _base) 895 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, 896 (IntRegIndex)_dest, (IntRegIndex)_op1, (IntRegIndex)_base) 897 { 898 %(constructor)s; 899 if (!(condCode == COND_AL || condCode == COND_UC)) { 900 for (int x = 0; x < _numDestRegs; x++) { 901 _srcRegIdx[_numSrcRegs++] = _destRegIdx[x]; 902 } 903 } 904 } 905}}; 906 907def template LoadStoreDImmConstructor {{ 908 %(class_name)s::%(class_name)s(ExtMachInst machInst, 909 uint32_t _dest, uint32_t _dest2, 910 uint32_t _base, bool _add, int32_t _imm) 911 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, 912 (IntRegIndex)_dest, (IntRegIndex)_dest2, 913 (IntRegIndex)_base, _add, _imm) 914 { 915 %(constructor)s; 916 if (!(condCode == COND_AL || condCode == COND_UC)) { 917 for (int x = 0; x < _numDestRegs; x++) { 918 _srcRegIdx[_numSrcRegs++] = _destRegIdx[x]; 919 } 920 } 921#if %(use_uops)d 922 assert(numMicroops >= 2); 923 uops = new StaticInstPtr[numMicroops]; 924 uops[0] = new %(acc_name)s(machInst, _dest, _dest2, _base, _add, _imm); 925 uops[0]->setFirstMicroop(); 926 uops[0]->setDelayedCommit(); 927 uops[1] = new %(wb_decl)s; 928 uops[1]->setLastMicroop(); 929#endif 930 } 931}}; 932 933def template StoreExDImmConstructor {{ 934 %(class_name)s::%(class_name)s(ExtMachInst machInst, 935 uint32_t _result, uint32_t _dest, uint32_t _dest2, 936 uint32_t _base, bool _add, int32_t _imm) 937 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, 938 (IntRegIndex)_result, 939 (IntRegIndex)_dest, (IntRegIndex)_dest2, 940 (IntRegIndex)_base, _add, _imm) 941 { 942 %(constructor)s; 943 if (!(condCode == COND_AL || condCode == COND_UC)) { 944 for (int x = 0; x < _numDestRegs; x++) { 945 _srcRegIdx[_numSrcRegs++] = _destRegIdx[x]; 946 } 947 } 948#if %(use_uops)d 949 assert(numMicroops >= 2); 950 uops = new StaticInstPtr[numMicroops]; 951 uops[0] = new %(acc_name)s(machInst, _result, _dest, _dest2, 952 _base, _add, _imm); 953 uops[0]->setDelayedCommit(); 954 uops[0]->setFirstMicroop(); 955 uops[1] = new %(wb_decl)s; 956 uops[1]->setLastMicroop(); 957#endif 958 } 959}}; 960 961def template LoadStoreImmConstructor {{ 962 %(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[0]->setFirstMicroop(); 979 uops[1] = new %(wb_decl)s; 980 uops[1]->setLastMicroop(); 981#endif 982 } 983}}; 984 985def template StoreExImmConstructor {{ 986 %(class_name)s::%(class_name)s(ExtMachInst machInst, 987 uint32_t _result, uint32_t _dest, uint32_t _base, 988 bool _add, int32_t _imm) 989 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, 990 (IntRegIndex)_result, (IntRegIndex)_dest, 991 (IntRegIndex)_base, _add, _imm) 992 { 993 %(constructor)s; 994 if (!(condCode == COND_AL || condCode == COND_UC)) { 995 for (int x = 0; x < _numDestRegs; x++) { 996 _srcRegIdx[_numSrcRegs++] = _destRegIdx[x]; 997 } 998 } 999#if %(use_uops)d 1000 assert(numMicroops >= 2); 1001 uops = new StaticInstPtr[numMicroops]; 1002 uops[0] = new %(acc_name)s(machInst, _result, _dest, 1003 _base, _add, _imm); 1004 uops[0]->setDelayedCommit(); 1005 uops[0]->setFirstMicroop(); 1006 uops[1] = new %(wb_decl)s; 1007 uops[1]->setLastMicroop(); 1008#endif 1009 } 1010}}; 1011 1012def template StoreDRegConstructor {{ 1013 %(class_name)s::%(class_name)s(ExtMachInst machInst, 1014 uint32_t _dest, uint32_t _dest2, uint32_t _base, bool _add, 1015 int32_t _shiftAmt, uint32_t _shiftType, uint32_t _index) 1016 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, 1017 (IntRegIndex)_dest, (IntRegIndex)_dest2, 1018 (IntRegIndex)_base, _add, 1019 _shiftAmt, (ArmShiftType)_shiftType, 1020 (IntRegIndex)_index) 1021 { 1022 %(constructor)s; 1023 if (!(condCode == COND_AL || condCode == COND_UC)) { 1024 for (int x = 0; x < _numDestRegs; x++) { 1025 _srcRegIdx[_numSrcRegs++] = _destRegIdx[x]; 1026 } 1027 } 1028#if %(use_uops)d 1029 assert(numMicroops >= 2); 1030 uops = new StaticInstPtr[numMicroops]; 1031 uops[0] = new %(acc_name)s(machInst, _dest, _dest2, _base, _add, 1032 _shiftAmt, _shiftType, _index); 1033 uops[0]->setDelayedCommit(); 1034 uops[0]->setFirstMicroop(); 1035 uops[1] = new %(wb_decl)s; 1036 uops[1]->setLastMicroop(); 1037#endif 1038 } 1039}}; 1040 1041def template StoreRegConstructor {{ 1042 %(class_name)s::%(class_name)s(ExtMachInst machInst, 1043 uint32_t _dest, uint32_t _base, bool _add, 1044 int32_t _shiftAmt, uint32_t _shiftType, uint32_t _index) 1045 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, 1046 (IntRegIndex)_dest, (IntRegIndex)_base, _add, 1047 _shiftAmt, (ArmShiftType)_shiftType, 1048 (IntRegIndex)_index) 1049 { 1050 %(constructor)s; 1051 if (!(condCode == COND_AL || condCode == COND_UC)) { 1052 for (int x = 0; x < _numDestRegs; x++) { 1053 _srcRegIdx[_numSrcRegs++] = _destRegIdx[x]; 1054 } 1055 } 1056#if %(use_uops)d 1057 assert(numMicroops >= 2); 1058 uops = new StaticInstPtr[numMicroops]; 1059 uops[0] = new %(acc_name)s(machInst, _dest, _base, _add, 1060 _shiftAmt, _shiftType, _index); 1061 uops[0]->setDelayedCommit(); 1062 uops[0]->setFirstMicroop(); 1063 uops[1] = new %(wb_decl)s; 1064 uops[1]->setLastMicroop(); 1065#endif 1066 } 1067}}; 1068 1069def template LoadDRegConstructor {{ 1070 %(class_name)s::%(class_name)s(ExtMachInst machInst, 1071 uint32_t _dest, uint32_t _dest2, uint32_t _base, bool _add, 1072 int32_t _shiftAmt, uint32_t _shiftType, uint32_t _index) 1073 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, 1074 (IntRegIndex)_dest, (IntRegIndex)_dest2, 1075 (IntRegIndex)_base, _add, 1076 _shiftAmt, (ArmShiftType)_shiftType, 1077 (IntRegIndex)_index) 1078 { 1079 %(constructor)s; 1080 if (!(condCode == COND_AL || condCode == COND_UC)) { 1081 for (int x = 0; x < _numDestRegs; x++) { 1082 _srcRegIdx[_numSrcRegs++] = _destRegIdx[x]; 1083 } 1084 } 1085#if %(use_uops)d 1086 assert(numMicroops >= 2); 1087 uops = new StaticInstPtr[numMicroops]; 1088 if ((_dest == _index) || (_dest2 == _index)) { 1089 IntRegIndex wbIndexReg = INTREG_UREG0; 1090 uops[0] = new MicroUopRegMov(machInst, INTREG_UREG0, _index); 1091 uops[0]->setDelayedCommit(); 1092 uops[0]->setFirstMicroop(); 1093 uops[1] = new %(acc_name)s(machInst, _dest, _dest2, _base, _add, 1094 _shiftAmt, _shiftType, _index); 1095 uops[1]->setDelayedCommit(); 1096 uops[2] = new %(wb_decl)s; 1097 uops[2]->setLastMicroop(); 1098 } else { 1099 IntRegIndex wbIndexReg = index; 1100 uops[0] = new %(acc_name)s(machInst, _dest, _dest2, _base, _add, 1101 _shiftAmt, _shiftType, _index); 1102 uops[0]->setDelayedCommit(); 1103 uops[0]->setFirstMicroop(); 1104 uops[1] = new %(wb_decl)s; 1105 uops[1]->setLastMicroop(); 1106 } 1107#endif 1108 } 1109}}; 1110 1111def template LoadRegConstructor {{ 1112 %(class_name)s::%(class_name)s(ExtMachInst machInst, 1113 uint32_t _dest, uint32_t _base, bool _add, 1114 int32_t _shiftAmt, uint32_t _shiftType, uint32_t _index) 1115 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, 1116 (IntRegIndex)_dest, (IntRegIndex)_base, _add, 1117 _shiftAmt, (ArmShiftType)_shiftType, 1118 (IntRegIndex)_index) 1119 { 1120 %(constructor)s; 1121 bool conditional M5_VAR_USED = false; 1122 if (!(condCode == COND_AL || condCode == COND_UC)) { 1123 conditional = true; 1124 for (int x = 0; x < _numDestRegs; x++) { 1125 _srcRegIdx[_numSrcRegs++] = _destRegIdx[x]; 1126 } 1127 } 1128#if %(use_uops)d 1129 assert(numMicroops >= 2); 1130 uops = new StaticInstPtr[numMicroops]; 1131 if (_dest == INTREG_PC && !isFloating() && !isVector()) { 1132 IntRegIndex wbIndexReg = index; 1133 uops[0] = new %(acc_name)s(machInst, INTREG_UREG0, _base, _add, 1134 _shiftAmt, _shiftType, _index); 1135 uops[0]->setDelayedCommit(); 1136 uops[0]->setFirstMicroop(); 1137 uops[1] = new %(wb_decl)s; 1138 uops[1]->setDelayedCommit(); 1139 uops[2] = new MicroUopRegMov(machInst, INTREG_PC, INTREG_UREG0); 1140 uops[2]->setFlag(StaticInst::IsControl); 1141 uops[2]->setFlag(StaticInst::IsIndirectControl); 1142 if (conditional) 1143 uops[2]->setFlag(StaticInst::IsCondControl); 1144 else 1145 uops[2]->setFlag(StaticInst::IsUncondControl); 1146 uops[2]->setLastMicroop(); 1147 } else if(_dest == _index) { 1148 IntRegIndex wbIndexReg = INTREG_UREG0; 1149 uops[0] = new MicroUopRegMov(machInst, INTREG_UREG0, _index); 1150 uops[0]->setDelayedCommit(); 1151 uops[0]->setFirstMicroop(); 1152 uops[1] = new %(acc_name)s(machInst, _dest, _base, _add, 1153 _shiftAmt, _shiftType, _index); 1154 uops[1]->setDelayedCommit(); 1155 uops[2] = new %(wb_decl)s; 1156 uops[2]->setLastMicroop(); 1157 } else { 1158 IntRegIndex wbIndexReg = index; 1159 uops[0] = new %(acc_name)s(machInst, _dest, _base, _add, 1160 _shiftAmt, _shiftType, _index); 1161 uops[0]->setDelayedCommit(); 1162 uops[0]->setFirstMicroop(); 1163 uops[1] = new %(wb_decl)s; 1164 uops[1]->setLastMicroop(); 1165 1166 } 1167#else 1168 if (_dest == INTREG_PC && !isFloating() && !isVector()) { 1169 flags[IsControl] = true; 1170 flags[IsIndirectControl] = true; 1171 if (conditional) 1172 flags[IsCondControl] = true; 1173 else 1174 flags[IsUncondControl] = true; 1175 } 1176#endif 1177 } 1178}}; 1179 1180def template LoadImmConstructor {{ 1181 %(class_name)s::%(class_name)s(ExtMachInst machInst, 1182 uint32_t _dest, uint32_t _base, bool _add, int32_t _imm) 1183 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, 1184 (IntRegIndex)_dest, (IntRegIndex)_base, _add, _imm) 1185 { 1186 %(constructor)s; 1187 bool conditional M5_VAR_USED = false; 1188 if (!(condCode == COND_AL || condCode == COND_UC)) { 1189 conditional = true; 1190 for (int x = 0; x < _numDestRegs; x++) { 1191 _srcRegIdx[_numSrcRegs++] = _destRegIdx[x]; 1192 } 1193 } 1194#if %(use_uops)d 1195 assert(numMicroops >= 2); 1196 uops = new StaticInstPtr[numMicroops]; 1197 if (_dest == INTREG_PC && !isFloating() && !isVector()) { 1198 uops[0] = new %(acc_name)s(machInst, INTREG_UREG0, _base, _add, 1199 _imm); 1200 uops[0]->setDelayedCommit(); 1201 uops[0]->setFirstMicroop(); 1202 uops[1] = new %(wb_decl)s; 1203 uops[1]->setDelayedCommit(); 1204 uops[2] = new MicroUopRegMov(machInst, INTREG_PC, INTREG_UREG0); 1205 uops[2]->setFlag(StaticInst::IsControl); 1206 uops[2]->setFlag(StaticInst::IsIndirectControl); 1207 /* Also set flags on the macroop so that pre-microop decomposition 1208 branch prediction can work */ 1209 setFlag(StaticInst::IsControl); 1210 setFlag(StaticInst::IsIndirectControl); 1211 if (conditional) { 1212 uops[2]->setFlag(StaticInst::IsCondControl); 1213 setFlag(StaticInst::IsCondControl); 1214 } else { 1215 uops[2]->setFlag(StaticInst::IsUncondControl); 1216 setFlag(StaticInst::IsUncondControl); 1217 } 1218 if (_base == INTREG_SP && _add && _imm == 4 && %(is_ras_pop)s) { 1219 uops[2]->setFlag(StaticInst::IsReturn); 1220 setFlag(StaticInst::IsReturn); 1221 } 1222 uops[2]->setLastMicroop(); 1223 } else { 1224 uops[0] = new %(acc_name)s(machInst, _dest, _base, _add, _imm); 1225 uops[0]->setDelayedCommit(); 1226 uops[0]->setFirstMicroop(); 1227 uops[1] = new %(wb_decl)s; 1228 uops[1]->setLastMicroop(); 1229 } 1230#else 1231 if (_dest == INTREG_PC && !isFloating() && !isVector()) { 1232 flags[IsControl] = true; 1233 flags[IsIndirectControl] = true; 1234 if (conditional) 1235 flags[IsCondControl] = true; 1236 else 1237 flags[IsUncondControl] = true; 1238 } 1239#endif 1240 } 1241}}; 1242 1243