3 // Copyright (c) 2010-2013,2017-2020 ARM Limited
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.
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.
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.
41 ThreadContext *tc = xc->tcBase();
43 bool have_semi = ArmSystem::haveSemihosting(tc);
44 if (have_semi && Thumb && imm == ArmSemihosting::T32Imm) {
45 // Enable gem5 extensions since we can't distinguish in thumb.
46 ArmSystem::callSemihosting32(tc, true);
47 } else if (have_semi && imm == ArmSemihosting::A32Imm) {
48 ArmSystem::callSemihosting32(tc);
49 } else if (have_semi && imm == ArmSemihosting::Gem5Imm) {
50 ArmSystem::callSemihosting32(tc, true);
52 fault = std::make_shared<SupervisorCall>(machInst, imm);
56 svcIop = InstObjParams("svc", "Svc", "ImmOp",
58 "predicate_test": predicateTest,
59 "thumb_semihost": '0xAB',
60 "arm_semihost": '0x123456' },
61 ["IsSyscall", "IsNonSpeculative",
63 header_output = ImmOpDeclare.subst(svcIop)
64 decoder_output = SemihostConstructor.subst(svcIop)
65 exec_output = PredOpExecute.subst(svcIop)
68 ThreadContext *tc = xc->tcBase();
70 const auto semihost_imm = Thumb? 0x3C : 0xF000;
72 if (ArmSystem::haveSemihosting(tc) && imm == semihost_imm) {
73 ArmSystem::callSemihosting32(tc);
75 // HLT instructions aren't implemented, so treat them as undefined
77 fault = std::make_shared<UndefinedInstruction>(
78 machInst, false, mnemonic);
82 hltIop = InstObjParams("hlt", "Hlt", "ImmOp",
84 "predicate_test": predicateTest,
85 "thumb_semihost": '0x3C',
86 "arm_semihost": '0xF000' },
87 ["IsNonSpeculative", "IsSerializeAfter"])
88 header_output += ImmOpDeclare.subst(hltIop)
89 decoder_output += SemihostConstructor.subst(hltIop)
90 exec_output += PredOpExecute.subst(hltIop)
97 if ((cpsr.mode != MODE_USER) && FullSystem) {
98 if (ArmSystem::haveVirtualization(xc->tcBase()) &&
99 !inSecureState(scr, cpsr) && (cpsr.mode != MODE_HYP) && hcr.tsc) {
100 fault = std::make_shared<HypervisorTrap>(machInst, 0,
104 fault = disabledFault();
106 fault = std::make_shared<SecureMonitorCall>(machInst);
110 fault = disabledFault();
114 smcIop = InstObjParams("smc", "Smc", "PredOp",
116 "predicate_test": predicateTest },
117 ["IsNonSpeculative", "IsSerializeAfter"])
118 header_output += BasicDeclare.subst(smcIop)
119 decoder_output += BasicConstructor.subst(smcIop)
120 exec_output += PredOpExecute.subst(smcIop)
126 // Filter out the various cases where this instruction isn't defined
127 if (!FullSystem || !ArmSystem::haveVirtualization(xc->tcBase()) ||
128 (cpsr.mode == MODE_USER) ||
129 (ArmSystem::haveSecurity(xc->tcBase()) && (!scr.ns || !scr.hce))) {
130 fault = disabledFault();
132 fault = std::make_shared<HypervisorCall>(machInst, imm);
136 hvcIop = InstObjParams("hvc", "Hvc", "ImmOp",
138 "predicate_test": predicateTest },
139 ["IsNonSpeculative", "IsSerializeAfter"])
140 header_output += ImmOpDeclare.subst(hvcIop)
141 decoder_output += ImmOpConstructor.subst(hvcIop)
142 exec_output += PredOpExecute.subst(hvcIop)
146 CPSR old_cpsr = Cpsr;
147 old_cpsr.nz = CondCodesNZ;
148 old_cpsr.c = CondCodesC;
149 old_cpsr.v = CondCodesV;
150 old_cpsr.ge = CondCodesGE;
152 CPSR new_cpsr = cpsrWriteByInstr(old_cpsr, Spsr, Scr, Nsacr, 0xF,
153 true, sctlr.nmfi, xc->tcBase());
154 Cpsr = ~CondCodesMask & new_cpsr;
155 CondCodesNZ = new_cpsr.nz;
156 CondCodesC = new_cpsr.c;
157 CondCodesV = new_cpsr.v;
158 CondCodesGE = new_cpsr.ge;
160 NextThumb = (new_cpsr).t;
161 NextJazelle = (new_cpsr).j;
162 NextItState = (((new_cpsr).it2 << 2) & 0xFC)
163 | ((new_cpsr).it1 & 0x3);
165 NPC = (old_cpsr.mode == MODE_HYP) ? ElrHyp : LR;
168 eretIop = InstObjParams("eret", "Eret", "PredOp",
170 "predicate_test": predicateTest },
171 ["IsNonSpeculative", "IsSerializeAfter",
173 header_output += BasicDeclare.subst(eretIop)
174 decoder_output += BasicConstructor.subst(eretIop)
175 exec_output += PredOpExecute.subst(eretIop)
178 constexpr uint8_t size_bytes = %(sz)d;
179 constexpr uint32_t poly = %(polynom)s;
181 uint32_t data = htole(Op2);
182 auto data_buffer = reinterpret_cast<uint8_t*>(&data);
185 data_buffer, /* Message Register */
186 Op1, /* Initial Value of the CRC */
187 size_bytes /* Size of the original Message */
191 def crc32Emit(mnem, implCode, castagnoli, size):
192 global header_output, decoder_output, exec_output
195 # crc32c instructions
201 data = {'sz' : size, 'polynom': poly}
203 instCode = implCode % data
205 crcIop = InstObjParams(mnem, mnem.capitalize(), "RegRegRegOp",
207 "predicate_test": predicateTest }, [])
208 header_output += RegRegRegOpDeclare.subst(crcIop)
209 decoder_output += RegRegRegOpConstructor.subst(crcIop)
210 exec_output += PredOpExecute.subst(crcIop)
212 crc32Emit("crc32b", crcCode, False, 1);
213 crc32Emit("crc32h", crcCode, False, 2);
214 crc32Emit("crc32w", crcCode, False, 4);
215 crc32Emit("crc32cb", crcCode, True, 1);
216 crc32Emit("crc32ch", crcCode, True, 2);
217 crc32Emit("crc32cw", crcCode, True, 4);
223 header_output = decoder_output = exec_output = ""
227 cpsr.nz = CondCodesNZ;
230 cpsr.ge = CondCodesGE;
231 Dest = cpsr & (cpsr.mode == MODE_USER ? ApsrMask : CpsrMask);
234 mrsCpsrIop = InstObjParams("mrs", "MrsCpsr", "MrsOp",
235 { "code": mrsCpsrCode,
236 "predicate_test": condPredicateTest },
237 ["IsSerializeBefore"])
238 header_output += MrsDeclare.subst(mrsCpsrIop)
239 decoder_output += MrsConstructor.subst(mrsCpsrIop)
240 exec_output += PredOpExecute.subst(mrsCpsrIop)
242 mrsSpsrCode = "Dest = Spsr"
243 mrsSpsrIop = InstObjParams("mrs", "MrsSpsr", "MrsOp",
244 { "code": mrsSpsrCode,
245 "predicate_test": predicateTest },
246 ["IsSerializeBefore"])
247 header_output += MrsDeclare.subst(mrsSpsrIop)
248 decoder_output += MrsConstructor.subst(mrsSpsrIop)
249 exec_output += PredOpExecute.subst(mrsSpsrIop)
251 mrsBankedRegCode = '''
255 if (decodeMrsMsrBankedReg(byteMask, r, isIntReg, regIdx, Cpsr, Scr, Nsacr)) {
257 Dest = DecodedBankedIntReg;
259 Dest = xc->readMiscReg(regIdx);
262 return std::make_shared<UndefinedInstruction>(machInst, false,
266 mrsBankedRegIop = InstObjParams("mrs", "MrsBankedReg", "MrsOp",
267 { "code": mrsBankedRegCode,
268 "predicate_test": predicateTest },
269 ["IsSerializeBefore"])
270 header_output += MrsBankedRegDeclare.subst(mrsBankedRegIop)
271 decoder_output += MrsBankedRegConstructor.subst(mrsBankedRegIop)
272 exec_output += PredOpExecute.subst(mrsBankedRegIop)
274 msrBankedRegCode = '''
278 if (decodeMrsMsrBankedReg(byteMask, r, isIntReg, regIdx, Cpsr, Scr, Nsacr)) {
280 // This is a bit nasty, you would have thought that
281 // DecodedBankedIntReg wouldn't be written to unless the
282 // conditions on the IF statements above are met, however if
283 // you look at the generated C code you'll find that they are.
284 // However this is safe as DecodedBankedIntReg (which is used
285 // in operands.isa to get the index of DecodedBankedIntReg)
286 // will return INTREG_DUMMY if its not a valid integer
287 // register, so redirecting the write to somewhere we don't
289 DecodedBankedIntReg = Op1;
291 xc->setMiscReg(regIdx, Op1);
294 return std::make_shared<UndefinedInstruction>(machInst, false,
298 msrBankedRegIop = InstObjParams("msr", "MsrBankedReg", "MsrRegOp",
299 { "code": msrBankedRegCode,
300 "predicate_test": predicateTest },
301 ["IsSerializeAfter", "IsNonSpeculative"])
302 header_output += MsrBankedRegDeclare.subst(msrBankedRegIop)
303 decoder_output += MsrBankedRegConstructor.subst(msrBankedRegIop)
304 exec_output += PredOpExecute.subst(msrBankedRegIop)
308 CPSR old_cpsr = Cpsr;
309 old_cpsr.nz = CondCodesNZ;
310 old_cpsr.c = CondCodesC;
311 old_cpsr.v = CondCodesV;
312 old_cpsr.ge = CondCodesGE;
315 cpsrWriteByInstr(old_cpsr, Op1, Scr, Nsacr, byteMask, false,
316 sctlr.nmfi, xc->tcBase());
317 Cpsr = ~CondCodesMask & new_cpsr;
318 CondCodesNZ = new_cpsr.nz;
319 CondCodesC = new_cpsr.c;
320 CondCodesV = new_cpsr.v;
321 CondCodesGE = new_cpsr.ge;
323 msrCpsrRegIop = InstObjParams("msr", "MsrCpsrReg", "MsrRegOp",
324 { "code": msrCpsrRegCode,
325 "predicate_test": condPredicateTest },
326 ["IsSerializeAfter","IsNonSpeculative"])
327 header_output += MsrRegDeclare.subst(msrCpsrRegIop)
328 decoder_output += MsrRegConstructor.subst(msrCpsrRegIop)
329 exec_output += PredOpExecute.subst(msrCpsrRegIop)
331 msrSpsrRegCode = "Spsr = spsrWriteByInstr(Spsr, Op1, byteMask, false);"
332 msrSpsrRegIop = InstObjParams("msr", "MsrSpsrReg", "MsrRegOp",
333 { "code": msrSpsrRegCode,
334 "predicate_test": predicateTest },
335 ["IsSerializeAfter","IsNonSpeculative"])
336 header_output += MsrRegDeclare.subst(msrSpsrRegIop)
337 decoder_output += MsrRegConstructor.subst(msrSpsrRegIop)
338 exec_output += PredOpExecute.subst(msrSpsrRegIop)
342 CPSR old_cpsr = Cpsr;
343 old_cpsr.nz = CondCodesNZ;
344 old_cpsr.c = CondCodesC;
345 old_cpsr.v = CondCodesV;
346 old_cpsr.ge = CondCodesGE;
348 cpsrWriteByInstr(old_cpsr, imm, Scr, Nsacr, byteMask, false,
349 sctlr.nmfi, xc->tcBase());
350 Cpsr = ~CondCodesMask & new_cpsr;
351 CondCodesNZ = new_cpsr.nz;
352 CondCodesC = new_cpsr.c;
353 CondCodesV = new_cpsr.v;
354 CondCodesGE = new_cpsr.ge;
356 msrCpsrImmIop = InstObjParams("msr", "MsrCpsrImm", "MsrImmOp",
357 { "code": msrCpsrImmCode,
358 "predicate_test": condPredicateTest },
359 ["IsSerializeAfter","IsNonSpeculative"])
360 header_output += MsrImmDeclare.subst(msrCpsrImmIop)
361 decoder_output += MsrImmConstructor.subst(msrCpsrImmIop)
362 exec_output += PredOpExecute.subst(msrCpsrImmIop)
364 msrSpsrImmCode = "Spsr = spsrWriteByInstr(Spsr, imm, byteMask, false);"
365 msrSpsrImmIop = InstObjParams("msr", "MsrSpsrImm", "MsrImmOp",
366 { "code": msrSpsrImmCode,
367 "predicate_test": predicateTest },
368 ["IsSerializeAfter","IsNonSpeculative"])
369 header_output += MsrImmDeclare.subst(msrSpsrImmIop)
370 decoder_output += MsrImmConstructor.subst(msrSpsrImmIop)
371 exec_output += PredOpExecute.subst(msrSpsrImmIop)
375 Dest = swap_byte(val);
377 revIop = InstObjParams("rev", "Rev", "RegRegOp",
379 "predicate_test": predicateTest }, [])
380 header_output += RegRegOpDeclare.subst(revIop)
381 decoder_output += RegRegOpConstructor.subst(revIop)
382 exec_output += PredOpExecute.subst(revIop)
386 Dest = (bits(val, 15, 8) << 0) |
387 (bits(val, 7, 0) << 8) |
388 (bits(val, 31, 24) << 16) |
389 (bits(val, 23, 16) << 24);
391 rev16Iop = InstObjParams("rev16", "Rev16", "RegRegOp",
393 "predicate_test": predicateTest }, [])
394 header_output += RegRegOpDeclare.subst(rev16Iop)
395 decoder_output += RegRegOpConstructor.subst(rev16Iop)
396 exec_output += PredOpExecute.subst(rev16Iop)
400 Dest = sext<16>(swap_byte(val));
402 revshIop = InstObjParams("revsh", "Revsh", "RegRegOp",
404 "predicate_test": predicateTest }, [])
405 header_output += RegRegOpDeclare.subst(revshIop)
406 decoder_output += RegRegOpConstructor.subst(revshIop)
407 exec_output += PredOpExecute.subst(revshIop)
410 Dest = reverseBits(Op1);
412 rbitIop = InstObjParams("rbit", "Rbit", "RegRegOp",
414 "predicate_test": predicateTest }, [])
415 header_output += RegRegOpDeclare.subst(rbitIop)
416 decoder_output += RegRegOpConstructor.subst(rbitIop)
417 exec_output += PredOpExecute.subst(rbitIop)
420 Dest = (Op1 == 0) ? 32 : (31 - findMsbSet(Op1));
422 clzIop = InstObjParams("clz", "Clz", "RegRegOp",
424 "predicate_test": predicateTest }, [])
425 header_output += RegRegOpDeclare.subst(clzIop)
426 decoder_output += RegRegOpConstructor.subst(clzIop)
427 exec_output += PredOpExecute.subst(clzIop)
430 int32_t operand = shift_rm_imm(Op1, shiftAmt, shiftType, 0);
432 if (satInt(res, operand, imm))
436 ssatIop = InstObjParams("ssat", "Ssat", "RegImmRegShiftOp",
438 "predicate_test": pickPredicate(ssatCode) }, [])
439 header_output += RegImmRegShiftOpDeclare.subst(ssatIop)
440 decoder_output += RegImmRegShiftOpConstructor.subst(ssatIop)
441 exec_output += PredOpExecute.subst(ssatIop)
444 int32_t operand = shift_rm_imm(Op1, shiftAmt, shiftType, 0);
446 if (uSatInt(res, operand, imm))
450 usatIop = InstObjParams("usat", "Usat", "RegImmRegShiftOp",
452 "predicate_test": pickPredicate(usatCode) }, [])
453 header_output += RegImmRegShiftOpDeclare.subst(usatIop)
454 decoder_output += RegImmRegShiftOpConstructor.subst(usatIop)
455 exec_output += PredOpExecute.subst(usatIop)
459 uint32_t resTemp = 0;
460 int32_t argLow = sext<16>(bits(Op1, 15, 0));
461 int32_t argHigh = sext<16>(bits(Op1, 31, 16));
462 if (satInt(res, argLow, imm))
464 replaceBits(resTemp, 15, 0, res);
465 if (satInt(res, argHigh, imm))
467 replaceBits(resTemp, 31, 16, res);
470 ssat16Iop = InstObjParams("ssat16", "Ssat16", "RegImmRegOp",
471 { "code": ssat16Code,
472 "predicate_test": pickPredicate(ssat16Code) }, [])
473 header_output += RegImmRegOpDeclare.subst(ssat16Iop)
474 decoder_output += RegImmRegOpConstructor.subst(ssat16Iop)
475 exec_output += PredOpExecute.subst(ssat16Iop)
479 uint32_t resTemp = 0;
480 int32_t argLow = sext<16>(bits(Op1, 15, 0));
481 int32_t argHigh = sext<16>(bits(Op1, 31, 16));
482 if (uSatInt(res, argLow, imm))
484 replaceBits(resTemp, 15, 0, res);
485 if (uSatInt(res, argHigh, imm))
487 replaceBits(resTemp, 31, 16, res);
490 usat16Iop = InstObjParams("usat16", "Usat16", "RegImmRegOp",
491 { "code": usat16Code,
492 "predicate_test": pickPredicate(usat16Code) }, [])
493 header_output += RegImmRegOpDeclare.subst(usat16Iop)
494 decoder_output += RegImmRegOpConstructor.subst(usat16Iop)
495 exec_output += PredOpExecute.subst(usat16Iop)
497 sxtbIop = InstObjParams("sxtb", "Sxtb", "RegImmRegOp",
499 "Dest = sext<8>((uint8_t)(Op1_ud >> imm));",
500 "predicate_test": predicateTest }, [])
501 header_output += RegImmRegOpDeclare.subst(sxtbIop)
502 decoder_output += RegImmRegOpConstructor.subst(sxtbIop)
503 exec_output += PredOpExecute.subst(sxtbIop)
505 sxtabIop = InstObjParams("sxtab", "Sxtab", "RegRegRegImmOp",
508 Dest = sext<8>((uint8_t)(Op2_ud >> imm)) +
511 "predicate_test": predicateTest }, [])
512 header_output += RegRegRegImmOpDeclare.subst(sxtabIop)
513 decoder_output += RegRegRegImmOpConstructor.subst(sxtabIop)
514 exec_output += PredOpExecute.subst(sxtabIop)
517 uint32_t resTemp = 0;
518 replaceBits(resTemp, 15, 0, sext<8>(bits(Op1, imm + 7, imm)));
519 replaceBits(resTemp, 31, 16,
520 sext<8>(bits(Op1, (imm + 23) % 32, (imm + 16) % 32)));
523 sxtb16Iop = InstObjParams("sxtb16", "Sxtb16", "RegImmRegOp",
524 { "code": sxtb16Code,
525 "predicate_test": predicateTest }, [])
526 header_output += RegImmRegOpDeclare.subst(sxtb16Iop)
527 decoder_output += RegImmRegOpConstructor.subst(sxtb16Iop)
528 exec_output += PredOpExecute.subst(sxtb16Iop)
531 uint32_t resTemp = 0;
532 replaceBits(resTemp, 15, 0, sext<8>(bits(Op2, imm + 7, imm)) +
534 replaceBits(resTemp, 31, 16,
535 sext<8>(bits(Op2, (imm + 23) % 32, (imm + 16) % 32)) +
539 sxtab16Iop = InstObjParams("sxtab16", "Sxtab16", "RegRegRegImmOp",
540 { "code": sxtab16Code,
541 "predicate_test": predicateTest }, [])
542 header_output += RegRegRegImmOpDeclare.subst(sxtab16Iop)
543 decoder_output += RegRegRegImmOpConstructor.subst(sxtab16Iop)
544 exec_output += PredOpExecute.subst(sxtab16Iop)
547 uint64_t rotated = (uint32_t)Op1;
548 rotated = (rotated | (rotated << 32)) >> imm;
549 Dest = sext<16>((uint16_t)rotated);
551 sxthIop = InstObjParams("sxth", "Sxth", "RegImmRegOp",
553 "predicate_test": predicateTest }, [])
554 header_output += RegImmRegOpDeclare.subst(sxthIop)
555 decoder_output += RegImmRegOpConstructor.subst(sxthIop)
556 exec_output += PredOpExecute.subst(sxthIop)
559 uint64_t rotated = (uint32_t)Op2;
560 rotated = (rotated | (rotated << 32)) >> imm;
561 Dest = sext<16>((uint16_t)rotated) + Op1;
563 sxtahIop = InstObjParams("sxtah", "Sxtah", "RegRegRegImmOp",
565 "predicate_test": predicateTest }, [])
566 header_output += RegRegRegImmOpDeclare.subst(sxtahIop)
567 decoder_output += RegRegRegImmOpConstructor.subst(sxtahIop)
568 exec_output += PredOpExecute.subst(sxtahIop)
570 uxtbIop = InstObjParams("uxtb", "Uxtb", "RegImmRegOp",
571 { "code": "Dest = (uint8_t)(Op1_ud >> imm);",
572 "predicate_test": predicateTest }, [])
573 header_output += RegImmRegOpDeclare.subst(uxtbIop)
574 decoder_output += RegImmRegOpConstructor.subst(uxtbIop)
575 exec_output += PredOpExecute.subst(uxtbIop)
577 uxtabIop = InstObjParams("uxtab", "Uxtab", "RegRegRegImmOp",
579 "Dest = (uint8_t)(Op2_ud >> imm) + Op1;",
580 "predicate_test": predicateTest }, [])
581 header_output += RegRegRegImmOpDeclare.subst(uxtabIop)
582 decoder_output += RegRegRegImmOpConstructor.subst(uxtabIop)
583 exec_output += PredOpExecute.subst(uxtabIop)
586 uint32_t resTemp = 0;
587 replaceBits(resTemp, 15, 0, (uint8_t)(bits(Op1, imm + 7, imm)));
588 replaceBits(resTemp, 31, 16,
589 (uint8_t)(bits(Op1, (imm + 23) % 32, (imm + 16) % 32)));
592 uxtb16Iop = InstObjParams("uxtb16", "Uxtb16", "RegImmRegOp",
593 { "code": uxtb16Code,
594 "predicate_test": predicateTest }, [])
595 header_output += RegImmRegOpDeclare.subst(uxtb16Iop)
596 decoder_output += RegImmRegOpConstructor.subst(uxtb16Iop)
597 exec_output += PredOpExecute.subst(uxtb16Iop)
600 uint32_t resTemp = 0;
601 replaceBits(resTemp, 15, 0, (uint8_t)(bits(Op2, imm + 7, imm)) +
603 replaceBits(resTemp, 31, 16,
604 (uint8_t)(bits(Op2, (imm + 23) % 32, (imm + 16) % 32)) +
608 uxtab16Iop = InstObjParams("uxtab16", "Uxtab16", "RegRegRegImmOp",
609 { "code": uxtab16Code,
610 "predicate_test": predicateTest }, [])
611 header_output += RegRegRegImmOpDeclare.subst(uxtab16Iop)
612 decoder_output += RegRegRegImmOpConstructor.subst(uxtab16Iop)
613 exec_output += PredOpExecute.subst(uxtab16Iop)
616 uint64_t rotated = (uint32_t)Op1;
617 rotated = (rotated | (rotated << 32)) >> imm;
618 Dest = (uint16_t)rotated;
620 uxthIop = InstObjParams("uxth", "Uxth", "RegImmRegOp",
622 "predicate_test": predicateTest }, [])
623 header_output += RegImmRegOpDeclare.subst(uxthIop)
624 decoder_output += RegImmRegOpConstructor.subst(uxthIop)
625 exec_output += PredOpExecute.subst(uxthIop)
628 uint64_t rotated = (uint32_t)Op2;
629 rotated = (rotated | (rotated << 32)) >> imm;
630 Dest = (uint16_t)rotated + Op1;
632 uxtahIop = InstObjParams("uxtah", "Uxtah", "RegRegRegImmOp",
634 "predicate_test": predicateTest }, [])
635 header_output += RegRegRegImmOpDeclare.subst(uxtahIop)
636 decoder_output += RegRegRegImmOpConstructor.subst(uxtahIop)
637 exec_output += PredOpExecute.subst(uxtahIop)
640 uint32_t resTemp = 0;
641 for (unsigned i = 0; i < 4; i++) {
644 replaceBits(resTemp, high, low,
645 bits(CondCodesGE, i) ?
646 bits(Op1, high, low) : bits(Op2, high, low));
650 selIop = InstObjParams("sel", "Sel", "RegRegRegOp",
652 "predicate_test": predicateTest }, [])
653 header_output += RegRegRegOpDeclare.subst(selIop)
654 decoder_output += RegRegRegOpConstructor.subst(selIop)
655 exec_output += PredOpExecute.subst(selIop)
658 uint32_t resTemp = 0;
659 for (unsigned i = 0; i < 4; i++) {
662 int32_t diff = bits(Op1, high, low) -
663 bits(Op2, high, low);
664 resTemp += ((diff < 0) ? -diff : diff);
668 usad8Iop = InstObjParams("usad8", "Usad8", "RegRegRegOp",
670 "predicate_test": predicateTest }, [])
671 header_output += RegRegRegOpDeclare.subst(usad8Iop)
672 decoder_output += RegRegRegOpConstructor.subst(usad8Iop)
673 exec_output += PredOpExecute.subst(usad8Iop)
676 uint32_t resTemp = 0;
677 for (unsigned i = 0; i < 4; i++) {
680 int32_t diff = bits(Op1, high, low) -
681 bits(Op2, high, low);
682 resTemp += ((diff < 0) ? -diff : diff);
684 Dest = Op3 + resTemp;
686 usada8Iop = InstObjParams("usada8", "Usada8", "RegRegRegRegOp",
687 { "code": usada8Code,
688 "predicate_test": predicateTest }, [])
689 header_output += RegRegRegRegOpDeclare.subst(usada8Iop)
690 decoder_output += RegRegRegRegOpConstructor.subst(usada8Iop)
691 exec_output += PredOpExecute.subst(usada8Iop)
696 imm16 = ((bits(machInst, 19, 8) << 4) | bits(machInst, 3, 0));
698 imm16 = bits(machInst, 7, 0);
700 return softwareBreakpoint32(xc, imm16);
702 bkptIop = InstObjParams("bkpt", "BkptInst", "PredOp", bkptCode)
703 header_output += BasicDeclare.subst(bkptIop)
704 decoder_output += BasicConstructor.subst(bkptIop)
705 exec_output += BasicExecute.subst(bkptIop)
707 nopIop = InstObjParams("nop", "NopInst", "ArmStaticInst", "", ['IsNop'])
708 header_output += BasicDeclare.subst(nopIop)
709 decoder_output += BasicConstructor64.subst(nopIop)
710 exec_output += BasicExecute.subst(nopIop)
712 yieldIop = InstObjParams("yield", "YieldInst", "PredOp", \
713 { "code" : "", "predicate_test" : predicateTest })
714 header_output += BasicDeclare.subst(yieldIop)
715 decoder_output += BasicConstructor.subst(yieldIop)
716 exec_output += PredOpExecute.subst(yieldIop)
722 // WFE Sleeps if SevMailbox==0 and no unmasked interrupts are pending,
723 ThreadContext *tc = xc->tcBase();
724 Tick next_cycle = tc->getCpuPtr()->nextCycle();
725 if (SevMailbox == 1) {
727 tc->quiesceTick(next_cycle + 1);
728 } else if (tc->getCpuPtr()->getInterruptController(
729 tc->threadId())->checkInterrupts()) {
730 tc->quiesceTick(next_cycle + 1);
732 fault = trapWFx(tc, cpsr, scr, true);
733 if (fault == NoFault) {
736 tc->quiesceTick(next_cycle + 1);
740 wfePredFixUpCode = '''
741 // WFE is predicated false, reset SevMailbox to reduce spurious sleeps
742 // and SEV interrupts
745 wfeIop = InstObjParams("wfe", "WfeInst", "PredOp", \
747 "pred_fixup" : wfePredFixUpCode,
748 "predicate_test" : predicateTest },
749 ["IsNonSpeculative", "IsQuiesce",
750 "IsSerializeAfter", "IsUnverifiable"])
751 header_output += BasicDeclare.subst(wfeIop)
752 decoder_output += BasicConstructor.subst(wfeIop)
753 exec_output += QuiescePredOpExecuteWithFixup.subst(wfeIop)
760 // WFI doesn't sleep if interrupts are pending (masked or not)
761 ThreadContext *tc = xc->tcBase();
762 auto *ic = dynamic_cast<ArmISA::Interrupts *>(
763 tc->getCpuPtr()->getInterruptController(tc->threadId()));
764 Tick next_cycle = tc->getCpuPtr()->nextCycle();
765 if (ic->checkWfiWake(hcr, cpsr, scr)) {
766 tc->quiesceTick(next_cycle + 1);
768 fault = trapWFx(tc, cpsr, scr, false);
769 if (fault == NoFault) {
771 ArmSystem::callSetStandByWfi(tc);
773 tc->quiesceTick(next_cycle + 1);
776 tc->getCpuPtr()->clearInterrupt(tc->threadId(), INT_ABT, 0);
778 wfiIop = InstObjParams("wfi", "WfiInst", "PredOp", \
779 { "code" : wfiCode, "predicate_test" : predicateTest },
780 ["IsNonSpeculative", "IsQuiesce",
781 "IsSerializeAfter", "IsUnverifiable"])
782 header_output += BasicDeclare.subst(wfiIop)
783 decoder_output += BasicConstructor.subst(wfiIop)
784 exec_output += QuiescePredOpExecute.subst(wfiIop)
788 System *sys = xc->tcBase()->getSystemPtr();
789 for (int x = 0; x < sys->threads.size(); x++) {
790 ThreadContext *oc = sys->threads[x];
791 if (oc == xc->tcBase())
794 // Wake CPU with interrupt if they were sleeping
798 sevIop = InstObjParams("sev", "SevInst", "PredOp", \
799 { "code" : sevCode, "predicate_test" : predicateTest },
800 ["IsNonSpeculative", "IsSquashAfter", "IsUnverifiable"])
801 header_output += BasicDeclare.subst(sevIop)
802 decoder_output += BasicConstructor.subst(sevIop)
803 exec_output += PredOpExecute.subst(sevIop)
808 sevlIop = InstObjParams("sevl", "SevlInst", "PredOp", \
809 { "code" : sevlCode, "predicate_test" : predicateTest },
810 ["IsNonSpeculative", "IsSquashAfter", "IsUnverifiable"])
811 header_output += BasicDeclare.subst(sevlIop)
812 decoder_output += BasicConstructor.subst(sevlIop)
813 exec_output += BasicExecute.subst(sevlIop)
815 itIop = InstObjParams("it", "ItInst", "PredOp", \
817 "predicate_test" : predicateTest }, [])
818 header_output += BasicDeclare.subst(itIop)
819 decoder_output += BasicConstructor.subst(itIop)
820 exec_output += PredOpExecute.subst(itIop)
822 return std::make_shared<UndefinedInstruction>(machInst, true);
824 unknownIop = InstObjParams("unknown", "Unknown", "UnknownOp", \
825 { "code": unknownCode,
826 "predicate_test": predicateTest })
827 header_output += BasicDeclare.subst(unknownIop)
828 decoder_output += BasicConstructor.subst(unknownIop)
829 exec_output += PredOpExecute.subst(unknownIop)
832 Dest = bits(Op1, imm2, imm1);
834 ubfxIop = InstObjParams("ubfx", "Ubfx", "RegRegImmImmOp",
836 "predicate_test": predicateTest }, [])
837 header_output += RegRegImmImmOpDeclare.subst(ubfxIop)
838 decoder_output += RegRegImmImmOpConstructor.subst(ubfxIop)
839 exec_output += PredOpExecute.subst(ubfxIop)
842 int32_t resTemp = bits(Op1, imm2, imm1);
843 Dest = resTemp | -(resTemp & (1 << (imm2 - imm1)));
845 sbfxIop = InstObjParams("sbfx", "Sbfx", "RegRegImmImmOp",
847 "predicate_test": predicateTest }, [])
848 header_output += RegRegImmImmOpDeclare.subst(sbfxIop)
849 decoder_output += RegRegImmImmOpConstructor.subst(sbfxIop)
850 exec_output += PredOpExecute.subst(sbfxIop)
853 Dest = Op1 & ~(mask(imm2 - imm1 + 1) << imm1);
855 bfcIop = InstObjParams("bfc", "Bfc", "RegRegImmImmOp",
857 "predicate_test": predicateTest }, [])
858 header_output += RegRegImmImmOpDeclare.subst(bfcIop)
859 decoder_output += RegRegImmImmOpConstructor.subst(bfcIop)
860 exec_output += PredOpExecute.subst(bfcIop)
863 uint32_t bitMask = (mask(imm2 - imm1 + 1) << imm1);
864 Dest = ((Op1 << imm1) & bitMask) | (Dest & ~bitMask);
866 bfiIop = InstObjParams("bfi", "Bfi", "RegRegImmImmOp",
868 "predicate_test": predicateTest }, [])
869 header_output += RegRegImmImmOpDeclare.subst(bfiIop)
870 decoder_output += RegRegImmImmOpConstructor.subst(bfiIop)
871 exec_output += PredOpExecute.subst(bfiIop)
874 MiscRegIndex miscReg = (MiscRegIndex) xc->tcBase()->flattenRegId(
875 RegId(MiscRegClass, op1)).index();
876 bool can_read, undefined;
877 std::tie(can_read, undefined) = canReadCoprocReg(miscReg, Scr, Cpsr,
879 if (!can_read || undefined) {
880 return std::make_shared<UndefinedInstruction>(machInst, false,
883 if (mcrMrc14TrapToHyp((MiscRegIndex) op1, Hcr, Cpsr, Scr, Hdcr,
885 return std::make_shared<HypervisorTrap>(machInst, imm,
886 EC_TRAPPED_CP14_MCR_MRC);
891 mrc14Iop = InstObjParams("mrc", "Mrc14", "RegMiscRegImmOp",
893 "predicate_test": predicateTest }, [])
894 header_output += RegMiscRegImmOpDeclare.subst(mrc14Iop)
895 decoder_output += RegMiscRegImmOpConstructor.subst(mrc14Iop)
896 exec_output += PredOpExecute.subst(mrc14Iop)
900 MiscRegIndex miscReg = (MiscRegIndex) xc->tcBase()->flattenRegId(
901 RegId(MiscRegClass, dest)).index();
902 bool can_write, undefined;
903 std::tie(can_write, undefined) = canWriteCoprocReg(miscReg, Scr, Cpsr,
905 if (undefined || !can_write) {
906 return std::make_shared<UndefinedInstruction>(machInst, false,
909 if (mcrMrc14TrapToHyp(miscReg, Hcr, Cpsr, Scr, Hdcr,
911 return std::make_shared<HypervisorTrap>(machInst, imm,
912 EC_TRAPPED_CP14_MCR_MRC);
916 mcr14Iop = InstObjParams("mcr", "Mcr14", "MiscRegRegImmOp",
918 "predicate_test": predicateTest },
919 ["IsSerializeAfter","IsNonSpeculative"])
920 header_output += MiscRegRegImmOpDeclare.subst(mcr14Iop)
921 decoder_output += MiscRegRegImmOpConstructor.subst(mcr14Iop)
922 exec_output += PredOpExecute.subst(mcr14Iop)
925 int preFlatOp1 = snsBankedIndex(op1, xc->tcBase());
926 MiscRegIndex miscReg = (MiscRegIndex)
927 xc->tcBase()->flattenRegId(RegId(MiscRegClass,
928 preFlatOp1)).index();
930 Fault fault = mcrMrc15Trap(miscReg, machInst, xc->tcBase(), imm);
932 bool can_read, undefined;
933 std::tie(can_read, undefined) = canReadCoprocReg(miscReg, Scr, Cpsr,
935 // if we're in non secure PL1 mode then we can trap regargless of whether
936 // the register is accessable, in other modes we trap if only if the register
938 if (undefined || (!can_read && !(fault != NoFault && !inUserMode(Cpsr) &&
939 !inSecureState(Scr, Cpsr)))) {
940 return std::make_shared<UndefinedInstruction>(machInst, false,
943 if (fault != NoFault) {
946 Dest = MiscNsBankedOp1;
949 mrc15Iop = InstObjParams("mrc", "Mrc15", "RegMiscRegImmOp",
951 "predicate_test": predicateTest }, [])
952 header_output += RegMiscRegImmOpDeclare.subst(mrc15Iop)
953 decoder_output += RegMiscRegImmOpConstructor.subst(mrc15Iop)
954 exec_output += PredOpExecute.subst(mrc15Iop)
958 int preFlatDest = snsBankedIndex(dest, xc->tcBase());
959 MiscRegIndex miscReg = (MiscRegIndex)
960 xc->tcBase()->flattenRegId(RegId(MiscRegClass,
961 preFlatDest)).index();
963 Fault fault = mcrMrc15Trap(miscReg, machInst, xc->tcBase(), imm);
965 bool can_write, undefined;
966 std::tie(can_write, undefined) = canWriteCoprocReg(miscReg, Scr, Cpsr,
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
972 if (undefined || (!can_write && !(fault != NoFault && !inUserMode(Cpsr) &&
973 !inSecureState(Scr, Cpsr)))) {
974 return std::make_shared<UndefinedInstruction>(machInst, false,
977 if (fault != NoFault) {
980 MiscNsBankedDest = Op1;
982 mcr15Iop = InstObjParams("mcr", "Mcr15", "MiscRegRegImmOp",
984 "predicate_test": predicateTest },
985 ["IsSerializeAfter","IsNonSpeculative"])
986 header_output += MiscRegRegImmOpDeclare.subst(mcr15Iop)
987 decoder_output += MiscRegRegImmOpConstructor.subst(mcr15Iop)
988 exec_output += PredOpExecute.subst(mcr15Iop)
992 int preFlatOp1 = snsBankedIndex(op1, xc->tcBase());
993 MiscRegIndex miscReg = (MiscRegIndex)
994 xc->tcBase()->flattenRegId(RegId(MiscRegClass,
995 preFlatOp1)).index();
997 Fault fault = mcrrMrrc15Trap(miscReg, machInst, xc->tcBase(), imm);
999 bool can_read, undefined;
1000 std::tie(can_read, undefined) = canReadCoprocReg(miscReg, Scr, Cpsr,
1002 // if we're in non secure PL1 mode then we can trap regargless of whether
1003 // the register is accessable, in other modes we trap if only if the register
1005 if (undefined || (!can_read && !(fault != NoFault && !inUserMode(Cpsr) &&
1006 !inSecureState(Scr, Cpsr)))) {
1007 return std::make_shared<UndefinedInstruction>(machInst, false,
1010 if (fault != NoFault) {
1013 Dest = bits(MiscNsBankedOp164, 63, 32);
1014 Dest2 = bits(MiscNsBankedOp164, 31, 0);
1016 mrrc15Iop = InstObjParams("mrrc", "Mrrc15", "MrrcOp",
1017 { "code": mrrc15code,
1018 "predicate_test": predicateTest }, [])
1019 header_output += MrrcOpDeclare.subst(mrrc15Iop)
1020 decoder_output += MrrcOpConstructor.subst(mrrc15Iop)
1021 exec_output += PredOpExecute.subst(mrrc15Iop)
1025 int preFlatDest = snsBankedIndex(dest, xc->tcBase());
1026 MiscRegIndex miscReg = (MiscRegIndex)
1027 xc->tcBase()->flattenRegId(RegId(MiscRegClass,
1028 preFlatDest)).index();
1030 Fault fault = mcrrMrrc15Trap(miscReg, machInst, xc->tcBase(), imm);
1032 bool can_write, undefined;
1033 std::tie(can_write, undefined) = canWriteCoprocReg(miscReg, Scr, Cpsr,
1036 // if we're in non secure PL1 mode then we can trap regargless of whether
1037 // the register is accessable, in other modes we trap if only if the register
1039 if (undefined || (!can_write && !(fault != NoFault && !inUserMode(Cpsr) &&
1040 !inSecureState(Scr, Cpsr)))) {
1041 return std::make_shared<UndefinedInstruction>(machInst, false,
1044 if (fault != NoFault) {
1047 MiscNsBankedDest64 = ((uint64_t) Op1 << 32) | Op2;
1049 mcrr15Iop = InstObjParams("mcrr", "Mcrr15", "McrrOp",
1050 { "code": mcrr15code,
1051 "predicate_test": predicateTest }, [])
1052 header_output += McrrOpDeclare.subst(mcrr15Iop)
1053 decoder_output += McrrOpConstructor.subst(mcrr15Iop)
1054 exec_output += PredOpExecute.subst(mcrr15Iop)
1061 enterxIop = InstObjParams("enterx", "Enterx", "PredOp",
1062 { "code": enterxCode,
1063 "predicate_test": predicateTest }, [])
1064 header_output += BasicDeclare.subst(enterxIop)
1065 decoder_output += BasicConstructor.subst(enterxIop)
1066 exec_output += PredOpExecute.subst(enterxIop)
1070 NextJazelle = false;
1072 leavexIop = InstObjParams("leavex", "Leavex", "PredOp",
1073 { "code": leavexCode,
1074 "predicate_test": predicateTest }, [])
1075 header_output += BasicDeclare.subst(leavexIop)
1076 decoder_output += BasicConstructor.subst(leavexIop)
1077 exec_output += PredOpExecute.subst(leavexIop)
1083 fault = checkSETENDEnabled(xc->tcBase(), cpsr);
1085 setendIop = InstObjParams("setend", "Setend", "ImmOp",
1086 { "code": setendCode,
1087 "predicate_test": predicateTest },
1088 ["IsSerializeAfter","IsNonSpeculative"])
1089 header_output += ImmOpDeclare.subst(setendIop)
1090 decoder_output += ImmOpConstructor.subst(setendIop)
1091 exec_output += PredOpExecute.subst(setendIop)
1096 clrexIop = InstObjParams("clrex", "Clrex","PredOp",
1097 { "code": clrexCode,
1098 "predicate_test": predicateTest },[])
1099 header_output += BasicDeclare.subst(clrexIop)
1100 decoder_output += BasicConstructor.subst(clrexIop)
1101 exec_output += PredOpExecute.subst(clrexIop)
1103 McrDcCheckCode = '''
1104 int preFlatDest = snsBankedIndex(dest, xc->tcBase());
1105 MiscRegIndex miscReg = (MiscRegIndex) xc->tcBase()->flattenRegId(
1106 RegId(MiscRegClass, preFlatDest)).index();
1108 bool hypTrap = mcrMrc15TrapToHyp(miscReg, xc->tcBase(), imm);
1110 bool can_write, undefined;
1111 std::tie(can_write, undefined) = canWriteCoprocReg(miscReg, Scr, Cpsr,
1114 // if we're in non secure PL1 mode then we can trap regardless
1115 // of whether the register is accessible, in other modes we
1116 // trap if only if the register IS accessible.
1117 if (undefined || (!can_write & !(hypTrap & !inUserMode(Cpsr) &
1118 !inSecureState(Scr, Cpsr)))) {
1119 return std::make_shared<UndefinedInstruction>(machInst, false,
1123 return std::make_shared<HypervisorTrap>(machInst, imm,
1124 EC_TRAPPED_CP15_MCR_MRC);
1128 McrDcimvacCode = '''
1129 const Request::Flags memAccessFlags(Request::INVALIDATE |
1133 McrDcimvacIop = InstObjParams("mcr", "McrDcimvac",
1135 {"memacc_code": McrDcCheckCode,
1137 "ea_code": McrDcimvacCode,
1138 "predicate_test": predicateTest},
1139 ['IsMemRef', 'IsStore'])
1140 header_output += MiscRegRegImmMemOpDeclare.subst(McrDcimvacIop)
1141 decoder_output += MiscRegRegImmOpConstructor.subst(McrDcimvacIop)
1142 exec_output += Mcr15Execute.subst(McrDcimvacIop) + \
1143 Mcr15InitiateAcc.subst(McrDcimvacIop) + \
1144 Mcr15CompleteAcc.subst(McrDcimvacIop)
1146 McrDccmvacCode = '''
1147 const Request::Flags memAccessFlags(Request::CLEAN |
1151 McrDccmvacIop = InstObjParams("mcr", "McrDccmvac",
1153 {"memacc_code": McrDcCheckCode,
1155 "ea_code": McrDccmvacCode,
1156 "predicate_test": predicateTest},
1157 ['IsMemRef', 'IsStore'])
1158 header_output += MiscRegRegImmMemOpDeclare.subst(McrDccmvacIop)
1159 decoder_output += MiscRegRegImmOpConstructor.subst(McrDccmvacIop)
1160 exec_output += Mcr15Execute.subst(McrDccmvacIop) + \
1161 Mcr15InitiateAcc.subst(McrDccmvacIop) + \
1162 Mcr15CompleteAcc.subst(McrDccmvacIop)
1164 McrDccmvauCode = '''
1165 const Request::Flags memAccessFlags(Request::CLEAN |
1169 McrDccmvauIop = InstObjParams("mcr", "McrDccmvau",
1171 {"memacc_code": McrDcCheckCode,
1173 "ea_code": McrDccmvauCode,
1174 "predicate_test": predicateTest},
1175 ['IsMemRef', 'IsStore'])
1176 header_output += MiscRegRegImmMemOpDeclare.subst(McrDccmvauIop)
1177 decoder_output += MiscRegRegImmOpConstructor.subst(McrDccmvauIop)
1178 exec_output += Mcr15Execute.subst(McrDccmvauIop) + \
1179 Mcr15InitiateAcc.subst(McrDccmvauIop) + \
1180 Mcr15CompleteAcc.subst(McrDccmvauIop)
1182 McrDccimvacCode = '''
1183 const Request::Flags memAccessFlags(Request::CLEAN |
1184 Request::INVALIDATE |
1188 McrDccimvacIop = InstObjParams("mcr", "McrDccimvac",
1190 {"memacc_code": McrDcCheckCode,
1192 "ea_code": McrDccimvacCode,
1193 "predicate_test": predicateTest},
1194 ['IsMemRef', 'IsStore'])
1195 header_output += MiscRegRegImmMemOpDeclare.subst(McrDccimvacIop)
1196 decoder_output += MiscRegRegImmOpConstructor.subst(McrDccimvacIop)
1197 exec_output += Mcr15Execute.subst(McrDccimvacIop) + \
1198 Mcr15InitiateAcc.subst(McrDccimvacIop) + \
1199 Mcr15CompleteAcc.subst(McrDccimvacIop)
1202 // If the barrier is due to a CP15 access check for hyp traps
1203 if ((imm != 0) && mcrMrc15TrapToHyp(MISCREG_CP15ISB,
1204 xc->tcBase(), imm)) {
1205 return std::make_shared<HypervisorTrap>(machInst, imm,
1206 EC_TRAPPED_CP15_MCR_MRC);
1209 isbIop = InstObjParams("isb", "Isb", "ImmOp",
1211 "predicate_test": predicateTest},
1213 header_output += ImmOpDeclare.subst(isbIop)
1214 decoder_output += ImmOpConstructor.subst(isbIop)
1215 exec_output += PredOpExecute.subst(isbIop)
1218 // If the barrier is due to a CP15 access check for hyp traps
1219 if ((imm != 0) && mcrMrc15TrapToHyp(MISCREG_CP15DSB,
1220 xc->tcBase(), imm)) {
1221 return std::make_shared<HypervisorTrap>(machInst, imm,
1222 EC_TRAPPED_CP15_MCR_MRC);
1225 dsbIop = InstObjParams("dsb", "Dsb", "ImmOp",
1227 "predicate_test": predicateTest},
1228 ['IsMemBarrier', 'IsSerializeAfter'])
1229 header_output += ImmOpDeclare.subst(dsbIop)
1230 decoder_output += ImmOpConstructor.subst(dsbIop)
1231 exec_output += PredOpExecute.subst(dsbIop)
1234 // If the barrier is due to a CP15 access check for hyp traps
1235 if ((imm != 0) && mcrMrc15TrapToHyp(MISCREG_CP15DMB,
1236 xc->tcBase(), imm)) {
1237 return std::make_shared<HypervisorTrap>(machInst, imm,
1238 EC_TRAPPED_CP15_MCR_MRC);
1241 dmbIop = InstObjParams("dmb", "Dmb", "ImmOp",
1243 "predicate_test": predicateTest},
1245 header_output += ImmOpDeclare.subst(dmbIop)
1246 decoder_output += ImmOpConstructor.subst(dmbIop)
1247 exec_output += PredOpExecute.subst(dmbIop)
1251 dbgIop = InstObjParams("dbg", "Dbg", "PredOp",
1253 "predicate_test": predicateTest})
1254 header_output += BasicDeclare.subst(dbgIop)
1255 decoder_output += BasicConstructor.subst(dbgIop)
1256 exec_output += PredOpExecute.subst(dbgIop)
1259 uint32_t mode = bits(imm, 4, 0);
1260 uint32_t f = bits(imm, 5);
1261 uint32_t i = bits(imm, 6);
1262 uint32_t a = bits(imm, 7);
1263 bool setMode = bits(imm, 8);
1264 bool enable = bits(imm, 9);
1266 SCTLR sctlr = Sctlr;
1267 if (cpsr.mode != MODE_USER) {
1273 if (f && !sctlr.nmfi) cpsr.f = 1;
1283 cpsIop = InstObjParams("cps", "Cps", "ImmOp",
1285 "predicate_test": predicateTest },
1286 ["IsSerializeAfter","IsNonSpeculative"])
1287 header_output += ImmOpDeclare.subst(cpsIop)
1288 decoder_output += ImmOpConstructor.subst(cpsIop)
1289 exec_output += PredOpExecute.subst(cpsIop)