str.isa revision 12788:fe6d6ae79d7c
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 instFlags = []): 53 super(StoreInst, self).__init__() 54 55 self.name = mnem 56 self.post = post 57 self.add = add 58 self.writeback = writeback 59 self.size = size 60 self.sign = sign 61 self.user = user 62 self.flavor = flavor 63 self.instFlags = instFlags 64 if self.add: 65 self.op = " +" 66 else: 67 self.op = " -" 68 69 self.memFlags = ["ArmISA::TLB::MustBeOne"] 70 self.codeBlobs = { "postacc_code" : "" } 71 72 def emitHelper(self, base = 'Memory', wbDecl = None): 73 74 global header_output, decoder_output, exec_output 75 76 codeBlobs = self.codeBlobs 77 codeBlobs["predicate_test"] = pickPredicate(codeBlobs) 78 (newHeader, 79 newDecoder, 80 newExec) = self.fillTemplates(self.name, self.Name, codeBlobs, 81 self.memFlags, self.instFlags, 82 base, wbDecl, None, False, 83 self.size, self.sign) 84 85 header_output += newHeader 86 decoder_output += newDecoder 87 exec_output += newExec 88 89 class SrsInst(LoadStoreInst): 90 execBase = 'Store' 91 decConstBase = 'Srs' 92 93 def __init__(self, mnem, post, add, writeback): 94 super(SrsInst, self).__init__() 95 self.name = mnem 96 self.post = post 97 self.add = add 98 self.writeback = writeback 99 100 self.Name = "SRS_" + storeImmClassName(post, add, writeback, 8) 101 102 def emit(self): 103 offset = 0 104 if self.post != self.add: 105 offset += 4 106 if not self.add: 107 offset -= 8 108 109 eaCode = "EA = SpMode + %d;" % offset 110 111 wbDiff = -8 112 if self.add: 113 wbDiff = 8 114 accCode = ''' 115 116 auto tc = xc->tcBase(); 117 if (badMode32(tc, static_cast<OperatingMode>(regMode))) { 118 return undefinedFault32(tc, opModeToEL(currOpMode(tc))); 119 } 120 121 CPSR cpsr = Cpsr; 122 Mem_ud = (uint64_t)cSwap(LR_uw, cpsr.e) | 123 ((uint64_t)cSwap(Spsr_uw, cpsr.e) << 32); 124 ''' 125 126 global header_output, decoder_output, exec_output 127 128 codeBlobs = { "ea_code": eaCode, 129 "memacc_code": accCode, 130 "postacc_code": "" } 131 codeBlobs["predicate_test"] = pickPredicate(codeBlobs) 132 133 wbDecl = None 134 if self.writeback: 135 wbDecl = '''MicroAddiUop(machInst, 136 intRegInMode((OperatingMode)regMode, INTREG_SP), 137 intRegInMode((OperatingMode)regMode, INTREG_SP), 138 %d);''' % wbDiff 139 140 (newHeader, 141 newDecoder, 142 newExec) = self.fillTemplates(self.name, self.Name, codeBlobs, 143 ["ArmISA::TLB::AlignWord", "ArmISA::TLB::MustBeOne"], [], 144 'SrsOp', wbDecl) 145 146 header_output += newHeader 147 decoder_output += newDecoder 148 exec_output += newExec 149 150 class StoreImmInst(StoreInst): 151 def __init__(self, *args, **kargs): 152 super(StoreImmInst, self).__init__(*args, **kargs) 153 self.offset = self.op + " imm" 154 155 if self.add: 156 self.wbDecl = "MicroAddiUop(machInst, base, base, imm);" 157 else: 158 self.wbDecl = "MicroSubiUop(machInst, base, base, imm);" 159 160 class StoreRegInst(StoreInst): 161 def __init__(self, *args, **kargs): 162 super(StoreRegInst, self).__init__(*args, **kargs) 163 self.offset = self.op + " shift_rm_imm(Index, shiftAmt," + \ 164 " shiftType, OptShiftRmCondCodesC)" 165 if self.add: 166 self.wbDecl = ''' 167 MicroAddUop(machInst, base, base, index, shiftAmt, shiftType); 168 ''' 169 else: 170 self.wbDecl = ''' 171 MicroSubUop(machInst, base, base, index, shiftAmt, shiftType); 172 ''' 173 174 class StoreSingle(StoreInst): 175 def __init__(self, *args, **kargs): 176 super(StoreSingle, self).__init__(*args, **kargs) 177 178 # Build the default class name 179 self.Name = self.nameFunc(self.post, self.add, self.writeback, 180 self.size, self.sign, self.user) 181 182 # Add memory request flags where necessary 183 self.memFlags.append("%d" % int(math.log(self.size, 2))) 184 if self.user: 185 self.memFlags.append("ArmISA::TLB::UserMode") 186 187 if self.flavor == "exclusive": 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.memFlags.append("Request::LLSC") 263 self.memFlags.append("ArmISA::TLB::AlignDoubleWord") 264 else: 265 self.memFlags.append("ArmISA::TLB::AlignWord") 266 267 # Disambiguate the class name for different flavors of stores 268 if self.flavor != "normal": 269 self.Name = "%s_%s" % (self.name.upper(), self.Name) 270 271 def emit(self): 272 # Address computation code 273 eaCode = "EA = Base" 274 if not self.post: 275 eaCode += self.offset 276 eaCode += ";" 277 278 if self.flavor == "fp": 279 eaCode += vfpEnabledCheckCode 280 281 self.codeBlobs["ea_code"] = eaCode 282 283 # Code that actually handles the access 284 if self.flavor == "fp": 285 accCode = ''' 286 uint64_t swappedMem = (uint64_t)FpDest_uw | 287 ((uint64_t)FpDest2_uw << 32); 288 Mem_ud = cSwap(swappedMem, ((CPSR)Cpsr).e); 289 ''' 290 else: 291 accCode = ''' 292 CPSR cpsr = Cpsr; 293 Mem_ud = (uint64_t)cSwap(Dest_uw, cpsr.e) | 294 ((uint64_t)cSwap(Dest2_uw, cpsr.e) << 32); 295 ''' 296 297 self.codeBlobs["memacc_code"] = accCode 298 299 # Push it out to the output files 300 base = buildMemBase(self.basePrefix, self.post, self.writeback) 301 wbDecl = None 302 if self.writeback: 303 wbDecl = self.wbDecl 304 self.emitHelper(base, wbDecl) 305 306 def storeDoubleImmClassName(post, add, writeback): 307 return memClassName("STORE_IMMD", post, add, writeback, 4, False, False) 308 309 class StoreDoubleImmEx(StoreImmInst, StoreDouble): 310 execBase = 'StoreEx' 311 decConstBase = 'StoreExDImm' 312 basePrefix = 'MemoryExDImm' 313 nameFunc = staticmethod(storeDoubleImmClassName) 314 315 def __init__(self, *args, **kargs): 316 super(StoreDoubleImmEx, self).__init__(*args, **kargs) 317 self.codeBlobs["postacc_code"] = \ 318 "Result = !writeResult; SevMailbox = 1; LLSCLock = 0;" 319 320 class StoreDoubleImm(StoreImmInst, StoreDouble): 321 decConstBase = 'LoadStoreDImm' 322 basePrefix = 'MemoryDImm' 323 nameFunc = staticmethod(storeDoubleImmClassName) 324 325 def storeDoubleRegClassName(post, add, writeback): 326 return memClassName("STORE_REGD", post, add, writeback, 4, False, False) 327 328 class StoreDoubleReg(StoreRegInst, StoreDouble): 329 decConstBase = 'StoreDReg' 330 basePrefix = 'MemoryDReg' 331 nameFunc = staticmethod(storeDoubleRegClassName) 332 333 def buildStores(mnem, size=4, sign=False, user=False): 334 StoreImm(mnem, True, True, True, size, sign, user).emit() 335 StoreReg(mnem, True, True, True, size, sign, user).emit() 336 StoreImm(mnem, True, False, True, size, sign, user).emit() 337 StoreReg(mnem, True, False, True, size, sign, user).emit() 338 StoreImm(mnem, False, True, True, size, sign, user).emit() 339 StoreReg(mnem, False, True, True, size, sign, user).emit() 340 StoreImm(mnem, False, False, True, size, sign, user).emit() 341 StoreReg(mnem, False, False, True, size, sign, user).emit() 342 StoreImm(mnem, False, True, False, size, sign, user).emit() 343 StoreReg(mnem, False, True, False, size, sign, user).emit() 344 StoreImm(mnem, False, False, False, size, sign, user).emit() 345 StoreReg(mnem, False, False, False, size, sign, user).emit() 346 347 def buildDoubleStores(mnem): 348 StoreDoubleImm(mnem, True, True, True).emit() 349 StoreDoubleReg(mnem, True, True, True).emit() 350 StoreDoubleImm(mnem, True, False, True).emit() 351 StoreDoubleReg(mnem, True, False, True).emit() 352 StoreDoubleImm(mnem, False, True, True).emit() 353 StoreDoubleReg(mnem, False, True, True).emit() 354 StoreDoubleImm(mnem, False, False, True).emit() 355 StoreDoubleReg(mnem, False, False, True).emit() 356 StoreDoubleImm(mnem, False, True, False).emit() 357 StoreDoubleReg(mnem, False, True, False).emit() 358 StoreDoubleImm(mnem, False, False, False).emit() 359 StoreDoubleReg(mnem, False, False, False).emit() 360 361 def buildSrsStores(mnem): 362 SrsInst(mnem, True, True, True).emit() 363 SrsInst(mnem, True, True, False).emit() 364 SrsInst(mnem, True, False, True).emit() 365 SrsInst(mnem, True, False, False).emit() 366 SrsInst(mnem, False, True, True).emit() 367 SrsInst(mnem, False, True, False).emit() 368 SrsInst(mnem, False, False, True).emit() 369 SrsInst(mnem, False, False, False).emit() 370 371 buildStores("str") 372 buildStores("strt", user=True) 373 buildStores("strb", size=1) 374 buildStores("strbt", size=1, user=True) 375 buildStores("strh", size=2) 376 buildStores("strht", size=2, user=True) 377 378 buildSrsStores("srs") 379 380 buildDoubleStores("strd") 381 382 StoreImmEx("strex", False, True, False, size=4, flavor="exclusive", 383 instFlags = ['IsStoreConditional']).emit() 384 StoreImmEx("strexh", False, True, False, size=2, flavor="exclusive", 385 instFlags = ['IsStoreConditional']).emit() 386 StoreImmEx("strexb", False, True, False, size=1, flavor="exclusive", 387 instFlags = ['IsStoreConditional']).emit() 388 StoreDoubleImmEx("strexd", False, True, False, flavor="exclusive", 389 instFlags = ['IsStoreConditional']).emit() 390 391 StoreImm("vstr", False, True, False, size=4, flavor="fp").emit() 392 StoreImm("vstr", False, False, False, size=4, flavor="fp").emit() 393 StoreDoubleImm("vstr", False, True, False, flavor="fp").emit() 394 StoreDoubleImm("vstr", False, False, False, flavor="fp").emit() 395}}; 396