str.isa revision 8301:858384f3af1c
16100Sgblack@eecs.umich.edu// -*- mode:c++ -*- 26098Sgblack@eecs.umich.edu 36098Sgblack@eecs.umich.edu// Copyright (c) 2010 ARM Limited 46100Sgblack@eecs.umich.edu// All rights reserved 56100Sgblack@eecs.umich.edu// 66100Sgblack@eecs.umich.edu// The license below extends only to copyright in the software and shall 76100Sgblack@eecs.umich.edu// not be construed as granting a license to any other intellectual 86100Sgblack@eecs.umich.edu// property including but not limited to intellectual property relating 96100Sgblack@eecs.umich.edu// to a hardware implementation of the functionality of the software 106100Sgblack@eecs.umich.edu// licensed hereunder. You may use the software subject to the license 116100Sgblack@eecs.umich.edu// terms below provided that you ensure that this notice is replicated 126098Sgblack@eecs.umich.edu// unmodified and in its entirety in all distributions of the software, 136100Sgblack@eecs.umich.edu// modified or unmodified, in source code or in binary form. 146098Sgblack@eecs.umich.edu// 156098Sgblack@eecs.umich.edu// Redistribution and use in source and binary forms, with or without 166098Sgblack@eecs.umich.edu// modification, are permitted provided that the following conditions are 176098Sgblack@eecs.umich.edu// met: redistributions of source code must retain the above copyright 186098Sgblack@eecs.umich.edu// notice, this list of conditions and the following disclaimer; 196098Sgblack@eecs.umich.edu// redistributions in binary form must reproduce the above copyright 206098Sgblack@eecs.umich.edu// notice, this list of conditions and the following disclaimer in the 216098Sgblack@eecs.umich.edu// documentation and/or other materials provided with the distribution; 226098Sgblack@eecs.umich.edu// neither the name of the copyright holders nor the names of its 236098Sgblack@eecs.umich.edu// contributors may be used to endorse or promote products derived from 246098Sgblack@eecs.umich.edu// this software without specific prior written permission. 256098Sgblack@eecs.umich.edu// 266098Sgblack@eecs.umich.edu// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 276098Sgblack@eecs.umich.edu// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 286098Sgblack@eecs.umich.edu// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 296098Sgblack@eecs.umich.edu// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 306098Sgblack@eecs.umich.edu// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 316098Sgblack@eecs.umich.edu// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 326098Sgblack@eecs.umich.edu// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 336098Sgblack@eecs.umich.edu// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 346098Sgblack@eecs.umich.edu// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 356098Sgblack@eecs.umich.edu// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 366098Sgblack@eecs.umich.edu// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 376098Sgblack@eecs.umich.edu// 386098Sgblack@eecs.umich.edu// Authors: Gabe Black 396098Sgblack@eecs.umich.edu 406098Sgblack@eecs.umich.edulet {{ 416098Sgblack@eecs.umich.edu 426098Sgblack@eecs.umich.edu header_output = "" 436098Sgblack@eecs.umich.edu decoder_output = "" 446098Sgblack@eecs.umich.edu exec_output = "" 456098Sgblack@eecs.umich.edu 466098Sgblack@eecs.umich.edu class StoreInst(LoadStoreInst): 476098Sgblack@eecs.umich.edu execBase = 'Store' 486098Sgblack@eecs.umich.edu 496098Sgblack@eecs.umich.edu def __init__(self, mnem, post, add, writeback, size=4, 506098Sgblack@eecs.umich.edu sign=False, user=False, flavor="normal", 516098Sgblack@eecs.umich.edu instFlags = []): 526098Sgblack@eecs.umich.edu super(StoreInst, self).__init__() 536098Sgblack@eecs.umich.edu 546098Sgblack@eecs.umich.edu self.name = mnem 556098Sgblack@eecs.umich.edu self.post = post 566098Sgblack@eecs.umich.edu self.add = add 576098Sgblack@eecs.umich.edu self.writeback = writeback 586098Sgblack@eecs.umich.edu self.size = size 596098Sgblack@eecs.umich.edu self.sign = sign 606098Sgblack@eecs.umich.edu self.user = user 616098Sgblack@eecs.umich.edu self.flavor = flavor 626098Sgblack@eecs.umich.edu self.instFlags = instFlags 636098Sgblack@eecs.umich.edu if self.add: 646098Sgblack@eecs.umich.edu self.op = " +" 656098Sgblack@eecs.umich.edu else: 666098Sgblack@eecs.umich.edu self.op = " -" 676098Sgblack@eecs.umich.edu 686098Sgblack@eecs.umich.edu self.memFlags = ["ArmISA::TLB::MustBeOne"] 696098Sgblack@eecs.umich.edu self.codeBlobs = { "postacc_code" : "" } 706098Sgblack@eecs.umich.edu 716098Sgblack@eecs.umich.edu def emitHelper(self, base = 'Memory', wbDecl = None): 726098Sgblack@eecs.umich.edu 736098Sgblack@eecs.umich.edu global header_output, decoder_output, exec_output 746098Sgblack@eecs.umich.edu 756098Sgblack@eecs.umich.edu codeBlobs = self.codeBlobs 766098Sgblack@eecs.umich.edu codeBlobs["predicate_test"] = pickPredicate(codeBlobs) 776098Sgblack@eecs.umich.edu (newHeader, 786098Sgblack@eecs.umich.edu newDecoder, 796098Sgblack@eecs.umich.edu newExec) = self.fillTemplates(self.name, self.Name, codeBlobs, 806098Sgblack@eecs.umich.edu self.memFlags, self.instFlags, base, wbDecl) 816098Sgblack@eecs.umich.edu 826098Sgblack@eecs.umich.edu header_output += newHeader 836098Sgblack@eecs.umich.edu decoder_output += newDecoder 846098Sgblack@eecs.umich.edu exec_output += newExec 856098Sgblack@eecs.umich.edu 866098Sgblack@eecs.umich.edu class SrsInst(LoadStoreInst): 876098Sgblack@eecs.umich.edu execBase = 'Store' 886098Sgblack@eecs.umich.edu decConstBase = 'Srs' 896098Sgblack@eecs.umich.edu 906098Sgblack@eecs.umich.edu def __init__(self, mnem, post, add, writeback): 916098Sgblack@eecs.umich.edu super(SrsInst, self).__init__() 926098Sgblack@eecs.umich.edu self.name = mnem 936098Sgblack@eecs.umich.edu self.post = post 946098Sgblack@eecs.umich.edu self.add = add 956098Sgblack@eecs.umich.edu self.writeback = writeback 966098Sgblack@eecs.umich.edu 976098Sgblack@eecs.umich.edu self.Name = "SRS_" + storeImmClassName(post, add, writeback, 8) 986098Sgblack@eecs.umich.edu 996098Sgblack@eecs.umich.edu def emit(self): 1006098Sgblack@eecs.umich.edu offset = 0 1016098Sgblack@eecs.umich.edu if self.post != self.add: 1026098Sgblack@eecs.umich.edu offset += 4 1036098Sgblack@eecs.umich.edu if not self.add: 1046098Sgblack@eecs.umich.edu offset -= 8 1056098Sgblack@eecs.umich.edu 1066098Sgblack@eecs.umich.edu eaCode = "EA = SpMode + %d;" % offset 1076098Sgblack@eecs.umich.edu 1086098Sgblack@eecs.umich.edu wbDiff = -8 1096098Sgblack@eecs.umich.edu if self.add: 1106098Sgblack@eecs.umich.edu wbDiff = 8 1116098Sgblack@eecs.umich.edu accCode = ''' 1126098Sgblack@eecs.umich.edu CPSR cpsr = Cpsr; 1136098Sgblack@eecs.umich.edu Mem.ud = (uint64_t)cSwap(LR.uw, cpsr.e) | 1146098Sgblack@eecs.umich.edu ((uint64_t)cSwap(Spsr.uw, cpsr.e) << 32); 1156098Sgblack@eecs.umich.edu ''' 1166098Sgblack@eecs.umich.edu 1176098Sgblack@eecs.umich.edu global header_output, decoder_output, exec_output 1186098Sgblack@eecs.umich.edu 1196098Sgblack@eecs.umich.edu codeBlobs = { "ea_code": eaCode, 1206098Sgblack@eecs.umich.edu "memacc_code": accCode, 1216098Sgblack@eecs.umich.edu "postacc_code": "" } 1226098Sgblack@eecs.umich.edu codeBlobs["predicate_test"] = pickPredicate(codeBlobs) 1236098Sgblack@eecs.umich.edu 1246098Sgblack@eecs.umich.edu wbDecl = None 1256098Sgblack@eecs.umich.edu if self.writeback: 1266098Sgblack@eecs.umich.edu wbDecl = '''MicroAddiUop(machInst, 1276098Sgblack@eecs.umich.edu intRegInMode((OperatingMode)regMode, INTREG_SP), 1286098Sgblack@eecs.umich.edu intRegInMode((OperatingMode)regMode, INTREG_SP), 1296098Sgblack@eecs.umich.edu %d);''' % wbDiff 1306098Sgblack@eecs.umich.edu 1316098Sgblack@eecs.umich.edu (newHeader, 1326098Sgblack@eecs.umich.edu newDecoder, 1336098Sgblack@eecs.umich.edu newExec) = self.fillTemplates(self.name, self.Name, codeBlobs, 1346098Sgblack@eecs.umich.edu ["ArmISA::TLB::AlignWord", "ArmISA::TLB::MustBeOne"], [], 1356098Sgblack@eecs.umich.edu 'SrsOp', wbDecl) 1366098Sgblack@eecs.umich.edu 1376098Sgblack@eecs.umich.edu header_output += newHeader 1386098Sgblack@eecs.umich.edu decoder_output += newDecoder 1396098Sgblack@eecs.umich.edu exec_output += newExec 1406098Sgblack@eecs.umich.edu 1416098Sgblack@eecs.umich.edu class StoreImmInst(StoreInst): 1426098Sgblack@eecs.umich.edu def __init__(self, *args, **kargs): 1436098Sgblack@eecs.umich.edu super(StoreImmInst, self).__init__(*args, **kargs) 1446098Sgblack@eecs.umich.edu self.offset = self.op + " imm" 1456098Sgblack@eecs.umich.edu 1466098Sgblack@eecs.umich.edu if self.add: 1476098Sgblack@eecs.umich.edu self.wbDecl = "MicroAddiUop(machInst, base, base, imm);" 1486098Sgblack@eecs.umich.edu else: 1496098Sgblack@eecs.umich.edu self.wbDecl = "MicroSubiUop(machInst, base, base, imm);" 1506098Sgblack@eecs.umich.edu 1516098Sgblack@eecs.umich.edu class StoreRegInst(StoreInst): 1526098Sgblack@eecs.umich.edu def __init__(self, *args, **kargs): 1536098Sgblack@eecs.umich.edu super(StoreRegInst, self).__init__(*args, **kargs) 1546098Sgblack@eecs.umich.edu self.offset = self.op + " shift_rm_imm(Index, shiftAmt," + \ 1556098Sgblack@eecs.umich.edu " shiftType, CondCodesF<29:>)" 1566098Sgblack@eecs.umich.edu if self.add: 1576098Sgblack@eecs.umich.edu self.wbDecl = ''' 1586098Sgblack@eecs.umich.edu MicroAddUop(machInst, base, base, index, shiftAmt, shiftType); 1596098Sgblack@eecs.umich.edu ''' 1606098Sgblack@eecs.umich.edu else: 1616098Sgblack@eecs.umich.edu self.wbDecl = ''' 1626098Sgblack@eecs.umich.edu MicroSubUop(machInst, base, base, index, shiftAmt, shiftType); 1636098Sgblack@eecs.umich.edu ''' 1646098Sgblack@eecs.umich.edu 1656098Sgblack@eecs.umich.edu class StoreSingle(StoreInst): 1666098Sgblack@eecs.umich.edu def __init__(self, *args, **kargs): 1676098Sgblack@eecs.umich.edu super(StoreSingle, self).__init__(*args, **kargs) 1686098Sgblack@eecs.umich.edu 1696098Sgblack@eecs.umich.edu # Build the default class name 1706098Sgblack@eecs.umich.edu self.Name = self.nameFunc(self.post, self.add, self.writeback, 1716098Sgblack@eecs.umich.edu self.size, self.sign, self.user) 1726098Sgblack@eecs.umich.edu 173 # Add memory request flags where necessary 174 self.memFlags.append("%d" % (self.size - 1)) 175 if self.user: 176 self.memFlags.append("ArmISA::TLB::UserMode") 177 178 if self.flavor == "exclusive": 179 self.memFlags.append("Request::LLSC") 180 elif self.flavor != "fp": 181 self.memFlags.append("ArmISA::TLB::AllowUnaligned") 182 183 # Disambiguate the class name for different flavors of stores 184 if self.flavor != "normal": 185 self.Name = "%s_%s" % (self.name.upper(), self.Name) 186 187 def emit(self): 188 # Address computation 189 eaCode = "EA = Base" 190 if not self.post: 191 eaCode += self.offset 192 eaCode += ";" 193 194 if self.flavor == "fp": 195 eaCode += vfpEnabledCheckCode 196 197 self.codeBlobs["ea_code"] = eaCode 198 199 # Code that actually handles the access 200 if self.flavor == "fp": 201 accCode = 'Mem%(suffix)s = cSwap(FpDest.uw, ((CPSR)Cpsr).e);' 202 else: 203 accCode = \ 204 'Mem%(suffix)s = cSwap(Dest%(suffix)s, ((CPSR)Cpsr).e);' 205 accCode = accCode % \ 206 { "suffix" : buildMemSuffix(self.sign, self.size) } 207 208 self.codeBlobs["memacc_code"] = accCode 209 210 # Push it out to the output files 211 base = buildMemBase(self.basePrefix, self.post, self.writeback) 212 wbDecl = None 213 if self.writeback: 214 wbDecl = self.wbDecl 215 self.emitHelper(base, wbDecl) 216 217 def storeImmClassName(post, add, writeback, size=4, sign=False, user=False): 218 return memClassName("STORE_IMM", post, add, writeback, size, sign, user) 219 220 class StoreImmEx(StoreImmInst, StoreSingle): 221 execBase = 'StoreEx' 222 decConstBase = 'StoreExImm' 223 basePrefix = 'MemoryExImm' 224 nameFunc = staticmethod(storeImmClassName) 225 226 def __init__(self, *args, **kargs): 227 super(StoreImmEx, self).__init__(*args, **kargs) 228 self.codeBlobs["postacc_code"] = "Result = !writeResult;" 229 230 class StoreImm(StoreImmInst, StoreSingle): 231 decConstBase = 'LoadStoreImm' 232 basePrefix = 'MemoryImm' 233 nameFunc = staticmethod(storeImmClassName) 234 235 def storeRegClassName(post, add, writeback, size=4, sign=False, user=False): 236 return memClassName("STORE_REG", post, add, writeback, size, sign, user) 237 238 class StoreReg(StoreRegInst, StoreSingle): 239 decConstBase = 'StoreReg' 240 basePrefix = 'MemoryReg' 241 nameFunc = staticmethod(storeRegClassName) 242 243 class StoreDouble(StoreInst): 244 def __init__(self, *args, **kargs): 245 super(StoreDouble, self).__init__(*args, **kargs) 246 247 # Build the default class name 248 self.Name = self.nameFunc(self.post, self.add, self.writeback) 249 250 # Add memory request flags where necessary 251 if self.flavor == "exclusive": 252 self.memFlags.append("Request::LLSC") 253 self.memFlags.append("ArmISA::TLB::AlignDoubleWord") 254 else: 255 self.memFlags.append("ArmISA::TLB::AlignWord") 256 257 # Disambiguate the class name for different flavors of stores 258 if self.flavor != "normal": 259 self.Name = "%s_%s" % (self.name.upper(), self.Name) 260 261 def emit(self): 262 # Address computation code 263 eaCode = "EA = Base" 264 if not self.post: 265 eaCode += self.offset 266 eaCode += ";" 267 268 if self.flavor == "fp": 269 eaCode += vfpEnabledCheckCode 270 271 self.codeBlobs["ea_code"] = eaCode 272 273 # Code that actually handles the access 274 if self.flavor == "fp": 275 accCode = ''' 276 uint64_t swappedMem = (uint64_t)FpDest.uw | 277 ((uint64_t)FpDest2.uw << 32); 278 Mem.ud = cSwap(swappedMem, ((CPSR)Cpsr).e); 279 ''' 280 else: 281 accCode = ''' 282 CPSR cpsr = Cpsr; 283 Mem.ud = (uint64_t)cSwap(Dest.uw, cpsr.e) | 284 ((uint64_t)cSwap(Dest2.uw, cpsr.e) << 32); 285 ''' 286 287 self.codeBlobs["memacc_code"] = accCode 288 289 # Push it out to the output files 290 base = buildMemBase(self.basePrefix, self.post, self.writeback) 291 wbDecl = None 292 if self.writeback: 293 wbDecl = self.wbDecl 294 self.emitHelper(base, wbDecl) 295 296 def storeDoubleImmClassName(post, add, writeback): 297 return memClassName("STORE_IMMD", post, add, writeback, 4, False, False) 298 299 class StoreDoubleImmEx(StoreImmInst, StoreDouble): 300 execBase = 'StoreEx' 301 decConstBase = 'StoreExDImm' 302 basePrefix = 'MemoryExDImm' 303 nameFunc = staticmethod(storeDoubleImmClassName) 304 305 def __init__(self, *args, **kargs): 306 super(StoreDoubleImmEx, self).__init__(*args, **kargs) 307 self.codeBlobs["postacc_code"] = "Result = !writeResult;" 308 309 class StoreDoubleImm(StoreImmInst, StoreDouble): 310 decConstBase = 'LoadStoreDImm' 311 basePrefix = 'MemoryDImm' 312 nameFunc = staticmethod(storeDoubleImmClassName) 313 314 def storeDoubleRegClassName(post, add, writeback): 315 return memClassName("STORE_REGD", post, add, writeback, 4, False, False) 316 317 class StoreDoubleReg(StoreRegInst, StoreDouble): 318 decConstBase = 'StoreDReg' 319 basePrefix = 'MemoryDReg' 320 nameFunc = staticmethod(storeDoubleRegClassName) 321 322 def buildStores(mnem, size=4, sign=False, user=False): 323 StoreImm(mnem, True, True, True, size, sign, user).emit() 324 StoreReg(mnem, True, True, True, size, sign, user).emit() 325 StoreImm(mnem, True, False, True, size, sign, user).emit() 326 StoreReg(mnem, True, False, True, size, sign, user).emit() 327 StoreImm(mnem, False, True, True, size, sign, user).emit() 328 StoreReg(mnem, False, True, True, size, sign, user).emit() 329 StoreImm(mnem, False, False, True, size, sign, user).emit() 330 StoreReg(mnem, False, False, True, size, sign, user).emit() 331 StoreImm(mnem, False, True, False, size, sign, user).emit() 332 StoreReg(mnem, False, True, False, size, sign, user).emit() 333 StoreImm(mnem, False, False, False, size, sign, user).emit() 334 StoreReg(mnem, False, False, False, size, sign, user).emit() 335 336 def buildDoubleStores(mnem): 337 StoreDoubleImm(mnem, True, True, True).emit() 338 StoreDoubleReg(mnem, True, True, True).emit() 339 StoreDoubleImm(mnem, True, False, True).emit() 340 StoreDoubleReg(mnem, True, False, True).emit() 341 StoreDoubleImm(mnem, False, True, True).emit() 342 StoreDoubleReg(mnem, False, True, True).emit() 343 StoreDoubleImm(mnem, False, False, True).emit() 344 StoreDoubleReg(mnem, False, False, True).emit() 345 StoreDoubleImm(mnem, False, True, False).emit() 346 StoreDoubleReg(mnem, False, True, False).emit() 347 StoreDoubleImm(mnem, False, False, False).emit() 348 StoreDoubleReg(mnem, False, False, False).emit() 349 350 def buildSrsStores(mnem): 351 SrsInst(mnem, True, True, True).emit() 352 SrsInst(mnem, True, True, False).emit() 353 SrsInst(mnem, True, False, True).emit() 354 SrsInst(mnem, True, False, False).emit() 355 SrsInst(mnem, False, True, True).emit() 356 SrsInst(mnem, False, True, False).emit() 357 SrsInst(mnem, False, False, True).emit() 358 SrsInst(mnem, False, False, False).emit() 359 360 buildStores("str") 361 buildStores("strt", user=True) 362 buildStores("strb", size=1) 363 buildStores("strbt", size=1, user=True) 364 buildStores("strh", size=2) 365 buildStores("strht", size=2, user=True) 366 367 buildSrsStores("srs") 368 369 buildDoubleStores("strd") 370 371 StoreImmEx("strex", False, True, False, size=4, flavor="exclusive", 372 instFlags = ['IsStoreConditional']).emit() 373 StoreImmEx("strexh", False, True, False, size=2, flavor="exclusive", 374 instFlags = ['IsStoreConditional']).emit() 375 StoreImmEx("strexb", False, True, False, size=1, flavor="exclusive", 376 instFlags = ['IsStoreConditional']).emit() 377 StoreDoubleImmEx("strexd", False, True, False, flavor="exclusive", 378 instFlags = ['IsStoreConditional']).emit() 379 380 StoreImm("vstr", False, True, False, size=4, flavor="fp").emit() 381 StoreImm("vstr", False, False, False, size=4, flavor="fp").emit() 382 StoreDoubleImm("vstr", False, True, False, flavor="fp").emit() 383 StoreDoubleImm("vstr", False, False, False, flavor="fp").emit() 384}}; 385