118 CondCodes = CondCodesMask & newCpsr; 119 ''' 120 self.codeBlobs["memacc_code"] = accCode 121 122 wbDecl = None 123 if self.writeback: 124 wbDecl = "MicroAddiUop(machInst, base, base, %d);" % wbDiff 125 self.emitHelper('RfeOp', wbDecl, ["IsSerializeAfter", "IsNonSpeculative"]) 126 127 class LoadImmInst(LoadInst): 128 def __init__(self, *args, **kargs): 129 super(LoadImmInst, self).__init__(*args, **kargs) 130 self.offset = self.op + " imm" 131 132 if self.add: 133 self.wbDecl = "MicroAddiUop(machInst, base, base, imm);" 134 else: 135 self.wbDecl = "MicroSubiUop(machInst, base, base, imm);" 136 137 class LoadRegInst(LoadInst): 138 def __init__(self, *args, **kargs): 139 super(LoadRegInst, self).__init__(*args, **kargs) 140 self.offset = self.op + " shift_rm_imm(Index, shiftAmt," + \ 141 " shiftType, CondCodes<29:>)" 142 if self.add: 143 self.wbDecl = ''' 144 MicroAddUop(machInst, base, base, wbIndexReg, shiftAmt, shiftType); 145 ''' 146 else: 147 self.wbDecl = ''' 148 MicroSubUop(machInst, base, base, wbIndexReg, shiftAmt, shiftType); 149 ''' 150 151 class LoadSingle(LoadInst): 152 def __init__(self, *args, **kargs): 153 super(LoadSingle, self).__init__(*args, **kargs) 154 155 # Build the default class name 156 self.Name = self.nameFunc(self.post, self.add, self.writeback, 157 self.size, self.sign, self.user) 158 159 # Add memory request flags where necessary 160 self.memFlags.append("%d" % (self.size - 1)) 161 if self.user: 162 self.memFlags.append("ArmISA::TLB::UserMode") 163 164 if self.flavor == "prefetch": 165 self.memFlags.append("Request::PREFETCH") 166 elif self.flavor == "exclusive": 167 self.memFlags.append("Request::LLSC") 168 elif self.flavor == "normal": 169 self.memFlags.append("ArmISA::TLB::AllowUnaligned") 170 171 # Disambiguate the class name for different flavors of loads 172 if self.flavor != "normal": 173 self.Name = "%s_%s" % (self.name.upper(), self.Name) 174 175 def emit(self): 176 # Address compuation code 177 eaCode = "EA = Base" 178 if not self.post: 179 eaCode += self.offset 180 eaCode += ";" 181 182 if self.flavor == "fp": 183 eaCode += vfpEnabledCheckCode 184 185 self.codeBlobs["ea_code"] = eaCode 186 187 # Code that actually handles the access 188 if self.flavor == "prefetch": 189 accCode = 'uint64_t temp = Mem%s; temp = temp;' 190 elif self.flavor == "fp": 191 accCode = "FpDest.uw = cSwap(Mem%s, ((CPSR)Cpsr).e);\n" 192 else: 193 accCode = "IWDest = cSwap(Mem%s, ((CPSR)Cpsr).e);" 194 accCode = accCode % buildMemSuffix(self.sign, self.size) 195 196 self.codeBlobs["memacc_code"] = accCode 197 198 # Push it out to the output files 199 base = buildMemBase(self.basePrefix, self.post, self.writeback) 200 wbDecl = None 201 if self.writeback: 202 wbDecl = self.wbDecl 203 self.emitHelper(base, wbDecl) 204 205 def loadImmClassName(post, add, writeback, size=4, sign=False, user=False): 206 return memClassName("LOAD_IMM", post, add, writeback, size, sign, user) 207 208 class LoadImm(LoadImmInst, LoadSingle): 209 decConstBase = 'LoadImm' 210 basePrefix = 'MemoryImm' 211 nameFunc = staticmethod(loadImmClassName) 212 213 def loadRegClassName(post, add, writeback, size=4, sign=False, user=False): 214 return memClassName("LOAD_REG", post, add, writeback, size, sign, user) 215 216 class LoadReg(LoadRegInst, LoadSingle): 217 decConstBase = 'LoadReg' 218 basePrefix = 'MemoryReg' 219 nameFunc = staticmethod(loadRegClassName) 220 221 class LoadDouble(LoadInst): 222 def __init__(self, *args, **kargs): 223 super(LoadDouble, self).__init__(*args, **kargs) 224 225 # Build the default class name 226 self.Name = self.nameFunc(self.post, self.add, self.writeback) 227 228 # Add memory request flags where necessary 229 if self.flavor == "exclusive": 230 self.memFlags.append("Request::LLSC") 231 self.memFlags.append("ArmISA::TLB::AlignDoubleWord") 232 else: 233 self.memFlags.append("ArmISA::TLB::AlignWord") 234 235 # Disambiguate the class name for different flavors of loads 236 if self.flavor != "normal": 237 self.Name = "%s_%s" % (self.name.upper(), self.Name) 238 239 def emit(self): 240 # Address computation code 241 eaCode = "EA = Base" 242 if not self.post: 243 eaCode += self.offset 244 eaCode += ";" 245 246 if self.flavor == "fp": 247 eaCode += vfpEnabledCheckCode 248 249 self.codeBlobs["ea_code"] = eaCode 250 251 # Code that actually handles the access 252 if self.flavor != "fp": 253 accCode = ''' 254 CPSR cpsr = Cpsr; 255 Dest = cSwap<uint32_t>(Mem.ud, cpsr.e); 256 Dest2 = cSwap<uint32_t>(Mem.ud >> 32, cpsr.e); 257 ''' 258 else: 259 accCode = ''' 260 uint64_t swappedMem = cSwap(Mem.ud, ((CPSR)Cpsr).e); 261 FpDest.uw = (uint32_t)swappedMem; 262 FpDest2.uw = (uint32_t)(swappedMem >> 32); 263 ''' 264 265 self.codeBlobs["memacc_code"] = accCode 266 267 # Push it out to the output files 268 base = buildMemBase(self.basePrefix, self.post, self.writeback) 269 wbDecl = None 270 if self.writeback: 271 wbDecl = self.wbDecl 272 self.emitHelper(base, wbDecl) 273 274 def loadDoubleImmClassName(post, add, writeback): 275 return memClassName("LOAD_IMMD", post, add, writeback, 4, False, False) 276 277 class LoadDoubleImm(LoadImmInst, LoadDouble): 278 decConstBase = 'LoadStoreDImm' 279 basePrefix = 'MemoryDImm' 280 nameFunc = staticmethod(loadDoubleImmClassName) 281 282 def loadDoubleRegClassName(post, add, writeback): 283 return memClassName("LOAD_REGD", post, add, writeback, 4, False, False) 284 285 class LoadDoubleReg(LoadRegInst, LoadDouble): 286 decConstBase = 'LoadDReg' 287 basePrefix = 'MemoryDReg' 288 nameFunc = staticmethod(loadDoubleRegClassName) 289 290 def buildLoads(mnem, size=4, sign=False, user=False): 291 LoadImm(mnem, True, True, True, size, sign, user).emit() 292 LoadReg(mnem, True, True, True, size, sign, user).emit() 293 LoadImm(mnem, True, False, True, size, sign, user).emit() 294 LoadReg(mnem, True, False, True, size, sign, user).emit() 295 LoadImm(mnem, False, True, True, size, sign, user).emit() 296 LoadReg(mnem, False, True, True, size, sign, user).emit() 297 LoadImm(mnem, False, False, True, size, sign, user).emit() 298 LoadReg(mnem, False, False, True, size, sign, user).emit() 299 LoadImm(mnem, False, True, False, size, sign, user).emit() 300 LoadReg(mnem, False, True, False, size, sign, user).emit() 301 LoadImm(mnem, False, False, False, size, sign, user).emit() 302 LoadReg(mnem, False, False, False, size, sign, user).emit() 303 304 def buildDoubleLoads(mnem): 305 LoadDoubleImm(mnem, True, True, True).emit() 306 LoadDoubleReg(mnem, True, True, True).emit() 307 LoadDoubleImm(mnem, True, False, True).emit() 308 LoadDoubleReg(mnem, True, False, True).emit() 309 LoadDoubleImm(mnem, False, True, True).emit() 310 LoadDoubleReg(mnem, False, True, True).emit() 311 LoadDoubleImm(mnem, False, False, True).emit() 312 LoadDoubleReg(mnem, False, False, True).emit() 313 LoadDoubleImm(mnem, False, True, False).emit() 314 LoadDoubleReg(mnem, False, True, False).emit() 315 LoadDoubleImm(mnem, False, False, False).emit() 316 LoadDoubleReg(mnem, False, False, False).emit() 317 318 def buildRfeLoads(mnem): 319 RfeInst(mnem, True, True, True).emit() 320 RfeInst(mnem, True, True, False).emit() 321 RfeInst(mnem, True, False, True).emit() 322 RfeInst(mnem, True, False, False).emit() 323 RfeInst(mnem, False, True, True).emit() 324 RfeInst(mnem, False, True, False).emit() 325 RfeInst(mnem, False, False, True).emit() 326 RfeInst(mnem, False, False, False).emit() 327 328 def buildPrefetches(mnem): 329 LoadReg(mnem, False, False, False, size=1, flavor="prefetch").emit() 330 LoadImm(mnem, False, False, False, size=1, flavor="prefetch").emit() 331 LoadReg(mnem, False, True, False, size=1, flavor="prefetch").emit() 332 LoadImm(mnem, False, True, False, size=1, flavor="prefetch").emit() 333 334 buildLoads("ldr") 335 buildLoads("ldrt", user=True) 336 buildLoads("ldrb", size=1) 337 buildLoads("ldrbt", size=1, user=True) 338 buildLoads("ldrsb", size=1, sign=True) 339 buildLoads("ldrsbt", size=1, sign=True, user=True) 340 buildLoads("ldrh", size=2) 341 buildLoads("ldrht", size=2, user=True) 342 buildLoads("hdrsh", size=2, sign=True) 343 buildLoads("ldrsht", size=2, sign=True, user=True) 344 345 buildDoubleLoads("ldrd") 346 347 buildRfeLoads("rfe") 348 349 buildPrefetches("pld") 350 buildPrefetches("pldw") 351 buildPrefetches("pli") 352 353 LoadImm("ldrex", False, True, False, size=4, flavor="exclusive").emit() 354 LoadImm("ldrexh", False, True, False, size=2, flavor="exclusive").emit() 355 LoadImm("ldrexb", False, True, False, size=1, flavor="exclusive").emit() 356 LoadDoubleImm("ldrexd", False, True, False, flavor="exclusive").emit() 357 358 LoadImm("vldr", False, True, False, size=4, flavor="fp").emit() 359 LoadImm("vldr", False, False, False, size=4, flavor="fp").emit() 360 LoadDoubleImm("vldr", False, True, False, flavor="fp").emit() 361 LoadDoubleImm("vldr", False, False, False, flavor="fp").emit() 362}};
|