str.isa revision 7593
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 super(StoreInst, self).__init__() 52 53 self.name = mnem 54 self.post = post 55 self.add = add 56 self.writeback = writeback 57 self.size = size 58 self.sign = sign 59 self.user = user 60 self.flavor = flavor 61 62 if self.add: 63 self.op = " +" 64 else: 65 self.op = " -" 66 67 self.memFlags = ["ArmISA::TLB::MustBeOne"] 68 self.codeBlobs = { "postacc_code" : "" } 69 70 def emitHelper(self, base = 'Memory'): 71 72 global header_output, decoder_output, exec_output 73 74 codeBlobs = self.codeBlobs 75 codeBlobs["predicate_test"] = pickPredicate(codeBlobs) 76 (newHeader, 77 newDecoder, 78 newExec) = self.fillTemplates(self.name, self.Name, codeBlobs, 79 self.memFlags, [], base) 80 81 header_output += newHeader 82 decoder_output += newDecoder 83 exec_output += newExec 84 85 class SrsInst(LoadStoreInst): 86 execBase = 'Store' 87 decConstBase = 'Srs' 88 89 def __init__(self, mnem, post, add, writeback): 90 super(SrsInst, self).__init__() 91 self.name = mnem 92 self.post = post 93 self.add = add 94 self.writeback = writeback 95 96 self.Name = "SRS_" + storeImmClassName(post, add, writeback, 8) 97 98 def emit(self): 99 offset = 0 100 if self.post != self.add: 101 offset += 4 102 if not self.add: 103 offset -= 8 104 105 eaCode = "EA = SpMode + %d;" % offset 106 107 wbDiff = -8 108 if self.add: 109 wbDiff = 8 110 accCode = ''' 111 CPSR cpsr = Cpsr; 112 Mem.ud = (uint64_t)cSwap(LR.uw, cpsr.e) | 113 ((uint64_t)cSwap(Spsr.uw, cpsr.e) << 32); 114 ''' 115 if self.writeback: 116 accCode += "SpMode = SpMode + %s;\n" % wbDiff 117 118 global header_output, decoder_output, exec_output 119 120 codeBlobs = { "ea_code": eaCode, 121 "memacc_code": accCode, 122 "postacc_code": "" } 123 codeBlobs["predicate_test"] = pickPredicate(codeBlobs) 124 125 (newHeader, 126 newDecoder, 127 newExec) = self.fillTemplates(self.name, self.Name, codeBlobs, 128 ["ArmISA::TLB::AlignWord", "ArmISA::TLB::MustBeOne"], [], 129 base = 'SrsOp') 130 131 header_output += newHeader 132 decoder_output += newDecoder 133 exec_output += newExec 134 135 class StoreImmInst(StoreInst): 136 def __init__(self, *args, **kargs): 137 super(StoreImmInst, self).__init__(*args, **kargs) 138 self.offset = self.op + " imm" 139 140 class StoreRegInst(StoreInst): 141 def __init__(self, *args, **kargs): 142 super(StoreRegInst, self).__init__(*args, **kargs) 143 self.offset = self.op + " shift_rm_imm(Index, shiftAmt," + \ 144 " shiftType, CondCodes<29:>)" 145 146 class StoreSingle(StoreInst): 147 def __init__(self, *args, **kargs): 148 super(StoreSingle, self).__init__(*args, **kargs) 149 150 # Build the default class name 151 self.Name = self.nameFunc(self.post, self.add, self.writeback, 152 self.size, self.sign, self.user) 153 154 # Add memory request flags where necessary 155 self.memFlags.append("%d" % (self.size - 1)) 156 if self.user: 157 self.memFlags.append("ArmISA::TLB::UserMode") 158 159 if self.flavor == "exclusive": 160 self.memFlags.append("Request::LLSC") 161 elif self.flavor != "fp": 162 self.memFlags.append("ArmISA::TLB::AllowUnaligned") 163 164 # Disambiguate the class name for different flavors of stores 165 if self.flavor != "normal": 166 self.Name = "%s_%s" % (self.name.upper(), self.Name) 167 168 def emit(self): 169 # Address computation 170 eaCode = "EA = Base" 171 if not self.post: 172 eaCode += self.offset 173 eaCode += ";" 174 self.codeBlobs["ea_code"] = eaCode 175 176 # Code that actually handles the access 177 if self.flavor == "fp": 178 accCode = 'Mem%(suffix)s = cSwap(FpDest.uw, ((CPSR)Cpsr).e);' 179 else: 180 accCode = \ 181 'Mem%(suffix)s = cSwap(Dest%(suffix)s, ((CPSR)Cpsr).e);' 182 accCode = accCode % \ 183 { "suffix" : buildMemSuffix(self.sign, self.size) } 184 185 if self.writeback: 186 accCode += "Base = Base %s;\n" % self.offset 187 188 self.codeBlobs["memacc_code"] = accCode 189 190 # Push it out to the output files 191 base = buildMemBase(self.basePrefix, self.post, self.writeback) 192 self.emitHelper(base) 193 194 def storeImmClassName(post, add, writeback, size=4, sign=False, user=False): 195 return memClassName("STORE_IMM", post, add, writeback, size, sign, user) 196 197 class StoreImmEx(StoreImmInst, StoreSingle): 198 execBase = 'StoreEx' 199 decConstBase = 'StoreExImm' 200 basePrefix = 'MemoryExImm' 201 nameFunc = staticmethod(storeImmClassName) 202 203 def __init__(self, *args, **kargs): 204 super(StoreImmEx, self).__init__(*args, **kargs) 205 self.codeBlobs["postacc_code"] = "Result = !writeResult;" 206 207 class StoreImm(StoreImmInst, StoreSingle): 208 decConstBase = 'LoadStoreImm' 209 basePrefix = 'MemoryImm' 210 nameFunc = staticmethod(storeImmClassName) 211 212 def storeRegClassName(post, add, writeback, size=4, sign=False, user=False): 213 return memClassName("STORE_REG", post, add, writeback, size, sign, user) 214 215 class StoreReg(StoreRegInst, StoreSingle): 216 decConstBase = 'LoadStoreReg' 217 basePrefix = 'MemoryReg' 218 nameFunc = staticmethod(storeRegClassName) 219 220 class StoreDouble(StoreInst): 221 def __init__(self, *args, **kargs): 222 super(StoreDouble, self).__init__(*args, **kargs) 223 224 # Build the default class name 225 self.Name = self.nameFunc(self.post, self.add, self.writeback) 226 227 # Add memory request flags where necessary 228 if self.flavor == "exclusive": 229 self.memFlags.append("Request::LLSC") 230 self.memFlags.append("ArmISA::TLB::AlignDoubleWord") 231 else: 232 self.memFlags.append("ArmISA::TLB::AlignWord") 233 234 # Disambiguate the class name for different flavors of stores 235 if self.flavor != "normal": 236 self.Name = "%s_%s" % (self.name.upper(), self.Name) 237 238 def emit(self): 239 # Address computation code 240 eaCode = "EA = Base" 241 if not self.post: 242 eaCode += self.offset 243 eaCode += ";" 244 self.codeBlobs["ea_code"] = eaCode 245 246 # Code that actually handles the access 247 if self.flavor == "fp": 248 accCode = ''' 249 uint64_t swappedMem = (uint64_t)FpDest.uw | 250 ((uint64_t)FpDest2.uw << 32); 251 Mem.ud = cSwap(swappedMem, ((CPSR)Cpsr).e); 252 ''' 253 else: 254 accCode = ''' 255 CPSR cpsr = Cpsr; 256 Mem.ud = (uint64_t)cSwap(Dest.uw, cpsr.e) | 257 ((uint64_t)cSwap(Dest2.uw, cpsr.e) << 32); 258 ''' 259 260 if self.writeback: 261 accCode += "Base = Base %s;\n" % self.offset 262 263 self.codeBlobs["memacc_code"] = accCode 264 265 # Push it out to the output files 266 base = buildMemBase(self.basePrefix, self.post, self.writeback) 267 self.emitHelper(base) 268 269 def storeDoubleImmClassName(post, add, writeback): 270 return memClassName("STORE_IMMD", post, add, writeback, 4, False, False) 271 272 class StoreDoubleImmEx(StoreImmInst, StoreDouble): 273 execBase = 'StoreEx' 274 decConstBase = 'StoreExDImm' 275 basePrefix = 'MemoryExDImm' 276 nameFunc = staticmethod(storeDoubleImmClassName) 277 278 def __init__(self, *args, **kargs): 279 super(StoreDoubleImmEx, self).__init__(*args, **kargs) 280 self.codeBlobs["postacc_code"] = "Result = !writeResult;" 281 282 class StoreDoubleImm(StoreImmInst, StoreDouble): 283 decConstBase = 'LoadStoreDImm' 284 basePrefix = 'MemoryDImm' 285 nameFunc = staticmethod(storeDoubleImmClassName) 286 287 def storeDoubleRegClassName(post, add, writeback): 288 return memClassName("STORE_REGD", post, add, writeback, 4, False, False) 289 290 class StoreDoubleReg(StoreRegInst, StoreDouble): 291 decConstBase = 'LoadStoreDReg' 292 basePrefix = 'MemoryDReg' 293 nameFunc = staticmethod(storeDoubleRegClassName) 294 295 def buildStores(mnem, size=4, sign=False, user=False): 296 StoreImm(mnem, True, True, True, size, sign, user).emit() 297 StoreReg(mnem, True, True, True, size, sign, user).emit() 298 StoreImm(mnem, True, False, True, size, sign, user).emit() 299 StoreReg(mnem, True, False, True, size, sign, user).emit() 300 StoreImm(mnem, False, True, True, size, sign, user).emit() 301 StoreReg(mnem, False, True, True, size, sign, user).emit() 302 StoreImm(mnem, False, False, True, size, sign, user).emit() 303 StoreReg(mnem, False, False, True, size, sign, user).emit() 304 StoreImm(mnem, False, True, False, size, sign, user).emit() 305 StoreReg(mnem, False, True, False, size, sign, user).emit() 306 StoreImm(mnem, False, False, False, size, sign, user).emit() 307 StoreReg(mnem, False, False, False, size, sign, user).emit() 308 309 def buildDoubleStores(mnem): 310 StoreDoubleImm(mnem, True, True, True).emit() 311 StoreDoubleReg(mnem, True, True, True).emit() 312 StoreDoubleImm(mnem, True, False, True).emit() 313 StoreDoubleReg(mnem, True, False, True).emit() 314 StoreDoubleImm(mnem, False, True, True).emit() 315 StoreDoubleReg(mnem, False, True, True).emit() 316 StoreDoubleImm(mnem, False, False, True).emit() 317 StoreDoubleReg(mnem, False, False, True).emit() 318 StoreDoubleImm(mnem, False, True, False).emit() 319 StoreDoubleReg(mnem, False, True, False).emit() 320 StoreDoubleImm(mnem, False, False, False).emit() 321 StoreDoubleReg(mnem, False, False, False).emit() 322 323 def buildSrsStores(mnem): 324 SrsInst(mnem, True, True, True).emit() 325 SrsInst(mnem, True, True, False).emit() 326 SrsInst(mnem, True, False, True).emit() 327 SrsInst(mnem, True, False, False).emit() 328 SrsInst(mnem, False, True, True).emit() 329 SrsInst(mnem, False, True, False).emit() 330 SrsInst(mnem, False, False, True).emit() 331 SrsInst(mnem, False, False, False).emit() 332 333 buildStores("str") 334 buildStores("strt", user=True) 335 buildStores("strb", size=1) 336 buildStores("strbt", size=1, user=True) 337 buildStores("strh", size=2) 338 buildStores("strht", size=2, user=True) 339 340 buildSrsStores("srs") 341 342 buildDoubleStores("strd") 343 344 StoreImmEx("strex", False, True, False, size=4, flavor="exclusive").emit() 345 StoreImmEx("strexh", False, True, False, size=2, flavor="exclusive").emit() 346 StoreImmEx("strexb", False, True, False, size=1, flavor="exclusive").emit() 347 StoreDoubleImmEx("strexd", False, True, False, flavor="exclusive").emit() 348 349 StoreImm("vstr", False, True, False, size=4, flavor="fp").emit() 350 StoreImm("vstr", False, False, False, size=4, flavor="fp").emit() 351 StoreDoubleImm("vstr", False, True, False, flavor="fp").emit() 352 StoreDoubleImm("vstr", False, False, False, flavor="fp").emit() 353}}; 354