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