1// -*- mode:c++ -*- 2 3// Copyright (c) 2003-2005 The Regents of The University of Michigan 4// All rights reserved. 5// 6// Redistribution and use in source and binary forms, with or without 7// modification, are permitted provided that the following conditions are 8// met: redistributions of source code must retain the above copyright 9// notice, this list of conditions and the following disclaimer; 10// redistributions in binary form must reproduce the above copyright 11// notice, this list of conditions and the following disclaimer in the 12// documentation and/or other materials provided with the distribution; 13// neither the name of the copyright holders nor the names of its 14// contributors may be used to endorse or promote products derived from 15// this software without specific prior written permission. 16// 17// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28// 29// Authors: Steve Reinhardt 30// Kevin Lim 31 32//////////////////////////////////////////////////////////////////// 33// 34// Memory-format instructions: LoadAddress, Load, Store 35// 36 37output header {{ 38 /** 39 * Base class for general Alpha memory-format instructions. 40 */ 41 class Memory : public AlphaStaticInst 42 { 43 protected: 44 45 /// Memory request flags. See mem_req_base.hh. 46 Request::Flags memAccessFlags; 47 /// Pointer to EAComp object. 48 const StaticInstPtr eaCompPtr; 49 /// Pointer to MemAcc object. 50 const StaticInstPtr memAccPtr; 51 52 /// Constructor 53 Memory(const char *mnem, ExtMachInst _machInst, OpClass __opClass, 54 StaticInstPtr _eaCompPtr = nullStaticInstPtr, 55 StaticInstPtr _memAccPtr = nullStaticInstPtr) 56 : AlphaStaticInst(mnem, _machInst, __opClass), 57 eaCompPtr(_eaCompPtr), memAccPtr(_memAccPtr) 58 { 59 } 60 61 std::string 62 generateDisassembly(Addr pc, const SymbolTable *symtab) const; 63 64 public: 65 66 const StaticInstPtr &eaCompInst() const { return eaCompPtr; } 67 const StaticInstPtr &memAccInst() const { return memAccPtr; }
| 1// -*- mode:c++ -*- 2 3// Copyright (c) 2003-2005 The Regents of The University of Michigan 4// All rights reserved. 5// 6// Redistribution and use in source and binary forms, with or without 7// modification, are permitted provided that the following conditions are 8// met: redistributions of source code must retain the above copyright 9// notice, this list of conditions and the following disclaimer; 10// redistributions in binary form must reproduce the above copyright 11// notice, this list of conditions and the following disclaimer in the 12// documentation and/or other materials provided with the distribution; 13// neither the name of the copyright holders nor the names of its 14// contributors may be used to endorse or promote products derived from 15// this software without specific prior written permission. 16// 17// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28// 29// Authors: Steve Reinhardt 30// Kevin Lim 31 32//////////////////////////////////////////////////////////////////// 33// 34// Memory-format instructions: LoadAddress, Load, Store 35// 36 37output header {{ 38 /** 39 * Base class for general Alpha memory-format instructions. 40 */ 41 class Memory : public AlphaStaticInst 42 { 43 protected: 44 45 /// Memory request flags. See mem_req_base.hh. 46 Request::Flags memAccessFlags; 47 /// Pointer to EAComp object. 48 const StaticInstPtr eaCompPtr; 49 /// Pointer to MemAcc object. 50 const StaticInstPtr memAccPtr; 51 52 /// Constructor 53 Memory(const char *mnem, ExtMachInst _machInst, OpClass __opClass, 54 StaticInstPtr _eaCompPtr = nullStaticInstPtr, 55 StaticInstPtr _memAccPtr = nullStaticInstPtr) 56 : AlphaStaticInst(mnem, _machInst, __opClass), 57 eaCompPtr(_eaCompPtr), memAccPtr(_memAccPtr) 58 { 59 } 60 61 std::string 62 generateDisassembly(Addr pc, const SymbolTable *symtab) const; 63 64 public: 65 66 const StaticInstPtr &eaCompInst() const { return eaCompPtr; } 67 const StaticInstPtr &memAccInst() const { return memAccPtr; }
|
| 68 69 Request::Flags memAccFlags() { return memAccessFlags; }
|
68 }; 69 70 /** 71 * Base class for memory-format instructions using a 32-bit 72 * displacement (i.e. most of them). 73 */ 74 class MemoryDisp32 : public Memory 75 { 76 protected: 77 /// Displacement for EA calculation (signed). 78 int32_t disp; 79 80 /// Constructor. 81 MemoryDisp32(const char *mnem, ExtMachInst _machInst, OpClass __opClass, 82 StaticInstPtr _eaCompPtr = nullStaticInstPtr, 83 StaticInstPtr _memAccPtr = nullStaticInstPtr) 84 : Memory(mnem, _machInst, __opClass, _eaCompPtr, _memAccPtr), 85 disp(MEMDISP) 86 { 87 } 88 }; 89 90 91 /** 92 * Base class for a few miscellaneous memory-format insts 93 * that don't interpret the disp field: wh64, fetch, fetch_m, ecb. 94 * None of these instructions has a destination register either. 95 */ 96 class MemoryNoDisp : public Memory 97 { 98 protected: 99 /// Constructor 100 MemoryNoDisp(const char *mnem, ExtMachInst _machInst, OpClass __opClass, 101 StaticInstPtr _eaCompPtr = nullStaticInstPtr, 102 StaticInstPtr _memAccPtr = nullStaticInstPtr) 103 : Memory(mnem, _machInst, __opClass, _eaCompPtr, _memAccPtr) 104 { 105 } 106 107 std::string 108 generateDisassembly(Addr pc, const SymbolTable *symtab) const; 109 }; 110}}; 111 112 113output decoder {{ 114 std::string 115 Memory::generateDisassembly(Addr pc, const SymbolTable *symtab) const 116 { 117 return csprintf("%-10s %c%d,%d(r%d)", mnemonic, 118 flags[IsFloating] ? 'f' : 'r', RA, MEMDISP, RB); 119 } 120 121 std::string 122 MemoryNoDisp::generateDisassembly(Addr pc, const SymbolTable *symtab) const 123 { 124 return csprintf("%-10s (r%d)", mnemonic, RB); 125 } 126}}; 127 128def format LoadAddress(code) {{ 129 iop = InstObjParams(name, Name, 'MemoryDisp32', code) 130 header_output = BasicDeclare.subst(iop) 131 decoder_output = BasicConstructor.subst(iop) 132 decode_block = BasicDecode.subst(iop) 133 exec_output = BasicExecute.subst(iop) 134}}; 135 136 137def template LoadStoreDeclare {{ 138 /** 139 * Static instruction class for "%(mnemonic)s". 140 */ 141 class %(class_name)s : public %(base_class)s 142 { 143 protected: 144 145 /** 146 * "Fake" effective address computation class for "%(mnemonic)s". 147 */ 148 class EAComp : public %(base_class)s 149 { 150 public: 151 /// Constructor 152 EAComp(ExtMachInst machInst); 153 154 %(BasicExecDeclare)s 155 }; 156 157 /** 158 * "Fake" memory access instruction class for "%(mnemonic)s". 159 */ 160 class MemAcc : public %(base_class)s 161 { 162 public: 163 /// Constructor 164 MemAcc(ExtMachInst machInst); 165 166 %(BasicExecDeclare)s 167 }; 168 169 public: 170 171 /// Constructor. 172 %(class_name)s(ExtMachInst machInst); 173 174 %(BasicExecDeclare)s 175 176 %(InitiateAccDeclare)s 177 178 %(CompleteAccDeclare)s
| 70 }; 71 72 /** 73 * Base class for memory-format instructions using a 32-bit 74 * displacement (i.e. most of them). 75 */ 76 class MemoryDisp32 : public Memory 77 { 78 protected: 79 /// Displacement for EA calculation (signed). 80 int32_t disp; 81 82 /// Constructor. 83 MemoryDisp32(const char *mnem, ExtMachInst _machInst, OpClass __opClass, 84 StaticInstPtr _eaCompPtr = nullStaticInstPtr, 85 StaticInstPtr _memAccPtr = nullStaticInstPtr) 86 : Memory(mnem, _machInst, __opClass, _eaCompPtr, _memAccPtr), 87 disp(MEMDISP) 88 { 89 } 90 }; 91 92 93 /** 94 * Base class for a few miscellaneous memory-format insts 95 * that don't interpret the disp field: wh64, fetch, fetch_m, ecb. 96 * None of these instructions has a destination register either. 97 */ 98 class MemoryNoDisp : public Memory 99 { 100 protected: 101 /// Constructor 102 MemoryNoDisp(const char *mnem, ExtMachInst _machInst, OpClass __opClass, 103 StaticInstPtr _eaCompPtr = nullStaticInstPtr, 104 StaticInstPtr _memAccPtr = nullStaticInstPtr) 105 : Memory(mnem, _machInst, __opClass, _eaCompPtr, _memAccPtr) 106 { 107 } 108 109 std::string 110 generateDisassembly(Addr pc, const SymbolTable *symtab) const; 111 }; 112}}; 113 114 115output decoder {{ 116 std::string 117 Memory::generateDisassembly(Addr pc, const SymbolTable *symtab) const 118 { 119 return csprintf("%-10s %c%d,%d(r%d)", mnemonic, 120 flags[IsFloating] ? 'f' : 'r', RA, MEMDISP, RB); 121 } 122 123 std::string 124 MemoryNoDisp::generateDisassembly(Addr pc, const SymbolTable *symtab) const 125 { 126 return csprintf("%-10s (r%d)", mnemonic, RB); 127 } 128}}; 129 130def format LoadAddress(code) {{ 131 iop = InstObjParams(name, Name, 'MemoryDisp32', code) 132 header_output = BasicDeclare.subst(iop) 133 decoder_output = BasicConstructor.subst(iop) 134 decode_block = BasicDecode.subst(iop) 135 exec_output = BasicExecute.subst(iop) 136}}; 137 138 139def template LoadStoreDeclare {{ 140 /** 141 * Static instruction class for "%(mnemonic)s". 142 */ 143 class %(class_name)s : public %(base_class)s 144 { 145 protected: 146 147 /** 148 * "Fake" effective address computation class for "%(mnemonic)s". 149 */ 150 class EAComp : public %(base_class)s 151 { 152 public: 153 /// Constructor 154 EAComp(ExtMachInst machInst); 155 156 %(BasicExecDeclare)s 157 }; 158 159 /** 160 * "Fake" memory access instruction class for "%(mnemonic)s". 161 */ 162 class MemAcc : public %(base_class)s 163 { 164 public: 165 /// Constructor 166 MemAcc(ExtMachInst machInst); 167 168 %(BasicExecDeclare)s 169 }; 170 171 public: 172 173 /// Constructor. 174 %(class_name)s(ExtMachInst machInst); 175 176 %(BasicExecDeclare)s 177 178 %(InitiateAccDeclare)s 179 180 %(CompleteAccDeclare)s
|
| 181 182 %(MemAccSizeDeclare)s
|
179 }; 180}}; 181 182 183def template InitiateAccDeclare {{ 184 Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const; 185}}; 186 187 188def template CompleteAccDeclare {{ 189 Fault completeAcc(PacketPtr, %(CPU_exec_context)s *, 190 Trace::InstRecord *) const; 191}}; 192
| 183 }; 184}}; 185 186 187def template InitiateAccDeclare {{ 188 Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const; 189}}; 190 191 192def template CompleteAccDeclare {{ 193 Fault completeAcc(PacketPtr, %(CPU_exec_context)s *, 194 Trace::InstRecord *) const; 195}}; 196
|
| 197def template MemAccSizeDeclare {{ 198 int memAccSize(%(CPU_exec_context)s *xc); 199}};
|
193
| 200
|
| 201def template MiscMemAccSize {{ 202 int %(class_name)s::memAccSize(%(CPU_exec_context)s *xc) 203 { 204 panic("Misc instruction does not support split access method!"); 205 return 0; 206 } 207}}; 208 209def template LoadStoreMemAccSize {{ 210 int %(class_name)s::memAccSize(%(CPU_exec_context)s *xc) 211 { 212 // Return the memory access size in bytes 213 return (%(mem_acc_size)d / 8); 214 } 215}}; 216
|
194def template EACompConstructor {{ 195 /** TODO: change op_class to AddrGenOp or something (requires 196 * creating new member of OpClass enum in op_class.hh, updating 197 * config files, etc.). */ 198 inline %(class_name)s::EAComp::EAComp(ExtMachInst machInst) 199 : %(base_class)s("%(mnemonic)s (EAComp)", machInst, IntAluOp) 200 { 201 %(constructor)s; 202 } 203}}; 204 205 206def template MemAccConstructor {{ 207 inline %(class_name)s::MemAcc::MemAcc(ExtMachInst machInst) 208 : %(base_class)s("%(mnemonic)s (MemAcc)", machInst, %(op_class)s) 209 { 210 %(constructor)s; 211 } 212}}; 213 214 215def template LoadStoreConstructor {{ 216 inline %(class_name)s::%(class_name)s(ExtMachInst machInst) 217 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, 218 new EAComp(machInst), new MemAcc(machInst)) 219 { 220 %(constructor)s; 221 } 222}}; 223 224 225def template EACompExecute {{ 226 Fault 227 %(class_name)s::EAComp::execute(%(CPU_exec_context)s *xc, 228 Trace::InstRecord *traceData) const 229 { 230 Addr EA; 231 Fault fault = NoFault; 232 233 %(fp_enable_check)s; 234 %(op_decl)s; 235 %(op_rd)s; 236 %(ea_code)s; 237 238 if (fault == NoFault) { 239 %(op_wb)s; 240 xc->setEA(EA); 241 } 242 243 return fault; 244 } 245}}; 246 247def template LoadMemAccExecute {{ 248 Fault 249 %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc, 250 Trace::InstRecord *traceData) const 251 { 252 Addr EA; 253 Fault fault = NoFault; 254 255 %(fp_enable_check)s; 256 %(op_decl)s; 257 %(op_rd)s; 258 EA = xc->getEA(); 259 260 if (fault == NoFault) { 261 fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags); 262 %(memacc_code)s; 263 } 264 265 if (fault == NoFault) { 266 %(op_wb)s; 267 } 268 269 return fault; 270 } 271}}; 272 273 274def template LoadExecute {{ 275 Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, 276 Trace::InstRecord *traceData) const 277 { 278 Addr EA; 279 Fault fault = NoFault; 280 281 %(fp_enable_check)s; 282 %(op_decl)s; 283 %(op_rd)s; 284 %(ea_code)s; 285 286 if (fault == NoFault) { 287 fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags); 288 %(memacc_code)s; 289 } 290 291 if (fault == NoFault) { 292 %(op_wb)s; 293 } 294 295 return fault; 296 } 297}}; 298 299 300def template LoadInitiateAcc {{ 301 Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc, 302 Trace::InstRecord *traceData) const 303 { 304 Addr EA; 305 Fault fault = NoFault; 306 307 %(fp_enable_check)s; 308 %(op_src_decl)s; 309 %(op_rd)s; 310 %(ea_code)s; 311 312 if (fault == NoFault) { 313 fault = xc->read(EA, (uint%(mem_acc_size)d_t &)Mem, memAccessFlags); 314 } 315 316 return fault; 317 } 318}}; 319 320 321def template LoadCompleteAcc {{ 322 Fault %(class_name)s::completeAcc(PacketPtr pkt, 323 %(CPU_exec_context)s *xc, 324 Trace::InstRecord *traceData) const 325 { 326 Fault fault = NoFault; 327 328 %(fp_enable_check)s; 329 %(op_decl)s; 330 331 Mem = pkt->get<typeof(Mem)>(); 332 333 if (fault == NoFault) { 334 %(memacc_code)s; 335 } 336 337 if (fault == NoFault) { 338 %(op_wb)s; 339 } 340 341 return fault; 342 } 343}}; 344 345 346def template StoreMemAccExecute {{ 347 Fault 348 %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc, 349 Trace::InstRecord *traceData) const 350 { 351 Addr EA; 352 Fault fault = NoFault; 353 354 %(fp_enable_check)s; 355 %(op_decl)s; 356 %(op_rd)s; 357 EA = xc->getEA(); 358 359 if (fault == NoFault) { 360 %(memacc_code)s; 361 } 362 363 if (fault == NoFault) { 364 fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA, 365 memAccessFlags, NULL); 366 if (traceData) { traceData->setData(Mem); } 367 } 368 369 if (fault == NoFault) { 370 %(postacc_code)s; 371 } 372 373 if (fault == NoFault) { 374 %(op_wb)s; 375 } 376 377 return fault; 378 } 379}}; 380 381def template StoreCondMemAccExecute {{ 382 Fault 383 %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc, 384 Trace::InstRecord *traceData) const 385 { 386 Addr EA; 387 Fault fault = NoFault; 388 uint64_t write_result = 0; 389 390 %(fp_enable_check)s; 391 %(op_decl)s; 392 %(op_rd)s; 393 EA = xc->getEA(); 394 395 if (fault == NoFault) { 396 %(memacc_code)s; 397 } 398 399 if (fault == NoFault) { 400 fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA, 401 memAccessFlags, &write_result); 402 if (traceData) { traceData->setData(Mem); } 403 } 404 405 if (fault == NoFault) { 406 %(postacc_code)s; 407 } 408 409 if (fault == NoFault) { 410 %(op_wb)s; 411 } 412 413 return fault; 414 } 415}}; 416 417 418def template StoreExecute {{ 419 Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, 420 Trace::InstRecord *traceData) const 421 { 422 Addr EA; 423 Fault fault = NoFault; 424 425 %(fp_enable_check)s; 426 %(op_decl)s; 427 %(op_rd)s; 428 %(ea_code)s; 429 430 if (fault == NoFault) { 431 %(memacc_code)s; 432 } 433 434 if (fault == NoFault) { 435 fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA, 436 memAccessFlags, NULL); 437 if (traceData) { traceData->setData(Mem); } 438 } 439 440 if (fault == NoFault) { 441 %(postacc_code)s; 442 } 443 444 if (fault == NoFault) { 445 %(op_wb)s; 446 } 447 448 return fault; 449 } 450}}; 451 452def template StoreCondExecute {{ 453 Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, 454 Trace::InstRecord *traceData) const 455 { 456 Addr EA; 457 Fault fault = NoFault; 458 uint64_t write_result = 0; 459 460 %(fp_enable_check)s; 461 %(op_decl)s; 462 %(op_rd)s; 463 %(ea_code)s; 464 465 if (fault == NoFault) { 466 %(memacc_code)s; 467 } 468 469 if (fault == NoFault) { 470 fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA, 471 memAccessFlags, &write_result); 472 if (traceData) { traceData->setData(Mem); } 473 } 474 475 if (fault == NoFault) { 476 %(postacc_code)s; 477 } 478 479 if (fault == NoFault) { 480 %(op_wb)s; 481 } 482 483 return fault; 484 } 485}}; 486 487def template StoreInitiateAcc {{ 488 Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc, 489 Trace::InstRecord *traceData) const 490 { 491 Addr EA; 492 Fault fault = NoFault; 493 494 %(fp_enable_check)s; 495 %(op_decl)s; 496 %(op_rd)s; 497 %(ea_code)s; 498 499 if (fault == NoFault) { 500 %(memacc_code)s; 501 } 502 503 if (fault == NoFault) { 504 fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA, 505 memAccessFlags, NULL); 506 if (traceData) { traceData->setData(Mem); } 507 } 508 509 return fault; 510 } 511}}; 512 513 514def template StoreCompleteAcc {{ 515 Fault %(class_name)s::completeAcc(PacketPtr pkt, 516 %(CPU_exec_context)s *xc, 517 Trace::InstRecord *traceData) const 518 { 519 Fault fault = NoFault; 520 521 %(fp_enable_check)s; 522 %(op_dest_decl)s; 523 524 if (fault == NoFault) { 525 %(postacc_code)s; 526 } 527 528 if (fault == NoFault) { 529 %(op_wb)s; 530 } 531 532 return fault; 533 } 534}}; 535 536 537def template StoreCondCompleteAcc {{ 538 Fault %(class_name)s::completeAcc(PacketPtr pkt, 539 %(CPU_exec_context)s *xc, 540 Trace::InstRecord *traceData) const 541 { 542 Fault fault = NoFault; 543 544 %(fp_enable_check)s; 545 %(op_dest_decl)s; 546 547 uint64_t write_result = pkt->req->getExtraData(); 548 549 if (fault == NoFault) { 550 %(postacc_code)s; 551 } 552 553 if (fault == NoFault) { 554 %(op_wb)s; 555 } 556 557 return fault; 558 } 559}}; 560 561 562def template MiscMemAccExecute {{ 563 Fault %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc, 564 Trace::InstRecord *traceData) const 565 { 566 Addr EA; 567 Fault fault = NoFault; 568 569 %(fp_enable_check)s; 570 %(op_decl)s; 571 %(op_rd)s; 572 EA = xc->getEA(); 573 574 if (fault == NoFault) { 575 %(memacc_code)s; 576 } 577 578 return NoFault; 579 } 580}}; 581 582def template MiscExecute {{ 583 Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, 584 Trace::InstRecord *traceData) const 585 { 586 Addr EA; 587 Fault fault = NoFault; 588 589 %(fp_enable_check)s; 590 %(op_decl)s; 591 %(op_rd)s; 592 %(ea_code)s; 593 594 if (fault == NoFault) { 595 %(memacc_code)s; 596 } 597 598 return NoFault; 599 } 600}}; 601 602def template MiscInitiateAcc {{ 603 Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc, 604 Trace::InstRecord *traceData) const 605 { 606 warn("Misc instruction does not support split access method!"); 607 return NoFault; 608 } 609}}; 610 611 612def template MiscCompleteAcc {{ 613 Fault %(class_name)s::completeAcc(PacketPtr pkt, 614 %(CPU_exec_context)s *xc, 615 Trace::InstRecord *traceData) const 616 { 617 warn("Misc instruction does not support split access method!"); 618 619 return NoFault; 620 } 621}}; 622
| 217def template EACompConstructor {{ 218 /** TODO: change op_class to AddrGenOp or something (requires 219 * creating new member of OpClass enum in op_class.hh, updating 220 * config files, etc.). */ 221 inline %(class_name)s::EAComp::EAComp(ExtMachInst machInst) 222 : %(base_class)s("%(mnemonic)s (EAComp)", machInst, IntAluOp) 223 { 224 %(constructor)s; 225 } 226}}; 227 228 229def template MemAccConstructor {{ 230 inline %(class_name)s::MemAcc::MemAcc(ExtMachInst machInst) 231 : %(base_class)s("%(mnemonic)s (MemAcc)", machInst, %(op_class)s) 232 { 233 %(constructor)s; 234 } 235}}; 236 237 238def template LoadStoreConstructor {{ 239 inline %(class_name)s::%(class_name)s(ExtMachInst machInst) 240 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, 241 new EAComp(machInst), new MemAcc(machInst)) 242 { 243 %(constructor)s; 244 } 245}}; 246 247 248def template EACompExecute {{ 249 Fault 250 %(class_name)s::EAComp::execute(%(CPU_exec_context)s *xc, 251 Trace::InstRecord *traceData) const 252 { 253 Addr EA; 254 Fault fault = NoFault; 255 256 %(fp_enable_check)s; 257 %(op_decl)s; 258 %(op_rd)s; 259 %(ea_code)s; 260 261 if (fault == NoFault) { 262 %(op_wb)s; 263 xc->setEA(EA); 264 } 265 266 return fault; 267 } 268}}; 269 270def template LoadMemAccExecute {{ 271 Fault 272 %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc, 273 Trace::InstRecord *traceData) const 274 { 275 Addr EA; 276 Fault fault = NoFault; 277 278 %(fp_enable_check)s; 279 %(op_decl)s; 280 %(op_rd)s; 281 EA = xc->getEA(); 282 283 if (fault == NoFault) { 284 fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags); 285 %(memacc_code)s; 286 } 287 288 if (fault == NoFault) { 289 %(op_wb)s; 290 } 291 292 return fault; 293 } 294}}; 295 296 297def template LoadExecute {{ 298 Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, 299 Trace::InstRecord *traceData) const 300 { 301 Addr EA; 302 Fault fault = NoFault; 303 304 %(fp_enable_check)s; 305 %(op_decl)s; 306 %(op_rd)s; 307 %(ea_code)s; 308 309 if (fault == NoFault) { 310 fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags); 311 %(memacc_code)s; 312 } 313 314 if (fault == NoFault) { 315 %(op_wb)s; 316 } 317 318 return fault; 319 } 320}}; 321 322 323def template LoadInitiateAcc {{ 324 Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc, 325 Trace::InstRecord *traceData) const 326 { 327 Addr EA; 328 Fault fault = NoFault; 329 330 %(fp_enable_check)s; 331 %(op_src_decl)s; 332 %(op_rd)s; 333 %(ea_code)s; 334 335 if (fault == NoFault) { 336 fault = xc->read(EA, (uint%(mem_acc_size)d_t &)Mem, memAccessFlags); 337 } 338 339 return fault; 340 } 341}}; 342 343 344def template LoadCompleteAcc {{ 345 Fault %(class_name)s::completeAcc(PacketPtr pkt, 346 %(CPU_exec_context)s *xc, 347 Trace::InstRecord *traceData) const 348 { 349 Fault fault = NoFault; 350 351 %(fp_enable_check)s; 352 %(op_decl)s; 353 354 Mem = pkt->get<typeof(Mem)>(); 355 356 if (fault == NoFault) { 357 %(memacc_code)s; 358 } 359 360 if (fault == NoFault) { 361 %(op_wb)s; 362 } 363 364 return fault; 365 } 366}}; 367 368 369def template StoreMemAccExecute {{ 370 Fault 371 %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc, 372 Trace::InstRecord *traceData) const 373 { 374 Addr EA; 375 Fault fault = NoFault; 376 377 %(fp_enable_check)s; 378 %(op_decl)s; 379 %(op_rd)s; 380 EA = xc->getEA(); 381 382 if (fault == NoFault) { 383 %(memacc_code)s; 384 } 385 386 if (fault == NoFault) { 387 fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA, 388 memAccessFlags, NULL); 389 if (traceData) { traceData->setData(Mem); } 390 } 391 392 if (fault == NoFault) { 393 %(postacc_code)s; 394 } 395 396 if (fault == NoFault) { 397 %(op_wb)s; 398 } 399 400 return fault; 401 } 402}}; 403 404def template StoreCondMemAccExecute {{ 405 Fault 406 %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc, 407 Trace::InstRecord *traceData) const 408 { 409 Addr EA; 410 Fault fault = NoFault; 411 uint64_t write_result = 0; 412 413 %(fp_enable_check)s; 414 %(op_decl)s; 415 %(op_rd)s; 416 EA = xc->getEA(); 417 418 if (fault == NoFault) { 419 %(memacc_code)s; 420 } 421 422 if (fault == NoFault) { 423 fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA, 424 memAccessFlags, &write_result); 425 if (traceData) { traceData->setData(Mem); } 426 } 427 428 if (fault == NoFault) { 429 %(postacc_code)s; 430 } 431 432 if (fault == NoFault) { 433 %(op_wb)s; 434 } 435 436 return fault; 437 } 438}}; 439 440 441def template StoreExecute {{ 442 Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, 443 Trace::InstRecord *traceData) const 444 { 445 Addr EA; 446 Fault fault = NoFault; 447 448 %(fp_enable_check)s; 449 %(op_decl)s; 450 %(op_rd)s; 451 %(ea_code)s; 452 453 if (fault == NoFault) { 454 %(memacc_code)s; 455 } 456 457 if (fault == NoFault) { 458 fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA, 459 memAccessFlags, NULL); 460 if (traceData) { traceData->setData(Mem); } 461 } 462 463 if (fault == NoFault) { 464 %(postacc_code)s; 465 } 466 467 if (fault == NoFault) { 468 %(op_wb)s; 469 } 470 471 return fault; 472 } 473}}; 474 475def template StoreCondExecute {{ 476 Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, 477 Trace::InstRecord *traceData) const 478 { 479 Addr EA; 480 Fault fault = NoFault; 481 uint64_t write_result = 0; 482 483 %(fp_enable_check)s; 484 %(op_decl)s; 485 %(op_rd)s; 486 %(ea_code)s; 487 488 if (fault == NoFault) { 489 %(memacc_code)s; 490 } 491 492 if (fault == NoFault) { 493 fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA, 494 memAccessFlags, &write_result); 495 if (traceData) { traceData->setData(Mem); } 496 } 497 498 if (fault == NoFault) { 499 %(postacc_code)s; 500 } 501 502 if (fault == NoFault) { 503 %(op_wb)s; 504 } 505 506 return fault; 507 } 508}}; 509 510def template StoreInitiateAcc {{ 511 Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc, 512 Trace::InstRecord *traceData) const 513 { 514 Addr EA; 515 Fault fault = NoFault; 516 517 %(fp_enable_check)s; 518 %(op_decl)s; 519 %(op_rd)s; 520 %(ea_code)s; 521 522 if (fault == NoFault) { 523 %(memacc_code)s; 524 } 525 526 if (fault == NoFault) { 527 fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA, 528 memAccessFlags, NULL); 529 if (traceData) { traceData->setData(Mem); } 530 } 531 532 return fault; 533 } 534}}; 535 536 537def template StoreCompleteAcc {{ 538 Fault %(class_name)s::completeAcc(PacketPtr pkt, 539 %(CPU_exec_context)s *xc, 540 Trace::InstRecord *traceData) const 541 { 542 Fault fault = NoFault; 543 544 %(fp_enable_check)s; 545 %(op_dest_decl)s; 546 547 if (fault == NoFault) { 548 %(postacc_code)s; 549 } 550 551 if (fault == NoFault) { 552 %(op_wb)s; 553 } 554 555 return fault; 556 } 557}}; 558 559 560def template StoreCondCompleteAcc {{ 561 Fault %(class_name)s::completeAcc(PacketPtr pkt, 562 %(CPU_exec_context)s *xc, 563 Trace::InstRecord *traceData) const 564 { 565 Fault fault = NoFault; 566 567 %(fp_enable_check)s; 568 %(op_dest_decl)s; 569 570 uint64_t write_result = pkt->req->getExtraData(); 571 572 if (fault == NoFault) { 573 %(postacc_code)s; 574 } 575 576 if (fault == NoFault) { 577 %(op_wb)s; 578 } 579 580 return fault; 581 } 582}}; 583 584 585def template MiscMemAccExecute {{ 586 Fault %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc, 587 Trace::InstRecord *traceData) const 588 { 589 Addr EA; 590 Fault fault = NoFault; 591 592 %(fp_enable_check)s; 593 %(op_decl)s; 594 %(op_rd)s; 595 EA = xc->getEA(); 596 597 if (fault == NoFault) { 598 %(memacc_code)s; 599 } 600 601 return NoFault; 602 } 603}}; 604 605def template MiscExecute {{ 606 Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, 607 Trace::InstRecord *traceData) const 608 { 609 Addr EA; 610 Fault fault = NoFault; 611 612 %(fp_enable_check)s; 613 %(op_decl)s; 614 %(op_rd)s; 615 %(ea_code)s; 616 617 if (fault == NoFault) { 618 %(memacc_code)s; 619 } 620 621 return NoFault; 622 } 623}}; 624 625def template MiscInitiateAcc {{ 626 Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc, 627 Trace::InstRecord *traceData) const 628 { 629 warn("Misc instruction does not support split access method!"); 630 return NoFault; 631 } 632}}; 633 634 635def template MiscCompleteAcc {{ 636 Fault %(class_name)s::completeAcc(PacketPtr pkt, 637 %(CPU_exec_context)s *xc, 638 Trace::InstRecord *traceData) const 639 { 640 warn("Misc instruction does not support split access method!"); 641 642 return NoFault; 643 } 644}}; 645
|
| 646def template MiscMemAccSize {{ 647 int %(class_name)s::memAccSize(%(CPU_exec_context)s *xc) 648 { 649 panic("Misc instruction does not support split access method!"); 650 return 0; 651 } 652}}; 653
|
623// load instructions use Ra as dest, so check for 624// Ra == 31 to detect nops 625def template LoadNopCheckDecode {{ 626 { 627 AlphaStaticInst *i = new %(class_name)s(machInst); 628 if (RA == 31) { 629 i = makeNop(i); 630 } 631 return i; 632 } 633}}; 634 635 636// for some load instructions, Ra == 31 indicates a prefetch (not a nop) 637def template LoadPrefetchCheckDecode {{ 638 { 639 if (RA != 31) { 640 return new %(class_name)s(machInst); 641 } 642 else { 643 return new %(class_name)sPrefetch(machInst); 644 } 645 } 646}}; 647 648 649let {{ 650def LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 651 postacc_code = '', base_class = 'MemoryDisp32', 652 decode_template = BasicDecode, exec_template_base = ''): 653 # Make sure flags are in lists (convert to lists if not). 654 mem_flags = makeList(mem_flags) 655 inst_flags = makeList(inst_flags) 656 657 # add hook to get effective addresses into execution trace output. 658 ea_code += '\nif (traceData) { traceData->setAddr(EA); }\n' 659 660 # Some CPU models execute the memory operation as an atomic unit, 661 # while others want to separate them into an effective address 662 # computation and a memory access operation. As a result, we need 663 # to generate three StaticInst objects. Note that the latter two 664 # are nested inside the larger "atomic" one. 665 666 # Generate InstObjParams for each of the three objects. Note that 667 # they differ only in the set of code objects contained (which in 668 # turn affects the object's overall operand list). 669 iop = InstObjParams(name, Name, base_class, 670 { 'ea_code':ea_code, 'memacc_code':memacc_code, 'postacc_code':postacc_code }, 671 inst_flags) 672 ea_iop = InstObjParams(name, Name, base_class, 673 { 'ea_code':ea_code }, 674 inst_flags) 675 memacc_iop = InstObjParams(name, Name, base_class, 676 { 'memacc_code':memacc_code, 'postacc_code':postacc_code }, 677 inst_flags) 678 679 if mem_flags: 680 mem_flags = [ 'Request::%s' % flag for flag in mem_flags ] 681 s = '\n\tmemAccessFlags = ' + string.join(mem_flags, '|') + ';' 682 iop.constructor += s 683 memacc_iop.constructor += s 684 685 # select templates 686 687 # The InitiateAcc template is the same for StoreCond templates as the 688 # corresponding Store template.. 689 StoreCondInitiateAcc = StoreInitiateAcc 690 691 memAccExecTemplate = eval(exec_template_base + 'MemAccExecute') 692 fullExecTemplate = eval(exec_template_base + 'Execute') 693 initiateAccTemplate = eval(exec_template_base + 'InitiateAcc') 694 completeAccTemplate = eval(exec_template_base + 'CompleteAcc') 695
| 654// load instructions use Ra as dest, so check for 655// Ra == 31 to detect nops 656def template LoadNopCheckDecode {{ 657 { 658 AlphaStaticInst *i = new %(class_name)s(machInst); 659 if (RA == 31) { 660 i = makeNop(i); 661 } 662 return i; 663 } 664}}; 665 666 667// for some load instructions, Ra == 31 indicates a prefetch (not a nop) 668def template LoadPrefetchCheckDecode {{ 669 { 670 if (RA != 31) { 671 return new %(class_name)s(machInst); 672 } 673 else { 674 return new %(class_name)sPrefetch(machInst); 675 } 676 } 677}}; 678 679 680let {{ 681def LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 682 postacc_code = '', base_class = 'MemoryDisp32', 683 decode_template = BasicDecode, exec_template_base = ''): 684 # Make sure flags are in lists (convert to lists if not). 685 mem_flags = makeList(mem_flags) 686 inst_flags = makeList(inst_flags) 687 688 # add hook to get effective addresses into execution trace output. 689 ea_code += '\nif (traceData) { traceData->setAddr(EA); }\n' 690 691 # Some CPU models execute the memory operation as an atomic unit, 692 # while others want to separate them into an effective address 693 # computation and a memory access operation. As a result, we need 694 # to generate three StaticInst objects. Note that the latter two 695 # are nested inside the larger "atomic" one. 696 697 # Generate InstObjParams for each of the three objects. Note that 698 # they differ only in the set of code objects contained (which in 699 # turn affects the object's overall operand list). 700 iop = InstObjParams(name, Name, base_class, 701 { 'ea_code':ea_code, 'memacc_code':memacc_code, 'postacc_code':postacc_code }, 702 inst_flags) 703 ea_iop = InstObjParams(name, Name, base_class, 704 { 'ea_code':ea_code }, 705 inst_flags) 706 memacc_iop = InstObjParams(name, Name, base_class, 707 { 'memacc_code':memacc_code, 'postacc_code':postacc_code }, 708 inst_flags) 709 710 if mem_flags: 711 mem_flags = [ 'Request::%s' % flag for flag in mem_flags ] 712 s = '\n\tmemAccessFlags = ' + string.join(mem_flags, '|') + ';' 713 iop.constructor += s 714 memacc_iop.constructor += s 715 716 # select templates 717 718 # The InitiateAcc template is the same for StoreCond templates as the 719 # corresponding Store template.. 720 StoreCondInitiateAcc = StoreInitiateAcc 721 722 memAccExecTemplate = eval(exec_template_base + 'MemAccExecute') 723 fullExecTemplate = eval(exec_template_base + 'Execute') 724 initiateAccTemplate = eval(exec_template_base + 'InitiateAcc') 725 completeAccTemplate = eval(exec_template_base + 'CompleteAcc') 726
|
| 727 if (exec_template_base == 'Load' or exec_template_base == 'Store'): 728 memAccSizeTemplate = eval('LoadStoreMemAccSize') 729 else: 730 memAccSizeTemplate = eval('MiscMemAccSize') 731
|
696 # (header_output, decoder_output, decode_block, exec_output) 697 return (LoadStoreDeclare.subst(iop), 698 EACompConstructor.subst(ea_iop) 699 + MemAccConstructor.subst(memacc_iop) 700 + LoadStoreConstructor.subst(iop), 701 decode_template.subst(iop), 702 EACompExecute.subst(ea_iop) 703 + memAccExecTemplate.subst(memacc_iop) 704 + fullExecTemplate.subst(iop) 705 + initiateAccTemplate.subst(iop)
| 732 # (header_output, decoder_output, decode_block, exec_output) 733 return (LoadStoreDeclare.subst(iop), 734 EACompConstructor.subst(ea_iop) 735 + MemAccConstructor.subst(memacc_iop) 736 + LoadStoreConstructor.subst(iop), 737 decode_template.subst(iop), 738 EACompExecute.subst(ea_iop) 739 + memAccExecTemplate.subst(memacc_iop) 740 + fullExecTemplate.subst(iop) 741 + initiateAccTemplate.subst(iop)
|
706 + completeAccTemplate.subst(iop))
| 742 + completeAccTemplate.subst(iop) 743 + memAccSizeTemplate.subst(memacc_iop))
|
707}}; 708 709def format LoadOrNop(memacc_code, ea_code = {{ EA = Rb + disp; }}, 710 mem_flags = [], inst_flags = []) {{ 711 (header_output, decoder_output, decode_block, exec_output) = \ 712 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 713 decode_template = LoadNopCheckDecode, 714 exec_template_base = 'Load') 715}}; 716 717 718// Note that the flags passed in apply only to the prefetch version 719def format LoadOrPrefetch(memacc_code, ea_code = {{ EA = Rb + disp; }}, 720 mem_flags = [], pf_flags = [], inst_flags = []) {{ 721 # declare the load instruction object and generate the decode block 722 (header_output, decoder_output, decode_block, exec_output) = \ 723 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 724 decode_template = LoadPrefetchCheckDecode, 725 exec_template_base = 'Load') 726 727 # Declare the prefetch instruction object. 728 729 # Make sure flag args are lists so we can mess with them. 730 mem_flags = makeList(mem_flags) 731 pf_flags = makeList(pf_flags) 732 inst_flags = makeList(inst_flags) 733 734 pf_mem_flags = mem_flags + pf_flags + ['NO_FAULT'] 735 pf_inst_flags = inst_flags + ['IsMemRef', 'IsLoad', 736 'IsDataPrefetch', 'MemReadOp'] 737 738 (pf_header_output, pf_decoder_output, _, pf_exec_output) = \ 739 LoadStoreBase(name, Name + 'Prefetch', ea_code, 740 'xc->prefetch(EA, memAccessFlags);', 741 pf_mem_flags, pf_inst_flags, exec_template_base = 'Misc') 742 743 header_output += pf_header_output 744 decoder_output += pf_decoder_output 745 exec_output += pf_exec_output 746}}; 747 748 749def format Store(memacc_code, ea_code = {{ EA = Rb + disp; }}, 750 mem_flags = [], inst_flags = []) {{ 751 (header_output, decoder_output, decode_block, exec_output) = \ 752 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 753 exec_template_base = 'Store') 754}}; 755 756 757def format StoreCond(memacc_code, postacc_code, 758 ea_code = {{ EA = Rb + disp; }}, 759 mem_flags = [], inst_flags = []) {{ 760 (header_output, decoder_output, decode_block, exec_output) = \ 761 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 762 postacc_code, exec_template_base = 'StoreCond') 763}}; 764 765 766// Use 'MemoryNoDisp' as base: for wh64, fetch, ecb 767def format MiscPrefetch(ea_code, memacc_code, 768 mem_flags = [], inst_flags = []) {{ 769 (header_output, decoder_output, decode_block, exec_output) = \ 770 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 771 base_class = 'MemoryNoDisp', exec_template_base = 'Misc') 772}}; 773 774
| 744}}; 745 746def format LoadOrNop(memacc_code, ea_code = {{ EA = Rb + disp; }}, 747 mem_flags = [], inst_flags = []) {{ 748 (header_output, decoder_output, decode_block, exec_output) = \ 749 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 750 decode_template = LoadNopCheckDecode, 751 exec_template_base = 'Load') 752}}; 753 754 755// Note that the flags passed in apply only to the prefetch version 756def format LoadOrPrefetch(memacc_code, ea_code = {{ EA = Rb + disp; }}, 757 mem_flags = [], pf_flags = [], inst_flags = []) {{ 758 # declare the load instruction object and generate the decode block 759 (header_output, decoder_output, decode_block, exec_output) = \ 760 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 761 decode_template = LoadPrefetchCheckDecode, 762 exec_template_base = 'Load') 763 764 # Declare the prefetch instruction object. 765 766 # Make sure flag args are lists so we can mess with them. 767 mem_flags = makeList(mem_flags) 768 pf_flags = makeList(pf_flags) 769 inst_flags = makeList(inst_flags) 770 771 pf_mem_flags = mem_flags + pf_flags + ['NO_FAULT'] 772 pf_inst_flags = inst_flags + ['IsMemRef', 'IsLoad', 773 'IsDataPrefetch', 'MemReadOp'] 774 775 (pf_header_output, pf_decoder_output, _, pf_exec_output) = \ 776 LoadStoreBase(name, Name + 'Prefetch', ea_code, 777 'xc->prefetch(EA, memAccessFlags);', 778 pf_mem_flags, pf_inst_flags, exec_template_base = 'Misc') 779 780 header_output += pf_header_output 781 decoder_output += pf_decoder_output 782 exec_output += pf_exec_output 783}}; 784 785 786def format Store(memacc_code, ea_code = {{ EA = Rb + disp; }}, 787 mem_flags = [], inst_flags = []) {{ 788 (header_output, decoder_output, decode_block, exec_output) = \ 789 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 790 exec_template_base = 'Store') 791}}; 792 793 794def format StoreCond(memacc_code, postacc_code, 795 ea_code = {{ EA = Rb + disp; }}, 796 mem_flags = [], inst_flags = []) {{ 797 (header_output, decoder_output, decode_block, exec_output) = \ 798 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 799 postacc_code, exec_template_base = 'StoreCond') 800}}; 801 802 803// Use 'MemoryNoDisp' as base: for wh64, fetch, ecb 804def format MiscPrefetch(ea_code, memacc_code, 805 mem_flags = [], inst_flags = []) {{ 806 (header_output, decoder_output, decode_block, exec_output) = \ 807 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 808 base_class = 'MemoryNoDisp', exec_template_base = 'Misc') 809}}; 810 811
|