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