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, memFlags, instFlags, base):
|
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,
|
69 memFlags, instFlags,
|
70 memFlags, instFlags, double, |
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 if prefetch: 96 Name = "%s_%s" % (mnem.upper(), Name) 97 memFlags = ["Request::PREFETCH"] 98 accCode = ''' 99 uint64_t temp = Mem%s;\n 100 temp = temp; 101 ''' % buildMemSuffix(sign, size) 102 else: 103 if ldrex: 104 memFlags = ["Request::LLSC"] 105 Name = "%s_%s" % (mnem.upper(), Name) 106 else: 107 memFlags = [] 108 accCode = "IWDest = Mem%s;\n" % buildMemSuffix(sign, size) 109 if writeback: 110 accCode += "Base = Base %s;\n" % offset 111 base = buildMemBase("MemoryImm", post, writeback) 112 113 emitLoad(name, Name, True, eaCode, accCode, memFlags, [], base) 114 115 def buildRegLoad(mnem, post, add, writeback, \ 116 size=4, sign=False, user=False, prefetch=False): 117 name = mnem 118 Name = loadRegClassName(post, add, writeback, 119 size, sign, user) 120 121 if add: 122 op = " +" 123 else: 124 op = " -" 125 126 offset = op + " shift_rm_imm(Index, shiftAmt," + \ 127 " shiftType, CondCodes<29:>)" 128 eaCode = "EA = Base" 129 if not post: 130 eaCode += offset 131 eaCode += ";" 132 133 if prefetch: 134 Name = "%s_%s" % (mnem.upper(), Name) 135 memFlags = ["Request::PREFETCH"] 136 accCode = ''' 137 uint64_t temp = Mem%s;\n 138 temp = temp; 139 ''' % buildMemSuffix(sign, size) 140 else: 141 memFlags = [] 142 accCode = "IWDest = Mem%s;\n" % buildMemSuffix(sign, size) 143 if writeback: 144 accCode += "Base = Base %s;\n" % offset 145 base = buildMemBase("MemoryReg", post, writeback) 146
|
146 emitLoad(name, Name, False, eaCode, accCode, memFlags, [], base)
|
147 emitLoad(name, Name, False, eaCode, accCode, \ 148 memFlags, [], base) |
149 150 def buildDoubleImmLoad(mnem, post, add, writeback, ldrex=False): 151 name = mnem 152 Name = loadDoubleImmClassName(post, add, writeback) 153 154 if add: 155 op = " +" 156 else: 157 op = " -" 158 159 offset = op + " imm" 160 eaCode = "EA = Base" 161 if not post: 162 eaCode += offset 163 eaCode += ";" 164 165 accCode = '''
|
164 Rdo = bits(Mem.ud, 31, 0);
165 Rde = bits(Mem.ud, 63, 32);
|
166 Dest = bits(Mem.ud, 31, 0); 167 Dest2 = bits(Mem.ud, 63, 32); |
168 ''' 169 if ldrex: 170 memFlags = ["Request::LLSC"] 171 Name = "%s_%s" % (mnem.upper(), Name) 172 else: 173 memFlags = [] 174 if writeback: 175 accCode += "Base = Base %s;\n" % offset
|
174 base = buildMemBase("MemoryImm", post, writeback)
|
176 base = buildMemBase("MemoryDImm", post, writeback) |
177
|
176 emitLoad(name, Name, True, eaCode, accCode, memFlags, [], base)
|
178 emitLoad(name, Name, True, eaCode, accCode, \ 179 memFlags, [], base, double=True) |
180 181 def buildDoubleRegLoad(mnem, post, add, writeback): 182 name = mnem 183 Name = loadDoubleRegClassName(post, add, writeback) 184 185 if add: 186 op = " +" 187 else: 188 op = " -" 189 190 offset = op + " shift_rm_imm(Index, shiftAmt," + \ 191 " shiftType, CondCodes<29:>)" 192 eaCode = "EA = Base" 193 if not post: 194 eaCode += offset 195 eaCode += ";" 196 197 accCode = '''
|
195 Rdo = bits(Mem.ud, 31, 0);
196 Rde = bits(Mem.ud, 63, 32);
|
198 Dest = bits(Mem.ud, 31, 0); 199 Dest2 = bits(Mem.ud, 63, 32); |
200 ''' 201 if writeback: 202 accCode += "Base = Base %s;\n" % offset
|
200 base = buildMemBase("MemoryReg", post, writeback)
|
203 base = buildMemBase("MemoryDReg", post, writeback) |
204
|
202 emitLoad(name, Name, False, eaCode, accCode, [], [], base)
|
205 emitLoad(name, Name, False, eaCode, accCode, 206 [], [], base, double=True) |
207 208 def buildLoads(mnem, size=4, sign=False, user=False): 209 buildImmLoad(mnem, True, True, True, size, sign, user) 210 buildRegLoad(mnem, True, True, True, size, sign, user) 211 buildImmLoad(mnem, True, False, True, size, sign, user) 212 buildRegLoad(mnem, True, False, True, size, sign, user) 213 buildImmLoad(mnem, False, True, True, size, sign, user) 214 buildRegLoad(mnem, False, True, True, size, sign, user) 215 buildImmLoad(mnem, False, False, True, size, sign, user) 216 buildRegLoad(mnem, False, False, True, size, sign, user) 217 buildImmLoad(mnem, False, True, False, size, sign, user) 218 buildRegLoad(mnem, False, True, False, size, sign, user) 219 buildImmLoad(mnem, False, False, False, size, sign, user) 220 buildRegLoad(mnem, False, False, False, size, sign, user) 221 222 def buildDoubleLoads(mnem): 223 buildDoubleImmLoad(mnem, True, True, True) 224 buildDoubleRegLoad(mnem, True, True, True) 225 buildDoubleImmLoad(mnem, True, False, True) 226 buildDoubleRegLoad(mnem, True, False, True) 227 buildDoubleImmLoad(mnem, False, True, True) 228 buildDoubleRegLoad(mnem, False, True, True) 229 buildDoubleImmLoad(mnem, False, False, True) 230 buildDoubleRegLoad(mnem, False, False, True) 231 buildDoubleImmLoad(mnem, False, True, False) 232 buildDoubleRegLoad(mnem, False, True, False) 233 buildDoubleImmLoad(mnem, False, False, False) 234 buildDoubleRegLoad(mnem, False, False, False) 235 236 def buildPrefetches(mnem): 237 buildRegLoad(mnem, False, False, False, size=1, prefetch=True) 238 buildImmLoad(mnem, False, False, False, size=1, prefetch=True) 239 buildRegLoad(mnem, False, True, False, size=1, prefetch=True) 240 buildImmLoad(mnem, False, True, False, size=1, prefetch=True) 241 242 buildLoads("ldr") 243 buildLoads("ldrt", user=True) 244 buildLoads("ldrb", size=1) 245 buildLoads("ldrbt", size=1, user=True) 246 buildLoads("ldrsb", size=1, sign=True) 247 buildLoads("ldrsbt", size=1, sign=True, user=True) 248 buildLoads("ldrh", size=2) 249 buildLoads("ldrht", size=2, user=True) 250 buildLoads("hdrsh", size=2, sign=True) 251 buildLoads("ldrsht", size=2, sign=True, user=True) 252 253 buildDoubleLoads("ldrd") 254 255 buildPrefetches("pld") 256 buildPrefetches("pldw") 257 buildPrefetches("pli") 258 259 buildImmLoad("ldrex", False, True, False, size=4, ldrex=True) 260 buildImmLoad("ldrexh", False, True, False, size=2, ldrex=True) 261 buildImmLoad("ldrexb", False, True, False, size=1, ldrex=True) 262 buildDoubleImmLoad("ldrexd", False, True, False, ldrex=True) 263}};
|