Deleted Added
sdiff udiff text old ( 7404:bfc74724914e ) new ( 7590:27dbb92bbad5 )
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

--- 29 unchanged lines hidden (view full) ---

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'):
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, [], base)
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);
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;
114 CondCodes = CondCodesMask & newCpsr;
115 '''
116 if self.writeback:
117 accCode += "Base = Base + %s;\n" % wbDiff
118 self.codeBlobs["memacc_code"] = accCode
119
120 self.emitHelper('RfeOp')
121
122 class LoadImmInst(LoadInst):
123 def __init__(self, *args, **kargs):
124 super(LoadImmInst, self).__init__(*args, **kargs)
125 self.offset = self.op + " imm"
126
127 class LoadRegInst(LoadInst):
128 def __init__(self, *args, **kargs):
129 super(LoadRegInst, self).__init__(*args, **kargs)
130 self.offset = self.op + " shift_rm_imm(Index, shiftAmt," + \
131 " shiftType, CondCodes<29:>)"
132
133 class LoadSingle(LoadInst):
134 def __init__(self, *args, **kargs):
135 super(LoadSingle, self).__init__(*args, **kargs)
136
137 # Build the default class name
138 self.Name = self.nameFunc(self.post, self.add, self.writeback,
139 self.size, self.sign, self.user)
140
141 # Add memory request flags where necessary
142 self.memFlags.append("%d" % (self.size - 1))
143 if self.user:
144 self.memFlags.append("ArmISA::TLB::UserMode")
145
146 if self.flavor == "prefetch":
147 self.memFlags.append("Request::PREFETCH")
148 elif self.flavor == "exclusive":
149 self.memFlags.append("Request::LLSC")
150 elif self.flavor == "normal":
151 self.memFlags.append("ArmISA::TLB::AllowUnaligned")
152
153 # Disambiguate the class name for different flavors of loads
154 if self.flavor != "normal":
155 self.Name = "%s_%s" % (self.name.upper(), self.Name)
156
157 def emit(self):
158 # Address compuation code
159 eaCode = "EA = Base"
160 if not self.post:
161 eaCode += self.offset
162 eaCode += ";"
163 self.codeBlobs["ea_code"] = eaCode
164
165 # Code that actually handles the access
166 if self.flavor == "prefetch":
167 accCode = 'uint64_t temp = Mem%s; temp = temp;'
168 elif self.flavor == "fp":
169 accCode = "FpDest.uw = cSwap(Mem%s, ((CPSR)Cpsr).e);\n"
170 else:
171 accCode = "IWDest = cSwap(Mem%s, ((CPSR)Cpsr).e);"
172 accCode = accCode % buildMemSuffix(self.sign, self.size)
173
174 if self.writeback:
175 accCode += "Base = Base %s;\n" % self.offset
176
177 self.codeBlobs["memacc_code"] = accCode
178
179 # Push it out to the output files
180 base = buildMemBase(self.basePrefix, self.post, self.writeback)
181 self.emitHelper(base)
182
183 def loadImmClassName(post, add, writeback, size=4, sign=False, user=False):
184 return memClassName("LOAD_IMM", post, add, writeback, size, sign, user)
185
186 class LoadImm(LoadImmInst, LoadSingle):
187 decConstBase = 'LoadStoreImm'
188 basePrefix = 'MemoryImm'
189 nameFunc = staticmethod(loadImmClassName)
190
191 def loadRegClassName(post, add, writeback, size=4, sign=False, user=False):
192 return memClassName("LOAD_REG", post, add, writeback, size, sign, user)
193
194 class LoadReg(LoadRegInst, LoadSingle):
195 decConstBase = 'LoadStoreReg'
196 basePrefix = 'MemoryReg'
197 nameFunc = staticmethod(loadRegClassName)
198
199 class LoadDouble(LoadInst):
200 def __init__(self, *args, **kargs):
201 super(LoadDouble, self).__init__(*args, **kargs)
202
203 # Build the default class name
204 self.Name = self.nameFunc(self.post, self.add, self.writeback)
205
206 # Add memory request flags where necessary
207 if self.flavor == "exclusive":
208 self.memFlags.append("Request::LLSC")
209 self.memFlags.append("ArmISA::TLB::AlignWord")
210
211 # Disambiguate the class name for different flavors of loads
212 if self.flavor != "normal":
213 self.Name = "%s_%s" % (self.name.upper(), self.Name)
214
215 def emit(self):
216 # Address computation code
217 eaCode = "EA = Base"
218 if not self.post:
219 eaCode += self.offset
220 eaCode += ";"
221 self.codeBlobs["ea_code"] = eaCode
222
223 # Code that actually handles the access
224 if self.flavor != "fp":
225 accCode = '''
226 CPSR cpsr = Cpsr;
227 Dest = cSwap<uint32_t>(Mem.ud, cpsr.e);
228 Dest2 = cSwap<uint32_t>(Mem.ud >> 32, cpsr.e);
229 '''
230 else:
231 accCode = '''
232 uint64_t swappedMem = cSwap(Mem.ud, ((CPSR)Cpsr).e);
233 FpDest.uw = (uint32_t)swappedMem;
234 FpDest2.uw = (uint32_t)(swappedMem >> 32);
235 '''
236
237 if self.writeback:
238 accCode += "Base = Base %s;\n" % self.offset
239
240 self.codeBlobs["memacc_code"] = accCode
241
242 # Push it out to the output files
243 base = buildMemBase(self.basePrefix, self.post, self.writeback)
244 self.emitHelper(base)
245
246 def loadDoubleImmClassName(post, add, writeback):
247 return memClassName("LOAD_IMMD", post, add, writeback, 4, False, False)
248
249 class LoadDoubleImm(LoadImmInst, LoadDouble):
250 decConstBase = 'LoadStoreDImm'
251 basePrefix = 'MemoryDImm'
252 nameFunc = staticmethod(loadDoubleImmClassName)
253
254 def loadDoubleRegClassName(post, add, writeback):
255 return memClassName("LOAD_REGD", post, add, writeback, 4, False, False)
256
257 class LoadDoubleReg(LoadRegInst, LoadDouble):
258 decConstBase = 'LoadStoreDReg'
259 basePrefix = 'MemoryDReg'
260 nameFunc = staticmethod(loadDoubleRegClassName)
261
262 def buildLoads(mnem, size=4, sign=False, user=False):
263 LoadImm(mnem, True, True, True, size, sign, user).emit()
264 LoadReg(mnem, True, True, True, size, sign, user).emit()
265 LoadImm(mnem, True, False, True, size, sign, user).emit()
266 LoadReg(mnem, True, False, True, size, sign, user).emit()
267 LoadImm(mnem, False, True, True, size, sign, user).emit()
268 LoadReg(mnem, False, True, True, size, sign, user).emit()
269 LoadImm(mnem, False, False, True, size, sign, user).emit()
270 LoadReg(mnem, False, False, True, size, sign, user).emit()
271 LoadImm(mnem, False, True, False, size, sign, user).emit()
272 LoadReg(mnem, False, True, False, size, sign, user).emit()
273 LoadImm(mnem, False, False, False, size, sign, user).emit()
274 LoadReg(mnem, False, False, False, size, sign, user).emit()
275
276 def buildDoubleLoads(mnem):
277 LoadDoubleImm(mnem, True, True, True).emit()
278 LoadDoubleReg(mnem, True, True, True).emit()
279 LoadDoubleImm(mnem, True, False, True).emit()
280 LoadDoubleReg(mnem, True, False, True).emit()
281 LoadDoubleImm(mnem, False, True, True).emit()
282 LoadDoubleReg(mnem, False, True, True).emit()
283 LoadDoubleImm(mnem, False, False, True).emit()
284 LoadDoubleReg(mnem, False, False, True).emit()
285 LoadDoubleImm(mnem, False, True, False).emit()
286 LoadDoubleReg(mnem, False, True, False).emit()
287 LoadDoubleImm(mnem, False, False, False).emit()
288 LoadDoubleReg(mnem, False, False, False).emit()
289
290 def buildRfeLoads(mnem):
291 RfeInst(mnem, True, True, True).emit()
292 RfeInst(mnem, True, True, False).emit()
293 RfeInst(mnem, True, False, True).emit()
294 RfeInst(mnem, True, False, False).emit()
295 RfeInst(mnem, False, True, True).emit()
296 RfeInst(mnem, False, True, False).emit()
297 RfeInst(mnem, False, False, True).emit()
298 RfeInst(mnem, False, False, False).emit()
299
300 def buildPrefetches(mnem):
301 LoadReg(mnem, False, False, False, size=1, flavor="prefetch").emit()
302 LoadImm(mnem, False, False, False, size=1, flavor="prefetch").emit()
303 LoadReg(mnem, False, True, False, size=1, flavor="prefetch").emit()
304 LoadImm(mnem, False, True, False, size=1, flavor="prefetch").emit()
305
306 buildLoads("ldr")
307 buildLoads("ldrt", user=True)
308 buildLoads("ldrb", size=1)
309 buildLoads("ldrbt", size=1, user=True)
310 buildLoads("ldrsb", size=1, sign=True)
311 buildLoads("ldrsbt", size=1, sign=True, user=True)
312 buildLoads("ldrh", size=2)

--- 4 unchanged lines hidden (view full) ---

317 buildDoubleLoads("ldrd")
318
319 buildRfeLoads("rfe")
320
321 buildPrefetches("pld")
322 buildPrefetches("pldw")
323 buildPrefetches("pli")
324
325 LoadImm("ldrex", False, True, False, size=4, flavor="exclusive").emit()
326 LoadImm("ldrexh", False, True, False, size=2, flavor="exclusive").emit()
327 LoadImm("ldrexb", False, True, False, size=1, flavor="exclusive").emit()
328 LoadDoubleImm("ldrexd", False, True, False, flavor="exclusive").emit()
329
330 LoadImm("vldr", False, True, False, size=4, flavor="fp").emit()
331 LoadImm("vldr", False, False, False, size=4, flavor="fp").emit()
332 LoadDoubleImm("vldr", False, True, False, flavor="fp").emit()
333 LoadDoubleImm("vldr", False, False, False, flavor="fp").emit()
334}};