1// -*- mode:c++ -*- 2 3// Copyright (c) 2010-2014 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// Gabe Black 43 44//////////////////////////////////////////////////////////////////// 45// 46// Load/store microops 47// 48 49def template MicroMemDeclare {{ 50 class %(class_name)s : public %(base_class)s 51 { 52 public: 53 %(class_name)s(ExtMachInst machInst, 54 RegIndex _ura, RegIndex _urb, bool _up, 55 uint8_t _imm); 56 Fault execute(ExecContext *, Trace::InstRecord *) const override; 57 Fault initiateAcc(ExecContext *, Trace::InstRecord *) const override; 58 Fault completeAcc(PacketPtr, ExecContext *, 59 Trace::InstRecord *) const override; 60 }; 61}}; 62 63def template MicroMemConstructor {{ 64 %(class_name)s::%(class_name)s(ExtMachInst machInst, 65 RegIndex _ura, 66 RegIndex _urb, 67 bool _up, 68 uint8_t _imm) 69 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, 70 _ura, _urb, _up, _imm) 71 { 72 %(constructor)s; 73 if (!(condCode == COND_AL || condCode == COND_UC)) { 74 for (int x = 0; x < _numDestRegs; x++) { 75 _srcRegIdx[_numSrcRegs++] = _destRegIdx[x]; 76 } 77 } 78 } 79}}; 80 81 82def template MicroMemPairDeclare {{ 83 class %(class_name)s : public %(base_class)s 84 { 85 public: 86 %(class_name)s(ExtMachInst machInst, 87 RegIndex _dreg1, RegIndex _dreg2, RegIndex _base, 88 bool _up, uint8_t _imm); 89 Fault execute(ExecContext *, Trace::InstRecord *) const override; 90 Fault initiateAcc(ExecContext *, Trace::InstRecord *) const override; 91 Fault completeAcc(PacketPtr, ExecContext *, 92 Trace::InstRecord *) const override; 93 }; 94}}; 95 96def template MicroMemPairConstructor {{ 97 %(class_name)s::%(class_name)s(ExtMachInst machInst, 98 RegIndex _dreg1, 99 RegIndex _dreg2, 100 RegIndex _base, 101 bool _up, 102 uint8_t _imm) 103 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, 104 _dreg1, _dreg2, _base, _up, _imm) 105 { 106 %(constructor)s; 107 if (!(condCode == COND_AL || condCode == COND_UC)) { 108 for (int x = 0; x < _numDestRegs; x++) { 109 _srcRegIdx[_numSrcRegs++] = _destRegIdx[x]; 110 } 111 } 112 } 113}}; 114 115//////////////////////////////////////////////////////////////////// 116// 117// Neon load/store microops 118// 119 120def template MicroNeonMemDeclare {{ 121 template <class Element> 122 class %(class_name)s : public %(base_class)s 123 { 124 public: 125 %(class_name)s(ExtMachInst machInst, RegIndex _dest, 126 RegIndex _ura, uint32_t _imm, unsigned extraMemFlags) 127 : %(base_class)s("%(mnemonic)s", machInst, 128 %(op_class)s, _dest, _ura, _imm) 129 { 130 memAccessFlags |= extraMemFlags; 131 %(constructor)s; 132 if (!(condCode == COND_AL || condCode == COND_UC)) { 133 for (int x = 0; x < _numDestRegs; x++) { 134 _srcRegIdx[_numSrcRegs++] = _destRegIdx[x]; 135 } 136 } 137 } 138 139 Fault execute(ExecContext *, Trace::InstRecord *) const override; 140 Fault initiateAcc(ExecContext *, Trace::InstRecord *) const override; 141 Fault completeAcc(PacketPtr, ExecContext *, 142 Trace::InstRecord *) const override; 143 }; 144}}; 145 146//////////////////////////////////////////////////////////////////// 147// 148// PC = Integer(ura) 149// CPSR = Integer(urb) 150// 151 152def template MicroSetPCCPSRDeclare {{ 153 class %(class_name)s : public %(base_class)s 154 { 155 public: 156 %(class_name)s(ExtMachInst machInst, 157 IntRegIndex _ura, 158 IntRegIndex _urb, 159 IntRegIndex _urc); 160 Fault execute(ExecContext *, Trace::InstRecord *) const override; 161 }; 162}}; 163 164def template MicroSetPCCPSRConstructor {{ 165 %(class_name)s::%(class_name)s(ExtMachInst machInst, 166 IntRegIndex _ura, 167 IntRegIndex _urb, 168 IntRegIndex _urc) 169 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, 170 _ura, _urb, _urc) 171 { 172 %(constructor)s; 173 if (!(condCode == COND_AL || condCode == COND_UC)) { 174 flags[IsCondControl] = true; 175 for (int x = 0; x < _numDestRegs; x++) { 176 _srcRegIdx[_numSrcRegs++] = _destRegIdx[x]; 177 } 178 } else { 179 flags[IsUncondControl] = true; 180 } 181 } 182}}; 183 184//////////////////////////////////////////////////////////////////// 185// 186// Integer = Integer op Integer microops 187// 188 189def template MicroIntDeclare {{ 190 class %(class_name)s : public %(base_class)s 191 { 192 public: 193 %(class_name)s(ExtMachInst machInst, 194 RegIndex _ura, RegIndex _urb, RegIndex _urc); 195 Fault execute(ExecContext *, Trace::InstRecord *) const override; 196 }; 197}}; 198 199def template MicroIntConstructor {{ 200 %(class_name)s::%(class_name)s(ExtMachInst machInst, 201 RegIndex _ura, 202 RegIndex _urb, 203 RegIndex _urc) 204 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, 205 _ura, _urb, _urc) 206 { 207 %(constructor)s; 208 if (!(condCode == COND_AL || condCode == COND_UC)) { 209 for (int x = 0; x < _numDestRegs; x++) { 210 _srcRegIdx[_numSrcRegs++] = _destRegIdx[x]; 211 } 212 } 213 } 214}}; 215 216def template MicroNeonMemExecDeclare {{ 217 template 218 Fault %(class_name)s<%(targs)s>::execute( 219 ExecContext *, Trace::InstRecord *) const; 220 template 221 Fault %(class_name)s<%(targs)s>::initiateAcc( 222 ExecContext *, Trace::InstRecord *) const; 223 template 224 Fault %(class_name)s<%(targs)s>::completeAcc(PacketPtr, 225 ExecContext *, Trace::InstRecord *) const; 226}}; 227 228def template MicroNeonExecDeclare {{ 229 template 230 Fault %(class_name)s<%(targs)s>::execute( 231 ExecContext *, Trace::InstRecord *) const; 232}}; 233 234//////////////////////////////////////////////////////////////////// 235// 236// Neon (de)interlacing microops 237// 238 239def template MicroNeonMixDeclare {{ 240 template <class Element> 241 class %(class_name)s : public %(base_class)s 242 { 243 public: 244 %(class_name)s(ExtMachInst machInst, RegIndex _dest, RegIndex _op1, 245 uint8_t _step) : 246 %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, 247 _dest, _op1, _step) 248 { 249 %(constructor)s; 250 if (!(condCode == COND_AL || condCode == COND_UC)) { 251 for (int x = 0; x < _numDestRegs; x++) { 252 _srcRegIdx[_numSrcRegs++] = _destRegIdx[x]; 253 } 254 } 255 } 256 257 Fault execute(ExecContext *, Trace::InstRecord *) const override; 258 }; 259}}; 260 261def template MicroNeonMixExecute {{ 262 template <class Element> 263 Fault %(class_name)s<Element>::execute(ExecContext *xc, 264 Trace::InstRecord *traceData) const 265 { 266 Fault fault = NoFault; 267 uint64_t resTemp = 0; 268 resTemp = resTemp; 269 %(op_decl)s; 270 %(op_rd)s; 271 272 if (%(predicate_test)s) 273 { 274 %(code)s; 275 if (fault == NoFault) 276 { 277 %(op_wb)s; 278 } 279 } else { 280 xc->setPredicate(false); 281 } 282 283 return fault; 284 } 285}}; 286 287//////////////////////////////////////////////////////////////////// 288// 289// Neon (un)packing microops using a particular lane 290// 291 292def template MicroNeonMixLaneDeclare {{ 293 template <class Element> 294 class %(class_name)s : public %(base_class)s 295 { 296 public: 297 %(class_name)s(ExtMachInst machInst, RegIndex _dest, RegIndex _op1, 298 uint8_t _step, unsigned _lane) : 299 %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, 300 _dest, _op1, _step, _lane) 301 { 302 %(constructor)s; 303 if (!(condCode == COND_AL || condCode == COND_UC)) { 304 for (int x = 0; x < _numDestRegs; x++) { 305 _srcRegIdx[_numSrcRegs++] = _destRegIdx[x]; 306 } 307 } 308 } 309 310 Fault execute(ExecContext *, Trace::InstRecord *) const override; 311 }; 312}}; 313 314//////////////////////////////////////////////////////////////////// 315// 316// Integer = Integer 317// 318 319def template MicroIntMovDeclare {{ 320 class %(class_name)s : public %(base_class)s 321 { 322 public: 323 %(class_name)s(ExtMachInst machInst, 324 RegIndex _ura, RegIndex _urb); 325 Fault execute(ExecContext *, Trace::InstRecord *) const override; 326 }; 327}}; 328def template MicroIntMovConstructor {{ 329 %(class_name)s::%(class_name)s(ExtMachInst machInst, 330 RegIndex _ura, 331 RegIndex _urb) 332 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, 333 _ura, _urb) 334 { 335 %(constructor)s; 336 if (!(condCode == COND_AL || condCode == COND_UC)) { 337 for (int x = 0; x < _numDestRegs; x++) { 338 _srcRegIdx[_numSrcRegs++] = _destRegIdx[x]; 339 } 340 } 341 } 342}}; 343 344//////////////////////////////////////////////////////////////////// 345// 346// Integer = Integer op Immediate microops 347// 348 349def template MicroIntImmDeclare {{ 350 class %(class_name)s : public %(base_class)s 351 { 352 public: 353 %(class_name)s(ExtMachInst machInst, 354 RegIndex _ura, RegIndex _urb, 355 int32_t _imm); 356 Fault execute(ExecContext *, Trace::InstRecord *) const override; 357 }; 358}}; 359 360def template MicroIntImmConstructor {{ 361 %(class_name)s::%(class_name)s(ExtMachInst machInst, 362 RegIndex _ura, 363 RegIndex _urb, 364 int32_t _imm) 365 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, 366 _ura, _urb, _imm) 367 { 368 %(constructor)s; 369 if (!(condCode == COND_AL || condCode == COND_UC)) { 370 for (int x = 0; x < _numDestRegs; x++) { 371 _srcRegIdx[_numSrcRegs++] = _destRegIdx[x]; 372 } 373 } 374 } 375}}; 376 377def template MicroIntImmXConstructor {{ 378 %(class_name)s::%(class_name)s(ExtMachInst machInst, 379 RegIndex _ura, 380 RegIndex _urb, 381 int32_t _imm) 382 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, 383 _ura, _urb, _imm) 384 { 385 %(constructor)s; 386 } 387}}; 388 389def template MicroIntRegDeclare {{ 390 class %(class_name)s : public %(base_class)s 391 { 392 public: 393 %(class_name)s(ExtMachInst machInst, 394 RegIndex _ura, RegIndex _urb, RegIndex _urc, 395 int32_t _shiftAmt, ArmShiftType _shiftType); 396 Fault execute(ExecContext *, Trace::InstRecord *) const override; 397 }; 398}}; 399 400def template MicroIntXERegConstructor {{ 401 %(class_name)s::%(class_name)s(ExtMachInst machInst, 402 RegIndex _ura, RegIndex _urb, RegIndex _urc, 403 ArmExtendType _type, uint32_t _shiftAmt) 404 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, 405 _ura, _urb, _urc, _type, _shiftAmt) 406 { 407 %(constructor)s; 408 } 409}}; 410 411def template MicroIntXERegDeclare {{ 412 class %(class_name)s : public %(base_class)s 413 { 414 public: 415 %(class_name)s(ExtMachInst machInst, 416 RegIndex _ura, RegIndex _urb, RegIndex _urc, 417 ArmExtendType _type, uint32_t _shiftAmt); 418 Fault execute(ExecContext *, Trace::InstRecord *) const override; 419 }; 420}}; 421 422def template MicroIntRegConstructor {{ 423 %(class_name)s::%(class_name)s(ExtMachInst machInst, 424 RegIndex _ura, RegIndex _urb, RegIndex _urc, 425 int32_t _shiftAmt, ArmShiftType _shiftType) 426 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, 427 _ura, _urb, _urc, _shiftAmt, _shiftType) 428 { 429 %(constructor)s; 430 if (!(condCode == COND_AL || condCode == COND_UC)) { 431 for (int x = 0; x < _numDestRegs; x++) { 432 _srcRegIdx[_numSrcRegs++] = _destRegIdx[x]; 433 } 434 } 435 } 436}}; 437 438//////////////////////////////////////////////////////////////////// 439// 440// Macro Memory-format instructions 441// 442 443def template MacroMemDeclare {{ 444/** 445 * Static instructions class for a store multiple instruction 446 */ 447class %(class_name)s : public %(base_class)s 448{ 449 public: 450 // Constructor 451 %(class_name)s(ExtMachInst machInst, IntRegIndex rn, 452 bool index, bool up, bool user, bool writeback, bool load, 453 uint32_t reglist); 454}; 455}}; 456 457def template MacroMemConstructor {{ 458%(class_name)s::%(class_name)s(ExtMachInst machInst, IntRegIndex rn, 459 bool index, bool up, bool user, bool writeback, bool load, 460 uint32_t reglist) 461 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, rn, 462 index, up, user, writeback, load, reglist) 463{ 464 %(constructor)s; 465 if (!(condCode == COND_AL || condCode == COND_UC)) { 466 for (int x = 0; x < _numDestRegs; x++) { 467 _srcRegIdx[_numSrcRegs++] = _destRegIdx[x]; 468 } 469 } 470} 471 472}}; 473 474def template BigFpMemImmDeclare {{ 475class %(class_name)s : public %(base_class)s 476{ 477 public: 478 // Constructor 479 %(class_name)s(const char *mnemonic, ExtMachInst machInst, 480 bool load, IntRegIndex dest, IntRegIndex base, int64_t imm); 481}; 482}}; 483 484def template BigFpMemImmConstructor {{ 485%(class_name)s::%(class_name)s(const char *mnemonic, ExtMachInst machInst, 486 bool load, IntRegIndex dest, IntRegIndex base, int64_t imm) 487 : %(base_class)s(mnemonic, machInst, %(op_class)s, load, dest, base, imm) 488{ 489 %(constructor)s; 490} 491}}; 492 493def template BigFpMemRegDeclare {{ 494class %(class_name)s : public %(base_class)s 495{ 496 public: 497 // Constructor 498 %(class_name)s(const char *mnemonic, ExtMachInst machInst, 499 bool load, IntRegIndex dest, IntRegIndex base, 500 IntRegIndex offset, ArmExtendType type, int64_t imm); 501}; 502}}; 503 504def template BigFpMemRegConstructor {{ 505%(class_name)s::%(class_name)s(const char *mnemonic, ExtMachInst machInst, 506 bool load, IntRegIndex dest, IntRegIndex base, 507 IntRegIndex offset, ArmExtendType type, int64_t imm) 508 : %(base_class)s(mnemonic, machInst, %(op_class)s, load, dest, base, 509 offset, type, imm) 510{ 511 %(constructor)s; 512} 513}}; 514 515def template BigFpMemLitDeclare {{ 516class %(class_name)s : public %(base_class)s 517{ 518 public: 519 // Constructor 520 %(class_name)s(const char *mnemonic, ExtMachInst machInst, 521 IntRegIndex dest, int64_t imm); 522}; 523}}; 524 525def template BigFpMemLitConstructor {{ 526%(class_name)s::%(class_name)s(const char *mnemonic, ExtMachInst machInst, 527 IntRegIndex dest, int64_t imm) 528 : %(base_class)s(mnemonic, machInst, %(op_class)s, dest, imm) 529{ 530 %(constructor)s; 531} 532}}; 533 534def template PairMemDeclare {{ 535class %(class_name)s : public %(base_class)s 536{ 537 public: 538 // Constructor 539 %(class_name)s(const char *mnemonic, ExtMachInst machInst, 540 uint32_t size, bool fp, bool load, bool noAlloc, bool signExt, 541 bool exclusive, bool acrel, uint32_t imm, 542 AddrMode mode, IntRegIndex rn, IntRegIndex rt, 543 IntRegIndex rt2); 544}; 545}}; 546 547def template PairMemConstructor {{ 548%(class_name)s::%(class_name)s(const char *mnemonic, ExtMachInst machInst, 549 uint32_t size, bool fp, bool load, bool noAlloc, bool signExt, 550 bool exclusive, bool acrel, uint32_t imm, AddrMode mode, 551 IntRegIndex rn, IntRegIndex rt, IntRegIndex rt2) 552 : %(base_class)s(mnemonic, machInst, %(op_class)s, size, 553 fp, load, noAlloc, signExt, exclusive, acrel, 554 imm, mode, rn, rt, rt2) 555{ 556 %(constructor)s; 557} 558}}; 559 560def template VMemMultDeclare {{ 561class %(class_name)s : public %(base_class)s 562{ 563 public: 564 // Constructor 565 %(class_name)s(ExtMachInst machInst, unsigned width, 566 RegIndex rn, RegIndex vd, unsigned regs, unsigned inc, 567 uint32_t size, uint32_t align, RegIndex rm); 568}; 569}}; 570 571def template VMemMultConstructor {{ 572%(class_name)s::%(class_name)s(ExtMachInst machInst, unsigned width, 573 RegIndex rn, RegIndex vd, unsigned regs, unsigned inc, 574 uint32_t size, uint32_t align, RegIndex rm) 575 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, width, 576 rn, vd, regs, inc, size, align, rm) 577{ 578 %(constructor)s; 579 if (!(condCode == COND_AL || condCode == COND_UC)) { 580 for (int x = 0; x < _numDestRegs; x++) { 581 _srcRegIdx[_numSrcRegs++] = _destRegIdx[x]; 582 } 583 } 584} 585}}; 586 587def template VMemSingleDeclare {{ 588class %(class_name)s : public %(base_class)s 589{ 590 public: 591 // Constructor 592 %(class_name)s(ExtMachInst machInst, bool all, unsigned width, 593 RegIndex rn, RegIndex vd, unsigned regs, unsigned inc, 594 uint32_t size, uint32_t align, RegIndex rm, unsigned lane = 0); 595}; 596}}; 597 598def template VMemSingleConstructor {{ 599%(class_name)s::%(class_name)s(ExtMachInst machInst, bool all, unsigned width, 600 RegIndex rn, RegIndex vd, unsigned regs, unsigned inc, 601 uint32_t size, uint32_t align, RegIndex rm, unsigned lane) 602 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, all, width, 603 rn, vd, regs, inc, size, align, rm, lane) 604{ 605 %(constructor)s; 606 if (!(condCode == COND_AL || condCode == COND_UC)) { 607 for (int x = 0; x < _numDestRegs; x++) { 608 _srcRegIdx[_numSrcRegs++] = _destRegIdx[x]; 609 } 610 } 611} 612}}; 613 614def template MacroVFPMemDeclare {{ 615/** 616 * Static instructions class for a store multiple instruction 617 */ 618class %(class_name)s : public %(base_class)s 619{ 620 public: 621 // Constructor 622 %(class_name)s(ExtMachInst machInst, IntRegIndex rn, 623 RegIndex vd, bool single, bool up, bool writeback, 624 bool load, uint32_t offset); 625}; 626}}; 627 628def template MacroVFPMemConstructor {{ 629%(class_name)s::%(class_name)s(ExtMachInst machInst, IntRegIndex rn, 630 RegIndex vd, bool single, bool up, bool writeback, bool load, 631 uint32_t offset) 632 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, rn, 633 vd, single, up, writeback, load, offset) 634{ 635 %(constructor)s; 636 if (!(condCode == COND_AL || condCode == COND_UC)) { 637 for (int x = 0; x < _numDestRegs; x++) { 638 _srcRegIdx[_numSrcRegs++] = _destRegIdx[x]; 639 } 640 } 641} 642 643}}; 644