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