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,
|
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): 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 prefetch: 97 Name = "%s_%s" % (mnem.upper(), Name) 98 memFlags.append("Request::PREFETCH") 99 accCode = ''' 100 uint64_t temp = Mem%s;\n 101 temp = temp; 102 ''' % buildMemSuffix(sign, size) 103 else: 104 if ldrex: 105 memFlags.append("Request::LLSC") 106 Name = "%s_%s" % (mnem.upper(), Name) 107 accCode = "IWDest = cSwap(Mem%s, ((CPSR)Cpsr).e);" % \ 108 buildMemSuffix(sign, size) 109 110 if not prefetch and not ldrex: 111 memFlags.append("ArmISA::TLB::AllowUnaligned") 112 113 if writeback: 114 accCode += "Base = Base %s;\n" % offset 115 base = buildMemBase("MemoryImm", post, writeback) 116 117 emitLoad(name, Name, True, eaCode, accCode, memFlags, [], base) 118 119 def buildRfeLoad(mnem, post, add, writeback): 120 name = mnem 121 Name = "RFE_" + loadImmClassName(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 = Base + %d;" % offset 130 131 wbDiff = -8 132 if add: 133 wbDiff = 8 134 accCode = ''' 135 CPSR cpsr = Cpsr; 136 NPC = cSwap<uint32_t>(Mem.ud, cpsr.e); 137 uint32_t newCpsr = 138 cpsrWriteByInstr(cpsr | CondCodes, 139 cSwap<uint32_t>(Mem.ud >> 32, cpsr.e), 140 0xF, true); 141 Cpsr = ~CondCodesMask & newCpsr; 142 CondCodes = CondCodesMask & newCpsr; 143 ''' 144 if writeback: 145 accCode += "Base = Base + %s;\n" % wbDiff 146 147 global header_output, decoder_output, exec_output 148 149 (newHeader, 150 newDecoder, 151 newExec) = RfeBase(name, Name, eaCode, accCode, 152 ["ArmISA::TLB::AlignWord", "ArmISA::TLB::MustBeOne"], []) 153 154 header_output += newHeader 155 decoder_output += newDecoder 156 exec_output += newExec 157 158 def buildRegLoad(mnem, post, add, writeback, \ 159 size=4, sign=False, user=False, prefetch=False): 160 name = mnem 161 Name = loadRegClassName(post, add, writeback, 162 size, sign, user) 163 164 if add: 165 op = " +" 166 else: 167 op = " -" 168 169 offset = op + " shift_rm_imm(Index, shiftAmt," + \ 170 " shiftType, CondCodes<29:>)" 171 eaCode = "EA = Base" 172 if not post: 173 eaCode += offset 174 eaCode += ";" 175 176 memFlags = ["%d" % (size - 1), "ArmISA::TLB::MustBeOne"] 177 if prefetch: 178 Name = "%s_%s" % (mnem.upper(), Name) 179 memFlags.append("Request::PREFETCH") 180 accCode = ''' 181 uint64_t temp = Mem%s;\n 182 temp = temp; 183 ''' % buildMemSuffix(sign, size) 184 else: 185 accCode = "IWDest = cSwap(Mem%s, ((CPSR)Cpsr).e);" % \ 186 buildMemSuffix(sign, size) 187 if writeback: 188 accCode += "Base = Base %s;\n" % offset 189 190 if not prefetch: 191 memFlags.append("ArmISA::TLB::AllowUnaligned") 192 193 base = buildMemBase("MemoryReg", post, writeback) 194 195 emitLoad(name, Name, False, eaCode, accCode, \ 196 memFlags, [], base) 197 198 def buildDoubleImmLoad(mnem, post, add, writeback, ldrex=False): 199 name = mnem 200 Name = loadDoubleImmClassName(post, add, writeback) 201 202 if add: 203 op = " +" 204 else: 205 op = " -" 206 207 offset = op + " imm" 208 eaCode = "EA = Base" 209 if not post: 210 eaCode += offset 211 eaCode += ";" 212 213 accCode = ''' 214 CPSR cpsr = Cpsr; 215 Dest = cSwap<uint32_t>(Mem.ud, cpsr.e); 216 Dest2 = cSwap<uint32_t>(Mem.ud >> 32, cpsr.e); 217 ''' 218 if ldrex: 219 memFlags = ["Request::LLSC"] 220 Name = "%s_%s" % (mnem.upper(), Name) 221 else: 222 memFlags = [] 223 if writeback: 224 accCode += "Base = Base %s;\n" % offset 225 base = buildMemBase("MemoryDImm", post, writeback) 226 227 memFlags.extend(["ArmISA::TLB::MustBeOne", 228 "ArmISA::TLB::AlignWord"]) 229 230 emitLoad(name, Name, True, eaCode, accCode, \ 231 memFlags, [], base, double=True) 232 233 def buildDoubleRegLoad(mnem, post, add, writeback): 234 name = mnem 235 Name = loadDoubleRegClassName(post, add, writeback) 236 237 if add: 238 op = " +" 239 else: 240 op = " -" 241 242 offset = op + " shift_rm_imm(Index, shiftAmt," + \ 243 " shiftType, CondCodes<29:>)" 244 eaCode = "EA = Base" 245 if not post: 246 eaCode += offset 247 eaCode += ";" 248 249 accCode = ''' 250 CPSR cpsr = Cpsr; 251 Dest = cSwap<uint32_t>(Mem.ud, cpsr.e); 252 Dest2 = cSwap<uint32_t>(Mem.ud >> 32, cpsr.e); 253 ''' 254 if writeback: 255 accCode += "Base = Base %s;\n" % offset 256 base = buildMemBase("MemoryDReg", post, writeback) 257 258 emitLoad(name, Name, False, eaCode, accCode, 259 ["ArmISA::TLB::MustBeOne", "ArmISA::TLB::AlignWord"], 260 [], base, double=True) 261 262 def buildLoads(mnem, size=4, sign=False, user=False): 263 buildImmLoad(mnem, True, True, True, size, sign, user) 264 buildRegLoad(mnem, True, True, True, size, sign, user) 265 buildImmLoad(mnem, True, False, True, size, sign, user) 266 buildRegLoad(mnem, True, False, True, size, sign, user) 267 buildImmLoad(mnem, False, True, True, size, sign, user) 268 buildRegLoad(mnem, False, True, True, size, sign, user) 269 buildImmLoad(mnem, False, False, True, size, sign, user) 270 buildRegLoad(mnem, False, False, True, size, sign, user) 271 buildImmLoad(mnem, False, True, False, size, sign, user) 272 buildRegLoad(mnem, False, True, False, size, sign, user) 273 buildImmLoad(mnem, False, False, False, size, sign, user) 274 buildRegLoad(mnem, False, False, False, size, sign, user) 275 276 def buildDoubleLoads(mnem): 277 buildDoubleImmLoad(mnem, True, True, True) 278 buildDoubleRegLoad(mnem, True, True, True) 279 buildDoubleImmLoad(mnem, True, False, True) 280 buildDoubleRegLoad(mnem, True, False, True) 281 buildDoubleImmLoad(mnem, False, True, True) 282 buildDoubleRegLoad(mnem, False, True, True) 283 buildDoubleImmLoad(mnem, False, False, True) 284 buildDoubleRegLoad(mnem, False, False, True) 285 buildDoubleImmLoad(mnem, False, True, False) 286 buildDoubleRegLoad(mnem, False, True, False) 287 buildDoubleImmLoad(mnem, False, False, False) 288 buildDoubleRegLoad(mnem, False, False, False) 289 290 def buildRfeLoads(mnem): 291 buildRfeLoad(mnem, True, True, True) 292 buildRfeLoad(mnem, True, True, False) 293 buildRfeLoad(mnem, True, False, True) 294 buildRfeLoad(mnem, True, False, False) 295 buildRfeLoad(mnem, False, True, True) 296 buildRfeLoad(mnem, False, True, False) 297 buildRfeLoad(mnem, False, False, True) 298 buildRfeLoad(mnem, False, False, False) 299 300 def buildPrefetches(mnem): 301 buildRegLoad(mnem, False, False, False, size=1, prefetch=True) 302 buildImmLoad(mnem, False, False, False, size=1, prefetch=True) 303 buildRegLoad(mnem, False, True, False, size=1, prefetch=True) 304 buildImmLoad(mnem, False, True, False, size=1, prefetch=True) 305 306 buildLoads("ldr") 307 buildLoads("ldrt", user=True) 308 buildLoads("ldrb", size=1) 309 buildLoads("ldrbt", size=1, user=True) 310 buildLoads("ldrsb", size=1, sign=True) 311 buildLoads("ldrsbt", size=1, sign=True, user=True) 312 buildLoads("ldrh", size=2) 313 buildLoads("ldrht", size=2, user=True) 314 buildLoads("hdrsh", size=2, sign=True) 315 buildLoads("ldrsht", size=2, sign=True, user=True) 316 317 buildDoubleLoads("ldrd") 318 319 buildRfeLoads("rfe") 320 321 buildPrefetches("pld") 322 buildPrefetches("pldw") 323 buildPrefetches("pli") 324 325 buildImmLoad("ldrex", False, True, False, size=4, ldrex=True) 326 buildImmLoad("ldrexh", False, True, False, size=2, ldrex=True) 327 buildImmLoad("ldrexb", False, True, False, size=1, ldrex=True) 328 buildDoubleImmLoad("ldrexd", False, True, False, ldrex=True) 329}};
|