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