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