mem.isa revision 2075
14876Sstever@eecs.umich.edu// -*- mode:c++ -*- 23646Srdreslin@umich.edu 33646Srdreslin@umich.edu// Copyright (c) 2003-2005 The Regents of The University of Michigan 43646Srdreslin@umich.edu// All rights reserved. 53646Srdreslin@umich.edu// 63646Srdreslin@umich.edu// Redistribution and use in source and binary forms, with or without 73646Srdreslin@umich.edu// modification, are permitted provided that the following conditions are 83646Srdreslin@umich.edu// met: redistributions of source code must retain the above copyright 93646Srdreslin@umich.edu// notice, this list of conditions and the following disclaimer; 103646Srdreslin@umich.edu// redistributions in binary form must reproduce the above copyright 113646Srdreslin@umich.edu// notice, this list of conditions and the following disclaimer in the 123646Srdreslin@umich.edu// documentation and/or other materials provided with the distribution; 133646Srdreslin@umich.edu// neither the name of the copyright holders nor the names of its 143646Srdreslin@umich.edu// contributors may be used to endorse or promote products derived from 153646Srdreslin@umich.edu// this software without specific prior written permission. 163646Srdreslin@umich.edu// 173646Srdreslin@umich.edu// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 183646Srdreslin@umich.edu// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 193646Srdreslin@umich.edu// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 203646Srdreslin@umich.edu// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 213646Srdreslin@umich.edu// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 223646Srdreslin@umich.edu// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 233646Srdreslin@umich.edu// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 243646Srdreslin@umich.edu// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 253646Srdreslin@umich.edu// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 263646Srdreslin@umich.edu// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 273646Srdreslin@umich.edu// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 283646Srdreslin@umich.edu 293646Srdreslin@umich.eduoutput header {{ 303646Srdreslin@umich.edu /** 313646Srdreslin@umich.edu * Base class for general Alpha memory-format instructions. 323646Srdreslin@umich.edu */ 336654Snate@binkert.org class Memory : public AlphaStaticInst 346654Snate@binkert.org { 356654Snate@binkert.org protected: 366654Snate@binkert.org 373646Srdreslin@umich.edu /// Memory request flags. See mem_req_base.hh. 383646Srdreslin@umich.edu unsigned memAccessFlags; 396654Snate@binkert.org /// Pointer to EAComp object. 406654Snate@binkert.org const StaticInstPtr<AlphaISA> eaCompPtr; 413646Srdreslin@umich.edu /// Pointer to MemAcc object. 423646Srdreslin@umich.edu const StaticInstPtr<AlphaISA> memAccPtr; 433646Srdreslin@umich.edu 443646Srdreslin@umich.edu /// Constructor 453646Srdreslin@umich.edu Memory(const char *mnem, MachInst _machInst, OpClass __opClass, 463646Srdreslin@umich.edu StaticInstPtr<AlphaISA> _eaCompPtr = nullStaticInstPtr, 473646Srdreslin@umich.edu StaticInstPtr<AlphaISA> _memAccPtr = nullStaticInstPtr) 483646Srdreslin@umich.edu : AlphaStaticInst(mnem, _machInst, __opClass), 493646Srdreslin@umich.edu memAccessFlags(0), eaCompPtr(_eaCompPtr), memAccPtr(_memAccPtr) 503646Srdreslin@umich.edu { 513646Srdreslin@umich.edu } 523646Srdreslin@umich.edu 533646Srdreslin@umich.edu std::string 543646Srdreslin@umich.edu generateDisassembly(Addr pc, const SymbolTable *symtab) const; 553646Srdreslin@umich.edu 563646Srdreslin@umich.edu public: 573646Srdreslin@umich.edu 583646Srdreslin@umich.edu const StaticInstPtr<AlphaISA> &eaCompInst() const { return eaCompPtr; } 593646Srdreslin@umich.edu const StaticInstPtr<AlphaISA> &memAccInst() const { return memAccPtr; } 603646Srdreslin@umich.edu }; 613646Srdreslin@umich.edu 623646Srdreslin@umich.edu /** 633646Srdreslin@umich.edu * Base class for memory-format instructions using a 32-bit 643646Srdreslin@umich.edu * displacement (i.e. most of them). 653646Srdreslin@umich.edu */ 663646Srdreslin@umich.edu class MemoryDisp32 : public Memory 673646Srdreslin@umich.edu { 683646Srdreslin@umich.edu protected: 693646Srdreslin@umich.edu /// Displacement for EA calculation (signed). 703646Srdreslin@umich.edu int32_t disp; 713646Srdreslin@umich.edu 723646Srdreslin@umich.edu /// Constructor. 733646Srdreslin@umich.edu MemoryDisp32(const char *mnem, MachInst _machInst, OpClass __opClass, 743646Srdreslin@umich.edu StaticInstPtr<AlphaISA> _eaCompPtr = nullStaticInstPtr, 753646Srdreslin@umich.edu StaticInstPtr<AlphaISA> _memAccPtr = nullStaticInstPtr) 763646Srdreslin@umich.edu : Memory(mnem, _machInst, __opClass, _eaCompPtr, _memAccPtr), 773646Srdreslin@umich.edu disp(MEMDISP) 783646Srdreslin@umich.edu { 793646Srdreslin@umich.edu } 803646Srdreslin@umich.edu }; 813646Srdreslin@umich.edu 823646Srdreslin@umich.edu 833646Srdreslin@umich.edu /** 843646Srdreslin@umich.edu * Base class for a few miscellaneous memory-format insts 853646Srdreslin@umich.edu * that don't interpret the disp field: wh64, fetch, fetch_m, ecb. 863646Srdreslin@umich.edu * None of these instructions has a destination register either. 873646Srdreslin@umich.edu */ 883646Srdreslin@umich.edu class MemoryNoDisp : public Memory 893646Srdreslin@umich.edu { 903646Srdreslin@umich.edu protected: 913646Srdreslin@umich.edu /// Constructor 923646Srdreslin@umich.edu MemoryNoDisp(const char *mnem, MachInst _machInst, OpClass __opClass, 933646Srdreslin@umich.edu StaticInstPtr<AlphaISA> _eaCompPtr = nullStaticInstPtr, 943646Srdreslin@umich.edu StaticInstPtr<AlphaISA> _memAccPtr = nullStaticInstPtr) 953646Srdreslin@umich.edu : Memory(mnem, _machInst, __opClass, _eaCompPtr, _memAccPtr) 963646Srdreslin@umich.edu { 973646Srdreslin@umich.edu } 983646Srdreslin@umich.edu 993646Srdreslin@umich.edu std::string 1003646Srdreslin@umich.edu generateDisassembly(Addr pc, const SymbolTable *symtab) const; 1013646Srdreslin@umich.edu }; 1023646Srdreslin@umich.edu}}; 1033646Srdreslin@umich.edu 1043646Srdreslin@umich.edu 1053646Srdreslin@umich.eduoutput decoder {{ 1063646Srdreslin@umich.edu std::string 1073646Srdreslin@umich.edu Memory::generateDisassembly(Addr pc, const SymbolTable *symtab) const 1083646Srdreslin@umich.edu { 1093646Srdreslin@umich.edu return csprintf("%-10s %c%d,%d(r%d)", mnemonic, 1103646Srdreslin@umich.edu flags[IsFloating] ? 'f' : 'r', RA, MEMDISP, RB); 1113646Srdreslin@umich.edu } 1123646Srdreslin@umich.edu 1133646Srdreslin@umich.edu std::string 1143646Srdreslin@umich.edu MemoryNoDisp::generateDisassembly(Addr pc, const SymbolTable *symtab) const 1153646Srdreslin@umich.edu { 1163646Srdreslin@umich.edu return csprintf("%-10s (r%d)", mnemonic, RB); 1173646Srdreslin@umich.edu } 1183646Srdreslin@umich.edu}}; 1193646Srdreslin@umich.edu 1203646Srdreslin@umich.edudef format LoadAddress(code) {{ 1213646Srdreslin@umich.edu iop = InstObjParams(name, Name, 'MemoryDisp32', CodeBlock(code)) 1223646Srdreslin@umich.edu header_output = BasicDeclare.subst(iop) 1233646Srdreslin@umich.edu decoder_output = BasicConstructor.subst(iop) 1243646Srdreslin@umich.edu decode_block = BasicDecode.subst(iop) 1253646Srdreslin@umich.edu exec_output = BasicExecute.subst(iop) 1263646Srdreslin@umich.edu}}; 1273646Srdreslin@umich.edu 1283646Srdreslin@umich.edu 1293646Srdreslin@umich.edudef template LoadStoreDeclare {{ 1303646Srdreslin@umich.edu /** 1313646Srdreslin@umich.edu * Static instruction class for "%(mnemonic)s". 1323646Srdreslin@umich.edu */ 1333646Srdreslin@umich.edu class %(class_name)s : public %(base_class)s 1343646Srdreslin@umich.edu { 1353646Srdreslin@umich.edu protected: 1363646Srdreslin@umich.edu 1373646Srdreslin@umich.edu /** 1383646Srdreslin@umich.edu * "Fake" effective address computation class for "%(mnemonic)s". 1393646Srdreslin@umich.edu */ 14011053Sandreas.hansson@arm.com class EAComp : public %(base_class)s 1413646Srdreslin@umich.edu { 1423646Srdreslin@umich.edu public: 1433646Srdreslin@umich.edu /// Constructor 1443646Srdreslin@umich.edu EAComp(MachInst machInst); 1453646Srdreslin@umich.edu 1463646Srdreslin@umich.edu %(BasicExecDeclare)s 1473646Srdreslin@umich.edu }; 1483646Srdreslin@umich.edu 14911053Sandreas.hansson@arm.com /** 1503646Srdreslin@umich.edu * "Fake" memory access instruction class for "%(mnemonic)s". 1513646Srdreslin@umich.edu */ 1523646Srdreslin@umich.edu class MemAcc : public %(base_class)s 1533646Srdreslin@umich.edu { 1543646Srdreslin@umich.edu public: 1553646Srdreslin@umich.edu /// Constructor 1563646Srdreslin@umich.edu MemAcc(MachInst machInst); 1573646Srdreslin@umich.edu 1583646Srdreslin@umich.edu %(BasicExecDeclare)s 1593646Srdreslin@umich.edu }; 1603646Srdreslin@umich.edu 1613646Srdreslin@umich.edu public: 1623646Srdreslin@umich.edu 1633646Srdreslin@umich.edu /// Constructor. 1643646Srdreslin@umich.edu %(class_name)s(MachInst machInst); 1653646Srdreslin@umich.edu 1663646Srdreslin@umich.edu %(BasicExecDeclare)s 1673646Srdreslin@umich.edu }; 1683646Srdreslin@umich.edu}}; 1693646Srdreslin@umich.edu 1703646Srdreslin@umich.edudef template LoadStoreConstructor {{ 1713646Srdreslin@umich.edu /** TODO: change op_class to AddrGenOp or something (requires 1723646Srdreslin@umich.edu * creating new member of OpClass enum in op_class.hh, updating 1733646Srdreslin@umich.edu * config files, etc.). */ 17410720Sandreas.hansson@arm.com inline %(class_name)s::EAComp::EAComp(MachInst machInst) 1753646Srdreslin@umich.edu : %(base_class)s("%(mnemonic)s (EAComp)", machInst, IntAluOp) 1763646Srdreslin@umich.edu { 1773646Srdreslin@umich.edu %(ea_constructor)s; 1783646Srdreslin@umich.edu } 1793646Srdreslin@umich.edu 1803646Srdreslin@umich.edu inline %(class_name)s::MemAcc::MemAcc(MachInst machInst) 1813646Srdreslin@umich.edu : %(base_class)s("%(mnemonic)s (MemAcc)", machInst, %(op_class)s) 1823646Srdreslin@umich.edu { 1833646Srdreslin@umich.edu %(memacc_constructor)s; 1843646Srdreslin@umich.edu } 1853646Srdreslin@umich.edu 1863646Srdreslin@umich.edu inline %(class_name)s::%(class_name)s(MachInst machInst) 18710720Sandreas.hansson@arm.com : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, 1883646Srdreslin@umich.edu new EAComp(machInst), new MemAcc(machInst)) 1893646Srdreslin@umich.edu { 1903646Srdreslin@umich.edu %(constructor)s; 1913646Srdreslin@umich.edu } 1923646Srdreslin@umich.edu}}; 1933646Srdreslin@umich.edu 1943646Srdreslin@umich.edu 1953646Srdreslin@umich.edudef template EACompExecute {{ 1963646Srdreslin@umich.edu Fault 1973646Srdreslin@umich.edu %(class_name)s::EAComp::execute(%(CPU_exec_context)s *xc, 1983646Srdreslin@umich.edu Trace::InstRecord *traceData) const 1993646Srdreslin@umich.edu { 20010720Sandreas.hansson@arm.com Addr EA; 2013646Srdreslin@umich.edu Fault fault = No_Fault; 2023646Srdreslin@umich.edu 2033646Srdreslin@umich.edu %(fp_enable_check)s; 2043646Srdreslin@umich.edu %(op_decl)s; 2053646Srdreslin@umich.edu %(op_rd)s; 2063646Srdreslin@umich.edu %(code)s; 2073646Srdreslin@umich.edu 2083646Srdreslin@umich.edu if (fault == No_Fault) { 2093646Srdreslin@umich.edu %(op_wb)s; 2103646Srdreslin@umich.edu xc->setEA(EA); 2113646Srdreslin@umich.edu } 2128931Sandreas.hansson@arm.com 2139036Sandreas.hansson@arm.com return fault; 21410720Sandreas.hansson@arm.com } 2159790Sakash.bagdia@arm.com}}; 2163646Srdreslin@umich.edu 21710720Sandreas.hansson@arm.comdef template LoadMemAccExecute {{ 2183646Srdreslin@umich.edu Fault 2193646Srdreslin@umich.edu %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc, 2203646Srdreslin@umich.edu Trace::InstRecord *traceData) const 2213646Srdreslin@umich.edu { 2223646Srdreslin@umich.edu Addr EA; 2233646Srdreslin@umich.edu Fault fault = No_Fault; 2248847Sandreas.hansson@arm.com 2258847Sandreas.hansson@arm.com %(fp_enable_check)s; 2268847Sandreas.hansson@arm.com %(op_decl)s; 2273646Srdreslin@umich.edu %(op_rd)s; 2283646Srdreslin@umich.edu EA = xc->getEA(); 2293646Srdreslin@umich.edu 2303646Srdreslin@umich.edu if (fault == No_Fault) { 2313646Srdreslin@umich.edu fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags); 2328847Sandreas.hansson@arm.com %(code)s; 2338847Sandreas.hansson@arm.com } 2343646Srdreslin@umich.edu 2358847Sandreas.hansson@arm.com if (fault == No_Fault) { 2368847Sandreas.hansson@arm.com %(op_wb)s; 2373646Srdreslin@umich.edu } 2383646Srdreslin@umich.edu 2393646Srdreslin@umich.edu return fault; 2403646Srdreslin@umich.edu } 2413646Srdreslin@umich.edu}}; 2428801Sgblack@eecs.umich.edu 2433646Srdreslin@umich.edu 2443646Srdreslin@umich.edudef template LoadExecute {{ 2453646Srdreslin@umich.edu Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, 2463646Srdreslin@umich.edu Trace::InstRecord *traceData) const 2473646Srdreslin@umich.edu { 2483646Srdreslin@umich.edu Addr EA; 2493646Srdreslin@umich.edu Fault fault = No_Fault; 2503646Srdreslin@umich.edu 2513646Srdreslin@umich.edu %(fp_enable_check)s; 2523646Srdreslin@umich.edu %(op_decl)s; 2533646Srdreslin@umich.edu %(op_rd)s; 2543646Srdreslin@umich.edu %(ea_code)s; 2553646Srdreslin@umich.edu 2563646Srdreslin@umich.edu if (fault == No_Fault) { 2573646Srdreslin@umich.edu fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags); 2583646Srdreslin@umich.edu %(memacc_code)s; 2593646Srdreslin@umich.edu } 2603646Srdreslin@umich.edu 2613646Srdreslin@umich.edu if (fault == No_Fault) { 2623646Srdreslin@umich.edu %(op_wb)s; 2633646Srdreslin@umich.edu } 2643646Srdreslin@umich.edu 2653646Srdreslin@umich.edu return fault; 2663646Srdreslin@umich.edu } 2673646Srdreslin@umich.edu}}; 2683646Srdreslin@umich.edu 2693646Srdreslin@umich.edu 2703646Srdreslin@umich.edudef template StoreMemAccExecute {{ 2713646Srdreslin@umich.edu Fault 2726654Snate@binkert.org %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc, 2736654Snate@binkert.org Trace::InstRecord *traceData) const 2746654Snate@binkert.org { 2756654Snate@binkert.org Addr EA; 2766654Snate@binkert.org Fault fault = No_Fault; 2773646Srdreslin@umich.edu uint64_t write_result = 0; 2783646Srdreslin@umich.edu 2793646Srdreslin@umich.edu %(fp_enable_check)s; 2803646Srdreslin@umich.edu %(op_decl)s; 2813646Srdreslin@umich.edu %(op_rd)s; 2823646Srdreslin@umich.edu EA = xc->getEA(); 2833646Srdreslin@umich.edu 2843646Srdreslin@umich.edu if (fault == No_Fault) { 2853646Srdreslin@umich.edu %(code)s; 2863646Srdreslin@umich.edu } 2873646Srdreslin@umich.edu 2883646Srdreslin@umich.edu if (fault == No_Fault) { 2893646Srdreslin@umich.edu fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA, 2903646Srdreslin@umich.edu memAccessFlags, &write_result); 2913646Srdreslin@umich.edu if (traceData) { traceData->setData(Mem); } 2923646Srdreslin@umich.edu } 2933646Srdreslin@umich.edu 2947525Ssteve.reinhardt@amd.com if (fault == No_Fault) { 2953646Srdreslin@umich.edu %(postacc_code)s; 2963646Srdreslin@umich.edu } 2973646Srdreslin@umich.edu 2983646Srdreslin@umich.edu if (fault == No_Fault) { 2993646Srdreslin@umich.edu %(op_wb)s; 3003646Srdreslin@umich.edu } 3013646Srdreslin@umich.edu 3023646Srdreslin@umich.edu return fault; 3033646Srdreslin@umich.edu } 304}}; 305 306 307def template StoreExecute {{ 308 Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, 309 Trace::InstRecord *traceData) const 310 { 311 Addr EA; 312 Fault fault = No_Fault; 313 uint64_t write_result = 0; 314 315 %(fp_enable_check)s; 316 %(op_decl)s; 317 %(op_rd)s; 318 %(ea_code)s; 319 320 if (fault == No_Fault) { 321 %(memacc_code)s; 322 } 323 324 if (fault == No_Fault) { 325 fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA, 326 memAccessFlags, &write_result); 327 if (traceData) { traceData->setData(Mem); } 328 } 329 330 if (fault == No_Fault) { 331 %(postacc_code)s; 332 } 333 334 if (fault == No_Fault) { 335 %(op_wb)s; 336 } 337 338 return fault; 339 } 340}}; 341 342 343def template MiscMemAccExecute {{ 344 Fault %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc, 345 Trace::InstRecord *traceData) const 346 { 347 Addr EA; 348 Fault fault = No_Fault; 349 350 %(fp_enable_check)s; 351 %(op_decl)s; 352 %(op_rd)s; 353 EA = xc->getEA(); 354 355 if (fault == No_Fault) { 356 %(code)s; 357 } 358 359 return No_Fault; 360 } 361}}; 362 363def template MiscExecute {{ 364 Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, 365 Trace::InstRecord *traceData) const 366 { 367 Addr EA; 368 Fault fault = No_Fault; 369 370 %(fp_enable_check)s; 371 %(op_decl)s; 372 %(op_rd)s; 373 %(ea_code)s; 374 375 if (fault == No_Fault) { 376 %(memacc_code)s; 377 } 378 379 return No_Fault; 380 } 381}}; 382 383// load instructions use Ra as dest, so check for 384// Ra == 31 to detect nops 385def template LoadNopCheckDecode {{ 386 { 387 AlphaStaticInst *i = new %(class_name)s(machInst); 388 if (RA == 31) { 389 i = makeNop(i); 390 } 391 return i; 392 } 393}}; 394 395 396// for some load instructions, Ra == 31 indicates a prefetch (not a nop) 397def template LoadPrefetchCheckDecode {{ 398 { 399 if (RA != 31) { 400 return new %(class_name)s(machInst); 401 } 402 else { 403 return new %(class_name)sPrefetch(machInst); 404 } 405 } 406}}; 407 408 409let {{ 410def LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 411 postacc_code = '', base_class = 'MemoryDisp32', 412 decode_template = BasicDecode, exec_template_base = ''): 413 # Make sure flags are in lists (convert to lists if not). 414 mem_flags = makeList(mem_flags) 415 inst_flags = makeList(inst_flags) 416 417 # add hook to get effective addresses into execution trace output. 418 ea_code += '\nif (traceData) { traceData->setAddr(EA); }\n' 419 420 # generate code block objects 421 ea_cblk = CodeBlock(ea_code) 422 memacc_cblk = CodeBlock(memacc_code) 423 postacc_cblk = CodeBlock(postacc_code) 424 425 # Some CPU models execute the memory operation as an atomic unit, 426 # while others want to separate them into an effective address 427 # computation and a memory access operation. As a result, we need 428 # to generate three StaticInst objects. Note that the latter two 429 # are nested inside the larger "atomic" one. 430 431 # generate InstObjParams for EAComp object 432 ea_iop = InstObjParams(name, Name, base_class, ea_cblk, inst_flags) 433 434 # generate InstObjParams for MemAcc object 435 memacc_iop = InstObjParams(name, Name, base_class, memacc_cblk, inst_flags) 436 # in the split execution model, the MemAcc portion is responsible 437 # for the post-access code. 438 memacc_iop.postacc_code = postacc_cblk.code 439 440 # generate InstObjParams for unified execution 441 cblk = CodeBlock(ea_code + memacc_code + postacc_code) 442 iop = InstObjParams(name, Name, base_class, cblk, inst_flags) 443 444 iop.ea_constructor = ea_cblk.constructor 445 iop.ea_code = ea_cblk.code 446 iop.memacc_constructor = memacc_cblk.constructor 447 iop.memacc_code = memacc_cblk.code 448 iop.postacc_code = postacc_cblk.code 449 450 if mem_flags: 451 s = '\n\tmemAccessFlags = ' + string.join(mem_flags, '|') + ';' 452 iop.constructor += s 453 memacc_iop.constructor += s 454 455 # select templates 456 memAccExecTemplate = eval(exec_template_base + 'MemAccExecute') 457 fullExecTemplate = eval(exec_template_base + 'Execute') 458 459 # (header_output, decoder_output, decode_block, exec_output) 460 return (LoadStoreDeclare.subst(iop), LoadStoreConstructor.subst(iop), 461 decode_template.subst(iop), 462 EACompExecute.subst(ea_iop) 463 + memAccExecTemplate.subst(memacc_iop) 464 + fullExecTemplate.subst(iop)) 465}}; 466 467 468def format LoadOrNop(memacc_code, ea_code = {{ EA = Rb + disp; }}, 469 mem_flags = [], inst_flags = []) {{ 470 (header_output, decoder_output, decode_block, exec_output) = \ 471 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 472 decode_template = LoadNopCheckDecode, 473 exec_template_base = 'Load') 474}}; 475 476 477// Note that the flags passed in apply only to the prefetch version 478def format LoadOrPrefetch(memacc_code, ea_code = {{ EA = Rb + disp; }}, 479 mem_flags = [], pf_flags = [], inst_flags = []) {{ 480 # declare the load instruction object and generate the decode block 481 (header_output, decoder_output, decode_block, exec_output) = \ 482 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 483 decode_template = LoadPrefetchCheckDecode, 484 exec_template_base = 'Load') 485 486 # Declare the prefetch instruction object. 487 488 # Make sure flag args are lists so we can mess with them. 489 mem_flags = makeList(mem_flags) 490 pf_flags = makeList(pf_flags) 491 inst_flags = makeList(inst_flags) 492 493 pf_mem_flags = mem_flags + pf_flags + ['NO_FAULT'] 494 pf_inst_flags = inst_flags + ['IsMemRef', 'IsLoad', 495 'IsDataPrefetch', 'MemReadOp'] 496 497 (pf_header_output, pf_decoder_output, _, pf_exec_output) = \ 498 LoadStoreBase(name, Name + 'Prefetch', ea_code, 499 'xc->prefetch(EA, memAccessFlags);', 500 pf_mem_flags, pf_inst_flags, exec_template_base = 'Misc') 501 502 header_output += pf_header_output 503 decoder_output += pf_decoder_output 504 exec_output += pf_exec_output 505}}; 506 507 508def format Store(memacc_code, ea_code = {{ EA = Rb + disp; }}, 509 mem_flags = [], inst_flags = []) {{ 510 (header_output, decoder_output, decode_block, exec_output) = \ 511 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 512 exec_template_base = 'Store') 513}}; 514 515 516def format StoreCond(memacc_code, postacc_code, 517 ea_code = {{ EA = Rb + disp; }}, 518 mem_flags = [], inst_flags = []) {{ 519 (header_output, decoder_output, decode_block, exec_output) = \ 520 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 521 postacc_code, exec_template_base = 'Store') 522}}; 523 524 525// Use 'MemoryNoDisp' as base: for wh64, fetch, ecb 526def format MiscPrefetch(ea_code, memacc_code, 527 mem_flags = [], inst_flags = []) {{ 528 (header_output, decoder_output, decode_block, exec_output) = \ 529 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 530 base_class = 'MemoryNoDisp', exec_template_base = 'Misc') 531}}; 532 533 534