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 (EL2Enabled(xc->tcBase()) && (cpsr.mode != MODE_HYP) && hcr.tsc) {
99 fault = std::make_shared<HypervisorTrap>(machInst, 0,
103 fault = disabledFault();
105 fault = std::make_shared<SecureMonitorCall>(machInst);
109 fault = disabledFault();
113 smcIop = InstObjParams("smc", "Smc", "PredOp",
115 "predicate_test": predicateTest },
116 ["IsNonSpeculative", "IsSerializeAfter"])
117 header_output += BasicDeclare.subst(smcIop)
118 decoder_output += BasicConstructor.subst(smcIop)
119 exec_output += PredOpExecute.subst(smcIop)
124 // Filter out the various cases where this instruction isn't defined
125 if (!FullSystem || !ArmSystem::haveVirtualization(xc->tcBase()) ||
126 (cpsr.mode == MODE_USER) ||
127 (isSecure(xc->tcBase()) && !IsSecureEL2Enabled(xc->tcBase()))) {
128 fault = disabledFault();
130 fault = std::make_shared<HypervisorCall>(machInst, imm);
134 hvcIop = InstObjParams("hvc", "Hvc", "ImmOp",
136 "predicate_test": predicateTest },
137 ["IsNonSpeculative", "IsSerializeAfter"])
138 header_output += ImmOpDeclare.subst(hvcIop)
139 decoder_output += ImmOpConstructor.subst(hvcIop)
140 exec_output += PredOpExecute.subst(hvcIop)
144 CPSR old_cpsr = Cpsr;
145 old_cpsr.nz = CondCodesNZ;
146 old_cpsr.c = CondCodesC;
147 old_cpsr.v = CondCodesV;
148 old_cpsr.ge = CondCodesGE;
150 CPSR new_cpsr = cpsrWriteByInstr(old_cpsr, Spsr, Scr, Nsacr, 0xF,
151 true, sctlr.nmfi, xc->tcBase());
152 Cpsr = ~CondCodesMask & new_cpsr;
153 CondCodesNZ = new_cpsr.nz;
154 CondCodesC = new_cpsr.c;
155 CondCodesV = new_cpsr.v;
156 CondCodesGE = new_cpsr.ge;
158 NextThumb = (new_cpsr).t;
159 NextJazelle = (new_cpsr).j;
160 NextItState = (((new_cpsr).it2 << 2) & 0xFC)
161 | ((new_cpsr).it1 & 0x3);
163 NPC = (old_cpsr.mode == MODE_HYP) ? ElrHyp : LR;
166 eretIop = InstObjParams("eret", "Eret", "PredOp",
168 "predicate_test": predicateTest },
169 ["IsNonSpeculative", "IsSerializeAfter",
171 header_output += BasicDeclare.subst(eretIop)
172 decoder_output += BasicConstructor.subst(eretIop)
173 exec_output += PredOpExecute.subst(eretIop)
176 constexpr uint8_t size_bytes = %(sz)d;
177 constexpr uint32_t poly = %(polynom)s;
179 uint32_t data = htole(Op2);
180 auto data_buffer = reinterpret_cast<uint8_t*>(&data);
183 data_buffer, /* Message Register */
184 Op1, /* Initial Value of the CRC */
185 size_bytes /* Size of the original Message */
189 def crc32Emit(mnem, implCode, castagnoli, size):
190 global header_output, decoder_output, exec_output
193 # crc32c instructions
199 data = {'sz' : size, 'polynom': poly}
201 instCode = implCode % data
203 crcIop = InstObjParams(mnem, mnem.capitalize(), "RegRegRegOp",
205 "predicate_test": predicateTest }, [])
206 header_output += RegRegRegOpDeclare.subst(crcIop)
207 decoder_output += RegRegRegOpConstructor.subst(crcIop)
208 exec_output += PredOpExecute.subst(crcIop)
210 crc32Emit("crc32b", crcCode, False, 1);
211 crc32Emit("crc32h", crcCode, False, 2);
212 crc32Emit("crc32w", crcCode, False, 4);
213 crc32Emit("crc32cb", crcCode, True, 1);
214 crc32Emit("crc32ch", crcCode, True, 2);
215 crc32Emit("crc32cw", crcCode, True, 4);
221 header_output = decoder_output = exec_output = ""
225 cpsr.nz = CondCodesNZ;
228 cpsr.ge = CondCodesGE;
229 Dest = cpsr & (cpsr.mode == MODE_USER ? ApsrMask : CpsrMask);
232 mrsCpsrIop = InstObjParams("mrs", "MrsCpsr", "MrsOp",
233 { "code": mrsCpsrCode,
234 "predicate_test": condPredicateTest },
235 ["IsSerializeBefore"])
236 header_output += MrsDeclare.subst(mrsCpsrIop)
237 decoder_output += MrsConstructor.subst(mrsCpsrIop)
238 exec_output += PredOpExecute.subst(mrsCpsrIop)
240 mrsSpsrCode = "Dest = Spsr"
241 mrsSpsrIop = InstObjParams("mrs", "MrsSpsr", "MrsOp",
242 { "code": mrsSpsrCode,
243 "predicate_test": predicateTest },
244 ["IsSerializeBefore"])
245 header_output += MrsDeclare.subst(mrsSpsrIop)
246 decoder_output += MrsConstructor.subst(mrsSpsrIop)
247 exec_output += PredOpExecute.subst(mrsSpsrIop)
249 mrsBankedRegCode = '''
253 if (decodeMrsMsrBankedReg(byteMask, r, isIntReg, regIdx, Cpsr, Scr, Nsacr)) {
255 Dest = DecodedBankedIntReg;
257 Dest = xc->readMiscReg(regIdx);
260 return std::make_shared<UndefinedInstruction>(machInst, false,
264 mrsBankedRegIop = InstObjParams("mrs", "MrsBankedReg", "MrsOp",
265 { "code": mrsBankedRegCode,
266 "predicate_test": predicateTest },
267 ["IsSerializeBefore"])
268 header_output += MrsBankedRegDeclare.subst(mrsBankedRegIop)
269 decoder_output += MrsBankedRegConstructor.subst(mrsBankedRegIop)
270 exec_output += PredOpExecute.subst(mrsBankedRegIop)
272 msrBankedRegCode = '''
276 if (decodeMrsMsrBankedReg(byteMask, r, isIntReg, regIdx, Cpsr, Scr, Nsacr)) {
278 // This is a bit nasty, you would have thought that
279 // DecodedBankedIntReg wouldn't be written to unless the
280 // conditions on the IF statements above are met, however if
281 // you look at the generated C code you'll find that they are.
282 // However this is safe as DecodedBankedIntReg (which is used
283 // in operands.isa to get the index of DecodedBankedIntReg)
284 // will return INTREG_DUMMY if its not a valid integer
285 // register, so redirecting the write to somewhere we don't
287 DecodedBankedIntReg = Op1;
289 xc->setMiscReg(regIdx, Op1);
292 return std::make_shared<UndefinedInstruction>(machInst, false,
296 msrBankedRegIop = InstObjParams("msr", "MsrBankedReg", "MsrRegOp",
297 { "code": msrBankedRegCode,
298 "predicate_test": predicateTest },
299 ["IsSerializeAfter", "IsNonSpeculative"])
300 header_output += MsrBankedRegDeclare.subst(msrBankedRegIop)
301 decoder_output += MsrBankedRegConstructor.subst(msrBankedRegIop)
302 exec_output += PredOpExecute.subst(msrBankedRegIop)
306 CPSR old_cpsr = Cpsr;
307 old_cpsr.nz = CondCodesNZ;
308 old_cpsr.c = CondCodesC;
309 old_cpsr.v = CondCodesV;
310 old_cpsr.ge = CondCodesGE;
313 cpsrWriteByInstr(old_cpsr, Op1, Scr, Nsacr, byteMask, false,
314 sctlr.nmfi, xc->tcBase());
315 Cpsr = ~CondCodesMask & new_cpsr;
316 CondCodesNZ = new_cpsr.nz;
317 CondCodesC = new_cpsr.c;
318 CondCodesV = new_cpsr.v;
319 CondCodesGE = new_cpsr.ge;
321 msrCpsrRegIop = InstObjParams("msr", "MsrCpsrReg", "MsrRegOp",
322 { "code": msrCpsrRegCode,
323 "predicate_test": condPredicateTest },
324 ["IsSerializeAfter","IsNonSpeculative"])
325 header_output += MsrRegDeclare.subst(msrCpsrRegIop)
326 decoder_output += MsrRegConstructor.subst(msrCpsrRegIop)
327 exec_output += PredOpExecute.subst(msrCpsrRegIop)
329 msrSpsrRegCode = "Spsr = spsrWriteByInstr(Spsr, Op1, byteMask, false);"
330 msrSpsrRegIop = InstObjParams("msr", "MsrSpsrReg", "MsrRegOp",
331 { "code": msrSpsrRegCode,
332 "predicate_test": predicateTest },
333 ["IsSerializeAfter","IsNonSpeculative"])
334 header_output += MsrRegDeclare.subst(msrSpsrRegIop)
335 decoder_output += MsrRegConstructor.subst(msrSpsrRegIop)
336 exec_output += PredOpExecute.subst(msrSpsrRegIop)
340 CPSR old_cpsr = Cpsr;
341 old_cpsr.nz = CondCodesNZ;
342 old_cpsr.c = CondCodesC;
343 old_cpsr.v = CondCodesV;
344 old_cpsr.ge = CondCodesGE;
346 cpsrWriteByInstr(old_cpsr, imm, Scr, Nsacr, byteMask, false,
347 sctlr.nmfi, xc->tcBase());
348 Cpsr = ~CondCodesMask & new_cpsr;
349 CondCodesNZ = new_cpsr.nz;
350 CondCodesC = new_cpsr.c;
351 CondCodesV = new_cpsr.v;
352 CondCodesGE = new_cpsr.ge;
354 msrCpsrImmIop = InstObjParams("msr", "MsrCpsrImm", "MsrImmOp",
355 { "code": msrCpsrImmCode,
356 "predicate_test": condPredicateTest },
357 ["IsSerializeAfter","IsNonSpeculative"])
358 header_output += MsrImmDeclare.subst(msrCpsrImmIop)
359 decoder_output += MsrImmConstructor.subst(msrCpsrImmIop)
360 exec_output += PredOpExecute.subst(msrCpsrImmIop)
362 msrSpsrImmCode = "Spsr = spsrWriteByInstr(Spsr, imm, byteMask, false);"
363 msrSpsrImmIop = InstObjParams("msr", "MsrSpsrImm", "MsrImmOp",
364 { "code": msrSpsrImmCode,
365 "predicate_test": predicateTest },
366 ["IsSerializeAfter","IsNonSpeculative"])
367 header_output += MsrImmDeclare.subst(msrSpsrImmIop)
368 decoder_output += MsrImmConstructor.subst(msrSpsrImmIop)
369 exec_output += PredOpExecute.subst(msrSpsrImmIop)
373 Dest = swap_byte(val);
375 revIop = InstObjParams("rev", "Rev", "RegRegOp",
377 "predicate_test": predicateTest }, [])
378 header_output += RegRegOpDeclare.subst(revIop)
379 decoder_output += RegRegOpConstructor.subst(revIop)
380 exec_output += PredOpExecute.subst(revIop)
384 Dest = (bits(val, 15, 8) << 0) |
385 (bits(val, 7, 0) << 8) |
386 (bits(val, 31, 24) << 16) |
387 (bits(val, 23, 16) << 24);
389 rev16Iop = InstObjParams("rev16", "Rev16", "RegRegOp",
391 "predicate_test": predicateTest }, [])
392 header_output += RegRegOpDeclare.subst(rev16Iop)
393 decoder_output += RegRegOpConstructor.subst(rev16Iop)
394 exec_output += PredOpExecute.subst(rev16Iop)
398 Dest = sext<16>(swap_byte(val));
400 revshIop = InstObjParams("revsh", "Revsh", "RegRegOp",
402 "predicate_test": predicateTest }, [])
403 header_output += RegRegOpDeclare.subst(revshIop)
404 decoder_output += RegRegOpConstructor.subst(revshIop)
405 exec_output += PredOpExecute.subst(revshIop)
408 Dest = reverseBits(Op1);
410 rbitIop = InstObjParams("rbit", "Rbit", "RegRegOp",
412 "predicate_test": predicateTest }, [])
413 header_output += RegRegOpDeclare.subst(rbitIop)
414 decoder_output += RegRegOpConstructor.subst(rbitIop)
415 exec_output += PredOpExecute.subst(rbitIop)
418 Dest = (Op1 == 0) ? 32 : (31 - findMsbSet(Op1));
420 clzIop = InstObjParams("clz", "Clz", "RegRegOp",
422 "predicate_test": predicateTest }, [])
423 header_output += RegRegOpDeclare.subst(clzIop)
424 decoder_output += RegRegOpConstructor.subst(clzIop)
425 exec_output += PredOpExecute.subst(clzIop)
428 int32_t operand = shift_rm_imm(Op1, shiftAmt, shiftType, 0);
430 if (satInt(res, operand, imm))
434 ssatIop = InstObjParams("ssat", "Ssat", "RegImmRegShiftOp",
436 "predicate_test": pickPredicate(ssatCode) }, [])
437 header_output += RegImmRegShiftOpDeclare.subst(ssatIop)
438 decoder_output += RegImmRegShiftOpConstructor.subst(ssatIop)
439 exec_output += PredOpExecute.subst(ssatIop)
442 int32_t operand = shift_rm_imm(Op1, shiftAmt, shiftType, 0);
444 if (uSatInt(res, operand, imm))
448 usatIop = InstObjParams("usat", "Usat", "RegImmRegShiftOp",
450 "predicate_test": pickPredicate(usatCode) }, [])
451 header_output += RegImmRegShiftOpDeclare.subst(usatIop)
452 decoder_output += RegImmRegShiftOpConstructor.subst(usatIop)
453 exec_output += PredOpExecute.subst(usatIop)
457 uint32_t resTemp = 0;
458 int32_t argLow = sext<16>(bits(Op1, 15, 0));
459 int32_t argHigh = sext<16>(bits(Op1, 31, 16));
460 if (satInt(res, argLow, imm))
462 replaceBits(resTemp, 15, 0, res);
463 if (satInt(res, argHigh, imm))
465 replaceBits(resTemp, 31, 16, res);
468 ssat16Iop = InstObjParams("ssat16", "Ssat16", "RegImmRegOp",
469 { "code": ssat16Code,
470 "predicate_test": pickPredicate(ssat16Code) }, [])
471 header_output += RegImmRegOpDeclare.subst(ssat16Iop)
472 decoder_output += RegImmRegOpConstructor.subst(ssat16Iop)
473 exec_output += PredOpExecute.subst(ssat16Iop)
477 uint32_t resTemp = 0;
478 int32_t argLow = sext<16>(bits(Op1, 15, 0));
479 int32_t argHigh = sext<16>(bits(Op1, 31, 16));
480 if (uSatInt(res, argLow, imm))
482 replaceBits(resTemp, 15, 0, res);
483 if (uSatInt(res, argHigh, imm))
485 replaceBits(resTemp, 31, 16, res);
488 usat16Iop = InstObjParams("usat16", "Usat16", "RegImmRegOp",
489 { "code": usat16Code,
490 "predicate_test": pickPredicate(usat16Code) }, [])
491 header_output += RegImmRegOpDeclare.subst(usat16Iop)
492 decoder_output += RegImmRegOpConstructor.subst(usat16Iop)
493 exec_output += PredOpExecute.subst(usat16Iop)
495 sxtbIop = InstObjParams("sxtb", "Sxtb", "RegImmRegOp",
497 "Dest = sext<8>((uint8_t)(Op1_ud >> imm));",
498 "predicate_test": predicateTest }, [])
499 header_output += RegImmRegOpDeclare.subst(sxtbIop)
500 decoder_output += RegImmRegOpConstructor.subst(sxtbIop)
501 exec_output += PredOpExecute.subst(sxtbIop)
503 sxtabIop = InstObjParams("sxtab", "Sxtab", "RegRegRegImmOp",
506 Dest = sext<8>((uint8_t)(Op2_ud >> imm)) +
509 "predicate_test": predicateTest }, [])
510 header_output += RegRegRegImmOpDeclare.subst(sxtabIop)
511 decoder_output += RegRegRegImmOpConstructor.subst(sxtabIop)
512 exec_output += PredOpExecute.subst(sxtabIop)
515 uint32_t resTemp = 0;
516 replaceBits(resTemp, 15, 0, sext<8>(bits(Op1, imm + 7, imm)));
517 replaceBits(resTemp, 31, 16,
518 sext<8>(bits(Op1, (imm + 23) % 32, (imm + 16) % 32)));
521 sxtb16Iop = InstObjParams("sxtb16", "Sxtb16", "RegImmRegOp",
522 { "code": sxtb16Code,
523 "predicate_test": predicateTest }, [])
524 header_output += RegImmRegOpDeclare.subst(sxtb16Iop)
525 decoder_output += RegImmRegOpConstructor.subst(sxtb16Iop)
526 exec_output += PredOpExecute.subst(sxtb16Iop)
529 uint32_t resTemp = 0;
530 replaceBits(resTemp, 15, 0, sext<8>(bits(Op2, imm + 7, imm)) +
532 replaceBits(resTemp, 31, 16,
533 sext<8>(bits(Op2, (imm + 23) % 32, (imm + 16) % 32)) +
537 sxtab16Iop = InstObjParams("sxtab16", "Sxtab16", "RegRegRegImmOp",
538 { "code": sxtab16Code,
539 "predicate_test": predicateTest }, [])
540 header_output += RegRegRegImmOpDeclare.subst(sxtab16Iop)
541 decoder_output += RegRegRegImmOpConstructor.subst(sxtab16Iop)
542 exec_output += PredOpExecute.subst(sxtab16Iop)
545 uint64_t rotated = (uint32_t)Op1;
546 rotated = (rotated | (rotated << 32)) >> imm;
547 Dest = sext<16>((uint16_t)rotated);
549 sxthIop = InstObjParams("sxth", "Sxth", "RegImmRegOp",
551 "predicate_test": predicateTest }, [])
552 header_output += RegImmRegOpDeclare.subst(sxthIop)
553 decoder_output += RegImmRegOpConstructor.subst(sxthIop)
554 exec_output += PredOpExecute.subst(sxthIop)
557 uint64_t rotated = (uint32_t)Op2;
558 rotated = (rotated | (rotated << 32)) >> imm;
559 Dest = sext<16>((uint16_t)rotated) + Op1;
561 sxtahIop = InstObjParams("sxtah", "Sxtah", "RegRegRegImmOp",
563 "predicate_test": predicateTest }, [])
564 header_output += RegRegRegImmOpDeclare.subst(sxtahIop)
565 decoder_output += RegRegRegImmOpConstructor.subst(sxtahIop)
566 exec_output += PredOpExecute.subst(sxtahIop)
568 uxtbIop = InstObjParams("uxtb", "Uxtb", "RegImmRegOp",
569 { "code": "Dest = (uint8_t)(Op1_ud >> imm);",
570 "predicate_test": predicateTest }, [])
571 header_output += RegImmRegOpDeclare.subst(uxtbIop)
572 decoder_output += RegImmRegOpConstructor.subst(uxtbIop)
573 exec_output += PredOpExecute.subst(uxtbIop)
575 uxtabIop = InstObjParams("uxtab", "Uxtab", "RegRegRegImmOp",
577 "Dest = (uint8_t)(Op2_ud >> imm) + Op1;",
578 "predicate_test": predicateTest }, [])
579 header_output += RegRegRegImmOpDeclare.subst(uxtabIop)
580 decoder_output += RegRegRegImmOpConstructor.subst(uxtabIop)
581 exec_output += PredOpExecute.subst(uxtabIop)
584 uint32_t resTemp = 0;
585 replaceBits(resTemp, 15, 0, (uint8_t)(bits(Op1, imm + 7, imm)));
586 replaceBits(resTemp, 31, 16,
587 (uint8_t)(bits(Op1, (imm + 23) % 32, (imm + 16) % 32)));
590 uxtb16Iop = InstObjParams("uxtb16", "Uxtb16", "RegImmRegOp",
591 { "code": uxtb16Code,
592 "predicate_test": predicateTest }, [])
593 header_output += RegImmRegOpDeclare.subst(uxtb16Iop)
594 decoder_output += RegImmRegOpConstructor.subst(uxtb16Iop)
595 exec_output += PredOpExecute.subst(uxtb16Iop)
598 uint32_t resTemp = 0;
599 replaceBits(resTemp, 15, 0, (uint8_t)(bits(Op2, imm + 7, imm)) +
601 replaceBits(resTemp, 31, 16,
602 (uint8_t)(bits(Op2, (imm + 23) % 32, (imm + 16) % 32)) +
606 uxtab16Iop = InstObjParams("uxtab16", "Uxtab16", "RegRegRegImmOp",
607 { "code": uxtab16Code,
608 "predicate_test": predicateTest }, [])
609 header_output += RegRegRegImmOpDeclare.subst(uxtab16Iop)
610 decoder_output += RegRegRegImmOpConstructor.subst(uxtab16Iop)
611 exec_output += PredOpExecute.subst(uxtab16Iop)
614 uint64_t rotated = (uint32_t)Op1;
615 rotated = (rotated | (rotated << 32)) >> imm;
616 Dest = (uint16_t)rotated;
618 uxthIop = InstObjParams("uxth", "Uxth", "RegImmRegOp",
620 "predicate_test": predicateTest }, [])
621 header_output += RegImmRegOpDeclare.subst(uxthIop)
622 decoder_output += RegImmRegOpConstructor.subst(uxthIop)
623 exec_output += PredOpExecute.subst(uxthIop)
626 uint64_t rotated = (uint32_t)Op2;
627 rotated = (rotated | (rotated << 32)) >> imm;
628 Dest = (uint16_t)rotated + Op1;
630 uxtahIop = InstObjParams("uxtah", "Uxtah", "RegRegRegImmOp",
632 "predicate_test": predicateTest }, [])
633 header_output += RegRegRegImmOpDeclare.subst(uxtahIop)
634 decoder_output += RegRegRegImmOpConstructor.subst(uxtahIop)
635 exec_output += PredOpExecute.subst(uxtahIop)
638 uint32_t resTemp = 0;
639 for (unsigned i = 0; i < 4; i++) {
642 replaceBits(resTemp, high, low,
643 bits(CondCodesGE, i) ?
644 bits(Op1, high, low) : bits(Op2, high, low));
648 selIop = InstObjParams("sel", "Sel", "RegRegRegOp",
650 "predicate_test": predicateTest }, [])
651 header_output += RegRegRegOpDeclare.subst(selIop)
652 decoder_output += RegRegRegOpConstructor.subst(selIop)
653 exec_output += PredOpExecute.subst(selIop)
656 uint32_t resTemp = 0;
657 for (unsigned i = 0; i < 4; i++) {
660 int32_t diff = bits(Op1, high, low) -
661 bits(Op2, high, low);
662 resTemp += ((diff < 0) ? -diff : diff);
666 usad8Iop = InstObjParams("usad8", "Usad8", "RegRegRegOp",
668 "predicate_test": predicateTest }, [])
669 header_output += RegRegRegOpDeclare.subst(usad8Iop)
670 decoder_output += RegRegRegOpConstructor.subst(usad8Iop)
671 exec_output += PredOpExecute.subst(usad8Iop)
674 uint32_t resTemp = 0;
675 for (unsigned i = 0; i < 4; i++) {
678 int32_t diff = bits(Op1, high, low) -
679 bits(Op2, high, low);
680 resTemp += ((diff < 0) ? -diff : diff);
682 Dest = Op3 + resTemp;
684 usada8Iop = InstObjParams("usada8", "Usada8", "RegRegRegRegOp",
685 { "code": usada8Code,
686 "predicate_test": predicateTest }, [])
687 header_output += RegRegRegRegOpDeclare.subst(usada8Iop)
688 decoder_output += RegRegRegRegOpConstructor.subst(usada8Iop)
689 exec_output += PredOpExecute.subst(usada8Iop)
694 imm16 = ((bits(machInst, 19, 8) << 4) | bits(machInst, 3, 0));
696 imm16 = bits(machInst, 7, 0);
698 return softwareBreakpoint32(xc, imm16);
700 bkptIop = InstObjParams("bkpt", "BkptInst", "PredOp", bkptCode)
701 header_output += BasicDeclare.subst(bkptIop)
702 decoder_output += BasicConstructor.subst(bkptIop)
703 exec_output += BasicExecute.subst(bkptIop)
705 nopIop = InstObjParams("nop", "NopInst", "ArmStaticInst", "", ['IsNop'])
706 header_output += BasicDeclare.subst(nopIop)
707 decoder_output += BasicConstructor64.subst(nopIop)
708 exec_output += BasicExecute.subst(nopIop)
710 yieldIop = InstObjParams("yield", "YieldInst", "PredOp", \
711 { "code" : "", "predicate_test" : predicateTest })
712 header_output += BasicDeclare.subst(yieldIop)
713 decoder_output += BasicConstructor.subst(yieldIop)
714 exec_output += PredOpExecute.subst(yieldIop)
720 // WFE Sleeps if SevMailbox==0 and no unmasked interrupts are pending,
721 ThreadContext *tc = xc->tcBase();
722 Tick next_cycle = tc->getCpuPtr()->nextCycle();
723 if (SevMailbox == 1) {
725 tc->quiesceTick(next_cycle + 1);
726 } else if (tc->getCpuPtr()->getInterruptController(
727 tc->threadId())->checkInterrupts()) {
728 tc->quiesceTick(next_cycle + 1);
730 fault = trapWFx(tc, cpsr, scr, true);
731 if (fault == NoFault) {
734 tc->quiesceTick(next_cycle + 1);
738 wfePredFixUpCode = '''
739 // WFE is predicated false, reset SevMailbox to reduce spurious sleeps
740 // and SEV interrupts
743 wfeIop = InstObjParams("wfe", "WfeInst", "PredOp", \
745 "pred_fixup" : wfePredFixUpCode,
746 "predicate_test" : predicateTest },
747 ["IsNonSpeculative", "IsQuiesce",
748 "IsSerializeAfter", "IsUnverifiable"])
749 header_output += BasicDeclare.subst(wfeIop)
750 decoder_output += BasicConstructor.subst(wfeIop)
751 exec_output += QuiescePredOpExecuteWithFixup.subst(wfeIop)
758 // WFI doesn't sleep if interrupts are pending (masked or not)
759 ThreadContext *tc = xc->tcBase();
760 auto *ic = dynamic_cast<ArmISA::Interrupts *>(
761 tc->getCpuPtr()->getInterruptController(tc->threadId()));
762 Tick next_cycle = tc->getCpuPtr()->nextCycle();
763 if (ic->checkWfiWake(hcr, cpsr, scr)) {
764 tc->quiesceTick(next_cycle + 1);
766 fault = trapWFx(tc, cpsr, scr, false);
767 if (fault == NoFault) {
769 ArmSystem::callSetStandByWfi(tc);
771 tc->quiesceTick(next_cycle + 1);
774 tc->getCpuPtr()->clearInterrupt(tc->threadId(), INT_ABT, 0);
776 wfiIop = InstObjParams("wfi", "WfiInst", "PredOp", \
777 { "code" : wfiCode, "predicate_test" : predicateTest },
778 ["IsNonSpeculative", "IsQuiesce",
779 "IsSerializeAfter", "IsUnverifiable"])
780 header_output += BasicDeclare.subst(wfiIop)
781 decoder_output += BasicConstructor.subst(wfiIop)
782 exec_output += QuiescePredOpExecute.subst(wfiIop)
786 System *sys = xc->tcBase()->getSystemPtr();
787 for (int x = 0; x < sys->threads.size(); x++) {
788 ThreadContext *oc = sys->threads[x];
789 if (oc == xc->tcBase())
792 // Wake CPU with interrupt if they were sleeping
796 sevIop = InstObjParams("sev", "SevInst", "PredOp", \
797 { "code" : sevCode, "predicate_test" : predicateTest },
798 ["IsNonSpeculative", "IsSquashAfter", "IsUnverifiable"])
799 header_output += BasicDeclare.subst(sevIop)
800 decoder_output += BasicConstructor.subst(sevIop)
801 exec_output += PredOpExecute.subst(sevIop)
806 sevlIop = InstObjParams("sevl", "SevlInst", "PredOp", \
807 { "code" : sevlCode, "predicate_test" : predicateTest },
808 ["IsNonSpeculative", "IsSquashAfter", "IsUnverifiable"])
809 header_output += BasicDeclare.subst(sevlIop)
810 decoder_output += BasicConstructor.subst(sevlIop)
811 exec_output += BasicExecute.subst(sevlIop)
813 itIop = InstObjParams("it", "ItInst", "PredOp", \
815 "predicate_test" : predicateTest }, [])
816 header_output += BasicDeclare.subst(itIop)
817 decoder_output += BasicConstructor.subst(itIop)
818 exec_output += PredOpExecute.subst(itIop)
820 return std::make_shared<UndefinedInstruction>(machInst, true);
822 unknownIop = InstObjParams("unknown", "Unknown", "UnknownOp", \
823 { "code": unknownCode,
824 "predicate_test": predicateTest })
825 header_output += BasicDeclare.subst(unknownIop)
826 decoder_output += BasicConstructor.subst(unknownIop)
827 exec_output += PredOpExecute.subst(unknownIop)
830 Dest = bits(Op1, imm2, imm1);
832 ubfxIop = InstObjParams("ubfx", "Ubfx", "RegRegImmImmOp",
834 "predicate_test": predicateTest }, [])
835 header_output += RegRegImmImmOpDeclare.subst(ubfxIop)
836 decoder_output += RegRegImmImmOpConstructor.subst(ubfxIop)
837 exec_output += PredOpExecute.subst(ubfxIop)
840 int32_t resTemp = bits(Op1, imm2, imm1);
841 Dest = resTemp | -(resTemp & (1 << (imm2 - imm1)));
843 sbfxIop = InstObjParams("sbfx", "Sbfx", "RegRegImmImmOp",
845 "predicate_test": predicateTest }, [])
846 header_output += RegRegImmImmOpDeclare.subst(sbfxIop)
847 decoder_output += RegRegImmImmOpConstructor.subst(sbfxIop)
848 exec_output += PredOpExecute.subst(sbfxIop)
851 Dest = Op1 & ~(mask(imm2 - imm1 + 1) << imm1);
853 bfcIop = InstObjParams("bfc", "Bfc", "RegRegImmImmOp",
855 "predicate_test": predicateTest }, [])
856 header_output += RegRegImmImmOpDeclare.subst(bfcIop)
857 decoder_output += RegRegImmImmOpConstructor.subst(bfcIop)
858 exec_output += PredOpExecute.subst(bfcIop)
861 uint32_t bitMask = (mask(imm2 - imm1 + 1) << imm1);
862 Dest = ((Op1 << imm1) & bitMask) | (Dest & ~bitMask);
864 bfiIop = InstObjParams("bfi", "Bfi", "RegRegImmImmOp",
866 "predicate_test": predicateTest }, [])
867 header_output += RegRegImmImmOpDeclare.subst(bfiIop)
868 decoder_output += RegRegImmImmOpConstructor.subst(bfiIop)
869 exec_output += PredOpExecute.subst(bfiIop)
872 MiscRegIndex miscReg = (MiscRegIndex) xc->tcBase()->flattenRegId(
873 RegId(MiscRegClass, op1)).index();
874 bool can_read, undefined;
875 std::tie(can_read, undefined) = canReadCoprocReg(miscReg, Scr, Cpsr,
877 if (!can_read || undefined) {
878 return std::make_shared<UndefinedInstruction>(machInst, false,
881 if (mcrMrc14TrapToHyp((MiscRegIndex) op1, Hcr, Cpsr, Scr, Hdcr,
883 return std::make_shared<HypervisorTrap>(machInst, imm,
884 EC_TRAPPED_CP14_MCR_MRC);
889 mrc14Iop = InstObjParams("mrc", "Mrc14", "RegMiscRegImmOp",
891 "predicate_test": predicateTest }, [])
892 header_output += RegMiscRegImmOpDeclare.subst(mrc14Iop)
893 decoder_output += RegMiscRegImmOpConstructor.subst(mrc14Iop)
894 exec_output += PredOpExecute.subst(mrc14Iop)
898 MiscRegIndex miscReg = (MiscRegIndex) xc->tcBase()->flattenRegId(
899 RegId(MiscRegClass, dest)).index();
900 bool can_write, undefined;
901 std::tie(can_write, undefined) = canWriteCoprocReg(miscReg, Scr, Cpsr,
903 if (undefined || !can_write) {
904 return std::make_shared<UndefinedInstruction>(machInst, false,
907 if (mcrMrc14TrapToHyp(miscReg, Hcr, Cpsr, Scr, Hdcr,
909 return std::make_shared<HypervisorTrap>(machInst, imm,
910 EC_TRAPPED_CP14_MCR_MRC);
914 mcr14Iop = InstObjParams("mcr", "Mcr14", "MiscRegRegImmOp",
916 "predicate_test": predicateTest },
917 ["IsSerializeAfter","IsNonSpeculative"])
918 header_output += MiscRegRegImmOpDeclare.subst(mcr14Iop)
919 decoder_output += MiscRegRegImmOpConstructor.subst(mcr14Iop)
920 exec_output += PredOpExecute.subst(mcr14Iop)
923 int preFlatOp1 = snsBankedIndex(op1, xc->tcBase());
924 MiscRegIndex miscReg = (MiscRegIndex)
925 xc->tcBase()->flattenRegId(RegId(MiscRegClass,
926 preFlatOp1)).index();
928 Fault fault = mcrMrc15Trap(miscReg, machInst, xc->tcBase(), imm);
930 bool can_read, undefined;
931 std::tie(can_read, undefined) = canReadCoprocReg(miscReg, Scr, Cpsr,
933 // if we're in non secure PL1 mode then we can trap regargless of whether
934 // the register is accessable, in other modes we trap if only if the register
936 if (undefined || (!can_read && !(fault != NoFault && !inUserMode(Cpsr) &&
937 !isSecure(xc->tcBase())))) {
938 return std::make_shared<UndefinedInstruction>(machInst, false,
941 if (fault != NoFault) {
944 Dest = MiscNsBankedOp1;
947 mrc15Iop = InstObjParams("mrc", "Mrc15", "RegMiscRegImmOp",
949 "predicate_test": predicateTest }, [])
950 header_output += RegMiscRegImmOpDeclare.subst(mrc15Iop)
951 decoder_output += RegMiscRegImmOpConstructor.subst(mrc15Iop)
952 exec_output += PredOpExecute.subst(mrc15Iop)
956 int preFlatDest = snsBankedIndex(dest, xc->tcBase());
957 MiscRegIndex miscReg = (MiscRegIndex)
958 xc->tcBase()->flattenRegId(RegId(MiscRegClass,
959 preFlatDest)).index();
961 Fault fault = mcrMrc15Trap(miscReg, machInst, xc->tcBase(), imm);
963 bool can_write, undefined;
964 std::tie(can_write, undefined) = canWriteCoprocReg(miscReg, Scr, Cpsr,
967 // if we're in non secure PL1 mode then we can trap regargless of whether
968 // the register is accessable, in other modes we trap if only if the register
970 if (undefined || (!can_write && !(fault != NoFault && !inUserMode(Cpsr) &&
971 !isSecure(xc->tcBase())))) {
972 return std::make_shared<UndefinedInstruction>(machInst, false,
975 if (fault != NoFault) {
978 MiscNsBankedDest = Op1;
980 mcr15Iop = InstObjParams("mcr", "Mcr15", "MiscRegRegImmOp",
982 "predicate_test": predicateTest },
983 ["IsSerializeAfter","IsNonSpeculative"])
984 header_output += MiscRegRegImmOpDeclare.subst(mcr15Iop)
985 decoder_output += MiscRegRegImmOpConstructor.subst(mcr15Iop)
986 exec_output += PredOpExecute.subst(mcr15Iop)
990 int preFlatOp1 = snsBankedIndex(op1, xc->tcBase());
991 MiscRegIndex miscReg = (MiscRegIndex)
992 xc->tcBase()->flattenRegId(RegId(MiscRegClass,
993 preFlatOp1)).index();
995 Fault fault = mcrrMrrc15Trap(miscReg, machInst, xc->tcBase(), imm);
997 bool can_read, undefined;
998 std::tie(can_read, undefined) = canReadCoprocReg(miscReg, Scr, Cpsr,
1000 // if we're in non secure PL1 mode then we can trap regargless of whether
1001 // the register is accessable, in other modes we trap if only if the register
1003 if (undefined || (!can_read && !(fault != NoFault && !inUserMode(Cpsr) &&
1004 !isSecure(xc->tcBase())))) {
1005 return std::make_shared<UndefinedInstruction>(machInst, false,
1008 if (fault != NoFault) {
1011 Dest = bits(MiscNsBankedOp164, 63, 32);
1012 Dest2 = bits(MiscNsBankedOp164, 31, 0);
1014 mrrc15Iop = InstObjParams("mrrc", "Mrrc15", "MrrcOp",
1015 { "code": mrrc15code,
1016 "predicate_test": predicateTest }, [])
1017 header_output += MrrcOpDeclare.subst(mrrc15Iop)
1018 decoder_output += MrrcOpConstructor.subst(mrrc15Iop)
1019 exec_output += PredOpExecute.subst(mrrc15Iop)
1023 int preFlatDest = snsBankedIndex(dest, xc->tcBase());
1024 MiscRegIndex miscReg = (MiscRegIndex)
1025 xc->tcBase()->flattenRegId(RegId(MiscRegClass,
1026 preFlatDest)).index();
1028 Fault fault = mcrrMrrc15Trap(miscReg, machInst, xc->tcBase(), imm);
1030 bool can_write, undefined;
1031 std::tie(can_write, undefined) = canWriteCoprocReg(miscReg, Scr, Cpsr,
1034 // if we're in non secure PL1 mode then we can trap regargless of whether
1035 // the register is accessable, in other modes we trap if only if the register
1037 if (undefined || (!can_write && !(fault != NoFault && !inUserMode(Cpsr) &&
1038 !isSecure(xc->tcBase())))) {
1039 return std::make_shared<UndefinedInstruction>(machInst, false,
1042 if (fault != NoFault) {
1045 MiscNsBankedDest64 = ((uint64_t) Op1 << 32) | Op2;
1047 mcrr15Iop = InstObjParams("mcrr", "Mcrr15", "McrrOp",
1048 { "code": mcrr15code,
1049 "predicate_test": predicateTest }, [])
1050 header_output += McrrOpDeclare.subst(mcrr15Iop)
1051 decoder_output += McrrOpConstructor.subst(mcrr15Iop)
1052 exec_output += PredOpExecute.subst(mcrr15Iop)
1059 enterxIop = InstObjParams("enterx", "Enterx", "PredOp",
1060 { "code": enterxCode,
1061 "predicate_test": predicateTest }, [])
1062 header_output += BasicDeclare.subst(enterxIop)
1063 decoder_output += BasicConstructor.subst(enterxIop)
1064 exec_output += PredOpExecute.subst(enterxIop)
1068 NextJazelle = false;
1070 leavexIop = InstObjParams("leavex", "Leavex", "PredOp",
1071 { "code": leavexCode,
1072 "predicate_test": predicateTest }, [])
1073 header_output += BasicDeclare.subst(leavexIop)
1074 decoder_output += BasicConstructor.subst(leavexIop)
1075 exec_output += PredOpExecute.subst(leavexIop)
1081 fault = checkSETENDEnabled(xc->tcBase(), cpsr);
1083 setendIop = InstObjParams("setend", "Setend", "ImmOp",
1084 { "code": setendCode,
1085 "predicate_test": predicateTest },
1086 ["IsSerializeAfter","IsNonSpeculative"])
1087 header_output += ImmOpDeclare.subst(setendIop)
1088 decoder_output += ImmOpConstructor.subst(setendIop)
1089 exec_output += PredOpExecute.subst(setendIop)
1094 clrexIop = InstObjParams("clrex", "Clrex","PredOp",
1095 { "code": clrexCode,
1096 "predicate_test": predicateTest },[])
1097 header_output += BasicDeclare.subst(clrexIop)
1098 decoder_output += BasicConstructor.subst(clrexIop)
1099 exec_output += PredOpExecute.subst(clrexIop)
1101 McrDcCheckCode = '''
1102 int preFlatDest = snsBankedIndex(dest, xc->tcBase());
1103 MiscRegIndex miscReg = (MiscRegIndex) xc->tcBase()->flattenRegId(
1104 RegId(MiscRegClass, preFlatDest)).index();
1106 bool hypTrap = mcrMrc15TrapToHyp(miscReg, xc->tcBase(), imm);
1108 bool can_write, undefined;
1109 std::tie(can_write, undefined) = canWriteCoprocReg(miscReg, Scr, Cpsr,
1112 // if we're in non secure PL1 mode then we can trap regardless
1113 // of whether the register is accessible, in other modes we
1114 // trap if only if the register IS accessible.
1115 if (undefined || (!can_write & !(hypTrap & !inUserMode(Cpsr) &
1116 !isSecure(xc->tcBase())))) {
1117 return std::make_shared<UndefinedInstruction>(machInst, false,
1121 return std::make_shared<HypervisorTrap>(machInst, imm,
1122 EC_TRAPPED_CP15_MCR_MRC);
1126 McrDcimvacCode = '''
1127 const Request::Flags memAccessFlags(Request::INVALIDATE |
1131 McrDcimvacIop = InstObjParams("mcr", "McrDcimvac",
1133 {"memacc_code": McrDcCheckCode,
1135 "ea_code": McrDcimvacCode,
1136 "predicate_test": predicateTest},
1137 ['IsMemRef', 'IsStore'])
1138 header_output += MiscRegRegImmMemOpDeclare.subst(McrDcimvacIop)
1139 decoder_output += MiscRegRegImmOpConstructor.subst(McrDcimvacIop)
1140 exec_output += Mcr15Execute.subst(McrDcimvacIop) + \
1141 Mcr15InitiateAcc.subst(McrDcimvacIop) + \
1142 Mcr15CompleteAcc.subst(McrDcimvacIop)
1144 McrDccmvacCode = '''
1145 const Request::Flags memAccessFlags(Request::CLEAN |
1149 McrDccmvacIop = InstObjParams("mcr", "McrDccmvac",
1151 {"memacc_code": McrDcCheckCode,
1153 "ea_code": McrDccmvacCode,
1154 "predicate_test": predicateTest},
1155 ['IsMemRef', 'IsStore'])
1156 header_output += MiscRegRegImmMemOpDeclare.subst(McrDccmvacIop)
1157 decoder_output += MiscRegRegImmOpConstructor.subst(McrDccmvacIop)
1158 exec_output += Mcr15Execute.subst(McrDccmvacIop) + \
1159 Mcr15InitiateAcc.subst(McrDccmvacIop) + \
1160 Mcr15CompleteAcc.subst(McrDccmvacIop)
1162 McrDccmvauCode = '''
1163 const Request::Flags memAccessFlags(Request::CLEAN |
1167 McrDccmvauIop = InstObjParams("mcr", "McrDccmvau",
1169 {"memacc_code": McrDcCheckCode,
1171 "ea_code": McrDccmvauCode,
1172 "predicate_test": predicateTest},
1173 ['IsMemRef', 'IsStore'])
1174 header_output += MiscRegRegImmMemOpDeclare.subst(McrDccmvauIop)
1175 decoder_output += MiscRegRegImmOpConstructor.subst(McrDccmvauIop)
1176 exec_output += Mcr15Execute.subst(McrDccmvauIop) + \
1177 Mcr15InitiateAcc.subst(McrDccmvauIop) + \
1178 Mcr15CompleteAcc.subst(McrDccmvauIop)
1180 McrDccimvacCode = '''
1181 const Request::Flags memAccessFlags(Request::CLEAN |
1182 Request::INVALIDATE |
1186 McrDccimvacIop = InstObjParams("mcr", "McrDccimvac",
1188 {"memacc_code": McrDcCheckCode,
1190 "ea_code": McrDccimvacCode,
1191 "predicate_test": predicateTest},
1192 ['IsMemRef', 'IsStore'])
1193 header_output += MiscRegRegImmMemOpDeclare.subst(McrDccimvacIop)
1194 decoder_output += MiscRegRegImmOpConstructor.subst(McrDccimvacIop)
1195 exec_output += Mcr15Execute.subst(McrDccimvacIop) + \
1196 Mcr15InitiateAcc.subst(McrDccimvacIop) + \
1197 Mcr15CompleteAcc.subst(McrDccimvacIop)
1200 // If the barrier is due to a CP15 access check for hyp traps
1201 if ((imm != 0) && mcrMrc15TrapToHyp(MISCREG_CP15ISB,
1202 xc->tcBase(), imm)) {
1203 return std::make_shared<HypervisorTrap>(machInst, imm,
1204 EC_TRAPPED_CP15_MCR_MRC);
1207 isbIop = InstObjParams("isb", "Isb", "ImmOp",
1209 "predicate_test": predicateTest},
1211 header_output += ImmOpDeclare.subst(isbIop)
1212 decoder_output += ImmOpConstructor.subst(isbIop)
1213 exec_output += PredOpExecute.subst(isbIop)
1216 // If the barrier is due to a CP15 access check for hyp traps
1217 if ((imm != 0) && mcrMrc15TrapToHyp(MISCREG_CP15DSB,
1218 xc->tcBase(), imm)) {
1219 return std::make_shared<HypervisorTrap>(machInst, imm,
1220 EC_TRAPPED_CP15_MCR_MRC);
1223 dsbIop = InstObjParams("dsb", "Dsb", "ImmOp",
1225 "predicate_test": predicateTest},
1226 ['IsMemBarrier', 'IsSerializeAfter'])
1227 header_output += ImmOpDeclare.subst(dsbIop)
1228 decoder_output += ImmOpConstructor.subst(dsbIop)
1229 exec_output += PredOpExecute.subst(dsbIop)
1232 // If the barrier is due to a CP15 access check for hyp traps
1233 if ((imm != 0) && mcrMrc15TrapToHyp(MISCREG_CP15DMB,
1234 xc->tcBase(), imm)) {
1235 return std::make_shared<HypervisorTrap>(machInst, imm,
1236 EC_TRAPPED_CP15_MCR_MRC);
1239 dmbIop = InstObjParams("dmb", "Dmb", "ImmOp",
1241 "predicate_test": predicateTest},
1243 header_output += ImmOpDeclare.subst(dmbIop)
1244 decoder_output += ImmOpConstructor.subst(dmbIop)
1245 exec_output += PredOpExecute.subst(dmbIop)
1249 dbgIop = InstObjParams("dbg", "Dbg", "PredOp",
1251 "predicate_test": predicateTest})
1252 header_output += BasicDeclare.subst(dbgIop)
1253 decoder_output += BasicConstructor.subst(dbgIop)
1254 exec_output += PredOpExecute.subst(dbgIop)
1257 uint32_t mode = bits(imm, 4, 0);
1258 uint32_t f = bits(imm, 5);
1259 uint32_t i = bits(imm, 6);
1260 uint32_t a = bits(imm, 7);
1261 bool setMode = bits(imm, 8);
1262 bool enable = bits(imm, 9);
1264 SCTLR sctlr = Sctlr;
1265 if (cpsr.mode != MODE_USER) {
1271 if (f && !sctlr.nmfi) cpsr.f = 1;
1281 cpsIop = InstObjParams("cps", "Cps", "ImmOp",
1283 "predicate_test": predicateTest },
1284 ["IsSerializeAfter","IsNonSpeculative"])
1285 header_output += ImmOpDeclare.subst(cpsIop)
1286 decoder_output += ImmOpConstructor.subst(cpsIop)
1287 exec_output += PredOpExecute.subst(cpsIop)