mem.isa revision 7597:063f160e8b50
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 SwapExecute {{ 45 Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, 46 Trace::InstRecord *traceData) const 47 { 48 Addr EA; 49 Fault fault = NoFault; 50 51 %(op_decl)s; 52 uint64_t memData = 0; 53 %(op_rd)s; 54 %(ea_code)s; 55 56 if (%(predicate_test)s) 57 { 58 %(preacc_code)s; 59 60 if (fault == NoFault) { 61 fault = xc->write((uint%(mem_acc_size)d_t&)Mem, 62 EA, memAccessFlags, &memData); 63 } 64 65 if (fault == NoFault) { 66 %(postacc_code)s; 67 } 68 69 if (fault == NoFault) { 70 %(op_wb)s; 71 } 72 } else { 73 xc->setPredicate(false); 74 } 75 76 if (fault == NoFault && machInst.itstateMask != 0) { 77 xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate); 78 } 79 80 return fault; 81 } 82}}; 83 84def template SwapInitiateAcc {{ 85 Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc, 86 Trace::InstRecord *traceData) const 87 { 88 Addr EA; 89 Fault fault = NoFault; 90 91 %(op_decl)s; 92 uint64_t memData = 0; 93 %(op_rd)s; 94 %(ea_code)s; 95 96 if (%(predicate_test)s) 97 { 98 %(preacc_code)s; 99 100 if (fault == NoFault) { 101 fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA, 102 memAccessFlags, &memData); 103 } 104 105 if (fault == NoFault) { 106 %(op_wb)s; 107 } 108 } else { 109 xc->setPredicate(false); 110 } 111 112 if (fault == NoFault && machInst.itstateMask != 0) { 113 xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate); 114 } 115 116 return fault; 117 } 118}}; 119 120def template SwapCompleteAcc {{ 121 Fault %(class_name)s::completeAcc(PacketPtr pkt, 122 %(CPU_exec_context)s *xc, 123 Trace::InstRecord *traceData) const 124 { 125 Fault fault = NoFault; 126 127 %(op_decl)s; 128 %(op_rd)s; 129 130 if (%(predicate_test)s) 131 { 132 // ARM instructions will not have a pkt if the predicate is false 133 uint64_t memData = pkt->get<typeof(Mem)>(); 134 135 %(postacc_code)s; 136 137 if (fault == NoFault) { 138 %(op_wb)s; 139 } 140 } 141 142 if (fault == NoFault && machInst.itstateMask != 0) { 143 xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate); 144 } 145 146 return fault; 147 } 148}}; 149 150def template LoadExecute {{ 151 Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, 152 Trace::InstRecord *traceData) const 153 { 154 Addr EA; 155 Fault fault = NoFault; 156 157 %(op_decl)s; 158 %(op_rd)s; 159 %(ea_code)s; 160 161 if (%(predicate_test)s) 162 { 163 if (fault == NoFault) { 164 fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags); 165 %(memacc_code)s; 166 } 167 168 if (fault == NoFault) { 169 %(op_wb)s; 170 } 171 } else { 172 xc->setPredicate(false); 173 } 174 175 if (fault == NoFault && machInst.itstateMask != 0) { 176 xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate); 177 } 178 179 return fault; 180 } 181}}; 182 183def template StoreExecute {{ 184 Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, 185 Trace::InstRecord *traceData) const 186 { 187 Addr EA; 188 Fault fault = NoFault; 189 190 %(op_decl)s; 191 %(op_rd)s; 192 %(ea_code)s; 193 194 if (%(predicate_test)s) 195 { 196 if (fault == NoFault) { 197 %(memacc_code)s; 198 } 199 200 if (fault == NoFault) { 201 fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA, 202 memAccessFlags, NULL); 203 if (traceData) { traceData->setData(Mem); } 204 } 205 206 if (fault == NoFault) { 207 %(op_wb)s; 208 } 209 } else { 210 xc->setPredicate(false); 211 } 212 213 if (fault == NoFault && machInst.itstateMask != 0) { 214 xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate); 215 } 216 217 return fault; 218 } 219}}; 220 221def template StoreExExecute {{ 222 Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, 223 Trace::InstRecord *traceData) const 224 { 225 Addr EA; 226 Fault fault = NoFault; 227 228 %(op_decl)s; 229 %(op_rd)s; 230 %(ea_code)s; 231 232 if (%(predicate_test)s) 233 { 234 if (fault == NoFault) { 235 %(memacc_code)s; 236 } 237 238 uint64_t writeResult; 239 240 if (fault == NoFault) { 241 fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA, 242 memAccessFlags, &writeResult); 243 if (traceData) { traceData->setData(Mem); } 244 } 245 246 if (fault == NoFault) { 247 %(postacc_code)s; 248 } 249 250 if (fault == NoFault) { 251 %(op_wb)s; 252 } 253 } else { 254 xc->setPredicate(false); 255 } 256 257 if (fault == NoFault && machInst.itstateMask != 0) { 258 xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate); 259 } 260 261 return fault; 262 } 263}}; 264 265def template StoreExInitiateAcc {{ 266 Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc, 267 Trace::InstRecord *traceData) const 268 { 269 Addr EA; 270 Fault fault = NoFault; 271 272 %(op_decl)s; 273 %(op_rd)s; 274 %(ea_code)s; 275 276 if (%(predicate_test)s) 277 { 278 if (fault == NoFault) { 279 %(memacc_code)s; 280 } 281 282 if (fault == NoFault) { 283 fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA, 284 memAccessFlags, NULL); 285 if (traceData) { traceData->setData(Mem); } 286 } 287 288 // Need to write back any potential address register update 289 if (fault == NoFault) { 290 %(op_wb)s; 291 } 292 } else { 293 xc->setPredicate(false); 294 } 295 296 if (fault == NoFault && machInst.itstateMask != 0) { 297 xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate); 298 } 299 300 return fault; 301 } 302}}; 303 304def template StoreInitiateAcc {{ 305 Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc, 306 Trace::InstRecord *traceData) const 307 { 308 Addr EA; 309 Fault fault = NoFault; 310 311 %(op_decl)s; 312 %(op_rd)s; 313 %(ea_code)s; 314 315 if (%(predicate_test)s) 316 { 317 if (fault == NoFault) { 318 %(memacc_code)s; 319 } 320 321 if (fault == NoFault) { 322 fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA, 323 memAccessFlags, NULL); 324 if (traceData) { traceData->setData(Mem); } 325 } 326 327 // Need to write back any potential address register update 328 if (fault == NoFault) { 329 %(op_wb)s; 330 } 331 } else { 332 xc->setPredicate(false); 333 } 334 335 if (fault == NoFault && machInst.itstateMask != 0) { 336 xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate); 337 } 338 339 return fault; 340 } 341}}; 342 343def template LoadInitiateAcc {{ 344 Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc, 345 Trace::InstRecord *traceData) const 346 { 347 Addr EA; 348 Fault fault = NoFault; 349 350 %(op_src_decl)s; 351 %(op_rd)s; 352 %(ea_code)s; 353 354 if (%(predicate_test)s) 355 { 356 if (fault == NoFault) { 357 fault = xc->read(EA, (uint%(mem_acc_size)d_t &)Mem, memAccessFlags); 358 } 359 } else { 360 xc->setPredicate(false); 361 if (fault == NoFault && machInst.itstateMask != 0) { 362 xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate); 363 } 364 } 365 366 return fault; 367 } 368}}; 369 370def template LoadCompleteAcc {{ 371 Fault %(class_name)s::completeAcc(PacketPtr pkt, 372 %(CPU_exec_context)s *xc, 373 Trace::InstRecord *traceData) const 374 { 375 Fault fault = NoFault; 376 377 %(op_decl)s; 378 %(op_rd)s; 379 380 if (%(predicate_test)s) 381 { 382 // ARM instructions will not have a pkt if the predicate is false 383 Mem = pkt->get<typeof(Mem)>(); 384 385 if (fault == NoFault) { 386 %(memacc_code)s; 387 } 388 389 if (fault == NoFault) { 390 %(op_wb)s; 391 } 392 } 393 394 if (fault == NoFault && machInst.itstateMask != 0) { 395 xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate); 396 } 397 398 return fault; 399 } 400}}; 401 402def template StoreCompleteAcc {{ 403 Fault %(class_name)s::completeAcc(PacketPtr pkt, 404 %(CPU_exec_context)s *xc, 405 Trace::InstRecord *traceData) const 406 { 407 Fault fault = NoFault; 408 409 %(op_decl)s; 410 %(op_rd)s; 411 412 if (%(predicate_test)s) 413 { 414 if (fault == NoFault) { 415 %(op_wb)s; 416 } 417 } 418 419 if (fault == NoFault && machInst.itstateMask != 0) { 420 xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate); 421 } 422 423 return fault; 424 } 425}}; 426 427def template StoreExCompleteAcc {{ 428 Fault %(class_name)s::completeAcc(PacketPtr pkt, 429 %(CPU_exec_context)s *xc, 430 Trace::InstRecord *traceData) const 431 { 432 Fault fault = NoFault; 433 434 %(op_decl)s; 435 %(op_rd)s; 436 437 if (%(predicate_test)s) 438 { 439 uint64_t writeResult = pkt->req->getExtraData(); 440 %(postacc_code)s; 441 442 if (fault == NoFault) { 443 %(op_wb)s; 444 } 445 } 446 447 if (fault == NoFault && machInst.itstateMask != 0) { 448 xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate); 449 } 450 451 return fault; 452 } 453}}; 454 455def template RfeDeclare {{ 456 /** 457 * Static instruction class for "%(mnemonic)s". 458 */ 459 class %(class_name)s : public %(base_class)s 460 { 461 public: 462 463 /// Constructor. 464 %(class_name)s(ExtMachInst machInst, 465 uint32_t _base, int _mode, bool _wb); 466 467 %(BasicExecDeclare)s 468 469 %(InitiateAccDeclare)s 470 471 %(CompleteAccDeclare)s 472 }; 473}}; 474 475def template SrsDeclare {{ 476 /** 477 * Static instruction class for "%(mnemonic)s". 478 */ 479 class %(class_name)s : public %(base_class)s 480 { 481 public: 482 483 /// Constructor. 484 %(class_name)s(ExtMachInst machInst, 485 uint32_t _regMode, int _mode, bool _wb); 486 487 %(BasicExecDeclare)s 488 489 %(InitiateAccDeclare)s 490 491 %(CompleteAccDeclare)s 492 }; 493}}; 494 495def template SwapDeclare {{ 496 /** 497 * Static instruction class for "%(mnemonic)s". 498 */ 499 class %(class_name)s : public %(base_class)s 500 { 501 public: 502 503 /// Constructor. 504 %(class_name)s(ExtMachInst machInst, 505 uint32_t _dest, uint32_t _op1, uint32_t _base); 506 507 %(BasicExecDeclare)s 508 509 %(InitiateAccDeclare)s 510 511 %(CompleteAccDeclare)s 512 }; 513}}; 514 515def template LoadStoreDImmDeclare {{ 516 /** 517 * Static instruction class for "%(mnemonic)s". 518 */ 519 class %(class_name)s : public %(base_class)s 520 { 521 public: 522 523 /// Constructor. 524 %(class_name)s(ExtMachInst machInst, 525 uint32_t _dest, uint32_t _dest2, 526 uint32_t _base, bool _add, int32_t _imm); 527 528 %(BasicExecDeclare)s 529 530 %(InitiateAccDeclare)s 531 532 %(CompleteAccDeclare)s 533 }; 534}}; 535 536def template StoreExDImmDeclare {{ 537 /** 538 * Static instruction class for "%(mnemonic)s". 539 */ 540 class %(class_name)s : public %(base_class)s 541 { 542 public: 543 544 /// Constructor. 545 %(class_name)s(ExtMachInst machInst, 546 uint32_t _result, uint32_t _dest, uint32_t _dest2, 547 uint32_t _base, bool _add, int32_t _imm); 548 549 %(BasicExecDeclare)s 550 551 %(InitiateAccDeclare)s 552 553 %(CompleteAccDeclare)s 554 }; 555}}; 556 557def template LoadStoreImmDeclare {{ 558 /** 559 * Static instruction class for "%(mnemonic)s". 560 */ 561 class %(class_name)s : public %(base_class)s 562 { 563 public: 564 565 /// Constructor. 566 %(class_name)s(ExtMachInst machInst, 567 uint32_t _dest, uint32_t _base, bool _add, int32_t _imm); 568 569 %(BasicExecDeclare)s 570 571 %(InitiateAccDeclare)s 572 573 %(CompleteAccDeclare)s 574 }; 575}}; 576 577def template StoreExImmDeclare {{ 578 /** 579 * Static instruction class for "%(mnemonic)s". 580 */ 581 class %(class_name)s : public %(base_class)s 582 { 583 public: 584 585 /// Constructor. 586 %(class_name)s(ExtMachInst machInst, 587 uint32_t _result, uint32_t _dest, uint32_t _base, 588 bool _add, int32_t _imm); 589 590 %(BasicExecDeclare)s 591 592 %(InitiateAccDeclare)s 593 594 %(CompleteAccDeclare)s 595 }; 596}}; 597 598def template LoadStoreDRegDeclare {{ 599 /** 600 * Static instruction class for "%(mnemonic)s". 601 */ 602 class %(class_name)s : public %(base_class)s 603 { 604 public: 605 606 /// Constructor. 607 %(class_name)s(ExtMachInst machInst, 608 uint32_t _dest, uint32_t _dest2, 609 uint32_t _base, bool _add, 610 int32_t _shiftAmt, uint32_t _shiftType, 611 uint32_t _index); 612 613 %(BasicExecDeclare)s 614 615 %(InitiateAccDeclare)s 616 617 %(CompleteAccDeclare)s 618 }; 619}}; 620 621def template LoadStoreRegDeclare {{ 622 /** 623 * Static instruction class for "%(mnemonic)s". 624 */ 625 class %(class_name)s : public %(base_class)s 626 { 627 public: 628 629 /// Constructor. 630 %(class_name)s(ExtMachInst machInst, 631 uint32_t _dest, uint32_t _base, bool _add, 632 int32_t _shiftAmt, uint32_t _shiftType, 633 uint32_t _index); 634 635 %(BasicExecDeclare)s 636 637 %(InitiateAccDeclare)s 638 639 %(CompleteAccDeclare)s 640 }; 641}}; 642 643def template InitiateAccDeclare {{ 644 Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const; 645}}; 646 647def template CompleteAccDeclare {{ 648 Fault completeAcc(PacketPtr, %(CPU_exec_context)s *, Trace::InstRecord *) const; 649}}; 650 651def template RfeConstructor {{ 652 inline %(class_name)s::%(class_name)s(ExtMachInst machInst, 653 uint32_t _base, int _mode, bool _wb) 654 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, 655 (IntRegIndex)_base, (AddrMode)_mode, _wb) 656 { 657 %(constructor)s; 658 } 659}}; 660 661def template SrsConstructor {{ 662 inline %(class_name)s::%(class_name)s(ExtMachInst machInst, 663 uint32_t _regMode, int _mode, bool _wb) 664 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, 665 (OperatingMode)_regMode, (AddrMode)_mode, _wb) 666 { 667 %(constructor)s; 668 } 669}}; 670 671def template SwapConstructor {{ 672 inline %(class_name)s::%(class_name)s(ExtMachInst machInst, 673 uint32_t _dest, uint32_t _op1, uint32_t _base) 674 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, 675 (IntRegIndex)_dest, (IntRegIndex)_op1, (IntRegIndex)_base) 676 { 677 %(constructor)s; 678 } 679}}; 680 681def template LoadStoreDImmConstructor {{ 682 inline %(class_name)s::%(class_name)s(ExtMachInst machInst, 683 uint32_t _dest, uint32_t _dest2, 684 uint32_t _base, bool _add, int32_t _imm) 685 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, 686 (IntRegIndex)_dest, (IntRegIndex)_dest2, 687 (IntRegIndex)_base, _add, _imm) 688 { 689 %(constructor)s; 690 } 691}}; 692 693def template StoreExDImmConstructor {{ 694 inline %(class_name)s::%(class_name)s(ExtMachInst machInst, 695 uint32_t _result, uint32_t _dest, uint32_t _dest2, 696 uint32_t _base, bool _add, int32_t _imm) 697 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, 698 (IntRegIndex)_result, 699 (IntRegIndex)_dest, (IntRegIndex)_dest2, 700 (IntRegIndex)_base, _add, _imm) 701 { 702 %(constructor)s; 703 } 704}}; 705 706def template LoadStoreImmConstructor {{ 707 inline %(class_name)s::%(class_name)s(ExtMachInst machInst, 708 uint32_t _dest, uint32_t _base, bool _add, int32_t _imm) 709 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, 710 (IntRegIndex)_dest, (IntRegIndex)_base, _add, _imm) 711 { 712 %(constructor)s; 713 } 714}}; 715 716def template StoreExImmConstructor {{ 717 inline %(class_name)s::%(class_name)s(ExtMachInst machInst, 718 uint32_t _result, uint32_t _dest, uint32_t _base, 719 bool _add, int32_t _imm) 720 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, 721 (IntRegIndex)_result, (IntRegIndex)_dest, 722 (IntRegIndex)_base, _add, _imm) 723 { 724 %(constructor)s; 725 } 726}}; 727 728def template LoadStoreDRegConstructor {{ 729 inline %(class_name)s::%(class_name)s(ExtMachInst machInst, 730 uint32_t _dest, uint32_t _dest2, uint32_t _base, bool _add, 731 int32_t _shiftAmt, uint32_t _shiftType, uint32_t _index) 732 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, 733 (IntRegIndex)_dest, (IntRegIndex)_dest2, 734 (IntRegIndex)_base, _add, 735 _shiftAmt, (ArmShiftType)_shiftType, 736 (IntRegIndex)_index) 737 { 738 %(constructor)s; 739 } 740}}; 741 742def template LoadStoreRegConstructor {{ 743 inline %(class_name)s::%(class_name)s(ExtMachInst machInst, 744 uint32_t _dest, uint32_t _base, bool _add, 745 int32_t _shiftAmt, uint32_t _shiftType, uint32_t _index) 746 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, 747 (IntRegIndex)_dest, (IntRegIndex)_base, _add, 748 _shiftAmt, (ArmShiftType)_shiftType, 749 (IntRegIndex)_index) 750 { 751 %(constructor)s; 752 } 753}}; 754