str.isa revision 8588
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, OptShiftRmCondCodesC)" 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 226 def __init__(self, *args, **kargs): 227 super(StoreImmEx, self).__init__(*args, **kargs) 228 self.codeBlobs["postacc_code"] = "Result = !writeResult;" 229 230 class StoreImm(StoreImmInst, StoreSingle): 231 decConstBase = 'LoadStoreImm' 232 basePrefix = 'MemoryImm' 233 nameFunc = staticmethod(storeImmClassName) 234 235 def storeRegClassName(post, add, writeback, size=4, sign=False, user=False): 236 return memClassName("STORE_REG", post, add, writeback, size, sign, user) 237 238 class StoreReg(StoreRegInst, StoreSingle): 239 decConstBase = 'StoreReg' 240 basePrefix = 'MemoryReg' 241 nameFunc = staticmethod(storeRegClassName) 242 243 class StoreDouble(StoreInst): 244 def __init__(self, *args, **kargs): 245 super(StoreDouble, self).__init__(*args, **kargs) 246 247 # Build the default class name 248 self.Name = self.nameFunc(self.post, self.add, self.writeback) 249 250 # Add memory request flags where necessary 251 if self.flavor == "exclusive": 252 self.memFlags.append("Request::LLSC") 253 self.memFlags.append("ArmISA::TLB::AlignDoubleWord") 254 else: 255 self.memFlags.append("ArmISA::TLB::AlignWord") 256 257 # Disambiguate the class name for different flavors of stores 258 if self.flavor != "normal": 259 self.Name = "%s_%s" % (self.name.upper(), self.Name) 260 261 def emit(self): 262 # Address computation code 263 eaCode = "EA = Base" 264 if not self.post: 265 eaCode += self.offset 266 eaCode += ";" 267 268 if self.flavor == "fp": 269 eaCode += vfpEnabledCheckCode 270 271 self.codeBlobs["ea_code"] = eaCode 272 273 # Code that actually handles the access 274 if self.flavor == "fp": 275 accCode = ''' 276 uint64_t swappedMem = (uint64_t)FpDest_uw | 277 ((uint64_t)FpDest2_uw << 32); 278 Mem_ud = cSwap(swappedMem, ((CPSR)Cpsr).e); 279 ''' 280 else: 281 accCode = ''' 282 CPSR cpsr = Cpsr; 283 Mem_ud = (uint64_t)cSwap(Dest_uw, cpsr.e) | 284 ((uint64_t)cSwap(Dest2_uw, cpsr.e) << 32); 285 ''' 286 287 self.codeBlobs["memacc_code"] = accCode 288 289 # Push it out to the output files 290 base = buildMemBase(self.basePrefix, self.post, self.writeback) 291 wbDecl = None 292 if self.writeback: 293 wbDecl = self.wbDecl 294 self.emitHelper(base, wbDecl) 295 296 def storeDoubleImmClassName(post, add, writeback): 297 return memClassName("STORE_IMMD", post, add, writeback, 4, False, False) 298 299 class StoreDoubleImmEx(StoreImmInst, StoreDouble): 300 execBase = 'StoreEx' 301 decConstBase = 'StoreExDImm' 302 basePrefix = 'MemoryExDImm' 303 nameFunc = staticmethod(storeDoubleImmClassName) 304 305 def __init__(self, *args, **kargs): 306 super(StoreDoubleImmEx, self).__init__(*args, **kargs) 307 self.codeBlobs["postacc_code"] = "Result = !writeResult;" 308 309 class StoreDoubleImm(StoreImmInst, StoreDouble): 310 decConstBase = 'LoadStoreDImm' 311 basePrefix = 'MemoryDImm' 312 nameFunc = staticmethod(storeDoubleImmClassName) 313 314 def storeDoubleRegClassName(post, add, writeback): 315 return memClassName("STORE_REGD", post, add, writeback, 4, False, False) 316 317 class StoreDoubleReg(StoreRegInst, StoreDouble): 318 decConstBase = 'StoreDReg' 319 basePrefix = 'MemoryDReg' 320 nameFunc = staticmethod(storeDoubleRegClassName) 321 322 def buildStores(mnem, size=4, sign=False, user=False): 323 StoreImm(mnem, True, True, True, size, sign, user).emit() 324 StoreReg(mnem, True, True, True, size, sign, user).emit() 325 StoreImm(mnem, True, False, True, size, sign, user).emit() 326 StoreReg(mnem, True, False, True, size, sign, user).emit() 327 StoreImm(mnem, False, True, True, size, sign, user).emit() 328 StoreReg(mnem, False, True, True, size, sign, user).emit() 329 StoreImm(mnem, False, False, True, size, sign, user).emit() 330 StoreReg(mnem, False, False, True, size, sign, user).emit() 331 StoreImm(mnem, False, True, False, size, sign, user).emit() 332 StoreReg(mnem, False, True, False, size, sign, user).emit() 333 StoreImm(mnem, False, False, False, size, sign, user).emit() 334 StoreReg(mnem, False, False, False, size, sign, user).emit() 335 336 def buildDoubleStores(mnem): 337 StoreDoubleImm(mnem, True, True, True).emit() 338 StoreDoubleReg(mnem, True, True, True).emit() 339 StoreDoubleImm(mnem, True, False, True).emit() 340 StoreDoubleReg(mnem, True, False, True).emit() 341 StoreDoubleImm(mnem, False, True, True).emit() 342 StoreDoubleReg(mnem, False, True, True).emit() 343 StoreDoubleImm(mnem, False, False, True).emit() 344 StoreDoubleReg(mnem, False, False, True).emit() 345 StoreDoubleImm(mnem, False, True, False).emit() 346 StoreDoubleReg(mnem, False, True, False).emit() 347 StoreDoubleImm(mnem, False, False, False).emit() 348 StoreDoubleReg(mnem, False, False, False).emit() 349 350 def buildSrsStores(mnem): 351 SrsInst(mnem, True, True, True).emit() 352 SrsInst(mnem, True, True, False).emit() 353 SrsInst(mnem, True, False, True).emit() 354 SrsInst(mnem, True, False, False).emit() 355 SrsInst(mnem, False, True, True).emit() 356 SrsInst(mnem, False, True, False).emit() 357 SrsInst(mnem, False, False, True).emit() 358 SrsInst(mnem, False, False, False).emit() 359 360 buildStores("str") 361 buildStores("strt", user=True) 362 buildStores("strb", size=1) 363 buildStores("strbt", size=1, user=True) 364 buildStores("strh", size=2) 365 buildStores("strht", size=2, user=True) 366 367 buildSrsStores("srs") 368 369 buildDoubleStores("strd") 370 371 StoreImmEx("strex", False, True, False, size=4, flavor="exclusive", 372 instFlags = ['IsStoreConditional']).emit() 373 StoreImmEx("strexh", False, True, False, size=2, flavor="exclusive", 374 instFlags = ['IsStoreConditional']).emit() 375 StoreImmEx("strexb", False, True, False, size=1, flavor="exclusive", 376 instFlags = ['IsStoreConditional']).emit() 377 StoreDoubleImmEx("strexd", False, True, False, flavor="exclusive", 378 instFlags = ['IsStoreConditional']).emit() 379 380 StoreImm("vstr", False, True, False, size=4, flavor="fp").emit() 381 StoreImm("vstr", False, False, False, size=4, flavor="fp").emit() 382 StoreDoubleImm("vstr", False, True, False, flavor="fp").emit() 383 StoreDoubleImm("vstr", False, False, False, flavor="fp").emit() 384}}; 385