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