str.isa revision 13588:fb25d9448acc
1// -*- mode:c++ -*- 2 3// Copyright (c) 2010-2011,2017 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 import math 42 43 header_output = "" 44 decoder_output = "" 45 exec_output = "" 46 47 class StoreInst(LoadStoreInst): 48 execBase = 'Store' 49 50 def __init__(self, mnem, post, add, writeback, size=4, 51 sign=False, user=False, flavor="normal"): 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 = [] 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, 81 base, wbDecl, None, False, 82 self.size, self.sign) 83 84 header_output += newHeader 85 decoder_output += newDecoder 86 exec_output += newExec 87 88 class SrsInst(LoadStoreInst): 89 execBase = 'Store' 90 decConstBase = 'Srs' 91 92 def __init__(self, mnem, post, add, writeback): 93 super(SrsInst, self).__init__() 94 self.name = mnem 95 self.post = post 96 self.add = add 97 self.writeback = writeback 98 99 self.Name = "SRS_" + storeImmClassName(post, add, writeback, 8) 100 101 def emit(self): 102 offset = 0 103 if self.post != self.add: 104 offset += 4 105 if not self.add: 106 offset -= 8 107 108 eaCode = "EA = SpMode + %d;" % offset 109 110 wbDiff = -8 111 if self.add: 112 wbDiff = 8 113 accCode = ''' 114 115 auto tc = xc->tcBase(); 116 if (badMode32(tc, static_cast<OperatingMode>(regMode))) { 117 return undefinedFault32(tc, opModeToEL(currOpMode(tc))); 118 } 119 120 CPSR cpsr = Cpsr; 121 Mem_ud = (uint64_t)cSwap(LR_uw, cpsr.e) | 122 ((uint64_t)cSwap(Spsr_uw, cpsr.e) << 32); 123 ''' 124 125 global header_output, decoder_output, exec_output 126 127 codeBlobs = { "ea_code": eaCode, 128 "memacc_code": accCode, 129 "postacc_code": "" } 130 codeBlobs["predicate_test"] = pickPredicate(codeBlobs) 131 132 wbDecl = None 133 if self.writeback: 134 wbDecl = '''MicroAddiUop(machInst, 135 intRegInMode((OperatingMode)regMode, INTREG_SP), 136 intRegInMode((OperatingMode)regMode, INTREG_SP), 137 %d);''' % wbDiff 138 139 (newHeader, 140 newDecoder, 141 newExec) = self.fillTemplates(self.name, self.Name, codeBlobs, 142 ["ArmISA::TLB::AlignWord", "ArmISA::TLB::MustBeOne"], [], 143 'SrsOp', wbDecl) 144 145 header_output += newHeader 146 decoder_output += newDecoder 147 exec_output += newExec 148 149 class StoreImmInst(StoreInst): 150 def __init__(self, *args, **kargs): 151 super(StoreImmInst, self).__init__(*args, **kargs) 152 self.offset = self.op + " imm" 153 154 if self.add: 155 self.wbDecl = "MicroAddiUop(machInst, base, base, imm);" 156 else: 157 self.wbDecl = "MicroSubiUop(machInst, base, base, imm);" 158 159 class StoreRegInst(StoreInst): 160 def __init__(self, *args, **kargs): 161 super(StoreRegInst, self).__init__(*args, **kargs) 162 self.offset = self.op + " shift_rm_imm(Index, shiftAmt," + \ 163 " shiftType, OptShiftRmCondCodesC)" 164 if self.add: 165 self.wbDecl = ''' 166 MicroAddUop(machInst, base, base, index, shiftAmt, shiftType); 167 ''' 168 else: 169 self.wbDecl = ''' 170 MicroSubUop(machInst, base, base, index, shiftAmt, shiftType); 171 ''' 172 173 class StoreSingle(StoreInst): 174 def __init__(self, *args, **kargs): 175 super(StoreSingle, self).__init__(*args, **kargs) 176 177 # Build the default class name 178 self.Name = self.nameFunc(self.post, self.add, self.writeback, 179 self.size, self.sign, self.user) 180 181 # Add memory request flags where necessary 182 self.memFlags.append("%d" % int(math.log(self.size, 2))) 183 if self.user: 184 self.memFlags.append("ArmISA::TLB::UserMode") 185 186 if self.flavor == "exclusive": 187 self.instFlags.append("IsStoreConditional") 188 self.memFlags.append("Request::LLSC") 189 elif self.flavor != "fp": 190 self.memFlags.append("ArmISA::TLB::AllowUnaligned") 191 192 # Disambiguate the class name for different flavors of stores 193 if self.flavor != "normal": 194 self.Name = "%s_%s" % (self.name.upper(), self.Name) 195 196 def emit(self): 197 # Address computation 198 eaCode = "EA = Base" 199 if not self.post: 200 eaCode += self.offset 201 eaCode += ";" 202 203 if self.flavor == "fp": 204 eaCode += vfpEnabledCheckCode 205 206 self.codeBlobs["ea_code"] = eaCode 207 208 # Code that actually handles the access 209 if self.flavor == "fp": 210 accCode = 'Mem%(suffix)s = cSwap(FpDest_uw, ((CPSR)Cpsr).e);' 211 else: 212 accCode = \ 213 'Mem%(suffix)s = cSwap(Dest%(suffix)s, ((CPSR)Cpsr).e);' 214 accCode = accCode % \ 215 { "suffix" : buildMemSuffix(self.sign, self.size) } 216 217 self.codeBlobs["memacc_code"] = accCode 218 219 # Push it out to the output files 220 base = buildMemBase(self.basePrefix, self.post, self.writeback) 221 wbDecl = None 222 if self.writeback: 223 wbDecl = self.wbDecl 224 self.emitHelper(base, wbDecl) 225 226 def storeImmClassName(post, add, writeback, size=4, sign=False, user=False): 227 return memClassName("STORE_IMM", post, add, writeback, size, sign, user) 228 229 class StoreImmEx(StoreImmInst, StoreSingle): 230 execBase = 'StoreEx' 231 decConstBase = 'StoreExImm' 232 basePrefix = 'MemoryExImm' 233 nameFunc = staticmethod(storeImmClassName) 234 235 def __init__(self, *args, **kargs): 236 super(StoreImmEx, self).__init__(*args, **kargs) 237 self.codeBlobs["postacc_code"] = \ 238 "Result = !writeResult; SevMailbox = 1; LLSCLock = 0;" 239 240 class StoreImm(StoreImmInst, StoreSingle): 241 decConstBase = 'LoadStoreImm' 242 basePrefix = 'MemoryImm' 243 nameFunc = staticmethod(storeImmClassName) 244 245 def storeRegClassName(post, add, writeback, size=4, sign=False, user=False): 246 return memClassName("STORE_REG", post, add, writeback, size, sign, user) 247 248 class StoreReg(StoreRegInst, StoreSingle): 249 decConstBase = 'StoreReg' 250 basePrefix = 'MemoryReg' 251 nameFunc = staticmethod(storeRegClassName) 252 253 class StoreDouble(StoreInst): 254 def __init__(self, *args, **kargs): 255 super(StoreDouble, self).__init__(*args, **kargs) 256 257 # Build the default class name 258 self.Name = self.nameFunc(self.post, self.add, self.writeback) 259 260 # Add memory request flags where necessary 261 if self.flavor == "exclusive": 262 self.instFlags.append("IsStoreConditional") 263 self.memFlags.append("Request::LLSC") 264 self.memFlags.append("ArmISA::TLB::AlignDoubleWord") 265 else: 266 self.memFlags.append("ArmISA::TLB::AlignWord") 267 268 # Disambiguate the class name for different flavors of stores 269 if self.flavor != "normal": 270 self.Name = "%s_%s" % (self.name.upper(), self.Name) 271 272 def emit(self): 273 # Address computation code 274 eaCode = "EA = Base" 275 if not self.post: 276 eaCode += self.offset 277 eaCode += ";" 278 279 if self.flavor == "fp": 280 eaCode += vfpEnabledCheckCode 281 282 self.codeBlobs["ea_code"] = eaCode 283 284 # Code that actually handles the access 285 if self.flavor == "fp": 286 accCode = ''' 287 uint64_t swappedMem = (uint64_t)FpDest_uw | 288 ((uint64_t)FpDest2_uw << 32); 289 Mem_ud = cSwap(swappedMem, ((CPSR)Cpsr).e); 290 ''' 291 else: 292 accCode = ''' 293 CPSR cpsr = Cpsr; 294 Mem_ud = (uint64_t)cSwap(Dest_uw, cpsr.e) | 295 ((uint64_t)cSwap(Dest2_uw, cpsr.e) << 32); 296 ''' 297 298 self.codeBlobs["memacc_code"] = accCode 299 300 # Push it out to the output files 301 base = buildMemBase(self.basePrefix, self.post, self.writeback) 302 wbDecl = None 303 if self.writeback: 304 wbDecl = self.wbDecl 305 self.emitHelper(base, wbDecl) 306 307 def storeDoubleImmClassName(post, add, writeback): 308 return memClassName("STORE_IMMD", post, add, writeback, 4, False, False) 309 310 class StoreDoubleImmEx(StoreImmInst, StoreDouble): 311 execBase = 'StoreEx' 312 decConstBase = 'StoreExDImm' 313 basePrefix = 'MemoryExDImm' 314 nameFunc = staticmethod(storeDoubleImmClassName) 315 316 def __init__(self, *args, **kargs): 317 super(StoreDoubleImmEx, self).__init__(*args, **kargs) 318 self.codeBlobs["postacc_code"] = \ 319 "Result = !writeResult; SevMailbox = 1; LLSCLock = 0;" 320 321 class StoreDoubleImm(StoreImmInst, StoreDouble): 322 decConstBase = 'LoadStoreDImm' 323 basePrefix = 'MemoryDImm' 324 nameFunc = staticmethod(storeDoubleImmClassName) 325 326 def storeDoubleRegClassName(post, add, writeback): 327 return memClassName("STORE_REGD", post, add, writeback, 4, False, False) 328 329 class StoreDoubleReg(StoreRegInst, StoreDouble): 330 decConstBase = 'StoreDReg' 331 basePrefix = 'MemoryDReg' 332 nameFunc = staticmethod(storeDoubleRegClassName) 333 334 def buildStores(mnem, size=4, sign=False, user=False): 335 StoreImm(mnem, True, True, True, size, sign, user).emit() 336 StoreReg(mnem, True, True, True, size, sign, user).emit() 337 StoreImm(mnem, True, False, True, size, sign, user).emit() 338 StoreReg(mnem, True, False, True, size, sign, user).emit() 339 StoreImm(mnem, False, True, True, size, sign, user).emit() 340 StoreReg(mnem, False, True, True, size, sign, user).emit() 341 StoreImm(mnem, False, False, True, size, sign, user).emit() 342 StoreReg(mnem, False, False, True, size, sign, user).emit() 343 StoreImm(mnem, False, True, False, size, sign, user).emit() 344 StoreReg(mnem, False, True, False, size, sign, user).emit() 345 StoreImm(mnem, False, False, False, size, sign, user).emit() 346 StoreReg(mnem, False, False, False, size, sign, user).emit() 347 348 def buildDoubleStores(mnem): 349 StoreDoubleImm(mnem, True, True, True).emit() 350 StoreDoubleReg(mnem, True, True, True).emit() 351 StoreDoubleImm(mnem, True, False, True).emit() 352 StoreDoubleReg(mnem, True, False, True).emit() 353 StoreDoubleImm(mnem, False, True, True).emit() 354 StoreDoubleReg(mnem, False, True, True).emit() 355 StoreDoubleImm(mnem, False, False, True).emit() 356 StoreDoubleReg(mnem, False, False, True).emit() 357 StoreDoubleImm(mnem, False, True, False).emit() 358 StoreDoubleReg(mnem, False, True, False).emit() 359 StoreDoubleImm(mnem, False, False, False).emit() 360 StoreDoubleReg(mnem, False, False, False).emit() 361 362 def buildSrsStores(mnem): 363 SrsInst(mnem, True, True, True).emit() 364 SrsInst(mnem, True, True, False).emit() 365 SrsInst(mnem, True, False, True).emit() 366 SrsInst(mnem, True, False, False).emit() 367 SrsInst(mnem, False, True, True).emit() 368 SrsInst(mnem, False, True, False).emit() 369 SrsInst(mnem, False, False, True).emit() 370 SrsInst(mnem, False, False, False).emit() 371 372 buildStores("str") 373 buildStores("strt", user=True) 374 buildStores("strb", size=1) 375 buildStores("strbt", size=1, user=True) 376 buildStores("strh", size=2) 377 buildStores("strht", size=2, user=True) 378 379 buildSrsStores("srs") 380 381 buildDoubleStores("strd") 382 383 StoreImmEx("strex", False, True, False, size=4, 384 flavor="exclusive").emit() 385 StoreImmEx("strexh", False, True, False, size=2, 386 flavor="exclusive").emit() 387 StoreImmEx("strexb", False, True, False, size=1, 388 flavor="exclusive").emit() 389 StoreDoubleImmEx("strexd", False, True, False, 390 flavor="exclusive").emit() 391 392 StoreImm("vstr", False, True, False, size=4, flavor="fp").emit() 393 StoreImm("vstr", False, False, False, size=4, flavor="fp").emit() 394 StoreDoubleImm("vstr", False, True, False, flavor="fp").emit() 395 StoreDoubleImm("vstr", False, False, False, flavor="fp").emit() 396}}; 397