str.isa revision 7313
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 def storeImmClassName(post, add, writeback, \ 47 size=4, sign=False, user=False): 48 return memClassName("STORE_IMM", post, add, writeback, 49 size, sign, user) 50 51 def storeRegClassName(post, add, writeback, \ 52 size=4, sign=False, user=False): 53 return memClassName("STORE_REG", post, add, writeback, 54 size, sign, user) 55 56 def storeDoubleImmClassName(post, add, writeback): 57 return memClassName("STORE_IMMD", post, add, writeback, 58 4, False, False) 59 60 def storeDoubleRegClassName(post, add, writeback): 61 return memClassName("STORE_REGD", post, add, writeback, 62 4, False, False) 63 64 def emitStore(name, Name, imm, eaCode, accCode, postAccCode, \ 65 memFlags, instFlags, base, double=False, strex=False, 66 execTemplateBase = 'Store'): 67 global header_output, decoder_output, exec_output 68 69 (newHeader, 70 newDecoder, 71 newExec) = loadStoreBase(name, Name, imm, 72 eaCode, accCode, postAccCode, 73 memFlags, instFlags, double, strex, 74 base, execTemplateBase = execTemplateBase) 75 76 header_output += newHeader 77 decoder_output += newDecoder 78 exec_output += newExec 79 80 def buildImmStore(mnem, post, add, writeback, \ 81 size=4, sign=False, user=False, strex=False): 82 name = mnem 83 Name = storeImmClassName(post, add, writeback, \ 84 size, sign, user) 85 86 if add: 87 op = " +" 88 else: 89 op = " -" 90 91 offset = op + " imm" 92 eaCode = "EA = Base" 93 if not post: 94 eaCode += offset 95 eaCode += ";" 96 97 accCode = "Mem%(suffix)s = cSwap(Dest%(suffix)s, ((CPSR)Cpsr).e);" % \ 98 { "suffix" : buildMemSuffix(sign, size) } 99 if writeback: 100 accCode += "Base = Base %s;\n" % offset 101 102 memFlags = ["ArmISA::TLB::MustBeOne", "%d" % (size - 1)] 103 if strex: 104 memFlags.append("Request::LLSC") 105 Name = "%s_%s" % (mnem.upper(), Name) 106 base = buildMemBase("MemoryExImm", post, writeback) 107 postAccCode = "Result = !writeResult;" 108 execTemplateBase = 'StoreEx' 109 else: 110 memFlags.append("ArmISA::TLB::AllowUnaligned") 111 base = buildMemBase("MemoryImm", post, writeback) 112 postAccCode = "" 113 execTemplateBase = 'Store' 114 115 emitStore(name, Name, True, eaCode, accCode, postAccCode, \ 116 memFlags, [], base, strex=strex, 117 execTemplateBase = execTemplateBase) 118 119 def buildSrsStore(mnem, post, add, writeback): 120 name = mnem 121 Name = "SRS_" + storeImmClassName(post, add, writeback, 8) 122 123 offset = 0 124 if post != add: 125 offset += 4 126 if not add: 127 offset -= 8 128 129 eaCode = "EA = SpMode + %d;" % offset 130 131 wbDiff = -8 132 if add: 133 wbDiff = 8 134 accCode = ''' 135 CPSR cpsr = Cpsr; 136 Mem.ud = (uint64_t)cSwap(LR.uw, cpsr.e) | 137 ((uint64_t)cSwap(Spsr.uw, cpsr.e) << 32); 138 ''' 139 if writeback: 140 accCode += "SpMode = SpMode + %s;\n" % wbDiff 141 142 global header_output, decoder_output, exec_output 143 144 (newHeader, 145 newDecoder, 146 newExec) = SrsBase(name, Name, eaCode, accCode, 147 ["ArmISA::TLB::AlignWord", "ArmISA::TLB::MustBeOne"], []) 148 149 header_output += newHeader 150 decoder_output += newDecoder 151 exec_output += newExec 152 153 def buildRegStore(mnem, post, add, writeback, \ 154 size=4, sign=False, user=False, strex=False): 155 name = mnem 156 Name = storeRegClassName(post, add, writeback, 157 size, sign, user) 158 159 if add: 160 op = " +" 161 else: 162 op = " -" 163 164 offset = op + " shift_rm_imm(Index, shiftAmt," + \ 165 " shiftType, CondCodes<29:>)" 166 eaCode = "EA = Base" 167 if not post: 168 eaCode += offset 169 eaCode += ";" 170 171 accCode = "Mem%(suffix)s = cSwap(Dest%(suffix)s, ((CPSR)Cpsr).e);" % \ 172 { "suffix" : buildMemSuffix(sign, size) } 173 if writeback: 174 accCode += "Base = Base %s;\n" % offset 175 base = buildMemBase("MemoryReg", post, writeback) 176 177 emitStore(name, Name, False, eaCode, accCode, "",\ 178 ["ArmISA::TLB::MustBeOne", \ 179 "ArmISA::TLB::AllowUnaligned", \ 180 "%d" % (size - 1)], [], base) 181 182 def buildDoubleImmStore(mnem, post, add, writeback, strex=False): 183 name = mnem 184 Name = storeDoubleImmClassName(post, add, writeback) 185 186 if add: 187 op = " +" 188 else: 189 op = " -" 190 191 offset = op + " imm" 192 eaCode = "EA = Base" 193 if not post: 194 eaCode += offset 195 eaCode += ";" 196 197 accCode = ''' 198 CPSR cpsr = Cpsr; 199 Mem.ud = (uint64_t)cSwap(Dest.uw, cpsr.e) | 200 ((uint64_t)cSwap(Dest2.uw, cpsr.e) << 32); 201 ''' 202 if writeback: 203 accCode += "Base = Base %s;\n" % offset 204 205 memFlags = ["ArmISA::TLB::MustBeOne", 206 "ArmISA::TLB::AlignWord"] 207 if strex: 208 memFlags.append("Request::LLSC") 209 Name = "%s_%s" % (mnem.upper(), Name) 210 base = buildMemBase("MemoryExDImm", post, writeback) 211 postAccCode = "Result = !writeResult;" 212 else: 213 base = buildMemBase("MemoryDImm", post, writeback) 214 postAccCode = "" 215 216 emitStore(name, Name, True, eaCode, accCode, postAccCode, \ 217 memFlags, [], base, double=True, strex=strex) 218 219 def buildDoubleRegStore(mnem, post, add, writeback): 220 name = mnem 221 Name = storeDoubleRegClassName(post, add, writeback) 222 223 if add: 224 op = " +" 225 else: 226 op = " -" 227 228 offset = op + " shift_rm_imm(Index, shiftAmt," + \ 229 " shiftType, CondCodes<29:>)" 230 eaCode = "EA = Base" 231 if not post: 232 eaCode += offset 233 eaCode += ";" 234 235 accCode = ''' 236 CPSR cpsr = Cpsr; 237 Mem.ud = (uint64_t)cSwap(Dest.uw, cpsr.e) | 238 ((uint64_t)cSwap(Dest2.uw, cpsr.e) << 32); 239 ''' 240 if writeback: 241 accCode += "Base = Base %s;\n" % offset 242 base = buildMemBase("MemoryDReg", post, writeback) 243 244 memFlags = ["ArmISA::TLB::MustBeOne", 245 "ArmISA::TLB::AlignWord"] 246 247 emitStore(name, Name, False, eaCode, accCode, "", \ 248 memFlags, [], base, double=True) 249 250 def buildStores(mnem, size=4, sign=False, user=False): 251 buildImmStore(mnem, True, True, True, size, sign, user) 252 buildRegStore(mnem, True, True, True, size, sign, user) 253 buildImmStore(mnem, True, False, True, size, sign, user) 254 buildRegStore(mnem, True, False, True, size, sign, user) 255 buildImmStore(mnem, False, True, True, size, sign, user) 256 buildRegStore(mnem, False, True, True, size, sign, user) 257 buildImmStore(mnem, False, False, True, size, sign, user) 258 buildRegStore(mnem, False, False, True, size, sign, user) 259 buildImmStore(mnem, False, True, False, size, sign, user) 260 buildRegStore(mnem, False, True, False, size, sign, user) 261 buildImmStore(mnem, False, False, False, size, sign, user) 262 buildRegStore(mnem, False, False, False, size, sign, user) 263 264 def buildDoubleStores(mnem): 265 buildDoubleImmStore(mnem, True, True, True) 266 buildDoubleRegStore(mnem, True, True, True) 267 buildDoubleImmStore(mnem, True, False, True) 268 buildDoubleRegStore(mnem, True, False, True) 269 buildDoubleImmStore(mnem, False, True, True) 270 buildDoubleRegStore(mnem, False, True, True) 271 buildDoubleImmStore(mnem, False, False, True) 272 buildDoubleRegStore(mnem, False, False, True) 273 buildDoubleImmStore(mnem, False, True, False) 274 buildDoubleRegStore(mnem, False, True, False) 275 buildDoubleImmStore(mnem, False, False, False) 276 buildDoubleRegStore(mnem, False, False, False) 277 278 def buildSrsStores(mnem): 279 buildSrsStore(mnem, True, True, True) 280 buildSrsStore(mnem, True, True, False) 281 buildSrsStore(mnem, True, False, True) 282 buildSrsStore(mnem, True, False, False) 283 buildSrsStore(mnem, False, True, True) 284 buildSrsStore(mnem, False, True, False) 285 buildSrsStore(mnem, False, False, True) 286 buildSrsStore(mnem, False, False, False) 287 288 buildStores("str") 289 buildStores("strt", user=True) 290 buildStores("strb", size=1) 291 buildStores("strbt", size=1, user=True) 292 buildStores("strh", size=2) 293 buildStores("strht", size=2, user=True) 294 295 buildSrsStores("srs") 296 297 buildDoubleStores("strd") 298 299 buildImmStore("strex", False, True, False, size=4, strex=True) 300 buildImmStore("strexh", False, True, False, size=2, strex=True) 301 buildImmStore("strexb", False, True, False, size=1, strex=True) 302 buildDoubleImmStore("strexd", False, True, False, strex=True) 303}}; 304