1// -*- mode:c++ -*- 2 3// Copyright (c) 2011-2014, 2017, 2019 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// Redistribution and use in source and binary forms, with or without 16// modification, are permitted provided that the following conditions are 17// met: redistributions of source code must retain the above copyright 18// notice, this list of conditions and the following disclaimer; 19// redistributions in binary form must reproduce the above copyright 20// notice, this list of conditions and the following disclaimer in the 21// documentation and/or other materials provided with the distribution; 22// neither the name of the copyright holders nor the names of its 23// contributors may be used to endorse or promote products derived from 24// this software without specific prior written permission. 25// 26// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 27// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 28// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 29// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 30// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 31// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 32// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 33// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 34// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 35// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 36// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 37// 38// Authors: Gabe Black 39 40let {{ 41 SPAlignmentCheckCode = ''' 42 if (baseIsSP && bits(XBase, 3, 0) && 43 SPAlignmentCheckEnabled(xc->tcBase())) { 44 return std::make_shared<SPAlignmentFault>(); 45 } 46 ''' 47}}; 48 49def template Load64Execute {{ 50 Fault %(class_name)s::execute(ExecContext *xc, 51 Trace::InstRecord *traceData) const 52 { 53 Addr EA; 54 Fault fault = NoFault; 55 56 %(op_decl)s; 57 %(op_rd)s; 58 %(ea_code)s; 59 60 if (fault == NoFault) { 61 fault = readMemAtomic(xc, traceData, EA, Mem, memAccessFlags); 62 %(memacc_code)s; 63 } 64 65 if (fault == NoFault) { 66 %(op_wb)s; 67 } 68 69 return fault; 70 } 71}}; 72 73def template Load64FpExecute {{ 74 Fault %(class_name)s::execute(ExecContext *xc, 75 Trace::InstRecord *traceData) const 76 { 77 Addr EA; 78 Fault fault = NoFault; 79 80 %(op_decl)s; 81 %(op_rd)s; 82 %(ea_code)s; 83 84 if (fault == NoFault) { 85 fault = readMemAtomic(xc, traceData, EA, Mem, memAccessFlags); 86 } 87 88 if (fault == NoFault) { 89 %(memacc_code)s; 90 %(op_wb)s; 91 } 92 93 return fault; 94 } 95}}; 96 97def template Store64Execute {{ 98 Fault %(class_name)s::execute(ExecContext *xc, 99 Trace::InstRecord *traceData) const 100 { 101 Addr EA; 102 Fault fault = NoFault; 103 104 %(op_decl)s; 105 %(op_rd)s; 106 %(ea_code)s; 107 108 if (fault == NoFault) { 109 %(memacc_code)s; 110 } 111 112 if (fault == NoFault) { 113 fault = writeMemAtomic(xc, traceData, Mem, EA, 114 memAccessFlags, NULL); 115 } 116 117 if (fault == NoFault) { 118 %(op_wb)s; 119 } 120 121 return fault; 122 } 123}}; 124 125def template Store64InitiateAcc {{ 126 Fault %(class_name)s::initiateAcc(ExecContext *xc, 127 Trace::InstRecord *traceData) const 128 { 129 Addr EA; 130 Fault fault = NoFault; 131 132 %(op_decl)s; 133 %(op_rd)s; 134 %(ea_code)s; 135 136 if (fault == NoFault) { 137 %(memacc_code)s; 138 } 139 140 if (fault == NoFault) { 141 fault = writeMemTiming(xc, traceData, Mem, EA, memAccessFlags, 142 NULL); 143 } 144 145 return fault; 146 } 147}}; 148 149def template StoreEx64Execute {{ 150 Fault %(class_name)s::execute(ExecContext *xc, 151 Trace::InstRecord *traceData) const 152 { 153 Addr EA; 154 Fault fault = NoFault; 155 156 %(op_decl)s; 157 %(op_rd)s; 158 %(ea_code)s; 159 160 if (fault == NoFault) { 161 %(memacc_code)s; 162 } 163 164 uint64_t writeResult = 0; 165 if (fault == NoFault) { 166 fault = writeMemAtomic(xc, traceData, Mem, EA, memAccessFlags, 167 &writeResult); 168 } 169 170 if (fault == NoFault) { 171 %(postacc_code)s; 172 } 173 174 if (fault == NoFault) { 175 %(op_wb)s; 176 } 177 178 return fault; 179 } 180}}; 181 182def template StoreEx64InitiateAcc {{ 183 Fault %(class_name)s::initiateAcc(ExecContext *xc, 184 Trace::InstRecord *traceData) const 185 { 186 Addr EA; 187 Fault fault = NoFault; 188 189 %(op_decl)s; 190 %(op_rd)s; 191 %(ea_code)s; 192 193 if (fault == NoFault) { 194 %(memacc_code)s; 195 } 196 197 if (fault == NoFault) { 198 fault = writeMemTiming(xc, traceData, Mem, EA, memAccessFlags, 199 NULL); 200 } 201 202 return fault; 203 } 204}}; 205 206def template Load64InitiateAcc {{ 207 Fault %(class_name)s::initiateAcc(ExecContext *xc, 208 Trace::InstRecord *traceData) const 209 { 210 Addr EA; 211 Fault fault = NoFault; 212 213 %(op_src_decl)s; 214 %(op_rd)s; 215 %(ea_code)s; 216 217 if (fault == NoFault) { 218 fault = initiateMemRead(xc, traceData, EA, Mem, memAccessFlags); 219 } 220 221 return fault; 222 } 223}}; 224 225def template Load64CompleteAcc {{ 226 Fault %(class_name)s::completeAcc(PacketPtr pkt, ExecContext *xc, 227 Trace::InstRecord *traceData) const 228 { 229 Fault fault = NoFault; 230 231 %(op_decl)s; 232 %(op_rd)s; 233 234 // ARM instructions will not have a pkt if the predicate is false 235 getMem(pkt, Mem, traceData); 236 237 if (fault == NoFault) { 238 %(memacc_code)s; 239 } 240 241 if (fault == NoFault) { 242 %(op_wb)s; 243 } 244 245 return fault; 246 } 247}}; 248 249def template Store64CompleteAcc {{ 250 Fault %(class_name)s::completeAcc(PacketPtr pkt, ExecContext *xc, 251 Trace::InstRecord *traceData) const 252 { 253 return NoFault; 254 } 255}}; 256 257def template StoreEx64CompleteAcc {{ 258 Fault %(class_name)s::completeAcc(PacketPtr pkt, ExecContext *xc, 259 Trace::InstRecord *traceData) const 260 { 261 Fault fault = NoFault; 262 263 %(op_decl)s; 264 %(op_rd)s; 265 266 uint64_t writeResult = pkt->req->getExtraData(); 267 %(postacc_code)s; 268 269 if (fault == NoFault) { 270 %(op_wb)s; 271 } 272 273 return fault; 274 } 275}}; 276 277def template DCStore64Declare {{ 278 class %(class_name)s : public %(base_class)s 279 { 280 public: 281 282 /// Constructor. 283 %(class_name)s(ExtMachInst machInst, IntRegIndex _base, 284 MiscRegIndex _dest, uint64_t _imm); 285 286 Fault execute(ExecContext *, Trace::InstRecord *) const override; 287 Fault initiateAcc(ExecContext *, Trace::InstRecord *) const override; 288 Fault completeAcc(PacketPtr, ExecContext *, 289 Trace::InstRecord *) const override; 290 291 void 292 annotateFault(ArmFault *fault) override 293 { 294 %(fa_code)s 295 } 296 }; 297}}; 298 299def template DCStore64Constructor {{ 300 %(class_name)s::%(class_name)s(ExtMachInst machInst, IntRegIndex _base, 301 MiscRegIndex _dest, uint64_t _imm) 302 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, 303 _base, _dest, _imm) 304 { 305 %(constructor)s; 306 assert(!%(use_uops)d); 307 } 308}}; 309 310def template DCStore64Execute {{ 311 Fault %(class_name)s::execute(ExecContext *xc, 312 Trace::InstRecord *traceData) const 313 { 314 Addr EA; 315 Fault fault = NoFault; 316 317 %(op_decl)s; 318 %(op_rd)s; 319 %(ea_code)s; 320 321 322 if (fault == NoFault) { 323 %(memacc_code)s; 324 } 325 326 if (fault == NoFault) { 327 fault = xc->writeMem(NULL, op_size, EA, memAccessFlags, NULL); 328 } 329 330 if (fault == NoFault) { 331 %(op_wb)s; 332 } 333 334 return fault; 335 } 336}}; 337 338def template DCStore64InitiateAcc {{ 339 Fault %(class_name)s::initiateAcc(ExecContext *xc, 340 Trace::InstRecord *traceData) const 341 { 342 Addr EA; 343 Fault fault = NoFault; 344 345 %(op_decl)s; 346 %(op_rd)s; 347 %(ea_code)s; 348 349 if (fault == NoFault) { 350 %(memacc_code)s; 351 } 352 353 if (fault == NoFault) { 354 fault = xc->writeMem(NULL, op_size, EA, memAccessFlags, NULL); 355 } 356 357 return fault; 358 } 359}}; 360 361 362def template LoadStoreImm64Declare {{ 363 class %(class_name)s : public %(base_class)s 364 { 365 public: 366 367 /// Constructor. 368 %(class_name)s(ExtMachInst machInst, 369 IntRegIndex _dest, IntRegIndex _base, int64_t _imm); 370 371 Fault execute(ExecContext *, Trace::InstRecord *) const override; 372 Fault initiateAcc(ExecContext *, Trace::InstRecord *) const override; 373 Fault completeAcc(PacketPtr, ExecContext *, 374 Trace::InstRecord *) const override; 375 376 void 377 annotateFault(ArmFault *fault) override 378 { 379 %(fa_code)s 380 } 381 }; 382}}; 383 384def template LoadStoreImmU64Declare {{ 385 class %(class_name)s : public %(base_class)s 386 { 387 public: 388 389 /// Constructor. 390 %(class_name)s(ExtMachInst machInst, 391 IntRegIndex _dest, IntRegIndex _base, int64_t _imm, 392 bool noAlloc = false, bool exclusive = false, 393 bool acrel = false); 394 395 Fault execute(ExecContext *, Trace::InstRecord *) const override; 396 Fault initiateAcc(ExecContext *, Trace::InstRecord *) const override; 397 Fault completeAcc(PacketPtr, ExecContext *, 398 Trace::InstRecord *) const override; 399 400 void 401 annotateFault(ArmFault *fault) override 402 { 403 %(fa_code)s 404 } 405 }; 406}}; 407 408def template LoadStoreImmDU64Declare {{ 409 class %(class_name)s : public %(base_class)s 410 { 411 public: 412 413 /// Constructor. 414 %(class_name)s(ExtMachInst machInst, 415 IntRegIndex _dest, IntRegIndex _dest2, IntRegIndex _base, 416 int64_t _imm = 0, bool noAlloc = false, bool exclusive = false, 417 bool acrel = false); 418 419 Fault execute(ExecContext *, Trace::InstRecord *) const override; 420 Fault initiateAcc(ExecContext *, Trace::InstRecord *) const override; 421 Fault completeAcc(PacketPtr, ExecContext *, 422 Trace::InstRecord *) const override; 423 424 void 425 annotateFault(ArmFault *fault) override 426 { 427 %(fa_code)s 428 } 429 }; 430}}; 431 432def template StoreImmDEx64Declare {{ 433 /** 434 * Static instruction class for "%(mnemonic)s". 435 */ 436 class %(class_name)s : public %(base_class)s 437 { 438 public: 439 440 /// Constructor. 441 %(class_name)s(ExtMachInst machInst, 442 IntRegIndex _result, IntRegIndex _dest, IntRegIndex _dest2, 443 IntRegIndex _base, int64_t _imm = 0); 444 445 Fault execute(ExecContext *, Trace::InstRecord *) const override; 446 Fault initiateAcc(ExecContext *, Trace::InstRecord *) const override; 447 Fault completeAcc(PacketPtr, ExecContext *, 448 Trace::InstRecord *) const override; 449 }; 450}}; 451 452 453def template LoadStoreReg64Declare {{ 454 class %(class_name)s : public %(base_class)s 455 { 456 public: 457 458 /// Constructor. 459 %(class_name)s(ExtMachInst machInst, 460 IntRegIndex _dest, IntRegIndex _base, IntRegIndex _offset, 461 ArmExtendType _type, uint32_t _shiftAmt); 462 463 Fault execute(ExecContext *, Trace::InstRecord *) const override; 464 Fault initiateAcc(ExecContext *, Trace::InstRecord *) const override; 465 Fault completeAcc(PacketPtr, ExecContext *, 466 Trace::InstRecord *) const override; 467 468 void 469 annotateFault(ArmFault *fault) override 470 { 471 %(fa_code)s 472 } 473 }; 474}}; 475 476def template LoadStoreRegU64Declare {{ 477 class %(class_name)s : public %(base_class)s 478 { 479 public: 480 481 /// Constructor. 482 %(class_name)s(ExtMachInst machInst, 483 IntRegIndex _dest, IntRegIndex _base, IntRegIndex _offset, 484 ArmExtendType _type, uint32_t _shiftAmt, 485 bool noAlloc = false, bool exclusive = false, 486 bool acrel = false); 487 488 Fault execute(ExecContext *, Trace::InstRecord *) const override; 489 Fault initiateAcc(ExecContext *, Trace::InstRecord *) const override; 490 Fault completeAcc(PacketPtr, ExecContext *, 491 Trace::InstRecord *) const override; 492 493 void 494 annotateFault(ArmFault *fault) override 495 { 496 %(fa_code)s 497 } 498 }; 499}}; 500 501def template LoadStoreRaw64Declare {{ 502 class %(class_name)s : public %(base_class)s 503 { 504 public: 505 506 /// Constructor. 507 %(class_name)s(ExtMachInst machInst, IntRegIndex _dest, 508 IntRegIndex _base); 509 510 Fault execute(ExecContext *, Trace::InstRecord *) const override; 511 Fault initiateAcc(ExecContext *, Trace::InstRecord *) const override; 512 Fault completeAcc(PacketPtr, ExecContext *, 513 Trace::InstRecord *) const override; 514 515 void 516 annotateFault(ArmFault *fault) override 517 { 518 %(fa_code)s 519 } 520 }; 521}}; 522 523def template LoadStoreEx64Declare {{ 524 class %(class_name)s : public %(base_class)s 525 { 526 public: 527 528 /// Constructor. 529 %(class_name)s(ExtMachInst machInst, IntRegIndex _dest, 530 IntRegIndex _base, IntRegIndex _result); 531 532 Fault execute(ExecContext *, Trace::InstRecord *) const override; 533 Fault initiateAcc(ExecContext *, Trace::InstRecord *) const override; 534 Fault completeAcc(PacketPtr, ExecContext *, 535 Trace::InstRecord *) const override; 536 537 void 538 annotateFault(ArmFault *fault) override 539 { 540 %(fa_code)s 541 } 542 }; 543}}; 544 545def template LoadStoreLit64Declare {{ 546 class %(class_name)s : public %(base_class)s 547 { 548 public: 549 550 /// Constructor. 551 %(class_name)s(ExtMachInst machInst, IntRegIndex _dest, int64_t _imm); 552 553 Fault execute(ExecContext *, Trace::InstRecord *) const override; 554 Fault initiateAcc(ExecContext *, Trace::InstRecord *) const override; 555 Fault completeAcc(PacketPtr, ExecContext *, 556 Trace::InstRecord *) const override; 557 558 void 559 annotateFault(ArmFault *fault) override 560 { 561 %(fa_code)s 562 } 563 }; 564}}; 565 566def template LoadStoreLitU64Declare {{ 567 class %(class_name)s : public %(base_class)s 568 { 569 public: 570 571 /// Constructor. 572 %(class_name)s(ExtMachInst machInst, IntRegIndex _dest, int64_t _imm, 573 bool noAlloc = false, bool exclusive = false, 574 bool acrel = false); 575 576 Fault execute(ExecContext *, Trace::InstRecord *) const override; 577 Fault initiateAcc(ExecContext *, Trace::InstRecord *) const override; 578 Fault completeAcc(PacketPtr, ExecContext *, 579 Trace::InstRecord *) const override; 580 581 void 582 annotateFault(ArmFault *fault) override 583 { 584 %(fa_code)s 585 } 586 }; 587}}; 588 589def template LoadStoreImm64Constructor {{ 590 %(class_name)s::%(class_name)s(ExtMachInst machInst, 591 IntRegIndex _dest, IntRegIndex _base, int64_t _imm) 592 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, 593 (IntRegIndex)_dest, (IntRegIndex)_base, _imm) 594 { 595 %(constructor)s; 596#if %(use_uops)d 597 assert(numMicroops >= 2); 598 uops = new StaticInstPtr[numMicroops]; 599 uops[0] = new %(acc_name)s(machInst, _dest, _base, _imm); 600 uops[0]->setDelayedCommit(); 601 uops[0]->setFirstMicroop(); 602 uops[1] = new %(wb_decl)s; 603 uops[1]->setLastMicroop(); 604#endif 605 } 606}}; 607 608def template LoadStoreImmU64Constructor {{ 609 %(class_name)s::%(class_name)s(ExtMachInst machInst, 610 IntRegIndex _dest, IntRegIndex _base, int64_t _imm, 611 bool noAlloc, bool exclusive, bool acrel) 612 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, 613 _dest, _base, _imm) 614 { 615 %(constructor)s; 616 assert(!%(use_uops)d); 617 setExcAcRel(exclusive, acrel); 618 } 619}}; 620 621def template LoadStoreImmDU64Constructor {{ 622 %(class_name)s::%(class_name)s(ExtMachInst machInst, 623 IntRegIndex _dest, IntRegIndex _dest2, IntRegIndex _base, 624 int64_t _imm, bool noAlloc, bool exclusive, bool acrel) 625 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, 626 _dest, _dest2, _base, _imm) 627 { 628 %(constructor)s; 629 assert(!%(use_uops)d); 630 setExcAcRel(exclusive, acrel); 631 } 632}}; 633 634def template StoreImmDEx64Constructor {{ 635 %(class_name)s::%(class_name)s(ExtMachInst machInst, 636 IntRegIndex _result, IntRegIndex _dest, IntRegIndex _dest2, 637 IntRegIndex _base, int64_t _imm) 638 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, 639 _result, _dest, _dest2, _base, _imm) 640 { 641 %(constructor)s; 642 assert(!%(use_uops)d); 643 } 644}}; 645 646 647def template LoadStoreReg64Constructor {{ 648 %(class_name)s::%(class_name)s(ExtMachInst machInst, 649 IntRegIndex _dest, IntRegIndex _base, IntRegIndex _offset, 650 ArmExtendType _type, uint32_t _shiftAmt) 651 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, 652 _dest, _base, _offset, _type, _shiftAmt) 653 { 654 %(constructor)s; 655#if %(use_uops)d 656 assert(numMicroops >= 2); 657 uops = new StaticInstPtr[numMicroops]; 658 uops[0] = new %(acc_name)s(machInst, _dest, _base, _offset, 659 _type, _shiftAmt); 660 uops[0]->setDelayedCommit(); 661 uops[0]->setFirstMicroop(); 662 uops[1] = new %(wb_decl)s; 663 uops[1]->setLastMicroop(); 664#endif 665 } 666}}; 667 668def template LoadStoreRegU64Constructor {{ 669 %(class_name)s::%(class_name)s(ExtMachInst machInst, 670 IntRegIndex _dest, IntRegIndex _base, IntRegIndex _offset, 671 ArmExtendType _type, uint32_t _shiftAmt, 672 bool noAlloc, bool exclusive, bool acrel) 673 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, 674 _dest, _base, _offset, _type, _shiftAmt) 675 { 676 %(constructor)s; 677 assert(!%(use_uops)d); 678 setExcAcRel(exclusive, acrel); 679 } 680}}; 681 682def template LoadStoreRaw64Constructor {{ 683 %(class_name)s::%(class_name)s(ExtMachInst machInst, 684 IntRegIndex _dest, IntRegIndex _base) 685 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, _dest, _base) 686 { 687 %(constructor)s; 688 } 689}}; 690 691def template LoadStoreEx64Constructor {{ 692 %(class_name)s::%(class_name)s(ExtMachInst machInst, 693 IntRegIndex _dest, IntRegIndex _base, IntRegIndex _result) 694 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, 695 _dest, _base, _result) 696 { 697 %(constructor)s; 698 } 699}}; 700 701def template LoadStoreLit64Constructor {{ 702 %(class_name)s::%(class_name)s(ExtMachInst machInst, 703 IntRegIndex _dest, int64_t _imm) 704 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, 705 (IntRegIndex)_dest, _imm) 706 { 707 %(constructor)s; 708#if %(use_uops)d 709 assert(numMicroops >= 2); 710 uops = new StaticInstPtr[numMicroops]; 711 uops[0] = new %(acc_name)s(machInst, _dest, _imm); 712 uops[0]->setDelayedCommit(); 713 uops[0]->setFirstMicroop(); 714 uops[1] = new %(wb_decl)s; 715 uops[1]->setLastMicroop(); 716#endif 717 } 718}}; 719 720def template LoadStoreLitU64Constructor {{ 721 %(class_name)s::%(class_name)s(ExtMachInst machInst, 722 IntRegIndex _dest, int64_t _imm, 723 bool noAlloc, bool exclusive, bool acrel) 724 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, 725 (IntRegIndex)_dest, _imm) 726 { 727 %(constructor)s; 728 assert(!%(use_uops)d); 729 setExcAcRel(exclusive, acrel); 730 } 731}}; 732 733// Atomic operations in memory 734 735def template AmoOpExecute {{ 736 Fault %(class_name)s::execute(ExecContext *xc, 737 Trace::InstRecord *traceData) const 738 { 739 Addr EA; 740 Fault fault = NoFault; 741 742 %(op_decl)s; 743 %(op_rd)s; 744 %(ea_code)s; 745 746 %(usrDecl)s; 747 if (fault == NoFault) { 748 %(memacc_code)s; 749 } 750 751 %(amo_code)s 752 assert(amo_op); 753 754 if (fault == NoFault) { 755 fault = amoMemAtomic(xc, traceData, Mem, EA, 756 memAccessFlags, amo_op); 757 } 758 759 if (fault == NoFault) { 760 %(postacc_code)s; 761 } 762 763 if (fault == NoFault) { 764 %(op_wb)s; 765 } 766 767 return fault; 768 } 769}}; 770 771def template AmoOpInitiateAcc {{ 772 Fault %(class_name)s::initiateAcc(ExecContext *xc, 773 Trace::InstRecord *traceData) const 774 { 775 Addr EA; 776 Fault fault = NoFault; 777 778 %(op_src_decl)s; 779 %(op_rd)s; 780 %(ea_code)s; 781 %(usrDecl)s; 782 783 if (fault == NoFault) { 784 %(memacc_code)s; 785 } 786 787 %(amo_code)s; 788 789 assert(amo_op); 790 if (fault == NoFault) { 791 fault = initiateMemAMO(xc, traceData, EA, Mem, memAccessFlags, 792 amo_op); 793 } 794 795 return fault; 796 } 797}}; 798 799def template AmoOpCompleteAcc {{ 800 Fault %(class_name)s::completeAcc(PacketPtr pkt, ExecContext *xc, 801 Trace::InstRecord *traceData) const 802 { 803 Fault fault = NoFault; 804 805 %(op_decl)s; 806 %(op_rd)s; 807 808 // ARM instructions will not have a pkt if the predicate is false 809 getMem(pkt, Mem, traceData); 810 811 if (fault == NoFault) { 812 %(postacc_code)s; 813 } 814 815 if (fault == NoFault) { 816 %(op_wb)s; 817 } 818 819 return fault; 820 } 821 822}}; 823 824def template AmoOpDeclare {{ 825 class %(class_name)s : public %(base_class)s 826 { 827 public: 828 829 /// Constructor. 830 %(class_name)s(ExtMachInst machInst, IntRegIndex _dest, 831 IntRegIndex _base, IntRegIndex _result); 832 833 Fault execute(ExecContext *, Trace::InstRecord *) const override; 834 Fault initiateAcc(ExecContext *, Trace::InstRecord *) const override; 835 Fault completeAcc(PacketPtr, ExecContext *, 836 Trace::InstRecord *) const override; 837 838 void 839 annotateFault(ArmFault *fault) override 840 { 841 %(fa_code)s 842 } 843 }; 844}}; 845 846 847def template AmoOpConstructor {{ 848 %(class_name)s::%(class_name)s(ExtMachInst machInst, 849 IntRegIndex _dest, IntRegIndex _base, IntRegIndex _result) 850 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, 851 _dest, _base, _result) 852 { 853 %(constructor)s; 854 flags[IsStore] = false; 855 flags[IsLoad] = false; 856 } 857}}; 858 859def template AmoPairOpDeclare {{ 860 class %(class_name)s : public %(base_class)s 861 { 862 public: 863 uint32_t d2_src ; 864 uint32_t r2_src ; 865 uint32_t r2_dst ; 866 /// Constructor. 867 %(class_name)s(ExtMachInst machInst, IntRegIndex _dest, 868 IntRegIndex _base, IntRegIndex _result); 869 870 Fault execute(ExecContext *, Trace::InstRecord *) const override; 871 Fault initiateAcc(ExecContext *, Trace::InstRecord *) const override; 872 Fault completeAcc(PacketPtr, ExecContext *, 873 Trace::InstRecord *) const override; 874 875 void 876 annotateFault(ArmFault *fault) override 877 { 878 %(fa_code)s 879 } 880 }; 881}}; 882 883 884def template AmoPairOpConstructor {{ 885 %(class_name)s::%(class_name)s(ExtMachInst machInst, 886 IntRegIndex _dest, IntRegIndex _base, IntRegIndex _result) 887 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, 888 _dest, _base, _result) 889 { 890 %(constructor)s; 891 892 uint32_t d2 = RegId(IntRegClass, dest).index() + 1 ; 893 uint32_t r2 = RegId(IntRegClass, result).index() + 1 ; 894 895 d2_src = _numSrcRegs ; 896 _srcRegIdx[_numSrcRegs++] = RegId(IntRegClass, d2); 897 r2_src = _numSrcRegs ; 898 _srcRegIdx[_numSrcRegs++] = RegId(IntRegClass, r2); 899 r2_dst = _numDestRegs ; 900 _destRegIdx[_numDestRegs++] = RegId(IntRegClass, r2); 901 flags[IsStore] = false; 902 flags[IsLoad] = false; 903 } 904}}; 905 906def template AmoArithmeticOpDeclare {{ 907 class %(class_name)s : public %(base_class)s 908 { 909 public: 910 bool isXZR ; 911 /// Constructor. 912 %(class_name)s(ExtMachInst machInst, IntRegIndex _dest, 913 IntRegIndex _base, IntRegIndex _result); 914 915 Fault execute(ExecContext *, Trace::InstRecord *) const override; 916 Fault initiateAcc(ExecContext *, Trace::InstRecord *) const override; 917 Fault completeAcc(PacketPtr, ExecContext *, 918 Trace::InstRecord *) const override; 919 920 void 921 annotateFault(ArmFault *fault) override 922 { 923 %(fa_code)s 924 } 925 }; 926}}; 927 928def template AmoArithmeticOpConstructor {{ 929 %(class_name)s::%(class_name)s(ExtMachInst machInst, 930 IntRegIndex _dest, IntRegIndex _base, IntRegIndex _result) 931 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, 932 _dest, _base, _result) 933 { 934 %(constructor)s; 935 isXZR = false; 936 uint32_t r2 = RegId(IntRegClass, dest).index() ; 937 flags[IsStore] = false; 938 flags[IsLoad] = false; 939 if (r2 == 31){ 940 isXZR = true; 941 } 942 } 943}}; 944