mem.isa revision 2649
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. 282068SN/A 292649Ssaidi@eecs.umich.edu//////////////////////////////////////////////////////////////////// 302649Ssaidi@eecs.umich.edu// 312649Ssaidi@eecs.umich.edu// Memory-format instructions: LoadAddress, Load, Store 322649Ssaidi@eecs.umich.edu// 332649Ssaidi@eecs.umich.edu 342068SN/Aoutput header {{ 352068SN/A /** 362068SN/A * Base class for general Alpha memory-format instructions. 372068SN/A */ 382068SN/A class Memory : public AlphaStaticInst 392068SN/A { 402068SN/A protected: 412068SN/A 422068SN/A /// Memory request flags. See mem_req_base.hh. 432068SN/A unsigned memAccessFlags; 442068SN/A /// Pointer to EAComp object. 452107SN/A const StaticInstPtr eaCompPtr; 462068SN/A /// Pointer to MemAcc object. 472107SN/A const StaticInstPtr memAccPtr; 482068SN/A 492068SN/A /// Constructor 502227SN/A Memory(const char *mnem, ExtMachInst _machInst, OpClass __opClass, 512107SN/A StaticInstPtr _eaCompPtr = nullStaticInstPtr, 522107SN/A StaticInstPtr _memAccPtr = nullStaticInstPtr) 532068SN/A : AlphaStaticInst(mnem, _machInst, __opClass), 542068SN/A memAccessFlags(0), eaCompPtr(_eaCompPtr), memAccPtr(_memAccPtr) 552068SN/A { 562068SN/A } 572068SN/A 582068SN/A std::string 592068SN/A generateDisassembly(Addr pc, const SymbolTable *symtab) const; 602068SN/A 612068SN/A public: 622068SN/A 632107SN/A const StaticInstPtr &eaCompInst() const { return eaCompPtr; } 642107SN/A const StaticInstPtr &memAccInst() const { return memAccPtr; } 652068SN/A }; 662068SN/A 672068SN/A /** 682068SN/A * Base class for memory-format instructions using a 32-bit 692068SN/A * displacement (i.e. most of them). 702068SN/A */ 712068SN/A class MemoryDisp32 : public Memory 722068SN/A { 732068SN/A protected: 742068SN/A /// Displacement for EA calculation (signed). 752068SN/A int32_t disp; 762068SN/A 772068SN/A /// Constructor. 782227SN/A MemoryDisp32(const char *mnem, ExtMachInst _machInst, OpClass __opClass, 792107SN/A StaticInstPtr _eaCompPtr = nullStaticInstPtr, 802107SN/A StaticInstPtr _memAccPtr = nullStaticInstPtr) 812068SN/A : Memory(mnem, _machInst, __opClass, _eaCompPtr, _memAccPtr), 822068SN/A disp(MEMDISP) 832068SN/A { 842068SN/A } 852068SN/A }; 862068SN/A 872068SN/A 882068SN/A /** 892068SN/A * Base class for a few miscellaneous memory-format insts 902068SN/A * that don't interpret the disp field: wh64, fetch, fetch_m, ecb. 912068SN/A * None of these instructions has a destination register either. 922068SN/A */ 932068SN/A class MemoryNoDisp : public Memory 942068SN/A { 952068SN/A protected: 962068SN/A /// Constructor 972227SN/A MemoryNoDisp(const char *mnem, ExtMachInst _machInst, OpClass __opClass, 982107SN/A StaticInstPtr _eaCompPtr = nullStaticInstPtr, 992107SN/A StaticInstPtr _memAccPtr = nullStaticInstPtr) 1002068SN/A : Memory(mnem, _machInst, __opClass, _eaCompPtr, _memAccPtr) 1012068SN/A { 1022068SN/A } 1032068SN/A 1042068SN/A std::string 1052068SN/A generateDisassembly(Addr pc, const SymbolTable *symtab) const; 1062068SN/A }; 1072068SN/A}}; 1082068SN/A 1092068SN/A 1102068SN/Aoutput decoder {{ 1112068SN/A std::string 1122068SN/A Memory::generateDisassembly(Addr pc, const SymbolTable *symtab) const 1132068SN/A { 1142068SN/A return csprintf("%-10s %c%d,%d(r%d)", mnemonic, 1152068SN/A flags[IsFloating] ? 'f' : 'r', RA, MEMDISP, RB); 1162068SN/A } 1172068SN/A 1182068SN/A std::string 1192068SN/A MemoryNoDisp::generateDisassembly(Addr pc, const SymbolTable *symtab) const 1202068SN/A { 1212068SN/A return csprintf("%-10s (r%d)", mnemonic, RB); 1222068SN/A } 1232068SN/A}}; 1242068SN/A 1252068SN/Adef format LoadAddress(code) {{ 1262068SN/A iop = InstObjParams(name, Name, 'MemoryDisp32', CodeBlock(code)) 1272068SN/A header_output = BasicDeclare.subst(iop) 1282068SN/A decoder_output = BasicConstructor.subst(iop) 1292068SN/A decode_block = BasicDecode.subst(iop) 1302068SN/A exec_output = BasicExecute.subst(iop) 1312068SN/A}}; 1322068SN/A 1332068SN/A 1342068SN/Adef template LoadStoreDeclare {{ 1352068SN/A /** 1362068SN/A * Static instruction class for "%(mnemonic)s". 1372068SN/A */ 1382068SN/A class %(class_name)s : public %(base_class)s 1392068SN/A { 1402068SN/A protected: 1412068SN/A 1422068SN/A /** 1432068SN/A * "Fake" effective address computation class for "%(mnemonic)s". 1442068SN/A */ 1452068SN/A class EAComp : public %(base_class)s 1462068SN/A { 1472068SN/A public: 1482068SN/A /// Constructor 1492227SN/A EAComp(ExtMachInst machInst); 1502068SN/A 1512068SN/A %(BasicExecDeclare)s 1522068SN/A }; 1532068SN/A 1542068SN/A /** 1552068SN/A * "Fake" memory access instruction class for "%(mnemonic)s". 1562068SN/A */ 1572068SN/A class MemAcc : public %(base_class)s 1582068SN/A { 1592068SN/A public: 1602068SN/A /// Constructor 1612227SN/A MemAcc(ExtMachInst machInst); 1622068SN/A 1632068SN/A %(BasicExecDeclare)s 1642068SN/A }; 1652068SN/A 1662068SN/A public: 1672068SN/A 1682068SN/A /// Constructor. 1692227SN/A %(class_name)s(ExtMachInst machInst); 1702068SN/A 1712068SN/A %(BasicExecDeclare)s 1722095SN/A 1732095SN/A %(InitiateAccDeclare)s 1742095SN/A 1752095SN/A %(CompleteAccDeclare)s 1762068SN/A }; 1772068SN/A}}; 1782068SN/A 1792095SN/A 1802095SN/Adef template InitiateAccDeclare {{ 1812132SN/A Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const; 1822095SN/A}}; 1832095SN/A 1842095SN/A 1852095SN/Adef template CompleteAccDeclare {{ 1862623SN/A Fault completeAcc(Packet *, %(CPU_exec_context)s *, 1872623SN/A Trace::InstRecord *) const; 1882095SN/A}}; 1892095SN/A 1902095SN/A 1912068SN/Adef template LoadStoreConstructor {{ 1922068SN/A /** TODO: change op_class to AddrGenOp or something (requires 1932068SN/A * creating new member of OpClass enum in op_class.hh, updating 1942068SN/A * config files, etc.). */ 1952227SN/A inline %(class_name)s::EAComp::EAComp(ExtMachInst machInst) 1962068SN/A : %(base_class)s("%(mnemonic)s (EAComp)", machInst, IntAluOp) 1972068SN/A { 1982068SN/A %(ea_constructor)s; 1992068SN/A } 2002068SN/A 2012227SN/A inline %(class_name)s::MemAcc::MemAcc(ExtMachInst machInst) 2022068SN/A : %(base_class)s("%(mnemonic)s (MemAcc)", machInst, %(op_class)s) 2032068SN/A { 2042068SN/A %(memacc_constructor)s; 2052068SN/A } 2062068SN/A 2072227SN/A inline %(class_name)s::%(class_name)s(ExtMachInst machInst) 2082068SN/A : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, 2092068SN/A new EAComp(machInst), new MemAcc(machInst)) 2102068SN/A { 2112068SN/A %(constructor)s; 2122068SN/A } 2132068SN/A}}; 2142068SN/A 2152068SN/A 2162068SN/Adef template EACompExecute {{ 2172132SN/A Fault 2182068SN/A %(class_name)s::EAComp::execute(%(CPU_exec_context)s *xc, 2192068SN/A Trace::InstRecord *traceData) const 2202068SN/A { 2212068SN/A Addr EA; 2222132SN/A Fault fault = NoFault; 2232068SN/A 2242068SN/A %(fp_enable_check)s; 2252068SN/A %(op_decl)s; 2262068SN/A %(op_rd)s; 2272068SN/A %(code)s; 2282068SN/A 2292090SN/A if (fault == NoFault) { 2302068SN/A %(op_wb)s; 2312068SN/A xc->setEA(EA); 2322068SN/A } 2332068SN/A 2342068SN/A return fault; 2352068SN/A } 2362068SN/A}}; 2372068SN/A 2382069SN/Adef template LoadMemAccExecute {{ 2392132SN/A Fault 2402068SN/A %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc, 2412068SN/A Trace::InstRecord *traceData) const 2422068SN/A { 2432068SN/A Addr EA; 2442132SN/A Fault fault = NoFault; 2452068SN/A 2462068SN/A %(fp_enable_check)s; 2472068SN/A %(op_decl)s; 2482069SN/A %(op_rd)s; 2492068SN/A EA = xc->getEA(); 2502068SN/A 2512090SN/A if (fault == NoFault) { 2522069SN/A fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags); 2532068SN/A %(code)s; 2542068SN/A } 2552068SN/A 2562090SN/A if (fault == NoFault) { 2572069SN/A %(op_wb)s; 2582068SN/A } 2592068SN/A 2602068SN/A return fault; 2612068SN/A } 2622068SN/A}}; 2632068SN/A 2642068SN/A 2652069SN/Adef template LoadExecute {{ 2662132SN/A Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, 2672068SN/A Trace::InstRecord *traceData) const 2682068SN/A { 2692068SN/A Addr EA; 2702132SN/A Fault fault = NoFault; 2712068SN/A 2722068SN/A %(fp_enable_check)s; 2732068SN/A %(op_decl)s; 2742069SN/A %(op_rd)s; 2752068SN/A %(ea_code)s; 2762068SN/A 2772090SN/A if (fault == NoFault) { 2782069SN/A fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags); 2792068SN/A %(memacc_code)s; 2802068SN/A } 2812068SN/A 2822090SN/A if (fault == NoFault) { 2832069SN/A %(op_wb)s; 2842069SN/A } 2852069SN/A 2862069SN/A return fault; 2872069SN/A } 2882069SN/A}}; 2892069SN/A 2902069SN/A 2912095SN/Adef template LoadInitiateAcc {{ 2922132SN/A Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc, 2932095SN/A Trace::InstRecord *traceData) const 2942095SN/A { 2952095SN/A Addr EA; 2962132SN/A Fault fault = NoFault; 2972095SN/A 2982095SN/A %(fp_enable_check)s; 2992095SN/A %(op_src_decl)s; 3002095SN/A %(op_rd)s; 3012095SN/A %(ea_code)s; 3022095SN/A 3032098SN/A if (fault == NoFault) { 3042095SN/A fault = xc->read(EA, (uint%(mem_acc_size)d_t &)Mem, memAccessFlags); 3052095SN/A } 3062095SN/A 3072095SN/A return fault; 3082095SN/A } 3092095SN/A}}; 3102095SN/A 3112095SN/A 3122095SN/Adef template LoadCompleteAcc {{ 3132623SN/A Fault %(class_name)s::completeAcc(Packet *pkt, 3142095SN/A %(CPU_exec_context)s *xc, 3152095SN/A Trace::InstRecord *traceData) const 3162095SN/A { 3172132SN/A Fault fault = NoFault; 3182095SN/A 3192095SN/A %(fp_enable_check)s; 3202506SN/A %(op_decl)s; 3212095SN/A 3222623SN/A Mem = pkt->get<typeof(Mem)>(); 3232095SN/A 3242098SN/A if (fault == NoFault) { 3252095SN/A %(memacc_code)s; 3262095SN/A } 3272095SN/A 3282098SN/A if (fault == NoFault) { 3292095SN/A %(op_wb)s; 3302095SN/A } 3312095SN/A 3322095SN/A return fault; 3332095SN/A } 3342095SN/A}}; 3352095SN/A 3362095SN/A 3372069SN/Adef template StoreMemAccExecute {{ 3382132SN/A Fault 3392069SN/A %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc, 3402069SN/A Trace::InstRecord *traceData) const 3412069SN/A { 3422069SN/A Addr EA; 3432132SN/A Fault fault = NoFault; 3442069SN/A uint64_t write_result = 0; 3452069SN/A 3462069SN/A %(fp_enable_check)s; 3472069SN/A %(op_decl)s; 3482069SN/A %(op_rd)s; 3492069SN/A EA = xc->getEA(); 3502069SN/A 3512090SN/A if (fault == NoFault) { 3522069SN/A %(code)s; 3532069SN/A } 3542069SN/A 3552090SN/A if (fault == NoFault) { 3562069SN/A fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA, 3572069SN/A memAccessFlags, &write_result); 3582069SN/A if (traceData) { traceData->setData(Mem); } 3592068SN/A } 3602068SN/A 3612090SN/A if (fault == NoFault) { 3622068SN/A %(postacc_code)s; 3632068SN/A } 3642068SN/A 3652090SN/A if (fault == NoFault) { 3662069SN/A %(op_wb)s; 3672068SN/A } 3682068SN/A 3692068SN/A return fault; 3702068SN/A } 3712068SN/A}}; 3722068SN/A 3732068SN/A 3742069SN/Adef template StoreExecute {{ 3752132SN/A Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, 3762069SN/A Trace::InstRecord *traceData) const 3772069SN/A { 3782069SN/A Addr EA; 3792132SN/A Fault fault = NoFault; 3802069SN/A uint64_t write_result = 0; 3812069SN/A 3822069SN/A %(fp_enable_check)s; 3832069SN/A %(op_decl)s; 3842069SN/A %(op_rd)s; 3852069SN/A %(ea_code)s; 3862069SN/A 3872090SN/A if (fault == NoFault) { 3882069SN/A %(memacc_code)s; 3892069SN/A } 3902069SN/A 3912090SN/A if (fault == NoFault) { 3922069SN/A fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA, 3932069SN/A memAccessFlags, &write_result); 3942069SN/A if (traceData) { traceData->setData(Mem); } 3952069SN/A } 3962069SN/A 3972090SN/A if (fault == NoFault) { 3982069SN/A %(postacc_code)s; 3992069SN/A } 4002069SN/A 4012090SN/A if (fault == NoFault) { 4022069SN/A %(op_wb)s; 4032069SN/A } 4042069SN/A 4052069SN/A return fault; 4062069SN/A } 4072069SN/A}}; 4082069SN/A 4092095SN/Adef template StoreInitiateAcc {{ 4102132SN/A Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc, 4112095SN/A Trace::InstRecord *traceData) const 4122095SN/A { 4132095SN/A Addr EA; 4142132SN/A Fault fault = NoFault; 4152095SN/A 4162095SN/A %(fp_enable_check)s; 4172506SN/A %(op_decl)s; 4182095SN/A %(op_rd)s; 4192095SN/A %(ea_code)s; 4202095SN/A 4212098SN/A if (fault == NoFault) { 4222095SN/A %(memacc_code)s; 4232095SN/A } 4242095SN/A 4252098SN/A if (fault == NoFault) { 4262095SN/A fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA, 4272623SN/A memAccessFlags, NULL); 4282095SN/A if (traceData) { traceData->setData(Mem); } 4292095SN/A } 4302095SN/A 4312095SN/A return fault; 4322095SN/A } 4332095SN/A}}; 4342095SN/A 4352095SN/A 4362095SN/Adef template StoreCompleteAcc {{ 4372623SN/A Fault %(class_name)s::completeAcc(Packet *pkt, 4382095SN/A %(CPU_exec_context)s *xc, 4392095SN/A Trace::InstRecord *traceData) const 4402095SN/A { 4412132SN/A Fault fault = NoFault; 4422095SN/A 4432095SN/A %(fp_enable_check)s; 4442095SN/A %(op_dest_decl)s; 4452095SN/A 4462623SN/A if (fault == NoFault) { 4472623SN/A %(postacc_code)s; 4482623SN/A } 4492623SN/A 4502623SN/A if (fault == NoFault) { 4512623SN/A %(op_wb)s; 4522623SN/A } 4532623SN/A 4542623SN/A return fault; 4552623SN/A } 4562623SN/A}}; 4572623SN/A 4582623SN/A 4592623SN/Adef template StoreCondCompleteAcc {{ 4602623SN/A Fault %(class_name)s::completeAcc(Packet *pkt, 4612623SN/A %(CPU_exec_context)s *xc, 4622623SN/A Trace::InstRecord *traceData) const 4632623SN/A { 4642623SN/A Fault fault = NoFault; 4652623SN/A 4662623SN/A %(fp_enable_check)s; 4672623SN/A %(op_dest_decl)s; 4682623SN/A 4692623SN/A uint64_t write_result = pkt->req->getScResult(); 4702095SN/A 4712098SN/A if (fault == NoFault) { 4722095SN/A %(postacc_code)s; 4732095SN/A } 4742095SN/A 4752098SN/A if (fault == NoFault) { 4762095SN/A %(op_wb)s; 4772095SN/A } 4782095SN/A 4792095SN/A return fault; 4802095SN/A } 4812095SN/A}}; 4822095SN/A 4832069SN/A 4842069SN/Adef template MiscMemAccExecute {{ 4852132SN/A Fault %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc, 4862069SN/A Trace::InstRecord *traceData) const 4872069SN/A { 4882069SN/A Addr EA; 4892132SN/A Fault fault = NoFault; 4902069SN/A 4912069SN/A %(fp_enable_check)s; 4922069SN/A %(op_decl)s; 4932069SN/A %(op_rd)s; 4942069SN/A EA = xc->getEA(); 4952069SN/A 4962090SN/A if (fault == NoFault) { 4972069SN/A %(code)s; 4982069SN/A } 4992069SN/A 5002090SN/A return NoFault; 5012069SN/A } 5022069SN/A}}; 5032069SN/A 5042069SN/Adef template MiscExecute {{ 5052132SN/A Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, 5062068SN/A Trace::InstRecord *traceData) const 5072068SN/A { 5082068SN/A Addr EA; 5092132SN/A Fault fault = NoFault; 5102068SN/A 5112068SN/A %(fp_enable_check)s; 5122068SN/A %(op_decl)s; 5132069SN/A %(op_rd)s; 5142068SN/A %(ea_code)s; 5152068SN/A 5162090SN/A if (fault == NoFault) { 5172069SN/A %(memacc_code)s; 5182068SN/A } 5192068SN/A 5202090SN/A return NoFault; 5212068SN/A } 5222068SN/A}}; 5232068SN/A 5242095SN/Adef template MiscInitiateAcc {{ 5252132SN/A Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc, 5262095SN/A Trace::InstRecord *traceData) const 5272095SN/A { 5282110SN/A panic("Misc instruction does not support split access method!"); 5292098SN/A return NoFault; 5302095SN/A } 5312095SN/A}}; 5322095SN/A 5332095SN/A 5342095SN/Adef template MiscCompleteAcc {{ 5352623SN/A Fault %(class_name)s::completeAcc(Packet *pkt, 5362095SN/A %(CPU_exec_context)s *xc, 5372095SN/A Trace::InstRecord *traceData) const 5382095SN/A { 5392110SN/A panic("Misc instruction does not support split access method!"); 5402110SN/A 5412098SN/A return NoFault; 5422095SN/A } 5432095SN/A}}; 5442095SN/A 5452068SN/A// load instructions use Ra as dest, so check for 5462068SN/A// Ra == 31 to detect nops 5472068SN/Adef template LoadNopCheckDecode {{ 5482068SN/A { 5492068SN/A AlphaStaticInst *i = new %(class_name)s(machInst); 5502068SN/A if (RA == 31) { 5512068SN/A i = makeNop(i); 5522068SN/A } 5532068SN/A return i; 5542068SN/A } 5552068SN/A}}; 5562068SN/A 5572068SN/A 5582068SN/A// for some load instructions, Ra == 31 indicates a prefetch (not a nop) 5592068SN/Adef template LoadPrefetchCheckDecode {{ 5602068SN/A { 5612068SN/A if (RA != 31) { 5622068SN/A return new %(class_name)s(machInst); 5632068SN/A } 5642068SN/A else { 5652068SN/A return new %(class_name)sPrefetch(machInst); 5662068SN/A } 5672068SN/A } 5682068SN/A}}; 5692068SN/A 5702068SN/A 5712068SN/Alet {{ 5722075SN/Adef LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 5732075SN/A postacc_code = '', base_class = 'MemoryDisp32', 5742069SN/A decode_template = BasicDecode, exec_template_base = ''): 5752075SN/A # Make sure flags are in lists (convert to lists if not). 5762075SN/A mem_flags = makeList(mem_flags) 5772075SN/A inst_flags = makeList(inst_flags) 5782068SN/A 5792068SN/A # add hook to get effective addresses into execution trace output. 5802068SN/A ea_code += '\nif (traceData) { traceData->setAddr(EA); }\n' 5812068SN/A 5822068SN/A # generate code block objects 5832068SN/A ea_cblk = CodeBlock(ea_code) 5842068SN/A memacc_cblk = CodeBlock(memacc_code) 5852068SN/A postacc_cblk = CodeBlock(postacc_code) 5862068SN/A 5872068SN/A # Some CPU models execute the memory operation as an atomic unit, 5882068SN/A # while others want to separate them into an effective address 5892068SN/A # computation and a memory access operation. As a result, we need 5902068SN/A # to generate three StaticInst objects. Note that the latter two 5912068SN/A # are nested inside the larger "atomic" one. 5922068SN/A 5932068SN/A # generate InstObjParams for EAComp object 5942068SN/A ea_iop = InstObjParams(name, Name, base_class, ea_cblk, inst_flags) 5952068SN/A 5962068SN/A # generate InstObjParams for MemAcc object 5972068SN/A memacc_iop = InstObjParams(name, Name, base_class, memacc_cblk, inst_flags) 5982068SN/A # in the split execution model, the MemAcc portion is responsible 5992068SN/A # for the post-access code. 6002068SN/A memacc_iop.postacc_code = postacc_cblk.code 6012068SN/A 6022110SN/A # generate InstObjParams for InitiateAcc, CompleteAcc object 6032110SN/A # The code used depends on the template being used 6042110SN/A if (exec_template_base == 'Load'): 6052110SN/A initiateacc_cblk = CodeBlock(ea_code + memacc_code) 6062110SN/A completeacc_cblk = CodeBlock(memacc_code + postacc_code) 6072623SN/A elif (exec_template_base.startswith('Store')): 6082110SN/A initiateacc_cblk = CodeBlock(ea_code + memacc_code) 6092110SN/A completeacc_cblk = CodeBlock(postacc_code) 6102110SN/A else: 6112110SN/A initiateacc_cblk = '' 6122110SN/A completeacc_cblk = '' 6132110SN/A 6142110SN/A initiateacc_iop = InstObjParams(name, Name, base_class, initiateacc_cblk, 6152110SN/A inst_flags) 6162110SN/A 6172110SN/A completeacc_iop = InstObjParams(name, Name, base_class, completeacc_cblk, 6182110SN/A inst_flags) 6192110SN/A 6202110SN/A if (exec_template_base == 'Load'): 6212110SN/A initiateacc_iop.ea_code = ea_cblk.code 6222110SN/A initiateacc_iop.memacc_code = memacc_cblk.code 6232110SN/A completeacc_iop.memacc_code = memacc_cblk.code 6242110SN/A completeacc_iop.postacc_code = postacc_cblk.code 6252623SN/A elif (exec_template_base.startswith('Store')): 6262110SN/A initiateacc_iop.ea_code = ea_cblk.code 6272110SN/A initiateacc_iop.memacc_code = memacc_cblk.code 6282110SN/A completeacc_iop.postacc_code = postacc_cblk.code 6292110SN/A 6302068SN/A # generate InstObjParams for unified execution 6312068SN/A cblk = CodeBlock(ea_code + memacc_code + postacc_code) 6322068SN/A iop = InstObjParams(name, Name, base_class, cblk, inst_flags) 6332068SN/A 6342068SN/A iop.ea_constructor = ea_cblk.constructor 6352068SN/A iop.ea_code = ea_cblk.code 6362068SN/A iop.memacc_constructor = memacc_cblk.constructor 6372068SN/A iop.memacc_code = memacc_cblk.code 6382068SN/A iop.postacc_code = postacc_cblk.code 6392068SN/A 6402068SN/A if mem_flags: 6412068SN/A s = '\n\tmemAccessFlags = ' + string.join(mem_flags, '|') + ';' 6422068SN/A iop.constructor += s 6432068SN/A memacc_iop.constructor += s 6442068SN/A 6452069SN/A # select templates 6462623SN/A 6472623SN/A # define aliases... most StoreCond templates are the same as the 6482623SN/A # corresponding Store templates (only CompleteAcc is different). 6492623SN/A StoreCondMemAccExecute = StoreMemAccExecute 6502623SN/A StoreCondExecute = StoreExecute 6512623SN/A StoreCondInitiateAcc = StoreInitiateAcc 6522623SN/A 6532069SN/A memAccExecTemplate = eval(exec_template_base + 'MemAccExecute') 6542069SN/A fullExecTemplate = eval(exec_template_base + 'Execute') 6552095SN/A initiateAccTemplate = eval(exec_template_base + 'InitiateAcc') 6562095SN/A completeAccTemplate = eval(exec_template_base + 'CompleteAcc') 6572069SN/A 6582068SN/A # (header_output, decoder_output, decode_block, exec_output) 6592068SN/A return (LoadStoreDeclare.subst(iop), LoadStoreConstructor.subst(iop), 6602068SN/A decode_template.subst(iop), 6612068SN/A EACompExecute.subst(ea_iop) 6622069SN/A + memAccExecTemplate.subst(memacc_iop) 6632095SN/A + fullExecTemplate.subst(iop) 6642110SN/A + initiateAccTemplate.subst(initiateacc_iop) 6652110SN/A + completeAccTemplate.subst(completeacc_iop)) 6662068SN/A}}; 6672068SN/A 6682068SN/A 6692075SN/Adef format LoadOrNop(memacc_code, ea_code = {{ EA = Rb + disp; }}, 6702075SN/A mem_flags = [], inst_flags = []) {{ 6712068SN/A (header_output, decoder_output, decode_block, exec_output) = \ 6722075SN/A LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 6732069SN/A decode_template = LoadNopCheckDecode, 6742069SN/A exec_template_base = 'Load') 6752068SN/A}}; 6762068SN/A 6772068SN/A 6782068SN/A// Note that the flags passed in apply only to the prefetch version 6792075SN/Adef format LoadOrPrefetch(memacc_code, ea_code = {{ EA = Rb + disp; }}, 6802075SN/A mem_flags = [], pf_flags = [], inst_flags = []) {{ 6812068SN/A # declare the load instruction object and generate the decode block 6822068SN/A (header_output, decoder_output, decode_block, exec_output) = \ 6832075SN/A LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 6842069SN/A decode_template = LoadPrefetchCheckDecode, 6852069SN/A exec_template_base = 'Load') 6862068SN/A 6872068SN/A # Declare the prefetch instruction object. 6882068SN/A 6892075SN/A # Make sure flag args are lists so we can mess with them. 6902075SN/A mem_flags = makeList(mem_flags) 6912075SN/A pf_flags = makeList(pf_flags) 6922075SN/A inst_flags = makeList(inst_flags) 6932075SN/A 6942075SN/A pf_mem_flags = mem_flags + pf_flags + ['NO_FAULT'] 6952075SN/A pf_inst_flags = inst_flags + ['IsMemRef', 'IsLoad', 6962075SN/A 'IsDataPrefetch', 'MemReadOp'] 6972068SN/A 6982068SN/A (pf_header_output, pf_decoder_output, _, pf_exec_output) = \ 6992069SN/A LoadStoreBase(name, Name + 'Prefetch', ea_code, 7002069SN/A 'xc->prefetch(EA, memAccessFlags);', 7012075SN/A pf_mem_flags, pf_inst_flags, exec_template_base = 'Misc') 7022068SN/A 7032068SN/A header_output += pf_header_output 7042068SN/A decoder_output += pf_decoder_output 7052068SN/A exec_output += pf_exec_output 7062068SN/A}}; 7072068SN/A 7082068SN/A 7092075SN/Adef format Store(memacc_code, ea_code = {{ EA = Rb + disp; }}, 7102075SN/A mem_flags = [], inst_flags = []) {{ 7112068SN/A (header_output, decoder_output, decode_block, exec_output) = \ 7122075SN/A LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 7132069SN/A exec_template_base = 'Store') 7142068SN/A}}; 7152068SN/A 7162068SN/A 7172075SN/Adef format StoreCond(memacc_code, postacc_code, 7182075SN/A ea_code = {{ EA = Rb + disp; }}, 7192075SN/A mem_flags = [], inst_flags = []) {{ 7202068SN/A (header_output, decoder_output, decode_block, exec_output) = \ 7212075SN/A LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 7222623SN/A postacc_code, exec_template_base = 'StoreCond') 7232068SN/A}}; 7242068SN/A 7252068SN/A 7262068SN/A// Use 'MemoryNoDisp' as base: for wh64, fetch, ecb 7272075SN/Adef format MiscPrefetch(ea_code, memacc_code, 7282075SN/A mem_flags = [], inst_flags = []) {{ 7292068SN/A (header_output, decoder_output, decode_block, exec_output) = \ 7302075SN/A LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 7312069SN/A base_class = 'MemoryNoDisp', exec_template_base = 'Misc') 7322068SN/A}}; 7332068SN/A 7342068SN/A 735