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