misc.isa (11939:9d1795bb5931) misc.isa (12106:7784fac1b159)
1// -*- mode:c++ -*-
2
3// Copyright (c) 2010-2013,2017 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 svcCode = '''
43 fault = std::make_shared<SupervisorCall>(machInst, imm);
44 '''
45
46 svcIop = InstObjParams("svc", "Svc", "ImmOp",
47 { "code": svcCode,
48 "predicate_test": predicateTest },
49 ["IsSyscall", "IsNonSpeculative", "IsSerializeAfter"])
50 header_output = ImmOpDeclare.subst(svcIop)
51 decoder_output = ImmOpConstructor.subst(svcIop)
52 exec_output = PredOpExecute.subst(svcIop)
53
54 smcCode = '''
55 HCR hcr = Hcr;
56 CPSR cpsr = Cpsr;
57 SCR scr = Scr;
58
59 if ((cpsr.mode != MODE_USER) && FullSystem) {
60 if (ArmSystem::haveVirtualization(xc->tcBase()) &&
61 !inSecureState(scr, cpsr) && (cpsr.mode != MODE_HYP) && hcr.tsc) {
62 fault = std::make_shared<HypervisorTrap>(machInst, 0,
63 EC_SMC_TO_HYP);
64 } else {
65 if (scr.scd) {
66 fault = disabledFault();
67 } else {
68 fault = std::make_shared<SecureMonitorCall>(machInst);
69 }
70 }
71 } else {
72 fault = disabledFault();
73 }
74 '''
75
76 smcIop = InstObjParams("smc", "Smc", "PredOp",
77 { "code": smcCode,
78 "predicate_test": predicateTest },
79 ["IsNonSpeculative", "IsSerializeAfter"])
80 header_output += BasicDeclare.subst(smcIop)
81 decoder_output += BasicConstructor.subst(smcIop)
82 exec_output += PredOpExecute.subst(smcIop)
83
84 hvcCode = '''
85 CPSR cpsr = Cpsr;
86 SCR scr = Scr;
87
88 // Filter out the various cases where this instruction isn't defined
89 if (!FullSystem || !ArmSystem::haveVirtualization(xc->tcBase()) ||
90 (cpsr.mode == MODE_USER) ||
91 (ArmSystem::haveSecurity(xc->tcBase()) && (!scr.ns || !scr.hce))) {
92 fault = disabledFault();
93 } else {
94 fault = std::make_shared<HypervisorCall>(machInst, imm);
95 }
96 '''
97
98 hvcIop = InstObjParams("hvc", "Hvc", "ImmOp",
99 { "code": hvcCode,
100 "predicate_test": predicateTest },
101 ["IsNonSpeculative", "IsSerializeAfter"])
102 header_output += ImmOpDeclare.subst(hvcIop)
103 decoder_output += ImmOpConstructor.subst(hvcIop)
104 exec_output += PredOpExecute.subst(hvcIop)
105
106 eretCode = '''
107 SCTLR sctlr = Sctlr;
108 CPSR old_cpsr = Cpsr;
109 old_cpsr.nz = CondCodesNZ;
110 old_cpsr.c = CondCodesC;
111 old_cpsr.v = CondCodesV;
112 old_cpsr.ge = CondCodesGE;
113
114 CPSR new_cpsr = cpsrWriteByInstr(old_cpsr, Spsr, Scr, Nsacr, 0xF,
115 true, sctlr.nmfi, xc->tcBase());
116 Cpsr = ~CondCodesMask & new_cpsr;
117 CondCodesNZ = new_cpsr.nz;
118 CondCodesC = new_cpsr.c;
119 CondCodesV = new_cpsr.v;
120 CondCodesGE = new_cpsr.ge;
121
122 NextThumb = (new_cpsr).t;
123 NextJazelle = (new_cpsr).j;
124 NextItState = (((new_cpsr).it2 << 2) & 0xFC)
125 | ((new_cpsr).it1 & 0x3);
126
127 NPC = (old_cpsr.mode == MODE_HYP) ? ElrHyp : LR;
128 '''
129
130 eretIop = InstObjParams("eret", "Eret", "PredOp",
131 { "code": eretCode,
132 "predicate_test": predicateTest },
133 ["IsNonSpeculative", "IsSerializeAfter",
134 "IsSquashAfter"])
135 header_output += BasicDeclare.subst(eretIop)
136 decoder_output += BasicConstructor.subst(eretIop)
137 exec_output += PredOpExecute.subst(eretIop)
138
139
140
141}};
142
143let {{
144
145 header_output = decoder_output = exec_output = ""
146
147 mrsCpsrCode = '''
148 CPSR cpsr = Cpsr;
149 cpsr.nz = CondCodesNZ;
150 cpsr.c = CondCodesC;
151 cpsr.v = CondCodesV;
152 cpsr.ge = CondCodesGE;
153 Dest = cpsr & 0xF8FF03DF
154 '''
155
156 mrsCpsrIop = InstObjParams("mrs", "MrsCpsr", "MrsOp",
157 { "code": mrsCpsrCode,
158 "predicate_test": condPredicateTest },
159 ["IsSerializeBefore"])
160 header_output += MrsDeclare.subst(mrsCpsrIop)
161 decoder_output += MrsConstructor.subst(mrsCpsrIop)
162 exec_output += PredOpExecute.subst(mrsCpsrIop)
163
164 mrsSpsrCode = "Dest = Spsr"
165 mrsSpsrIop = InstObjParams("mrs", "MrsSpsr", "MrsOp",
166 { "code": mrsSpsrCode,
167 "predicate_test": predicateTest },
168 ["IsSerializeBefore"])
169 header_output += MrsDeclare.subst(mrsSpsrIop)
170 decoder_output += MrsConstructor.subst(mrsSpsrIop)
171 exec_output += PredOpExecute.subst(mrsSpsrIop)
172
173 mrsBankedRegCode = '''
174 bool isIntReg;
175 int regIdx;
176
177 if (decodeMrsMsrBankedReg(byteMask, r, isIntReg, regIdx, Cpsr, Scr, Nsacr)) {
178 if (isIntReg) {
179 Dest = DecodedBankedIntReg;
180 } else {
181 Dest = xc->readMiscReg(regIdx);
182 }
183 } else {
184 return std::make_shared<UndefinedInstruction>(machInst, false,
185 mnemonic);
186 }
187 '''
188 mrsBankedRegIop = InstObjParams("mrs", "MrsBankedReg", "MrsOp",
189 { "code": mrsBankedRegCode,
190 "predicate_test": predicateTest },
191 ["IsSerializeBefore"])
192 header_output += MrsBankedRegDeclare.subst(mrsBankedRegIop)
193 decoder_output += MrsBankedRegConstructor.subst(mrsBankedRegIop)
194 exec_output += PredOpExecute.subst(mrsBankedRegIop)
195
196 msrBankedRegCode = '''
197 bool isIntReg;
198 int regIdx;
199
200 if (decodeMrsMsrBankedReg(byteMask, r, isIntReg, regIdx, Cpsr, Scr, Nsacr)) {
201 if (isIntReg) {
202 // This is a bit nasty, you would have thought that
203 // DecodedBankedIntReg wouldn't be written to unless the
204 // conditions on the IF statements above are met, however if
205 // you look at the generated C code you'll find that they are.
206 // However this is safe as DecodedBankedIntReg (which is used
207 // in operands.isa to get the index of DecodedBankedIntReg)
208 // will return INTREG_DUMMY if its not a valid integer
209 // register, so redirecting the write to somewhere we don't
210 // care about.
211 DecodedBankedIntReg = Op1;
212 } else {
213 xc->setMiscReg(regIdx, Op1);
214 }
215 } else {
216 return std::make_shared<UndefinedInstruction>(machInst, false,
217 mnemonic);
218 }
219 '''
220 msrBankedRegIop = InstObjParams("msr", "MsrBankedReg", "MsrRegOp",
221 { "code": msrBankedRegCode,
222 "predicate_test": predicateTest },
223 ["IsSerializeAfter", "IsNonSpeculative"])
224 header_output += MsrBankedRegDeclare.subst(msrBankedRegIop)
225 decoder_output += MsrBankedRegConstructor.subst(msrBankedRegIop)
226 exec_output += PredOpExecute.subst(msrBankedRegIop)
227
228 msrCpsrRegCode = '''
229 SCTLR sctlr = Sctlr;
230 CPSR old_cpsr = Cpsr;
231 old_cpsr.nz = CondCodesNZ;
232 old_cpsr.c = CondCodesC;
233 old_cpsr.v = CondCodesV;
234 old_cpsr.ge = CondCodesGE;
235
236 CPSR new_cpsr =
237 cpsrWriteByInstr(old_cpsr, Op1, Scr, Nsacr, byteMask, false,
238 sctlr.nmfi, xc->tcBase());
239 Cpsr = ~CondCodesMask & new_cpsr;
240 CondCodesNZ = new_cpsr.nz;
241 CondCodesC = new_cpsr.c;
242 CondCodesV = new_cpsr.v;
243 CondCodesGE = new_cpsr.ge;
244 '''
245 msrCpsrRegIop = InstObjParams("msr", "MsrCpsrReg", "MsrRegOp",
246 { "code": msrCpsrRegCode,
247 "predicate_test": condPredicateTest },
248 ["IsSerializeAfter","IsNonSpeculative"])
249 header_output += MsrRegDeclare.subst(msrCpsrRegIop)
250 decoder_output += MsrRegConstructor.subst(msrCpsrRegIop)
251 exec_output += PredOpExecute.subst(msrCpsrRegIop)
252
253 msrSpsrRegCode = "Spsr = spsrWriteByInstr(Spsr, Op1, byteMask, false);"
254 msrSpsrRegIop = InstObjParams("msr", "MsrSpsrReg", "MsrRegOp",
255 { "code": msrSpsrRegCode,
256 "predicate_test": predicateTest },
257 ["IsSerializeAfter","IsNonSpeculative"])
258 header_output += MsrRegDeclare.subst(msrSpsrRegIop)
259 decoder_output += MsrRegConstructor.subst(msrSpsrRegIop)
260 exec_output += PredOpExecute.subst(msrSpsrRegIop)
261
262 msrCpsrImmCode = '''
263 SCTLR sctlr = Sctlr;
264 CPSR old_cpsr = Cpsr;
265 old_cpsr.nz = CondCodesNZ;
266 old_cpsr.c = CondCodesC;
267 old_cpsr.v = CondCodesV;
268 old_cpsr.ge = CondCodesGE;
269 CPSR new_cpsr =
270 cpsrWriteByInstr(old_cpsr, imm, Scr, Nsacr, byteMask, false,
271 sctlr.nmfi, xc->tcBase());
272 Cpsr = ~CondCodesMask & new_cpsr;
273 CondCodesNZ = new_cpsr.nz;
274 CondCodesC = new_cpsr.c;
275 CondCodesV = new_cpsr.v;
276 CondCodesGE = new_cpsr.ge;
277 '''
278 msrCpsrImmIop = InstObjParams("msr", "MsrCpsrImm", "MsrImmOp",
279 { "code": msrCpsrImmCode,
280 "predicate_test": condPredicateTest },
281 ["IsSerializeAfter","IsNonSpeculative"])
282 header_output += MsrImmDeclare.subst(msrCpsrImmIop)
283 decoder_output += MsrImmConstructor.subst(msrCpsrImmIop)
284 exec_output += PredOpExecute.subst(msrCpsrImmIop)
285
286 msrSpsrImmCode = "Spsr = spsrWriteByInstr(Spsr, imm, byteMask, false);"
287 msrSpsrImmIop = InstObjParams("msr", "MsrSpsrImm", "MsrImmOp",
288 { "code": msrSpsrImmCode,
289 "predicate_test": predicateTest },
290 ["IsSerializeAfter","IsNonSpeculative"])
291 header_output += MsrImmDeclare.subst(msrSpsrImmIop)
292 decoder_output += MsrImmConstructor.subst(msrSpsrImmIop)
293 exec_output += PredOpExecute.subst(msrSpsrImmIop)
294
295 revCode = '''
296 uint32_t val = Op1;
297 Dest = swap_byte(val);
298 '''
299 revIop = InstObjParams("rev", "Rev", "RegRegOp",
300 { "code": revCode,
301 "predicate_test": predicateTest }, [])
302 header_output += RegRegOpDeclare.subst(revIop)
303 decoder_output += RegRegOpConstructor.subst(revIop)
304 exec_output += PredOpExecute.subst(revIop)
305
306 rev16Code = '''
307 uint32_t val = Op1;
308 Dest = (bits(val, 15, 8) << 0) |
309 (bits(val, 7, 0) << 8) |
310 (bits(val, 31, 24) << 16) |
311 (bits(val, 23, 16) << 24);
312 '''
313 rev16Iop = InstObjParams("rev16", "Rev16", "RegRegOp",
314 { "code": rev16Code,
315 "predicate_test": predicateTest }, [])
316 header_output += RegRegOpDeclare.subst(rev16Iop)
317 decoder_output += RegRegOpConstructor.subst(rev16Iop)
318 exec_output += PredOpExecute.subst(rev16Iop)
319
320 revshCode = '''
321 uint16_t val = Op1;
322 Dest = sext<16>(swap_byte(val));
323 '''
324 revshIop = InstObjParams("revsh", "Revsh", "RegRegOp",
325 { "code": revshCode,
326 "predicate_test": predicateTest }, [])
327 header_output += RegRegOpDeclare.subst(revshIop)
328 decoder_output += RegRegOpConstructor.subst(revshIop)
329 exec_output += PredOpExecute.subst(revshIop)
330
331 rbitCode = '''
332 uint8_t *opBytes = (uint8_t *)&Op1;
333 uint32_t resTemp;
334 uint8_t *destBytes = (uint8_t *)&resTemp;
335 // This reverses the bytes and bits of the input, or so says the
336 // internet.
337 for (int i = 0; i < 4; i++) {
338 uint32_t temp = opBytes[i];
339 temp = (temp * 0x0802 & 0x22110) | (temp * 0x8020 & 0x88440);
340 destBytes[3 - i] = (temp * 0x10101) >> 16;
341 }
342 Dest = resTemp;
343 '''
344 rbitIop = InstObjParams("rbit", "Rbit", "RegRegOp",
345 { "code": rbitCode,
346 "predicate_test": predicateTest }, [])
347 header_output += RegRegOpDeclare.subst(rbitIop)
348 decoder_output += RegRegOpConstructor.subst(rbitIop)
349 exec_output += PredOpExecute.subst(rbitIop)
350
351 clzCode = '''
352 Dest = (Op1 == 0) ? 32 : (31 - findMsbSet(Op1));
353 '''
354 clzIop = InstObjParams("clz", "Clz", "RegRegOp",
355 { "code": clzCode,
356 "predicate_test": predicateTest }, [])
357 header_output += RegRegOpDeclare.subst(clzIop)
358 decoder_output += RegRegOpConstructor.subst(clzIop)
359 exec_output += PredOpExecute.subst(clzIop)
360
361 ssatCode = '''
362 int32_t operand = shift_rm_imm(Op1, shiftAmt, shiftType, 0);
363 int32_t res;
364 if (satInt(res, operand, imm))
365 CpsrQ = 1 << 27;
366 Dest = res;
367 '''
368 ssatIop = InstObjParams("ssat", "Ssat", "RegImmRegShiftOp",
369 { "code": ssatCode,
370 "predicate_test": pickPredicate(ssatCode) }, [])
371 header_output += RegImmRegShiftOpDeclare.subst(ssatIop)
372 decoder_output += RegImmRegShiftOpConstructor.subst(ssatIop)
373 exec_output += PredOpExecute.subst(ssatIop)
374
375 usatCode = '''
376 int32_t operand = shift_rm_imm(Op1, shiftAmt, shiftType, 0);
377 int32_t res;
378 if (uSatInt(res, operand, imm))
379 CpsrQ = 1 << 27;
380 Dest = res;
381 '''
382 usatIop = InstObjParams("usat", "Usat", "RegImmRegShiftOp",
383 { "code": usatCode,
384 "predicate_test": pickPredicate(usatCode) }, [])
385 header_output += RegImmRegShiftOpDeclare.subst(usatIop)
386 decoder_output += RegImmRegShiftOpConstructor.subst(usatIop)
387 exec_output += PredOpExecute.subst(usatIop)
388
389 ssat16Code = '''
390 int32_t res;
391 uint32_t resTemp = 0;
392 int32_t argLow = sext<16>(bits(Op1, 15, 0));
393 int32_t argHigh = sext<16>(bits(Op1, 31, 16));
394 if (satInt(res, argLow, imm))
395 CpsrQ = 1 << 27;
396 replaceBits(resTemp, 15, 0, res);
397 if (satInt(res, argHigh, imm))
398 CpsrQ = 1 << 27;
399 replaceBits(resTemp, 31, 16, res);
400 Dest = resTemp;
401 '''
402 ssat16Iop = InstObjParams("ssat16", "Ssat16", "RegImmRegOp",
403 { "code": ssat16Code,
404 "predicate_test": pickPredicate(ssat16Code) }, [])
405 header_output += RegImmRegOpDeclare.subst(ssat16Iop)
406 decoder_output += RegImmRegOpConstructor.subst(ssat16Iop)
407 exec_output += PredOpExecute.subst(ssat16Iop)
408
409 usat16Code = '''
410 int32_t res;
411 uint32_t resTemp = 0;
412 int32_t argLow = sext<16>(bits(Op1, 15, 0));
413 int32_t argHigh = sext<16>(bits(Op1, 31, 16));
414 if (uSatInt(res, argLow, imm))
415 CpsrQ = 1 << 27;
416 replaceBits(resTemp, 15, 0, res);
417 if (uSatInt(res, argHigh, imm))
418 CpsrQ = 1 << 27;
419 replaceBits(resTemp, 31, 16, res);
420 Dest = resTemp;
421 '''
422 usat16Iop = InstObjParams("usat16", "Usat16", "RegImmRegOp",
423 { "code": usat16Code,
424 "predicate_test": pickPredicate(usat16Code) }, [])
425 header_output += RegImmRegOpDeclare.subst(usat16Iop)
426 decoder_output += RegImmRegOpConstructor.subst(usat16Iop)
427 exec_output += PredOpExecute.subst(usat16Iop)
428
429 sxtbIop = InstObjParams("sxtb", "Sxtb", "RegImmRegOp",
430 { "code":
431 "Dest = sext<8>((uint8_t)(Op1_ud >> imm));",
432 "predicate_test": predicateTest }, [])
433 header_output += RegImmRegOpDeclare.subst(sxtbIop)
434 decoder_output += RegImmRegOpConstructor.subst(sxtbIop)
435 exec_output += PredOpExecute.subst(sxtbIop)
436
437 sxtabIop = InstObjParams("sxtab", "Sxtab", "RegRegRegImmOp",
438 { "code":
439 '''
440 Dest = sext<8>((uint8_t)(Op2_ud >> imm)) +
441 Op1;
442 ''',
443 "predicate_test": predicateTest }, [])
444 header_output += RegRegRegImmOpDeclare.subst(sxtabIop)
445 decoder_output += RegRegRegImmOpConstructor.subst(sxtabIop)
446 exec_output += PredOpExecute.subst(sxtabIop)
447
448 sxtb16Code = '''
449 uint32_t resTemp = 0;
450 replaceBits(resTemp, 15, 0, sext<8>(bits(Op1, imm + 7, imm)));
451 replaceBits(resTemp, 31, 16,
452 sext<8>(bits(Op1, (imm + 23) % 32, (imm + 16) % 32)));
453 Dest = resTemp;
454 '''
455 sxtb16Iop = InstObjParams("sxtb16", "Sxtb16", "RegImmRegOp",
456 { "code": sxtb16Code,
457 "predicate_test": predicateTest }, [])
458 header_output += RegImmRegOpDeclare.subst(sxtb16Iop)
459 decoder_output += RegImmRegOpConstructor.subst(sxtb16Iop)
460 exec_output += PredOpExecute.subst(sxtb16Iop)
461
462 sxtab16Code = '''
463 uint32_t resTemp = 0;
464 replaceBits(resTemp, 15, 0, sext<8>(bits(Op2, imm + 7, imm)) +
465 bits(Op1, 15, 0));
466 replaceBits(resTemp, 31, 16,
467 sext<8>(bits(Op2, (imm + 23) % 32, (imm + 16) % 32)) +
468 bits(Op1, 31, 16));
469 Dest = resTemp;
470 '''
471 sxtab16Iop = InstObjParams("sxtab16", "Sxtab16", "RegRegRegImmOp",
472 { "code": sxtab16Code,
473 "predicate_test": predicateTest }, [])
474 header_output += RegRegRegImmOpDeclare.subst(sxtab16Iop)
475 decoder_output += RegRegRegImmOpConstructor.subst(sxtab16Iop)
476 exec_output += PredOpExecute.subst(sxtab16Iop)
477
478 sxthCode = '''
479 uint64_t rotated = (uint32_t)Op1;
480 rotated = (rotated | (rotated << 32)) >> imm;
481 Dest = sext<16>((uint16_t)rotated);
482 '''
483 sxthIop = InstObjParams("sxth", "Sxth", "RegImmRegOp",
484 { "code": sxthCode,
485 "predicate_test": predicateTest }, [])
486 header_output += RegImmRegOpDeclare.subst(sxthIop)
487 decoder_output += RegImmRegOpConstructor.subst(sxthIop)
488 exec_output += PredOpExecute.subst(sxthIop)
489
490 sxtahCode = '''
491 uint64_t rotated = (uint32_t)Op2;
492 rotated = (rotated | (rotated << 32)) >> imm;
493 Dest = sext<16>((uint16_t)rotated) + Op1;
494 '''
495 sxtahIop = InstObjParams("sxtah", "Sxtah", "RegRegRegImmOp",
496 { "code": sxtahCode,
497 "predicate_test": predicateTest }, [])
498 header_output += RegRegRegImmOpDeclare.subst(sxtahIop)
499 decoder_output += RegRegRegImmOpConstructor.subst(sxtahIop)
500 exec_output += PredOpExecute.subst(sxtahIop)
501
502 uxtbIop = InstObjParams("uxtb", "Uxtb", "RegImmRegOp",
503 { "code": "Dest = (uint8_t)(Op1_ud >> imm);",
504 "predicate_test": predicateTest }, [])
505 header_output += RegImmRegOpDeclare.subst(uxtbIop)
506 decoder_output += RegImmRegOpConstructor.subst(uxtbIop)
507 exec_output += PredOpExecute.subst(uxtbIop)
508
509 uxtabIop = InstObjParams("uxtab", "Uxtab", "RegRegRegImmOp",
510 { "code":
511 "Dest = (uint8_t)(Op2_ud >> imm) + Op1;",
512 "predicate_test": predicateTest }, [])
513 header_output += RegRegRegImmOpDeclare.subst(uxtabIop)
514 decoder_output += RegRegRegImmOpConstructor.subst(uxtabIop)
515 exec_output += PredOpExecute.subst(uxtabIop)
516
517 uxtb16Code = '''
518 uint32_t resTemp = 0;
519 replaceBits(resTemp, 15, 0, (uint8_t)(bits(Op1, imm + 7, imm)));
520 replaceBits(resTemp, 31, 16,
521 (uint8_t)(bits(Op1, (imm + 23) % 32, (imm + 16) % 32)));
522 Dest = resTemp;
523 '''
524 uxtb16Iop = InstObjParams("uxtb16", "Uxtb16", "RegImmRegOp",
525 { "code": uxtb16Code,
526 "predicate_test": predicateTest }, [])
527 header_output += RegImmRegOpDeclare.subst(uxtb16Iop)
528 decoder_output += RegImmRegOpConstructor.subst(uxtb16Iop)
529 exec_output += PredOpExecute.subst(uxtb16Iop)
530
531 uxtab16Code = '''
532 uint32_t resTemp = 0;
533 replaceBits(resTemp, 15, 0, (uint8_t)(bits(Op2, imm + 7, imm)) +
534 bits(Op1, 15, 0));
535 replaceBits(resTemp, 31, 16,
536 (uint8_t)(bits(Op2, (imm + 23) % 32, (imm + 16) % 32)) +
537 bits(Op1, 31, 16));
538 Dest = resTemp;
539 '''
540 uxtab16Iop = InstObjParams("uxtab16", "Uxtab16", "RegRegRegImmOp",
541 { "code": uxtab16Code,
542 "predicate_test": predicateTest }, [])
543 header_output += RegRegRegImmOpDeclare.subst(uxtab16Iop)
544 decoder_output += RegRegRegImmOpConstructor.subst(uxtab16Iop)
545 exec_output += PredOpExecute.subst(uxtab16Iop)
546
547 uxthCode = '''
548 uint64_t rotated = (uint32_t)Op1;
549 rotated = (rotated | (rotated << 32)) >> imm;
550 Dest = (uint16_t)rotated;
551 '''
552 uxthIop = InstObjParams("uxth", "Uxth", "RegImmRegOp",
553 { "code": uxthCode,
554 "predicate_test": predicateTest }, [])
555 header_output += RegImmRegOpDeclare.subst(uxthIop)
556 decoder_output += RegImmRegOpConstructor.subst(uxthIop)
557 exec_output += PredOpExecute.subst(uxthIop)
558
559 uxtahCode = '''
560 uint64_t rotated = (uint32_t)Op2;
561 rotated = (rotated | (rotated << 32)) >> imm;
562 Dest = (uint16_t)rotated + Op1;
563 '''
564 uxtahIop = InstObjParams("uxtah", "Uxtah", "RegRegRegImmOp",
565 { "code": uxtahCode,
566 "predicate_test": predicateTest }, [])
567 header_output += RegRegRegImmOpDeclare.subst(uxtahIop)
568 decoder_output += RegRegRegImmOpConstructor.subst(uxtahIop)
569 exec_output += PredOpExecute.subst(uxtahIop)
570
571 selCode = '''
572 uint32_t resTemp = 0;
573 for (unsigned i = 0; i < 4; i++) {
574 int low = i * 8;
575 int high = low + 7;
576 replaceBits(resTemp, high, low,
577 bits(CondCodesGE, i) ?
578 bits(Op1, high, low) : bits(Op2, high, low));
579 }
580 Dest = resTemp;
581 '''
582 selIop = InstObjParams("sel", "Sel", "RegRegRegOp",
583 { "code": selCode,
584 "predicate_test": predicateTest }, [])
585 header_output += RegRegRegOpDeclare.subst(selIop)
586 decoder_output += RegRegRegOpConstructor.subst(selIop)
587 exec_output += PredOpExecute.subst(selIop)
588
589 usad8Code = '''
590 uint32_t resTemp = 0;
591 for (unsigned i = 0; i < 4; i++) {
592 int low = i * 8;
593 int high = low + 7;
594 int32_t diff = bits(Op1, high, low) -
595 bits(Op2, high, low);
596 resTemp += ((diff < 0) ? -diff : diff);
597 }
598 Dest = resTemp;
599 '''
600 usad8Iop = InstObjParams("usad8", "Usad8", "RegRegRegOp",
601 { "code": usad8Code,
602 "predicate_test": predicateTest }, [])
603 header_output += RegRegRegOpDeclare.subst(usad8Iop)
604 decoder_output += RegRegRegOpConstructor.subst(usad8Iop)
605 exec_output += PredOpExecute.subst(usad8Iop)
606
607 usada8Code = '''
608 uint32_t resTemp = 0;
609 for (unsigned i = 0; i < 4; i++) {
610 int low = i * 8;
611 int high = low + 7;
612 int32_t diff = bits(Op1, high, low) -
613 bits(Op2, high, low);
614 resTemp += ((diff < 0) ? -diff : diff);
615 }
616 Dest = Op3 + resTemp;
617 '''
618 usada8Iop = InstObjParams("usada8", "Usada8", "RegRegRegRegOp",
619 { "code": usada8Code,
620 "predicate_test": predicateTest }, [])
621 header_output += RegRegRegRegOpDeclare.subst(usada8Iop)
622 decoder_output += RegRegRegRegOpConstructor.subst(usada8Iop)
623 exec_output += PredOpExecute.subst(usada8Iop)
624
625 bkptCode = 'return std::make_shared<PrefetchAbort>(PC, ArmFault::DebugEvent);\n'
626 bkptIop = InstObjParams("bkpt", "BkptInst", "PredOp", bkptCode)
627 header_output += BasicDeclare.subst(bkptIop)
628 decoder_output += BasicConstructor.subst(bkptIop)
629 exec_output += BasicExecute.subst(bkptIop)
630
631 nopIop = InstObjParams("nop", "NopInst", "ArmStaticInst", "", ['IsNop'])
632 header_output += BasicDeclare.subst(nopIop)
633 decoder_output += BasicConstructor64.subst(nopIop)
634 exec_output += BasicExecute.subst(nopIop)
635
636 yieldIop = InstObjParams("yield", "YieldInst", "PredOp", \
637 { "code" : "", "predicate_test" : predicateTest })
638 header_output += BasicDeclare.subst(yieldIop)
639 decoder_output += BasicConstructor.subst(yieldIop)
640 exec_output += PredOpExecute.subst(yieldIop)
641
642 wfeCode = '''
643 HCR hcr = Hcr;
644 CPSR cpsr = Cpsr;
645 SCR scr = Scr64;
646 SCTLR sctlr = Sctlr;
647
648 // WFE Sleeps if SevMailbox==0 and no unmasked interrupts are pending,
649 ThreadContext *tc = xc->tcBase();
650 if (SevMailbox == 1) {
651 SevMailbox = 0;
652 PseudoInst::quiesceSkip(tc);
653 } else if (tc->getCpuPtr()->getInterruptController(
654 tc->threadId())->checkInterrupts(tc)) {
655 PseudoInst::quiesceSkip(tc);
656 } else if (cpsr.el == EL0 && !sctlr.ntwe) {
657 PseudoInst::quiesceSkip(tc);
658 fault = std::make_shared<SupervisorTrap>(machInst, 0x1E00001,
659 EC_TRAPPED_WFI_WFE);
660 } else if (ArmSystem::haveVirtualization(tc) &&
661 !inSecureState(scr, cpsr) && (cpsr.mode != MODE_HYP) &&
662 hcr.twe) {
663 PseudoInst::quiesceSkip(tc);
664 fault = std::make_shared<HypervisorTrap>(machInst, 0x1E00001,
665 EC_TRAPPED_WFI_WFE);
666 } else if (ArmSystem::haveSecurity(tc) && cpsr.el != EL3 && scr.twe) {
667 PseudoInst::quiesceSkip(tc);
668 fault = std::make_shared<SecureMonitorTrap>(machInst, 0x1E00001,
669 EC_TRAPPED_WFI_WFE);
670 } else {
671 PseudoInst::quiesce(tc);
672 }
673 '''
674 wfePredFixUpCode = '''
675 // WFE is predicated false, reset SevMailbox to reduce spurious sleeps
676 // and SEV interrupts
677 SevMailbox = 1;
678 '''
679 wfeIop = InstObjParams("wfe", "WfeInst", "PredOp", \
680 { "code" : wfeCode,
681 "pred_fixup" : wfePredFixUpCode,
682 "predicate_test" : predicateTest },
683 ["IsNonSpeculative", "IsQuiesce",
684 "IsSerializeAfter", "IsUnverifiable"])
685 header_output += BasicDeclare.subst(wfeIop)
686 decoder_output += BasicConstructor.subst(wfeIop)
687 exec_output += QuiescePredOpExecuteWithFixup.subst(wfeIop)
688
689 wfiCode = '''
690 HCR hcr = Hcr;
691 CPSR cpsr = Cpsr;
692 SCR scr = Scr64;
693 SCTLR sctlr = Sctlr;
694
695 // WFI doesn't sleep if interrupts are pending (masked or not)
696 ThreadContext *tc = xc->tcBase();
697 if (tc->getCpuPtr()->getInterruptController(
698 tc->threadId())->checkWfiWake(hcr, cpsr, scr)) {
699 PseudoInst::quiesceSkip(tc);
700 } else if (cpsr.el == EL0 && !sctlr.ntwi) {
701 PseudoInst::quiesceSkip(tc);
702 fault = std::make_shared<SupervisorTrap>(machInst, 0x1E00000,
703 EC_TRAPPED_WFI_WFE);
704 } else if (ArmSystem::haveVirtualization(tc) && hcr.twi &&
705 (cpsr.mode != MODE_HYP) && !inSecureState(scr, cpsr)) {
706 PseudoInst::quiesceSkip(tc);
707 fault = std::make_shared<HypervisorTrap>(machInst, 0x1E00000,
708 EC_TRAPPED_WFI_WFE);
709 } else if (ArmSystem::haveSecurity(tc) && cpsr.el != EL3 && scr.twi) {
710 PseudoInst::quiesceSkip(tc);
711 fault = std::make_shared<SecureMonitorTrap>(machInst, 0x1E00000,
712 EC_TRAPPED_WFI_WFE);
713 } else {
714 PseudoInst::quiesce(tc);
715 }
716 tc->getCpuPtr()->clearInterrupt(tc->threadId(), INT_ABT, 0);
717 '''
718 wfiIop = InstObjParams("wfi", "WfiInst", "PredOp", \
719 { "code" : wfiCode, "predicate_test" : predicateTest },
720 ["IsNonSpeculative", "IsQuiesce",
721 "IsSerializeAfter", "IsUnverifiable"])
722 header_output += BasicDeclare.subst(wfiIop)
723 decoder_output += BasicConstructor.subst(wfiIop)
724 exec_output += QuiescePredOpExecute.subst(wfiIop)
725
726 sevCode = '''
727 SevMailbox = 1;
728 System *sys = xc->tcBase()->getSystemPtr();
729 for (int x = 0; x < sys->numContexts(); x++) {
730 ThreadContext *oc = sys->getThreadContext(x);
731 if (oc == xc->tcBase())
732 continue;
733 // Wake CPU with interrupt if they were sleeping
734 if (oc->readMiscReg(MISCREG_SEV_MAILBOX) == 0) {
735 // Post Interrupt and wake cpu if needed
736 oc->getCpuPtr()->postInterrupt(oc->threadId(), INT_SEV, 0);
737 }
738 }
739 '''
740 sevIop = InstObjParams("sev", "SevInst", "PredOp", \
741 { "code" : sevCode, "predicate_test" : predicateTest },
742 ["IsNonSpeculative", "IsSquashAfter", "IsUnverifiable"])
743 header_output += BasicDeclare.subst(sevIop)
744 decoder_output += BasicConstructor.subst(sevIop)
745 exec_output += PredOpExecute.subst(sevIop)
746
747 sevlCode = '''
748 SevMailbox = 1;
749 '''
750 sevlIop = InstObjParams("sevl", "SevlInst", "PredOp", \
751 { "code" : sevlCode, "predicate_test" : predicateTest },
752 ["IsNonSpeculative", "IsSquashAfter", "IsUnverifiable"])
753 header_output += BasicDeclare.subst(sevlIop)
754 decoder_output += BasicConstructor.subst(sevlIop)
755 exec_output += BasicExecute.subst(sevlIop)
756
757 itIop = InstObjParams("it", "ItInst", "PredOp", \
758 { "code" : ";",
759 "predicate_test" : predicateTest }, [])
760 header_output += BasicDeclare.subst(itIop)
761 decoder_output += BasicConstructor.subst(itIop)
762 exec_output += PredOpExecute.subst(itIop)
763 unknownCode = '''
764 return std::make_shared<UndefinedInstruction>(machInst, true);
765 '''
766 unknownIop = InstObjParams("unknown", "Unknown", "UnknownOp", \
767 { "code": unknownCode,
768 "predicate_test": predicateTest })
769 header_output += BasicDeclare.subst(unknownIop)
770 decoder_output += BasicConstructor.subst(unknownIop)
771 exec_output += PredOpExecute.subst(unknownIop)
772
773 ubfxCode = '''
774 Dest = bits(Op1, imm2, imm1);
775 '''
776 ubfxIop = InstObjParams("ubfx", "Ubfx", "RegRegImmImmOp",
777 { "code": ubfxCode,
778 "predicate_test": predicateTest }, [])
779 header_output += RegRegImmImmOpDeclare.subst(ubfxIop)
780 decoder_output += RegRegImmImmOpConstructor.subst(ubfxIop)
781 exec_output += PredOpExecute.subst(ubfxIop)
782
783 sbfxCode = '''
784 int32_t resTemp = bits(Op1, imm2, imm1);
785 Dest = resTemp | -(resTemp & (1 << (imm2 - imm1)));
786 '''
787 sbfxIop = InstObjParams("sbfx", "Sbfx", "RegRegImmImmOp",
788 { "code": sbfxCode,
789 "predicate_test": predicateTest }, [])
790 header_output += RegRegImmImmOpDeclare.subst(sbfxIop)
791 decoder_output += RegRegImmImmOpConstructor.subst(sbfxIop)
792 exec_output += PredOpExecute.subst(sbfxIop)
793
794 bfcCode = '''
795 Dest = Op1 & ~(mask(imm2 - imm1 + 1) << imm1);
796 '''
797 bfcIop = InstObjParams("bfc", "Bfc", "RegRegImmImmOp",
798 { "code": bfcCode,
799 "predicate_test": predicateTest }, [])
800 header_output += RegRegImmImmOpDeclare.subst(bfcIop)
801 decoder_output += RegRegImmImmOpConstructor.subst(bfcIop)
802 exec_output += PredOpExecute.subst(bfcIop)
803
804 bfiCode = '''
805 uint32_t bitMask = (mask(imm2 - imm1 + 1) << imm1);
806 Dest = ((Op1 << imm1) & bitMask) | (Dest & ~bitMask);
807 '''
808 bfiIop = InstObjParams("bfi", "Bfi", "RegRegImmImmOp",
809 { "code": bfiCode,
810 "predicate_test": predicateTest }, [])
811 header_output += RegRegImmImmOpDeclare.subst(bfiIop)
812 decoder_output += RegRegImmImmOpConstructor.subst(bfiIop)
813 exec_output += PredOpExecute.subst(bfiIop)
814
815 mrc14code = '''
1// -*- mode:c++ -*-
2
3// Copyright (c) 2010-2013,2017 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 svcCode = '''
43 fault = std::make_shared<SupervisorCall>(machInst, imm);
44 '''
45
46 svcIop = InstObjParams("svc", "Svc", "ImmOp",
47 { "code": svcCode,
48 "predicate_test": predicateTest },
49 ["IsSyscall", "IsNonSpeculative", "IsSerializeAfter"])
50 header_output = ImmOpDeclare.subst(svcIop)
51 decoder_output = ImmOpConstructor.subst(svcIop)
52 exec_output = PredOpExecute.subst(svcIop)
53
54 smcCode = '''
55 HCR hcr = Hcr;
56 CPSR cpsr = Cpsr;
57 SCR scr = Scr;
58
59 if ((cpsr.mode != MODE_USER) && FullSystem) {
60 if (ArmSystem::haveVirtualization(xc->tcBase()) &&
61 !inSecureState(scr, cpsr) && (cpsr.mode != MODE_HYP) && hcr.tsc) {
62 fault = std::make_shared<HypervisorTrap>(machInst, 0,
63 EC_SMC_TO_HYP);
64 } else {
65 if (scr.scd) {
66 fault = disabledFault();
67 } else {
68 fault = std::make_shared<SecureMonitorCall>(machInst);
69 }
70 }
71 } else {
72 fault = disabledFault();
73 }
74 '''
75
76 smcIop = InstObjParams("smc", "Smc", "PredOp",
77 { "code": smcCode,
78 "predicate_test": predicateTest },
79 ["IsNonSpeculative", "IsSerializeAfter"])
80 header_output += BasicDeclare.subst(smcIop)
81 decoder_output += BasicConstructor.subst(smcIop)
82 exec_output += PredOpExecute.subst(smcIop)
83
84 hvcCode = '''
85 CPSR cpsr = Cpsr;
86 SCR scr = Scr;
87
88 // Filter out the various cases where this instruction isn't defined
89 if (!FullSystem || !ArmSystem::haveVirtualization(xc->tcBase()) ||
90 (cpsr.mode == MODE_USER) ||
91 (ArmSystem::haveSecurity(xc->tcBase()) && (!scr.ns || !scr.hce))) {
92 fault = disabledFault();
93 } else {
94 fault = std::make_shared<HypervisorCall>(machInst, imm);
95 }
96 '''
97
98 hvcIop = InstObjParams("hvc", "Hvc", "ImmOp",
99 { "code": hvcCode,
100 "predicate_test": predicateTest },
101 ["IsNonSpeculative", "IsSerializeAfter"])
102 header_output += ImmOpDeclare.subst(hvcIop)
103 decoder_output += ImmOpConstructor.subst(hvcIop)
104 exec_output += PredOpExecute.subst(hvcIop)
105
106 eretCode = '''
107 SCTLR sctlr = Sctlr;
108 CPSR old_cpsr = Cpsr;
109 old_cpsr.nz = CondCodesNZ;
110 old_cpsr.c = CondCodesC;
111 old_cpsr.v = CondCodesV;
112 old_cpsr.ge = CondCodesGE;
113
114 CPSR new_cpsr = cpsrWriteByInstr(old_cpsr, Spsr, Scr, Nsacr, 0xF,
115 true, sctlr.nmfi, xc->tcBase());
116 Cpsr = ~CondCodesMask & new_cpsr;
117 CondCodesNZ = new_cpsr.nz;
118 CondCodesC = new_cpsr.c;
119 CondCodesV = new_cpsr.v;
120 CondCodesGE = new_cpsr.ge;
121
122 NextThumb = (new_cpsr).t;
123 NextJazelle = (new_cpsr).j;
124 NextItState = (((new_cpsr).it2 << 2) & 0xFC)
125 | ((new_cpsr).it1 & 0x3);
126
127 NPC = (old_cpsr.mode == MODE_HYP) ? ElrHyp : LR;
128 '''
129
130 eretIop = InstObjParams("eret", "Eret", "PredOp",
131 { "code": eretCode,
132 "predicate_test": predicateTest },
133 ["IsNonSpeculative", "IsSerializeAfter",
134 "IsSquashAfter"])
135 header_output += BasicDeclare.subst(eretIop)
136 decoder_output += BasicConstructor.subst(eretIop)
137 exec_output += PredOpExecute.subst(eretIop)
138
139
140
141}};
142
143let {{
144
145 header_output = decoder_output = exec_output = ""
146
147 mrsCpsrCode = '''
148 CPSR cpsr = Cpsr;
149 cpsr.nz = CondCodesNZ;
150 cpsr.c = CondCodesC;
151 cpsr.v = CondCodesV;
152 cpsr.ge = CondCodesGE;
153 Dest = cpsr & 0xF8FF03DF
154 '''
155
156 mrsCpsrIop = InstObjParams("mrs", "MrsCpsr", "MrsOp",
157 { "code": mrsCpsrCode,
158 "predicate_test": condPredicateTest },
159 ["IsSerializeBefore"])
160 header_output += MrsDeclare.subst(mrsCpsrIop)
161 decoder_output += MrsConstructor.subst(mrsCpsrIop)
162 exec_output += PredOpExecute.subst(mrsCpsrIop)
163
164 mrsSpsrCode = "Dest = Spsr"
165 mrsSpsrIop = InstObjParams("mrs", "MrsSpsr", "MrsOp",
166 { "code": mrsSpsrCode,
167 "predicate_test": predicateTest },
168 ["IsSerializeBefore"])
169 header_output += MrsDeclare.subst(mrsSpsrIop)
170 decoder_output += MrsConstructor.subst(mrsSpsrIop)
171 exec_output += PredOpExecute.subst(mrsSpsrIop)
172
173 mrsBankedRegCode = '''
174 bool isIntReg;
175 int regIdx;
176
177 if (decodeMrsMsrBankedReg(byteMask, r, isIntReg, regIdx, Cpsr, Scr, Nsacr)) {
178 if (isIntReg) {
179 Dest = DecodedBankedIntReg;
180 } else {
181 Dest = xc->readMiscReg(regIdx);
182 }
183 } else {
184 return std::make_shared<UndefinedInstruction>(machInst, false,
185 mnemonic);
186 }
187 '''
188 mrsBankedRegIop = InstObjParams("mrs", "MrsBankedReg", "MrsOp",
189 { "code": mrsBankedRegCode,
190 "predicate_test": predicateTest },
191 ["IsSerializeBefore"])
192 header_output += MrsBankedRegDeclare.subst(mrsBankedRegIop)
193 decoder_output += MrsBankedRegConstructor.subst(mrsBankedRegIop)
194 exec_output += PredOpExecute.subst(mrsBankedRegIop)
195
196 msrBankedRegCode = '''
197 bool isIntReg;
198 int regIdx;
199
200 if (decodeMrsMsrBankedReg(byteMask, r, isIntReg, regIdx, Cpsr, Scr, Nsacr)) {
201 if (isIntReg) {
202 // This is a bit nasty, you would have thought that
203 // DecodedBankedIntReg wouldn't be written to unless the
204 // conditions on the IF statements above are met, however if
205 // you look at the generated C code you'll find that they are.
206 // However this is safe as DecodedBankedIntReg (which is used
207 // in operands.isa to get the index of DecodedBankedIntReg)
208 // will return INTREG_DUMMY if its not a valid integer
209 // register, so redirecting the write to somewhere we don't
210 // care about.
211 DecodedBankedIntReg = Op1;
212 } else {
213 xc->setMiscReg(regIdx, Op1);
214 }
215 } else {
216 return std::make_shared<UndefinedInstruction>(machInst, false,
217 mnemonic);
218 }
219 '''
220 msrBankedRegIop = InstObjParams("msr", "MsrBankedReg", "MsrRegOp",
221 { "code": msrBankedRegCode,
222 "predicate_test": predicateTest },
223 ["IsSerializeAfter", "IsNonSpeculative"])
224 header_output += MsrBankedRegDeclare.subst(msrBankedRegIop)
225 decoder_output += MsrBankedRegConstructor.subst(msrBankedRegIop)
226 exec_output += PredOpExecute.subst(msrBankedRegIop)
227
228 msrCpsrRegCode = '''
229 SCTLR sctlr = Sctlr;
230 CPSR old_cpsr = Cpsr;
231 old_cpsr.nz = CondCodesNZ;
232 old_cpsr.c = CondCodesC;
233 old_cpsr.v = CondCodesV;
234 old_cpsr.ge = CondCodesGE;
235
236 CPSR new_cpsr =
237 cpsrWriteByInstr(old_cpsr, Op1, Scr, Nsacr, byteMask, false,
238 sctlr.nmfi, xc->tcBase());
239 Cpsr = ~CondCodesMask & new_cpsr;
240 CondCodesNZ = new_cpsr.nz;
241 CondCodesC = new_cpsr.c;
242 CondCodesV = new_cpsr.v;
243 CondCodesGE = new_cpsr.ge;
244 '''
245 msrCpsrRegIop = InstObjParams("msr", "MsrCpsrReg", "MsrRegOp",
246 { "code": msrCpsrRegCode,
247 "predicate_test": condPredicateTest },
248 ["IsSerializeAfter","IsNonSpeculative"])
249 header_output += MsrRegDeclare.subst(msrCpsrRegIop)
250 decoder_output += MsrRegConstructor.subst(msrCpsrRegIop)
251 exec_output += PredOpExecute.subst(msrCpsrRegIop)
252
253 msrSpsrRegCode = "Spsr = spsrWriteByInstr(Spsr, Op1, byteMask, false);"
254 msrSpsrRegIop = InstObjParams("msr", "MsrSpsrReg", "MsrRegOp",
255 { "code": msrSpsrRegCode,
256 "predicate_test": predicateTest },
257 ["IsSerializeAfter","IsNonSpeculative"])
258 header_output += MsrRegDeclare.subst(msrSpsrRegIop)
259 decoder_output += MsrRegConstructor.subst(msrSpsrRegIop)
260 exec_output += PredOpExecute.subst(msrSpsrRegIop)
261
262 msrCpsrImmCode = '''
263 SCTLR sctlr = Sctlr;
264 CPSR old_cpsr = Cpsr;
265 old_cpsr.nz = CondCodesNZ;
266 old_cpsr.c = CondCodesC;
267 old_cpsr.v = CondCodesV;
268 old_cpsr.ge = CondCodesGE;
269 CPSR new_cpsr =
270 cpsrWriteByInstr(old_cpsr, imm, Scr, Nsacr, byteMask, false,
271 sctlr.nmfi, xc->tcBase());
272 Cpsr = ~CondCodesMask & new_cpsr;
273 CondCodesNZ = new_cpsr.nz;
274 CondCodesC = new_cpsr.c;
275 CondCodesV = new_cpsr.v;
276 CondCodesGE = new_cpsr.ge;
277 '''
278 msrCpsrImmIop = InstObjParams("msr", "MsrCpsrImm", "MsrImmOp",
279 { "code": msrCpsrImmCode,
280 "predicate_test": condPredicateTest },
281 ["IsSerializeAfter","IsNonSpeculative"])
282 header_output += MsrImmDeclare.subst(msrCpsrImmIop)
283 decoder_output += MsrImmConstructor.subst(msrCpsrImmIop)
284 exec_output += PredOpExecute.subst(msrCpsrImmIop)
285
286 msrSpsrImmCode = "Spsr = spsrWriteByInstr(Spsr, imm, byteMask, false);"
287 msrSpsrImmIop = InstObjParams("msr", "MsrSpsrImm", "MsrImmOp",
288 { "code": msrSpsrImmCode,
289 "predicate_test": predicateTest },
290 ["IsSerializeAfter","IsNonSpeculative"])
291 header_output += MsrImmDeclare.subst(msrSpsrImmIop)
292 decoder_output += MsrImmConstructor.subst(msrSpsrImmIop)
293 exec_output += PredOpExecute.subst(msrSpsrImmIop)
294
295 revCode = '''
296 uint32_t val = Op1;
297 Dest = swap_byte(val);
298 '''
299 revIop = InstObjParams("rev", "Rev", "RegRegOp",
300 { "code": revCode,
301 "predicate_test": predicateTest }, [])
302 header_output += RegRegOpDeclare.subst(revIop)
303 decoder_output += RegRegOpConstructor.subst(revIop)
304 exec_output += PredOpExecute.subst(revIop)
305
306 rev16Code = '''
307 uint32_t val = Op1;
308 Dest = (bits(val, 15, 8) << 0) |
309 (bits(val, 7, 0) << 8) |
310 (bits(val, 31, 24) << 16) |
311 (bits(val, 23, 16) << 24);
312 '''
313 rev16Iop = InstObjParams("rev16", "Rev16", "RegRegOp",
314 { "code": rev16Code,
315 "predicate_test": predicateTest }, [])
316 header_output += RegRegOpDeclare.subst(rev16Iop)
317 decoder_output += RegRegOpConstructor.subst(rev16Iop)
318 exec_output += PredOpExecute.subst(rev16Iop)
319
320 revshCode = '''
321 uint16_t val = Op1;
322 Dest = sext<16>(swap_byte(val));
323 '''
324 revshIop = InstObjParams("revsh", "Revsh", "RegRegOp",
325 { "code": revshCode,
326 "predicate_test": predicateTest }, [])
327 header_output += RegRegOpDeclare.subst(revshIop)
328 decoder_output += RegRegOpConstructor.subst(revshIop)
329 exec_output += PredOpExecute.subst(revshIop)
330
331 rbitCode = '''
332 uint8_t *opBytes = (uint8_t *)&Op1;
333 uint32_t resTemp;
334 uint8_t *destBytes = (uint8_t *)&resTemp;
335 // This reverses the bytes and bits of the input, or so says the
336 // internet.
337 for (int i = 0; i < 4; i++) {
338 uint32_t temp = opBytes[i];
339 temp = (temp * 0x0802 & 0x22110) | (temp * 0x8020 & 0x88440);
340 destBytes[3 - i] = (temp * 0x10101) >> 16;
341 }
342 Dest = resTemp;
343 '''
344 rbitIop = InstObjParams("rbit", "Rbit", "RegRegOp",
345 { "code": rbitCode,
346 "predicate_test": predicateTest }, [])
347 header_output += RegRegOpDeclare.subst(rbitIop)
348 decoder_output += RegRegOpConstructor.subst(rbitIop)
349 exec_output += PredOpExecute.subst(rbitIop)
350
351 clzCode = '''
352 Dest = (Op1 == 0) ? 32 : (31 - findMsbSet(Op1));
353 '''
354 clzIop = InstObjParams("clz", "Clz", "RegRegOp",
355 { "code": clzCode,
356 "predicate_test": predicateTest }, [])
357 header_output += RegRegOpDeclare.subst(clzIop)
358 decoder_output += RegRegOpConstructor.subst(clzIop)
359 exec_output += PredOpExecute.subst(clzIop)
360
361 ssatCode = '''
362 int32_t operand = shift_rm_imm(Op1, shiftAmt, shiftType, 0);
363 int32_t res;
364 if (satInt(res, operand, imm))
365 CpsrQ = 1 << 27;
366 Dest = res;
367 '''
368 ssatIop = InstObjParams("ssat", "Ssat", "RegImmRegShiftOp",
369 { "code": ssatCode,
370 "predicate_test": pickPredicate(ssatCode) }, [])
371 header_output += RegImmRegShiftOpDeclare.subst(ssatIop)
372 decoder_output += RegImmRegShiftOpConstructor.subst(ssatIop)
373 exec_output += PredOpExecute.subst(ssatIop)
374
375 usatCode = '''
376 int32_t operand = shift_rm_imm(Op1, shiftAmt, shiftType, 0);
377 int32_t res;
378 if (uSatInt(res, operand, imm))
379 CpsrQ = 1 << 27;
380 Dest = res;
381 '''
382 usatIop = InstObjParams("usat", "Usat", "RegImmRegShiftOp",
383 { "code": usatCode,
384 "predicate_test": pickPredicate(usatCode) }, [])
385 header_output += RegImmRegShiftOpDeclare.subst(usatIop)
386 decoder_output += RegImmRegShiftOpConstructor.subst(usatIop)
387 exec_output += PredOpExecute.subst(usatIop)
388
389 ssat16Code = '''
390 int32_t res;
391 uint32_t resTemp = 0;
392 int32_t argLow = sext<16>(bits(Op1, 15, 0));
393 int32_t argHigh = sext<16>(bits(Op1, 31, 16));
394 if (satInt(res, argLow, imm))
395 CpsrQ = 1 << 27;
396 replaceBits(resTemp, 15, 0, res);
397 if (satInt(res, argHigh, imm))
398 CpsrQ = 1 << 27;
399 replaceBits(resTemp, 31, 16, res);
400 Dest = resTemp;
401 '''
402 ssat16Iop = InstObjParams("ssat16", "Ssat16", "RegImmRegOp",
403 { "code": ssat16Code,
404 "predicate_test": pickPredicate(ssat16Code) }, [])
405 header_output += RegImmRegOpDeclare.subst(ssat16Iop)
406 decoder_output += RegImmRegOpConstructor.subst(ssat16Iop)
407 exec_output += PredOpExecute.subst(ssat16Iop)
408
409 usat16Code = '''
410 int32_t res;
411 uint32_t resTemp = 0;
412 int32_t argLow = sext<16>(bits(Op1, 15, 0));
413 int32_t argHigh = sext<16>(bits(Op1, 31, 16));
414 if (uSatInt(res, argLow, imm))
415 CpsrQ = 1 << 27;
416 replaceBits(resTemp, 15, 0, res);
417 if (uSatInt(res, argHigh, imm))
418 CpsrQ = 1 << 27;
419 replaceBits(resTemp, 31, 16, res);
420 Dest = resTemp;
421 '''
422 usat16Iop = InstObjParams("usat16", "Usat16", "RegImmRegOp",
423 { "code": usat16Code,
424 "predicate_test": pickPredicate(usat16Code) }, [])
425 header_output += RegImmRegOpDeclare.subst(usat16Iop)
426 decoder_output += RegImmRegOpConstructor.subst(usat16Iop)
427 exec_output += PredOpExecute.subst(usat16Iop)
428
429 sxtbIop = InstObjParams("sxtb", "Sxtb", "RegImmRegOp",
430 { "code":
431 "Dest = sext<8>((uint8_t)(Op1_ud >> imm));",
432 "predicate_test": predicateTest }, [])
433 header_output += RegImmRegOpDeclare.subst(sxtbIop)
434 decoder_output += RegImmRegOpConstructor.subst(sxtbIop)
435 exec_output += PredOpExecute.subst(sxtbIop)
436
437 sxtabIop = InstObjParams("sxtab", "Sxtab", "RegRegRegImmOp",
438 { "code":
439 '''
440 Dest = sext<8>((uint8_t)(Op2_ud >> imm)) +
441 Op1;
442 ''',
443 "predicate_test": predicateTest }, [])
444 header_output += RegRegRegImmOpDeclare.subst(sxtabIop)
445 decoder_output += RegRegRegImmOpConstructor.subst(sxtabIop)
446 exec_output += PredOpExecute.subst(sxtabIop)
447
448 sxtb16Code = '''
449 uint32_t resTemp = 0;
450 replaceBits(resTemp, 15, 0, sext<8>(bits(Op1, imm + 7, imm)));
451 replaceBits(resTemp, 31, 16,
452 sext<8>(bits(Op1, (imm + 23) % 32, (imm + 16) % 32)));
453 Dest = resTemp;
454 '''
455 sxtb16Iop = InstObjParams("sxtb16", "Sxtb16", "RegImmRegOp",
456 { "code": sxtb16Code,
457 "predicate_test": predicateTest }, [])
458 header_output += RegImmRegOpDeclare.subst(sxtb16Iop)
459 decoder_output += RegImmRegOpConstructor.subst(sxtb16Iop)
460 exec_output += PredOpExecute.subst(sxtb16Iop)
461
462 sxtab16Code = '''
463 uint32_t resTemp = 0;
464 replaceBits(resTemp, 15, 0, sext<8>(bits(Op2, imm + 7, imm)) +
465 bits(Op1, 15, 0));
466 replaceBits(resTemp, 31, 16,
467 sext<8>(bits(Op2, (imm + 23) % 32, (imm + 16) % 32)) +
468 bits(Op1, 31, 16));
469 Dest = resTemp;
470 '''
471 sxtab16Iop = InstObjParams("sxtab16", "Sxtab16", "RegRegRegImmOp",
472 { "code": sxtab16Code,
473 "predicate_test": predicateTest }, [])
474 header_output += RegRegRegImmOpDeclare.subst(sxtab16Iop)
475 decoder_output += RegRegRegImmOpConstructor.subst(sxtab16Iop)
476 exec_output += PredOpExecute.subst(sxtab16Iop)
477
478 sxthCode = '''
479 uint64_t rotated = (uint32_t)Op1;
480 rotated = (rotated | (rotated << 32)) >> imm;
481 Dest = sext<16>((uint16_t)rotated);
482 '''
483 sxthIop = InstObjParams("sxth", "Sxth", "RegImmRegOp",
484 { "code": sxthCode,
485 "predicate_test": predicateTest }, [])
486 header_output += RegImmRegOpDeclare.subst(sxthIop)
487 decoder_output += RegImmRegOpConstructor.subst(sxthIop)
488 exec_output += PredOpExecute.subst(sxthIop)
489
490 sxtahCode = '''
491 uint64_t rotated = (uint32_t)Op2;
492 rotated = (rotated | (rotated << 32)) >> imm;
493 Dest = sext<16>((uint16_t)rotated) + Op1;
494 '''
495 sxtahIop = InstObjParams("sxtah", "Sxtah", "RegRegRegImmOp",
496 { "code": sxtahCode,
497 "predicate_test": predicateTest }, [])
498 header_output += RegRegRegImmOpDeclare.subst(sxtahIop)
499 decoder_output += RegRegRegImmOpConstructor.subst(sxtahIop)
500 exec_output += PredOpExecute.subst(sxtahIop)
501
502 uxtbIop = InstObjParams("uxtb", "Uxtb", "RegImmRegOp",
503 { "code": "Dest = (uint8_t)(Op1_ud >> imm);",
504 "predicate_test": predicateTest }, [])
505 header_output += RegImmRegOpDeclare.subst(uxtbIop)
506 decoder_output += RegImmRegOpConstructor.subst(uxtbIop)
507 exec_output += PredOpExecute.subst(uxtbIop)
508
509 uxtabIop = InstObjParams("uxtab", "Uxtab", "RegRegRegImmOp",
510 { "code":
511 "Dest = (uint8_t)(Op2_ud >> imm) + Op1;",
512 "predicate_test": predicateTest }, [])
513 header_output += RegRegRegImmOpDeclare.subst(uxtabIop)
514 decoder_output += RegRegRegImmOpConstructor.subst(uxtabIop)
515 exec_output += PredOpExecute.subst(uxtabIop)
516
517 uxtb16Code = '''
518 uint32_t resTemp = 0;
519 replaceBits(resTemp, 15, 0, (uint8_t)(bits(Op1, imm + 7, imm)));
520 replaceBits(resTemp, 31, 16,
521 (uint8_t)(bits(Op1, (imm + 23) % 32, (imm + 16) % 32)));
522 Dest = resTemp;
523 '''
524 uxtb16Iop = InstObjParams("uxtb16", "Uxtb16", "RegImmRegOp",
525 { "code": uxtb16Code,
526 "predicate_test": predicateTest }, [])
527 header_output += RegImmRegOpDeclare.subst(uxtb16Iop)
528 decoder_output += RegImmRegOpConstructor.subst(uxtb16Iop)
529 exec_output += PredOpExecute.subst(uxtb16Iop)
530
531 uxtab16Code = '''
532 uint32_t resTemp = 0;
533 replaceBits(resTemp, 15, 0, (uint8_t)(bits(Op2, imm + 7, imm)) +
534 bits(Op1, 15, 0));
535 replaceBits(resTemp, 31, 16,
536 (uint8_t)(bits(Op2, (imm + 23) % 32, (imm + 16) % 32)) +
537 bits(Op1, 31, 16));
538 Dest = resTemp;
539 '''
540 uxtab16Iop = InstObjParams("uxtab16", "Uxtab16", "RegRegRegImmOp",
541 { "code": uxtab16Code,
542 "predicate_test": predicateTest }, [])
543 header_output += RegRegRegImmOpDeclare.subst(uxtab16Iop)
544 decoder_output += RegRegRegImmOpConstructor.subst(uxtab16Iop)
545 exec_output += PredOpExecute.subst(uxtab16Iop)
546
547 uxthCode = '''
548 uint64_t rotated = (uint32_t)Op1;
549 rotated = (rotated | (rotated << 32)) >> imm;
550 Dest = (uint16_t)rotated;
551 '''
552 uxthIop = InstObjParams("uxth", "Uxth", "RegImmRegOp",
553 { "code": uxthCode,
554 "predicate_test": predicateTest }, [])
555 header_output += RegImmRegOpDeclare.subst(uxthIop)
556 decoder_output += RegImmRegOpConstructor.subst(uxthIop)
557 exec_output += PredOpExecute.subst(uxthIop)
558
559 uxtahCode = '''
560 uint64_t rotated = (uint32_t)Op2;
561 rotated = (rotated | (rotated << 32)) >> imm;
562 Dest = (uint16_t)rotated + Op1;
563 '''
564 uxtahIop = InstObjParams("uxtah", "Uxtah", "RegRegRegImmOp",
565 { "code": uxtahCode,
566 "predicate_test": predicateTest }, [])
567 header_output += RegRegRegImmOpDeclare.subst(uxtahIop)
568 decoder_output += RegRegRegImmOpConstructor.subst(uxtahIop)
569 exec_output += PredOpExecute.subst(uxtahIop)
570
571 selCode = '''
572 uint32_t resTemp = 0;
573 for (unsigned i = 0; i < 4; i++) {
574 int low = i * 8;
575 int high = low + 7;
576 replaceBits(resTemp, high, low,
577 bits(CondCodesGE, i) ?
578 bits(Op1, high, low) : bits(Op2, high, low));
579 }
580 Dest = resTemp;
581 '''
582 selIop = InstObjParams("sel", "Sel", "RegRegRegOp",
583 { "code": selCode,
584 "predicate_test": predicateTest }, [])
585 header_output += RegRegRegOpDeclare.subst(selIop)
586 decoder_output += RegRegRegOpConstructor.subst(selIop)
587 exec_output += PredOpExecute.subst(selIop)
588
589 usad8Code = '''
590 uint32_t resTemp = 0;
591 for (unsigned i = 0; i < 4; i++) {
592 int low = i * 8;
593 int high = low + 7;
594 int32_t diff = bits(Op1, high, low) -
595 bits(Op2, high, low);
596 resTemp += ((diff < 0) ? -diff : diff);
597 }
598 Dest = resTemp;
599 '''
600 usad8Iop = InstObjParams("usad8", "Usad8", "RegRegRegOp",
601 { "code": usad8Code,
602 "predicate_test": predicateTest }, [])
603 header_output += RegRegRegOpDeclare.subst(usad8Iop)
604 decoder_output += RegRegRegOpConstructor.subst(usad8Iop)
605 exec_output += PredOpExecute.subst(usad8Iop)
606
607 usada8Code = '''
608 uint32_t resTemp = 0;
609 for (unsigned i = 0; i < 4; i++) {
610 int low = i * 8;
611 int high = low + 7;
612 int32_t diff = bits(Op1, high, low) -
613 bits(Op2, high, low);
614 resTemp += ((diff < 0) ? -diff : diff);
615 }
616 Dest = Op3 + resTemp;
617 '''
618 usada8Iop = InstObjParams("usada8", "Usada8", "RegRegRegRegOp",
619 { "code": usada8Code,
620 "predicate_test": predicateTest }, [])
621 header_output += RegRegRegRegOpDeclare.subst(usada8Iop)
622 decoder_output += RegRegRegRegOpConstructor.subst(usada8Iop)
623 exec_output += PredOpExecute.subst(usada8Iop)
624
625 bkptCode = 'return std::make_shared<PrefetchAbort>(PC, ArmFault::DebugEvent);\n'
626 bkptIop = InstObjParams("bkpt", "BkptInst", "PredOp", bkptCode)
627 header_output += BasicDeclare.subst(bkptIop)
628 decoder_output += BasicConstructor.subst(bkptIop)
629 exec_output += BasicExecute.subst(bkptIop)
630
631 nopIop = InstObjParams("nop", "NopInst", "ArmStaticInst", "", ['IsNop'])
632 header_output += BasicDeclare.subst(nopIop)
633 decoder_output += BasicConstructor64.subst(nopIop)
634 exec_output += BasicExecute.subst(nopIop)
635
636 yieldIop = InstObjParams("yield", "YieldInst", "PredOp", \
637 { "code" : "", "predicate_test" : predicateTest })
638 header_output += BasicDeclare.subst(yieldIop)
639 decoder_output += BasicConstructor.subst(yieldIop)
640 exec_output += PredOpExecute.subst(yieldIop)
641
642 wfeCode = '''
643 HCR hcr = Hcr;
644 CPSR cpsr = Cpsr;
645 SCR scr = Scr64;
646 SCTLR sctlr = Sctlr;
647
648 // WFE Sleeps if SevMailbox==0 and no unmasked interrupts are pending,
649 ThreadContext *tc = xc->tcBase();
650 if (SevMailbox == 1) {
651 SevMailbox = 0;
652 PseudoInst::quiesceSkip(tc);
653 } else if (tc->getCpuPtr()->getInterruptController(
654 tc->threadId())->checkInterrupts(tc)) {
655 PseudoInst::quiesceSkip(tc);
656 } else if (cpsr.el == EL0 && !sctlr.ntwe) {
657 PseudoInst::quiesceSkip(tc);
658 fault = std::make_shared<SupervisorTrap>(machInst, 0x1E00001,
659 EC_TRAPPED_WFI_WFE);
660 } else if (ArmSystem::haveVirtualization(tc) &&
661 !inSecureState(scr, cpsr) && (cpsr.mode != MODE_HYP) &&
662 hcr.twe) {
663 PseudoInst::quiesceSkip(tc);
664 fault = std::make_shared<HypervisorTrap>(machInst, 0x1E00001,
665 EC_TRAPPED_WFI_WFE);
666 } else if (ArmSystem::haveSecurity(tc) && cpsr.el != EL3 && scr.twe) {
667 PseudoInst::quiesceSkip(tc);
668 fault = std::make_shared<SecureMonitorTrap>(machInst, 0x1E00001,
669 EC_TRAPPED_WFI_WFE);
670 } else {
671 PseudoInst::quiesce(tc);
672 }
673 '''
674 wfePredFixUpCode = '''
675 // WFE is predicated false, reset SevMailbox to reduce spurious sleeps
676 // and SEV interrupts
677 SevMailbox = 1;
678 '''
679 wfeIop = InstObjParams("wfe", "WfeInst", "PredOp", \
680 { "code" : wfeCode,
681 "pred_fixup" : wfePredFixUpCode,
682 "predicate_test" : predicateTest },
683 ["IsNonSpeculative", "IsQuiesce",
684 "IsSerializeAfter", "IsUnverifiable"])
685 header_output += BasicDeclare.subst(wfeIop)
686 decoder_output += BasicConstructor.subst(wfeIop)
687 exec_output += QuiescePredOpExecuteWithFixup.subst(wfeIop)
688
689 wfiCode = '''
690 HCR hcr = Hcr;
691 CPSR cpsr = Cpsr;
692 SCR scr = Scr64;
693 SCTLR sctlr = Sctlr;
694
695 // WFI doesn't sleep if interrupts are pending (masked or not)
696 ThreadContext *tc = xc->tcBase();
697 if (tc->getCpuPtr()->getInterruptController(
698 tc->threadId())->checkWfiWake(hcr, cpsr, scr)) {
699 PseudoInst::quiesceSkip(tc);
700 } else if (cpsr.el == EL0 && !sctlr.ntwi) {
701 PseudoInst::quiesceSkip(tc);
702 fault = std::make_shared<SupervisorTrap>(machInst, 0x1E00000,
703 EC_TRAPPED_WFI_WFE);
704 } else if (ArmSystem::haveVirtualization(tc) && hcr.twi &&
705 (cpsr.mode != MODE_HYP) && !inSecureState(scr, cpsr)) {
706 PseudoInst::quiesceSkip(tc);
707 fault = std::make_shared<HypervisorTrap>(machInst, 0x1E00000,
708 EC_TRAPPED_WFI_WFE);
709 } else if (ArmSystem::haveSecurity(tc) && cpsr.el != EL3 && scr.twi) {
710 PseudoInst::quiesceSkip(tc);
711 fault = std::make_shared<SecureMonitorTrap>(machInst, 0x1E00000,
712 EC_TRAPPED_WFI_WFE);
713 } else {
714 PseudoInst::quiesce(tc);
715 }
716 tc->getCpuPtr()->clearInterrupt(tc->threadId(), INT_ABT, 0);
717 '''
718 wfiIop = InstObjParams("wfi", "WfiInst", "PredOp", \
719 { "code" : wfiCode, "predicate_test" : predicateTest },
720 ["IsNonSpeculative", "IsQuiesce",
721 "IsSerializeAfter", "IsUnverifiable"])
722 header_output += BasicDeclare.subst(wfiIop)
723 decoder_output += BasicConstructor.subst(wfiIop)
724 exec_output += QuiescePredOpExecute.subst(wfiIop)
725
726 sevCode = '''
727 SevMailbox = 1;
728 System *sys = xc->tcBase()->getSystemPtr();
729 for (int x = 0; x < sys->numContexts(); x++) {
730 ThreadContext *oc = sys->getThreadContext(x);
731 if (oc == xc->tcBase())
732 continue;
733 // Wake CPU with interrupt if they were sleeping
734 if (oc->readMiscReg(MISCREG_SEV_MAILBOX) == 0) {
735 // Post Interrupt and wake cpu if needed
736 oc->getCpuPtr()->postInterrupt(oc->threadId(), INT_SEV, 0);
737 }
738 }
739 '''
740 sevIop = InstObjParams("sev", "SevInst", "PredOp", \
741 { "code" : sevCode, "predicate_test" : predicateTest },
742 ["IsNonSpeculative", "IsSquashAfter", "IsUnverifiable"])
743 header_output += BasicDeclare.subst(sevIop)
744 decoder_output += BasicConstructor.subst(sevIop)
745 exec_output += PredOpExecute.subst(sevIop)
746
747 sevlCode = '''
748 SevMailbox = 1;
749 '''
750 sevlIop = InstObjParams("sevl", "SevlInst", "PredOp", \
751 { "code" : sevlCode, "predicate_test" : predicateTest },
752 ["IsNonSpeculative", "IsSquashAfter", "IsUnverifiable"])
753 header_output += BasicDeclare.subst(sevlIop)
754 decoder_output += BasicConstructor.subst(sevlIop)
755 exec_output += BasicExecute.subst(sevlIop)
756
757 itIop = InstObjParams("it", "ItInst", "PredOp", \
758 { "code" : ";",
759 "predicate_test" : predicateTest }, [])
760 header_output += BasicDeclare.subst(itIop)
761 decoder_output += BasicConstructor.subst(itIop)
762 exec_output += PredOpExecute.subst(itIop)
763 unknownCode = '''
764 return std::make_shared<UndefinedInstruction>(machInst, true);
765 '''
766 unknownIop = InstObjParams("unknown", "Unknown", "UnknownOp", \
767 { "code": unknownCode,
768 "predicate_test": predicateTest })
769 header_output += BasicDeclare.subst(unknownIop)
770 decoder_output += BasicConstructor.subst(unknownIop)
771 exec_output += PredOpExecute.subst(unknownIop)
772
773 ubfxCode = '''
774 Dest = bits(Op1, imm2, imm1);
775 '''
776 ubfxIop = InstObjParams("ubfx", "Ubfx", "RegRegImmImmOp",
777 { "code": ubfxCode,
778 "predicate_test": predicateTest }, [])
779 header_output += RegRegImmImmOpDeclare.subst(ubfxIop)
780 decoder_output += RegRegImmImmOpConstructor.subst(ubfxIop)
781 exec_output += PredOpExecute.subst(ubfxIop)
782
783 sbfxCode = '''
784 int32_t resTemp = bits(Op1, imm2, imm1);
785 Dest = resTemp | -(resTemp & (1 << (imm2 - imm1)));
786 '''
787 sbfxIop = InstObjParams("sbfx", "Sbfx", "RegRegImmImmOp",
788 { "code": sbfxCode,
789 "predicate_test": predicateTest }, [])
790 header_output += RegRegImmImmOpDeclare.subst(sbfxIop)
791 decoder_output += RegRegImmImmOpConstructor.subst(sbfxIop)
792 exec_output += PredOpExecute.subst(sbfxIop)
793
794 bfcCode = '''
795 Dest = Op1 & ~(mask(imm2 - imm1 + 1) << imm1);
796 '''
797 bfcIop = InstObjParams("bfc", "Bfc", "RegRegImmImmOp",
798 { "code": bfcCode,
799 "predicate_test": predicateTest }, [])
800 header_output += RegRegImmImmOpDeclare.subst(bfcIop)
801 decoder_output += RegRegImmImmOpConstructor.subst(bfcIop)
802 exec_output += PredOpExecute.subst(bfcIop)
803
804 bfiCode = '''
805 uint32_t bitMask = (mask(imm2 - imm1 + 1) << imm1);
806 Dest = ((Op1 << imm1) & bitMask) | (Dest & ~bitMask);
807 '''
808 bfiIop = InstObjParams("bfi", "Bfi", "RegRegImmImmOp",
809 { "code": bfiCode,
810 "predicate_test": predicateTest }, [])
811 header_output += RegRegImmImmOpDeclare.subst(bfiIop)
812 decoder_output += RegRegImmImmOpConstructor.subst(bfiIop)
813 exec_output += PredOpExecute.subst(bfiIop)
814
815 mrc14code = '''
816 MiscRegIndex miscReg = (MiscRegIndex) xc->tcBase()->flattenMiscIndex(op1);
816 MiscRegIndex miscReg = (MiscRegIndex) xc->tcBase()->flattenRegId(
817 RegId(MiscRegClass, op1)).index();
817 bool can_read, undefined;
818 std::tie(can_read, undefined) = canReadCoprocReg(miscReg, Scr, Cpsr);
819 if (!can_read || undefined) {
820 return std::make_shared<UndefinedInstruction>(machInst, false,
821 mnemonic);
822 }
823 if (mcrMrc14TrapToHyp((const MiscRegIndex) op1, Hcr, Cpsr, Scr, Hdcr,
824 Hstr, Hcptr, imm)) {
825 return std::make_shared<HypervisorTrap>(machInst, imm,
826 EC_TRAPPED_CP14_MCR_MRC);
827 }
828 Dest = MiscOp1;
829 '''
830
831 mrc14Iop = InstObjParams("mrc", "Mrc14", "RegRegImmOp",
832 { "code": mrc14code,
833 "predicate_test": predicateTest }, [])
834 header_output += RegRegImmOpDeclare.subst(mrc14Iop)
835 decoder_output += RegRegImmOpConstructor.subst(mrc14Iop)
836 exec_output += PredOpExecute.subst(mrc14Iop)
837
838
839 mcr14code = '''
818 bool can_read, undefined;
819 std::tie(can_read, undefined) = canReadCoprocReg(miscReg, Scr, Cpsr);
820 if (!can_read || undefined) {
821 return std::make_shared<UndefinedInstruction>(machInst, false,
822 mnemonic);
823 }
824 if (mcrMrc14TrapToHyp((const MiscRegIndex) op1, Hcr, Cpsr, Scr, Hdcr,
825 Hstr, Hcptr, imm)) {
826 return std::make_shared<HypervisorTrap>(machInst, imm,
827 EC_TRAPPED_CP14_MCR_MRC);
828 }
829 Dest = MiscOp1;
830 '''
831
832 mrc14Iop = InstObjParams("mrc", "Mrc14", "RegRegImmOp",
833 { "code": mrc14code,
834 "predicate_test": predicateTest }, [])
835 header_output += RegRegImmOpDeclare.subst(mrc14Iop)
836 decoder_output += RegRegImmOpConstructor.subst(mrc14Iop)
837 exec_output += PredOpExecute.subst(mrc14Iop)
838
839
840 mcr14code = '''
840 MiscRegIndex miscReg = (MiscRegIndex) xc->tcBase()->flattenMiscIndex(dest);
841 MiscRegIndex miscReg = (MiscRegIndex) xc->tcBase()->flattenRegId(
842 RegId(MiscRegClass, dest)).index();
841 bool can_write, undefined;
842 std::tie(can_write, undefined) = canWriteCoprocReg(miscReg, Scr, Cpsr);
843 if (undefined || !can_write) {
844 return std::make_shared<UndefinedInstruction>(machInst, false,
845 mnemonic);
846 }
847 if (mcrMrc14TrapToHyp(miscReg, Hcr, Cpsr, Scr, Hdcr,
848 Hstr, Hcptr, imm)) {
849 return std::make_shared<HypervisorTrap>(machInst, imm,
850 EC_TRAPPED_CP14_MCR_MRC);
851 }
852 MiscDest = Op1;
853 '''
854 mcr14Iop = InstObjParams("mcr", "Mcr14", "RegRegImmOp",
855 { "code": mcr14code,
856 "predicate_test": predicateTest },
857 ["IsSerializeAfter","IsNonSpeculative"])
858 header_output += RegRegImmOpDeclare.subst(mcr14Iop)
859 decoder_output += RegRegImmOpConstructor.subst(mcr14Iop)
860 exec_output += PredOpExecute.subst(mcr14Iop)
861
862 mrc15code = '''
863 int preFlatOp1 = flattenMiscRegNsBanked(op1, xc->tcBase());
864 MiscRegIndex miscReg = (MiscRegIndex)
843 bool can_write, undefined;
844 std::tie(can_write, undefined) = canWriteCoprocReg(miscReg, Scr, Cpsr);
845 if (undefined || !can_write) {
846 return std::make_shared<UndefinedInstruction>(machInst, false,
847 mnemonic);
848 }
849 if (mcrMrc14TrapToHyp(miscReg, Hcr, Cpsr, Scr, Hdcr,
850 Hstr, Hcptr, imm)) {
851 return std::make_shared<HypervisorTrap>(machInst, imm,
852 EC_TRAPPED_CP14_MCR_MRC);
853 }
854 MiscDest = Op1;
855 '''
856 mcr14Iop = InstObjParams("mcr", "Mcr14", "RegRegImmOp",
857 { "code": mcr14code,
858 "predicate_test": predicateTest },
859 ["IsSerializeAfter","IsNonSpeculative"])
860 header_output += RegRegImmOpDeclare.subst(mcr14Iop)
861 decoder_output += RegRegImmOpConstructor.subst(mcr14Iop)
862 exec_output += PredOpExecute.subst(mcr14Iop)
863
864 mrc15code = '''
865 int preFlatOp1 = flattenMiscRegNsBanked(op1, xc->tcBase());
866 MiscRegIndex miscReg = (MiscRegIndex)
865 xc->tcBase()->flattenMiscIndex(preFlatOp1);
867 xc->tcBase()->flattenRegId(RegId(MiscRegClass,
868 preFlatOp1)).index();
866 bool hypTrap = mcrMrc15TrapToHyp(miscReg, Hcr, Cpsr, Scr, Hdcr, Hstr,
867 Hcptr, imm);
868 bool can_read, undefined;
869 std::tie(can_read, undefined) = canReadCoprocReg(miscReg, Scr, Cpsr);
870 // if we're in non secure PL1 mode then we can trap regargless of whether
871 // the register is accessable, in other modes we trap if only if the register
872 // IS accessable.
873 if (undefined || (!can_read && !(hypTrap && !inUserMode(Cpsr) &&
874 !inSecureState(Scr, Cpsr)))) {
875 return std::make_shared<UndefinedInstruction>(machInst, false,
876 mnemonic);
877 }
878 if (hypTrap) {
879 return std::make_shared<HypervisorTrap>(machInst, imm,
880 EC_TRAPPED_CP15_MCR_MRC);
881 }
882 Dest = MiscNsBankedOp1;
883 '''
884
885 mrc15Iop = InstObjParams("mrc", "Mrc15", "RegMiscRegImmOp",
886 { "code": mrc15code,
887 "predicate_test": predicateTest }, [])
888 header_output += RegMiscRegImmOpDeclare.subst(mrc15Iop)
889 decoder_output += RegMiscRegImmOpConstructor.subst(mrc15Iop)
890 exec_output += PredOpExecute.subst(mrc15Iop)
891
892
893 mcr15code = '''
894 int preFlatDest = flattenMiscRegNsBanked(dest, xc->tcBase());
895 MiscRegIndex miscReg = (MiscRegIndex)
869 bool hypTrap = mcrMrc15TrapToHyp(miscReg, Hcr, Cpsr, Scr, Hdcr, Hstr,
870 Hcptr, imm);
871 bool can_read, undefined;
872 std::tie(can_read, undefined) = canReadCoprocReg(miscReg, Scr, Cpsr);
873 // if we're in non secure PL1 mode then we can trap regargless of whether
874 // the register is accessable, in other modes we trap if only if the register
875 // IS accessable.
876 if (undefined || (!can_read && !(hypTrap && !inUserMode(Cpsr) &&
877 !inSecureState(Scr, Cpsr)))) {
878 return std::make_shared<UndefinedInstruction>(machInst, false,
879 mnemonic);
880 }
881 if (hypTrap) {
882 return std::make_shared<HypervisorTrap>(machInst, imm,
883 EC_TRAPPED_CP15_MCR_MRC);
884 }
885 Dest = MiscNsBankedOp1;
886 '''
887
888 mrc15Iop = InstObjParams("mrc", "Mrc15", "RegMiscRegImmOp",
889 { "code": mrc15code,
890 "predicate_test": predicateTest }, [])
891 header_output += RegMiscRegImmOpDeclare.subst(mrc15Iop)
892 decoder_output += RegMiscRegImmOpConstructor.subst(mrc15Iop)
893 exec_output += PredOpExecute.subst(mrc15Iop)
894
895
896 mcr15code = '''
897 int preFlatDest = flattenMiscRegNsBanked(dest, xc->tcBase());
898 MiscRegIndex miscReg = (MiscRegIndex)
896 xc->tcBase()->flattenMiscIndex(preFlatDest);
899 xc->tcBase()->flattenRegId(RegId(MiscRegClass,
900 preFlatDest)).index();
897 bool hypTrap = mcrMrc15TrapToHyp(miscReg, Hcr, Cpsr, Scr, Hdcr, Hstr,
898 Hcptr, imm);
899 bool can_write, undefined;
900 std::tie(can_write, undefined) = canWriteCoprocReg(miscReg, Scr, Cpsr);
901
902 // if we're in non secure PL1 mode then we can trap regargless of whether
903 // the register is accessable, in other modes we trap if only if the register
904 // IS accessable.
905 if (undefined || (!can_write && !(hypTrap && !inUserMode(Cpsr) &&
906 !inSecureState(Scr, Cpsr)))) {
907 return std::make_shared<UndefinedInstruction>(machInst, false,
908 mnemonic);
909 }
910 if (hypTrap) {
911 return std::make_shared<HypervisorTrap>(machInst, imm,
912 EC_TRAPPED_CP15_MCR_MRC);
913 }
914 MiscNsBankedDest = Op1;
915 '''
916 mcr15Iop = InstObjParams("mcr", "Mcr15", "MiscRegRegImmOp",
917 { "code": mcr15code,
918 "predicate_test": predicateTest },
919 ["IsSerializeAfter","IsNonSpeculative"])
920 header_output += MiscRegRegImmOpDeclare.subst(mcr15Iop)
921 decoder_output += MiscRegRegImmOpConstructor.subst(mcr15Iop)
922 exec_output += PredOpExecute.subst(mcr15Iop)
923
924
925 mrrc15code = '''
926 int preFlatOp1 = flattenMiscRegNsBanked(op1, xc->tcBase());
927 MiscRegIndex miscReg = (MiscRegIndex)
901 bool hypTrap = mcrMrc15TrapToHyp(miscReg, Hcr, Cpsr, Scr, Hdcr, Hstr,
902 Hcptr, imm);
903 bool can_write, undefined;
904 std::tie(can_write, undefined) = canWriteCoprocReg(miscReg, Scr, Cpsr);
905
906 // if we're in non secure PL1 mode then we can trap regargless of whether
907 // the register is accessable, in other modes we trap if only if the register
908 // IS accessable.
909 if (undefined || (!can_write && !(hypTrap && !inUserMode(Cpsr) &&
910 !inSecureState(Scr, Cpsr)))) {
911 return std::make_shared<UndefinedInstruction>(machInst, false,
912 mnemonic);
913 }
914 if (hypTrap) {
915 return std::make_shared<HypervisorTrap>(machInst, imm,
916 EC_TRAPPED_CP15_MCR_MRC);
917 }
918 MiscNsBankedDest = Op1;
919 '''
920 mcr15Iop = InstObjParams("mcr", "Mcr15", "MiscRegRegImmOp",
921 { "code": mcr15code,
922 "predicate_test": predicateTest },
923 ["IsSerializeAfter","IsNonSpeculative"])
924 header_output += MiscRegRegImmOpDeclare.subst(mcr15Iop)
925 decoder_output += MiscRegRegImmOpConstructor.subst(mcr15Iop)
926 exec_output += PredOpExecute.subst(mcr15Iop)
927
928
929 mrrc15code = '''
930 int preFlatOp1 = flattenMiscRegNsBanked(op1, xc->tcBase());
931 MiscRegIndex miscReg = (MiscRegIndex)
928 xc->tcBase()->flattenMiscIndex(preFlatOp1);
932 xc->tcBase()->flattenRegId(RegId(MiscRegClass,
933 preFlatOp1)).index();
929 bool hypTrap = mcrrMrrc15TrapToHyp(miscReg, Cpsr, Scr, Hstr, Hcr, imm);
930 bool can_read, undefined;
931 std::tie(can_read, undefined) = canReadCoprocReg(miscReg, Scr, Cpsr);
932 // if we're in non secure PL1 mode then we can trap regargless of whether
933 // the register is accessable, in other modes we trap if only if the register
934 // IS accessable.
935 if (undefined || (!can_read && !(hypTrap && !inUserMode(Cpsr) &&
936 !inSecureState(Scr, Cpsr)))) {
937 return std::make_shared<UndefinedInstruction>(machInst, false,
938 mnemonic);
939 }
940 if (hypTrap) {
941 return std::make_shared<HypervisorTrap>(machInst, imm,
942 EC_TRAPPED_CP15_MCRR_MRRC);
943 }
944 Dest = bits(MiscNsBankedOp164, 63, 32);
945 Dest2 = bits(MiscNsBankedOp164, 31, 0);
946 '''
947 mrrc15Iop = InstObjParams("mrrc", "Mrrc15", "MrrcOp",
948 { "code": mrrc15code,
949 "predicate_test": predicateTest }, [])
950 header_output += MrrcOpDeclare.subst(mrrc15Iop)
951 decoder_output += MrrcOpConstructor.subst(mrrc15Iop)
952 exec_output += PredOpExecute.subst(mrrc15Iop)
953
954
955 mcrr15code = '''
956 int preFlatDest = flattenMiscRegNsBanked(dest, xc->tcBase());
957 MiscRegIndex miscReg = (MiscRegIndex)
934 bool hypTrap = mcrrMrrc15TrapToHyp(miscReg, Cpsr, Scr, Hstr, Hcr, imm);
935 bool can_read, undefined;
936 std::tie(can_read, undefined) = canReadCoprocReg(miscReg, Scr, Cpsr);
937 // if we're in non secure PL1 mode then we can trap regargless of whether
938 // the register is accessable, in other modes we trap if only if the register
939 // IS accessable.
940 if (undefined || (!can_read && !(hypTrap && !inUserMode(Cpsr) &&
941 !inSecureState(Scr, Cpsr)))) {
942 return std::make_shared<UndefinedInstruction>(machInst, false,
943 mnemonic);
944 }
945 if (hypTrap) {
946 return std::make_shared<HypervisorTrap>(machInst, imm,
947 EC_TRAPPED_CP15_MCRR_MRRC);
948 }
949 Dest = bits(MiscNsBankedOp164, 63, 32);
950 Dest2 = bits(MiscNsBankedOp164, 31, 0);
951 '''
952 mrrc15Iop = InstObjParams("mrrc", "Mrrc15", "MrrcOp",
953 { "code": mrrc15code,
954 "predicate_test": predicateTest }, [])
955 header_output += MrrcOpDeclare.subst(mrrc15Iop)
956 decoder_output += MrrcOpConstructor.subst(mrrc15Iop)
957 exec_output += PredOpExecute.subst(mrrc15Iop)
958
959
960 mcrr15code = '''
961 int preFlatDest = flattenMiscRegNsBanked(dest, xc->tcBase());
962 MiscRegIndex miscReg = (MiscRegIndex)
958 xc->tcBase()->flattenMiscIndex(preFlatDest);
963 xc->tcBase()->flattenRegId(RegId(MiscRegClass,
964 preFlatDest)).index();
959 bool hypTrap = mcrrMrrc15TrapToHyp(miscReg, Cpsr, Scr, Hstr, Hcr, imm);
960 bool can_write, undefined;
961 std::tie(can_write, undefined) = canWriteCoprocReg(miscReg, Scr, Cpsr);
962
963 // if we're in non secure PL1 mode then we can trap regargless of whether
964 // the register is accessable, in other modes we trap if only if the register
965 // IS accessable.
966 if (undefined || (!can_write && !(hypTrap && !inUserMode(Cpsr) &&
967 !inSecureState(Scr, Cpsr)))) {
968 return std::make_shared<UndefinedInstruction>(machInst, false,
969 mnemonic);
970 }
971 if (hypTrap) {
972 return std::make_shared<HypervisorTrap>(machInst, imm,
973 EC_TRAPPED_CP15_MCRR_MRRC);
974 }
975 MiscNsBankedDest64 = ((uint64_t) Op1 << 32) | Op2;
976 '''
977 mcrr15Iop = InstObjParams("mcrr", "Mcrr15", "McrrOp",
978 { "code": mcrr15code,
979 "predicate_test": predicateTest }, [])
980 header_output += McrrOpDeclare.subst(mcrr15Iop)
981 decoder_output += McrrOpConstructor.subst(mcrr15Iop)
982 exec_output += PredOpExecute.subst(mcrr15Iop)
983
984
985 enterxCode = '''
986 NextThumb = true;
987 NextJazelle = true;
988 '''
989 enterxIop = InstObjParams("enterx", "Enterx", "PredOp",
990 { "code": enterxCode,
991 "predicate_test": predicateTest }, [])
992 header_output += BasicDeclare.subst(enterxIop)
993 decoder_output += BasicConstructor.subst(enterxIop)
994 exec_output += PredOpExecute.subst(enterxIop)
995
996 leavexCode = '''
997 NextThumb = true;
998 NextJazelle = false;
999 '''
1000 leavexIop = InstObjParams("leavex", "Leavex", "PredOp",
1001 { "code": leavexCode,
1002 "predicate_test": predicateTest }, [])
1003 header_output += BasicDeclare.subst(leavexIop)
1004 decoder_output += BasicConstructor.subst(leavexIop)
1005 exec_output += PredOpExecute.subst(leavexIop)
1006
1007 setendCode = '''
1008 CPSR cpsr = Cpsr;
1009 cpsr.e = imm;
1010 Cpsr = cpsr;
1011 '''
1012 setendIop = InstObjParams("setend", "Setend", "ImmOp",
1013 { "code": setendCode,
1014 "predicate_test": predicateTest },
1015 ["IsSerializeAfter","IsNonSpeculative"])
1016 header_output += ImmOpDeclare.subst(setendIop)
1017 decoder_output += ImmOpConstructor.subst(setendIop)
1018 exec_output += PredOpExecute.subst(setendIop)
1019
1020 clrexCode = '''
1021 LLSCLock = 0;
1022 '''
1023 clrexIop = InstObjParams("clrex", "Clrex","PredOp",
1024 { "code": clrexCode,
1025 "predicate_test": predicateTest },[])
1026 header_output += BasicDeclare.subst(clrexIop)
1027 decoder_output += BasicConstructor.subst(clrexIop)
1028 exec_output += PredOpExecute.subst(clrexIop)
1029
1030 isbCode = '''
1031 // If the barrier is due to a CP15 access check for hyp traps
1032 if ((imm != 0) && mcrMrc15TrapToHyp(MISCREG_CP15ISB, Hcr, Cpsr, Scr,
1033 Hdcr, Hstr, Hcptr, imm)) {
1034 return std::make_shared<HypervisorTrap>(machInst, imm,
1035 EC_TRAPPED_CP15_MCR_MRC);
1036 }
1037 fault = std::make_shared<FlushPipe>();
1038 '''
1039 isbIop = InstObjParams("isb", "Isb", "ImmOp",
1040 {"code": isbCode,
1041 "predicate_test": predicateTest},
1042 ['IsSerializeAfter'])
1043 header_output += ImmOpDeclare.subst(isbIop)
1044 decoder_output += ImmOpConstructor.subst(isbIop)
1045 exec_output += PredOpExecute.subst(isbIop)
1046
1047 dsbCode = '''
1048 // If the barrier is due to a CP15 access check for hyp traps
1049 if ((imm != 0) && mcrMrc15TrapToHyp(MISCREG_CP15DSB, Hcr, Cpsr, Scr,
1050 Hdcr, Hstr, Hcptr, imm)) {
1051 return std::make_shared<HypervisorTrap>(machInst, imm,
1052 EC_TRAPPED_CP15_MCR_MRC);
1053 }
1054 fault = std::make_shared<FlushPipe>();
1055 '''
1056 dsbIop = InstObjParams("dsb", "Dsb", "ImmOp",
1057 {"code": dsbCode,
1058 "predicate_test": predicateTest},
1059 ['IsMemBarrier', 'IsSerializeAfter'])
1060 header_output += ImmOpDeclare.subst(dsbIop)
1061 decoder_output += ImmOpConstructor.subst(dsbIop)
1062 exec_output += PredOpExecute.subst(dsbIop)
1063
1064 dmbCode = '''
1065 // If the barrier is due to a CP15 access check for hyp traps
1066 if ((imm != 0) && mcrMrc15TrapToHyp(MISCREG_CP15DMB, Hcr, Cpsr, Scr,
1067 Hdcr, Hstr, Hcptr, imm)) {
1068 return std::make_shared<HypervisorTrap>(machInst, imm,
1069 EC_TRAPPED_CP15_MCR_MRC);
1070 }
1071 '''
1072 dmbIop = InstObjParams("dmb", "Dmb", "ImmOp",
1073 {"code": dmbCode,
1074 "predicate_test": predicateTest},
1075 ['IsMemBarrier'])
1076 header_output += ImmOpDeclare.subst(dmbIop)
1077 decoder_output += ImmOpConstructor.subst(dmbIop)
1078 exec_output += PredOpExecute.subst(dmbIop)
1079
1080 dbgCode = '''
1081 '''
1082 dbgIop = InstObjParams("dbg", "Dbg", "PredOp",
1083 {"code": dbgCode,
1084 "predicate_test": predicateTest})
1085 header_output += BasicDeclare.subst(dbgIop)
1086 decoder_output += BasicConstructor.subst(dbgIop)
1087 exec_output += PredOpExecute.subst(dbgIop)
1088
1089 cpsCode = '''
1090 uint32_t mode = bits(imm, 4, 0);
1091 uint32_t f = bits(imm, 5);
1092 uint32_t i = bits(imm, 6);
1093 uint32_t a = bits(imm, 7);
1094 bool setMode = bits(imm, 8);
1095 bool enable = bits(imm, 9);
1096 CPSR cpsr = Cpsr;
1097 SCTLR sctlr = Sctlr;
1098 if (cpsr.mode != MODE_USER) {
1099 if (enable) {
1100 if (f) cpsr.f = 0;
1101 if (i) cpsr.i = 0;
1102 if (a) cpsr.a = 0;
1103 } else {
1104 if (f && !sctlr.nmfi) cpsr.f = 1;
1105 if (i) cpsr.i = 1;
1106 if (a) cpsr.a = 1;
1107 }
1108 if (setMode) {
1109 cpsr.mode = mode;
1110 }
1111 }
1112 Cpsr = cpsr;
1113 '''
1114 cpsIop = InstObjParams("cps", "Cps", "ImmOp",
1115 { "code": cpsCode,
1116 "predicate_test": predicateTest },
1117 ["IsSerializeAfter","IsNonSpeculative"])
1118 header_output += ImmOpDeclare.subst(cpsIop)
1119 decoder_output += ImmOpConstructor.subst(cpsIop)
1120 exec_output += PredOpExecute.subst(cpsIop)
1121}};
965 bool hypTrap = mcrrMrrc15TrapToHyp(miscReg, Cpsr, Scr, Hstr, Hcr, imm);
966 bool can_write, undefined;
967 std::tie(can_write, undefined) = canWriteCoprocReg(miscReg, Scr, Cpsr);
968
969 // if we're in non secure PL1 mode then we can trap regargless of whether
970 // the register is accessable, in other modes we trap if only if the register
971 // IS accessable.
972 if (undefined || (!can_write && !(hypTrap && !inUserMode(Cpsr) &&
973 !inSecureState(Scr, Cpsr)))) {
974 return std::make_shared<UndefinedInstruction>(machInst, false,
975 mnemonic);
976 }
977 if (hypTrap) {
978 return std::make_shared<HypervisorTrap>(machInst, imm,
979 EC_TRAPPED_CP15_MCRR_MRRC);
980 }
981 MiscNsBankedDest64 = ((uint64_t) Op1 << 32) | Op2;
982 '''
983 mcrr15Iop = InstObjParams("mcrr", "Mcrr15", "McrrOp",
984 { "code": mcrr15code,
985 "predicate_test": predicateTest }, [])
986 header_output += McrrOpDeclare.subst(mcrr15Iop)
987 decoder_output += McrrOpConstructor.subst(mcrr15Iop)
988 exec_output += PredOpExecute.subst(mcrr15Iop)
989
990
991 enterxCode = '''
992 NextThumb = true;
993 NextJazelle = true;
994 '''
995 enterxIop = InstObjParams("enterx", "Enterx", "PredOp",
996 { "code": enterxCode,
997 "predicate_test": predicateTest }, [])
998 header_output += BasicDeclare.subst(enterxIop)
999 decoder_output += BasicConstructor.subst(enterxIop)
1000 exec_output += PredOpExecute.subst(enterxIop)
1001
1002 leavexCode = '''
1003 NextThumb = true;
1004 NextJazelle = false;
1005 '''
1006 leavexIop = InstObjParams("leavex", "Leavex", "PredOp",
1007 { "code": leavexCode,
1008 "predicate_test": predicateTest }, [])
1009 header_output += BasicDeclare.subst(leavexIop)
1010 decoder_output += BasicConstructor.subst(leavexIop)
1011 exec_output += PredOpExecute.subst(leavexIop)
1012
1013 setendCode = '''
1014 CPSR cpsr = Cpsr;
1015 cpsr.e = imm;
1016 Cpsr = cpsr;
1017 '''
1018 setendIop = InstObjParams("setend", "Setend", "ImmOp",
1019 { "code": setendCode,
1020 "predicate_test": predicateTest },
1021 ["IsSerializeAfter","IsNonSpeculative"])
1022 header_output += ImmOpDeclare.subst(setendIop)
1023 decoder_output += ImmOpConstructor.subst(setendIop)
1024 exec_output += PredOpExecute.subst(setendIop)
1025
1026 clrexCode = '''
1027 LLSCLock = 0;
1028 '''
1029 clrexIop = InstObjParams("clrex", "Clrex","PredOp",
1030 { "code": clrexCode,
1031 "predicate_test": predicateTest },[])
1032 header_output += BasicDeclare.subst(clrexIop)
1033 decoder_output += BasicConstructor.subst(clrexIop)
1034 exec_output += PredOpExecute.subst(clrexIop)
1035
1036 isbCode = '''
1037 // If the barrier is due to a CP15 access check for hyp traps
1038 if ((imm != 0) && mcrMrc15TrapToHyp(MISCREG_CP15ISB, Hcr, Cpsr, Scr,
1039 Hdcr, Hstr, Hcptr, imm)) {
1040 return std::make_shared<HypervisorTrap>(machInst, imm,
1041 EC_TRAPPED_CP15_MCR_MRC);
1042 }
1043 fault = std::make_shared<FlushPipe>();
1044 '''
1045 isbIop = InstObjParams("isb", "Isb", "ImmOp",
1046 {"code": isbCode,
1047 "predicate_test": predicateTest},
1048 ['IsSerializeAfter'])
1049 header_output += ImmOpDeclare.subst(isbIop)
1050 decoder_output += ImmOpConstructor.subst(isbIop)
1051 exec_output += PredOpExecute.subst(isbIop)
1052
1053 dsbCode = '''
1054 // If the barrier is due to a CP15 access check for hyp traps
1055 if ((imm != 0) && mcrMrc15TrapToHyp(MISCREG_CP15DSB, Hcr, Cpsr, Scr,
1056 Hdcr, Hstr, Hcptr, imm)) {
1057 return std::make_shared<HypervisorTrap>(machInst, imm,
1058 EC_TRAPPED_CP15_MCR_MRC);
1059 }
1060 fault = std::make_shared<FlushPipe>();
1061 '''
1062 dsbIop = InstObjParams("dsb", "Dsb", "ImmOp",
1063 {"code": dsbCode,
1064 "predicate_test": predicateTest},
1065 ['IsMemBarrier', 'IsSerializeAfter'])
1066 header_output += ImmOpDeclare.subst(dsbIop)
1067 decoder_output += ImmOpConstructor.subst(dsbIop)
1068 exec_output += PredOpExecute.subst(dsbIop)
1069
1070 dmbCode = '''
1071 // If the barrier is due to a CP15 access check for hyp traps
1072 if ((imm != 0) && mcrMrc15TrapToHyp(MISCREG_CP15DMB, Hcr, Cpsr, Scr,
1073 Hdcr, Hstr, Hcptr, imm)) {
1074 return std::make_shared<HypervisorTrap>(machInst, imm,
1075 EC_TRAPPED_CP15_MCR_MRC);
1076 }
1077 '''
1078 dmbIop = InstObjParams("dmb", "Dmb", "ImmOp",
1079 {"code": dmbCode,
1080 "predicate_test": predicateTest},
1081 ['IsMemBarrier'])
1082 header_output += ImmOpDeclare.subst(dmbIop)
1083 decoder_output += ImmOpConstructor.subst(dmbIop)
1084 exec_output += PredOpExecute.subst(dmbIop)
1085
1086 dbgCode = '''
1087 '''
1088 dbgIop = InstObjParams("dbg", "Dbg", "PredOp",
1089 {"code": dbgCode,
1090 "predicate_test": predicateTest})
1091 header_output += BasicDeclare.subst(dbgIop)
1092 decoder_output += BasicConstructor.subst(dbgIop)
1093 exec_output += PredOpExecute.subst(dbgIop)
1094
1095 cpsCode = '''
1096 uint32_t mode = bits(imm, 4, 0);
1097 uint32_t f = bits(imm, 5);
1098 uint32_t i = bits(imm, 6);
1099 uint32_t a = bits(imm, 7);
1100 bool setMode = bits(imm, 8);
1101 bool enable = bits(imm, 9);
1102 CPSR cpsr = Cpsr;
1103 SCTLR sctlr = Sctlr;
1104 if (cpsr.mode != MODE_USER) {
1105 if (enable) {
1106 if (f) cpsr.f = 0;
1107 if (i) cpsr.i = 0;
1108 if (a) cpsr.a = 0;
1109 } else {
1110 if (f && !sctlr.nmfi) cpsr.f = 1;
1111 if (i) cpsr.i = 1;
1112 if (a) cpsr.a = 1;
1113 }
1114 if (setMode) {
1115 cpsr.mode = mode;
1116 }
1117 }
1118 Cpsr = cpsr;
1119 '''
1120 cpsIop = InstObjParams("cps", "Cps", "ImmOp",
1121 { "code": cpsCode,
1122 "predicate_test": predicateTest },
1123 ["IsSerializeAfter","IsNonSpeculative"])
1124 header_output += ImmOpDeclare.subst(cpsIop)
1125 decoder_output += ImmOpConstructor.subst(cpsIop)
1126 exec_output += PredOpExecute.subst(cpsIop)
1127}};