util.isa (3931:de791fa53d04) | util.isa (3949:b6664282d899) |
---|---|
1// Copyright (c) 2006-2007 The Regents of The University of Michigan | 1// Copyright (c) 2006 The Regents of The University of Michigan |
2// All rights reserved. 3// 4// Redistribution and use in source and binary forms, with or without 5// modification, are permitted provided that the following conditions are 6// met: redistributions of source code must retain the above copyright 7// notice, this list of conditions and the following disclaimer; 8// redistributions in binary form must reproduce the above copyright 9// notice, this list of conditions and the following disclaimer in the --- 126 unchanged lines hidden (view full) --- 136 137//This template provides the execute functions for a load 138def template LoadExecute {{ 139 Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, 140 Trace::InstRecord *traceData) const 141 { 142 Fault fault = NoFault; 143 Addr EA; | 2// All rights reserved. 3// 4// Redistribution and use in source and binary forms, with or without 5// modification, are permitted provided that the following conditions are 6// met: redistributions of source code must retain the above copyright 7// notice, this list of conditions and the following disclaimer; 8// redistributions in binary form must reproduce the above copyright 9// notice, this list of conditions and the following disclaimer in the --- 126 unchanged lines hidden (view full) --- 136 137//This template provides the execute functions for a load 138def template LoadExecute {{ 139 Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, 140 Trace::InstRecord *traceData) const 141 { 142 Fault fault = NoFault; 143 Addr EA; |
144 %(fp_enable_check)s; | |
145 %(op_decl)s; 146 %(op_rd)s; 147 %(ea_code)s; | 144 %(op_decl)s; 145 %(op_rd)s; 146 %(ea_code)s; |
148 DPRINTF(Sparc, "The address is 0x%x\n", EA); | 147 DPRINTF(Sparc, "%s: The address is 0x%x\n", mnemonic, EA); |
149 %(fault_check)s; 150 if(fault == NoFault) 151 { 152 fault = xc->read(EA, (uint%(mem_acc_size)s_t&)Mem, %(asi_val)s); 153 } 154 if(fault == NoFault) 155 { 156 %(code)s; 157 } 158 if(fault == NoFault) 159 { 160 //Write the resulting state to the execution context 161 %(op_wb)s; 162 } 163 164 return fault; 165 } | 148 %(fault_check)s; 149 if(fault == NoFault) 150 { 151 fault = xc->read(EA, (uint%(mem_acc_size)s_t&)Mem, %(asi_val)s); 152 } 153 if(fault == NoFault) 154 { 155 %(code)s; 156 } 157 if(fault == NoFault) 158 { 159 //Write the resulting state to the execution context 160 %(op_wb)s; 161 } 162 163 return fault; 164 } |
165}}; |
|
166 | 166 |
167def template LoadInitiateAcc {{ |
|
167 Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s * xc, 168 Trace::InstRecord * traceData) const 169 { 170 Fault fault = NoFault; 171 Addr EA; 172 uint%(mem_acc_size)s_t Mem; | 168 Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s * xc, 169 Trace::InstRecord * traceData) const 170 { 171 Fault fault = NoFault; 172 Addr EA; 173 uint%(mem_acc_size)s_t Mem; |
173 %(fp_enable_check)s; 174 %(ea_decl)s; 175 %(ea_rd)s; | 174 %(op_decl)s; 175 %(op_rd)s; |
176 %(ea_code)s; | 176 %(ea_code)s; |
177 DPRINTF(Sparc, "%s: The address is 0x%x\n", mnemonic, EA); |
|
177 %(fault_check)s; 178 if(fault == NoFault) 179 { 180 fault = xc->read(EA, (uint%(mem_acc_size)s_t&)Mem, %(asi_val)s); 181 } 182 return fault; 183 } | 178 %(fault_check)s; 179 if(fault == NoFault) 180 { 181 fault = xc->read(EA, (uint%(mem_acc_size)s_t&)Mem, %(asi_val)s); 182 } 183 return fault; 184 } |
185}}; |
|
184 | 186 |
187def template LoadCompleteAcc {{ |
|
185 Fault %(class_name)s::completeAcc(PacketPtr pkt, %(CPU_exec_context)s * xc, 186 Trace::InstRecord * traceData) const 187 { 188 Fault fault = NoFault; | 188 Fault %(class_name)s::completeAcc(PacketPtr pkt, %(CPU_exec_context)s * xc, 189 Trace::InstRecord * traceData) const 190 { 191 Fault fault = NoFault; |
189 %(code_decl)s; 190 %(code_rd)s; | 192 %(op_decl)s; 193 %(op_rd)s; |
191 Mem = pkt->get<typeof(Mem)>(); 192 %(code)s; 193 if(fault == NoFault) 194 { | 194 Mem = pkt->get<typeof(Mem)>(); 195 %(code)s; 196 if(fault == NoFault) 197 { |
195 %(code_wb)s; | 198 %(op_wb)s; |
196 } 197 return fault; 198 } 199}}; 200 201//This template provides the execute functions for a store 202def template StoreExecute {{ 203 Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, 204 Trace::InstRecord *traceData) const 205 { 206 Fault fault = NoFault; 207 //This is to support the conditional store in cas instructions. 208 //It should be optomized out in all the others 209 bool storeCond = true; 210 Addr EA; | 199 } 200 return fault; 201 } 202}}; 203 204//This template provides the execute functions for a store 205def template StoreExecute {{ 206 Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, 207 Trace::InstRecord *traceData) const 208 { 209 Fault fault = NoFault; 210 //This is to support the conditional store in cas instructions. 211 //It should be optomized out in all the others 212 bool storeCond = true; 213 Addr EA; |
211 %(fp_enable_check)s; | |
212 %(op_decl)s; 213 %(op_rd)s; 214 %(ea_code)s; | 214 %(op_decl)s; 215 %(op_rd)s; 216 %(ea_code)s; |
215 DPRINTF(Sparc, "The address is 0x%x\n", EA); | 217 DPRINTF(Sparc, "%s: The address is 0x%x\n", mnemonic, EA); |
216 %(fault_check)s; 217 if(fault == NoFault) 218 { 219 %(code)s; 220 } 221 if(storeCond && fault == NoFault) 222 { 223 fault = xc->write((uint%(mem_acc_size)s_t)Mem, 224 EA, %(asi_val)s, 0); 225 } 226 if(fault == NoFault) 227 { 228 //Write the resulting state to the execution context 229 %(op_wb)s; 230 } 231 232 return fault; 233 } | 218 %(fault_check)s; 219 if(fault == NoFault) 220 { 221 %(code)s; 222 } 223 if(storeCond && fault == NoFault) 224 { 225 fault = xc->write((uint%(mem_acc_size)s_t)Mem, 226 EA, %(asi_val)s, 0); 227 } 228 if(fault == NoFault) 229 { 230 //Write the resulting state to the execution context 231 %(op_wb)s; 232 } 233 234 return fault; 235 } |
236}}; |
|
234 | 237 |
238def template StoreInitiateAcc {{ |
|
235 Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s * xc, 236 Trace::InstRecord * traceData) const 237 { 238 Fault fault = NoFault; 239 bool storeCond = true; 240 Addr EA; | 239 Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s * xc, 240 Trace::InstRecord * traceData) const 241 { 242 Fault fault = NoFault; 243 bool storeCond = true; 244 Addr EA; |
241 %(fp_enable_check)s; | |
242 %(op_decl)s; 243 %(op_rd)s; 244 %(ea_code)s; | 245 %(op_decl)s; 246 %(op_rd)s; 247 %(ea_code)s; |
245 DPRINTF(Sparc, "The address is 0x%x\n", EA); | 248 DPRINTF(Sparc, "%s: The address is 0x%x\n", mnemonic, EA); |
246 %(fault_check)s; 247 if(fault == NoFault) 248 { 249 %(code)s; 250 } 251 if(storeCond && fault == NoFault) 252 { 253 fault = xc->write((uint%(mem_acc_size)s_t)Mem, 254 EA, %(asi_val)s, 0); 255 } 256 if(fault == NoFault) 257 { 258 //Write the resulting state to the execution context 259 %(op_wb)s; 260 } 261 return fault; 262 } | 249 %(fault_check)s; 250 if(fault == NoFault) 251 { 252 %(code)s; 253 } 254 if(storeCond && fault == NoFault) 255 { 256 fault = xc->write((uint%(mem_acc_size)s_t)Mem, 257 EA, %(asi_val)s, 0); 258 } 259 if(fault == NoFault) 260 { 261 //Write the resulting state to the execution context 262 %(op_wb)s; 263 } 264 return fault; 265 } |
266}}; |
|
263 | 267 |
268def template StoreCompleteAcc {{ |
|
264 Fault %(class_name)s::completeAcc(PacketPtr, %(CPU_exec_context)s * xc, 265 Trace::InstRecord * traceData) const 266 { 267 return NoFault; 268 } 269}}; 270 271//This delcares the initiateAcc function in memory operations 272def template InitiateAccDeclare {{ 273 Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const; 274}}; 275 276//This declares the completeAcc function in memory operations 277def template CompleteAccDeclare {{ 278 Fault completeAcc(PacketPtr, %(CPU_exec_context)s *, Trace::InstRecord *) const; 279}}; 280 281//Here are some code snippets which check for various fault conditions 282let {{ | 269 Fault %(class_name)s::completeAcc(PacketPtr, %(CPU_exec_context)s * xc, 270 Trace::InstRecord * traceData) const 271 { 272 return NoFault; 273 } 274}}; 275 276//This delcares the initiateAcc function in memory operations 277def template InitiateAccDeclare {{ 278 Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const; 279}}; 280 281//This declares the completeAcc function in memory operations 282def template CompleteAccDeclare {{ 283 Fault completeAcc(PacketPtr, %(CPU_exec_context)s *, Trace::InstRecord *) const; 284}}; 285 286//Here are some code snippets which check for various fault conditions 287let {{ |
288 LoadFuncs = [LoadExecute, LoadInitiateAcc, LoadCompleteAcc] 289 StoreFuncs = [StoreExecute, StoreInitiateAcc, StoreCompleteAcc] |
|
283 # The LSB can be zero, since it's really the MSB in doubles and quads 284 # and we're dealing with doubles 285 BlockAlignmentFaultCheck = ''' 286 if(RD & 0xe) 287 fault = new IllegalInstruction; 288 else if(EA & 0x3f) 289 fault = new MemAddressNotAligned; 290 ''' | 290 # The LSB can be zero, since it's really the MSB in doubles and quads 291 # and we're dealing with doubles 292 BlockAlignmentFaultCheck = ''' 293 if(RD & 0xe) 294 fault = new IllegalInstruction; 295 else if(EA & 0x3f) 296 fault = new MemAddressNotAligned; 297 ''' |
291 TwinAlignmentFaultCheck = ''' 292 if(RD & 0x1) 293 fault = new IllegalInstruction; 294 else if(EA & 0xf) 295 fault = new MemAddressNotAligned; 296 ''' | |
297 # XXX Need to take care of pstate.hpriv as well. The lower ASIs 298 # are split into ones that are available in priv and hpriv, and 299 # those that are only available in hpriv 300 AlternateASIPrivFaultCheck = ''' 301 if(!bits(Pstate,2,2) && !bits(Hpstate,2,2) && !AsiIsUnPriv((ASI)EXT_ASI) || 302 !bits(Hpstate,2,2) && AsiIsHPriv((ASI)EXT_ASI)) 303 fault = new PrivilegedAction; 304 else if(AsiIsAsIfUser((ASI)EXT_ASI) && !bits(Pstate,2,2)) --- 10 unchanged lines hidden (view full) --- 315}}; 316 317//This function properly generates the execute functions for one of the 318//templates above. This is needed because in one case, ea computation, 319//fault checks and the actual code all occur in the same function, 320//and in the other they're distributed across two. Also note that for 321//execute functions, the name of the base class doesn't matter. 322let {{ | 298 # XXX Need to take care of pstate.hpriv as well. The lower ASIs 299 # are split into ones that are available in priv and hpriv, and 300 # those that are only available in hpriv 301 AlternateASIPrivFaultCheck = ''' 302 if(!bits(Pstate,2,2) && !bits(Hpstate,2,2) && !AsiIsUnPriv((ASI)EXT_ASI) || 303 !bits(Hpstate,2,2) && AsiIsHPriv((ASI)EXT_ASI)) 304 fault = new PrivilegedAction; 305 else if(AsiIsAsIfUser((ASI)EXT_ASI) && !bits(Pstate,2,2)) --- 10 unchanged lines hidden (view full) --- 316}}; 317 318//This function properly generates the execute functions for one of the 319//templates above. This is needed because in one case, ea computation, 320//fault checks and the actual code all occur in the same function, 321//and in the other they're distributed across two. Also note that for 322//execute functions, the name of the base class doesn't matter. 323let {{ |
323 def doSplitExecute(code, execute, name, Name, asi, opt_flags, microParam): | 324 def doSplitExecute(execute, name, Name, asi, opt_flags, microParam): |
324 microParam["asi_val"] = asi; | 325 microParam["asi_val"] = asi; |
325 codeParam = microParam.copy() 326 codeParam["ea_code"] = '' 327 codeIop = InstObjParams(name, Name, '', code, opt_flags, codeParam) 328 eaIop = InstObjParams(name, Name, '', microParam["ea_code"], 329 opt_flags, microParam) 330 iop = InstObjParams(name, Name, '', code, opt_flags, microParam) 331 (iop.ea_decl, 332 iop.ea_rd, 333 iop.ea_wb) = (eaIop.op_decl, eaIop.op_rd, eaIop.op_wb) 334 (iop.code_decl, 335 iop.code_rd, 336 iop.code_wb) = (codeIop.op_decl, codeIop.op_rd, codeIop.op_wb) 337 return execute.subst(iop) | 326 iop = InstObjParams(name, Name, '', microParam, opt_flags) 327 (execf, initf, compf) = execute 328 return execf.subst(iop) + initf.subst(iop) + compf.subst(iop) |
338 339 340 def doDualSplitExecute(code, eaRegCode, eaImmCode, execute, 341 faultCode, nameReg, nameImm, NameReg, NameImm, asi, opt_flags): 342 executeCode = '' 343 for (eaCode, name, Name) in ( 344 (eaRegCode, nameReg, NameReg), 345 (eaImmCode, nameImm, NameImm)): | 329 330 331 def doDualSplitExecute(code, eaRegCode, eaImmCode, execute, 332 faultCode, nameReg, nameImm, NameReg, NameImm, asi, opt_flags): 333 executeCode = '' 334 for (eaCode, name, Name) in ( 335 (eaRegCode, nameReg, NameReg), 336 (eaImmCode, nameImm, NameImm)): |
346 microParams = {"ea_code" : eaCode, "fault_check": faultCode} 347 executeCode += doSplitExecute(code, execute, name, Name, | 337 microParams = {"code": code, "ea_code": eaCode, 338 "fault_check": faultCode} 339 executeCode += doSplitExecute(execute, name, Name, |
348 asi, opt_flags, microParams) 349 return executeCode 350}}; | 340 asi, opt_flags, microParams) 341 return executeCode 342}}; |