ldr.isa (7725:00ea9430643b) ldr.isa (7797:998b217dcae7)
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 ArmISA::PCState pc = PCS;
109 pc.instNPC(cSwap<uint32_t>(Mem.ud, cpsr.e));
108 // Use the version of NPC that gets set before NextThumb
109 pNPC = cSwap<uint32_t>(Mem.ud, cpsr.e);
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;
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;
115 NextThumb = ((CPSR)newCpsr).t;
116 NextJazelle = ((CPSR)newCpsr).j;
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 self.instFlags = []
165 if self.flavor == "dprefetch":
166 self.memFlags.append("Request::PREFETCH")
167 self.instFlags = ['IsDataPrefetch']
168 elif self.flavor == "iprefetch":
169 self.memFlags.append("Request::PREFETCH")
170 self.instFlags = ['IsInstPrefetch']
171 elif self.flavor == "exclusive":
172 self.memFlags.append("Request::LLSC")
173 elif self.flavor == "normal":
174 self.memFlags.append("ArmISA::TLB::AllowUnaligned")
175
176 # Disambiguate the class name for different flavors of loads
177 if self.flavor != "normal":
178 self.Name = "%s_%s" % (self.name.upper(), self.Name)
179
180 def emit(self):
181 # Address compuation code
182 eaCode = "EA = Base"
183 if not self.post:
184 eaCode += self.offset
185 eaCode += ";"
186
187 if self.flavor == "fp":
188 eaCode += vfpEnabledCheckCode
189
190 self.codeBlobs["ea_code"] = eaCode
191
192 # Code that actually handles the access
193 if self.flavor == "dprefetch" or self.flavor == "iprefetch":
194 accCode = 'uint64_t temp = Mem%s; temp = temp;'
195 elif self.flavor == "fp":
196 accCode = "FpDest.uw = cSwap(Mem%s, ((CPSR)Cpsr).e);\n"
197 else:
198 accCode = "IWDest = cSwap(Mem%s, ((CPSR)Cpsr).e);"
199 accCode = accCode % buildMemSuffix(self.sign, self.size)
200
201 self.codeBlobs["memacc_code"] = accCode
202
203 # Push it out to the output files
204 base = buildMemBase(self.basePrefix, self.post, self.writeback)
205 wbDecl = None
206 if self.writeback:
207 wbDecl = self.wbDecl
208 self.emitHelper(base, wbDecl, self.instFlags)
209
210 def loadImmClassName(post, add, writeback, size=4, sign=False, user=False):
211 return memClassName("LOAD_IMM", post, add, writeback, size, sign, user)
212
213 class LoadImm(LoadImmInst, LoadSingle):
214 decConstBase = 'LoadImm'
215 basePrefix = 'MemoryImm'
216 nameFunc = staticmethod(loadImmClassName)
217
218 def loadRegClassName(post, add, writeback, size=4, sign=False, user=False):
219 return memClassName("LOAD_REG", post, add, writeback, size, sign, user)
220
221 class LoadReg(LoadRegInst, LoadSingle):
222 decConstBase = 'LoadReg'
223 basePrefix = 'MemoryReg'
224 nameFunc = staticmethod(loadRegClassName)
225
226 class LoadDouble(LoadInst):
227 def __init__(self, *args, **kargs):
228 super(LoadDouble, self).__init__(*args, **kargs)
229
230 # Build the default class name
231 self.Name = self.nameFunc(self.post, self.add, self.writeback)
232
233 # Add memory request flags where necessary
234 if self.flavor == "exclusive":
235 self.memFlags.append("Request::LLSC")
236 self.memFlags.append("ArmISA::TLB::AlignDoubleWord")
237 else:
238 self.memFlags.append("ArmISA::TLB::AlignWord")
239
240 # Disambiguate the class name for different flavors of loads
241 if self.flavor != "normal":
242 self.Name = "%s_%s" % (self.name.upper(), self.Name)
243
244 def emit(self):
245 # Address computation code
246 eaCode = "EA = Base"
247 if not self.post:
248 eaCode += self.offset
249 eaCode += ";"
250
251 if self.flavor == "fp":
252 eaCode += vfpEnabledCheckCode
253
254 self.codeBlobs["ea_code"] = eaCode
255
256 # Code that actually handles the access
257 if self.flavor != "fp":
258 accCode = '''
259 CPSR cpsr = Cpsr;
260 Dest = cSwap<uint32_t>(Mem.ud, cpsr.e);
261 Dest2 = cSwap<uint32_t>(Mem.ud >> 32, cpsr.e);
262 '''
263 else:
264 accCode = '''
265 uint64_t swappedMem = cSwap(Mem.ud, ((CPSR)Cpsr).e);
266 FpDest.uw = (uint32_t)swappedMem;
267 FpDest2.uw = (uint32_t)(swappedMem >> 32);
268 '''
269
270 self.codeBlobs["memacc_code"] = accCode
271
272 # Push it out to the output files
273 base = buildMemBase(self.basePrefix, self.post, self.writeback)
274 wbDecl = None
275 if self.writeback:
276 wbDecl = self.wbDecl
277 self.emitHelper(base, wbDecl)
278
279 def loadDoubleImmClassName(post, add, writeback):
280 return memClassName("LOAD_IMMD", post, add, writeback, 4, False, False)
281
282 class LoadDoubleImm(LoadImmInst, LoadDouble):
283 decConstBase = 'LoadStoreDImm'
284 basePrefix = 'MemoryDImm'
285 nameFunc = staticmethod(loadDoubleImmClassName)
286
287 def loadDoubleRegClassName(post, add, writeback):
288 return memClassName("LOAD_REGD", post, add, writeback, 4, False, False)
289
290 class LoadDoubleReg(LoadRegInst, LoadDouble):
291 decConstBase = 'LoadDReg'
292 basePrefix = 'MemoryDReg'
293 nameFunc = staticmethod(loadDoubleRegClassName)
294
295 def buildLoads(mnem, size=4, sign=False, user=False):
296 LoadImm(mnem, True, True, True, size, sign, user).emit()
297 LoadReg(mnem, True, True, True, size, sign, user).emit()
298 LoadImm(mnem, True, False, True, size, sign, user).emit()
299 LoadReg(mnem, True, False, True, size, sign, user).emit()
300 LoadImm(mnem, False, True, True, size, sign, user).emit()
301 LoadReg(mnem, False, True, True, size, sign, user).emit()
302 LoadImm(mnem, False, False, True, size, sign, user).emit()
303 LoadReg(mnem, False, False, True, size, sign, user).emit()
304 LoadImm(mnem, False, True, False, size, sign, user).emit()
305 LoadReg(mnem, False, True, False, size, sign, user).emit()
306 LoadImm(mnem, False, False, False, size, sign, user).emit()
307 LoadReg(mnem, False, False, False, size, sign, user).emit()
308
309 def buildDoubleLoads(mnem):
310 LoadDoubleImm(mnem, True, True, True).emit()
311 LoadDoubleReg(mnem, True, True, True).emit()
312 LoadDoubleImm(mnem, True, False, True).emit()
313 LoadDoubleReg(mnem, True, False, True).emit()
314 LoadDoubleImm(mnem, False, True, True).emit()
315 LoadDoubleReg(mnem, False, True, True).emit()
316 LoadDoubleImm(mnem, False, False, True).emit()
317 LoadDoubleReg(mnem, False, False, True).emit()
318 LoadDoubleImm(mnem, False, True, False).emit()
319 LoadDoubleReg(mnem, False, True, False).emit()
320 LoadDoubleImm(mnem, False, False, False).emit()
321 LoadDoubleReg(mnem, False, False, False).emit()
322
323 def buildRfeLoads(mnem):
324 RfeInst(mnem, True, True, True).emit()
325 RfeInst(mnem, True, True, False).emit()
326 RfeInst(mnem, True, False, True).emit()
327 RfeInst(mnem, True, False, False).emit()
328 RfeInst(mnem, False, True, True).emit()
329 RfeInst(mnem, False, True, False).emit()
330 RfeInst(mnem, False, False, True).emit()
331 RfeInst(mnem, False, False, False).emit()
332
333 def buildPrefetches(mnem, type):
334 LoadReg(mnem, False, False, False, size=1, flavor=type).emit()
335 LoadImm(mnem, False, False, False, size=1, flavor=type).emit()
336 LoadReg(mnem, False, True, False, size=1, flavor=type).emit()
337 LoadImm(mnem, False, True, False, size=1, flavor=type).emit()
338
339 buildLoads("ldr")
340 buildLoads("ldrt", user=True)
341 buildLoads("ldrb", size=1)
342 buildLoads("ldrbt", size=1, user=True)
343 buildLoads("ldrsb", size=1, sign=True)
344 buildLoads("ldrsbt", size=1, sign=True, user=True)
345 buildLoads("ldrh", size=2)
346 buildLoads("ldrht", size=2, user=True)
347 buildLoads("hdrsh", size=2, sign=True)
348 buildLoads("ldrsht", size=2, sign=True, user=True)
349
350 buildDoubleLoads("ldrd")
351
352 buildRfeLoads("rfe")
353
354 buildPrefetches("pld", "dprefetch")
355 buildPrefetches("pldw", "dprefetch")
356 buildPrefetches("pli", "iprefetch")
357
358 LoadImm("ldrex", False, True, False, size=4, flavor="exclusive").emit()
359 LoadImm("ldrexh", False, True, False, size=2, flavor="exclusive").emit()
360 LoadImm("ldrexb", False, True, False, size=1, flavor="exclusive").emit()
361 LoadDoubleImm("ldrexd", False, True, False, flavor="exclusive").emit()
362
363 LoadImm("vldr", False, True, False, size=4, flavor="fp").emit()
364 LoadImm("vldr", False, False, False, size=4, flavor="fp").emit()
365 LoadDoubleImm("vldr", False, True, False, flavor="fp").emit()
366 LoadDoubleImm("vldr", False, False, False, flavor="fp").emit()
367}};
117 CondCodes = CondCodesMask & newCpsr;
118 '''
119 self.codeBlobs["memacc_code"] = accCode
120
121 wbDecl = None
122 if self.writeback:
123 wbDecl = "MicroAddiUop(machInst, base, base, %d);" % wbDiff
124 self.emitHelper('RfeOp', wbDecl, ["IsSerializeAfter", "IsNonSpeculative"])
125
126 class LoadImmInst(LoadInst):
127 def __init__(self, *args, **kargs):
128 super(LoadImmInst, self).__init__(*args, **kargs)
129 self.offset = self.op + " imm"
130
131 if self.add:
132 self.wbDecl = "MicroAddiUop(machInst, base, base, imm);"
133 else:
134 self.wbDecl = "MicroSubiUop(machInst, base, base, imm);"
135
136 class LoadRegInst(LoadInst):
137 def __init__(self, *args, **kargs):
138 super(LoadRegInst, self).__init__(*args, **kargs)
139 self.offset = self.op + " shift_rm_imm(Index, shiftAmt," + \
140 " shiftType, CondCodes<29:>)"
141 if self.add:
142 self.wbDecl = '''
143 MicroAddUop(machInst, base, base, wbIndexReg, shiftAmt, shiftType);
144 '''
145 else:
146 self.wbDecl = '''
147 MicroSubUop(machInst, base, base, wbIndexReg, shiftAmt, shiftType);
148 '''
149
150 class LoadSingle(LoadInst):
151 def __init__(self, *args, **kargs):
152 super(LoadSingle, self).__init__(*args, **kargs)
153
154 # Build the default class name
155 self.Name = self.nameFunc(self.post, self.add, self.writeback,
156 self.size, self.sign, self.user)
157
158 # Add memory request flags where necessary
159 self.memFlags.append("%d" % (self.size - 1))
160 if self.user:
161 self.memFlags.append("ArmISA::TLB::UserMode")
162
163 self.instFlags = []
164 if self.flavor == "dprefetch":
165 self.memFlags.append("Request::PREFETCH")
166 self.instFlags = ['IsDataPrefetch']
167 elif self.flavor == "iprefetch":
168 self.memFlags.append("Request::PREFETCH")
169 self.instFlags = ['IsInstPrefetch']
170 elif self.flavor == "exclusive":
171 self.memFlags.append("Request::LLSC")
172 elif self.flavor == "normal":
173 self.memFlags.append("ArmISA::TLB::AllowUnaligned")
174
175 # Disambiguate the class name for different flavors of loads
176 if self.flavor != "normal":
177 self.Name = "%s_%s" % (self.name.upper(), self.Name)
178
179 def emit(self):
180 # Address compuation code
181 eaCode = "EA = Base"
182 if not self.post:
183 eaCode += self.offset
184 eaCode += ";"
185
186 if self.flavor == "fp":
187 eaCode += vfpEnabledCheckCode
188
189 self.codeBlobs["ea_code"] = eaCode
190
191 # Code that actually handles the access
192 if self.flavor == "dprefetch" or self.flavor == "iprefetch":
193 accCode = 'uint64_t temp = Mem%s; temp = temp;'
194 elif self.flavor == "fp":
195 accCode = "FpDest.uw = cSwap(Mem%s, ((CPSR)Cpsr).e);\n"
196 else:
197 accCode = "IWDest = cSwap(Mem%s, ((CPSR)Cpsr).e);"
198 accCode = accCode % buildMemSuffix(self.sign, self.size)
199
200 self.codeBlobs["memacc_code"] = accCode
201
202 # Push it out to the output files
203 base = buildMemBase(self.basePrefix, self.post, self.writeback)
204 wbDecl = None
205 if self.writeback:
206 wbDecl = self.wbDecl
207 self.emitHelper(base, wbDecl, self.instFlags)
208
209 def loadImmClassName(post, add, writeback, size=4, sign=False, user=False):
210 return memClassName("LOAD_IMM", post, add, writeback, size, sign, user)
211
212 class LoadImm(LoadImmInst, LoadSingle):
213 decConstBase = 'LoadImm'
214 basePrefix = 'MemoryImm'
215 nameFunc = staticmethod(loadImmClassName)
216
217 def loadRegClassName(post, add, writeback, size=4, sign=False, user=False):
218 return memClassName("LOAD_REG", post, add, writeback, size, sign, user)
219
220 class LoadReg(LoadRegInst, LoadSingle):
221 decConstBase = 'LoadReg'
222 basePrefix = 'MemoryReg'
223 nameFunc = staticmethod(loadRegClassName)
224
225 class LoadDouble(LoadInst):
226 def __init__(self, *args, **kargs):
227 super(LoadDouble, self).__init__(*args, **kargs)
228
229 # Build the default class name
230 self.Name = self.nameFunc(self.post, self.add, self.writeback)
231
232 # Add memory request flags where necessary
233 if self.flavor == "exclusive":
234 self.memFlags.append("Request::LLSC")
235 self.memFlags.append("ArmISA::TLB::AlignDoubleWord")
236 else:
237 self.memFlags.append("ArmISA::TLB::AlignWord")
238
239 # Disambiguate the class name for different flavors of loads
240 if self.flavor != "normal":
241 self.Name = "%s_%s" % (self.name.upper(), self.Name)
242
243 def emit(self):
244 # Address computation code
245 eaCode = "EA = Base"
246 if not self.post:
247 eaCode += self.offset
248 eaCode += ";"
249
250 if self.flavor == "fp":
251 eaCode += vfpEnabledCheckCode
252
253 self.codeBlobs["ea_code"] = eaCode
254
255 # Code that actually handles the access
256 if self.flavor != "fp":
257 accCode = '''
258 CPSR cpsr = Cpsr;
259 Dest = cSwap<uint32_t>(Mem.ud, cpsr.e);
260 Dest2 = cSwap<uint32_t>(Mem.ud >> 32, cpsr.e);
261 '''
262 else:
263 accCode = '''
264 uint64_t swappedMem = cSwap(Mem.ud, ((CPSR)Cpsr).e);
265 FpDest.uw = (uint32_t)swappedMem;
266 FpDest2.uw = (uint32_t)(swappedMem >> 32);
267 '''
268
269 self.codeBlobs["memacc_code"] = accCode
270
271 # Push it out to the output files
272 base = buildMemBase(self.basePrefix, self.post, self.writeback)
273 wbDecl = None
274 if self.writeback:
275 wbDecl = self.wbDecl
276 self.emitHelper(base, wbDecl)
277
278 def loadDoubleImmClassName(post, add, writeback):
279 return memClassName("LOAD_IMMD", post, add, writeback, 4, False, False)
280
281 class LoadDoubleImm(LoadImmInst, LoadDouble):
282 decConstBase = 'LoadStoreDImm'
283 basePrefix = 'MemoryDImm'
284 nameFunc = staticmethod(loadDoubleImmClassName)
285
286 def loadDoubleRegClassName(post, add, writeback):
287 return memClassName("LOAD_REGD", post, add, writeback, 4, False, False)
288
289 class LoadDoubleReg(LoadRegInst, LoadDouble):
290 decConstBase = 'LoadDReg'
291 basePrefix = 'MemoryDReg'
292 nameFunc = staticmethod(loadDoubleRegClassName)
293
294 def buildLoads(mnem, size=4, sign=False, user=False):
295 LoadImm(mnem, True, True, True, size, sign, user).emit()
296 LoadReg(mnem, True, True, True, size, sign, user).emit()
297 LoadImm(mnem, True, False, True, size, sign, user).emit()
298 LoadReg(mnem, True, False, True, size, sign, user).emit()
299 LoadImm(mnem, False, True, True, size, sign, user).emit()
300 LoadReg(mnem, False, True, True, size, sign, user).emit()
301 LoadImm(mnem, False, False, True, size, sign, user).emit()
302 LoadReg(mnem, False, False, True, size, sign, user).emit()
303 LoadImm(mnem, False, True, False, size, sign, user).emit()
304 LoadReg(mnem, False, True, False, size, sign, user).emit()
305 LoadImm(mnem, False, False, False, size, sign, user).emit()
306 LoadReg(mnem, False, False, False, size, sign, user).emit()
307
308 def buildDoubleLoads(mnem):
309 LoadDoubleImm(mnem, True, True, True).emit()
310 LoadDoubleReg(mnem, True, True, True).emit()
311 LoadDoubleImm(mnem, True, False, True).emit()
312 LoadDoubleReg(mnem, True, False, True).emit()
313 LoadDoubleImm(mnem, False, True, True).emit()
314 LoadDoubleReg(mnem, False, True, True).emit()
315 LoadDoubleImm(mnem, False, False, True).emit()
316 LoadDoubleReg(mnem, False, False, True).emit()
317 LoadDoubleImm(mnem, False, True, False).emit()
318 LoadDoubleReg(mnem, False, True, False).emit()
319 LoadDoubleImm(mnem, False, False, False).emit()
320 LoadDoubleReg(mnem, False, False, False).emit()
321
322 def buildRfeLoads(mnem):
323 RfeInst(mnem, True, True, True).emit()
324 RfeInst(mnem, True, True, False).emit()
325 RfeInst(mnem, True, False, True).emit()
326 RfeInst(mnem, True, False, False).emit()
327 RfeInst(mnem, False, True, True).emit()
328 RfeInst(mnem, False, True, False).emit()
329 RfeInst(mnem, False, False, True).emit()
330 RfeInst(mnem, False, False, False).emit()
331
332 def buildPrefetches(mnem, type):
333 LoadReg(mnem, False, False, False, size=1, flavor=type).emit()
334 LoadImm(mnem, False, False, False, size=1, flavor=type).emit()
335 LoadReg(mnem, False, True, False, size=1, flavor=type).emit()
336 LoadImm(mnem, False, True, False, size=1, flavor=type).emit()
337
338 buildLoads("ldr")
339 buildLoads("ldrt", user=True)
340 buildLoads("ldrb", size=1)
341 buildLoads("ldrbt", size=1, user=True)
342 buildLoads("ldrsb", size=1, sign=True)
343 buildLoads("ldrsbt", size=1, sign=True, user=True)
344 buildLoads("ldrh", size=2)
345 buildLoads("ldrht", size=2, user=True)
346 buildLoads("hdrsh", size=2, sign=True)
347 buildLoads("ldrsht", size=2, sign=True, user=True)
348
349 buildDoubleLoads("ldrd")
350
351 buildRfeLoads("rfe")
352
353 buildPrefetches("pld", "dprefetch")
354 buildPrefetches("pldw", "dprefetch")
355 buildPrefetches("pli", "iprefetch")
356
357 LoadImm("ldrex", False, True, False, size=4, flavor="exclusive").emit()
358 LoadImm("ldrexh", False, True, False, size=2, flavor="exclusive").emit()
359 LoadImm("ldrexb", False, True, False, size=1, flavor="exclusive").emit()
360 LoadDoubleImm("ldrexd", False, True, False, flavor="exclusive").emit()
361
362 LoadImm("vldr", False, True, False, size=4, flavor="fp").emit()
363 LoadImm("vldr", False, False, False, size=4, flavor="fp").emit()
364 LoadDoubleImm("vldr", False, True, False, flavor="fp").emit()
365 LoadDoubleImm("vldr", False, False, False, flavor="fp").emit()
366}};