str.isa revision 7644
12SN/A// -*- mode:c++ -*- 21762SN/A 32SN/A// Copyright (c) 2010 ARM Limited 42SN/A// All rights reserved 52SN/A// 62SN/A// The license below extends only to copyright in the software and shall 72SN/A// not be construed as granting a license to any other intellectual 82SN/A// property including but not limited to intellectual property relating 92SN/A// to a hardware implementation of the functionality of the software 102SN/A// licensed hereunder. You may use the software subject to the license 112SN/A// terms below provided that you ensure that this notice is replicated 122SN/A// unmodified and in its entirety in all distributions of the software, 132SN/A// modified or unmodified, in source code or in binary form. 142SN/A// 152SN/A// Redistribution and use in source and binary forms, with or without 162SN/A// modification, are permitted provided that the following conditions are 172SN/A// met: redistributions of source code must retain the above copyright 182SN/A// notice, this list of conditions and the following disclaimer; 192SN/A// redistributions in binary form must reproduce the above copyright 202SN/A// notice, this list of conditions and the following disclaimer in the 212SN/A// documentation and/or other materials provided with the distribution; 222SN/A// neither the name of the copyright holders nor the names of its 232SN/A// contributors may be used to endorse or promote products derived from 242SN/A// this software without specific prior written permission. 252SN/A// 262SN/A// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 272665Ssaidi@eecs.umich.edu// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 282665Ssaidi@eecs.umich.edu// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 292665Ssaidi@eecs.umich.edu// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 302SN/A// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 312SN/A// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 321717SN/A// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 331717SN/A// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 342SN/A// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 352SN/A// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 362SN/A// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 37707SN/A// 381858SN/A// Authors: Gabe Black 391717SN/A 4056SN/Alet {{ 4156SN/A 422109SN/A header_output = "" 432SN/A decoder_output = "" 442190SN/A exec_output = "" 452315SN/A 462680Sktlim@umich.edu class StoreInst(LoadStoreInst): 472SN/A execBase = 'Store' 482SN/A 492SN/A def __init__(self, mnem, post, add, writeback, size=4, 502SN/A sign=False, user=False, flavor="normal"): 511634SN/A super(StoreInst, self).__init__() 521634SN/A 531695SN/A self.name = mnem 541634SN/A self.post = post 551634SN/A self.add = add 561695SN/A self.writeback = writeback 571695SN/A self.size = size 581695SN/A self.sign = sign 591634SN/A self.user = user 601858SN/A self.flavor = flavor 612SN/A 622107SN/A if self.add: 632SN/A self.op = " +" 642SN/A else: 652SN/A self.op = " -" 662SN/A 672SN/A self.memFlags = ["ArmISA::TLB::MustBeOne"] 682SN/A self.codeBlobs = { "postacc_code" : "" } 691133SN/A 702SN/A def emitHelper(self, base = 'Memory'): 712SN/A 722107SN/A global header_output, decoder_output, exec_output 732SN/A 742SN/A codeBlobs = self.codeBlobs 752SN/A codeBlobs["predicate_test"] = pickPredicate(codeBlobs) 762SN/A (newHeader, 772SN/A newDecoder, 782SN/A newExec) = self.fillTemplates(self.name, self.Name, codeBlobs, 792SN/A self.memFlags, [], base) 801917SN/A 811917SN/A header_output += newHeader 821917SN/A decoder_output += newDecoder 831917SN/A exec_output += newExec 841917SN/A 851917SN/A class SrsInst(LoadStoreInst): 861917SN/A execBase = 'Store' 871917SN/A decConstBase = 'Srs' 881917SN/A 891917SN/A def __init__(self, mnem, post, add, writeback): 901917SN/A super(SrsInst, self).__init__() 911917SN/A self.name = mnem 922SN/A self.post = post 932SN/A self.add = add 942SN/A self.writeback = writeback 952680Sktlim@umich.edu 962SN/A self.Name = "SRS_" + storeImmClassName(post, add, writeback, 8) 972SN/A 98393SN/A def emit(self): 99393SN/A offset = 0 100393SN/A if self.post != self.add: 101393SN/A offset += 4 102393SN/A if not self.add: 103393SN/A offset -= 8 104393SN/A 105393SN/A eaCode = "EA = SpMode + %d;" % offset 106393SN/A 107393SN/A wbDiff = -8 108393SN/A if self.add: 109393SN/A wbDiff = 8 110393SN/A accCode = ''' 111393SN/A CPSR cpsr = Cpsr; 1122SN/A Mem.ud = (uint64_t)cSwap(LR.uw, cpsr.e) | 1132SN/A ((uint64_t)cSwap(Spsr.uw, cpsr.e) << 32); 1141400SN/A ''' 1151400SN/A if self.writeback: 1161400SN/A accCode += "SpMode = SpMode + %s;\n" % wbDiff 1171400SN/A 1181400SN/A global header_output, decoder_output, exec_output 1191400SN/A 1201400SN/A codeBlobs = { "ea_code": eaCode, 1211400SN/A "memacc_code": accCode, 1221400SN/A "postacc_code": "" } 1231695SN/A codeBlobs["predicate_test"] = pickPredicate(codeBlobs) 1241400SN/A 1251400SN/A (newHeader, 1262378SN/A newDecoder, 1271858SN/A newExec) = self.fillTemplates(self.name, self.Name, codeBlobs, 1281806SN/A ["ArmISA::TLB::AlignWord", "ArmISA::TLB::MustBeOne"], [], 1291917SN/A base = 'SrsOp') 1301400SN/A 1312315SN/A header_output += newHeader 1321917SN/A decoder_output += newDecoder 1331917SN/A exec_output += newExec 1341400SN/A 1352SN/A class StoreImmInst(StoreInst): 1361400SN/A def __init__(self, *args, **kargs): 1372SN/A super(StoreImmInst, self).__init__(*args, **kargs) 1381400SN/A self.offset = self.op + " imm" 1391191SN/A 1402SN/A class StoreRegInst(StoreInst): 1411129SN/A def __init__(self, *args, **kargs): 1421917SN/A super(StoreRegInst, self).__init__(*args, **kargs) 1432SN/A self.offset = self.op + " shift_rm_imm(Index, shiftAmt," + \ 1442SN/A " shiftType, CondCodes<29:>)" 1452103SN/A 1462103SN/A class StoreSingle(StoreInst): 1472680Sktlim@umich.edu def __init__(self, *args, **kargs): 148180SN/A super(StoreSingle, self).__init__(*args, **kargs) 1491492SN/A 1501492SN/A # Build the default class name 1511752SN/A self.Name = self.nameFunc(self.post, self.add, self.writeback, 152180SN/A self.size, self.sign, self.user) 153180SN/A 154180SN/A # Add memory request flags where necessary 155180SN/A self.memFlags.append("%d" % (self.size - 1)) 156180SN/A if self.user: 157124SN/A self.memFlags.append("ArmISA::TLB::UserMode") 158124SN/A 159124SN/A if self.flavor == "exclusive": 160124SN/A self.memFlags.append("Request::LLSC") 1612SN/A elif self.flavor != "fp": 1622SN/A self.memFlags.append("ArmISA::TLB::AllowUnaligned") 163124SN/A 164124SN/A # Disambiguate the class name for different flavors of stores 165124SN/A if self.flavor != "normal": 166124SN/A self.Name = "%s_%s" % (self.name.upper(), self.Name) 167124SN/A 168503SN/A def emit(self): 1692SN/A # Address computation 170124SN/A eaCode = "EA = Base" 171124SN/A if not self.post: 172124SN/A eaCode += self.offset 173124SN/A eaCode += ";" 174124SN/A 175124SN/A if self.flavor == "fp": 176124SN/A eaCode += vfpEnabledCheckCode 1772SN/A 178921SN/A self.codeBlobs["ea_code"] = eaCode 1792378SN/A 180921SN/A # Code that actually handles the access 181921SN/A if self.flavor == "fp": 182921SN/A accCode = 'Mem%(suffix)s = cSwap(FpDest.uw, ((CPSR)Cpsr).e);' 183921SN/A else: 184921SN/A accCode = \ 185921SN/A 'Mem%(suffix)s = cSwap(Dest%(suffix)s, ((CPSR)Cpsr).e);' 186921SN/A accCode = accCode % \ 187921SN/A { "suffix" : buildMemSuffix(self.sign, self.size) } 188921SN/A 189921SN/A if self.writeback: 190921SN/A accCode += "Base = Base %s;\n" % self.offset 191921SN/A 192921SN/A self.codeBlobs["memacc_code"] = accCode 1932SN/A 1942SN/A # Push it out to the output files 195124SN/A base = buildMemBase(self.basePrefix, self.post, self.writeback) 196124SN/A self.emitHelper(base) 197124SN/A 198124SN/A def storeImmClassName(post, add, writeback, size=4, sign=False, user=False): 1992SN/A return memClassName("STORE_IMM", post, add, writeback, size, sign, user) 2002SN/A 201707SN/A class StoreImmEx(StoreImmInst, StoreSingle): 202707SN/A execBase = 'StoreEx' 2031191SN/A decConstBase = 'StoreExImm' 2041191SN/A basePrefix = 'MemoryExImm' 2051191SN/A nameFunc = staticmethod(storeImmClassName) 2061191SN/A 2071191SN/A def __init__(self, *args, **kargs): 2081191SN/A super(StoreImmEx, self).__init__(*args, **kargs) 2091191SN/A self.codeBlobs["postacc_code"] = "Result = !writeResult;" 2101191SN/A 2111191SN/A class StoreImm(StoreImmInst, StoreSingle): 2121191SN/A decConstBase = 'LoadStoreImm' 2131191SN/A basePrefix = 'MemoryImm' 2141191SN/A nameFunc = staticmethod(storeImmClassName) 2151191SN/A 2161191SN/A def storeRegClassName(post, add, writeback, size=4, sign=False, user=False): 2171191SN/A return memClassName("STORE_REG", post, add, writeback, size, sign, user) 2181191SN/A 2191191SN/A class StoreReg(StoreRegInst, StoreSingle): 2202SN/A decConstBase = 'LoadStoreReg' 2212SN/A basePrefix = 'MemoryReg' 2222SN/A nameFunc = staticmethod(storeRegClassName) 2232SN/A 2242SN/A class StoreDouble(StoreInst): 225707SN/A def __init__(self, *args, **kargs): 226707SN/A super(StoreDouble, self).__init__(*args, **kargs) 227707SN/A 228707SN/A # Build the default class name 229707SN/A self.Name = self.nameFunc(self.post, self.add, self.writeback) 230707SN/A 231707SN/A # Add memory request flags where necessary 232707SN/A if self.flavor == "exclusive": 233707SN/A self.memFlags.append("Request::LLSC") 234707SN/A self.memFlags.append("ArmISA::TLB::AlignDoubleWord") 235707SN/A else: 236707SN/A self.memFlags.append("ArmISA::TLB::AlignWord") 237707SN/A 238729SN/A # Disambiguate the class name for different flavors of stores 2392SN/A if self.flavor != "normal": 2402SN/A self.Name = "%s_%s" % (self.name.upper(), self.Name) 2411717SN/A 242 def emit(self): 243 # Address computation code 244 eaCode = "EA = Base" 245 if not self.post: 246 eaCode += self.offset 247 eaCode += ";" 248 249 if self.flavor == "fp": 250 eaCode += vfpEnabledCheckCode 251 252 self.codeBlobs["ea_code"] = eaCode 253 254 # Code that actually handles the access 255 if self.flavor == "fp": 256 accCode = ''' 257 uint64_t swappedMem = (uint64_t)FpDest.uw | 258 ((uint64_t)FpDest2.uw << 32); 259 Mem.ud = cSwap(swappedMem, ((CPSR)Cpsr).e); 260 ''' 261 else: 262 accCode = ''' 263 CPSR cpsr = Cpsr; 264 Mem.ud = (uint64_t)cSwap(Dest.uw, cpsr.e) | 265 ((uint64_t)cSwap(Dest2.uw, cpsr.e) << 32); 266 ''' 267 268 if self.writeback: 269 accCode += "Base = Base %s;\n" % self.offset 270 271 self.codeBlobs["memacc_code"] = accCode 272 273 # Push it out to the output files 274 base = buildMemBase(self.basePrefix, self.post, self.writeback) 275 self.emitHelper(base) 276 277 def storeDoubleImmClassName(post, add, writeback): 278 return memClassName("STORE_IMMD", post, add, writeback, 4, False, False) 279 280 class StoreDoubleImmEx(StoreImmInst, StoreDouble): 281 execBase = 'StoreEx' 282 decConstBase = 'StoreExDImm' 283 basePrefix = 'MemoryExDImm' 284 nameFunc = staticmethod(storeDoubleImmClassName) 285 286 def __init__(self, *args, **kargs): 287 super(StoreDoubleImmEx, self).__init__(*args, **kargs) 288 self.codeBlobs["postacc_code"] = "Result = !writeResult;" 289 290 class StoreDoubleImm(StoreImmInst, StoreDouble): 291 decConstBase = 'LoadStoreDImm' 292 basePrefix = 'MemoryDImm' 293 nameFunc = staticmethod(storeDoubleImmClassName) 294 295 def storeDoubleRegClassName(post, add, writeback): 296 return memClassName("STORE_REGD", post, add, writeback, 4, False, False) 297 298 class StoreDoubleReg(StoreRegInst, StoreDouble): 299 decConstBase = 'LoadStoreDReg' 300 basePrefix = 'MemoryDReg' 301 nameFunc = staticmethod(storeDoubleRegClassName) 302 303 def buildStores(mnem, size=4, sign=False, user=False): 304 StoreImm(mnem, True, True, True, size, sign, user).emit() 305 StoreReg(mnem, True, True, True, size, sign, user).emit() 306 StoreImm(mnem, True, False, True, size, sign, user).emit() 307 StoreReg(mnem, True, False, True, size, sign, user).emit() 308 StoreImm(mnem, False, True, True, size, sign, user).emit() 309 StoreReg(mnem, False, True, True, size, sign, user).emit() 310 StoreImm(mnem, False, False, True, size, sign, user).emit() 311 StoreReg(mnem, False, False, True, size, sign, user).emit() 312 StoreImm(mnem, False, True, False, size, sign, user).emit() 313 StoreReg(mnem, False, True, False, size, sign, user).emit() 314 StoreImm(mnem, False, False, False, size, sign, user).emit() 315 StoreReg(mnem, False, False, False, size, sign, user).emit() 316 317 def buildDoubleStores(mnem): 318 StoreDoubleImm(mnem, True, True, True).emit() 319 StoreDoubleReg(mnem, True, True, True).emit() 320 StoreDoubleImm(mnem, True, False, True).emit() 321 StoreDoubleReg(mnem, True, False, True).emit() 322 StoreDoubleImm(mnem, False, True, True).emit() 323 StoreDoubleReg(mnem, False, True, True).emit() 324 StoreDoubleImm(mnem, False, False, True).emit() 325 StoreDoubleReg(mnem, False, False, True).emit() 326 StoreDoubleImm(mnem, False, True, False).emit() 327 StoreDoubleReg(mnem, False, True, False).emit() 328 StoreDoubleImm(mnem, False, False, False).emit() 329 StoreDoubleReg(mnem, False, False, False).emit() 330 331 def buildSrsStores(mnem): 332 SrsInst(mnem, True, True, True).emit() 333 SrsInst(mnem, True, True, False).emit() 334 SrsInst(mnem, True, False, True).emit() 335 SrsInst(mnem, True, False, False).emit() 336 SrsInst(mnem, False, True, True).emit() 337 SrsInst(mnem, False, True, False).emit() 338 SrsInst(mnem, False, False, True).emit() 339 SrsInst(mnem, False, False, False).emit() 340 341 buildStores("str") 342 buildStores("strt", user=True) 343 buildStores("strb", size=1) 344 buildStores("strbt", size=1, user=True) 345 buildStores("strh", size=2) 346 buildStores("strht", size=2, user=True) 347 348 buildSrsStores("srs") 349 350 buildDoubleStores("strd") 351 352 StoreImmEx("strex", False, True, False, size=4, flavor="exclusive").emit() 353 StoreImmEx("strexh", False, True, False, size=2, flavor="exclusive").emit() 354 StoreImmEx("strexb", False, True, False, size=1, flavor="exclusive").emit() 355 StoreDoubleImmEx("strexd", False, True, False, flavor="exclusive").emit() 356 357 StoreImm("vstr", False, True, False, size=4, flavor="fp").emit() 358 StoreImm("vstr", False, False, False, size=4, flavor="fp").emit() 359 StoreDoubleImm("vstr", False, True, False, flavor="fp").emit() 360 StoreDoubleImm("vstr", False, False, False, flavor="fp").emit() 361}}; 362