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