misc.isa revision 10474:799c8ee4ecba
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"])
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()->checkInterrupts(tc)) {
653        PseudoInst::quiesceSkip(tc);
654    } else if (cpsr.el == EL0 && !sctlr.ntwe) {
655        PseudoInst::quiesceSkip(tc);
656        fault = std::make_shared<SupervisorTrap>(machInst, 0x1E00001,
657                                                 EC_TRAPPED_WFI_WFE);
658    } else if (ArmSystem::haveVirtualization(tc) &&
659               !inSecureState(scr, cpsr) && (cpsr.mode != MODE_HYP) &&
660               hcr.twe) {
661        PseudoInst::quiesceSkip(tc);
662        fault = std::make_shared<HypervisorTrap>(machInst, 0x1E00001,
663                                                 EC_TRAPPED_WFI_WFE);
664    } else if (ArmSystem::haveSecurity(tc) && cpsr.el != EL3 && scr.twe) {
665        PseudoInst::quiesceSkip(tc);
666        fault = std::make_shared<SecureMonitorTrap>(machInst, 0x1E00001,
667                                                    EC_TRAPPED_WFI_WFE);
668    } else {
669        PseudoInst::quiesce(tc);
670    }
671    '''
672    wfePredFixUpCode = '''
673    // WFE is predicated false, reset SevMailbox to reduce spurious sleeps
674    // and SEV interrupts
675    SevMailbox = 1;
676    '''
677    wfeIop = InstObjParams("wfe", "WfeInst", "PredOp", \
678            { "code" : wfeCode,
679              "pred_fixup" : wfePredFixUpCode,
680              "predicate_test" : predicateTest },
681            ["IsNonSpeculative", "IsQuiesce",
682             "IsSerializeAfter", "IsUnverifiable"])
683    header_output += BasicDeclare.subst(wfeIop)
684    decoder_output += BasicConstructor.subst(wfeIop)
685    exec_output += QuiescePredOpExecuteWithFixup.subst(wfeIop)
686
687    wfiCode = '''
688    HCR  hcr  = Hcr;
689    CPSR cpsr = Cpsr;
690    SCR  scr  = Scr64;
691    SCTLR sctlr = Sctlr;
692
693    // WFI doesn't sleep if interrupts are pending (masked or not)
694    ThreadContext *tc = xc->tcBase();
695    if (tc->getCpuPtr()->getInterruptController()->checkWfiWake(hcr, cpsr,
696                                                                scr)) {
697        PseudoInst::quiesceSkip(tc);
698    } else if (cpsr.el == EL0 && !sctlr.ntwi) {
699        PseudoInst::quiesceSkip(tc);
700        fault = std::make_shared<SupervisorTrap>(machInst, 0x1E00000,
701                                                 EC_TRAPPED_WFI_WFE);
702    } else if (ArmSystem::haveVirtualization(tc) && hcr.twi &&
703               (cpsr.mode != MODE_HYP) && !inSecureState(scr, cpsr)) {
704        PseudoInst::quiesceSkip(tc);
705        fault = std::make_shared<HypervisorTrap>(machInst, 0x1E00000,
706                                                 EC_TRAPPED_WFI_WFE);
707    } else if (ArmSystem::haveSecurity(tc) && cpsr.el != EL3 && scr.twi) {
708        PseudoInst::quiesceSkip(tc);
709        fault = std::make_shared<SecureMonitorTrap>(machInst, 0x1E00000,
710                                                    EC_TRAPPED_WFI_WFE);
711    } else {
712        PseudoInst::quiesce(tc);
713    }
714    tc->getCpuPtr()->clearInterrupt(INT_ABT, 0);
715    '''
716    wfiIop = InstObjParams("wfi", "WfiInst", "PredOp", \
717            { "code" : wfiCode, "predicate_test" : predicateTest },
718            ["IsNonSpeculative", "IsQuiesce",
719             "IsSerializeAfter", "IsUnverifiable"])
720    header_output += BasicDeclare.subst(wfiIop)
721    decoder_output += BasicConstructor.subst(wfiIop)
722    exec_output += QuiescePredOpExecute.subst(wfiIop)
723
724    sevCode = '''
725    SevMailbox = 1;
726    System *sys = xc->tcBase()->getSystemPtr();
727    for (int x = 0; x < sys->numContexts(); x++) {
728        ThreadContext *oc = sys->getThreadContext(x);
729        if (oc == xc->tcBase())
730            continue;
731        // Wake CPU with interrupt if they were sleeping
732        if (oc->readMiscReg(MISCREG_SEV_MAILBOX) == 0) {
733            // Post Interrupt and wake cpu if needed
734            oc->getCpuPtr()->postInterrupt(INT_SEV, 0);
735        }
736    }
737    '''
738    sevIop = InstObjParams("sev", "SevInst", "PredOp", \
739            { "code" : sevCode, "predicate_test" : predicateTest },
740            ["IsNonSpeculative", "IsSquashAfter", "IsUnverifiable"])
741    header_output += BasicDeclare.subst(sevIop)
742    decoder_output += BasicConstructor.subst(sevIop)
743    exec_output += PredOpExecute.subst(sevIop)
744
745    sevlCode = '''
746    SevMailbox = 1;
747    '''
748    sevlIop = InstObjParams("sevl", "SevlInst", "PredOp", \
749            { "code" : sevlCode, "predicate_test" : predicateTest },
750            ["IsNonSpeculative", "IsSquashAfter", "IsUnverifiable"])
751    header_output += BasicDeclare.subst(sevlIop)
752    decoder_output += BasicConstructor.subst(sevlIop)
753    exec_output += BasicExecute.subst(sevlIop)
754
755    itIop = InstObjParams("it", "ItInst", "PredOp", \
756            { "code" : ";",
757              "predicate_test" : predicateTest }, [])
758    header_output += BasicDeclare.subst(itIop)
759    decoder_output += BasicConstructor.subst(itIop)
760    exec_output += PredOpExecute.subst(itIop)
761    unknownCode = '''
762        return std::make_shared<UndefinedInstruction>(machInst, true);
763    '''
764    unknownIop = InstObjParams("unknown", "Unknown", "UnknownOp", \
765                               { "code": unknownCode,
766                                 "predicate_test": predicateTest })
767    header_output += BasicDeclare.subst(unknownIop)
768    decoder_output += BasicConstructor.subst(unknownIop)
769    exec_output += PredOpExecute.subst(unknownIop)
770
771    ubfxCode = '''
772        Dest = bits(Op1, imm2, imm1);
773    '''
774    ubfxIop = InstObjParams("ubfx", "Ubfx", "RegRegImmImmOp",
775                            { "code": ubfxCode,
776                              "predicate_test": predicateTest }, [])
777    header_output += RegRegImmImmOpDeclare.subst(ubfxIop)
778    decoder_output += RegRegImmImmOpConstructor.subst(ubfxIop)
779    exec_output += PredOpExecute.subst(ubfxIop)
780
781    sbfxCode = '''
782        int32_t resTemp = bits(Op1, imm2, imm1);
783        Dest = resTemp | -(resTemp & (1 << (imm2 - imm1)));
784    '''
785    sbfxIop = InstObjParams("sbfx", "Sbfx", "RegRegImmImmOp",
786                            { "code": sbfxCode,
787                              "predicate_test": predicateTest }, [])
788    header_output += RegRegImmImmOpDeclare.subst(sbfxIop)
789    decoder_output += RegRegImmImmOpConstructor.subst(sbfxIop)
790    exec_output += PredOpExecute.subst(sbfxIop)
791
792    bfcCode = '''
793        Dest = Op1 & ~(mask(imm2 - imm1 + 1) << imm1);
794    '''
795    bfcIop = InstObjParams("bfc", "Bfc", "RegRegImmImmOp",
796                           { "code": bfcCode,
797                             "predicate_test": predicateTest }, [])
798    header_output += RegRegImmImmOpDeclare.subst(bfcIop)
799    decoder_output += RegRegImmImmOpConstructor.subst(bfcIop)
800    exec_output += PredOpExecute.subst(bfcIop)
801
802    bfiCode = '''
803        uint32_t bitMask = (mask(imm2 - imm1 + 1) << imm1);
804        Dest = ((Op1 << imm1) & bitMask) | (Dest & ~bitMask);
805    '''
806    bfiIop = InstObjParams("bfi", "Bfi", "RegRegImmImmOp",
807                           { "code": bfiCode,
808                             "predicate_test": predicateTest }, [])
809    header_output += RegRegImmImmOpDeclare.subst(bfiIop)
810    decoder_output += RegRegImmImmOpConstructor.subst(bfiIop)
811    exec_output += PredOpExecute.subst(bfiIop)
812
813    mrc14code = '''
814    MiscRegIndex miscReg = (MiscRegIndex) xc->tcBase()->flattenMiscIndex(op1);
815    if (!canReadCoprocReg(miscReg, Scr, Cpsr, xc->tcBase())) {
816        return std::make_shared<UndefinedInstruction>(machInst, false,
817                                                      mnemonic);
818    }
819    if (mcrMrc14TrapToHyp((const MiscRegIndex) op1, Hcr, Cpsr, Scr, Hdcr,
820                          Hstr, Hcptr, imm)) {
821        return std::make_shared<HypervisorTrap>(machInst, imm,
822                                                EC_TRAPPED_CP14_MCR_MRC);
823    }
824    Dest = MiscOp1;
825    '''
826
827    mrc14Iop = InstObjParams("mrc", "Mrc14", "RegRegImmOp",
828                             { "code": mrc14code,
829                               "predicate_test": predicateTest }, [])
830    header_output += RegRegImmOpDeclare.subst(mrc14Iop)
831    decoder_output += RegRegImmOpConstructor.subst(mrc14Iop)
832    exec_output += PredOpExecute.subst(mrc14Iop)
833
834
835    mcr14code = '''
836    MiscRegIndex miscReg = (MiscRegIndex) xc->tcBase()->flattenMiscIndex(dest);
837    if (!canWriteCoprocReg(miscReg, Scr, Cpsr, xc->tcBase())) {
838        return std::make_shared<UndefinedInstruction>(machInst, false,
839                                                      mnemonic);
840    }
841    if (mcrMrc14TrapToHyp(miscReg, Hcr, Cpsr, Scr, Hdcr,
842                          Hstr, Hcptr, imm)) {
843        return std::make_shared<HypervisorTrap>(machInst, imm,
844                                                EC_TRAPPED_CP14_MCR_MRC);
845    }
846    MiscDest = Op1;
847    '''
848    mcr14Iop = InstObjParams("mcr", "Mcr14", "RegRegImmOp",
849                             { "code": mcr14code,
850                               "predicate_test": predicateTest },
851                               ["IsSerializeAfter","IsNonSpeculative"])
852    header_output += RegRegImmOpDeclare.subst(mcr14Iop)
853    decoder_output += RegRegImmOpConstructor.subst(mcr14Iop)
854    exec_output += PredOpExecute.subst(mcr14Iop)
855
856    mrc15code = '''
857    int preFlatOp1 = flattenMiscRegNsBanked(op1, xc->tcBase());
858    MiscRegIndex miscReg = (MiscRegIndex)
859                           xc->tcBase()->flattenMiscIndex(preFlatOp1);
860    bool hypTrap = mcrMrc15TrapToHyp(miscReg, Hcr, Cpsr, Scr, Hdcr, Hstr,
861                                     Hcptr, imm);
862    bool canRead = canReadCoprocReg(miscReg, Scr, Cpsr, xc->tcBase());
863
864    // if we're in non secure PL1 mode then we can trap regargless of whether
865    // the register is accessable, in other modes we trap if only if the register
866    // IS accessable.
867    if (!canRead && !(hypTrap && !inUserMode(Cpsr) && !inSecureState(Scr, Cpsr))) {
868        return std::make_shared<UndefinedInstruction>(machInst, false,
869                                                      mnemonic);
870    }
871    if (hypTrap) {
872        return std::make_shared<HypervisorTrap>(machInst, imm,
873                                                EC_TRAPPED_CP15_MCR_MRC);
874    }
875    Dest = MiscNsBankedOp1;
876    '''
877
878    mrc15Iop = InstObjParams("mrc", "Mrc15", "RegMiscRegImmOp",
879                             { "code": mrc15code,
880                               "predicate_test": predicateTest }, [])
881    header_output += RegMiscRegImmOpDeclare.subst(mrc15Iop)
882    decoder_output += RegMiscRegImmOpConstructor.subst(mrc15Iop)
883    exec_output += PredOpExecute.subst(mrc15Iop)
884
885
886    mcr15code = '''
887    int preFlatDest = flattenMiscRegNsBanked(dest, xc->tcBase());
888    MiscRegIndex miscReg = (MiscRegIndex)
889                       xc->tcBase()->flattenMiscIndex(preFlatDest);
890    bool hypTrap  = mcrMrc15TrapToHyp(miscReg, Hcr, Cpsr, Scr, Hdcr, Hstr,
891                                      Hcptr, imm);
892    bool canWrite = canWriteCoprocReg(miscReg, Scr, Cpsr, xc->tcBase());
893
894    // if we're in non secure PL1 mode then we can trap regargless of whether
895    // the register is accessable, in other modes we trap if only if the register
896    // IS accessable.
897    if (!canWrite & !(hypTrap & !inUserMode(Cpsr) & !inSecureState(Scr, Cpsr))) {
898        return std::make_shared<UndefinedInstruction>(machInst, false,
899                                                      mnemonic);
900    }
901    if (hypTrap) {
902        return std::make_shared<HypervisorTrap>(machInst, imm,
903                                                EC_TRAPPED_CP15_MCR_MRC);
904    }
905    MiscNsBankedDest = Op1;
906    '''
907    mcr15Iop = InstObjParams("mcr", "Mcr15", "MiscRegRegImmOp",
908                             { "code": mcr15code,
909                               "predicate_test": predicateTest },
910                               ["IsSerializeAfter","IsNonSpeculative"])
911    header_output += MiscRegRegImmOpDeclare.subst(mcr15Iop)
912    decoder_output += MiscRegRegImmOpConstructor.subst(mcr15Iop)
913    exec_output += PredOpExecute.subst(mcr15Iop)
914
915
916    mrrc15code = '''
917    int preFlatOp1 = flattenMiscRegNsBanked(op1, xc->tcBase());
918    MiscRegIndex miscReg = (MiscRegIndex)
919                           xc->tcBase()->flattenMiscIndex(preFlatOp1);
920    bool hypTrap = mcrrMrrc15TrapToHyp(miscReg, Cpsr, Scr, Hstr, Hcr, imm);
921    bool canRead = canReadCoprocReg(miscReg, Scr, Cpsr, xc->tcBase());
922
923    // if we're in non secure PL1 mode then we can trap regargless of whether
924    // the register is accessable, in other modes we trap if only if the register
925    // IS accessable.
926    if (!canRead && !(hypTrap && !inUserMode(Cpsr) && !inSecureState(Scr, Cpsr))) {
927        return std::make_shared<UndefinedInstruction>(machInst, false,
928                                                      mnemonic);
929    }
930    if (hypTrap) {
931        return std::make_shared<HypervisorTrap>(machInst, imm,
932                                                EC_TRAPPED_CP15_MCRR_MRRC);
933    }
934    Dest = bits(MiscNsBankedOp164, 63, 32);
935    Dest2 = bits(MiscNsBankedOp164, 31, 0);
936    '''
937    mrrc15Iop = InstObjParams("mrrc", "Mrrc15", "MrrcOp",
938                              { "code": mrrc15code,
939                                "predicate_test": predicateTest }, [])
940    header_output += MrrcOpDeclare.subst(mrrc15Iop)
941    decoder_output += MrrcOpConstructor.subst(mrrc15Iop)
942    exec_output += PredOpExecute.subst(mrrc15Iop)
943
944
945    mcrr15code = '''
946    int preFlatDest = flattenMiscRegNsBanked(dest, xc->tcBase());
947    MiscRegIndex miscReg = (MiscRegIndex)
948                           xc->tcBase()->flattenMiscIndex(preFlatDest);
949    bool hypTrap  = mcrrMrrc15TrapToHyp(miscReg, Cpsr, Scr, Hstr, Hcr, imm);
950    bool canWrite = canWriteCoprocReg(miscReg, Scr, Cpsr, xc->tcBase());
951
952    // if we're in non secure PL1 mode then we can trap regargless of whether
953    // the register is accessable, in other modes we trap if only if the register
954    // IS accessable.
955    if (!canWrite & !(hypTrap & !inUserMode(Cpsr) & !inSecureState(Scr, Cpsr))) {
956        return std::make_shared<UndefinedInstruction>(machInst, false,
957                                                      mnemonic);
958    }
959    if (hypTrap) {
960        return std::make_shared<HypervisorTrap>(machInst, imm,
961                                                EC_TRAPPED_CP15_MCRR_MRRC);
962    }
963    MiscNsBankedDest64 = ((uint64_t) Op1 << 32) | Op2;
964    '''
965    mcrr15Iop = InstObjParams("mcrr", "Mcrr15", "McrrOp",
966                              { "code": mcrr15code,
967                                "predicate_test": predicateTest }, [])
968    header_output += McrrOpDeclare.subst(mcrr15Iop)
969    decoder_output += McrrOpConstructor.subst(mcrr15Iop)
970    exec_output += PredOpExecute.subst(mcrr15Iop)
971
972
973    enterxCode = '''
974        NextThumb = true;
975        NextJazelle = true;
976    '''
977    enterxIop = InstObjParams("enterx", "Enterx", "PredOp",
978                              { "code": enterxCode,
979                                "predicate_test": predicateTest }, [])
980    header_output += BasicDeclare.subst(enterxIop)
981    decoder_output += BasicConstructor.subst(enterxIop)
982    exec_output += PredOpExecute.subst(enterxIop)
983
984    leavexCode = '''
985        NextThumb = true;
986        NextJazelle = false;
987    '''
988    leavexIop = InstObjParams("leavex", "Leavex", "PredOp",
989                              { "code": leavexCode,
990                                "predicate_test": predicateTest }, [])
991    header_output += BasicDeclare.subst(leavexIop)
992    decoder_output += BasicConstructor.subst(leavexIop)
993    exec_output += PredOpExecute.subst(leavexIop)
994
995    setendCode = '''
996        CPSR cpsr = Cpsr;
997        cpsr.e = imm;
998        Cpsr = cpsr;
999    '''
1000    setendIop = InstObjParams("setend", "Setend", "ImmOp",
1001                              { "code": setendCode,
1002                                "predicate_test": predicateTest },
1003                              ["IsSerializeAfter","IsNonSpeculative"])
1004    header_output += ImmOpDeclare.subst(setendIop)
1005    decoder_output += ImmOpConstructor.subst(setendIop)
1006    exec_output += PredOpExecute.subst(setendIop)
1007
1008    clrexCode = '''
1009        LLSCLock = 0;
1010    '''
1011    clrexIop = InstObjParams("clrex", "Clrex","PredOp",
1012                             { "code": clrexCode,
1013                               "predicate_test": predicateTest },[])
1014    header_output += BasicDeclare.subst(clrexIop)
1015    decoder_output += BasicConstructor.subst(clrexIop)
1016    exec_output += PredOpExecute.subst(clrexIop)
1017
1018    isbCode = '''
1019        // If the barrier is due to a CP15 access check for hyp traps
1020        if ((imm != 0) && mcrMrc15TrapToHyp(MISCREG_CP15ISB, Hcr, Cpsr, Scr,
1021            Hdcr, Hstr, Hcptr, imm)) {
1022            return std::make_shared<HypervisorTrap>(machInst, imm,
1023                EC_TRAPPED_CP15_MCR_MRC);
1024        }
1025        fault = std::make_shared<FlushPipe>();
1026    '''
1027    isbIop = InstObjParams("isb", "Isb", "ImmOp",
1028                             {"code": isbCode,
1029                               "predicate_test": predicateTest},
1030                                ['IsSerializeAfter'])
1031    header_output += ImmOpDeclare.subst(isbIop)
1032    decoder_output += ImmOpConstructor.subst(isbIop)
1033    exec_output += PredOpExecute.subst(isbIop)
1034
1035    dsbCode = '''
1036        // If the barrier is due to a CP15 access check for hyp traps
1037        if ((imm != 0) && mcrMrc15TrapToHyp(MISCREG_CP15DSB, Hcr, Cpsr, Scr,
1038            Hdcr, Hstr, Hcptr, imm)) {
1039            return std::make_shared<HypervisorTrap>(machInst, imm,
1040                EC_TRAPPED_CP15_MCR_MRC);
1041        }
1042        fault = std::make_shared<FlushPipe>();
1043    '''
1044    dsbIop = InstObjParams("dsb", "Dsb", "ImmOp",
1045                             {"code": dsbCode,
1046                               "predicate_test": predicateTest},
1047                              ['IsMemBarrier', 'IsSerializeAfter'])
1048    header_output += ImmOpDeclare.subst(dsbIop)
1049    decoder_output += ImmOpConstructor.subst(dsbIop)
1050    exec_output += PredOpExecute.subst(dsbIop)
1051
1052    dmbCode = '''
1053        // If the barrier is due to a CP15 access check for hyp traps
1054        if ((imm != 0) && mcrMrc15TrapToHyp(MISCREG_CP15DMB, Hcr, Cpsr, Scr,
1055            Hdcr, Hstr, Hcptr, imm)) {
1056            return std::make_shared<HypervisorTrap>(machInst, imm,
1057                EC_TRAPPED_CP15_MCR_MRC);
1058        }
1059    '''
1060    dmbIop = InstObjParams("dmb", "Dmb", "ImmOp",
1061                             {"code": dmbCode,
1062                               "predicate_test": predicateTest},
1063                               ['IsMemBarrier'])
1064    header_output += ImmOpDeclare.subst(dmbIop)
1065    decoder_output += ImmOpConstructor.subst(dmbIop)
1066    exec_output += PredOpExecute.subst(dmbIop)
1067
1068    dbgCode = '''
1069    '''
1070    dbgIop = InstObjParams("dbg", "Dbg", "PredOp",
1071                             {"code": dbgCode,
1072                               "predicate_test": predicateTest})
1073    header_output += BasicDeclare.subst(dbgIop)
1074    decoder_output += BasicConstructor.subst(dbgIop)
1075    exec_output += PredOpExecute.subst(dbgIop)
1076
1077    cpsCode = '''
1078    uint32_t mode = bits(imm, 4, 0);
1079    uint32_t f = bits(imm, 5);
1080    uint32_t i = bits(imm, 6);
1081    uint32_t a = bits(imm, 7);
1082    bool setMode = bits(imm, 8);
1083    bool enable = bits(imm, 9);
1084    CPSR cpsr = Cpsr;
1085    SCTLR sctlr = Sctlr;
1086    if (cpsr.mode != MODE_USER) {
1087        if (enable) {
1088            if (f) cpsr.f = 0;
1089            if (i) cpsr.i = 0;
1090            if (a) cpsr.a = 0;
1091        } else {
1092            if (f && !sctlr.nmfi) cpsr.f = 1;
1093            if (i) cpsr.i = 1;
1094            if (a) cpsr.a = 1;
1095        }
1096        if (setMode) {
1097            cpsr.mode = mode;
1098        }
1099    }
1100    Cpsr = cpsr;
1101    '''
1102    cpsIop = InstObjParams("cps", "Cps", "ImmOp",
1103                           { "code": cpsCode,
1104                             "predicate_test": predicateTest },
1105                           ["IsSerializeAfter","IsNonSpeculative"])
1106    header_output += ImmOpDeclare.subst(cpsIop)
1107    decoder_output += ImmOpConstructor.subst(cpsIop)
1108    exec_output += PredOpExecute.subst(cpsIop)
1109}};
1110