basicmem.isa revision 3385
1//////////////////////////////////////////////////////////////////// 2// 3// Mem instructions 4// 5 6output header {{ 7 /** 8 * Base class for memory operations. 9 */ 10 class Mem : public SparcStaticInst 11 { 12 protected: 13 14 // Constructor 15 Mem(const char *mnem, ExtMachInst _machInst, OpClass __opClass) : 16 SparcStaticInst(mnem, _machInst, __opClass) 17 { 18 } 19 20 std::string generateDisassembly(Addr pc, 21 const SymbolTable *symtab) const; 22 }; 23 24 /** 25 * Class for memory operations which use an immediate offset. 26 */ 27 class MemImm : public Mem 28 { 29 protected: 30 31 // Constructor 32 MemImm(const char *mnem, ExtMachInst _machInst, OpClass __opClass) : 33 Mem(mnem, _machInst, __opClass) 34 { 35 imm = sext<13>(SIMM13); 36 } 37 38 std::string generateDisassembly(Addr pc, 39 const SymbolTable *symtab) const; 40 41 int32_t imm; 42 }; 43}}; 44 45output decoder {{ 46 std::string Mem::generateDisassembly(Addr pc, 47 const SymbolTable *symtab) const 48 { 49 std::stringstream response; 50 bool load = flags[IsLoad]; 51 bool save = flags[IsStore]; 52 53 printMnemonic(response, mnemonic); 54 if(save) 55 { 56 printReg(response, _srcRegIdx[0]); 57 ccprintf(response, ", "); 58 } 59 ccprintf(response, "[ "); 60 printReg(response, _srcRegIdx[!save ? 0 : 1]); 61 ccprintf(response, " + "); 62 printReg(response, _srcRegIdx[!save ? 1 : 2]); 63 ccprintf(response, " ]"); 64 if(load) 65 { 66 ccprintf(response, ", "); 67 printReg(response, _destRegIdx[0]); 68 } 69 70 return response.str(); 71 } 72 73 std::string MemImm::generateDisassembly(Addr pc, 74 const SymbolTable *symtab) const 75 { 76 std::stringstream response; 77 bool load = flags[IsLoad]; 78 bool save = flags[IsStore]; 79 80 printMnemonic(response, mnemonic); 81 if(save) 82 { 83 printReg(response, _srcRegIdx[0]); 84 ccprintf(response, ", "); 85 } 86 ccprintf(response, "[ "); 87 printReg(response, _srcRegIdx[!save ? 0 : 1]); 88 if(imm >= 0) 89 ccprintf(response, " + 0x%x ]", imm); 90 else 91 ccprintf(response, " + -0x%x ]", -imm); 92 if(load) 93 { 94 ccprintf(response, ", "); 95 printReg(response, _destRegIdx[0]); 96 } 97 98 return response.str(); 99 } 100 101}}; 102 103def template LoadExecute {{ 104 Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, 105 Trace::InstRecord *traceData) const 106 { 107 Fault fault = NoFault; 108 Addr EA; 109 %(op_decl)s; 110 %(op_rd)s; 111 %(priv_check)s; 112 %(ea_code)s; 113 DPRINTF(Sparc, "The address is 0x%x\n", EA); 114 fault = xc->read(EA, (uint%(mem_acc_size)s_t&)Mem, 0); 115 %(code)s; 116 if(fault == NoFault) 117 { 118 //Write the resulting state to the execution context 119 %(op_wb)s; 120 } 121 122 return fault; 123 } 124 125 Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s * xc, 126 Trace::InstRecord * traceData) const 127 { 128 Fault fault = NoFault; 129 Addr EA; 130 uint%(mem_acc_size)s_t Mem; 131 %(ea_decl)s; 132 %(ea_rd)s; 133 %(priv_check)s; 134 %(ea_code)s; 135 fault = xc->read(EA, (uint%(mem_acc_size)s_t&)Mem, 0); 136 return fault; 137 } 138 139 Fault %(class_name)s::completeAcc(PacketPtr pkt, %(CPU_exec_context)s * xc, 140 Trace::InstRecord * traceData) const 141 { 142 Fault fault = NoFault; 143 %(code_decl)s; 144 %(code_rd)s; 145 Mem = pkt->get<typeof(Mem)>(); 146 %(code)s; 147 if(fault == NoFault) 148 { 149 %(code_wb)s; 150 } 151 return fault; 152 } 153}}; 154 155def template StoreExecute {{ 156 Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, 157 Trace::InstRecord *traceData) const 158 { 159 Fault fault = NoFault; 160 uint64_t write_result = 0; 161 Addr EA; 162 %(op_decl)s; 163 %(op_rd)s; 164 %(priv_check)s; 165 %(ea_code)s; 166 DPRINTF(Sparc, "The address is 0x%x\n", EA); 167 %(code)s; 168 169 if(fault == NoFault) 170 { 171 fault = xc->write((uint%(mem_acc_size)s_t)Mem, EA, 0, &write_result); 172 } 173 if(fault == NoFault) 174 { 175 //Write the resulting state to the execution context 176 %(op_wb)s; 177 } 178 179 return fault; 180 } 181 182 Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s * xc, 183 Trace::InstRecord * traceData) const 184 { 185 Fault fault = NoFault; 186 uint64_t write_result = 0; 187 Addr EA; 188 %(op_decl)s; 189 %(op_rd)s; 190 %(priv_check)s; 191 %(ea_code)s; 192 DPRINTF(Sparc, "The address is 0x%x\n", EA); 193 %(code)s; 194 if(fault == NoFault) 195 { 196 fault = xc->write((uint%(mem_acc_size)s_t)Mem, EA, 0, &write_result); 197 } 198 if(fault == NoFault) 199 { 200 //Write the resulting state to the execution context 201 %(op_wb)s; 202 } 203 return fault; 204 } 205 206 Fault %(class_name)s::completeAcc(PacketPtr, %(CPU_exec_context)s * xc, 207 Trace::InstRecord * traceData) const 208 { 209 return NoFault; 210 } 211}}; 212 213def template LoadStoreExecute {{ 214 Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, 215 Trace::InstRecord *traceData) const 216 { 217 Fault fault = NoFault; 218 uint64_t write_result = 0; 219 Addr EA; 220 %(op_decl)s; 221 %(op_rd)s; 222 %(priv_check)s; 223 %(ea_code)s; 224 DPRINTF(Sparc, "The address is 0x%x\n", EA); 225 xc->read(EA, (uint%(mem_acc_size)s_t&)Mem, 0); 226 %(code)s; 227 228 if(fault == NoFault) 229 { 230 xc->write((uint%(mem_acc_size)s_t)Mem, EA, 0, &write_result); 231 //Write the resulting state to the execution context 232 %(op_wb)s; 233 } 234 235 return fault; 236 } 237}}; 238 239def template MemDeclare {{ 240 /** 241 * Static instruction class for "%(mnemonic)s". 242 */ 243 class %(class_name)s : public %(base_class)s 244 { 245 public: 246 247 /// Constructor. 248 %(class_name)s(ExtMachInst machInst); 249 250 %(BasicExecDeclare)s 251 252 %(InitiateAccDeclare)s 253 254 %(CompleteAccDeclare)s 255 }; 256}}; 257 258def template InitiateAccDeclare {{ 259 Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const; 260}}; 261 262def template CompleteAccDeclare {{ 263 Fault completeAcc(PacketPtr, %(CPU_exec_context)s *, Trace::InstRecord *) const; 264}}; 265 266 267let {{ 268 # XXX Need to take care of pstate.hpriv as well. The lower ASIs are split 269 # into ones that are available in priv and hpriv, and those that are only 270 # available in hpriv 271 privilegedString = '''if(bits(Pstate,2,2) == 0 && (EXT_ASI & 0x80) == 0) 272 return new PrivilegedAction; 273 if(AsiIsAsIfUser(EXT_ASI) && !bits(Pstate,2,2)) 274 return new PrivilegedAction;''' 275 276 def doMemFormat(code, execute, priv, name, Name, opt_flags): 277 addrCalcReg = 'EA = Rs1 + Rs2;' 278 addrCalcImm = 'EA = Rs1 + imm;' 279 ea_iop = InstObjParams(name, Name, 'Mem', 280 addrCalcReg, opt_flags, {"priv_check": priv}) 281 ea_iop_imm = InstObjParams(name, Name, 'MemImm', 282 addrCalcImm, opt_flags, {"priv_check": priv}) 283 code_iop = InstObjParams(name, Name, 'Mem', code, opt_flags) 284 iop = InstObjParams(name, Name, 'Mem', code, 285 opt_flags, {"ea_code": addrCalcReg, 286 "priv_check": priv}) 287 (iop.ea_decl, 288 iop.ea_rd, 289 iop.ea_wb) = (ea_iop.op_decl, ea_iop.op_rd, ea_iop.op_wb) 290 (iop.code_decl, 291 iop.code_rd, 292 iop.code_wb) = (code_iop.op_decl, code_iop.op_rd, code_iop.op_wb) 293 iop_imm = InstObjParams(name, Name + 'Imm', 'MemImm', code, 294 opt_flags, {"ea_code": addrCalcImm, 295 "priv_check": priv}) 296 (iop_imm.ea_decl, 297 iop_imm.ea_rd, 298 iop_imm.ea_wb) = (ea_iop_imm.op_decl, ea_iop_imm.op_rd, ea_iop_imm.op_wb) 299 (iop_imm.code_decl, 300 iop_imm.code_rd, 301 iop_imm.code_wb) = (code_iop.op_decl, code_iop.op_rd, code_iop.op_wb) 302 header_output = MemDeclare.subst(iop) + MemDeclare.subst(iop_imm) 303 decoder_output = BasicConstructor.subst(iop) + BasicConstructor.subst(iop_imm) 304 decode_block = ROrImmDecode.subst(iop) 305 exec_output = execute.subst(iop) + execute.subst(iop_imm) 306 return (header_output, decoder_output, exec_output, decode_block) 307}}; 308 309def format LoadAlt(code, *opt_flags) {{ 310 (header_output, 311 decoder_output, 312 exec_output, 313 decode_block) = doMemFormat(code, LoadExecute, 314 privelegedString, name, Name, opt_flags) 315}}; 316 317def format StoreAlt(code, *opt_flags) {{ 318 (header_output, 319 decoder_output, 320 exec_output, 321 decode_block) = doMemFormat(code, StoreExecute, 322 privilegedString, name, Name, opt_flags) 323}}; 324 325def format Load(code, *opt_flags) {{ 326 (header_output, 327 decoder_output, 328 exec_output, 329 decode_block) = doMemFormat(code, 330 LoadExecute, '', name, Name, opt_flags) 331}}; 332 333def format Store(code, *opt_flags) {{ 334 (header_output, 335 decoder_output, 336 exec_output, 337 decode_block) = doMemFormat(code, 338 StoreExecute, '', name, Name, opt_flags) 339}}; 340 341def format LoadStore(code, *opt_flags) {{ 342 (header_output, 343 decoder_output, 344 exec_output, 345 decode_block) = doMemFormat(code, 346 LoadStoreExecute, '', name, Name, opt_flags) 347}}; 348