ldr.isa (7648:3e561a5c0456) ldr.isa (7720:65d338a8dba4)
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 class LoadInst(LoadStoreInst):
47 execBase = 'Load'
48
49 def __init__(self, mnem, post, add, writeback,
50 size=4, sign=False, user=False, flavor="normal"):
51 super(LoadInst, self).__init__()
52
53 self.name = mnem
54 self.post = post
55 self.add = add
56 self.writeback = writeback
57 self.size = size
58 self.sign = sign
59 self.user = user
60 self.flavor = flavor
61
62 if self.add:
63 self.op = " +"
64 else:
65 self.op = " -"
66
67 self.memFlags = ["ArmISA::TLB::MustBeOne"]
68 self.codeBlobs = {"postacc_code" : ""}
69
70 def emitHelper(self, base = 'Memory', wbDecl = None, instFlags = []):
71
72 global header_output, decoder_output, exec_output
73
74 codeBlobs = self.codeBlobs
75 codeBlobs["predicate_test"] = pickPredicate(codeBlobs)
76 (newHeader,
77 newDecoder,
78 newExec) = self.fillTemplates(self.name, self.Name, codeBlobs,
79 self.memFlags, instFlags, base, wbDecl)
80
81 header_output += newHeader
82 decoder_output += newDecoder
83 exec_output += newExec
84
85 class RfeInst(LoadInst):
86 decConstBase = 'Rfe'
87
88 def __init__(self, mnem, post, add, writeback):
89 super(RfeInst, self).__init__(mnem, post, add, writeback)
90 self.Name = "RFE_" + loadImmClassName(post, add, writeback, 8)
91
92 self.memFlags.append("ArmISA::TLB::AlignWord")
93
94 def emit(self):
95 offset = 0
96 if self.post != self.add:
97 offset += 4
98 if not self.add:
99 offset -= 8
100 self.codeBlobs["ea_code"] = "EA = Base + %d;" % offset
101
102 wbDiff = -8
103 if self.add:
104 wbDiff = 8
105 accCode = '''
106 CPSR cpsr = Cpsr;
107 SCTLR sctlr = Sctlr;
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 class LoadInst(LoadStoreInst):
47 execBase = 'Load'
48
49 def __init__(self, mnem, post, add, writeback,
50 size=4, sign=False, user=False, flavor="normal"):
51 super(LoadInst, self).__init__()
52
53 self.name = mnem
54 self.post = post
55 self.add = add
56 self.writeback = writeback
57 self.size = size
58 self.sign = sign
59 self.user = user
60 self.flavor = flavor
61
62 if self.add:
63 self.op = " +"
64 else:
65 self.op = " -"
66
67 self.memFlags = ["ArmISA::TLB::MustBeOne"]
68 self.codeBlobs = {"postacc_code" : ""}
69
70 def emitHelper(self, base = 'Memory', wbDecl = None, instFlags = []):
71
72 global header_output, decoder_output, exec_output
73
74 codeBlobs = self.codeBlobs
75 codeBlobs["predicate_test"] = pickPredicate(codeBlobs)
76 (newHeader,
77 newDecoder,
78 newExec) = self.fillTemplates(self.name, self.Name, codeBlobs,
79 self.memFlags, instFlags, base, wbDecl)
80
81 header_output += newHeader
82 decoder_output += newDecoder
83 exec_output += newExec
84
85 class RfeInst(LoadInst):
86 decConstBase = 'Rfe'
87
88 def __init__(self, mnem, post, add, writeback):
89 super(RfeInst, self).__init__(mnem, post, add, writeback)
90 self.Name = "RFE_" + loadImmClassName(post, add, writeback, 8)
91
92 self.memFlags.append("ArmISA::TLB::AlignWord")
93
94 def emit(self):
95 offset = 0
96 if self.post != self.add:
97 offset += 4
98 if not self.add:
99 offset -= 8
100 self.codeBlobs["ea_code"] = "EA = Base + %d;" % offset
101
102 wbDiff = -8
103 if self.add:
104 wbDiff = 8
105 accCode = '''
106 CPSR cpsr = Cpsr;
107 SCTLR sctlr = Sctlr;
108 NPC = cSwap<uint32_t>(Mem.ud, cpsr.e);
108 ArmISA::PCState pc = PCS;
109 pc.instNPC(cSwap<uint32_t>(Mem.ud, cpsr.e));
109 uint32_t newCpsr =
110 cpsrWriteByInstr(cpsr | CondCodes,
111 cSwap<uint32_t>(Mem.ud >> 32, cpsr.e),
112 0xF, true, sctlr.nmfi);
113 Cpsr = ~CondCodesMask & newCpsr;
110 uint32_t newCpsr =
111 cpsrWriteByInstr(cpsr | CondCodes,
112 cSwap<uint32_t>(Mem.ud >> 32, cpsr.e),
113 0xF, true, sctlr.nmfi);
114 Cpsr = ~CondCodesMask & newCpsr;
115 pc.nextThumb(((CPSR)newCpsr).t);
116 pc.nextJazelle(((CPSR)newCpsr).j);
117 PCS = pc;
114 CondCodes = CondCodesMask & newCpsr;
115 '''
116 self.codeBlobs["memacc_code"] = accCode
117
118 wbDecl = None
119 if self.writeback:
120 wbDecl = "MicroAddiUop(machInst, base, base, %d);" % wbDiff
121 self.emitHelper('RfeOp', wbDecl, ["IsSerializeAfter", "IsNonSpeculative"])
122
123 class LoadImmInst(LoadInst):
124 def __init__(self, *args, **kargs):
125 super(LoadImmInst, self).__init__(*args, **kargs)
126 self.offset = self.op + " imm"
127
128 if self.add:
129 self.wbDecl = "MicroAddiUop(machInst, base, base, imm);"
130 else:
131 self.wbDecl = "MicroSubiUop(machInst, base, base, imm);"
132
133 class LoadRegInst(LoadInst):
134 def __init__(self, *args, **kargs):
135 super(LoadRegInst, self).__init__(*args, **kargs)
136 self.offset = self.op + " shift_rm_imm(Index, shiftAmt," + \
137 " shiftType, CondCodes<29:>)"
138 if self.add:
139 self.wbDecl = '''
140 MicroAddUop(machInst, base, base, wbIndexReg, shiftAmt, shiftType);
141 '''
142 else:
143 self.wbDecl = '''
144 MicroSubUop(machInst, base, base, wbIndexReg, shiftAmt, shiftType);
145 '''
146
147 class LoadSingle(LoadInst):
148 def __init__(self, *args, **kargs):
149 super(LoadSingle, self).__init__(*args, **kargs)
150
151 # Build the default class name
152 self.Name = self.nameFunc(self.post, self.add, self.writeback,
153 self.size, self.sign, self.user)
154
155 # Add memory request flags where necessary
156 self.memFlags.append("%d" % (self.size - 1))
157 if self.user:
158 self.memFlags.append("ArmISA::TLB::UserMode")
159
160 if self.flavor == "prefetch":
161 self.memFlags.append("Request::PREFETCH")
162 elif self.flavor == "exclusive":
163 self.memFlags.append("Request::LLSC")
164 elif self.flavor == "normal":
165 self.memFlags.append("ArmISA::TLB::AllowUnaligned")
166
167 # Disambiguate the class name for different flavors of loads
168 if self.flavor != "normal":
169 self.Name = "%s_%s" % (self.name.upper(), self.Name)
170
171 def emit(self):
172 # Address compuation code
173 eaCode = "EA = Base"
174 if not self.post:
175 eaCode += self.offset
176 eaCode += ";"
177
178 if self.flavor == "fp":
179 eaCode += vfpEnabledCheckCode
180
181 self.codeBlobs["ea_code"] = eaCode
182
183 # Code that actually handles the access
184 if self.flavor == "prefetch":
185 accCode = 'uint64_t temp = Mem%s; temp = temp;'
186 elif self.flavor == "fp":
187 accCode = "FpDest.uw = cSwap(Mem%s, ((CPSR)Cpsr).e);\n"
188 else:
189 accCode = "IWDest = cSwap(Mem%s, ((CPSR)Cpsr).e);"
190 accCode = accCode % buildMemSuffix(self.sign, self.size)
191
192 self.codeBlobs["memacc_code"] = accCode
193
194 # Push it out to the output files
195 base = buildMemBase(self.basePrefix, self.post, self.writeback)
196 wbDecl = None
197 if self.writeback:
198 wbDecl = self.wbDecl
199 self.emitHelper(base, wbDecl)
200
201 def loadImmClassName(post, add, writeback, size=4, sign=False, user=False):
202 return memClassName("LOAD_IMM", post, add, writeback, size, sign, user)
203
204 class LoadImm(LoadImmInst, LoadSingle):
205 decConstBase = 'LoadImm'
206 basePrefix = 'MemoryImm'
207 nameFunc = staticmethod(loadImmClassName)
208
209 def loadRegClassName(post, add, writeback, size=4, sign=False, user=False):
210 return memClassName("LOAD_REG", post, add, writeback, size, sign, user)
211
212 class LoadReg(LoadRegInst, LoadSingle):
213 decConstBase = 'LoadReg'
214 basePrefix = 'MemoryReg'
215 nameFunc = staticmethod(loadRegClassName)
216
217 class LoadDouble(LoadInst):
218 def __init__(self, *args, **kargs):
219 super(LoadDouble, self).__init__(*args, **kargs)
220
221 # Build the default class name
222 self.Name = self.nameFunc(self.post, self.add, self.writeback)
223
224 # Add memory request flags where necessary
225 if self.flavor == "exclusive":
226 self.memFlags.append("Request::LLSC")
227 self.memFlags.append("ArmISA::TLB::AlignDoubleWord")
228 else:
229 self.memFlags.append("ArmISA::TLB::AlignWord")
230
231 # Disambiguate the class name for different flavors of loads
232 if self.flavor != "normal":
233 self.Name = "%s_%s" % (self.name.upper(), self.Name)
234
235 def emit(self):
236 # Address computation code
237 eaCode = "EA = Base"
238 if not self.post:
239 eaCode += self.offset
240 eaCode += ";"
241
242 if self.flavor == "fp":
243 eaCode += vfpEnabledCheckCode
244
245 self.codeBlobs["ea_code"] = eaCode
246
247 # Code that actually handles the access
248 if self.flavor != "fp":
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 else:
255 accCode = '''
256 uint64_t swappedMem = cSwap(Mem.ud, ((CPSR)Cpsr).e);
257 FpDest.uw = (uint32_t)swappedMem;
258 FpDest2.uw = (uint32_t)(swappedMem >> 32);
259 '''
260
261 self.codeBlobs["memacc_code"] = accCode
262
263 # Push it out to the output files
264 base = buildMemBase(self.basePrefix, self.post, self.writeback)
265 wbDecl = None
266 if self.writeback:
267 wbDecl = self.wbDecl
268 self.emitHelper(base, wbDecl)
269
270 def loadDoubleImmClassName(post, add, writeback):
271 return memClassName("LOAD_IMMD", post, add, writeback, 4, False, False)
272
273 class LoadDoubleImm(LoadImmInst, LoadDouble):
274 decConstBase = 'LoadStoreDImm'
275 basePrefix = 'MemoryDImm'
276 nameFunc = staticmethod(loadDoubleImmClassName)
277
278 def loadDoubleRegClassName(post, add, writeback):
279 return memClassName("LOAD_REGD", post, add, writeback, 4, False, False)
280
281 class LoadDoubleReg(LoadRegInst, LoadDouble):
282 decConstBase = 'LoadDReg'
283 basePrefix = 'MemoryDReg'
284 nameFunc = staticmethod(loadDoubleRegClassName)
285
286 def buildLoads(mnem, size=4, sign=False, user=False):
287 LoadImm(mnem, True, True, True, size, sign, user).emit()
288 LoadReg(mnem, True, True, True, size, sign, user).emit()
289 LoadImm(mnem, True, False, True, size, sign, user).emit()
290 LoadReg(mnem, True, False, True, size, sign, user).emit()
291 LoadImm(mnem, False, True, True, size, sign, user).emit()
292 LoadReg(mnem, False, True, True, size, sign, user).emit()
293 LoadImm(mnem, False, False, True, size, sign, user).emit()
294 LoadReg(mnem, False, False, True, size, sign, user).emit()
295 LoadImm(mnem, False, True, False, size, sign, user).emit()
296 LoadReg(mnem, False, True, False, size, sign, user).emit()
297 LoadImm(mnem, False, False, False, size, sign, user).emit()
298 LoadReg(mnem, False, False, False, size, sign, user).emit()
299
300 def buildDoubleLoads(mnem):
301 LoadDoubleImm(mnem, True, True, True).emit()
302 LoadDoubleReg(mnem, True, True, True).emit()
303 LoadDoubleImm(mnem, True, False, True).emit()
304 LoadDoubleReg(mnem, True, False, True).emit()
305 LoadDoubleImm(mnem, False, True, True).emit()
306 LoadDoubleReg(mnem, False, True, True).emit()
307 LoadDoubleImm(mnem, False, False, True).emit()
308 LoadDoubleReg(mnem, False, False, True).emit()
309 LoadDoubleImm(mnem, False, True, False).emit()
310 LoadDoubleReg(mnem, False, True, False).emit()
311 LoadDoubleImm(mnem, False, False, False).emit()
312 LoadDoubleReg(mnem, False, False, False).emit()
313
314 def buildRfeLoads(mnem):
315 RfeInst(mnem, True, True, True).emit()
316 RfeInst(mnem, True, True, False).emit()
317 RfeInst(mnem, True, False, True).emit()
318 RfeInst(mnem, True, False, False).emit()
319 RfeInst(mnem, False, True, True).emit()
320 RfeInst(mnem, False, True, False).emit()
321 RfeInst(mnem, False, False, True).emit()
322 RfeInst(mnem, False, False, False).emit()
323
324 def buildPrefetches(mnem):
325 LoadReg(mnem, False, False, False, size=1, flavor="prefetch").emit()
326 LoadImm(mnem, False, False, False, size=1, flavor="prefetch").emit()
327 LoadReg(mnem, False, True, False, size=1, flavor="prefetch").emit()
328 LoadImm(mnem, False, True, False, size=1, flavor="prefetch").emit()
329
330 buildLoads("ldr")
331 buildLoads("ldrt", user=True)
332 buildLoads("ldrb", size=1)
333 buildLoads("ldrbt", size=1, user=True)
334 buildLoads("ldrsb", size=1, sign=True)
335 buildLoads("ldrsbt", size=1, sign=True, user=True)
336 buildLoads("ldrh", size=2)
337 buildLoads("ldrht", size=2, user=True)
338 buildLoads("hdrsh", size=2, sign=True)
339 buildLoads("ldrsht", size=2, sign=True, user=True)
340
341 buildDoubleLoads("ldrd")
342
343 buildRfeLoads("rfe")
344
345 buildPrefetches("pld")
346 buildPrefetches("pldw")
347 buildPrefetches("pli")
348
349 LoadImm("ldrex", False, True, False, size=4, flavor="exclusive").emit()
350 LoadImm("ldrexh", False, True, False, size=2, flavor="exclusive").emit()
351 LoadImm("ldrexb", False, True, False, size=1, flavor="exclusive").emit()
352 LoadDoubleImm("ldrexd", False, True, False, flavor="exclusive").emit()
353
354 LoadImm("vldr", False, True, False, size=4, flavor="fp").emit()
355 LoadImm("vldr", False, False, False, size=4, flavor="fp").emit()
356 LoadDoubleImm("vldr", False, True, False, flavor="fp").emit()
357 LoadDoubleImm("vldr", False, False, False, flavor="fp").emit()
358}};
118 CondCodes = CondCodesMask & newCpsr;
119 '''
120 self.codeBlobs["memacc_code"] = accCode
121
122 wbDecl = None
123 if self.writeback:
124 wbDecl = "MicroAddiUop(machInst, base, base, %d);" % wbDiff
125 self.emitHelper('RfeOp', wbDecl, ["IsSerializeAfter", "IsNonSpeculative"])
126
127 class LoadImmInst(LoadInst):
128 def __init__(self, *args, **kargs):
129 super(LoadImmInst, self).__init__(*args, **kargs)
130 self.offset = self.op + " imm"
131
132 if self.add:
133 self.wbDecl = "MicroAddiUop(machInst, base, base, imm);"
134 else:
135 self.wbDecl = "MicroSubiUop(machInst, base, base, imm);"
136
137 class LoadRegInst(LoadInst):
138 def __init__(self, *args, **kargs):
139 super(LoadRegInst, self).__init__(*args, **kargs)
140 self.offset = self.op + " shift_rm_imm(Index, shiftAmt," + \
141 " shiftType, CondCodes<29:>)"
142 if self.add:
143 self.wbDecl = '''
144 MicroAddUop(machInst, base, base, wbIndexReg, shiftAmt, shiftType);
145 '''
146 else:
147 self.wbDecl = '''
148 MicroSubUop(machInst, base, base, wbIndexReg, shiftAmt, shiftType);
149 '''
150
151 class LoadSingle(LoadInst):
152 def __init__(self, *args, **kargs):
153 super(LoadSingle, self).__init__(*args, **kargs)
154
155 # Build the default class name
156 self.Name = self.nameFunc(self.post, self.add, self.writeback,
157 self.size, self.sign, self.user)
158
159 # Add memory request flags where necessary
160 self.memFlags.append("%d" % (self.size - 1))
161 if self.user:
162 self.memFlags.append("ArmISA::TLB::UserMode")
163
164 if self.flavor == "prefetch":
165 self.memFlags.append("Request::PREFETCH")
166 elif self.flavor == "exclusive":
167 self.memFlags.append("Request::LLSC")
168 elif self.flavor == "normal":
169 self.memFlags.append("ArmISA::TLB::AllowUnaligned")
170
171 # Disambiguate the class name for different flavors of loads
172 if self.flavor != "normal":
173 self.Name = "%s_%s" % (self.name.upper(), self.Name)
174
175 def emit(self):
176 # Address compuation code
177 eaCode = "EA = Base"
178 if not self.post:
179 eaCode += self.offset
180 eaCode += ";"
181
182 if self.flavor == "fp":
183 eaCode += vfpEnabledCheckCode
184
185 self.codeBlobs["ea_code"] = eaCode
186
187 # Code that actually handles the access
188 if self.flavor == "prefetch":
189 accCode = 'uint64_t temp = Mem%s; temp = temp;'
190 elif self.flavor == "fp":
191 accCode = "FpDest.uw = cSwap(Mem%s, ((CPSR)Cpsr).e);\n"
192 else:
193 accCode = "IWDest = cSwap(Mem%s, ((CPSR)Cpsr).e);"
194 accCode = accCode % buildMemSuffix(self.sign, self.size)
195
196 self.codeBlobs["memacc_code"] = accCode
197
198 # Push it out to the output files
199 base = buildMemBase(self.basePrefix, self.post, self.writeback)
200 wbDecl = None
201 if self.writeback:
202 wbDecl = self.wbDecl
203 self.emitHelper(base, wbDecl)
204
205 def loadImmClassName(post, add, writeback, size=4, sign=False, user=False):
206 return memClassName("LOAD_IMM", post, add, writeback, size, sign, user)
207
208 class LoadImm(LoadImmInst, LoadSingle):
209 decConstBase = 'LoadImm'
210 basePrefix = 'MemoryImm'
211 nameFunc = staticmethod(loadImmClassName)
212
213 def loadRegClassName(post, add, writeback, size=4, sign=False, user=False):
214 return memClassName("LOAD_REG", post, add, writeback, size, sign, user)
215
216 class LoadReg(LoadRegInst, LoadSingle):
217 decConstBase = 'LoadReg'
218 basePrefix = 'MemoryReg'
219 nameFunc = staticmethod(loadRegClassName)
220
221 class LoadDouble(LoadInst):
222 def __init__(self, *args, **kargs):
223 super(LoadDouble, self).__init__(*args, **kargs)
224
225 # Build the default class name
226 self.Name = self.nameFunc(self.post, self.add, self.writeback)
227
228 # Add memory request flags where necessary
229 if self.flavor == "exclusive":
230 self.memFlags.append("Request::LLSC")
231 self.memFlags.append("ArmISA::TLB::AlignDoubleWord")
232 else:
233 self.memFlags.append("ArmISA::TLB::AlignWord")
234
235 # Disambiguate the class name for different flavors of loads
236 if self.flavor != "normal":
237 self.Name = "%s_%s" % (self.name.upper(), self.Name)
238
239 def emit(self):
240 # Address computation code
241 eaCode = "EA = Base"
242 if not self.post:
243 eaCode += self.offset
244 eaCode += ";"
245
246 if self.flavor == "fp":
247 eaCode += vfpEnabledCheckCode
248
249 self.codeBlobs["ea_code"] = eaCode
250
251 # Code that actually handles the access
252 if self.flavor != "fp":
253 accCode = '''
254 CPSR cpsr = Cpsr;
255 Dest = cSwap<uint32_t>(Mem.ud, cpsr.e);
256 Dest2 = cSwap<uint32_t>(Mem.ud >> 32, cpsr.e);
257 '''
258 else:
259 accCode = '''
260 uint64_t swappedMem = cSwap(Mem.ud, ((CPSR)Cpsr).e);
261 FpDest.uw = (uint32_t)swappedMem;
262 FpDest2.uw = (uint32_t)(swappedMem >> 32);
263 '''
264
265 self.codeBlobs["memacc_code"] = accCode
266
267 # Push it out to the output files
268 base = buildMemBase(self.basePrefix, self.post, self.writeback)
269 wbDecl = None
270 if self.writeback:
271 wbDecl = self.wbDecl
272 self.emitHelper(base, wbDecl)
273
274 def loadDoubleImmClassName(post, add, writeback):
275 return memClassName("LOAD_IMMD", post, add, writeback, 4, False, False)
276
277 class LoadDoubleImm(LoadImmInst, LoadDouble):
278 decConstBase = 'LoadStoreDImm'
279 basePrefix = 'MemoryDImm'
280 nameFunc = staticmethod(loadDoubleImmClassName)
281
282 def loadDoubleRegClassName(post, add, writeback):
283 return memClassName("LOAD_REGD", post, add, writeback, 4, False, False)
284
285 class LoadDoubleReg(LoadRegInst, LoadDouble):
286 decConstBase = 'LoadDReg'
287 basePrefix = 'MemoryDReg'
288 nameFunc = staticmethod(loadDoubleRegClassName)
289
290 def buildLoads(mnem, size=4, sign=False, user=False):
291 LoadImm(mnem, True, True, True, size, sign, user).emit()
292 LoadReg(mnem, True, True, True, size, sign, user).emit()
293 LoadImm(mnem, True, False, True, size, sign, user).emit()
294 LoadReg(mnem, True, False, True, size, sign, user).emit()
295 LoadImm(mnem, False, True, True, size, sign, user).emit()
296 LoadReg(mnem, False, True, True, size, sign, user).emit()
297 LoadImm(mnem, False, False, True, size, sign, user).emit()
298 LoadReg(mnem, False, False, True, size, sign, user).emit()
299 LoadImm(mnem, False, True, False, size, sign, user).emit()
300 LoadReg(mnem, False, True, False, size, sign, user).emit()
301 LoadImm(mnem, False, False, False, size, sign, user).emit()
302 LoadReg(mnem, False, False, False, size, sign, user).emit()
303
304 def buildDoubleLoads(mnem):
305 LoadDoubleImm(mnem, True, True, True).emit()
306 LoadDoubleReg(mnem, True, True, True).emit()
307 LoadDoubleImm(mnem, True, False, True).emit()
308 LoadDoubleReg(mnem, True, False, True).emit()
309 LoadDoubleImm(mnem, False, True, True).emit()
310 LoadDoubleReg(mnem, False, True, True).emit()
311 LoadDoubleImm(mnem, False, False, True).emit()
312 LoadDoubleReg(mnem, False, False, True).emit()
313 LoadDoubleImm(mnem, False, True, False).emit()
314 LoadDoubleReg(mnem, False, True, False).emit()
315 LoadDoubleImm(mnem, False, False, False).emit()
316 LoadDoubleReg(mnem, False, False, False).emit()
317
318 def buildRfeLoads(mnem):
319 RfeInst(mnem, True, True, True).emit()
320 RfeInst(mnem, True, True, False).emit()
321 RfeInst(mnem, True, False, True).emit()
322 RfeInst(mnem, True, False, False).emit()
323 RfeInst(mnem, False, True, True).emit()
324 RfeInst(mnem, False, True, False).emit()
325 RfeInst(mnem, False, False, True).emit()
326 RfeInst(mnem, False, False, False).emit()
327
328 def buildPrefetches(mnem):
329 LoadReg(mnem, False, False, False, size=1, flavor="prefetch").emit()
330 LoadImm(mnem, False, False, False, size=1, flavor="prefetch").emit()
331 LoadReg(mnem, False, True, False, size=1, flavor="prefetch").emit()
332 LoadImm(mnem, False, True, False, size=1, flavor="prefetch").emit()
333
334 buildLoads("ldr")
335 buildLoads("ldrt", user=True)
336 buildLoads("ldrb", size=1)
337 buildLoads("ldrbt", size=1, user=True)
338 buildLoads("ldrsb", size=1, sign=True)
339 buildLoads("ldrsbt", size=1, sign=True, user=True)
340 buildLoads("ldrh", size=2)
341 buildLoads("ldrht", size=2, user=True)
342 buildLoads("hdrsh", size=2, sign=True)
343 buildLoads("ldrsht", size=2, sign=True, user=True)
344
345 buildDoubleLoads("ldrd")
346
347 buildRfeLoads("rfe")
348
349 buildPrefetches("pld")
350 buildPrefetches("pldw")
351 buildPrefetches("pli")
352
353 LoadImm("ldrex", False, True, False, size=4, flavor="exclusive").emit()
354 LoadImm("ldrexh", False, True, False, size=2, flavor="exclusive").emit()
355 LoadImm("ldrexb", False, True, False, size=1, flavor="exclusive").emit()
356 LoadDoubleImm("ldrexd", False, True, False, flavor="exclusive").emit()
357
358 LoadImm("vldr", False, True, False, size=4, flavor="fp").emit()
359 LoadImm("vldr", False, False, False, size=4, flavor="fp").emit()
360 LoadDoubleImm("vldr", False, True, False, flavor="fp").emit()
361 LoadDoubleImm("vldr", False, False, False, flavor="fp").emit()
362}};