basicmem.isa revision 3385
12315SN/A//////////////////////////////////////////////////////////////////// 28733Sgeoffrey.blake@arm.com// 39913Ssteve.reinhardt@amd.com// Mem instructions 48733Sgeoffrey.blake@arm.com// 58733Sgeoffrey.blake@arm.com 68733Sgeoffrey.blake@arm.comoutput header {{ 78733Sgeoffrey.blake@arm.com /** 88733Sgeoffrey.blake@arm.com * Base class for memory operations. 98733Sgeoffrey.blake@arm.com */ 108733Sgeoffrey.blake@arm.com class Mem : public SparcStaticInst 118733Sgeoffrey.blake@arm.com { 128733Sgeoffrey.blake@arm.com protected: 138733Sgeoffrey.blake@arm.com 148733Sgeoffrey.blake@arm.com // Constructor 152332SN/A Mem(const char *mnem, ExtMachInst _machInst, OpClass __opClass) : 162315SN/A SparcStaticInst(mnem, _machInst, __opClass) 172315SN/A { 182315SN/A } 192315SN/A 202315SN/A std::string generateDisassembly(Addr pc, 212315SN/A const SymbolTable *symtab) const; 222315SN/A }; 232315SN/A 242315SN/A /** 252315SN/A * Class for memory operations which use an immediate offset. 262315SN/A */ 272315SN/A class MemImm : public Mem 282315SN/A { 292315SN/A protected: 302315SN/A 312315SN/A // Constructor 322315SN/A MemImm(const char *mnem, ExtMachInst _machInst, OpClass __opClass) : 332315SN/A Mem(mnem, _machInst, __opClass) 342315SN/A { 352315SN/A imm = sext<13>(SIMM13); 362315SN/A } 372315SN/A 382315SN/A std::string generateDisassembly(Addr pc, 392315SN/A const SymbolTable *symtab) const; 402689SN/A 412689SN/A int32_t imm; 428733Sgeoffrey.blake@arm.com }; 432315SN/A}}; 442315SN/A 452315SN/Aoutput decoder {{ 462315SN/A std::string Mem::generateDisassembly(Addr pc, 472315SN/A const SymbolTable *symtab) const 488888Sgeoffrey.blake@arm.com { 498793Sgblack@eecs.umich.edu std::stringstream response; 502315SN/A bool load = flags[IsLoad]; 516658Snate@binkert.org bool save = flags[IsStore]; 522315SN/A 538733Sgeoffrey.blake@arm.com printMnemonic(response, mnemonic); 549913Ssteve.reinhardt@amd.com if(save) 552683SN/A { 568229Snate@binkert.org printReg(response, _srcRegIdx[0]); 572680SN/A ccprintf(response, ", "); 588733Sgeoffrey.blake@arm.com } 598733Sgeoffrey.blake@arm.com ccprintf(response, "[ "); 608793Sgblack@eecs.umich.edu printReg(response, _srcRegIdx[!save ? 0 : 1]); 612315SN/A ccprintf(response, " + "); 622315SN/A printReg(response, _srcRegIdx[!save ? 1 : 2]); 632315SN/A ccprintf(response, " ]"); 642315SN/A if(load) 658733Sgeoffrey.blake@arm.com { 662315SN/A ccprintf(response, ", "); 678733Sgeoffrey.blake@arm.com printReg(response, _destRegIdx[0]); 682315SN/A } 698733Sgeoffrey.blake@arm.com 708733Sgeoffrey.blake@arm.com return response.str(); 718733Sgeoffrey.blake@arm.com } 728733Sgeoffrey.blake@arm.com 738733Sgeoffrey.blake@arm.com std::string MemImm::generateDisassembly(Addr pc, 749023Sgblack@eecs.umich.edu const SymbolTable *symtab) const 758733Sgeoffrey.blake@arm.com { 768733Sgeoffrey.blake@arm.com std::stringstream response; 778733Sgeoffrey.blake@arm.com bool load = flags[IsLoad]; 788733Sgeoffrey.blake@arm.com bool save = flags[IsStore]; 798733Sgeoffrey.blake@arm.com 808733Sgeoffrey.blake@arm.com printMnemonic(response, mnemonic); 818733Sgeoffrey.blake@arm.com if(save) 828733Sgeoffrey.blake@arm.com { 838733Sgeoffrey.blake@arm.com printReg(response, _srcRegIdx[0]); 848733Sgeoffrey.blake@arm.com ccprintf(response, ", "); 858733Sgeoffrey.blake@arm.com } 868733Sgeoffrey.blake@arm.com ccprintf(response, "[ "); 878733Sgeoffrey.blake@arm.com printReg(response, _srcRegIdx[!save ? 0 : 1]); 888733Sgeoffrey.blake@arm.com if(imm >= 0) 898733Sgeoffrey.blake@arm.com ccprintf(response, " + 0x%x ]", imm); 908733Sgeoffrey.blake@arm.com else 918733Sgeoffrey.blake@arm.com ccprintf(response, " + -0x%x ]", -imm); 928733Sgeoffrey.blake@arm.com if(load) 938733Sgeoffrey.blake@arm.com { 948733Sgeoffrey.blake@arm.com ccprintf(response, ", "); 958733Sgeoffrey.blake@arm.com printReg(response, _destRegIdx[0]); 968733Sgeoffrey.blake@arm.com } 978733Sgeoffrey.blake@arm.com 988733Sgeoffrey.blake@arm.com return response.str(); 998733Sgeoffrey.blake@arm.com } 1008733Sgeoffrey.blake@arm.com 1018733Sgeoffrey.blake@arm.com}}; 1028733Sgeoffrey.blake@arm.com 1038733Sgeoffrey.blake@arm.comdef template LoadExecute {{ 1048733Sgeoffrey.blake@arm.com Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, 1058733Sgeoffrey.blake@arm.com Trace::InstRecord *traceData) const 1068733Sgeoffrey.blake@arm.com { 1078733Sgeoffrey.blake@arm.com Fault fault = NoFault; 1088733Sgeoffrey.blake@arm.com Addr EA; 1098733Sgeoffrey.blake@arm.com %(op_decl)s; 1108733Sgeoffrey.blake@arm.com %(op_rd)s; 1118733Sgeoffrey.blake@arm.com %(priv_check)s; 1128733Sgeoffrey.blake@arm.com %(ea_code)s; 1138733Sgeoffrey.blake@arm.com DPRINTF(Sparc, "The address is 0x%x\n", EA); 1148733Sgeoffrey.blake@arm.com fault = xc->read(EA, (uint%(mem_acc_size)s_t&)Mem, 0); 1158733Sgeoffrey.blake@arm.com %(code)s; 1168733Sgeoffrey.blake@arm.com if(fault == NoFault) 1178733Sgeoffrey.blake@arm.com { 1189023Sgblack@eecs.umich.edu //Write the resulting state to the execution context 1198733Sgeoffrey.blake@arm.com %(op_wb)s; 1208733Sgeoffrey.blake@arm.com } 1218733Sgeoffrey.blake@arm.com 1228733Sgeoffrey.blake@arm.com return fault; 1238733Sgeoffrey.blake@arm.com } 1248733Sgeoffrey.blake@arm.com 1252315SN/A Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s * xc, 1262315SN/A Trace::InstRecord * traceData) const 1272315SN/A { 1288733Sgeoffrey.blake@arm.com Fault fault = NoFault; 1298733Sgeoffrey.blake@arm.com Addr EA; 1308733Sgeoffrey.blake@arm.com uint%(mem_acc_size)s_t Mem; 1318733Sgeoffrey.blake@arm.com %(ea_decl)s; 1328733Sgeoffrey.blake@arm.com %(ea_rd)s; 1338733Sgeoffrey.blake@arm.com %(priv_check)s; 1348733Sgeoffrey.blake@arm.com %(ea_code)s; 1358733Sgeoffrey.blake@arm.com fault = xc->read(EA, (uint%(mem_acc_size)s_t&)Mem, 0); 1368733Sgeoffrey.blake@arm.com return fault; 1378733Sgeoffrey.blake@arm.com } 1388733Sgeoffrey.blake@arm.com 1398733Sgeoffrey.blake@arm.com Fault %(class_name)s::completeAcc(PacketPtr pkt, %(CPU_exec_context)s * xc, 1402332SN/A Trace::InstRecord * traceData) const 1412332SN/A { 1422332SN/A Fault fault = NoFault; 1432332SN/A %(code_decl)s; 1442332SN/A %(code_rd)s; 1452315SN/A Mem = pkt->get<typeof(Mem)>(); 1462315SN/A %(code)s; 1478733Sgeoffrey.blake@arm.com if(fault == NoFault) 1488733Sgeoffrey.blake@arm.com { 1492315SN/A %(code_wb)s; 1502315SN/A } 1512315SN/A return fault; 1522315SN/A } 1532315SN/A}}; 1542315SN/A 1552315SN/Adef template StoreExecute {{ 1562315SN/A Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, 1572315SN/A Trace::InstRecord *traceData) const 1582315SN/A { 1592315SN/A Fault fault = NoFault; 1602315SN/A uint64_t write_result = 0; 1612315SN/A Addr EA; 1628733Sgeoffrey.blake@arm.com %(op_decl)s; 1638733Sgeoffrey.blake@arm.com %(op_rd)s; 1642315SN/A %(priv_check)s; 1652315SN/A %(ea_code)s; 1662315SN/A DPRINTF(Sparc, "The address is 0x%x\n", EA); 1672315SN/A %(code)s; 1682315SN/A 1692315SN/A if(fault == NoFault) 1702315SN/A { 1712315SN/A fault = xc->write((uint%(mem_acc_size)s_t)Mem, EA, 0, &write_result); 1722315SN/A } 1732315SN/A if(fault == NoFault) 1742315SN/A { 1752315SN/A //Write the resulting state to the execution context 1762315SN/A %(op_wb)s; 1772315SN/A } 1788733Sgeoffrey.blake@arm.com 1798733Sgeoffrey.blake@arm.com return fault; 1808733Sgeoffrey.blake@arm.com } 1818733Sgeoffrey.blake@arm.com 1828733Sgeoffrey.blake@arm.com Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s * xc, 1838733Sgeoffrey.blake@arm.com Trace::InstRecord * traceData) const 1848733Sgeoffrey.blake@arm.com { 1852354SN/A Fault fault = NoFault; 1868733Sgeoffrey.blake@arm.com uint64_t write_result = 0; 1872354SN/A Addr EA; 1882332SN/A %(op_decl)s; 1892332SN/A %(op_rd)s; 1902332SN/A %(priv_check)s; 1912315SN/A %(ea_code)s; 1928733Sgeoffrey.blake@arm.com DPRINTF(Sparc, "The address is 0x%x\n", EA); 1938733Sgeoffrey.blake@arm.com %(code)s; 1948733Sgeoffrey.blake@arm.com if(fault == NoFault) 1958733Sgeoffrey.blake@arm.com { 1968733Sgeoffrey.blake@arm.com fault = xc->write((uint%(mem_acc_size)s_t)Mem, EA, 0, &write_result); 1978733Sgeoffrey.blake@arm.com } 1988733Sgeoffrey.blake@arm.com if(fault == NoFault) 1998733Sgeoffrey.blake@arm.com { 2008733Sgeoffrey.blake@arm.com //Write the resulting state to the execution context 2012315SN/A %(op_wb)s; 2022315SN/A } 2032315SN/A return fault; 2042315SN/A } 2052315SN/A 2062683SN/A Fault %(class_name)s::completeAcc(PacketPtr, %(CPU_exec_context)s * xc, 2078888Sgeoffrey.blake@arm.com Trace::InstRecord * traceData) const 2088888Sgeoffrey.blake@arm.com { 2098888Sgeoffrey.blake@arm.com return NoFault; 2102315SN/A } 2112332SN/A}}; 2122332SN/A 2132332SN/Adef template LoadStoreExecute {{ 2142315SN/A Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, 2158733Sgeoffrey.blake@arm.com Trace::InstRecord *traceData) const 2168733Sgeoffrey.blake@arm.com { 2172315SN/A Fault fault = NoFault; 2188733Sgeoffrey.blake@arm.com uint64_t write_result = 0; 2192315SN/A Addr EA; 2202315SN/A %(op_decl)s; 2212332SN/A %(op_rd)s; 2228733Sgeoffrey.blake@arm.com %(priv_check)s; 2238733Sgeoffrey.blake@arm.com %(ea_code)s; 2242732SN/A DPRINTF(Sparc, "The address is 0x%x\n", EA); 2252315SN/A xc->read(EA, (uint%(mem_acc_size)s_t&)Mem, 0); 2262315SN/A %(code)s; 2272315SN/A 2282315SN/A if(fault == NoFault) 2292315SN/A { 2302315SN/A xc->write((uint%(mem_acc_size)s_t)Mem, EA, 0, &write_result); 2312315SN/A //Write the resulting state to the execution context 2328733Sgeoffrey.blake@arm.com %(op_wb)s; 2332315SN/A } 2342315SN/A 2352315SN/A return fault; 2362332SN/A } 2378733Sgeoffrey.blake@arm.com}}; 2388733Sgeoffrey.blake@arm.com 2392332SN/Adef template MemDeclare {{ 2408733Sgeoffrey.blake@arm.com /** 2418733Sgeoffrey.blake@arm.com * Static instruction class for "%(mnemonic)s". 2428733Sgeoffrey.blake@arm.com */ 2432332SN/A class %(class_name)s : public %(base_class)s 2449023Sgblack@eecs.umich.edu { 2459023Sgblack@eecs.umich.edu public: 2468733Sgeoffrey.blake@arm.com 2478733Sgeoffrey.blake@arm.com /// Constructor. 2488733Sgeoffrey.blake@arm.com %(class_name)s(ExtMachInst machInst); 2498733Sgeoffrey.blake@arm.com 2508733Sgeoffrey.blake@arm.com %(BasicExecDeclare)s 2518733Sgeoffrey.blake@arm.com 2528887Sgeoffrey.blake@arm.com %(InitiateAccDeclare)s 2538733Sgeoffrey.blake@arm.com 2548733Sgeoffrey.blake@arm.com %(CompleteAccDeclare)s 2558733Sgeoffrey.blake@arm.com }; 2568832SAli.Saidi@ARM.com}}; 2572679SN/A 2582315SN/Adef template InitiateAccDeclare {{ 2598733Sgeoffrey.blake@arm.com Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const; 2602315SN/A}}; 2618733Sgeoffrey.blake@arm.com 2628733Sgeoffrey.blake@arm.comdef template CompleteAccDeclare {{ 2638733Sgeoffrey.blake@arm.com Fault completeAcc(PacketPtr, %(CPU_exec_context)s *, Trace::InstRecord *) const; 2648733Sgeoffrey.blake@arm.com}}; 2658733Sgeoffrey.blake@arm.com 2668733Sgeoffrey.blake@arm.com 2678733Sgeoffrey.blake@arm.comlet {{ 2688733Sgeoffrey.blake@arm.com # XXX Need to take care of pstate.hpriv as well. The lower ASIs are split 2698733Sgeoffrey.blake@arm.com # into ones that are available in priv and hpriv, and those that are only 2708733Sgeoffrey.blake@arm.com # available in hpriv 2712315SN/A privilegedString = '''if(bits(Pstate,2,2) == 0 && (EXT_ASI & 0x80) == 0) 2728733Sgeoffrey.blake@arm.com return new PrivilegedAction; 2738733Sgeoffrey.blake@arm.com if(AsiIsAsIfUser(EXT_ASI) && !bits(Pstate,2,2)) 2742315SN/A return new PrivilegedAction;''' 2758733Sgeoffrey.blake@arm.com 2768733Sgeoffrey.blake@arm.com def doMemFormat(code, execute, priv, name, Name, opt_flags): 2778733Sgeoffrey.blake@arm.com addrCalcReg = 'EA = Rs1 + Rs2;' 2788733Sgeoffrey.blake@arm.com addrCalcImm = 'EA = Rs1 + imm;' 2798733Sgeoffrey.blake@arm.com ea_iop = InstObjParams(name, Name, 'Mem', 2808733Sgeoffrey.blake@arm.com addrCalcReg, opt_flags, {"priv_check": priv}) 2818733Sgeoffrey.blake@arm.com ea_iop_imm = InstObjParams(name, Name, 'MemImm', 2828733Sgeoffrey.blake@arm.com addrCalcImm, opt_flags, {"priv_check": priv}) 2838733Sgeoffrey.blake@arm.com code_iop = InstObjParams(name, Name, 'Mem', code, opt_flags) 2848733Sgeoffrey.blake@arm.com iop = InstObjParams(name, Name, 'Mem', code, 2858733Sgeoffrey.blake@arm.com opt_flags, {"ea_code": addrCalcReg, 2868733Sgeoffrey.blake@arm.com "priv_check": priv}) 2878733Sgeoffrey.blake@arm.com (iop.ea_decl, 2888949Sandreas.hansson@arm.com iop.ea_rd, 2898733Sgeoffrey.blake@arm.com iop.ea_wb) = (ea_iop.op_decl, ea_iop.op_rd, ea_iop.op_wb) 2908733Sgeoffrey.blake@arm.com (iop.code_decl, 2918733Sgeoffrey.blake@arm.com iop.code_rd, 2928733Sgeoffrey.blake@arm.com iop.code_wb) = (code_iop.op_decl, code_iop.op_rd, code_iop.op_wb) 2938733Sgeoffrey.blake@arm.com iop_imm = InstObjParams(name, Name + 'Imm', 'MemImm', code, 2948733Sgeoffrey.blake@arm.com opt_flags, {"ea_code": addrCalcImm, 2958733Sgeoffrey.blake@arm.com "priv_check": priv}) 2968733Sgeoffrey.blake@arm.com (iop_imm.ea_decl, 2978733Sgeoffrey.blake@arm.com iop_imm.ea_rd, 2988733Sgeoffrey.blake@arm.com iop_imm.ea_wb) = (ea_iop_imm.op_decl, ea_iop_imm.op_rd, ea_iop_imm.op_wb) 2998733Sgeoffrey.blake@arm.com (iop_imm.code_decl, 3008733Sgeoffrey.blake@arm.com iop_imm.code_rd, 3018733Sgeoffrey.blake@arm.com iop_imm.code_wb) = (code_iop.op_decl, code_iop.op_rd, code_iop.op_wb) 3028733Sgeoffrey.blake@arm.com header_output = MemDeclare.subst(iop) + MemDeclare.subst(iop_imm) 3038733Sgeoffrey.blake@arm.com decoder_output = BasicConstructor.subst(iop) + BasicConstructor.subst(iop_imm) 3048733Sgeoffrey.blake@arm.com decode_block = ROrImmDecode.subst(iop) 3058733Sgeoffrey.blake@arm.com exec_output = execute.subst(iop) + execute.subst(iop_imm) 3068733Sgeoffrey.blake@arm.com return (header_output, decoder_output, exec_output, decode_block) 3078733Sgeoffrey.blake@arm.com}}; 3088733Sgeoffrey.blake@arm.com 3098733Sgeoffrey.blake@arm.comdef format LoadAlt(code, *opt_flags) {{ 3108733Sgeoffrey.blake@arm.com (header_output, 3118733Sgeoffrey.blake@arm.com decoder_output, 3128733Sgeoffrey.blake@arm.com exec_output, 3139023Sgblack@eecs.umich.edu decode_block) = doMemFormat(code, LoadExecute, 3148733Sgeoffrey.blake@arm.com privelegedString, name, Name, opt_flags) 3158733Sgeoffrey.blake@arm.com}}; 3168733Sgeoffrey.blake@arm.com 3178733Sgeoffrey.blake@arm.comdef format StoreAlt(code, *opt_flags) {{ 3189023Sgblack@eecs.umich.edu (header_output, 3198733Sgeoffrey.blake@arm.com decoder_output, 3209023Sgblack@eecs.umich.edu exec_output, 3218733Sgeoffrey.blake@arm.com decode_block) = doMemFormat(code, StoreExecute, 3228733Sgeoffrey.blake@arm.com privilegedString, name, Name, opt_flags) 3238733Sgeoffrey.blake@arm.com}}; 3248733Sgeoffrey.blake@arm.com 3258733Sgeoffrey.blake@arm.comdef format Load(code, *opt_flags) {{ 3268733Sgeoffrey.blake@arm.com (header_output, 3278733Sgeoffrey.blake@arm.com decoder_output, 3288733Sgeoffrey.blake@arm.com exec_output, 3298733Sgeoffrey.blake@arm.com decode_block) = doMemFormat(code, 3308733Sgeoffrey.blake@arm.com LoadExecute, '', name, Name, opt_flags) 3318733Sgeoffrey.blake@arm.com}}; 3328733Sgeoffrey.blake@arm.com 3338733Sgeoffrey.blake@arm.comdef format Store(code, *opt_flags) {{ 3348733Sgeoffrey.blake@arm.com (header_output, 3358733Sgeoffrey.blake@arm.com decoder_output, 3368733Sgeoffrey.blake@arm.com exec_output, 3378733Sgeoffrey.blake@arm.com decode_block) = doMemFormat(code, 3388733Sgeoffrey.blake@arm.com StoreExecute, '', name, Name, opt_flags) 3398733Sgeoffrey.blake@arm.com}}; 3408733Sgeoffrey.blake@arm.com 3418733Sgeoffrey.blake@arm.comdef format LoadStore(code, *opt_flags) {{ 3422323SN/A (header_output, 3432315SN/A decoder_output, 3449023Sgblack@eecs.umich.edu exec_output, 3459023Sgblack@eecs.umich.edu decode_block) = doMemFormat(code, 3462315SN/A LoadStoreExecute, '', name, Name, opt_flags) 3478733Sgeoffrey.blake@arm.com}}; 3488733Sgeoffrey.blake@arm.com