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