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