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