str.isa (13589:13522f2a5126) str.isa (14172:bba55ff08279)
1// -*- mode:c++ -*-
2
3// Copyright (c) 2010-2011,2017,2019 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 import math
42
43 header_output = ""
44 decoder_output = ""
45 exec_output = ""
46
47 class StoreInst(LoadStoreInst):
48 execBase = 'Store'
49
50 def __init__(self, mnem, post, add, writeback, size=4,
51 sign=False, user=False, flavor="normal"):
52 super(StoreInst, self).__init__()
53
54 self.name = mnem
55 self.post = post
56 self.add = add
57 self.writeback = writeback
58 self.size = size
59 self.sign = sign
60 self.user = user
61 self.flavor = flavor
62 self.instFlags = []
63 if self.add:
64 self.op = " +"
65 else:
66 self.op = " -"
67
68 self.memFlags = ["ArmISA::TLB::MustBeOne"]
69 self.codeBlobs = { "postacc_code" : "" }
70
71 def emitHelper(self, base = 'Memory', wbDecl = None):
72
73 global header_output, decoder_output, exec_output
74
75 codeBlobs = self.codeBlobs
76 codeBlobs["predicate_test"] = pickPredicate(codeBlobs)
77 (newHeader,
78 newDecoder,
79 newExec) = self.fillTemplates(self.name, self.Name, codeBlobs,
80 self.memFlags, self.instFlags,
81 base, wbDecl, None, False,
82 self.size, self.sign)
83
84 header_output += newHeader
85 decoder_output += newDecoder
86 exec_output += newExec
87
88 class SrsInst(LoadStoreInst):
89 execBase = 'Store'
90 decConstBase = 'Srs'
91
92 def __init__(self, mnem, post, add, writeback):
93 super(SrsInst, self).__init__()
94 self.name = mnem
95 self.post = post
96 self.add = add
97 self.writeback = writeback
98
99 self.Name = "SRS_" + storeImmClassName(post, add, writeback, 8)
100
101 def emit(self):
102 offset = 0
103 if self.post != self.add:
104 offset += 4
105 if not self.add:
106 offset -= 8
107
108 eaCode = "EA = SpMode + %d;" % offset
109
110 wbDiff = -8
111 if self.add:
112 wbDiff = 8
113 accCode = '''
114
115 auto tc = xc->tcBase();
116 if (badMode32(tc, static_cast<OperatingMode>(regMode))) {
1// -*- mode:c++ -*-
2
3// Copyright (c) 2010-2011,2017,2019 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 import math
42
43 header_output = ""
44 decoder_output = ""
45 exec_output = ""
46
47 class StoreInst(LoadStoreInst):
48 execBase = 'Store'
49
50 def __init__(self, mnem, post, add, writeback, size=4,
51 sign=False, user=False, flavor="normal"):
52 super(StoreInst, self).__init__()
53
54 self.name = mnem
55 self.post = post
56 self.add = add
57 self.writeback = writeback
58 self.size = size
59 self.sign = sign
60 self.user = user
61 self.flavor = flavor
62 self.instFlags = []
63 if self.add:
64 self.op = " +"
65 else:
66 self.op = " -"
67
68 self.memFlags = ["ArmISA::TLB::MustBeOne"]
69 self.codeBlobs = { "postacc_code" : "" }
70
71 def emitHelper(self, base = 'Memory', wbDecl = None):
72
73 global header_output, decoder_output, exec_output
74
75 codeBlobs = self.codeBlobs
76 codeBlobs["predicate_test"] = pickPredicate(codeBlobs)
77 (newHeader,
78 newDecoder,
79 newExec) = self.fillTemplates(self.name, self.Name, codeBlobs,
80 self.memFlags, self.instFlags,
81 base, wbDecl, None, False,
82 self.size, self.sign)
83
84 header_output += newHeader
85 decoder_output += newDecoder
86 exec_output += newExec
87
88 class SrsInst(LoadStoreInst):
89 execBase = 'Store'
90 decConstBase = 'Srs'
91
92 def __init__(self, mnem, post, add, writeback):
93 super(SrsInst, self).__init__()
94 self.name = mnem
95 self.post = post
96 self.add = add
97 self.writeback = writeback
98
99 self.Name = "SRS_" + storeImmClassName(post, add, writeback, 8)
100
101 def emit(self):
102 offset = 0
103 if self.post != self.add:
104 offset += 4
105 if not self.add:
106 offset -= 8
107
108 eaCode = "EA = SpMode + %d;" % offset
109
110 wbDiff = -8
111 if self.add:
112 wbDiff = 8
113 accCode = '''
114
115 auto tc = xc->tcBase();
116 if (badMode32(tc, static_cast<OperatingMode>(regMode))) {
117 return undefinedFault32(tc, opModeToEL(currOpMode(tc)));
117 return undefinedFault32(tc, currEL(tc));
118 }
119
120 CPSR cpsr = Cpsr;
121 Mem_ud = (uint64_t)cSwap(LR_uw, cpsr.e) |
122 ((uint64_t)cSwap(Spsr_uw, cpsr.e) << 32);
123 '''
124
125 global header_output, decoder_output, exec_output
126
127 codeBlobs = { "ea_code": eaCode,
128 "memacc_code": accCode,
129 "postacc_code": "" }
130 codeBlobs["predicate_test"] = pickPredicate(codeBlobs)
131
132 wbDecl = None
133 if self.writeback:
134 wbDecl = '''MicroAddiUop(machInst,
135 intRegInMode((OperatingMode)regMode, INTREG_SP),
136 intRegInMode((OperatingMode)regMode, INTREG_SP),
137 %d);''' % wbDiff
138
139 (newHeader,
140 newDecoder,
141 newExec) = self.fillTemplates(self.name, self.Name, codeBlobs,
142 ["ArmISA::TLB::AlignWord", "ArmISA::TLB::MustBeOne"], [],
143 'SrsOp', wbDecl)
144
145 header_output += newHeader
146 decoder_output += newDecoder
147 exec_output += newExec
148
149 class StoreImmInst(StoreInst):
150 def __init__(self, *args, **kargs):
151 super(StoreImmInst, self).__init__(*args, **kargs)
152 self.offset = self.op + " imm"
153
154 if self.add:
155 self.wbDecl = "MicroAddiUop(machInst, base, base, imm);"
156 else:
157 self.wbDecl = "MicroSubiUop(machInst, base, base, imm);"
158
159 class StoreRegInst(StoreInst):
160 def __init__(self, *args, **kargs):
161 super(StoreRegInst, self).__init__(*args, **kargs)
162 self.offset = self.op + " shift_rm_imm(Index, shiftAmt," + \
163 " shiftType, OptShiftRmCondCodesC)"
164 if self.add:
165 self.wbDecl = '''
166 MicroAddUop(machInst, base, base, index, shiftAmt, shiftType);
167 '''
168 else:
169 self.wbDecl = '''
170 MicroSubUop(machInst, base, base, index, shiftAmt, shiftType);
171 '''
172
173 class StoreSingle(StoreInst):
174 def __init__(self, *args, **kargs):
175 super(StoreSingle, self).__init__(*args, **kargs)
176
177 # Build the default class name
178 self.Name = self.nameFunc(self.post, self.add, self.writeback,
179 self.size, self.sign, self.user)
180
181 # Add memory request flags where necessary
182 self.memFlags.append("%d" % int(math.log(self.size, 2)))
183 if self.user:
184 self.memFlags.append("ArmISA::TLB::UserMode")
185
186 if self.flavor in ("exclusive", "relex"):
187 self.instFlags.append("IsStoreConditional")
188 self.memFlags.append("Request::LLSC")
189 elif self.flavor != "fp":
190 self.memFlags.append("ArmISA::TLB::AllowUnaligned")
191
192 if self.flavor in ("release", "relex"):
193 self.instFlags.extend(["IsMemBarrier",
194 "IsWriteBarrier",
195 "IsReadBarrier"])
196
197 # Disambiguate the class name for different flavors of stores
198 if self.flavor != "normal":
199 self.Name = "%s_%s" % (self.name.upper(), self.Name)
200
201 def emit(self):
202 # Address computation
203 eaCode = "EA = Base"
204 if not self.post:
205 eaCode += self.offset
206 eaCode += ";"
207
208 if self.flavor == "fp":
209 eaCode += vfpEnabledCheckCode
210
211 self.codeBlobs["ea_code"] = eaCode
212
213 # Code that actually handles the access
214 if self.flavor == "fp":
215 accCode = 'Mem%(suffix)s = cSwap(FpDest_uw, ((CPSR)Cpsr).e);'
216 else:
217 accCode = \
218 'Mem%(suffix)s = cSwap(Dest%(suffix)s, ((CPSR)Cpsr).e);'
219 accCode = accCode % \
220 { "suffix" : buildMemSuffix(self.sign, self.size) }
221
222 self.codeBlobs["memacc_code"] = accCode
223
224 # Push it out to the output files
225 base = buildMemBase(self.basePrefix, self.post, self.writeback)
226 wbDecl = None
227 if self.writeback:
228 wbDecl = self.wbDecl
229 self.emitHelper(base, wbDecl)
230
231 def storeImmClassName(post, add, writeback, size=4, sign=False, user=False):
232 return memClassName("STORE_IMM", post, add, writeback, size, sign, user)
233
234 class StoreImmEx(StoreImmInst, StoreSingle):
235 execBase = 'StoreEx'
236 decConstBase = 'StoreExImm'
237 basePrefix = 'MemoryExImm'
238 nameFunc = staticmethod(storeImmClassName)
239
240 def __init__(self, *args, **kargs):
241 super(StoreImmEx, self).__init__(*args, **kargs)
242 self.codeBlobs["postacc_code"] = \
243 "Result = !writeResult; SevMailbox = 1; LLSCLock = 0;"
244
245 class StoreImm(StoreImmInst, StoreSingle):
246 decConstBase = 'LoadStoreImm'
247 basePrefix = 'MemoryImm'
248 nameFunc = staticmethod(storeImmClassName)
249
250 def storeRegClassName(post, add, writeback, size=4, sign=False, user=False):
251 return memClassName("STORE_REG", post, add, writeback, size, sign, user)
252
253 class StoreReg(StoreRegInst, StoreSingle):
254 decConstBase = 'StoreReg'
255 basePrefix = 'MemoryReg'
256 nameFunc = staticmethod(storeRegClassName)
257
258 class StoreDouble(StoreInst):
259 def __init__(self, *args, **kargs):
260 super(StoreDouble, self).__init__(*args, **kargs)
261
262 # Build the default class name
263 self.Name = self.nameFunc(self.post, self.add, self.writeback)
264
265 # Add memory request flags where necessary
266 if self.flavor in ("exclusive", "relex"):
267 self.instFlags.append("IsStoreConditional")
268 self.memFlags.append("Request::LLSC")
269 self.memFlags.append("ArmISA::TLB::AlignDoubleWord")
270 else:
271 self.memFlags.append("ArmISA::TLB::AlignWord")
272
273 if self.flavor in ("release", "relex"):
274 self.instFlags.extend(["IsMemBarrier",
275 "IsWriteBarrier",
276 "IsReadBarrier"])
277
278 # Disambiguate the class name for different flavors of stores
279 if self.flavor != "normal":
280 self.Name = "%s_%s" % (self.name.upper(), self.Name)
281
282 def emit(self):
283 # Address computation code
284 eaCode = "EA = Base"
285 if not self.post:
286 eaCode += self.offset
287 eaCode += ";"
288
289 if self.flavor == "fp":
290 eaCode += vfpEnabledCheckCode
291
292 self.codeBlobs["ea_code"] = eaCode
293
294 # Code that actually handles the access
295 if self.flavor == "fp":
296 accCode = '''
297 uint64_t swappedMem = (uint64_t)FpDest_uw |
298 ((uint64_t)FpDest2_uw << 32);
299 Mem_ud = cSwap(swappedMem, ((CPSR)Cpsr).e);
300 '''
301 else:
302 accCode = '''
303 CPSR cpsr = Cpsr;
304 Mem_ud = (uint64_t)cSwap(Dest_uw, cpsr.e) |
305 ((uint64_t)cSwap(Dest2_uw, cpsr.e) << 32);
306 '''
307
308 self.codeBlobs["memacc_code"] = accCode
309
310 # Push it out to the output files
311 base = buildMemBase(self.basePrefix, self.post, self.writeback)
312 wbDecl = None
313 if self.writeback:
314 wbDecl = self.wbDecl
315 self.emitHelper(base, wbDecl)
316
317 def storeDoubleImmClassName(post, add, writeback):
318 return memClassName("STORE_IMMD", post, add, writeback, 4, False, False)
319
320 class StoreDoubleImmEx(StoreImmInst, StoreDouble):
321 execBase = 'StoreEx'
322 decConstBase = 'StoreExDImm'
323 basePrefix = 'MemoryExDImm'
324 nameFunc = staticmethod(storeDoubleImmClassName)
325
326 def __init__(self, *args, **kargs):
327 super(StoreDoubleImmEx, self).__init__(*args, **kargs)
328 self.codeBlobs["postacc_code"] = \
329 "Result = !writeResult; SevMailbox = 1; LLSCLock = 0;"
330
331 class StoreDoubleImm(StoreImmInst, StoreDouble):
332 decConstBase = 'LoadStoreDImm'
333 basePrefix = 'MemoryDImm'
334 nameFunc = staticmethod(storeDoubleImmClassName)
335
336 def storeDoubleRegClassName(post, add, writeback):
337 return memClassName("STORE_REGD", post, add, writeback, 4, False, False)
338
339 class StoreDoubleReg(StoreRegInst, StoreDouble):
340 decConstBase = 'StoreDReg'
341 basePrefix = 'MemoryDReg'
342 nameFunc = staticmethod(storeDoubleRegClassName)
343
344 def buildStores(mnem, size=4, sign=False, user=False):
345 StoreImm(mnem, True, True, True, size, sign, user).emit()
346 StoreReg(mnem, True, True, True, size, sign, user).emit()
347 StoreImm(mnem, True, False, True, size, sign, user).emit()
348 StoreReg(mnem, True, False, True, size, sign, user).emit()
349 StoreImm(mnem, False, True, True, size, sign, user).emit()
350 StoreReg(mnem, False, True, True, size, sign, user).emit()
351 StoreImm(mnem, False, False, True, size, sign, user).emit()
352 StoreReg(mnem, False, False, True, size, sign, user).emit()
353 StoreImm(mnem, False, True, False, size, sign, user).emit()
354 StoreReg(mnem, False, True, False, size, sign, user).emit()
355 StoreImm(mnem, False, False, False, size, sign, user).emit()
356 StoreReg(mnem, False, False, False, size, sign, user).emit()
357
358 def buildDoubleStores(mnem):
359 StoreDoubleImm(mnem, True, True, True).emit()
360 StoreDoubleReg(mnem, True, True, True).emit()
361 StoreDoubleImm(mnem, True, False, True).emit()
362 StoreDoubleReg(mnem, True, False, True).emit()
363 StoreDoubleImm(mnem, False, True, True).emit()
364 StoreDoubleReg(mnem, False, True, True).emit()
365 StoreDoubleImm(mnem, False, False, True).emit()
366 StoreDoubleReg(mnem, False, False, True).emit()
367 StoreDoubleImm(mnem, False, True, False).emit()
368 StoreDoubleReg(mnem, False, True, False).emit()
369 StoreDoubleImm(mnem, False, False, False).emit()
370 StoreDoubleReg(mnem, False, False, False).emit()
371
372 def buildSrsStores(mnem):
373 SrsInst(mnem, True, True, True).emit()
374 SrsInst(mnem, True, True, False).emit()
375 SrsInst(mnem, True, False, True).emit()
376 SrsInst(mnem, True, False, False).emit()
377 SrsInst(mnem, False, True, True).emit()
378 SrsInst(mnem, False, True, False).emit()
379 SrsInst(mnem, False, False, True).emit()
380 SrsInst(mnem, False, False, False).emit()
381
382 buildStores("str")
383 buildStores("strt", user=True)
384 buildStores("strb", size=1)
385 buildStores("strbt", size=1, user=True)
386 buildStores("strh", size=2)
387 buildStores("strht", size=2, user=True)
388
389 buildSrsStores("srs")
390
391 buildDoubleStores("strd")
392
393 StoreImmEx("strex", False, True, False, size=4,
394 flavor="exclusive").emit()
395 StoreImmEx("strexh", False, True, False, size=2,
396 flavor="exclusive").emit()
397 StoreImmEx("strexb", False, True, False, size=1,
398 flavor="exclusive").emit()
399 StoreDoubleImmEx("strexd", False, True, False,
400 flavor="exclusive").emit()
401
402 StoreImm("stl", False, True, False, size=4, flavor="release").emit()
403 StoreImm("stlh", False, True, False, size=2, flavor="release").emit()
404 StoreImm("stlb", False, True, False, size=1, flavor="release").emit()
405 StoreImmEx("stlex", False, True, False, size=4, flavor="relex").emit()
406 StoreImmEx("stlexh", False, True, False, size=2, flavor="relex").emit()
407 StoreImmEx("stlexb", False, True, False, size=1, flavor="relex").emit()
408 StoreDoubleImmEx("stlexd", False, True, False, flavor="relex").emit()
409
410 StoreImm("vstr", False, True, False, size=4, flavor="fp").emit()
411 StoreImm("vstr", False, False, False, size=4, flavor="fp").emit()
412 StoreDoubleImm("vstr", False, True, False, flavor="fp").emit()
413 StoreDoubleImm("vstr", False, False, False, flavor="fp").emit()
414}};
118 }
119
120 CPSR cpsr = Cpsr;
121 Mem_ud = (uint64_t)cSwap(LR_uw, cpsr.e) |
122 ((uint64_t)cSwap(Spsr_uw, cpsr.e) << 32);
123 '''
124
125 global header_output, decoder_output, exec_output
126
127 codeBlobs = { "ea_code": eaCode,
128 "memacc_code": accCode,
129 "postacc_code": "" }
130 codeBlobs["predicate_test"] = pickPredicate(codeBlobs)
131
132 wbDecl = None
133 if self.writeback:
134 wbDecl = '''MicroAddiUop(machInst,
135 intRegInMode((OperatingMode)regMode, INTREG_SP),
136 intRegInMode((OperatingMode)regMode, INTREG_SP),
137 %d);''' % wbDiff
138
139 (newHeader,
140 newDecoder,
141 newExec) = self.fillTemplates(self.name, self.Name, codeBlobs,
142 ["ArmISA::TLB::AlignWord", "ArmISA::TLB::MustBeOne"], [],
143 'SrsOp', wbDecl)
144
145 header_output += newHeader
146 decoder_output += newDecoder
147 exec_output += newExec
148
149 class StoreImmInst(StoreInst):
150 def __init__(self, *args, **kargs):
151 super(StoreImmInst, self).__init__(*args, **kargs)
152 self.offset = self.op + " imm"
153
154 if self.add:
155 self.wbDecl = "MicroAddiUop(machInst, base, base, imm);"
156 else:
157 self.wbDecl = "MicroSubiUop(machInst, base, base, imm);"
158
159 class StoreRegInst(StoreInst):
160 def __init__(self, *args, **kargs):
161 super(StoreRegInst, self).__init__(*args, **kargs)
162 self.offset = self.op + " shift_rm_imm(Index, shiftAmt," + \
163 " shiftType, OptShiftRmCondCodesC)"
164 if self.add:
165 self.wbDecl = '''
166 MicroAddUop(machInst, base, base, index, shiftAmt, shiftType);
167 '''
168 else:
169 self.wbDecl = '''
170 MicroSubUop(machInst, base, base, index, shiftAmt, shiftType);
171 '''
172
173 class StoreSingle(StoreInst):
174 def __init__(self, *args, **kargs):
175 super(StoreSingle, self).__init__(*args, **kargs)
176
177 # Build the default class name
178 self.Name = self.nameFunc(self.post, self.add, self.writeback,
179 self.size, self.sign, self.user)
180
181 # Add memory request flags where necessary
182 self.memFlags.append("%d" % int(math.log(self.size, 2)))
183 if self.user:
184 self.memFlags.append("ArmISA::TLB::UserMode")
185
186 if self.flavor in ("exclusive", "relex"):
187 self.instFlags.append("IsStoreConditional")
188 self.memFlags.append("Request::LLSC")
189 elif self.flavor != "fp":
190 self.memFlags.append("ArmISA::TLB::AllowUnaligned")
191
192 if self.flavor in ("release", "relex"):
193 self.instFlags.extend(["IsMemBarrier",
194 "IsWriteBarrier",
195 "IsReadBarrier"])
196
197 # Disambiguate the class name for different flavors of stores
198 if self.flavor != "normal":
199 self.Name = "%s_%s" % (self.name.upper(), self.Name)
200
201 def emit(self):
202 # Address computation
203 eaCode = "EA = Base"
204 if not self.post:
205 eaCode += self.offset
206 eaCode += ";"
207
208 if self.flavor == "fp":
209 eaCode += vfpEnabledCheckCode
210
211 self.codeBlobs["ea_code"] = eaCode
212
213 # Code that actually handles the access
214 if self.flavor == "fp":
215 accCode = 'Mem%(suffix)s = cSwap(FpDest_uw, ((CPSR)Cpsr).e);'
216 else:
217 accCode = \
218 'Mem%(suffix)s = cSwap(Dest%(suffix)s, ((CPSR)Cpsr).e);'
219 accCode = accCode % \
220 { "suffix" : buildMemSuffix(self.sign, self.size) }
221
222 self.codeBlobs["memacc_code"] = accCode
223
224 # Push it out to the output files
225 base = buildMemBase(self.basePrefix, self.post, self.writeback)
226 wbDecl = None
227 if self.writeback:
228 wbDecl = self.wbDecl
229 self.emitHelper(base, wbDecl)
230
231 def storeImmClassName(post, add, writeback, size=4, sign=False, user=False):
232 return memClassName("STORE_IMM", post, add, writeback, size, sign, user)
233
234 class StoreImmEx(StoreImmInst, StoreSingle):
235 execBase = 'StoreEx'
236 decConstBase = 'StoreExImm'
237 basePrefix = 'MemoryExImm'
238 nameFunc = staticmethod(storeImmClassName)
239
240 def __init__(self, *args, **kargs):
241 super(StoreImmEx, self).__init__(*args, **kargs)
242 self.codeBlobs["postacc_code"] = \
243 "Result = !writeResult; SevMailbox = 1; LLSCLock = 0;"
244
245 class StoreImm(StoreImmInst, StoreSingle):
246 decConstBase = 'LoadStoreImm'
247 basePrefix = 'MemoryImm'
248 nameFunc = staticmethod(storeImmClassName)
249
250 def storeRegClassName(post, add, writeback, size=4, sign=False, user=False):
251 return memClassName("STORE_REG", post, add, writeback, size, sign, user)
252
253 class StoreReg(StoreRegInst, StoreSingle):
254 decConstBase = 'StoreReg'
255 basePrefix = 'MemoryReg'
256 nameFunc = staticmethod(storeRegClassName)
257
258 class StoreDouble(StoreInst):
259 def __init__(self, *args, **kargs):
260 super(StoreDouble, self).__init__(*args, **kargs)
261
262 # Build the default class name
263 self.Name = self.nameFunc(self.post, self.add, self.writeback)
264
265 # Add memory request flags where necessary
266 if self.flavor in ("exclusive", "relex"):
267 self.instFlags.append("IsStoreConditional")
268 self.memFlags.append("Request::LLSC")
269 self.memFlags.append("ArmISA::TLB::AlignDoubleWord")
270 else:
271 self.memFlags.append("ArmISA::TLB::AlignWord")
272
273 if self.flavor in ("release", "relex"):
274 self.instFlags.extend(["IsMemBarrier",
275 "IsWriteBarrier",
276 "IsReadBarrier"])
277
278 # Disambiguate the class name for different flavors of stores
279 if self.flavor != "normal":
280 self.Name = "%s_%s" % (self.name.upper(), self.Name)
281
282 def emit(self):
283 # Address computation code
284 eaCode = "EA = Base"
285 if not self.post:
286 eaCode += self.offset
287 eaCode += ";"
288
289 if self.flavor == "fp":
290 eaCode += vfpEnabledCheckCode
291
292 self.codeBlobs["ea_code"] = eaCode
293
294 # Code that actually handles the access
295 if self.flavor == "fp":
296 accCode = '''
297 uint64_t swappedMem = (uint64_t)FpDest_uw |
298 ((uint64_t)FpDest2_uw << 32);
299 Mem_ud = cSwap(swappedMem, ((CPSR)Cpsr).e);
300 '''
301 else:
302 accCode = '''
303 CPSR cpsr = Cpsr;
304 Mem_ud = (uint64_t)cSwap(Dest_uw, cpsr.e) |
305 ((uint64_t)cSwap(Dest2_uw, cpsr.e) << 32);
306 '''
307
308 self.codeBlobs["memacc_code"] = accCode
309
310 # Push it out to the output files
311 base = buildMemBase(self.basePrefix, self.post, self.writeback)
312 wbDecl = None
313 if self.writeback:
314 wbDecl = self.wbDecl
315 self.emitHelper(base, wbDecl)
316
317 def storeDoubleImmClassName(post, add, writeback):
318 return memClassName("STORE_IMMD", post, add, writeback, 4, False, False)
319
320 class StoreDoubleImmEx(StoreImmInst, StoreDouble):
321 execBase = 'StoreEx'
322 decConstBase = 'StoreExDImm'
323 basePrefix = 'MemoryExDImm'
324 nameFunc = staticmethod(storeDoubleImmClassName)
325
326 def __init__(self, *args, **kargs):
327 super(StoreDoubleImmEx, self).__init__(*args, **kargs)
328 self.codeBlobs["postacc_code"] = \
329 "Result = !writeResult; SevMailbox = 1; LLSCLock = 0;"
330
331 class StoreDoubleImm(StoreImmInst, StoreDouble):
332 decConstBase = 'LoadStoreDImm'
333 basePrefix = 'MemoryDImm'
334 nameFunc = staticmethod(storeDoubleImmClassName)
335
336 def storeDoubleRegClassName(post, add, writeback):
337 return memClassName("STORE_REGD", post, add, writeback, 4, False, False)
338
339 class StoreDoubleReg(StoreRegInst, StoreDouble):
340 decConstBase = 'StoreDReg'
341 basePrefix = 'MemoryDReg'
342 nameFunc = staticmethod(storeDoubleRegClassName)
343
344 def buildStores(mnem, size=4, sign=False, user=False):
345 StoreImm(mnem, True, True, True, size, sign, user).emit()
346 StoreReg(mnem, True, True, True, size, sign, user).emit()
347 StoreImm(mnem, True, False, True, size, sign, user).emit()
348 StoreReg(mnem, True, False, True, size, sign, user).emit()
349 StoreImm(mnem, False, True, True, size, sign, user).emit()
350 StoreReg(mnem, False, True, True, size, sign, user).emit()
351 StoreImm(mnem, False, False, True, size, sign, user).emit()
352 StoreReg(mnem, False, False, True, size, sign, user).emit()
353 StoreImm(mnem, False, True, False, size, sign, user).emit()
354 StoreReg(mnem, False, True, False, size, sign, user).emit()
355 StoreImm(mnem, False, False, False, size, sign, user).emit()
356 StoreReg(mnem, False, False, False, size, sign, user).emit()
357
358 def buildDoubleStores(mnem):
359 StoreDoubleImm(mnem, True, True, True).emit()
360 StoreDoubleReg(mnem, True, True, True).emit()
361 StoreDoubleImm(mnem, True, False, True).emit()
362 StoreDoubleReg(mnem, True, False, True).emit()
363 StoreDoubleImm(mnem, False, True, True).emit()
364 StoreDoubleReg(mnem, False, True, True).emit()
365 StoreDoubleImm(mnem, False, False, True).emit()
366 StoreDoubleReg(mnem, False, False, True).emit()
367 StoreDoubleImm(mnem, False, True, False).emit()
368 StoreDoubleReg(mnem, False, True, False).emit()
369 StoreDoubleImm(mnem, False, False, False).emit()
370 StoreDoubleReg(mnem, False, False, False).emit()
371
372 def buildSrsStores(mnem):
373 SrsInst(mnem, True, True, True).emit()
374 SrsInst(mnem, True, True, False).emit()
375 SrsInst(mnem, True, False, True).emit()
376 SrsInst(mnem, True, False, False).emit()
377 SrsInst(mnem, False, True, True).emit()
378 SrsInst(mnem, False, True, False).emit()
379 SrsInst(mnem, False, False, True).emit()
380 SrsInst(mnem, False, False, False).emit()
381
382 buildStores("str")
383 buildStores("strt", user=True)
384 buildStores("strb", size=1)
385 buildStores("strbt", size=1, user=True)
386 buildStores("strh", size=2)
387 buildStores("strht", size=2, user=True)
388
389 buildSrsStores("srs")
390
391 buildDoubleStores("strd")
392
393 StoreImmEx("strex", False, True, False, size=4,
394 flavor="exclusive").emit()
395 StoreImmEx("strexh", False, True, False, size=2,
396 flavor="exclusive").emit()
397 StoreImmEx("strexb", False, True, False, size=1,
398 flavor="exclusive").emit()
399 StoreDoubleImmEx("strexd", False, True, False,
400 flavor="exclusive").emit()
401
402 StoreImm("stl", False, True, False, size=4, flavor="release").emit()
403 StoreImm("stlh", False, True, False, size=2, flavor="release").emit()
404 StoreImm("stlb", False, True, False, size=1, flavor="release").emit()
405 StoreImmEx("stlex", False, True, False, size=4, flavor="relex").emit()
406 StoreImmEx("stlexh", False, True, False, size=2, flavor="relex").emit()
407 StoreImmEx("stlexb", False, True, False, size=1, flavor="relex").emit()
408 StoreDoubleImmEx("stlexd", False, True, False, flavor="relex").emit()
409
410 StoreImm("vstr", False, True, False, size=4, flavor="fp").emit()
411 StoreImm("vstr", False, False, False, size=4, flavor="fp").emit()
412 StoreDoubleImm("vstr", False, True, False, flavor="fp").emit()
413 StoreDoubleImm("vstr", False, False, False, flavor="fp").emit()
414}};