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