str.isa revision 12788:fe6d6ae79d7c
15222Sksewell@umich.edu// -*- mode:c++ -*- 25222Sksewell@umich.edu 35268Sksewell@umich.edu// Copyright (c) 2010-2011,2017 ARM Limited 45222Sksewell@umich.edu// All rights reserved 55222Sksewell@umich.edu// 65222Sksewell@umich.edu// The license below extends only to copyright in the software and shall 75222Sksewell@umich.edu// not be construed as granting a license to any other intellectual 85222Sksewell@umich.edu// property including but not limited to intellectual property relating 95222Sksewell@umich.edu// to a hardware implementation of the functionality of the software 105222Sksewell@umich.edu// licensed hereunder. You may use the software subject to the license 115222Sksewell@umich.edu// terms below provided that you ensure that this notice is replicated 125222Sksewell@umich.edu// unmodified and in its entirety in all distributions of the software, 135222Sksewell@umich.edu// modified or unmodified, in source code or in binary form. 145222Sksewell@umich.edu// 155222Sksewell@umich.edu// Redistribution and use in source and binary forms, with or without 165222Sksewell@umich.edu// modification, are permitted provided that the following conditions are 175222Sksewell@umich.edu// met: redistributions of source code must retain the above copyright 185222Sksewell@umich.edu// notice, this list of conditions and the following disclaimer; 195222Sksewell@umich.edu// redistributions in binary form must reproduce the above copyright 205222Sksewell@umich.edu// notice, this list of conditions and the following disclaimer in the 215222Sksewell@umich.edu// documentation and/or other materials provided with the distribution; 225222Sksewell@umich.edu// neither the name of the copyright holders nor the names of its 235222Sksewell@umich.edu// contributors may be used to endorse or promote products derived from 245222Sksewell@umich.edu// this software without specific prior written permission. 255222Sksewell@umich.edu// 265222Sksewell@umich.edu// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 275222Sksewell@umich.edu// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 285222Sksewell@umich.edu// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 295268Sksewell@umich.edu// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 305268Sksewell@umich.edu// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 315222Sksewell@umich.edu// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 325222Sksewell@umich.edu// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 335222Sksewell@umich.edu// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 345222Sksewell@umich.edu// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 355222Sksewell@umich.edu// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 365222Sksewell@umich.edu// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 375222Sksewell@umich.edu// 385222Sksewell@umich.edu// Authors: Gabe Black 395222Sksewell@umich.edu 405222Sksewell@umich.edulet {{ 415222Sksewell@umich.edu import math 425222Sksewell@umich.edu 435222Sksewell@umich.edu header_output = "" 445222Sksewell@umich.edu decoder_output = "" 455254Sksewell@umich.edu exec_output = "" 465254Sksewell@umich.edu 475254Sksewell@umich.edu class StoreInst(LoadStoreInst): 485254Sksewell@umich.edu execBase = 'Store' 495254Sksewell@umich.edu 505254Sksewell@umich.edu def __init__(self, mnem, post, add, writeback, size=4, 515254Sksewell@umich.edu sign=False, user=False, flavor="normal", 525254Sksewell@umich.edu instFlags = []): 535254Sksewell@umich.edu super(StoreInst, self).__init__() 545254Sksewell@umich.edu 555254Sksewell@umich.edu self.name = mnem 565254Sksewell@umich.edu self.post = post 575254Sksewell@umich.edu self.add = add 585254Sksewell@umich.edu self.writeback = writeback 595254Sksewell@umich.edu self.size = size 605254Sksewell@umich.edu self.sign = sign 615222Sksewell@umich.edu self.user = user 625222Sksewell@umich.edu self.flavor = flavor 635222Sksewell@umich.edu self.instFlags = instFlags 645222Sksewell@umich.edu if self.add: 655222Sksewell@umich.edu self.op = " +" 665222Sksewell@umich.edu else: 675222Sksewell@umich.edu self.op = " -" 685222Sksewell@umich.edu 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