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