amo64.isa (14150:1391e94a7b95) amo64.isa (14157:0f836da31d9c)
1// -*- mode:c++ -*-
2
3// Copyright (c) 2018 Metempsy Technology Consulting
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: Jordi Vaquero
39
40let {{
41
42 import math
43
44 OP_DICT = { "CAS" : 'if (a == *b){*b = c;}',
45 "SWP" : '*b = c;',
46 "ADD" : '*b += c;',
47 "EOR" : '*b ^= c;',
48 "CLR" : '*b &= ~c;',
49 "SET" : '*b |= c;',
50 "MAX" : '*b = std::max(*b, c);',
51 "MIN" : '*b = std::min(*b, c);', }
52
53 MASKS = { 1: 0xFF,
54 2: 0xFFFF,
55 4: 0xFFFFFFFF,
56 8: 0xFFFFFFFFFFFFFFFF,
57 }
58
59 header_output = ""
60 decoder_output = ""
61 exec_output = ""
62
63 class AtomicInst64(LoadStoreInst):
64 execBase = 'AtomicInst64'
65 micro = False
66
67 def __init__(self, mnem, Name, size=4, user=False, flavor="normal",
1// -*- mode:c++ -*-
2
3// Copyright (c) 2018 Metempsy Technology Consulting
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: Jordi Vaquero
39
40let {{
41
42 import math
43
44 OP_DICT = { "CAS" : 'if (a == *b){*b = c;}',
45 "SWP" : '*b = c;',
46 "ADD" : '*b += c;',
47 "EOR" : '*b ^= c;',
48 "CLR" : '*b &= ~c;',
49 "SET" : '*b |= c;',
50 "MAX" : '*b = std::max(*b, c);',
51 "MIN" : '*b = std::min(*b, c);', }
52
53 MASKS = { 1: 0xFF,
54 2: 0xFFFF,
55 4: 0xFFFFFFFF,
56 8: 0xFFFFFFFFFFFFFFFF,
57 }
58
59 header_output = ""
60 decoder_output = ""
61 exec_output = ""
62
63 class AtomicInst64(LoadStoreInst):
64 execBase = 'AtomicInst64'
65 micro = False
66
67 def __init__(self, mnem, Name, size=4, user=False, flavor="normal",
68 unsign=True, top = False, paired=False):
68 unsign=True, top = False, paired=False, ret_op=True):
69 super(AtomicInst64, self).__init__()
70
71 self.name= mnem
72 self.Name = Name
73 self.size = size
74 self.user = user
75 self.flavor = flavor
76 self.unsign = unsign
77 self.top = top
78 self.paired = paired
79
80 self.memFlags = ["ArmISA::TLB::MustBeOne"]
81 self.instFlags = ["IsAtomic"]
82 self.codeBlobs = { "postacc_code" : "" }
83 self.codeBlobs['usrDecl'] = ""
84
85 # Add memory request flags where necessary
86 if self.user:
87 self.memFlags.append("ArmISA::TLB::UserMode")
88
89 sz = self.size*2 if paired else self.size
90 self.memFlags.append("%d" % int(math.log(sz, 2)))
91
92 if self.micro:
93 self.instFlags.append("IsMicroop")
94
95 if self.flavor in ("release", "acquire_release", "acquire"):
96 self.instFlags.append("IsMemBarrier")
97 if self.flavor in ("release", "acquire_release"):
98 self.instFlags.append("IsWriteBarrier")
99 if self.flavor in ("acquire_release", "acquire"):
100 self.instFlags.append("IsReadBarrier")
69 super(AtomicInst64, self).__init__()
70
71 self.name= mnem
72 self.Name = Name
73 self.size = size
74 self.user = user
75 self.flavor = flavor
76 self.unsign = unsign
77 self.top = top
78 self.paired = paired
79
80 self.memFlags = ["ArmISA::TLB::MustBeOne"]
81 self.instFlags = ["IsAtomic"]
82 self.codeBlobs = { "postacc_code" : "" }
83 self.codeBlobs['usrDecl'] = ""
84
85 # Add memory request flags where necessary
86 if self.user:
87 self.memFlags.append("ArmISA::TLB::UserMode")
88
89 sz = self.size*2 if paired else self.size
90 self.memFlags.append("%d" % int(math.log(sz, 2)))
91
92 if self.micro:
93 self.instFlags.append("IsMicroop")
94
95 if self.flavor in ("release", "acquire_release", "acquire"):
96 self.instFlags.append("IsMemBarrier")
97 if self.flavor in ("release", "acquire_release"):
98 self.instFlags.append("IsWriteBarrier")
99 if self.flavor in ("acquire_release", "acquire"):
100 self.instFlags.append("IsReadBarrier")
101 self.memFlags.append('Request::ATOMIC_RETURN_OP')
101 if ret_op:
102 self.memFlags.append('Request::ATOMIC_RETURN_OP')
103 else:
104 self.memFlags.append('Request::ATOMIC_NO_RETURN_OP')
102
103 def emitHelper(self, base = 'Memory64', wbDecl = None, ):
104 global header_output, decoder_output, exec_output
105
106 # If this is a microop itself, don't allow anything that would
107 # require further microcoding.
108 if self.micro:
109 assert not wbDecl
110
105
106 def emitHelper(self, base = 'Memory64', wbDecl = None, ):
107 global header_output, decoder_output, exec_output
108
109 # If this is a microop itself, don't allow anything that would
110 # require further microcoding.
111 if self.micro:
112 assert not wbDecl
113
111 fa_code = None
112 if not self.micro :
113 #and self.flavor in ("normal", "release"):
114 fa_code = '''
115 fault->annotate(ArmFault::SAS, %s);
116 fault->annotate(ArmFault::SSE, false);
117 fault->annotate(ArmFault::SRT, dest);
118 fault->annotate(ArmFault::SF, %s);
119 fault->annotate(ArmFault::AR, %s);
120 ''' % ("0" if self.size == 1 else
121 "1" if self.size == 2 else
122 "2" if self.size == 4 else "3",
123 "true" if self.size == 8 else "false",
124 "true" if self.flavor != "normal" else "false")
125 sas_code = "3"
126 if self.size == 1 :
127 sas_code = "0"
128 elif self.size == 2:
129 sas_code = "1"
130 elif self.size == 4:
131 sas_code = "2"
132
133 if self.paired and sas_code == "3":
134 sas_code = "4"
135 if self.paired and sas_code == "2":
136 sas_code = "3"
137
138
139 fa_code = '''
140 fault->annotate(ArmFault::SAS, %s);
141 fault->annotate(ArmFault::SSE, %s);
142 fault->annotate(ArmFault::SRT, dest);
143 fault->annotate(ArmFault::SF, %s);
144 fault->annotate(ArmFault::AR, %s);
145 ''' % (sas_code,
146 "true" if not self.unsign else "false",
147 "true" if self.size == 8 else "false",
148 "true" if self.flavor != "normal" else "false")
149
150 (newHeader, newDecoder, newExec) = \
151 self.fillTemplates(self.name, self.Name, self.codeBlobs,
152 self.memFlags, self.instFlags,
153 base, wbDecl, faCode=fa_code)
154
155 header_output += newHeader
156 decoder_output += newDecoder
157 exec_output += newExec
158
159 def buildEACode(self):
160 # Address computation
161 eaCode = SPAlignmentCheckCode + "EA = XBase"
162 if self.size == 16:
163 if self.top:
164 eaCode += " + (isBigEndian64(xc->tcBase()) ? 0 : 8)"
165 else:
166 eaCode += " + (isBigEndian64(xc->tcBase()) ? 8 : 0)"
167 if not self.post:
168 eaCode += self.offset
169 eaCode += ";"
170 self.codeBlobs["ea_code"] = eaCode
171
172
173 class AtomicSingleOp(AtomicInst64):
174 decConstBase = 'AmoOp'
175 base = 'ArmISA::MemoryEx64'
176 writeback = True
177 post = False
178 execBase = 'AmoOp'
179
180 def __init__(self, *args, **kargs):
181 super(AtomicSingleOp, self).__init__(*args, **kargs)
182 self.suffix = buildMemSuffix(not self.unsign, self.size)
183 if self.size == 8:
184 self.res = 'XResult_ud' #if self.unsign else 'XResult_sd'
185 self.des = 'XDest_ud' #if self.unsign else 'XDest_sd'
186 self.tp = 'uint64_t' if self.unsign else 'int64_t'
187 self.utp = 'uint64_t'
188 self.suffix = '_sd' if not self.unsign else '_ud'
189 elif self.size == 4:
190 self.res = 'XResult_uw' #if self.unsign else 'XResult_sw'
191 self.des = 'XDest_uw' #if self.unsign else 'XDest_sw'
192 self.tp = 'uint32_t' if self.unsign else 'int32_t'
193 self.utp = 'uint32_t'
194 elif self.size == 2:
195 self.res = 'XResult_uh' #if self.unsign else 'XResult_sh'
196 self.des = 'XDest_uh' #if self.unsign else 'XDest_sh'
197 self.tp = 'uint16_t' if self.unsign else 'int16_t'
198 self.utp = 'uint16_t'
199 elif self.size == 1:
200 self.res = 'XResult_ub' #if self.unsign else 'XResult_sb'
201 self.des = 'XDest_ub' #if self.unsign else 'XDest_sb'
202 self.tp = 'uint8_t' if self.unsign else 'int8_t'
203 self.utp = 'uint8_t'
204 self.offset = ""
205 store_res = '''
206 %(result)s = cSwap(Mem%(suffix)s,
207 isBigEndian64(xc->tcBase()));
208 '''
209 store_res = store_res % {"result":self.res, "suffix":self.suffix}
210 self.codeBlobs["postacc_code"] = \
211 store_res + " SevMailbox = 1; LLSCLock = 0;"
212
213 def emit(self, op):
214 self.buildEACode()
215 usrDecl = "%(type)s valRs;\n" % {'type': self.tp}
216 self.codeBlobs['usrDecl'] = usrDecl
217
218 opcode = "valRs = cSwap(%(dest)s,"\
219 " isBigEndian64(xc->tcBase()));\n"
220 opcode += "TypedAtomicOpFunctor<%(type)s> *amo_op = "\
221 "new AtomicGeneric3Op<%(type)s>(Mem%(suffix)s,"\
222 " valRs, [](%(type)s* b, %(type)s a,"\
223 " %(type)s c){ %(op)s });\n"
224
225 opcode = opcode % {"suffix": self.suffix,
226 "type": self.tp ,
227 "dest": self.des,
228 "op": op}
229 self.codeBlobs['amo_code'] = opcode
230 accCode = "Mem%(suffix)s = cSwap(%(result)s,"\
231 " isBigEndian64(xc->tcBase()));"
232 accCode = accCode % { "result": self.res, "type":self.tp,
233 "suffix": self.suffix}
234 self.codeBlobs["memacc_code"] = accCode
235 self.emitHelper(self.base)
236
237
238 AtomicSingleOp("cas", "CAS64", 8, unsign=True,
239 flavor="normal").emit(OP_DICT['CAS'])
240 AtomicSingleOp("casa", "CASA64", 8, unsign=True,
241 flavor="acquire").emit(OP_DICT['CAS'])
242 AtomicSingleOp("casal", "CASAL64", 8, unsign=True,
243 flavor="acquire_release").emit(OP_DICT['CAS'])
244 AtomicSingleOp("casl", "CASL64", 8, unsign=True,
245 flavor="release").emit(OP_DICT['CAS'])
246
247 AtomicSingleOp("casb", "CASB", 1, unsign=True,
248 flavor="normal").emit(OP_DICT['CAS'])
249 AtomicSingleOp("casab", "CASAB", 1, unsign=True,
250 flavor="acquire").emit(OP_DICT['CAS'])
251 AtomicSingleOp("casalb", "CASALB", 1, unsign=True,
252 flavor="acquire_release").emit(OP_DICT['CAS'])
253 AtomicSingleOp("caslb", "CASLB", 1, unsign=True,
254 flavor="release").emit(OP_DICT['CAS'])
255
256 AtomicSingleOp("cash", "CASH", 2, unsign=True,
257 flavor="normal").emit(OP_DICT['CAS'])
258 AtomicSingleOp("casah", "CASAH", 2, unsign=True,
259 flavor="acquire").emit(OP_DICT['CAS'])
260 AtomicSingleOp("casalh", "CASALH", 2, unsign=True,
261 flavor="acquire_release").emit(OP_DICT['CAS'])
262 AtomicSingleOp("caslh", "CASLH", 2, unsign=True,
263 flavor="release").emit(OP_DICT['CAS'])
264
265 AtomicSingleOp("cas", "CAS32", 4, unsign=True,
266 flavor="normal").emit(OP_DICT['CAS'])
267 AtomicSingleOp("casa", "CASA32", 4, unsign=True,
268 flavor="acquire").emit(OP_DICT['CAS'])
269 AtomicSingleOp("casal", "CASAL32", 4, unsign=True,
270 flavor="acquire_release").emit(OP_DICT['CAS'])
271 AtomicSingleOp("casl", "CASL32", 4, unsign=True,
272 flavor="release").emit(OP_DICT['CAS'])
273
274 class CasPair64(AtomicInst64):
275 decConstBase = 'AmoPairOp'
276 base = 'ArmISA::MemoryEx64'
277 writeback = True
278 post = False
279 execBase = 'AmoOp'
280
281 def __init__(self, *args, **kargs):
282 super(CasPair64, self).__init__(*args, **kargs)
283 self.paired = True
284 self.offset = ""
285 if self.size == 8:
286 self.res = 'XResult_ud'
287 self.des = 'XDest_ud'
288 self.tp = 'std::array<uint64_t, 2>'
289 self.suffix = "_tud"
290 store_res = '''
291 %(result)s = cSwap(Mem%(suffix)s[0],
292 isBigEndian64(xc->tcBase()));
293 uint64_t result2 = cSwap(Mem%(suffix)s[1],
294 isBigEndian64(xc->tcBase()));
295 xc->setIntRegOperand(this, r2_dst, (result2)
296 & mask(aarch64 ? 64 : 32));
297 '''
298 elif self.size == 4:
299 self.res = 'Result_uw'
300 self.des = 'WDest_uw'
301 self.tp = 'uint64_t'
302 self.suffix = "_ud"
303 store_res = '''
304 uint64_t data = cSwap(Mem%(suffix)s,
305 isBigEndian64(xc->tcBase()));
306 %(result)s = isBigEndian64(xc->tcBase())
307 ? (data >> 32)
308 : (uint32_t)data;
309 uint32_t result2 = isBigEndian64(xc->tcBase())
310 ? (uint32_t)data
311 : (data >> 32);
312 xc->setIntRegOperand(this, r2_dst, (result2) &
313 mask(aarch64 ? 64 : 32));
314 '''
315
316 store_res = store_res % {"result":self.res, "suffix":self.suffix}
317 usrDecl = "%(type)s valRs;\n" % {'type': self.tp}
318 self.codeBlobs['usrDecl'] = usrDecl
319 self.codeBlobs["postacc_code"] = \
320 store_res + " SevMailbox = 1; LLSCLock = 0;"
321
322 def emit(self):
323 self.buildEACode()
324
325 # Code that actually handles the access
326
327 if self.size == 4:
328 accCode = \
329 "uint32_t result2 = ((xc->readIntRegOperand(this, r2_src))"\
330 " & mask(aarch64 ? 64 : 32)) ;\n"\
331 " uint32_t dest2 = ((xc->readIntRegOperand(this, d2_src)) "\
332 " & mask(aarch64 ? 64 : 32)) ;"
333 accCode += '''
334 uint64_t data = dest2;
335 data = isBigEndian64(xc->tcBase())
336 ? ((uint64_t(WDest_uw) << 32) | data)
337 : ((data << 32) | WDest_uw);
338 valRs = cSwap(data, isBigEndian64(xc->tcBase()));
339 uint64_t data2 = result2 ;
340 data2 = isBigEndian64(xc->tcBase())
341 ? ((uint64_t(Result_uw) << 32) | data2)
342 : ((data2 << 32) | Result_uw);
343 Mem_ud = cSwap(data2, isBigEndian64(xc->tcBase()));
344 '''
345
346 opcode = "TypedAtomicOpFunctor<%(type)s> *amo_op = "\
347 "new AtomicGeneric3Op<%(type)s>(Mem%(suffix)s,"\
348 " valRs, [](%(type)s* b, %(type)s a,"\
349 " %(type)s c){ %(op)s });\n"
350
351 elif self.size == 8:
352 accCode = ""\
353 "uint64_t result2 = ((xc->readIntRegOperand(this, r2_src))"\
354 " & mask(aarch64 ? 64 : 32)) ;\n"\
355 " uint64_t dest2 = ((xc->readIntRegOperand(this, d2_src)) "\
356 " & mask(aarch64 ? 64 : 32)) ;"
357 accCode += '''
358 // This temporary needs to be here so that the parser
359 // will correctly identify this instruction as a store.
360 std::array<uint64_t, 2> temp;
361 temp[0] = cSwap(XDest_ud,isBigEndian64(xc->tcBase()));
362 temp[1] = cSwap(dest2,isBigEndian64(xc->tcBase()));
363 valRs = temp;
364 std::array<uint64_t, 2> temp2;
365 temp2[0] = cSwap(XResult_ud,isBigEndian64(xc->tcBase()));
366 temp2[1] = cSwap(result2,isBigEndian64(xc->tcBase()));
367 Mem_tud = temp2;
368 '''
369
370 opcode = "TypedAtomicOpFunctor<uint64_t> *amo_op = "\
371 "new AtomicGenericPair3Op<uint64_t>(Mem_tud, "\
372 "valRs, [](uint64_t* b, std::array<uint64_t,2> a,"\
373 '''
374 std::array<uint64_t,2> c){
375 if(a[0]==b[0] && a[1]==b[1]){
376 b[0] = c[0]; b[1] = c[1];
377 }
378 });'''
379
380 opcode = opcode % { "suffix" : self.suffix,
381 "type": self.tp,
382 "op": OP_DICT['CAS']}
383 self.codeBlobs['amo_code'] = opcode
384 self.codeBlobs["memacc_code"] = accCode % {"type": self.tp}
385
386 # Push it out to the output files
387 self.emitHelper(self.base)
388
389 CasPair64("casp", "CASP64", 8, flavor="normal", paired=True).emit()
390 CasPair64("caspa", "CASPA64", 8, flavor="acquire", paired=True).emit()
391 CasPair64("caspal", "CASPAL64", 8, flavor="acquire_release",
392 paired=True).emit()
393 CasPair64("caspl", "CASPL64", 8, flavor="release", paired=True).emit()
394
395 CasPair64("casp", "CASP32", 4, flavor="normal", paired=True).emit()
396 CasPair64("caspa", "CASPA32", 4, flavor="acquire", paired=True).emit()
397 CasPair64("caspal", "CASPAL32", 4, flavor="acquire_release",
398 paired=True).emit()
399 CasPair64("caspl", "CASPL32", 4, flavor="release", paired=True).emit()
400
114 sas_code = "3"
115 if self.size == 1 :
116 sas_code = "0"
117 elif self.size == 2:
118 sas_code = "1"
119 elif self.size == 4:
120 sas_code = "2"
121
122 if self.paired and sas_code == "3":
123 sas_code = "4"
124 if self.paired and sas_code == "2":
125 sas_code = "3"
126
127
128 fa_code = '''
129 fault->annotate(ArmFault::SAS, %s);
130 fault->annotate(ArmFault::SSE, %s);
131 fault->annotate(ArmFault::SRT, dest);
132 fault->annotate(ArmFault::SF, %s);
133 fault->annotate(ArmFault::AR, %s);
134 ''' % (sas_code,
135 "true" if not self.unsign else "false",
136 "true" if self.size == 8 else "false",
137 "true" if self.flavor != "normal" else "false")
138
139 (newHeader, newDecoder, newExec) = \
140 self.fillTemplates(self.name, self.Name, self.codeBlobs,
141 self.memFlags, self.instFlags,
142 base, wbDecl, faCode=fa_code)
143
144 header_output += newHeader
145 decoder_output += newDecoder
146 exec_output += newExec
147
148 def buildEACode(self):
149 # Address computation
150 eaCode = SPAlignmentCheckCode + "EA = XBase"
151 if self.size == 16:
152 if self.top:
153 eaCode += " + (isBigEndian64(xc->tcBase()) ? 0 : 8)"
154 else:
155 eaCode += " + (isBigEndian64(xc->tcBase()) ? 8 : 0)"
156 if not self.post:
157 eaCode += self.offset
158 eaCode += ";"
159 self.codeBlobs["ea_code"] = eaCode
160
161
162 class AtomicSingleOp(AtomicInst64):
163 decConstBase = 'AmoOp'
164 base = 'ArmISA::MemoryEx64'
165 writeback = True
166 post = False
167 execBase = 'AmoOp'
168
169 def __init__(self, *args, **kargs):
170 super(AtomicSingleOp, self).__init__(*args, **kargs)
171 self.suffix = buildMemSuffix(not self.unsign, self.size)
172 if self.size == 8:
173 self.res = 'XResult_ud' #if self.unsign else 'XResult_sd'
174 self.des = 'XDest_ud' #if self.unsign else 'XDest_sd'
175 self.tp = 'uint64_t' if self.unsign else 'int64_t'
176 self.utp = 'uint64_t'
177 self.suffix = '_sd' if not self.unsign else '_ud'
178 elif self.size == 4:
179 self.res = 'XResult_uw' #if self.unsign else 'XResult_sw'
180 self.des = 'XDest_uw' #if self.unsign else 'XDest_sw'
181 self.tp = 'uint32_t' if self.unsign else 'int32_t'
182 self.utp = 'uint32_t'
183 elif self.size == 2:
184 self.res = 'XResult_uh' #if self.unsign else 'XResult_sh'
185 self.des = 'XDest_uh' #if self.unsign else 'XDest_sh'
186 self.tp = 'uint16_t' if self.unsign else 'int16_t'
187 self.utp = 'uint16_t'
188 elif self.size == 1:
189 self.res = 'XResult_ub' #if self.unsign else 'XResult_sb'
190 self.des = 'XDest_ub' #if self.unsign else 'XDest_sb'
191 self.tp = 'uint8_t' if self.unsign else 'int8_t'
192 self.utp = 'uint8_t'
193 self.offset = ""
194 store_res = '''
195 %(result)s = cSwap(Mem%(suffix)s,
196 isBigEndian64(xc->tcBase()));
197 '''
198 store_res = store_res % {"result":self.res, "suffix":self.suffix}
199 self.codeBlobs["postacc_code"] = \
200 store_res + " SevMailbox = 1; LLSCLock = 0;"
201
202 def emit(self, op):
203 self.buildEACode()
204 usrDecl = "%(type)s valRs;\n" % {'type': self.tp}
205 self.codeBlobs['usrDecl'] = usrDecl
206
207 opcode = "valRs = cSwap(%(dest)s,"\
208 " isBigEndian64(xc->tcBase()));\n"
209 opcode += "TypedAtomicOpFunctor<%(type)s> *amo_op = "\
210 "new AtomicGeneric3Op<%(type)s>(Mem%(suffix)s,"\
211 " valRs, [](%(type)s* b, %(type)s a,"\
212 " %(type)s c){ %(op)s });\n"
213
214 opcode = opcode % {"suffix": self.suffix,
215 "type": self.tp ,
216 "dest": self.des,
217 "op": op}
218 self.codeBlobs['amo_code'] = opcode
219 accCode = "Mem%(suffix)s = cSwap(%(result)s,"\
220 " isBigEndian64(xc->tcBase()));"
221 accCode = accCode % { "result": self.res, "type":self.tp,
222 "suffix": self.suffix}
223 self.codeBlobs["memacc_code"] = accCode
224 self.emitHelper(self.base)
225
226
227 AtomicSingleOp("cas", "CAS64", 8, unsign=True,
228 flavor="normal").emit(OP_DICT['CAS'])
229 AtomicSingleOp("casa", "CASA64", 8, unsign=True,
230 flavor="acquire").emit(OP_DICT['CAS'])
231 AtomicSingleOp("casal", "CASAL64", 8, unsign=True,
232 flavor="acquire_release").emit(OP_DICT['CAS'])
233 AtomicSingleOp("casl", "CASL64", 8, unsign=True,
234 flavor="release").emit(OP_DICT['CAS'])
235
236 AtomicSingleOp("casb", "CASB", 1, unsign=True,
237 flavor="normal").emit(OP_DICT['CAS'])
238 AtomicSingleOp("casab", "CASAB", 1, unsign=True,
239 flavor="acquire").emit(OP_DICT['CAS'])
240 AtomicSingleOp("casalb", "CASALB", 1, unsign=True,
241 flavor="acquire_release").emit(OP_DICT['CAS'])
242 AtomicSingleOp("caslb", "CASLB", 1, unsign=True,
243 flavor="release").emit(OP_DICT['CAS'])
244
245 AtomicSingleOp("cash", "CASH", 2, unsign=True,
246 flavor="normal").emit(OP_DICT['CAS'])
247 AtomicSingleOp("casah", "CASAH", 2, unsign=True,
248 flavor="acquire").emit(OP_DICT['CAS'])
249 AtomicSingleOp("casalh", "CASALH", 2, unsign=True,
250 flavor="acquire_release").emit(OP_DICT['CAS'])
251 AtomicSingleOp("caslh", "CASLH", 2, unsign=True,
252 flavor="release").emit(OP_DICT['CAS'])
253
254 AtomicSingleOp("cas", "CAS32", 4, unsign=True,
255 flavor="normal").emit(OP_DICT['CAS'])
256 AtomicSingleOp("casa", "CASA32", 4, unsign=True,
257 flavor="acquire").emit(OP_DICT['CAS'])
258 AtomicSingleOp("casal", "CASAL32", 4, unsign=True,
259 flavor="acquire_release").emit(OP_DICT['CAS'])
260 AtomicSingleOp("casl", "CASL32", 4, unsign=True,
261 flavor="release").emit(OP_DICT['CAS'])
262
263 class CasPair64(AtomicInst64):
264 decConstBase = 'AmoPairOp'
265 base = 'ArmISA::MemoryEx64'
266 writeback = True
267 post = False
268 execBase = 'AmoOp'
269
270 def __init__(self, *args, **kargs):
271 super(CasPair64, self).__init__(*args, **kargs)
272 self.paired = True
273 self.offset = ""
274 if self.size == 8:
275 self.res = 'XResult_ud'
276 self.des = 'XDest_ud'
277 self.tp = 'std::array<uint64_t, 2>'
278 self.suffix = "_tud"
279 store_res = '''
280 %(result)s = cSwap(Mem%(suffix)s[0],
281 isBigEndian64(xc->tcBase()));
282 uint64_t result2 = cSwap(Mem%(suffix)s[1],
283 isBigEndian64(xc->tcBase()));
284 xc->setIntRegOperand(this, r2_dst, (result2)
285 & mask(aarch64 ? 64 : 32));
286 '''
287 elif self.size == 4:
288 self.res = 'Result_uw'
289 self.des = 'WDest_uw'
290 self.tp = 'uint64_t'
291 self.suffix = "_ud"
292 store_res = '''
293 uint64_t data = cSwap(Mem%(suffix)s,
294 isBigEndian64(xc->tcBase()));
295 %(result)s = isBigEndian64(xc->tcBase())
296 ? (data >> 32)
297 : (uint32_t)data;
298 uint32_t result2 = isBigEndian64(xc->tcBase())
299 ? (uint32_t)data
300 : (data >> 32);
301 xc->setIntRegOperand(this, r2_dst, (result2) &
302 mask(aarch64 ? 64 : 32));
303 '''
304
305 store_res = store_res % {"result":self.res, "suffix":self.suffix}
306 usrDecl = "%(type)s valRs;\n" % {'type': self.tp}
307 self.codeBlobs['usrDecl'] = usrDecl
308 self.codeBlobs["postacc_code"] = \
309 store_res + " SevMailbox = 1; LLSCLock = 0;"
310
311 def emit(self):
312 self.buildEACode()
313
314 # Code that actually handles the access
315
316 if self.size == 4:
317 accCode = \
318 "uint32_t result2 = ((xc->readIntRegOperand(this, r2_src))"\
319 " & mask(aarch64 ? 64 : 32)) ;\n"\
320 " uint32_t dest2 = ((xc->readIntRegOperand(this, d2_src)) "\
321 " & mask(aarch64 ? 64 : 32)) ;"
322 accCode += '''
323 uint64_t data = dest2;
324 data = isBigEndian64(xc->tcBase())
325 ? ((uint64_t(WDest_uw) << 32) | data)
326 : ((data << 32) | WDest_uw);
327 valRs = cSwap(data, isBigEndian64(xc->tcBase()));
328 uint64_t data2 = result2 ;
329 data2 = isBigEndian64(xc->tcBase())
330 ? ((uint64_t(Result_uw) << 32) | data2)
331 : ((data2 << 32) | Result_uw);
332 Mem_ud = cSwap(data2, isBigEndian64(xc->tcBase()));
333 '''
334
335 opcode = "TypedAtomicOpFunctor<%(type)s> *amo_op = "\
336 "new AtomicGeneric3Op<%(type)s>(Mem%(suffix)s,"\
337 " valRs, [](%(type)s* b, %(type)s a,"\
338 " %(type)s c){ %(op)s });\n"
339
340 elif self.size == 8:
341 accCode = ""\
342 "uint64_t result2 = ((xc->readIntRegOperand(this, r2_src))"\
343 " & mask(aarch64 ? 64 : 32)) ;\n"\
344 " uint64_t dest2 = ((xc->readIntRegOperand(this, d2_src)) "\
345 " & mask(aarch64 ? 64 : 32)) ;"
346 accCode += '''
347 // This temporary needs to be here so that the parser
348 // will correctly identify this instruction as a store.
349 std::array<uint64_t, 2> temp;
350 temp[0] = cSwap(XDest_ud,isBigEndian64(xc->tcBase()));
351 temp[1] = cSwap(dest2,isBigEndian64(xc->tcBase()));
352 valRs = temp;
353 std::array<uint64_t, 2> temp2;
354 temp2[0] = cSwap(XResult_ud,isBigEndian64(xc->tcBase()));
355 temp2[1] = cSwap(result2,isBigEndian64(xc->tcBase()));
356 Mem_tud = temp2;
357 '''
358
359 opcode = "TypedAtomicOpFunctor<uint64_t> *amo_op = "\
360 "new AtomicGenericPair3Op<uint64_t>(Mem_tud, "\
361 "valRs, [](uint64_t* b, std::array<uint64_t,2> a,"\
362 '''
363 std::array<uint64_t,2> c){
364 if(a[0]==b[0] && a[1]==b[1]){
365 b[0] = c[0]; b[1] = c[1];
366 }
367 });'''
368
369 opcode = opcode % { "suffix" : self.suffix,
370 "type": self.tp,
371 "op": OP_DICT['CAS']}
372 self.codeBlobs['amo_code'] = opcode
373 self.codeBlobs["memacc_code"] = accCode % {"type": self.tp}
374
375 # Push it out to the output files
376 self.emitHelper(self.base)
377
378 CasPair64("casp", "CASP64", 8, flavor="normal", paired=True).emit()
379 CasPair64("caspa", "CASPA64", 8, flavor="acquire", paired=True).emit()
380 CasPair64("caspal", "CASPAL64", 8, flavor="acquire_release",
381 paired=True).emit()
382 CasPair64("caspl", "CASPL64", 8, flavor="release", paired=True).emit()
383
384 CasPair64("casp", "CASP32", 4, flavor="normal", paired=True).emit()
385 CasPair64("caspa", "CASPA32", 4, flavor="acquire", paired=True).emit()
386 CasPair64("caspal", "CASPAL32", 4, flavor="acquire_release",
387 paired=True).emit()
388 CasPair64("caspl", "CASPL32", 4, flavor="release", paired=True).emit()
389
390 #Set of LD<OP> atomic instructions
391
392 class AtomicArithmeticSingleOp(AtomicSingleOp):
393 decConstBase = 'AmoArithmeticOp'
394 base = 'ArmISA::MemoryEx64'
395 writeback = True
396 post = False
397 execBase = 'AmoOp'
398
399 def __init__(self, *args, **kargs):
400 super(AtomicArithmeticSingleOp, self).__init__(*args, **kargs)
401 store_res = "%(utype)s unsMem = Mem%(suffix)s"
402
403 if self.size != 8:
404 store_res += " & %(mask)s"
405
406 store_res += ";\n"
407 store_res += ''' if (!isXZR) %(dest)s = cSwap(unsMem,
408 isBigEndian64(xc->tcBase()));
409 '''
410 store_res = store_res % { "dest": self.des, "suffix":self.suffix,
411 "mask": MASKS[self.size], "utype": self.utp}
412 self.codeBlobs["postacc_code"] = \
413 store_res + " SevMailbox = 1; LLSCLock = 0;"
414
415 def emit(self, op):
416 self.buildEACode()
417
418 opcode = "%(type)s val = cSwap(%(result)s,"\
419 " isBigEndian64(xc->tcBase()));\n"
420 opcode += "TypedAtomicOpFunctor<%(type)s> *amo_op = "\
421 "new AtomicGeneric3Op<%(type)s>(Mem%(suffix)s,"\
422 " val, [](%(type)s* b, %(type)s a,"\
423 " %(type)s c){ %(op)s });\n"
424
425 opcode = opcode % { "suffix" : self.suffix,
426 "type": self.tp , "result": self.res, "op": op}
427 self.codeBlobs['amo_code'] = opcode
428 accCode = "Mem%(suffix)s = cSwap(%(dest)s,"\
429 "isBigEndian64(xc->tcBase()));"
430 accCode = accCode % { "dest": self.des, "suffix":self.suffix}
431 self.codeBlobs["memacc_code"] = accCode
432 self.emitHelper(self.base)
433
434
435 AtomicArithmeticSingleOp("ldaddb", "LDADDB", 1, unsign=True,
436 flavor="normal").emit(OP_DICT['ADD'])
437 AtomicArithmeticSingleOp("ldaddlb", "LDADDLB", 1, unsign=True,
438 flavor="release").emit(OP_DICT['ADD'])
439 AtomicArithmeticSingleOp("ldaddab", "LDADDAB", 1, unsign=True,
440 flavor="acquire").emit(OP_DICT['ADD'])
441 AtomicArithmeticSingleOp("ldaddlab", "LDADDLAB", 1, unsign=True,
442 flavor="acquire_release").emit(OP_DICT['ADD'])
443 AtomicArithmeticSingleOp("ldaddh", "LDADDH", 2, unsign=True,
444 flavor="normal").emit(OP_DICT['ADD'])
445 AtomicArithmeticSingleOp("ldaddlh", "LDADDLH", 2, unsign=True,
446 flavor="release").emit(OP_DICT['ADD'])
447 AtomicArithmeticSingleOp("ldaddah", "LDADDAH", 2, unsign=True,
448 flavor="acquire").emit(OP_DICT['ADD'])
449 AtomicArithmeticSingleOp("ldaddlah", "LDADDLAH", 2, unsign=True,
450 flavor="acquire_release").emit(OP_DICT['ADD'])
451 AtomicArithmeticSingleOp("ldadd", "LDADD", 4, unsign=True,
452 flavor="normal").emit(OP_DICT['ADD'])
453 AtomicArithmeticSingleOp("ldaddl", "LDADDL", 4, unsign=True,
454 flavor="release").emit(OP_DICT['ADD'])
455 AtomicArithmeticSingleOp("ldadda", "LDADDA", 4, unsign=True,
456 flavor="acquire").emit(OP_DICT['ADD'])
457 AtomicArithmeticSingleOp("ldaddla", "LDADDLA", 4, unsign=True,
458 flavor="acquire_release").emit(OP_DICT['ADD'])
459 AtomicArithmeticSingleOp("ldadd64", "LDADD64", 8, unsign=True,
460 flavor="normal").emit(OP_DICT['ADD'])
461 AtomicArithmeticSingleOp("ldaddl64", "LDADDL64", 8, unsign=True,
462 flavor="release").emit(OP_DICT['ADD'])
463 AtomicArithmeticSingleOp("ldadda64", "LDADDA64", 8, unsign=True,
464 flavor="acquire").emit(OP_DICT['ADD'])
465 AtomicArithmeticSingleOp("ldaddla64", "LDADDLA64", 8, unsign=True,
466 flavor="acquire_release").emit(OP_DICT['ADD'])
467
468 AtomicArithmeticSingleOp("ldclrb", "LDCLRB", 1, unsign=True,
469 flavor="normal").emit(OP_DICT['CLR'])
470 AtomicArithmeticSingleOp("ldclrlb", "LDCLRLB", 1, unsign=True,
471 flavor="release").emit(OP_DICT['CLR'])
472 AtomicArithmeticSingleOp("ldclrab", "LDCLRAB", 1, unsign=True,
473 flavor="acquire").emit(OP_DICT['CLR'])
474 AtomicArithmeticSingleOp("ldclrlab", "LDCLRLAB", 1, unsign=True,
475 flavor="acquire_release").emit(OP_DICT['CLR'])
476 AtomicArithmeticSingleOp("ldclrh", "LDCLRH", 2, unsign=True,
477 flavor="normal").emit(OP_DICT['CLR'])
478 AtomicArithmeticSingleOp("ldclrlh", "LDCLRLH", 2, unsign=True,
479 flavor="release").emit(OP_DICT['CLR'])
480 AtomicArithmeticSingleOp("ldclrah", "LDCLRAH", 2, unsign=True,
481 flavor="acquire").emit(OP_DICT['CLR'])
482 AtomicArithmeticSingleOp("ldclrlah", "LDCLRLAH", 2, unsign=True,
483 flavor="acquire_release").emit(OP_DICT['CLR'])
484 AtomicArithmeticSingleOp("ldclr", "LDCLR", 4, unsign=True,
485 flavor="normal").emit(OP_DICT['CLR'])
486 AtomicArithmeticSingleOp("ldclrl", "LDCLRL", 4, unsign=True,
487 flavor="release").emit(OP_DICT['CLR'])
488 AtomicArithmeticSingleOp("ldclra", "LDCLRA", 4, unsign=True,
489 flavor="acquire").emit(OP_DICT['CLR'])
490 AtomicArithmeticSingleOp("ldclrla", "LDCLRLA", 4, unsign=True,
491 flavor="acquire_release").emit(OP_DICT['CLR'])
492 AtomicArithmeticSingleOp("ldclr64", "LDCLR64", 8, unsign=True,
493 flavor="normal").emit(OP_DICT['CLR'])
494 AtomicArithmeticSingleOp("ldclrl64", "LDCLRL64", 8, unsign=True,
495 flavor="release").emit(OP_DICT['CLR'])
496 AtomicArithmeticSingleOp("ldclra64", "LDCLRA64", 8, unsign=True,
497 flavor="acquire").emit(OP_DICT['CLR'])
498 AtomicArithmeticSingleOp("ldclrla64", "LDCLRLA64", 8, unsign=True,
499 flavor="acquire_release").emit(OP_DICT['CLR'])
500
501 AtomicArithmeticSingleOp("ldeorb", "LDEORB", 1, unsign=True,
502 flavor="normal").emit(OP_DICT['EOR'])
503 AtomicArithmeticSingleOp("ldeorlb", "LDEORLB", 1, unsign=True,
504 flavor="release").emit(OP_DICT['EOR'])
505 AtomicArithmeticSingleOp("ldeorab", "LDEORAB", 1, unsign=True,
506 flavor="acquire").emit(OP_DICT['EOR'])
507 AtomicArithmeticSingleOp("ldeorlab", "LDEORLAB", 1, unsign=True,
508 flavor="acquire_release").emit(OP_DICT['EOR'])
509 AtomicArithmeticSingleOp("ldeorh", "LDEORH", 2, unsign=True,
510 flavor="normal").emit(OP_DICT['EOR'])
511 AtomicArithmeticSingleOp("ldeorlh", "LDEORLH", 2, unsign=True,
512 flavor="release").emit(OP_DICT['EOR'])
513 AtomicArithmeticSingleOp("ldeorah", "LDEORAH", 2, unsign=True,
514 flavor="acquire").emit(OP_DICT['EOR'])
515 AtomicArithmeticSingleOp("ldeorlah", "LDEORLAH", 2, unsign=True,
516 flavor="acquire_release").emit(OP_DICT['EOR'])
517 AtomicArithmeticSingleOp("ldeor", "LDEOR", 4, unsign=True,
518 flavor="normal").emit(OP_DICT['EOR'])
519 AtomicArithmeticSingleOp("ldeorl", "LDEORL", 4, unsign=True,
520 flavor="release").emit(OP_DICT['EOR'])
521 AtomicArithmeticSingleOp("ldeora", "LDEORA", 4, unsign=True,
522 flavor="acquire").emit(OP_DICT['EOR'])
523 AtomicArithmeticSingleOp("ldeorla", "LDEORLA", 4, unsign=True,
524 flavor="acquire_release").emit(OP_DICT['EOR'])
525 AtomicArithmeticSingleOp("ldeor64", "LDEOR64", 8, unsign=True,
526 flavor="normal").emit(OP_DICT['EOR'])
527 AtomicArithmeticSingleOp("ldeorl64", "LDEORL64", 8, unsign=True,
528 flavor="release").emit(OP_DICT['EOR'])
529 AtomicArithmeticSingleOp("ldeora64", "LDEORA64", 8, unsign=True,
530 flavor="acquire").emit(OP_DICT['EOR'])
531 AtomicArithmeticSingleOp("ldeorla64", "LDEORLA64", 8, unsign=True,
532 flavor="acquire_release").emit(OP_DICT['EOR'])
533
534 AtomicArithmeticSingleOp("ldsetb", "LDSETB", 1, unsign=True,
535 flavor="normal").emit(OP_DICT['SET'])
536 AtomicArithmeticSingleOp("ldsetlb", "LDSETLB", 1, unsign=True,
537 flavor="release").emit(OP_DICT['SET'])
538 AtomicArithmeticSingleOp("ldsetab", "LDSETAB", 1, unsign=True,
539 flavor="acquire").emit(OP_DICT['SET'])
540 AtomicArithmeticSingleOp("ldsetlab", "LDSETLAB", 1, unsign=True,
541 flavor="acquire_release").emit(OP_DICT['SET'])
542 AtomicArithmeticSingleOp("ldseth", "LDSETH", 2, unsign=True,
543 flavor="normal").emit(OP_DICT['SET'])
544 AtomicArithmeticSingleOp("ldsetlh", "LDSETLH", 2, unsign=True,
545 flavor="release").emit(OP_DICT['SET'])
546 AtomicArithmeticSingleOp("ldsetah", "LDSETAH", 2, unsign=True,
547 flavor="acquire").emit(OP_DICT['SET'])
548 AtomicArithmeticSingleOp("ldsetlah", "LDSETLAH", 2, unsign=True,
549 flavor="acquire_release").emit(OP_DICT['SET'])
550 AtomicArithmeticSingleOp("ldset", "LDSET", 4, unsign=True,
551 flavor="normal").emit(OP_DICT['SET'])
552 AtomicArithmeticSingleOp("ldsetl", "LDSETL", 4, unsign=True,
553 flavor="release").emit(OP_DICT['SET'])
554 AtomicArithmeticSingleOp("ldseta", "LDSETA", 4, unsign=True,
555 flavor="acquire").emit(OP_DICT['SET'])
556 AtomicArithmeticSingleOp("ldsetla", "LDSETLA", 4, unsign=True,
557 flavor="acquire_release").emit(OP_DICT['SET'])
558 AtomicArithmeticSingleOp("ldset64", "LDSET64", 8, unsign=True,
559 flavor="normal").emit(OP_DICT['SET'])
560 AtomicArithmeticSingleOp("ldsetl64", "LDSETL64", 8, unsign=True,
561 flavor="release").emit(OP_DICT['SET'])
562 AtomicArithmeticSingleOp("ldseta64", "LDSETA64", 8, unsign=True,
563 flavor="acquire").emit(OP_DICT['SET'])
564 AtomicArithmeticSingleOp("ldsetla64", "LDSETLA64", 8, unsign=True,
565 flavor="acquire_release").emit(OP_DICT['SET'])
566
567 AtomicArithmeticSingleOp("ldsmaxb", "LDSMAXB", 1, unsign=False,
568 flavor="normal").emit(OP_DICT['MAX'])
569 AtomicArithmeticSingleOp("ldsmaxlb", "LDSMAXLB", 1, unsign=False,
570 flavor="release").emit(OP_DICT['MAX'])
571 AtomicArithmeticSingleOp("ldsmaxab", "LDSMAXAB", 1, unsign=False,
572 flavor="acquire").emit(OP_DICT['MAX'])
573 AtomicArithmeticSingleOp("ldsmaxlab", "LDSMAXLAB", 1, unsign=False,
574 flavor="acquire_release").emit(OP_DICT['MAX'])
575 AtomicArithmeticSingleOp("ldsmaxh", "LDSMAXH", 2, unsign=False,
576 flavor="normal").emit(OP_DICT['MAX'])
577 AtomicArithmeticSingleOp("ldsmaxlh", "LDSMAXLH", 2, unsign=False,
578 flavor="release").emit(OP_DICT['MAX'])
579 AtomicArithmeticSingleOp("ldsmaxah", "LDSMAXAH", 2, unsign=False,
580 flavor="acquire").emit(OP_DICT['MAX'])
581 AtomicArithmeticSingleOp("ldsmaxlah", "LDSMAXLAH", 2, unsign=False,
582 flavor="acquire_release").emit(OP_DICT['MAX'])
583 AtomicArithmeticSingleOp("ldsmax", "LDSMAX", 4, unsign=False,
584 flavor="normal").emit(OP_DICT['MAX'])
585 AtomicArithmeticSingleOp("ldsmaxl", "LDSMAXL", 4, unsign=False,
586 flavor="release").emit(OP_DICT['MAX'])
587 AtomicArithmeticSingleOp("ldsmaxa", "LDSMAXA", 4, unsign=False,
588 flavor="acquire").emit(OP_DICT['MAX'])
589 AtomicArithmeticSingleOp("ldsmaxla", "LDSMAXLA", 4, unsign=False,
590 flavor="acquire_release").emit(OP_DICT['MAX'])
591 AtomicArithmeticSingleOp("ldsmax64", "LDSMAX64", 8, unsign=False,
592 flavor="normal").emit(OP_DICT['MAX'])
593 AtomicArithmeticSingleOp("ldsmaxl64", "LDSMAXL64", 8, unsign=False,
594 flavor="release").emit(OP_DICT['MAX'])
595 AtomicArithmeticSingleOp("ldsmaxa64", "LDSMAXA64", 8, unsign=False,
596 flavor="acquire").emit(OP_DICT['MAX'])
597 AtomicArithmeticSingleOp("ldsmaxla64", "LDSMAXLA64", 8, unsign=False,
598 flavor="acquire_release").emit(OP_DICT['MAX'])
599
600 AtomicArithmeticSingleOp("ldsminb", "LDSMINB", 1, unsign=False,
601 flavor="normal").emit(OP_DICT['MIN'])
602 AtomicArithmeticSingleOp("ldsminlb", "LDSMINLB", 1, unsign=False,
603 flavor="release").emit(OP_DICT['MIN'])
604 AtomicArithmeticSingleOp("ldsminab", "LDSMINAB", 1, unsign=False,
605 flavor="acquire").emit(OP_DICT['MIN'])
606 AtomicArithmeticSingleOp("ldsminlab", "LDSMINLAB", 1, unsign=False,
607 flavor="acquire_release").emit(OP_DICT['MIN'])
608 AtomicArithmeticSingleOp("ldsminh", "LDSMINH", 2, unsign=False,
609 flavor="normal").emit(OP_DICT['MIN'])
610 AtomicArithmeticSingleOp("ldsminlh", "LDSMINLH", 2, unsign=False,
611 flavor="release").emit(OP_DICT['MIN'])
612 AtomicArithmeticSingleOp("ldsminah", "LDSMINAH", 2, unsign=False,
613 flavor="acquire").emit(OP_DICT['MIN'])
614 AtomicArithmeticSingleOp("ldsminlah", "LDSMINLAH", 2, unsign=False,
615 flavor="acquire_release").emit(OP_DICT['MIN'])
616 AtomicArithmeticSingleOp("ldsmin", "LDSMIN", 4, unsign=False,
617 flavor="normal").emit(OP_DICT['MIN'])
618 AtomicArithmeticSingleOp("ldsminl", "LDSMINL", 4, unsign=False,
619 flavor="release").emit(OP_DICT['MIN'])
620 AtomicArithmeticSingleOp("ldsmina", "LDSMINA", 4, unsign=False,
621 flavor="acquire").emit(OP_DICT['MIN'])
622 AtomicArithmeticSingleOp("ldsminla", "LDSMINLA", 4, unsign=False,
623 flavor="acquire_release").emit(OP_DICT['MIN'])
624 AtomicArithmeticSingleOp("ldsmin64", "LDSMIN64", 8, unsign=False,
625 flavor="normal").emit(OP_DICT['MIN'])
626 AtomicArithmeticSingleOp("ldsminl64", "LDSMINL64", 8, unsign=False,
627 flavor="release").emit(OP_DICT['MIN'])
628 AtomicArithmeticSingleOp("ldsmina64", "LDSMINA64", 8, unsign=False,
629 flavor="acquire").emit(OP_DICT['MIN'])
630 AtomicArithmeticSingleOp("ldsminla64", "LDSMINLA64", 8, unsign=False,
631 flavor="acquire_release").emit(OP_DICT['MIN'])
632
633 AtomicArithmeticSingleOp("ldumaxb", "LDUMAXB", 1, unsign=True,
634 flavor="normal").emit(OP_DICT['MAX'])
635 AtomicArithmeticSingleOp("ldumaxlb", "LDUMAXLB", 1, unsign=True,
636 flavor="release").emit(OP_DICT['MAX'])
637 AtomicArithmeticSingleOp("ldumaxab", "LDUMAXAB", 1, unsign=True,
638 flavor="acquire").emit(OP_DICT['MAX'])
639 AtomicArithmeticSingleOp("ldumaxlab", "LDUMAXLAB", 1, unsign=True,
640 flavor="acquire_release").emit(OP_DICT['MAX'])
641 AtomicArithmeticSingleOp("ldumaxh", "LDUMAXH", 2, unsign=True,
642 flavor="normal").emit(OP_DICT['MAX'])
643 AtomicArithmeticSingleOp("ldumaxlh", "LDUMAXLH", 2, unsign=True,
644 flavor="release").emit(OP_DICT['MAX'])
645 AtomicArithmeticSingleOp("ldumaxah", "LDUMAXAH", 2, unsign=True,
646 flavor="acquire").emit(OP_DICT['MAX'])
647 AtomicArithmeticSingleOp("ldumaxlah", "LDUMAXLAH", 2, unsign=True,
648 flavor="acquire_release").emit(OP_DICT['MAX'])
649 AtomicArithmeticSingleOp("ldumax", "LDUMAX", 4, unsign=True,
650 flavor="normal").emit(OP_DICT['MAX'])
651 AtomicArithmeticSingleOp("ldumaxl", "LDUMAXL", 4, unsign=True,
652 flavor="release").emit(OP_DICT['MAX'])
653 AtomicArithmeticSingleOp("ldumaxa", "LDUMAXA", 4, unsign=True,
654 flavor="acquire").emit(OP_DICT['MAX'])
655 AtomicArithmeticSingleOp("ldumaxla", "LDUMAXLA", 4, unsign=True,
656 flavor="acquire_release").emit(OP_DICT['MAX'])
657 AtomicArithmeticSingleOp("ldumax64", "LDUMAX64", 8, unsign=True,
658 flavor="normal").emit(OP_DICT['MAX'])
659 AtomicArithmeticSingleOp("ldumaxl64", "LDUMAXL64", 8, unsign=True,
660 flavor="release").emit(OP_DICT['MAX'])
661 AtomicArithmeticSingleOp("ldumaxa64", "LDUMAXA64", 8, unsign=True,
662 flavor="acquire").emit(OP_DICT['MAX'])
663 AtomicArithmeticSingleOp("ldumaxla64", "LDUMAXLA64", 8, unsign=True,
664 flavor="acquire_release").emit(OP_DICT['MAX'])
665
666
667 AtomicArithmeticSingleOp("lduminb", "LDUMINB", 1, unsign=True,
668 flavor="normal").emit(OP_DICT['MIN'])
669 AtomicArithmeticSingleOp("lduminlb", "LDUMINLB", 1, unsign=True,
670 flavor="release").emit(OP_DICT['MIN'])
671 AtomicArithmeticSingleOp("lduminab", "LDUMINAB", 1, unsign=True,
672 flavor="acquire").emit(OP_DICT['MIN'])
673 AtomicArithmeticSingleOp("lduminlab", "LDUMINLAB", 1, unsign=True,
674 flavor="acquire_release").emit(OP_DICT['MIN'])
675 AtomicArithmeticSingleOp("lduminh", "LDUMINH", 2, unsign=True,
676 flavor="normal").emit(OP_DICT['MIN'])
677 AtomicArithmeticSingleOp("lduminlh", "LDUMINLH", 2, unsign=True,
678 flavor="release").emit(OP_DICT['MIN'])
679 AtomicArithmeticSingleOp("lduminah", "LDUMINAH", 2, unsign=True,
680 flavor="acquire").emit(OP_DICT['MIN'])
681 AtomicArithmeticSingleOp("lduminlah", "LDUMINLAH", 2, unsign=True,
682 flavor="acquire_release").emit(OP_DICT['MIN'])
683 AtomicArithmeticSingleOp("ldumin", "LDUMIN", 4, unsign=True,
684 flavor="normal").emit(OP_DICT['MIN'])
685 AtomicArithmeticSingleOp("lduminl", "LDUMINL", 4, unsign=True,
686 flavor="release").emit(OP_DICT['MIN'])
687 AtomicArithmeticSingleOp("ldumina", "LDUMINA", 4, unsign=True,
688 flavor="acquire").emit(OP_DICT['MIN'])
689 AtomicArithmeticSingleOp("lduminla", "LDUMINLA", 4, unsign=True,
690 flavor="acquire_release").emit(OP_DICT['MIN'])
691 AtomicArithmeticSingleOp("ldumin64", "LDUMIN64", 8, unsign=True,
692 flavor="normal").emit(OP_DICT['MIN'])
693 AtomicArithmeticSingleOp("lduminl64", "LDUMINL64", 8, unsign=True,
694 flavor="release").emit(OP_DICT['MIN'])
695 AtomicArithmeticSingleOp("ldumina64", "LDUMINA64", 8, unsign=True,
696 flavor="acquire").emit(OP_DICT['MIN'])
697 AtomicArithmeticSingleOp("lduminla64", "LDUMINLA64", 8, unsign=True,
698 flavor="acquire_release").emit(OP_DICT['MIN'])
699
700 AtomicArithmeticSingleOp("staddb", "STADDB", 1, unsign=True,
701 ret_op=False, flavor="normal").emit(OP_DICT['ADD'])
702 AtomicArithmeticSingleOp("staddlb", "STADDLB", 1, unsign=True,
703 ret_op=False, flavor="release").emit(OP_DICT['ADD'])
704 AtomicArithmeticSingleOp("staddh", "STADDH", 2, unsign=True,
705 ret_op=False, flavor="normal").emit(OP_DICT['ADD'])
706 AtomicArithmeticSingleOp("staddlh", "STADDLH", 2, unsign=True,
707 ret_op=False, flavor="release").emit(OP_DICT['ADD'])
708 AtomicArithmeticSingleOp("stadd", "STADD", 4, unsign=True,
709 ret_op=False, flavor="normal").emit(OP_DICT['ADD'])
710 AtomicArithmeticSingleOp("staddl", "STADDL", 4, unsign=True,
711 ret_op=False, flavor="release").emit(OP_DICT['ADD'])
712 AtomicArithmeticSingleOp("stadd64", "STADD64", 8, unsign=True,
713 ret_op=False, flavor="normal").emit(OP_DICT['ADD'])
714 AtomicArithmeticSingleOp("staddl64", "STADDL64", 8, unsign=True,
715 ret_op=False, flavor="release").emit(OP_DICT['ADD'])
716
717 AtomicArithmeticSingleOp("stclrb", "STCLRB", 1, unsign=True,
718 ret_op=False, flavor="normal").emit(OP_DICT['CLR'])
719 AtomicArithmeticSingleOp("stclrlb", "STCLRLB", 1, unsign=True,
720 ret_op=False, flavor="release").emit(OP_DICT['CLR'])
721 AtomicArithmeticSingleOp("stclrh", "STCLRH", 2, unsign=True,
722 ret_op=False, flavor="normal").emit(OP_DICT['CLR'])
723 AtomicArithmeticSingleOp("stclrlh", "STCLRLH", 2, unsign=True,
724 ret_op=False, flavor="release").emit(OP_DICT['CLR'])
725 AtomicArithmeticSingleOp("stclr", "STCLR", 4, unsign=True,
726 ret_op=False, flavor="normal").emit(OP_DICT['CLR'])
727 AtomicArithmeticSingleOp("stclrl", "STCLRL", 4, unsign=True,
728 ret_op=False, flavor="release").emit(OP_DICT['CLR'])
729 AtomicArithmeticSingleOp("stclr64", "STCLR64", 8, unsign=True,
730 ret_op=False, flavor="normal").emit(OP_DICT['CLR'])
731 AtomicArithmeticSingleOp("stclrl64", "STCLRL64", 8, unsign=True,
732 ret_op=False, flavor="release").emit(OP_DICT['CLR'])
733
734 AtomicArithmeticSingleOp("steorb", "STEORB", 1, unsign=True,
735 ret_op=False, flavor="normal").emit(OP_DICT['EOR'])
736 AtomicArithmeticSingleOp("steorlb", "STEORLB", 1, unsign=True,
737 ret_op=False, flavor="release").emit(OP_DICT['EOR'])
738 AtomicArithmeticSingleOp("steorh", "STEORH", 2, unsign=True,
739 ret_op=False, flavor="normal").emit(OP_DICT['EOR'])
740 AtomicArithmeticSingleOp("steorlh", "STEORLH", 2, unsign=True,
741 ret_op=False, flavor="release").emit(OP_DICT['EOR'])
742 AtomicArithmeticSingleOp("steor", "STEOR", 4, unsign=True,
743 ret_op=False, flavor="normal").emit(OP_DICT['EOR'])
744 AtomicArithmeticSingleOp("steorl", "STEORL", 4, unsign=True,
745 ret_op=False, flavor="release").emit(OP_DICT['EOR'])
746 AtomicArithmeticSingleOp("steor64", "STEOR64", 8, unsign=True,
747 ret_op=False, flavor="normal").emit(OP_DICT['EOR'])
748 AtomicArithmeticSingleOp("steorl64", "STEORL64", 8, unsign=True,
749 ret_op=False, flavor="release").emit(OP_DICT['EOR'])
750
751 AtomicArithmeticSingleOp("stsetb", "STSETB", 1, unsign=True,
752 ret_op=False, flavor="normal").emit(OP_DICT['SET'])
753 AtomicArithmeticSingleOp("stsetlb", "STSETLB", 1, unsign=True,
754 ret_op=False, flavor="release").emit(OP_DICT['SET'])
755 AtomicArithmeticSingleOp("stsetab", "STSETAB", 1, unsign=True,
756 ret_op=False, flavor="acquire").emit(OP_DICT['SET'])
757 AtomicArithmeticSingleOp("stsetlab", "STSETLAB", 1, unsign=True,
758 ret_op=False, flavor="acquire_release").emit(OP_DICT['SET'])
759 AtomicArithmeticSingleOp("stseth", "STSETH", 2, unsign=True,
760 ret_op=False, flavor="normal").emit(OP_DICT['SET'])
761 AtomicArithmeticSingleOp("stsetlh", "STSETLH", 2, unsign=True,
762 ret_op=False, flavor="release").emit(OP_DICT['SET'])
763 AtomicArithmeticSingleOp("stset", "STSET", 4, unsign=True,
764 ret_op=False, flavor="normal").emit(OP_DICT['SET'])
765 AtomicArithmeticSingleOp("stsetl", "STSETL", 4, unsign=True,
766 ret_op=False, flavor="release").emit(OP_DICT['SET'])
767 AtomicArithmeticSingleOp("stset64", "STSET64", 8, unsign=True,
768 ret_op=False, flavor="normal").emit(OP_DICT['SET'])
769 AtomicArithmeticSingleOp("stsetl64", "STSETL64", 8, unsign=True,
770 ret_op=False, flavor="release").emit(OP_DICT['SET'])
771
772 AtomicArithmeticSingleOp("stsmaxb", "STSMAXB", 1, unsign=False,
773 ret_op=False, flavor="normal").emit(OP_DICT['MAX'])
774 AtomicArithmeticSingleOp("stsmaxlb", "STSMAXLB", 1, unsign=False,
775 ret_op=False, flavor="release").emit(OP_DICT['MAX'])
776 AtomicArithmeticSingleOp("stsmaxh", "STSMAXH", 2, unsign=False,
777 ret_op=False, flavor="normal").emit(OP_DICT['MAX'])
778 AtomicArithmeticSingleOp("stsmaxlh", "STSMAXLH", 2, unsign=False,
779 ret_op=False, flavor="release").emit(OP_DICT['MAX'])
780 AtomicArithmeticSingleOp("stsmax", "STSMAX", 4, unsign=False,
781 ret_op=False, flavor="normal").emit(OP_DICT['MAX'])
782 AtomicArithmeticSingleOp("stsmaxl", "STSMAXL", 4, unsign=False,
783 ret_op=False, flavor="release").emit(OP_DICT['MAX'])
784 AtomicArithmeticSingleOp("stsmax64", "STSMAX64", 8, unsign=False,
785 ret_op=False, flavor="normal").emit(OP_DICT['MAX'])
786 AtomicArithmeticSingleOp("stsmaxl64", "STSMAXL64", 8, unsign=False,
787 ret_op=False, flavor="release").emit(OP_DICT['MAX'])
788
789 AtomicArithmeticSingleOp("stsminb", "STSMINB", 1, unsign=False,
790 ret_op=False, flavor="normal").emit(OP_DICT['MIN'])
791 AtomicArithmeticSingleOp("stsminlb", "STSMINLB", 1, unsign=False,
792 ret_op=False, flavor="release").emit(OP_DICT['MIN'])
793 AtomicArithmeticSingleOp("stsminh", "STSMINH", 2, unsign=False,
794 ret_op=False, flavor="normal").emit(OP_DICT['MIN'])
795 AtomicArithmeticSingleOp("stsminlh", "STSMINLH", 2, unsign=False,
796 ret_op=False, flavor="release").emit(OP_DICT['MIN'])
797 AtomicArithmeticSingleOp("stsmin", "STSMIN", 4, unsign=False,
798 ret_op=False, flavor="normal").emit(OP_DICT['MIN'])
799 AtomicArithmeticSingleOp("stsminl", "STSMINL", 4, unsign=False,
800 ret_op=False, flavor="release").emit(OP_DICT['MIN'])
801 AtomicArithmeticSingleOp("stsmin64", "STSMIN64", 8, unsign=False,
802 ret_op=False, flavor="normal").emit(OP_DICT['MIN'])
803 AtomicArithmeticSingleOp("stsminl64", "STSMINL64", 8, unsign=False,
804 ret_op=False, flavor="release").emit(OP_DICT['MIN'])
805
806 AtomicArithmeticSingleOp("stumaxb", "STUMAXB", 1, unsign=True,
807 ret_op=False, flavor="normal").emit(OP_DICT['MAX'])
808 AtomicArithmeticSingleOp("stumaxlb", "STUMAXLB", 1, unsign=True,
809 ret_op=False, flavor="release").emit(OP_DICT['MAX'])
810 AtomicArithmeticSingleOp("stumaxh", "STUMAXH", 2, unsign=True,
811 ret_op=False, flavor="normal").emit(OP_DICT['MAX'])
812 AtomicArithmeticSingleOp("stumaxlh", "STUMAXLH", 2, unsign=True,
813 ret_op=False, flavor="release").emit(OP_DICT['MAX'])
814 AtomicArithmeticSingleOp("stumax", "STUMAX", 4, unsign=True,
815 ret_op=False, flavor="normal").emit(OP_DICT['MAX'])
816 AtomicArithmeticSingleOp("stumaxl", "STUMAXL", 4, unsign=True,
817 ret_op=False, flavor="release").emit(OP_DICT['MAX'])
818 AtomicArithmeticSingleOp("stumax64", "STUMAX64", 8, unsign=True,
819 ret_op=False, flavor="normal").emit(OP_DICT['MAX'])
820 AtomicArithmeticSingleOp("stumaxl64", "STUMAXL64", 8, unsign=True,
821 ret_op=False, flavor="release").emit(OP_DICT['MAX'])
822
823 AtomicArithmeticSingleOp("stuminb", "STUMINB", 1, unsign=True,
824 ret_op=False, flavor="normal").emit(OP_DICT['MIN'])
825 AtomicArithmeticSingleOp("stuminlb", "STUMINLB", 1, unsign=True,
826 ret_op=False, flavor="release").emit(OP_DICT['MIN'])
827 AtomicArithmeticSingleOp("stuminh", "STUMINH", 2, unsign=True,
828 ret_op=False, flavor="normal").emit(OP_DICT['MIN'])
829 AtomicArithmeticSingleOp("stuminlh", "STUMINLH", 2, unsign=True,
830 ret_op=False, flavor="release").emit(OP_DICT['MIN'])
831 AtomicArithmeticSingleOp("stumin", "STUMIN", 4, unsign=True,
832 ret_op=False, flavor="normal").emit(OP_DICT['MIN'])
833 AtomicArithmeticSingleOp("stuminl", "STUMINL", 4, unsign=True,
834 ret_op=False, flavor="release").emit(OP_DICT['MIN'])
835 AtomicArithmeticSingleOp("stumin64", "STUMIN64", 8, unsign=True,
836 ret_op=False, flavor="normal").emit(OP_DICT['MIN'])
837 AtomicArithmeticSingleOp("stuminl64", "STUMINL64", 8, unsign=True,
838 ret_op=False, flavor="release").emit(OP_DICT['MIN'])
839
840 AtomicArithmeticSingleOp("swpb", "SWPB", 1, unsign=True,
841 ret_op=False, flavor="normal").emit(OP_DICT['SWP'])
842 AtomicArithmeticSingleOp("swplb", "SWPLB", 1, unsign=True,
843 ret_op=False, flavor="release").emit(OP_DICT['SWP'])
844 AtomicArithmeticSingleOp("swpab", "SWPAB", 1, unsign=True,
845 ret_op=False, flavor="acquire").emit(OP_DICT['SWP'])
846 AtomicArithmeticSingleOp("swplab", "SWPLAB", 1, unsign=True,
847 ret_op=False, flavor="acquire_release").emit(OP_DICT['SWP'])
848 AtomicArithmeticSingleOp("swph", "SWPH", 2, unsign=True,
849 ret_op=False, flavor="normal").emit(OP_DICT['SWP'])
850 AtomicArithmeticSingleOp("swplh", "SWPLH", 2, unsign=True,
851 ret_op=False, flavor="release").emit(OP_DICT['SWP'])
852 AtomicArithmeticSingleOp("swpah", "SWPAH", 2, unsign=True,
853 ret_op=False, flavor="acquire").emit(OP_DICT['SWP'])
854 AtomicArithmeticSingleOp("swplah", "SWPLAH", 2, unsign=True,
855 ret_op=False, flavor="acquire_release").emit(OP_DICT['SWP'])
856 AtomicArithmeticSingleOp("swp", "SWP", 4, unsign=True,
857 ret_op=False, flavor="normal").emit(OP_DICT['SWP'])
858 AtomicArithmeticSingleOp("swpl", "SWPL", 4, unsign=True,
859 ret_op=False, flavor="release").emit(OP_DICT['SWP'])
860 AtomicArithmeticSingleOp("swpa", "SWPA", 4, unsign=True,
861 ret_op=False, flavor="acquire").emit(OP_DICT['SWP'])
862 AtomicArithmeticSingleOp("swpla", "SWPLA", 4, unsign=True,
863 ret_op=False, flavor="acquire_release").emit(OP_DICT['SWP'])
864 AtomicArithmeticSingleOp("swp64", "SWP64", 8, unsign=True,
865 ret_op=False, flavor="normal").emit(OP_DICT['SWP'])
866 AtomicArithmeticSingleOp("swpl64", "SWPL64", 8, unsign=True,
867 ret_op=False, flavor="release").emit(OP_DICT['SWP'])
868 AtomicArithmeticSingleOp("swpa64", "SWPA64", 8, unsign=True,
869 ret_op=False, flavor="acquire").emit(OP_DICT['SWP'])
870 AtomicArithmeticSingleOp("swpla64", "SWPLA64", 8, unsign=True,
871 ret_op=False, flavor="acquire_release").emit(OP_DICT['SWP'])
401}};
872}};