mem.isa revision 2742
12068SN/A// -*- mode:c++ -*- 22068SN/A 32068SN/A// Copyright (c) 2003-2005 The Regents of The University of Michigan 42068SN/A// All rights reserved. 52068SN/A// 62068SN/A// Redistribution and use in source and binary forms, with or without 72068SN/A// modification, are permitted provided that the following conditions are 82068SN/A// met: redistributions of source code must retain the above copyright 92068SN/A// notice, this list of conditions and the following disclaimer; 102068SN/A// redistributions in binary form must reproduce the above copyright 112068SN/A// notice, this list of conditions and the following disclaimer in the 122068SN/A// documentation and/or other materials provided with the distribution; 132068SN/A// neither the name of the copyright holders nor the names of its 142068SN/A// contributors may be used to endorse or promote products derived from 152068SN/A// this software without specific prior written permission. 162068SN/A// 172068SN/A// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 182068SN/A// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 192068SN/A// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 202068SN/A// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 212068SN/A// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 222068SN/A// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 232068SN/A// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 242068SN/A// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 252068SN/A// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 262068SN/A// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 272068SN/A// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 282665Ssaidi@eecs.umich.edu// 292665Ssaidi@eecs.umich.edu// Authors: Steve Reinhardt 302665Ssaidi@eecs.umich.edu// Kevin Lim 312068SN/A 322649Ssaidi@eecs.umich.edu//////////////////////////////////////////////////////////////////// 332649Ssaidi@eecs.umich.edu// 342649Ssaidi@eecs.umich.edu// Memory-format instructions: LoadAddress, Load, Store 352649Ssaidi@eecs.umich.edu// 362649Ssaidi@eecs.umich.edu 372068SN/Aoutput header {{ 382068SN/A /** 392068SN/A * Base class for general Alpha memory-format instructions. 402068SN/A */ 412068SN/A class Memory : public AlphaStaticInst 422068SN/A { 432068SN/A protected: 442068SN/A 452068SN/A /// Memory request flags. See mem_req_base.hh. 462068SN/A unsigned memAccessFlags; 472068SN/A /// Pointer to EAComp object. 482107SN/A const StaticInstPtr eaCompPtr; 492068SN/A /// Pointer to MemAcc object. 502107SN/A const StaticInstPtr memAccPtr; 512068SN/A 522068SN/A /// Constructor 532227SN/A Memory(const char *mnem, ExtMachInst _machInst, OpClass __opClass, 542107SN/A StaticInstPtr _eaCompPtr = nullStaticInstPtr, 552107SN/A StaticInstPtr _memAccPtr = nullStaticInstPtr) 562068SN/A : AlphaStaticInst(mnem, _machInst, __opClass), 572068SN/A memAccessFlags(0), eaCompPtr(_eaCompPtr), memAccPtr(_memAccPtr) 582068SN/A { 592068SN/A } 602068SN/A 612068SN/A std::string 622068SN/A generateDisassembly(Addr pc, const SymbolTable *symtab) const; 632068SN/A 642068SN/A public: 652068SN/A 662107SN/A const StaticInstPtr &eaCompInst() const { return eaCompPtr; } 672107SN/A const StaticInstPtr &memAccInst() const { return memAccPtr; } 682068SN/A }; 692068SN/A 702068SN/A /** 712068SN/A * Base class for memory-format instructions using a 32-bit 722068SN/A * displacement (i.e. most of them). 732068SN/A */ 742068SN/A class MemoryDisp32 : public Memory 752068SN/A { 762068SN/A protected: 772068SN/A /// Displacement for EA calculation (signed). 782068SN/A int32_t disp; 792068SN/A 802068SN/A /// Constructor. 812227SN/A MemoryDisp32(const char *mnem, ExtMachInst _machInst, OpClass __opClass, 822107SN/A StaticInstPtr _eaCompPtr = nullStaticInstPtr, 832107SN/A StaticInstPtr _memAccPtr = nullStaticInstPtr) 842068SN/A : Memory(mnem, _machInst, __opClass, _eaCompPtr, _memAccPtr), 852068SN/A disp(MEMDISP) 862068SN/A { 872068SN/A } 882068SN/A }; 892068SN/A 902068SN/A 912068SN/A /** 922068SN/A * Base class for a few miscellaneous memory-format insts 932068SN/A * that don't interpret the disp field: wh64, fetch, fetch_m, ecb. 942068SN/A * None of these instructions has a destination register either. 952068SN/A */ 962068SN/A class MemoryNoDisp : public Memory 972068SN/A { 982068SN/A protected: 992068SN/A /// Constructor 1002227SN/A MemoryNoDisp(const char *mnem, ExtMachInst _machInst, OpClass __opClass, 1012107SN/A StaticInstPtr _eaCompPtr = nullStaticInstPtr, 1022107SN/A StaticInstPtr _memAccPtr = nullStaticInstPtr) 1032068SN/A : Memory(mnem, _machInst, __opClass, _eaCompPtr, _memAccPtr) 1042068SN/A { 1052068SN/A } 1062068SN/A 1072068SN/A std::string 1082068SN/A generateDisassembly(Addr pc, const SymbolTable *symtab) const; 1092068SN/A }; 1102068SN/A}}; 1112068SN/A 1122068SN/A 1132068SN/Aoutput decoder {{ 1142068SN/A std::string 1152068SN/A Memory::generateDisassembly(Addr pc, const SymbolTable *symtab) const 1162068SN/A { 1172068SN/A return csprintf("%-10s %c%d,%d(r%d)", mnemonic, 1182068SN/A flags[IsFloating] ? 'f' : 'r', RA, MEMDISP, RB); 1192068SN/A } 1202068SN/A 1212068SN/A std::string 1222068SN/A MemoryNoDisp::generateDisassembly(Addr pc, const SymbolTable *symtab) const 1232068SN/A { 1242068SN/A return csprintf("%-10s (r%d)", mnemonic, RB); 1252068SN/A } 1262068SN/A}}; 1272068SN/A 1282068SN/Adef format LoadAddress(code) {{ 1292068SN/A iop = InstObjParams(name, Name, 'MemoryDisp32', CodeBlock(code)) 1302068SN/A header_output = BasicDeclare.subst(iop) 1312068SN/A decoder_output = BasicConstructor.subst(iop) 1322068SN/A decode_block = BasicDecode.subst(iop) 1332068SN/A exec_output = BasicExecute.subst(iop) 1342068SN/A}}; 1352068SN/A 1362068SN/A 1372068SN/Adef template LoadStoreDeclare {{ 1382068SN/A /** 1392068SN/A * Static instruction class for "%(mnemonic)s". 1402068SN/A */ 1412068SN/A class %(class_name)s : public %(base_class)s 1422068SN/A { 1432068SN/A protected: 1442068SN/A 1452068SN/A /** 1462068SN/A * "Fake" effective address computation class for "%(mnemonic)s". 1472068SN/A */ 1482068SN/A class EAComp : public %(base_class)s 1492068SN/A { 1502068SN/A public: 1512068SN/A /// Constructor 1522227SN/A EAComp(ExtMachInst machInst); 1532068SN/A 1542068SN/A %(BasicExecDeclare)s 1552068SN/A }; 1562068SN/A 1572068SN/A /** 1582068SN/A * "Fake" memory access instruction class for "%(mnemonic)s". 1592068SN/A */ 1602068SN/A class MemAcc : public %(base_class)s 1612068SN/A { 1622068SN/A public: 1632068SN/A /// Constructor 1642227SN/A MemAcc(ExtMachInst machInst); 1652068SN/A 1662068SN/A %(BasicExecDeclare)s 1672068SN/A }; 1682068SN/A 1692068SN/A public: 1702068SN/A 1712068SN/A /// Constructor. 1722227SN/A %(class_name)s(ExtMachInst machInst); 1732068SN/A 1742068SN/A %(BasicExecDeclare)s 1752095SN/A 1762095SN/A %(InitiateAccDeclare)s 1772095SN/A 1782095SN/A %(CompleteAccDeclare)s 1792068SN/A }; 1802068SN/A}}; 1812068SN/A 1822095SN/A 1832095SN/Adef template InitiateAccDeclare {{ 1842132SN/A Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const; 1852095SN/A}}; 1862095SN/A 1872095SN/A 1882095SN/Adef template CompleteAccDeclare {{ 1892623SN/A Fault completeAcc(Packet *, %(CPU_exec_context)s *, 1902623SN/A Trace::InstRecord *) const; 1912095SN/A}}; 1922095SN/A 1932095SN/A 1942068SN/Adef template LoadStoreConstructor {{ 1952068SN/A /** TODO: change op_class to AddrGenOp or something (requires 1962068SN/A * creating new member of OpClass enum in op_class.hh, updating 1972068SN/A * config files, etc.). */ 1982227SN/A inline %(class_name)s::EAComp::EAComp(ExtMachInst machInst) 1992068SN/A : %(base_class)s("%(mnemonic)s (EAComp)", machInst, IntAluOp) 2002068SN/A { 2012068SN/A %(ea_constructor)s; 2022068SN/A } 2032068SN/A 2042227SN/A inline %(class_name)s::MemAcc::MemAcc(ExtMachInst machInst) 2052068SN/A : %(base_class)s("%(mnemonic)s (MemAcc)", machInst, %(op_class)s) 2062068SN/A { 2072068SN/A %(memacc_constructor)s; 2082068SN/A } 2092068SN/A 2102227SN/A inline %(class_name)s::%(class_name)s(ExtMachInst machInst) 2112068SN/A : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, 2122068SN/A new EAComp(machInst), new MemAcc(machInst)) 2132068SN/A { 2142068SN/A %(constructor)s; 2152068SN/A } 2162068SN/A}}; 2172068SN/A 2182068SN/A 2192068SN/Adef template EACompExecute {{ 2202132SN/A Fault 2212068SN/A %(class_name)s::EAComp::execute(%(CPU_exec_context)s *xc, 2222068SN/A Trace::InstRecord *traceData) const 2232068SN/A { 2242068SN/A Addr EA; 2252132SN/A Fault fault = NoFault; 2262068SN/A 2272068SN/A %(fp_enable_check)s; 2282068SN/A %(op_decl)s; 2292068SN/A %(op_rd)s; 2302068SN/A %(code)s; 2312068SN/A 2322090SN/A if (fault == NoFault) { 2332068SN/A %(op_wb)s; 2342068SN/A xc->setEA(EA); 2352068SN/A } 2362068SN/A 2372068SN/A return fault; 2382068SN/A } 2392068SN/A}}; 2402068SN/A 2412069SN/Adef template LoadMemAccExecute {{ 2422132SN/A Fault 2432068SN/A %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc, 2442068SN/A Trace::InstRecord *traceData) const 2452068SN/A { 2462068SN/A Addr EA; 2472132SN/A Fault fault = NoFault; 2482068SN/A 2492068SN/A %(fp_enable_check)s; 2502068SN/A %(op_decl)s; 2512069SN/A %(op_rd)s; 2522068SN/A EA = xc->getEA(); 2532068SN/A 2542090SN/A if (fault == NoFault) { 2552069SN/A fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags); 2562068SN/A %(code)s; 2572068SN/A } 2582068SN/A 2592090SN/A if (fault == NoFault) { 2602069SN/A %(op_wb)s; 2612068SN/A } 2622068SN/A 2632068SN/A return fault; 2642068SN/A } 2652068SN/A}}; 2662068SN/A 2672068SN/A 2682069SN/Adef template LoadExecute {{ 2692132SN/A Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, 2702068SN/A Trace::InstRecord *traceData) const 2712068SN/A { 2722068SN/A Addr EA; 2732132SN/A Fault fault = NoFault; 2742068SN/A 2752068SN/A %(fp_enable_check)s; 2762068SN/A %(op_decl)s; 2772069SN/A %(op_rd)s; 2782068SN/A %(ea_code)s; 2792068SN/A 2802090SN/A if (fault == NoFault) { 2812069SN/A fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags); 2822068SN/A %(memacc_code)s; 2832068SN/A } 2842068SN/A 2852090SN/A if (fault == NoFault) { 2862069SN/A %(op_wb)s; 2872069SN/A } 2882069SN/A 2892069SN/A return fault; 2902069SN/A } 2912069SN/A}}; 2922069SN/A 2932069SN/A 2942095SN/Adef template LoadInitiateAcc {{ 2952132SN/A Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc, 2962095SN/A Trace::InstRecord *traceData) const 2972095SN/A { 2982095SN/A Addr EA; 2992132SN/A Fault fault = NoFault; 3002095SN/A 3012095SN/A %(fp_enable_check)s; 3022095SN/A %(op_src_decl)s; 3032095SN/A %(op_rd)s; 3042095SN/A %(ea_code)s; 3052095SN/A 3062098SN/A if (fault == NoFault) { 3072095SN/A fault = xc->read(EA, (uint%(mem_acc_size)d_t &)Mem, memAccessFlags); 3082095SN/A } 3092095SN/A 3102095SN/A return fault; 3112095SN/A } 3122095SN/A}}; 3132095SN/A 3142095SN/A 3152095SN/Adef template LoadCompleteAcc {{ 3162623SN/A Fault %(class_name)s::completeAcc(Packet *pkt, 3172095SN/A %(CPU_exec_context)s *xc, 3182095SN/A Trace::InstRecord *traceData) const 3192095SN/A { 3202132SN/A Fault fault = NoFault; 3212095SN/A 3222095SN/A %(fp_enable_check)s; 3232506SN/A %(op_decl)s; 3242095SN/A 3252623SN/A Mem = pkt->get<typeof(Mem)>(); 3262095SN/A 3272098SN/A if (fault == NoFault) { 3282095SN/A %(memacc_code)s; 3292095SN/A } 3302095SN/A 3312098SN/A if (fault == NoFault) { 3322095SN/A %(op_wb)s; 3332095SN/A } 3342095SN/A 3352095SN/A return fault; 3362095SN/A } 3372095SN/A}}; 3382095SN/A 3392095SN/A 3402069SN/Adef template StoreMemAccExecute {{ 3412132SN/A Fault 3422069SN/A %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc, 3432069SN/A Trace::InstRecord *traceData) const 3442069SN/A { 3452069SN/A Addr EA; 3462132SN/A Fault fault = NoFault; 3472069SN/A uint64_t write_result = 0; 3482069SN/A 3492069SN/A %(fp_enable_check)s; 3502069SN/A %(op_decl)s; 3512069SN/A %(op_rd)s; 3522069SN/A EA = xc->getEA(); 3532069SN/A 3542090SN/A if (fault == NoFault) { 3552069SN/A %(code)s; 3562069SN/A } 3572069SN/A 3582090SN/A if (fault == NoFault) { 3592069SN/A fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA, 3602069SN/A memAccessFlags, &write_result); 3612069SN/A if (traceData) { traceData->setData(Mem); } 3622068SN/A } 3632068SN/A 3642090SN/A if (fault == NoFault) { 3652068SN/A %(postacc_code)s; 3662068SN/A } 3672068SN/A 3682090SN/A if (fault == NoFault) { 3692069SN/A %(op_wb)s; 3702068SN/A } 3712068SN/A 3722068SN/A return fault; 3732068SN/A } 3742068SN/A}}; 3752068SN/A 3762068SN/A 3772069SN/Adef template StoreExecute {{ 3782132SN/A Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, 3792069SN/A Trace::InstRecord *traceData) const 3802069SN/A { 3812069SN/A Addr EA; 3822132SN/A Fault fault = NoFault; 3832069SN/A uint64_t write_result = 0; 3842069SN/A 3852069SN/A %(fp_enable_check)s; 3862069SN/A %(op_decl)s; 3872069SN/A %(op_rd)s; 3882069SN/A %(ea_code)s; 3892069SN/A 3902090SN/A if (fault == NoFault) { 3912069SN/A %(memacc_code)s; 3922069SN/A } 3932069SN/A 3942090SN/A if (fault == NoFault) { 3952069SN/A fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA, 3962069SN/A memAccessFlags, &write_result); 3972069SN/A if (traceData) { traceData->setData(Mem); } 3982069SN/A } 3992069SN/A 4002090SN/A if (fault == NoFault) { 4012069SN/A %(postacc_code)s; 4022069SN/A } 4032069SN/A 4042090SN/A if (fault == NoFault) { 4052069SN/A %(op_wb)s; 4062069SN/A } 4072069SN/A 4082069SN/A return fault; 4092069SN/A } 4102069SN/A}}; 4112069SN/A 4122095SN/Adef template StoreInitiateAcc {{ 4132132SN/A Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc, 4142095SN/A Trace::InstRecord *traceData) const 4152095SN/A { 4162095SN/A Addr EA; 4172132SN/A Fault fault = NoFault; 4182095SN/A 4192095SN/A %(fp_enable_check)s; 4202506SN/A %(op_decl)s; 4212095SN/A %(op_rd)s; 4222095SN/A %(ea_code)s; 4232095SN/A 4242098SN/A if (fault == NoFault) { 4252095SN/A %(memacc_code)s; 4262095SN/A } 4272095SN/A 4282098SN/A if (fault == NoFault) { 4292095SN/A fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA, 4302623SN/A memAccessFlags, NULL); 4312095SN/A if (traceData) { traceData->setData(Mem); } 4322095SN/A } 4332095SN/A 4342095SN/A return fault; 4352095SN/A } 4362095SN/A}}; 4372095SN/A 4382095SN/A 4392095SN/Adef template StoreCompleteAcc {{ 4402623SN/A Fault %(class_name)s::completeAcc(Packet *pkt, 4412095SN/A %(CPU_exec_context)s *xc, 4422095SN/A Trace::InstRecord *traceData) const 4432095SN/A { 4442132SN/A Fault fault = NoFault; 4452095SN/A 4462095SN/A %(fp_enable_check)s; 4472095SN/A %(op_dest_decl)s; 4482095SN/A 4492623SN/A if (fault == NoFault) { 4502623SN/A %(postacc_code)s; 4512623SN/A } 4522623SN/A 4532623SN/A if (fault == NoFault) { 4542623SN/A %(op_wb)s; 4552623SN/A } 4562623SN/A 4572623SN/A return fault; 4582623SN/A } 4592623SN/A}}; 4602623SN/A 4612623SN/A 4622623SN/Adef template StoreCondCompleteAcc {{ 4632623SN/A Fault %(class_name)s::completeAcc(Packet *pkt, 4642623SN/A %(CPU_exec_context)s *xc, 4652623SN/A Trace::InstRecord *traceData) const 4662623SN/A { 4672623SN/A Fault fault = NoFault; 4682623SN/A 4692623SN/A %(fp_enable_check)s; 4702623SN/A %(op_dest_decl)s; 4712623SN/A 4722623SN/A uint64_t write_result = pkt->req->getScResult(); 4732095SN/A 4742098SN/A if (fault == NoFault) { 4752095SN/A %(postacc_code)s; 4762095SN/A } 4772095SN/A 4782098SN/A if (fault == NoFault) { 4792095SN/A %(op_wb)s; 4802095SN/A } 4812095SN/A 4822095SN/A return fault; 4832095SN/A } 4842095SN/A}}; 4852095SN/A 4862069SN/A 4872069SN/Adef template MiscMemAccExecute {{ 4882132SN/A Fault %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc, 4892069SN/A Trace::InstRecord *traceData) const 4902069SN/A { 4912069SN/A Addr EA; 4922132SN/A Fault fault = NoFault; 4932069SN/A 4942069SN/A %(fp_enable_check)s; 4952069SN/A %(op_decl)s; 4962069SN/A %(op_rd)s; 4972069SN/A EA = xc->getEA(); 4982069SN/A 4992090SN/A if (fault == NoFault) { 5002069SN/A %(code)s; 5012069SN/A } 5022069SN/A 5032090SN/A return NoFault; 5042069SN/A } 5052069SN/A}}; 5062069SN/A 5072069SN/Adef template MiscExecute {{ 5082132SN/A Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, 5092068SN/A Trace::InstRecord *traceData) const 5102068SN/A { 5112068SN/A Addr EA; 5122132SN/A Fault fault = NoFault; 5132068SN/A 5142068SN/A %(fp_enable_check)s; 5152068SN/A %(op_decl)s; 5162069SN/A %(op_rd)s; 5172068SN/A %(ea_code)s; 5182068SN/A 5192090SN/A if (fault == NoFault) { 5202069SN/A %(memacc_code)s; 5212068SN/A } 5222068SN/A 5232090SN/A return NoFault; 5242068SN/A } 5252068SN/A}}; 5262068SN/A 5272095SN/Adef template MiscInitiateAcc {{ 5282132SN/A Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc, 5292095SN/A Trace::InstRecord *traceData) const 5302095SN/A { 5312110SN/A panic("Misc instruction does not support split access method!"); 5322098SN/A return NoFault; 5332095SN/A } 5342095SN/A}}; 5352095SN/A 5362095SN/A 5372095SN/Adef template MiscCompleteAcc {{ 5382623SN/A Fault %(class_name)s::completeAcc(Packet *pkt, 5392095SN/A %(CPU_exec_context)s *xc, 5402095SN/A Trace::InstRecord *traceData) const 5412095SN/A { 5422110SN/A panic("Misc instruction does not support split access method!"); 5432110SN/A 5442098SN/A return NoFault; 5452095SN/A } 5462095SN/A}}; 5472095SN/A 5482068SN/A// load instructions use Ra as dest, so check for 5492068SN/A// Ra == 31 to detect nops 5502068SN/Adef template LoadNopCheckDecode {{ 5512068SN/A { 5522068SN/A AlphaStaticInst *i = new %(class_name)s(machInst); 5532068SN/A if (RA == 31) { 5542068SN/A i = makeNop(i); 5552068SN/A } 5562068SN/A return i; 5572068SN/A } 5582068SN/A}}; 5592068SN/A 5602068SN/A 5612068SN/A// for some load instructions, Ra == 31 indicates a prefetch (not a nop) 5622068SN/Adef template LoadPrefetchCheckDecode {{ 5632068SN/A { 5642068SN/A if (RA != 31) { 5652068SN/A return new %(class_name)s(machInst); 5662068SN/A } 5672068SN/A else { 5682068SN/A return new %(class_name)sPrefetch(machInst); 5692068SN/A } 5702068SN/A } 5712068SN/A}}; 5722068SN/A 5732068SN/A 5742068SN/Alet {{ 5752075SN/Adef LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 5762075SN/A postacc_code = '', base_class = 'MemoryDisp32', 5772069SN/A decode_template = BasicDecode, exec_template_base = ''): 5782075SN/A # Make sure flags are in lists (convert to lists if not). 5792075SN/A mem_flags = makeList(mem_flags) 5802075SN/A inst_flags = makeList(inst_flags) 5812068SN/A 5822068SN/A # add hook to get effective addresses into execution trace output. 5832068SN/A ea_code += '\nif (traceData) { traceData->setAddr(EA); }\n' 5842068SN/A 5852068SN/A # generate code block objects 5862068SN/A ea_cblk = CodeBlock(ea_code) 5872068SN/A memacc_cblk = CodeBlock(memacc_code) 5882068SN/A postacc_cblk = CodeBlock(postacc_code) 5892068SN/A 5902068SN/A # Some CPU models execute the memory operation as an atomic unit, 5912068SN/A # while others want to separate them into an effective address 5922068SN/A # computation and a memory access operation. As a result, we need 5932068SN/A # to generate three StaticInst objects. Note that the latter two 5942068SN/A # are nested inside the larger "atomic" one. 5952068SN/A 5962068SN/A # generate InstObjParams for EAComp object 5972068SN/A ea_iop = InstObjParams(name, Name, base_class, ea_cblk, inst_flags) 5982068SN/A 5992068SN/A # generate InstObjParams for MemAcc object 6002068SN/A memacc_iop = InstObjParams(name, Name, base_class, memacc_cblk, inst_flags) 6012068SN/A # in the split execution model, the MemAcc portion is responsible 6022068SN/A # for the post-access code. 6032068SN/A memacc_iop.postacc_code = postacc_cblk.code 6042068SN/A 6052110SN/A # generate InstObjParams for InitiateAcc, CompleteAcc object 6062110SN/A # The code used depends on the template being used 6072110SN/A if (exec_template_base == 'Load'): 6082110SN/A initiateacc_cblk = CodeBlock(ea_code + memacc_code) 6092110SN/A completeacc_cblk = CodeBlock(memacc_code + postacc_code) 6102623SN/A elif (exec_template_base.startswith('Store')): 6112110SN/A initiateacc_cblk = CodeBlock(ea_code + memacc_code) 6122110SN/A completeacc_cblk = CodeBlock(postacc_code) 6132110SN/A else: 6142110SN/A initiateacc_cblk = '' 6152110SN/A completeacc_cblk = '' 6162110SN/A 6172110SN/A initiateacc_iop = InstObjParams(name, Name, base_class, initiateacc_cblk, 6182110SN/A inst_flags) 6192110SN/A 6202110SN/A completeacc_iop = InstObjParams(name, Name, base_class, completeacc_cblk, 6212110SN/A inst_flags) 6222110SN/A 6232110SN/A if (exec_template_base == 'Load'): 6242110SN/A initiateacc_iop.ea_code = ea_cblk.code 6252110SN/A initiateacc_iop.memacc_code = memacc_cblk.code 6262110SN/A completeacc_iop.memacc_code = memacc_cblk.code 6272110SN/A completeacc_iop.postacc_code = postacc_cblk.code 6282623SN/A elif (exec_template_base.startswith('Store')): 6292110SN/A initiateacc_iop.ea_code = ea_cblk.code 6302110SN/A initiateacc_iop.memacc_code = memacc_cblk.code 6312110SN/A completeacc_iop.postacc_code = postacc_cblk.code 6322110SN/A 6332068SN/A # generate InstObjParams for unified execution 6342068SN/A cblk = CodeBlock(ea_code + memacc_code + postacc_code) 6352068SN/A iop = InstObjParams(name, Name, base_class, cblk, inst_flags) 6362068SN/A 6372068SN/A iop.ea_constructor = ea_cblk.constructor 6382068SN/A iop.ea_code = ea_cblk.code 6392068SN/A iop.memacc_constructor = memacc_cblk.constructor 6402068SN/A iop.memacc_code = memacc_cblk.code 6412068SN/A iop.postacc_code = postacc_cblk.code 6422068SN/A 6432068SN/A if mem_flags: 6442068SN/A s = '\n\tmemAccessFlags = ' + string.join(mem_flags, '|') + ';' 6452068SN/A iop.constructor += s 6462068SN/A memacc_iop.constructor += s 6472068SN/A 6482069SN/A # select templates 6492623SN/A 6502623SN/A # define aliases... most StoreCond templates are the same as the 6512623SN/A # corresponding Store templates (only CompleteAcc is different). 6522623SN/A StoreCondMemAccExecute = StoreMemAccExecute 6532623SN/A StoreCondExecute = StoreExecute 6542623SN/A StoreCondInitiateAcc = StoreInitiateAcc 6552623SN/A 6562069SN/A memAccExecTemplate = eval(exec_template_base + 'MemAccExecute') 6572069SN/A fullExecTemplate = eval(exec_template_base + 'Execute') 6582095SN/A initiateAccTemplate = eval(exec_template_base + 'InitiateAcc') 6592095SN/A completeAccTemplate = eval(exec_template_base + 'CompleteAcc') 6602069SN/A 6612068SN/A # (header_output, decoder_output, decode_block, exec_output) 6622068SN/A return (LoadStoreDeclare.subst(iop), LoadStoreConstructor.subst(iop), 6632068SN/A decode_template.subst(iop), 6642068SN/A EACompExecute.subst(ea_iop) 6652069SN/A + memAccExecTemplate.subst(memacc_iop) 6662095SN/A + fullExecTemplate.subst(iop) 6672110SN/A + initiateAccTemplate.subst(initiateacc_iop) 6682110SN/A + completeAccTemplate.subst(completeacc_iop)) 6692068SN/A}}; 6702068SN/A 6712068SN/A 6722075SN/Adef format LoadOrNop(memacc_code, ea_code = {{ EA = Rb + disp; }}, 6732075SN/A mem_flags = [], inst_flags = []) {{ 6742068SN/A (header_output, decoder_output, decode_block, exec_output) = \ 6752075SN/A LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 6762069SN/A decode_template = LoadNopCheckDecode, 6772069SN/A exec_template_base = 'Load') 6782068SN/A}}; 6792068SN/A 6802068SN/A 6812068SN/A// Note that the flags passed in apply only to the prefetch version 6822075SN/Adef format LoadOrPrefetch(memacc_code, ea_code = {{ EA = Rb + disp; }}, 6832075SN/A mem_flags = [], pf_flags = [], inst_flags = []) {{ 6842068SN/A # declare the load instruction object and generate the decode block 6852068SN/A (header_output, decoder_output, decode_block, exec_output) = \ 6862075SN/A LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 6872069SN/A decode_template = LoadPrefetchCheckDecode, 6882069SN/A exec_template_base = 'Load') 6892068SN/A 6902068SN/A # Declare the prefetch instruction object. 6912068SN/A 6922075SN/A # Make sure flag args are lists so we can mess with them. 6932075SN/A mem_flags = makeList(mem_flags) 6942075SN/A pf_flags = makeList(pf_flags) 6952075SN/A inst_flags = makeList(inst_flags) 6962075SN/A 6972075SN/A pf_mem_flags = mem_flags + pf_flags + ['NO_FAULT'] 6982075SN/A pf_inst_flags = inst_flags + ['IsMemRef', 'IsLoad', 6992075SN/A 'IsDataPrefetch', 'MemReadOp'] 7002068SN/A 7012068SN/A (pf_header_output, pf_decoder_output, _, pf_exec_output) = \ 7022069SN/A LoadStoreBase(name, Name + 'Prefetch', ea_code, 7032069SN/A 'xc->prefetch(EA, memAccessFlags);', 7042075SN/A pf_mem_flags, pf_inst_flags, exec_template_base = 'Misc') 7052068SN/A 7062068SN/A header_output += pf_header_output 7072068SN/A decoder_output += pf_decoder_output 7082068SN/A exec_output += pf_exec_output 7092068SN/A}}; 7102068SN/A 7112068SN/A 7122075SN/Adef format Store(memacc_code, ea_code = {{ EA = Rb + disp; }}, 7132075SN/A mem_flags = [], inst_flags = []) {{ 7142068SN/A (header_output, decoder_output, decode_block, exec_output) = \ 7152075SN/A LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 7162069SN/A exec_template_base = 'Store') 7172068SN/A}}; 7182068SN/A 7192068SN/A 7202075SN/Adef format StoreCond(memacc_code, postacc_code, 7212075SN/A ea_code = {{ EA = Rb + disp; }}, 7222075SN/A mem_flags = [], inst_flags = []) {{ 7232068SN/A (header_output, decoder_output, decode_block, exec_output) = \ 7242075SN/A LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 7252623SN/A postacc_code, exec_template_base = 'StoreCond') 7262068SN/A}}; 7272068SN/A 7282068SN/A 7292068SN/A// Use 'MemoryNoDisp' as base: for wh64, fetch, ecb 7302075SN/Adef format MiscPrefetch(ea_code, memacc_code, 7312075SN/A mem_flags = [], inst_flags = []) {{ 7322068SN/A (header_output, decoder_output, decode_block, exec_output) = \ 7332075SN/A LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 7342069SN/A base_class = 'MemoryNoDisp', exec_template_base = 'Misc') 7352068SN/A}}; 7362068SN/A 7372068SN/A 738