str.isa revision 8069
1// -*- mode:c++ -*- 2 3// Copyright (c) 2010 ARM Limited 4// All rights reserved 5// 6// The license below extends only to copyright in the software and shall 7// not be construed as granting a license to any other intellectual 8// property including but not limited to intellectual property relating 9// to a hardware implementation of the functionality of the software 10// licensed hereunder. You may use the software subject to the license 11// terms below provided that you ensure that this notice is replicated 12// unmodified and in its entirety in all distributions of the software, 13// modified or unmodified, in source code or in binary form. 14// 15// Redistribution and use in source and binary forms, with or without 16// modification, are permitted provided that the following conditions are 17// met: redistributions of source code must retain the above copyright 18// notice, this list of conditions and the following disclaimer; 19// redistributions in binary form must reproduce the above copyright 20// notice, this list of conditions and the following disclaimer in the 21// documentation and/or other materials provided with the distribution; 22// neither the name of the copyright holders nor the names of its 23// contributors may be used to endorse or promote products derived from 24// this software without specific prior written permission. 25// 26// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 27// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 28// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 29// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 30// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 31// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 32// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 33// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 34// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 35// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 36// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 37// 38// Authors: Gabe Black 39 40let {{ 41 42 header_output = "" 43 decoder_output = "" 44 exec_output = "" 45 46 class StoreInst(LoadStoreInst): 47 execBase = 'Store' 48 49 def __init__(self, mnem, post, add, writeback, size=4, 50 sign=False, user=False, flavor="normal", 51 instFlags = []): 52 super(StoreInst, self).__init__() 53 54 self.name = mnem 55 self.post = post 56 self.add = add 57 self.writeback = writeback 58 self.size = size 59 self.sign = sign 60 self.user = user 61 self.flavor = flavor 62 self.instFlags = instFlags 63 if self.add: 64 self.op = " +" 65 else: 66 self.op = " -" 67 68 self.memFlags = ["ArmISA::TLB::MustBeOne"] 69 self.codeBlobs = { "postacc_code" : "" } 70 71 def emitHelper(self, base = 'Memory', wbDecl = None): 72 73 global header_output, decoder_output, exec_output 74 75 codeBlobs = self.codeBlobs 76 codeBlobs["predicate_test"] = pickPredicate(codeBlobs) 77 (newHeader, 78 newDecoder, 79 newExec) = self.fillTemplates(self.name, self.Name, codeBlobs, 80 self.memFlags, self.instFlags, base, wbDecl) 81 82 header_output += newHeader 83 decoder_output += newDecoder 84 exec_output += newExec 85 86 class SrsInst(LoadStoreInst): 87 execBase = 'Store' 88 decConstBase = 'Srs' 89 90 def __init__(self, mnem, post, add, writeback): 91 super(SrsInst, self).__init__() 92 self.name = mnem 93 self.post = post 94 self.add = add 95 self.writeback = writeback 96 97 self.Name = "SRS_" + storeImmClassName(post, add, writeback, 8) 98 99 def emit(self): 100 offset = 0 101 if self.post != self.add: 102 offset += 4 103 if not self.add: 104 offset -= 8 105 106 eaCode = "EA = SpMode + %d;" % offset 107 108 wbDiff = -8 109 if self.add: 110 wbDiff = 8 111 accCode = ''' 112 CPSR cpsr = Cpsr; 113 Mem.ud = (uint64_t)cSwap(LR.uw, cpsr.e) | 114 ((uint64_t)cSwap(Spsr.uw, cpsr.e) << 32); 115 ''' 116 117 global header_output, decoder_output, exec_output 118 119 codeBlobs = { "ea_code": eaCode, 120 "memacc_code": accCode, 121 "postacc_code": "" } 122 codeBlobs["predicate_test"] = pickPredicate(codeBlobs) 123 124 wbDecl = None 125 if self.writeback: 126 wbDecl = '''MicroAddiUop(machInst, 127 intRegInMode((OperatingMode)regMode, INTREG_SP), 128 intRegInMode((OperatingMode)regMode, INTREG_SP), 129 %d);''' % wbDiff 130 131 (newHeader, 132 newDecoder, 133 newExec) = self.fillTemplates(self.name, self.Name, codeBlobs, 134 ["ArmISA::TLB::AlignWord", "ArmISA::TLB::MustBeOne"], [], 135 'SrsOp', wbDecl) 136 137 header_output += newHeader 138 decoder_output += newDecoder 139 exec_output += newExec 140 141 class StoreImmInst(StoreInst): 142 def __init__(self, *args, **kargs): 143 super(StoreImmInst, self).__init__(*args, **kargs) 144 self.offset = self.op + " imm" 145 146 if self.add: 147 self.wbDecl = "MicroAddiUop(machInst, base, base, imm);" 148 else: 149 self.wbDecl = "MicroSubiUop(machInst, base, base, imm);" 150 151 class StoreRegInst(StoreInst): 152 def __init__(self, *args, **kargs): 153 super(StoreRegInst, self).__init__(*args, **kargs) 154 self.offset = self.op + " shift_rm_imm(Index, shiftAmt," + \ 155 " shiftType, CondCodes<29:>)" 156 if self.add: 157 self.wbDecl = ''' 158 MicroAddUop(machInst, base, base, index, shiftAmt, shiftType); 159 ''' 160 else: 161 self.wbDecl = ''' 162 MicroSubUop(machInst, base, base, index, shiftAmt, shiftType); 163 ''' 164 165 class StoreSingle(StoreInst): 166 def __init__(self, *args, **kargs): 167 super(StoreSingle, self).__init__(*args, **kargs) 168 169 # Build the default class name 170 self.Name = self.nameFunc(self.post, self.add, self.writeback, 171 self.size, self.sign, self.user) 172 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 instFlags = ['IsStoreConditional'] 226 227 def __init__(self, *args, **kargs): 228 super(StoreImmEx, self).__init__(*args, **kargs) 229 self.codeBlobs["postacc_code"] = "Result = !writeResult;" 230 231 class StoreImm(StoreImmInst, StoreSingle): 232 decConstBase = 'LoadStoreImm' 233 basePrefix = 'MemoryImm' 234 nameFunc = staticmethod(storeImmClassName) 235 236 def storeRegClassName(post, add, writeback, size=4, sign=False, user=False): 237 return memClassName("STORE_REG", post, add, writeback, size, sign, user) 238 239 class StoreReg(StoreRegInst, StoreSingle): 240 decConstBase = 'StoreReg' 241 basePrefix = 'MemoryReg' 242 nameFunc = staticmethod(storeRegClassName) 243 244 class StoreDouble(StoreInst): 245 def __init__(self, *args, **kargs): 246 super(StoreDouble, self).__init__(*args, **kargs) 247 248 # Build the default class name 249 self.Name = self.nameFunc(self.post, self.add, self.writeback) 250 251 # Add memory request flags where necessary 252 if self.flavor == "exclusive": 253 self.memFlags.append("Request::LLSC") 254 self.memFlags.append("ArmISA::TLB::AlignDoubleWord") 255 else: 256 self.memFlags.append("ArmISA::TLB::AlignWord") 257 258 # Disambiguate the class name for different flavors of stores 259 if self.flavor != "normal": 260 self.Name = "%s_%s" % (self.name.upper(), self.Name) 261 262 def emit(self): 263 # Address computation code 264 eaCode = "EA = Base" 265 if not self.post: 266 eaCode += self.offset 267 eaCode += ";" 268 269 if self.flavor == "fp": 270 eaCode += vfpEnabledCheckCode 271 272 self.codeBlobs["ea_code"] = eaCode 273 274 # Code that actually handles the access 275 if self.flavor == "fp": 276 accCode = ''' 277 uint64_t swappedMem = (uint64_t)FpDest.uw | 278 ((uint64_t)FpDest2.uw << 32); 279 Mem.ud = cSwap(swappedMem, ((CPSR)Cpsr).e); 280 ''' 281 else: 282 accCode = ''' 283 CPSR cpsr = Cpsr; 284 Mem.ud = (uint64_t)cSwap(Dest.uw, cpsr.e) | 285 ((uint64_t)cSwap(Dest2.uw, cpsr.e) << 32); 286 ''' 287 288 self.codeBlobs["memacc_code"] = accCode 289 290 # Push it out to the output files 291 base = buildMemBase(self.basePrefix, self.post, self.writeback) 292 wbDecl = None 293 if self.writeback: 294 wbDecl = self.wbDecl 295 self.emitHelper(base, wbDecl) 296 297 def storeDoubleImmClassName(post, add, writeback): 298 return memClassName("STORE_IMMD", post, add, writeback, 4, False, False) 299 300 class StoreDoubleImmEx(StoreImmInst, StoreDouble): 301 execBase = 'StoreEx' 302 decConstBase = 'StoreExDImm' 303 basePrefix = 'MemoryExDImm' 304 nameFunc = staticmethod(storeDoubleImmClassName) 305 instFlags = ['IsStoreConditional'] 306 307 def __init__(self, *args, **kargs): 308 super(StoreDoubleImmEx, self).__init__(*args, **kargs) 309 self.codeBlobs["postacc_code"] = "Result = !writeResult;" 310 311 class StoreDoubleImm(StoreImmInst, StoreDouble): 312 decConstBase = 'LoadStoreDImm' 313 basePrefix = 'MemoryDImm' 314 nameFunc = staticmethod(storeDoubleImmClassName) 315 316 def storeDoubleRegClassName(post, add, writeback): 317 return memClassName("STORE_REGD", post, add, writeback, 4, False, False) 318 319 class StoreDoubleReg(StoreRegInst, StoreDouble): 320 decConstBase = 'StoreDReg' 321 basePrefix = 'MemoryDReg' 322 nameFunc = staticmethod(storeDoubleRegClassName) 323 324 def buildStores(mnem, size=4, sign=False, user=False): 325 StoreImm(mnem, True, True, True, size, sign, user).emit() 326 StoreReg(mnem, True, True, True, size, sign, user).emit() 327 StoreImm(mnem, True, False, True, size, sign, user).emit() 328 StoreReg(mnem, True, False, True, size, sign, user).emit() 329 StoreImm(mnem, False, True, True, size, sign, user).emit() 330 StoreReg(mnem, False, True, True, size, sign, user).emit() 331 StoreImm(mnem, False, False, True, size, sign, user).emit() 332 StoreReg(mnem, False, False, True, size, sign, user).emit() 333 StoreImm(mnem, False, True, False, size, sign, user).emit() 334 StoreReg(mnem, False, True, False, size, sign, user).emit() 335 StoreImm(mnem, False, False, False, size, sign, user).emit() 336 StoreReg(mnem, False, False, False, size, sign, user).emit() 337 338 def buildDoubleStores(mnem): 339 StoreDoubleImm(mnem, True, True, True).emit() 340 StoreDoubleReg(mnem, True, True, True).emit() 341 StoreDoubleImm(mnem, True, False, True).emit() 342 StoreDoubleReg(mnem, True, False, True).emit() 343 StoreDoubleImm(mnem, False, True, True).emit() 344 StoreDoubleReg(mnem, False, True, True).emit() 345 StoreDoubleImm(mnem, False, False, True).emit() 346 StoreDoubleReg(mnem, False, False, True).emit() 347 StoreDoubleImm(mnem, False, True, False).emit() 348 StoreDoubleReg(mnem, False, True, False).emit() 349 StoreDoubleImm(mnem, False, False, False).emit() 350 StoreDoubleReg(mnem, False, False, False).emit() 351 352 def buildSrsStores(mnem): 353 SrsInst(mnem, True, True, True).emit() 354 SrsInst(mnem, True, True, False).emit() 355 SrsInst(mnem, True, False, True).emit() 356 SrsInst(mnem, True, False, False).emit() 357 SrsInst(mnem, False, True, True).emit() 358 SrsInst(mnem, False, True, False).emit() 359 SrsInst(mnem, False, False, True).emit() 360 SrsInst(mnem, False, False, False).emit() 361 362 buildStores("str") 363 buildStores("strt", user=True) 364 buildStores("strb", size=1) 365 buildStores("strbt", size=1, user=True) 366 buildStores("strh", size=2) 367 buildStores("strht", size=2, user=True) 368 369 buildSrsStores("srs") 370 371 buildDoubleStores("strd") 372 373 StoreImmEx("strex", False, True, False, size=4, flavor="exclusive").emit() 374 StoreImmEx("strexh", False, True, False, size=2, flavor="exclusive").emit() 375 StoreImmEx("strexb", False, True, False, size=1, flavor="exclusive").emit() 376 StoreDoubleImmEx("strexd", False, True, False, flavor="exclusive").emit() 377 378 StoreImm("vstr", False, True, False, size=4, flavor="fp").emit() 379 StoreImm("vstr", False, False, False, size=4, flavor="fp").emit() 380 StoreDoubleImm("vstr", False, True, False, flavor="fp").emit() 381 StoreDoubleImm("vstr", False, False, False, flavor="fp").emit() 382}}; 383