Deleted Added
sdiff udiff text old ( 7644:62873d5c2bfc ) new ( 7646:a444dbee8c07 )
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 class StoreInst(LoadStoreInst):
47 execBase = 'Store'
48
49 def __init__(self, mnem, post, add, writeback, size=4,
50 sign=False, user=False, flavor="normal"):
51 super(StoreInst, 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):
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, wbDecl)
80
81 header_output += newHeader
82 decoder_output += newDecoder
83 exec_output += newExec
84
85 class SrsInst(LoadStoreInst):
86 execBase = 'Store'
87 decConstBase = 'Srs'
88
89 def __init__(self, mnem, post, add, writeback):
90 super(SrsInst, self).__init__()
91 self.name = mnem
92 self.post = post
93 self.add = add
94 self.writeback = writeback
95
96 self.Name = "SRS_" + storeImmClassName(post, add, writeback, 8)
97
98 def emit(self):
99 offset = 0
100 if self.post != self.add:
101 offset += 4
102 if not self.add:
103 offset -= 8
104
105 eaCode = "EA = SpMode + %d;" % offset
106
107 wbDiff = -8
108 if self.add:
109 wbDiff = 8
110 accCode = '''
111 CPSR cpsr = Cpsr;
112 Mem.ud = (uint64_t)cSwap(LR.uw, cpsr.e) |
113 ((uint64_t)cSwap(Spsr.uw, cpsr.e) << 32);
114 '''
115 if self.writeback:
116 accCode += "SpMode = SpMode + %s;\n" % wbDiff
117
118 global header_output, decoder_output, exec_output
119
120 codeBlobs = { "ea_code": eaCode,
121 "memacc_code": accCode,
122 "postacc_code": "" }
123 codeBlobs["predicate_test"] = pickPredicate(codeBlobs)
124
125 (newHeader,
126 newDecoder,
127 newExec) = self.fillTemplates(self.name, self.Name, codeBlobs,
128 ["ArmISA::TLB::AlignWord", "ArmISA::TLB::MustBeOne"], [],
129 base = 'SrsOp')
130
131 header_output += newHeader
132 decoder_output += newDecoder
133 exec_output += newExec
134
135 class StoreImmInst(StoreInst):
136 def __init__(self, *args, **kargs):
137 super(StoreImmInst, self).__init__(*args, **kargs)
138 self.offset = self.op + " imm"
139
140 if self.add:
141 self.wbDecl = "MicroAddiUop(machInst, base, base, imm);"
142 else:
143 self.wbDecl = "MicroSubiUop(machInst, base, base, imm);"
144
145 class StoreRegInst(StoreInst):
146 def __init__(self, *args, **kargs):
147 super(StoreRegInst, self).__init__(*args, **kargs)
148 self.offset = self.op + " shift_rm_imm(Index, shiftAmt," + \
149 " shiftType, CondCodes<29:>)"
150 if self.add:
151 self.wbDecl = '''
152 MicroAddUop(machInst, base, base, index, shiftAmt, shiftType);
153 '''
154 else:
155 self.wbDecl = '''
156 MicroSubUop(machInst, base, base, index, shiftAmt, shiftType);
157 '''
158
159 class StoreSingle(StoreInst):
160 def __init__(self, *args, **kargs):
161 super(StoreSingle, self).__init__(*args, **kargs)
162
163 # Build the default class name
164 self.Name = self.nameFunc(self.post, self.add, self.writeback,
165 self.size, self.sign, self.user)
166
167 # Add memory request flags where necessary
168 self.memFlags.append("%d" % (self.size - 1))
169 if self.user:
170 self.memFlags.append("ArmISA::TLB::UserMode")
171
172 if self.flavor == "exclusive":
173 self.memFlags.append("Request::LLSC")
174 elif self.flavor != "fp":
175 self.memFlags.append("ArmISA::TLB::AllowUnaligned")
176
177 # Disambiguate the class name for different flavors of stores
178 if self.flavor != "normal":
179 self.Name = "%s_%s" % (self.name.upper(), self.Name)
180
181 def emit(self):
182 # Address computation
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 == "fp":
195 accCode = 'Mem%(suffix)s = cSwap(FpDest.uw, ((CPSR)Cpsr).e);'
196 else:
197 accCode = \
198 'Mem%(suffix)s = cSwap(Dest%(suffix)s, ((CPSR)Cpsr).e);'
199 accCode = accCode % \
200 { "suffix" : 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)
210
211 def storeImmClassName(post, add, writeback, size=4, sign=False, user=False):
212 return memClassName("STORE_IMM", post, add, writeback, size, sign, user)
213
214 class StoreImmEx(StoreImmInst, StoreSingle):
215 execBase = 'StoreEx'
216 decConstBase = 'StoreExImm'
217 basePrefix = 'MemoryExImm'
218 nameFunc = staticmethod(storeImmClassName)
219
220 def __init__(self, *args, **kargs):
221 super(StoreImmEx, self).__init__(*args, **kargs)
222 self.codeBlobs["postacc_code"] = "Result = !writeResult;"
223
224 class StoreImm(StoreImmInst, StoreSingle):
225 decConstBase = 'LoadStoreImm'
226 basePrefix = 'MemoryImm'
227 nameFunc = staticmethod(storeImmClassName)
228
229 def storeRegClassName(post, add, writeback, size=4, sign=False, user=False):
230 return memClassName("STORE_REG", post, add, writeback, size, sign, user)
231
232 class StoreReg(StoreRegInst, StoreSingle):
233 decConstBase = 'StoreReg'
234 basePrefix = 'MemoryReg'
235 nameFunc = staticmethod(storeRegClassName)
236
237 class StoreDouble(StoreInst):
238 def __init__(self, *args, **kargs):
239 super(StoreDouble, self).__init__(*args, **kargs)
240
241 # Build the default class name
242 self.Name = self.nameFunc(self.post, self.add, self.writeback)
243
244 # Add memory request flags where necessary
245 if self.flavor == "exclusive":
246 self.memFlags.append("Request::LLSC")
247 self.memFlags.append("ArmISA::TLB::AlignDoubleWord")
248 else:
249 self.memFlags.append("ArmISA::TLB::AlignWord")
250
251 # Disambiguate the class name for different flavors of stores
252 if self.flavor != "normal":
253 self.Name = "%s_%s" % (self.name.upper(), self.Name)
254
255 def emit(self):
256 # Address computation code
257 eaCode = "EA = Base"
258 if not self.post:
259 eaCode += self.offset
260 eaCode += ";"
261
262 if self.flavor == "fp":
263 eaCode += vfpEnabledCheckCode
264
265 self.codeBlobs["ea_code"] = eaCode
266
267 # Code that actually handles the access
268 if self.flavor == "fp":
269 accCode = '''
270 uint64_t swappedMem = (uint64_t)FpDest.uw |
271 ((uint64_t)FpDest2.uw << 32);
272 Mem.ud = cSwap(swappedMem, ((CPSR)Cpsr).e);
273 '''
274 else:
275 accCode = '''
276 CPSR cpsr = Cpsr;
277 Mem.ud = (uint64_t)cSwap(Dest.uw, cpsr.e) |
278 ((uint64_t)cSwap(Dest2.uw, cpsr.e) << 32);
279 '''
280
281 self.codeBlobs["memacc_code"] = accCode
282
283 # Push it out to the output files
284 base = buildMemBase(self.basePrefix, self.post, self.writeback)
285 wbDecl = None
286 if self.writeback:
287 wbDecl = self.wbDecl
288 self.emitHelper(base, wbDecl)
289
290 def storeDoubleImmClassName(post, add, writeback):
291 return memClassName("STORE_IMMD", post, add, writeback, 4, False, False)
292
293 class StoreDoubleImmEx(StoreImmInst, StoreDouble):
294 execBase = 'StoreEx'
295 decConstBase = 'StoreExDImm'
296 basePrefix = 'MemoryExDImm'
297 nameFunc = staticmethod(storeDoubleImmClassName)
298
299 def __init__(self, *args, **kargs):
300 super(StoreDoubleImmEx, self).__init__(*args, **kargs)
301 self.codeBlobs["postacc_code"] = "Result = !writeResult;"
302
303 class StoreDoubleImm(StoreImmInst, StoreDouble):
304 decConstBase = 'LoadStoreDImm'
305 basePrefix = 'MemoryDImm'
306 nameFunc = staticmethod(storeDoubleImmClassName)
307
308 def storeDoubleRegClassName(post, add, writeback):
309 return memClassName("STORE_REGD", post, add, writeback, 4, False, False)
310
311 class StoreDoubleReg(StoreRegInst, StoreDouble):
312 decConstBase = 'StoreDReg'
313 basePrefix = 'MemoryDReg'
314 nameFunc = staticmethod(storeDoubleRegClassName)
315
316 def buildStores(mnem, size=4, sign=False, user=False):
317 StoreImm(mnem, True, True, True, size, sign, user).emit()
318 StoreReg(mnem, True, True, True, size, sign, user).emit()
319 StoreImm(mnem, True, False, True, size, sign, user).emit()
320 StoreReg(mnem, True, False, True, size, sign, user).emit()
321 StoreImm(mnem, False, True, True, size, sign, user).emit()
322 StoreReg(mnem, False, True, True, size, sign, user).emit()
323 StoreImm(mnem, False, False, True, size, sign, user).emit()
324 StoreReg(mnem, False, False, True, size, sign, user).emit()
325 StoreImm(mnem, False, True, False, size, sign, user).emit()
326 StoreReg(mnem, False, True, False, size, sign, user).emit()
327 StoreImm(mnem, False, False, False, size, sign, user).emit()
328 StoreReg(mnem, False, False, False, size, sign, user).emit()
329
330 def buildDoubleStores(mnem):
331 StoreDoubleImm(mnem, True, True, True).emit()
332 StoreDoubleReg(mnem, True, True, True).emit()
333 StoreDoubleImm(mnem, True, False, True).emit()
334 StoreDoubleReg(mnem, True, False, True).emit()
335 StoreDoubleImm(mnem, False, True, True).emit()
336 StoreDoubleReg(mnem, False, True, True).emit()
337 StoreDoubleImm(mnem, False, False, True).emit()
338 StoreDoubleReg(mnem, False, False, True).emit()
339 StoreDoubleImm(mnem, False, True, False).emit()
340 StoreDoubleReg(mnem, False, True, False).emit()
341 StoreDoubleImm(mnem, False, False, False).emit()
342 StoreDoubleReg(mnem, False, False, False).emit()
343
344 def buildSrsStores(mnem):
345 SrsInst(mnem, True, True, True).emit()
346 SrsInst(mnem, True, True, False).emit()
347 SrsInst(mnem, True, False, True).emit()
348 SrsInst(mnem, True, False, False).emit()
349 SrsInst(mnem, False, True, True).emit()
350 SrsInst(mnem, False, True, False).emit()
351 SrsInst(mnem, False, False, True).emit()
352 SrsInst(mnem, False, False, False).emit()
353
354 buildStores("str")
355 buildStores("strt", user=True)
356 buildStores("strb", size=1)
357 buildStores("strbt", size=1, user=True)
358 buildStores("strh", size=2)
359 buildStores("strht", size=2, user=True)
360
361 buildSrsStores("srs")
362
363 buildDoubleStores("strd")
364
365 StoreImmEx("strex", False, True, False, size=4, flavor="exclusive").emit()
366 StoreImmEx("strexh", False, True, False, size=2, flavor="exclusive").emit()
367 StoreImmEx("strexb", False, True, False, size=1, flavor="exclusive").emit()
368 StoreDoubleImmEx("strexd", False, True, False, flavor="exclusive").emit()
369
370 StoreImm("vstr", False, True, False, size=4, flavor="fp").emit()
371 StoreImm("vstr", False, False, False, size=4, flavor="fp").emit()
372 StoreDoubleImm("vstr", False, True, False, flavor="fp").emit()
373 StoreDoubleImm("vstr", False, False, False, flavor="fp").emit()
374}};