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