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