ldr.isa revision 7404:bfc74724914e
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 loadImmClassName(post, add, writeback, \ 47 size=4, sign=False, user=False): 48 return memClassName("LOAD_IMM", post, add, writeback, 49 size, sign, user) 50 51 def loadRegClassName(post, add, writeback, \ 52 size=4, sign=False, user=False): 53 return memClassName("LOAD_REG", post, add, writeback, 54 size, sign, user) 55 56 def loadDoubleImmClassName(post, add, writeback): 57 return memClassName("LOAD_IMMD", post, add, writeback, 4, False, False) 58 59 def loadDoubleRegClassName(post, add, writeback): 60 return memClassName("LOAD_REGD", post, add, writeback, 4, False, False) 61 62 def emitLoad(name, Name, imm, eaCode, accCode, \ 63 memFlags, instFlags, base, double=False): 64 global header_output, decoder_output, exec_output 65 66 (newHeader, 67 newDecoder, 68 newExec) = loadStoreBase(name, Name, imm, 69 eaCode, accCode, "", 70 memFlags, instFlags, double, False, 71 base, execTemplateBase = 'Load') 72 73 header_output += newHeader 74 decoder_output += newDecoder 75 exec_output += newExec 76 77 def buildImmLoad(mnem, post, add, writeback, \ 78 size=4, sign=False, user=False, \ 79 prefetch=False, ldrex=False, vldr=False): 80 name = mnem 81 Name = loadImmClassName(post, add, writeback, \ 82 size, sign, user) 83 84 if add: 85 op = " +" 86 else: 87 op = " -" 88 89 offset = op + " imm" 90 eaCode = "EA = Base" 91 if not post: 92 eaCode += offset 93 eaCode += ";" 94 95 memFlags = ["ArmISA::TLB::MustBeOne", "%d" % (size - 1)] 96 if user: 97 memFlags.append("ArmISA::TLB::UserMode") 98 99 if prefetch: 100 Name = "%s_%s" % (mnem.upper(), Name) 101 memFlags.append("Request::PREFETCH") 102 accCode = ''' 103 uint64_t temp = Mem%s;\n 104 temp = temp; 105 ''' % buildMemSuffix(sign, size) 106 elif vldr: 107 Name = "%s_%s" % (mnem.upper(), Name) 108 accCode = "FpDest.uw = cSwap(Mem%s, ((CPSR)Cpsr).e);\n" % \ 109 buildMemSuffix(sign, size) 110 else: 111 if ldrex: 112 memFlags.append("Request::LLSC") 113 Name = "%s_%s" % (mnem.upper(), Name) 114 accCode = "IWDest = cSwap(Mem%s, ((CPSR)Cpsr).e);" % \ 115 buildMemSuffix(sign, size) 116 117 if not prefetch and not ldrex and not vldr: 118 memFlags.append("ArmISA::TLB::AllowUnaligned") 119 120 if writeback: 121 accCode += "Base = Base %s;\n" % offset 122 base = buildMemBase("MemoryImm", post, writeback) 123 124 emitLoad(name, Name, True, eaCode, accCode, memFlags, [], base) 125 126 def buildRfeLoad(mnem, post, add, writeback): 127 name = mnem 128 Name = "RFE_" + loadImmClassName(post, add, writeback, 8) 129 130 offset = 0 131 if post != add: 132 offset += 4 133 if not add: 134 offset -= 8 135 136 eaCode = "EA = Base + %d;" % offset 137 138 wbDiff = -8 139 if add: 140 wbDiff = 8 141 accCode = ''' 142 CPSR cpsr = Cpsr; 143 SCTLR sctlr = Sctlr; 144 NPC = cSwap<uint32_t>(Mem.ud, cpsr.e); 145 uint32_t newCpsr = 146 cpsrWriteByInstr(cpsr | CondCodes, 147 cSwap<uint32_t>(Mem.ud >> 32, cpsr.e), 148 0xF, true, sctlr.nmfi); 149 Cpsr = ~CondCodesMask & newCpsr; 150 CondCodes = CondCodesMask & newCpsr; 151 ''' 152 if writeback: 153 accCode += "Base = Base + %s;\n" % wbDiff 154 155 global header_output, decoder_output, exec_output 156 157 (newHeader, 158 newDecoder, 159 newExec) = RfeBase(name, Name, eaCode, accCode, 160 ["ArmISA::TLB::AlignWord", "ArmISA::TLB::MustBeOne"], []) 161 162 header_output += newHeader 163 decoder_output += newDecoder 164 exec_output += newExec 165 166 def buildRegLoad(mnem, post, add, writeback, size=4, sign=False, \ 167 user=False, prefetch=False): 168 name = mnem 169 Name = loadRegClassName(post, add, writeback, 170 size, sign, user) 171 172 if add: 173 op = " +" 174 else: 175 op = " -" 176 177 offset = op + " shift_rm_imm(Index, shiftAmt," + \ 178 " shiftType, CondCodes<29:>)" 179 eaCode = "EA = Base" 180 if not post: 181 eaCode += offset 182 eaCode += ";" 183 184 memFlags = ["%d" % (size - 1), "ArmISA::TLB::MustBeOne"] 185 if user: 186 memFlags.append("ArmISA::TLB::UserMode") 187 188 if prefetch: 189 Name = "%s_%s" % (mnem.upper(), Name) 190 memFlags.append("Request::PREFETCH") 191 accCode = ''' 192 uint64_t temp = Mem%s;\n 193 temp = temp; 194 ''' % buildMemSuffix(sign, size) 195 else: 196 accCode = "IWDest = cSwap(Mem%s, ((CPSR)Cpsr).e);" % \ 197 buildMemSuffix(sign, size) 198 if writeback: 199 accCode += "Base = Base %s;\n" % offset 200 201 if not prefetch: 202 memFlags.append("ArmISA::TLB::AllowUnaligned") 203 204 base = buildMemBase("MemoryReg", post, writeback) 205 206 emitLoad(name, Name, False, eaCode, accCode, \ 207 memFlags, [], base) 208 209 def buildDoubleImmLoad(mnem, post, add, writeback, \ 210 ldrex=False, vldr=False): 211 name = mnem 212 Name = loadDoubleImmClassName(post, add, writeback) 213 214 if add: 215 op = " +" 216 else: 217 op = " -" 218 219 offset = op + " imm" 220 eaCode = "EA = Base" 221 if not post: 222 eaCode += offset 223 eaCode += ";" 224 225 if not vldr: 226 accCode = ''' 227 CPSR cpsr = Cpsr; 228 Dest = cSwap<uint32_t>(Mem.ud, cpsr.e); 229 Dest2 = cSwap<uint32_t>(Mem.ud >> 32, cpsr.e); 230 ''' 231 else: 232 accCode = ''' 233 uint64_t swappedMem = cSwap(Mem.ud, ((CPSR)Cpsr).e); 234 FpDest.uw = (uint32_t)swappedMem; 235 FpDest2.uw = (uint32_t)(swappedMem >> 32); 236 ''' 237 if ldrex: 238 memFlags = ["Request::LLSC"] 239 else: 240 memFlags = [] 241 if ldrex or vldr: 242 Name = "%s_%s" % (mnem.upper(), Name) 243 if writeback: 244 accCode += "Base = Base %s;\n" % offset 245 base = buildMemBase("MemoryDImm", post, writeback) 246 247 memFlags.extend(["ArmISA::TLB::MustBeOne", 248 "ArmISA::TLB::AlignWord"]) 249 250 emitLoad(name, Name, True, eaCode, accCode, \ 251 memFlags, [], base, double=True) 252 253 def buildDoubleRegLoad(mnem, post, add, writeback): 254 name = mnem 255 Name = loadDoubleRegClassName(post, add, writeback) 256 257 if add: 258 op = " +" 259 else: 260 op = " -" 261 262 offset = op + " shift_rm_imm(Index, shiftAmt," + \ 263 " shiftType, CondCodes<29:>)" 264 eaCode = "EA = Base" 265 if not post: 266 eaCode += offset 267 eaCode += ";" 268 269 accCode = ''' 270 CPSR cpsr = Cpsr; 271 Dest = cSwap<uint32_t>(Mem.ud, cpsr.e); 272 Dest2 = cSwap<uint32_t>(Mem.ud >> 32, cpsr.e); 273 ''' 274 if writeback: 275 accCode += "Base = Base %s;\n" % offset 276 base = buildMemBase("MemoryDReg", post, writeback) 277 278 emitLoad(name, Name, False, eaCode, accCode, 279 ["ArmISA::TLB::MustBeOne", "ArmISA::TLB::AlignWord"], 280 [], base, double=True) 281 282 def buildLoads(mnem, size=4, sign=False, user=False): 283 buildImmLoad(mnem, True, True, True, size, sign, user) 284 buildRegLoad(mnem, True, True, True, size, sign, user) 285 buildImmLoad(mnem, True, False, True, size, sign, user) 286 buildRegLoad(mnem, True, False, True, size, sign, user) 287 buildImmLoad(mnem, False, True, True, size, sign, user) 288 buildRegLoad(mnem, False, True, True, size, sign, user) 289 buildImmLoad(mnem, False, False, True, size, sign, user) 290 buildRegLoad(mnem, False, False, True, size, sign, user) 291 buildImmLoad(mnem, False, True, False, size, sign, user) 292 buildRegLoad(mnem, False, True, False, size, sign, user) 293 buildImmLoad(mnem, False, False, False, size, sign, user) 294 buildRegLoad(mnem, False, False, False, size, sign, user) 295 296 def buildDoubleLoads(mnem): 297 buildDoubleImmLoad(mnem, True, True, True) 298 buildDoubleRegLoad(mnem, True, True, True) 299 buildDoubleImmLoad(mnem, True, False, True) 300 buildDoubleRegLoad(mnem, True, False, True) 301 buildDoubleImmLoad(mnem, False, True, True) 302 buildDoubleRegLoad(mnem, False, True, True) 303 buildDoubleImmLoad(mnem, False, False, True) 304 buildDoubleRegLoad(mnem, False, False, True) 305 buildDoubleImmLoad(mnem, False, True, False) 306 buildDoubleRegLoad(mnem, False, True, False) 307 buildDoubleImmLoad(mnem, False, False, False) 308 buildDoubleRegLoad(mnem, False, False, False) 309 310 def buildRfeLoads(mnem): 311 buildRfeLoad(mnem, True, True, True) 312 buildRfeLoad(mnem, True, True, False) 313 buildRfeLoad(mnem, True, False, True) 314 buildRfeLoad(mnem, True, False, False) 315 buildRfeLoad(mnem, False, True, True) 316 buildRfeLoad(mnem, False, True, False) 317 buildRfeLoad(mnem, False, False, True) 318 buildRfeLoad(mnem, False, False, False) 319 320 def buildPrefetches(mnem): 321 buildRegLoad(mnem, False, False, False, size=1, prefetch=True) 322 buildImmLoad(mnem, False, False, False, size=1, prefetch=True) 323 buildRegLoad(mnem, False, True, False, size=1, prefetch=True) 324 buildImmLoad(mnem, False, True, False, size=1, prefetch=True) 325 326 buildLoads("ldr") 327 buildLoads("ldrt", user=True) 328 buildLoads("ldrb", size=1) 329 buildLoads("ldrbt", size=1, user=True) 330 buildLoads("ldrsb", size=1, sign=True) 331 buildLoads("ldrsbt", size=1, sign=True, user=True) 332 buildLoads("ldrh", size=2) 333 buildLoads("ldrht", size=2, user=True) 334 buildLoads("hdrsh", size=2, sign=True) 335 buildLoads("ldrsht", size=2, sign=True, user=True) 336 337 buildDoubleLoads("ldrd") 338 339 buildRfeLoads("rfe") 340 341 buildPrefetches("pld") 342 buildPrefetches("pldw") 343 buildPrefetches("pli") 344 345 buildImmLoad("ldrex", False, True, False, size=4, ldrex=True) 346 buildImmLoad("ldrexh", False, True, False, size=2, ldrex=True) 347 buildImmLoad("ldrexb", False, True, False, size=1, ldrex=True) 348 buildDoubleImmLoad("ldrexd", False, True, False, ldrex=True) 349 350 buildImmLoad("vldr", False, True, False, size=4, vldr=True) 351 buildImmLoad("vldr", False, False, False, size=4, vldr=True) 352 buildDoubleImmLoad("vldr", False, True, False, vldr=True) 353 buildDoubleImmLoad("vldr", False, False, False, vldr=True) 354}}; 355