misc.isa revision 8302:9f23d01421de
1// -*- mode:c++ -*-
2
3// Copyright (c) 2010 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#if FULL_SYSTEM
44    fault = new SupervisorCall;
45#else
46    fault = new SupervisorCall(machInst);
47#endif
48    '''
49
50    svcIop = InstObjParams("svc", "Svc", "PredOp",
51                           { "code": svcCode,
52                             "predicate_test": predicateTest }, ["IsSyscall"])
53    header_output = BasicDeclare.subst(svcIop)
54    decoder_output = BasicConstructor.subst(svcIop)
55    exec_output = PredOpExecute.subst(svcIop)
56
57}};
58
59let {{
60
61    header_output = decoder_output = exec_output = ""
62
63    mrsCpsrCode = '''
64        Dest = (Cpsr | CondCodesF | CondCodesGE) & 0xF8FF03DF
65    '''
66
67    mrsCpsrIop = InstObjParams("mrs", "MrsCpsr", "MrsOp",
68                               { "code": mrsCpsrCode,
69                                 "predicate_test": condPredicateTest },
70                               ["IsSerializeBefore"])
71    header_output += MrsDeclare.subst(mrsCpsrIop)
72    decoder_output += MrsConstructor.subst(mrsCpsrIop)
73    exec_output += PredOpExecute.subst(mrsCpsrIop)
74
75    mrsSpsrCode = "Dest = Spsr"
76    mrsSpsrIop = InstObjParams("mrs", "MrsSpsr", "MrsOp",
77                               { "code": mrsSpsrCode,
78                                 "predicate_test": predicateTest },
79                               ["IsSerializeBefore"])
80    header_output += MrsDeclare.subst(mrsSpsrIop)
81    decoder_output += MrsConstructor.subst(mrsSpsrIop)
82    exec_output += PredOpExecute.subst(mrsSpsrIop)
83
84    msrCpsrRegCode = '''
85        SCTLR sctlr = Sctlr;
86        uint32_t newCpsr =
87            cpsrWriteByInstr(Cpsr | CondCodesF |  CondCodesGE, Op1,
88                             byteMask, false, sctlr.nmfi);
89        Cpsr = ~CondCodesMask & newCpsr;
90        CondCodesF = CondCodesMaskF & newCpsr;
91        CondCodesGE = CondCodesMaskGE & newCpsr;
92    '''
93    msrCpsrRegIop = InstObjParams("msr", "MsrCpsrReg", "MsrRegOp",
94                                  { "code": msrCpsrRegCode,
95                                    "predicate_test": condPredicateTest },
96                                  ["IsSerializeAfter","IsNonSpeculative"])
97    header_output += MsrRegDeclare.subst(msrCpsrRegIop)
98    decoder_output += MsrRegConstructor.subst(msrCpsrRegIop)
99    exec_output += PredOpExecute.subst(msrCpsrRegIop)
100
101    msrSpsrRegCode = "Spsr = spsrWriteByInstr(Spsr, Op1, byteMask, false);"
102    msrSpsrRegIop = InstObjParams("msr", "MsrSpsrReg", "MsrRegOp",
103                                  { "code": msrSpsrRegCode,
104                                    "predicate_test": predicateTest },
105                                  ["IsSerializeAfter","IsNonSpeculative"])
106    header_output += MsrRegDeclare.subst(msrSpsrRegIop)
107    decoder_output += MsrRegConstructor.subst(msrSpsrRegIop)
108    exec_output += PredOpExecute.subst(msrSpsrRegIop)
109
110    msrCpsrImmCode = '''
111        SCTLR sctlr = Sctlr;
112        uint32_t newCpsr =
113            cpsrWriteByInstr(Cpsr | CondCodesF | CondCodesGE, imm,
114                             byteMask, false, sctlr.nmfi);
115        Cpsr = ~CondCodesMask & newCpsr;
116        CondCodesF = CondCodesMaskF & newCpsr;
117        CondCodesGE = CondCodesMaskGE & newCpsr;
118    '''
119    msrCpsrImmIop = InstObjParams("msr", "MsrCpsrImm", "MsrImmOp",
120                                  { "code": msrCpsrImmCode,
121                                    "predicate_test": condPredicateTest },
122                                  ["IsSerializeAfter","IsNonSpeculative"])
123    header_output += MsrImmDeclare.subst(msrCpsrImmIop)
124    decoder_output += MsrImmConstructor.subst(msrCpsrImmIop)
125    exec_output += PredOpExecute.subst(msrCpsrImmIop)
126
127    msrSpsrImmCode = "Spsr = spsrWriteByInstr(Spsr, imm, byteMask, false);"
128    msrSpsrImmIop = InstObjParams("msr", "MsrSpsrImm", "MsrImmOp",
129                                  { "code": msrSpsrImmCode,
130                                    "predicate_test": predicateTest },
131                                  ["IsSerializeAfter","IsNonSpeculative"])
132    header_output += MsrImmDeclare.subst(msrSpsrImmIop)
133    decoder_output += MsrImmConstructor.subst(msrSpsrImmIop)
134    exec_output += PredOpExecute.subst(msrSpsrImmIop)
135
136    revCode = '''
137    uint32_t val = Op1;
138    Dest = swap_byte(val);
139    '''
140    revIop = InstObjParams("rev", "Rev", "RegRegOp",
141                           { "code": revCode,
142                             "predicate_test": predicateTest }, [])
143    header_output += RegRegOpDeclare.subst(revIop)
144    decoder_output += RegRegOpConstructor.subst(revIop)
145    exec_output += PredOpExecute.subst(revIop)
146
147    rev16Code = '''
148    uint32_t val = Op1;
149    Dest = (bits(val, 15, 8) << 0) |
150           (bits(val, 7, 0) << 8) |
151           (bits(val, 31, 24) << 16) |
152           (bits(val, 23, 16) << 24);
153    '''
154    rev16Iop = InstObjParams("rev16", "Rev16", "RegRegOp",
155                             { "code": rev16Code,
156                               "predicate_test": predicateTest }, [])
157    header_output += RegRegOpDeclare.subst(rev16Iop)
158    decoder_output += RegRegOpConstructor.subst(rev16Iop)
159    exec_output += PredOpExecute.subst(rev16Iop)
160
161    revshCode = '''
162    uint16_t val = Op1;
163    Dest = sext<16>(swap_byte(val));
164    '''
165    revshIop = InstObjParams("revsh", "Revsh", "RegRegOp",
166                             { "code": revshCode,
167                               "predicate_test": predicateTest }, [])
168    header_output += RegRegOpDeclare.subst(revshIop)
169    decoder_output += RegRegOpConstructor.subst(revshIop)
170    exec_output += PredOpExecute.subst(revshIop)
171
172    rbitCode = '''
173    uint8_t *opBytes = (uint8_t *)&Op1;
174    uint32_t resTemp;
175    uint8_t *destBytes = (uint8_t *)&resTemp;
176    // This reverses the bytes and bits of the input, or so says the
177    // internet.
178    for (int i = 0; i < 4; i++) {
179        uint32_t temp = opBytes[i];
180        temp = (temp * 0x0802 & 0x22110) | (temp * 0x8020 & 0x88440);
181        destBytes[3 - i] = (temp * 0x10101) >> 16;
182    }
183    Dest = resTemp;
184    '''
185    rbitIop = InstObjParams("rbit", "Rbit", "RegRegOp",
186                            { "code": rbitCode,
187                              "predicate_test": predicateTest }, [])
188    header_output += RegRegOpDeclare.subst(rbitIop)
189    decoder_output += RegRegOpConstructor.subst(rbitIop)
190    exec_output += PredOpExecute.subst(rbitIop)
191
192    clzCode = '''
193        Dest = (Op1 == 0) ? 32 : (31 - findMsbSet(Op1));
194    '''
195    clzIop = InstObjParams("clz", "Clz", "RegRegOp",
196                           { "code": clzCode,
197                             "predicate_test": predicateTest }, [])
198    header_output += RegRegOpDeclare.subst(clzIop)
199    decoder_output += RegRegOpConstructor.subst(clzIop)
200    exec_output += PredOpExecute.subst(clzIop)
201
202    ssatCode = '''
203        int32_t operand = shift_rm_imm(Op1, shiftAmt, shiftType, 0);
204        int32_t res;
205        if (satInt(res, operand, imm))
206            CpsrQ = 1 << 27;
207        Dest = res;
208    '''
209    ssatIop = InstObjParams("ssat", "Ssat", "RegImmRegShiftOp",
210                            { "code": ssatCode,
211                              "predicate_test": condPredicateTest }, [])
212    header_output += RegImmRegShiftOpDeclare.subst(ssatIop)
213    decoder_output += RegImmRegShiftOpConstructor.subst(ssatIop)
214    exec_output += PredOpExecute.subst(ssatIop)
215
216    usatCode = '''
217        int32_t operand = shift_rm_imm(Op1, shiftAmt, shiftType, 0);
218        int32_t res;
219        if (uSatInt(res, operand, imm))
220            CpsrQ = 1 << 27;
221        Dest = res;
222    '''
223    usatIop = InstObjParams("usat", "Usat", "RegImmRegShiftOp",
224                            { "code": usatCode,
225                              "predicate_test": condPredicateTest }, [])
226    header_output += RegImmRegShiftOpDeclare.subst(usatIop)
227    decoder_output += RegImmRegShiftOpConstructor.subst(usatIop)
228    exec_output += PredOpExecute.subst(usatIop)
229
230    ssat16Code = '''
231        int32_t res;
232        uint32_t resTemp = 0;
233        int32_t argLow = sext<16>(bits(Op1, 15, 0));
234        int32_t argHigh = sext<16>(bits(Op1, 31, 16));
235        if (satInt(res, argLow, imm))
236            CpsrQ = 1 << 27;
237        replaceBits(resTemp, 15, 0, res);
238        if (satInt(res, argHigh, imm))
239            CpsrQ = 1 << 27;
240        replaceBits(resTemp, 31, 16, res);
241        Dest = resTemp;
242    '''
243    ssat16Iop = InstObjParams("ssat16", "Ssat16", "RegImmRegOp",
244                              { "code": ssat16Code,
245                                "predicate_test": condPredicateTest }, [])
246    header_output += RegImmRegOpDeclare.subst(ssat16Iop)
247    decoder_output += RegImmRegOpConstructor.subst(ssat16Iop)
248    exec_output += PredOpExecute.subst(ssat16Iop)
249
250    usat16Code = '''
251        int32_t res;
252        uint32_t resTemp = 0;
253        int32_t argLow = sext<16>(bits(Op1, 15, 0));
254        int32_t argHigh = sext<16>(bits(Op1, 31, 16));
255        if (uSatInt(res, argLow, imm))
256            CpsrQ = 1 << 27;
257        replaceBits(resTemp, 15, 0, res);
258        if (uSatInt(res, argHigh, imm))
259            CpsrQ = 1 << 27;
260        replaceBits(resTemp, 31, 16, res);
261        Dest = resTemp;
262    '''
263    usat16Iop = InstObjParams("usat16", "Usat16", "RegImmRegOp",
264                              { "code": usat16Code,
265                                "predicate_test": condPredicateTest }, [])
266    header_output += RegImmRegOpDeclare.subst(usat16Iop)
267    decoder_output += RegImmRegOpConstructor.subst(usat16Iop)
268    exec_output += PredOpExecute.subst(usat16Iop)
269
270    sxtbIop = InstObjParams("sxtb", "Sxtb", "RegImmRegOp",
271                            { "code":
272                              "Dest = sext<8>((uint8_t)(Op1.ud >> imm));",
273                              "predicate_test": predicateTest }, [])
274    header_output += RegImmRegOpDeclare.subst(sxtbIop)
275    decoder_output += RegImmRegOpConstructor.subst(sxtbIop)
276    exec_output += PredOpExecute.subst(sxtbIop)
277
278    sxtabIop = InstObjParams("sxtab", "Sxtab", "RegRegRegImmOp",
279                             { "code":
280                               '''
281                                   Dest = sext<8>((uint8_t)(Op2.ud >> imm)) +
282                                          Op1;
283                               ''',
284                               "predicate_test": predicateTest }, [])
285    header_output += RegRegRegImmOpDeclare.subst(sxtabIop)
286    decoder_output += RegRegRegImmOpConstructor.subst(sxtabIop)
287    exec_output += PredOpExecute.subst(sxtabIop)
288
289    sxtb16Code = '''
290    uint32_t resTemp = 0;
291    replaceBits(resTemp, 15, 0, sext<8>(bits(Op1, imm + 7, imm)));
292    replaceBits(resTemp, 31, 16,
293                sext<8>(bits(Op1, (imm + 23) % 32, (imm + 16) % 32)));
294    Dest = resTemp;
295    '''
296    sxtb16Iop = InstObjParams("sxtb16", "Sxtb16", "RegImmRegOp",
297                              { "code": sxtb16Code,
298                                "predicate_test": predicateTest }, [])
299    header_output += RegImmRegOpDeclare.subst(sxtb16Iop)
300    decoder_output += RegImmRegOpConstructor.subst(sxtb16Iop)
301    exec_output += PredOpExecute.subst(sxtb16Iop)
302
303    sxtab16Code = '''
304    uint32_t resTemp = 0;
305    replaceBits(resTemp, 15, 0, sext<8>(bits(Op2, imm + 7, imm)) +
306                                        bits(Op1, 15, 0));
307    replaceBits(resTemp, 31, 16,
308                sext<8>(bits(Op2, (imm + 23) % 32, (imm + 16) % 32)) +
309                bits(Op1, 31, 16));
310    Dest = resTemp;
311    '''
312    sxtab16Iop = InstObjParams("sxtab16", "Sxtab16", "RegRegRegImmOp",
313                               { "code": sxtab16Code,
314                                 "predicate_test": predicateTest }, [])
315    header_output += RegRegRegImmOpDeclare.subst(sxtab16Iop)
316    decoder_output += RegRegRegImmOpConstructor.subst(sxtab16Iop)
317    exec_output += PredOpExecute.subst(sxtab16Iop)
318
319    sxthCode = '''
320    uint64_t rotated = (uint32_t)Op1;
321    rotated = (rotated | (rotated << 32)) >> imm;
322    Dest = sext<16>((uint16_t)rotated);
323    '''
324    sxthIop = InstObjParams("sxth", "Sxth", "RegImmRegOp",
325                              { "code": sxthCode,
326                                "predicate_test": predicateTest }, [])
327    header_output += RegImmRegOpDeclare.subst(sxthIop)
328    decoder_output += RegImmRegOpConstructor.subst(sxthIop)
329    exec_output += PredOpExecute.subst(sxthIop)
330
331    sxtahCode = '''
332    uint64_t rotated = (uint32_t)Op2;
333    rotated = (rotated | (rotated << 32)) >> imm;
334    Dest = sext<16>((uint16_t)rotated) + Op1;
335    '''
336    sxtahIop = InstObjParams("sxtah", "Sxtah", "RegRegRegImmOp",
337                             { "code": sxtahCode,
338                               "predicate_test": predicateTest }, [])
339    header_output += RegRegRegImmOpDeclare.subst(sxtahIop)
340    decoder_output += RegRegRegImmOpConstructor.subst(sxtahIop)
341    exec_output += PredOpExecute.subst(sxtahIop)
342
343    uxtbIop = InstObjParams("uxtb", "Uxtb", "RegImmRegOp",
344                            { "code": "Dest = (uint8_t)(Op1.ud >> imm);",
345                              "predicate_test": predicateTest }, [])
346    header_output += RegImmRegOpDeclare.subst(uxtbIop)
347    decoder_output += RegImmRegOpConstructor.subst(uxtbIop)
348    exec_output += PredOpExecute.subst(uxtbIop)
349
350    uxtabIop = InstObjParams("uxtab", "Uxtab", "RegRegRegImmOp",
351                             { "code":
352                               "Dest = (uint8_t)(Op2.ud >> imm) + Op1;",
353                               "predicate_test": predicateTest }, [])
354    header_output += RegRegRegImmOpDeclare.subst(uxtabIop)
355    decoder_output += RegRegRegImmOpConstructor.subst(uxtabIop)
356    exec_output += PredOpExecute.subst(uxtabIop)
357
358    uxtb16Code = '''
359    uint32_t resTemp = 0;
360    replaceBits(resTemp, 15, 0, (uint8_t)(bits(Op1, imm + 7, imm)));
361    replaceBits(resTemp, 31, 16,
362                (uint8_t)(bits(Op1, (imm + 23) % 32, (imm + 16) % 32)));
363    Dest = resTemp;
364    '''
365    uxtb16Iop = InstObjParams("uxtb16", "Uxtb16", "RegImmRegOp",
366                              { "code": uxtb16Code,
367                                "predicate_test": predicateTest }, [])
368    header_output += RegImmRegOpDeclare.subst(uxtb16Iop)
369    decoder_output += RegImmRegOpConstructor.subst(uxtb16Iop)
370    exec_output += PredOpExecute.subst(uxtb16Iop)
371
372    uxtab16Code = '''
373    uint32_t resTemp = 0;
374    replaceBits(resTemp, 15, 0, (uint8_t)(bits(Op2, imm + 7, imm)) +
375                                        bits(Op1, 15, 0));
376    replaceBits(resTemp, 31, 16,
377                (uint8_t)(bits(Op2, (imm + 23) % 32, (imm + 16) % 32)) +
378                bits(Op1, 31, 16));
379    Dest = resTemp;
380    '''
381    uxtab16Iop = InstObjParams("uxtab16", "Uxtab16", "RegRegRegImmOp",
382                               { "code": uxtab16Code,
383                                 "predicate_test": predicateTest }, [])
384    header_output += RegRegRegImmOpDeclare.subst(uxtab16Iop)
385    decoder_output += RegRegRegImmOpConstructor.subst(uxtab16Iop)
386    exec_output += PredOpExecute.subst(uxtab16Iop)
387
388    uxthCode = '''
389    uint64_t rotated = (uint32_t)Op1;
390    rotated = (rotated | (rotated << 32)) >> imm;
391    Dest = (uint16_t)rotated;
392    '''
393    uxthIop = InstObjParams("uxth", "Uxth", "RegImmRegOp",
394                              { "code": uxthCode,
395                                "predicate_test": predicateTest }, [])
396    header_output += RegImmRegOpDeclare.subst(uxthIop)
397    decoder_output += RegImmRegOpConstructor.subst(uxthIop)
398    exec_output += PredOpExecute.subst(uxthIop)
399
400    uxtahCode = '''
401    uint64_t rotated = (uint32_t)Op2;
402    rotated = (rotated | (rotated << 32)) >> imm;
403    Dest = (uint16_t)rotated + Op1;
404    '''
405    uxtahIop = InstObjParams("uxtah", "Uxtah", "RegRegRegImmOp",
406                             { "code": uxtahCode,
407                               "predicate_test": predicateTest }, [])
408    header_output += RegRegRegImmOpDeclare.subst(uxtahIop)
409    decoder_output += RegRegRegImmOpConstructor.subst(uxtahIop)
410    exec_output += PredOpExecute.subst(uxtahIop)
411
412    selCode = '''
413        uint32_t resTemp = 0;
414        for (unsigned i = 0; i < 4; i++) {
415            int low = i * 8;
416            int high = low + 7;
417            replaceBits(resTemp, high, low,
418                        bits(CondCodesGE, 16 + i) ?
419                            bits(Op1, high, low) : bits(Op2, high, low));
420        }
421        Dest = resTemp;
422    '''
423    selIop = InstObjParams("sel", "Sel", "RegRegRegOp",
424                           { "code": selCode,
425                             "predicate_test": condPredicateTest }, [])
426    header_output += RegRegRegOpDeclare.subst(selIop)
427    decoder_output += RegRegRegOpConstructor.subst(selIop)
428    exec_output += PredOpExecute.subst(selIop)
429
430    usad8Code = '''
431        uint32_t resTemp = 0;
432        for (unsigned i = 0; i < 4; i++) {
433            int low = i * 8;
434            int high = low + 7;
435            int32_t diff = bits(Op1, high, low) -
436                           bits(Op2, high, low);
437            resTemp += ((diff < 0) ? -diff : diff);
438        }
439        Dest = resTemp;
440    '''
441    usad8Iop = InstObjParams("usad8", "Usad8", "RegRegRegOp",
442                             { "code": usad8Code,
443                               "predicate_test": predicateTest }, [])
444    header_output += RegRegRegOpDeclare.subst(usad8Iop)
445    decoder_output += RegRegRegOpConstructor.subst(usad8Iop)
446    exec_output += PredOpExecute.subst(usad8Iop)
447
448    usada8Code = '''
449        uint32_t resTemp = 0;
450        for (unsigned i = 0; i < 4; i++) {
451            int low = i * 8;
452            int high = low + 7;
453            int32_t diff = bits(Op1, high, low) -
454                           bits(Op2, high, low);
455            resTemp += ((diff < 0) ? -diff : diff);
456        }
457        Dest = Op3 + resTemp;
458    '''
459    usada8Iop = InstObjParams("usada8", "Usada8", "RegRegRegRegOp",
460                              { "code": usada8Code,
461                                "predicate_test": predicateTest }, [])
462    header_output += RegRegRegRegOpDeclare.subst(usada8Iop)
463    decoder_output += RegRegRegRegOpConstructor.subst(usada8Iop)
464    exec_output += PredOpExecute.subst(usada8Iop)
465
466    bkptCode = 'return new PrefetchAbort(PC, ArmFault::DebugEvent);\n'
467    bkptIop = InstObjParams("bkpt", "BkptInst", "PredOp", bkptCode)
468    header_output += BasicDeclare.subst(bkptIop)
469    decoder_output += BasicConstructor.subst(bkptIop)
470    exec_output += BasicExecute.subst(bkptIop)
471
472    nopIop = InstObjParams("nop", "NopInst", "PredOp", \
473            { "code" : "", "predicate_test" : predicateTest },
474            ['IsNop'])
475    header_output += BasicDeclare.subst(nopIop)
476    decoder_output += BasicConstructor.subst(nopIop)
477    exec_output += PredOpExecute.subst(nopIop)
478
479    yieldIop = InstObjParams("yield", "YieldInst", "PredOp", \
480            { "code" : "", "predicate_test" : predicateTest })
481    header_output += BasicDeclare.subst(yieldIop)
482    decoder_output += BasicConstructor.subst(yieldIop)
483    exec_output += PredOpExecute.subst(yieldIop)
484
485    wfeCode = '''
486#if FULL_SYSTEM
487    if (SevMailbox == 1) {
488        SevMailbox = 0;
489        PseudoInst::quiesceSkip(xc->tcBase());
490    } else {
491        PseudoInst::quiesce(xc->tcBase());
492    }
493#endif
494    '''
495    wfeIop = InstObjParams("wfe", "WfeInst", "PredOp", \
496            { "code" : wfeCode, "predicate_test" : predicateTest },
497            ["IsNonSpeculative", "IsQuiesce", "IsSerializeAfter"])
498    header_output += BasicDeclare.subst(wfeIop)
499    decoder_output += BasicConstructor.subst(wfeIop)
500    exec_output += QuiescePredOpExecute.subst(wfeIop)
501
502    wfiCode = '''
503#if FULL_SYSTEM
504    // WFI doesn't sleep if interrupts are pending (masked or not)
505    if (xc->tcBase()->getCpuPtr()->getInterruptController()->checkRaw()) {
506        PseudoInst::quiesceSkip(xc->tcBase());
507    } else {
508        PseudoInst::quiesce(xc->tcBase());
509    }
510#endif
511    '''
512    wfiIop = InstObjParams("wfi", "WfiInst", "PredOp", \
513            { "code" : wfiCode, "predicate_test" : predicateTest },
514            ["IsNonSpeculative", "IsQuiesce", "IsSerializeAfter"])
515    header_output += BasicDeclare.subst(wfiIop)
516    decoder_output += BasicConstructor.subst(wfiIop)
517    exec_output += QuiescePredOpExecute.subst(wfiIop)
518
519    sevCode = '''
520    // Need a way for O3 to not scoreboard these accesses as pipe flushes.
521    SevMailbox = 1;
522    System *sys = xc->tcBase()->getSystemPtr();
523    for (int x = 0; x < sys->numContexts(); x++) {
524        ThreadContext *oc = sys->getThreadContext(x);
525        if (oc == xc->tcBase())
526            continue;
527        // Only wake if they were sleeping
528        if (oc->readMiscReg(MISCREG_SEV_MAILBOX) == 0) {
529            oc->setMiscReg(MISCREG_SEV_MAILBOX, 1);
530            PseudoInst::wakeCPU(xc->tcBase(), x);
531        }
532    }
533    '''
534    sevIop = InstObjParams("sev", "SevInst", "PredOp", \
535            { "code" : sevCode, "predicate_test" : predicateTest },
536            ["IsNonSpeculative", "IsSquashAfter"])
537    header_output += BasicDeclare.subst(sevIop)
538    decoder_output += BasicConstructor.subst(sevIop)
539    exec_output += PredOpExecute.subst(sevIop)
540
541    itIop = InstObjParams("it", "ItInst", "PredOp", \
542            { "code" : ";",
543              "predicate_test" : predicateTest },
544            ["IsNonSpeculative", "IsSerializeAfter"])
545    header_output += BasicDeclare.subst(itIop)
546    decoder_output += BasicConstructor.subst(itIop)
547    exec_output += PredOpExecute.subst(itIop)
548    unknownCode = '''
549#if FULL_SYSTEM
550            return new UndefinedInstruction;
551#else
552            return new UndefinedInstruction(machInst, true);
553#endif
554    '''
555    unknownIop = InstObjParams("unknown", "Unknown", "UnknownOp", \
556                               { "code": unknownCode,
557                                 "predicate_test": predicateTest })
558    header_output += BasicDeclare.subst(unknownIop)
559    decoder_output += BasicConstructor.subst(unknownIop)
560    exec_output += PredOpExecute.subst(unknownIop)
561
562    ubfxCode = '''
563        Dest = bits(Op1, imm2, imm1);
564    '''
565    ubfxIop = InstObjParams("ubfx", "Ubfx", "RegRegImmImmOp",
566                            { "code": ubfxCode,
567                              "predicate_test": predicateTest }, [])
568    header_output += RegRegImmImmOpDeclare.subst(ubfxIop)
569    decoder_output += RegRegImmImmOpConstructor.subst(ubfxIop)
570    exec_output += PredOpExecute.subst(ubfxIop)
571
572    sbfxCode = '''
573        int32_t resTemp = bits(Op1, imm2, imm1);
574        Dest = resTemp | -(resTemp & (1 << (imm2 - imm1)));
575    '''
576    sbfxIop = InstObjParams("sbfx", "Sbfx", "RegRegImmImmOp",
577                            { "code": sbfxCode,
578                              "predicate_test": predicateTest }, [])
579    header_output += RegRegImmImmOpDeclare.subst(sbfxIop)
580    decoder_output += RegRegImmImmOpConstructor.subst(sbfxIop)
581    exec_output += PredOpExecute.subst(sbfxIop)
582
583    bfcCode = '''
584        Dest = Op1 & ~(mask(imm2 - imm1 + 1) << imm1);
585    '''
586    bfcIop = InstObjParams("bfc", "Bfc", "RegRegImmImmOp",
587                           { "code": bfcCode,
588                             "predicate_test": predicateTest }, [])
589    header_output += RegRegImmImmOpDeclare.subst(bfcIop)
590    decoder_output += RegRegImmImmOpConstructor.subst(bfcIop)
591    exec_output += PredOpExecute.subst(bfcIop)
592
593    bfiCode = '''
594        uint32_t bitMask = (mask(imm2 - imm1 + 1) << imm1);
595        Dest = ((Op1 << imm1) & bitMask) | (Dest & ~bitMask);
596    '''
597    bfiIop = InstObjParams("bfi", "Bfi", "RegRegImmImmOp",
598                           { "code": bfiCode,
599                             "predicate_test": predicateTest }, [])
600    header_output += RegRegImmImmOpDeclare.subst(bfiIop)
601    decoder_output += RegRegImmImmOpConstructor.subst(bfiIop)
602    exec_output += PredOpExecute.subst(bfiIop)
603
604    mrc15code = '''
605    CPSR cpsr = Cpsr;
606    if (cpsr.mode == MODE_USER)
607#if FULL_SYSTEM
608        return new UndefinedInstruction;
609#else
610        return new UndefinedInstruction(false, mnemonic);
611#endif
612    Dest = MiscOp1;
613    '''
614
615    mrc15Iop = InstObjParams("mrc", "Mrc15", "RegRegOp",
616                             { "code": mrc15code,
617                               "predicate_test": predicateTest }, [])
618    header_output += RegRegOpDeclare.subst(mrc15Iop)
619    decoder_output += RegRegOpConstructor.subst(mrc15Iop)
620    exec_output += PredOpExecute.subst(mrc15Iop)
621
622
623    mcr15code = '''
624    CPSR cpsr = Cpsr;
625    if (cpsr.mode == MODE_USER)
626#if FULL_SYSTEM
627        return new UndefinedInstruction;
628#else
629        return new UndefinedInstruction(false, mnemonic);
630#endif
631    MiscDest = Op1;
632    '''
633    mcr15Iop = InstObjParams("mcr", "Mcr15", "RegRegOp",
634                             { "code": mcr15code,
635                               "predicate_test": predicateTest },
636                               ["IsSerializeAfter","IsNonSpeculative"])
637    header_output += RegRegOpDeclare.subst(mcr15Iop)
638    decoder_output += RegRegOpConstructor.subst(mcr15Iop)
639    exec_output += PredOpExecute.subst(mcr15Iop)
640
641    mrc15UserIop = InstObjParams("mrc", "Mrc15User", "RegRegOp",
642                                 { "code": "Dest = MiscOp1;",
643                                   "predicate_test": predicateTest }, [])
644    header_output += RegRegOpDeclare.subst(mrc15UserIop)
645    decoder_output += RegRegOpConstructor.subst(mrc15UserIop)
646    exec_output += PredOpExecute.subst(mrc15UserIop)
647
648    mcr15UserIop = InstObjParams("mcr", "Mcr15User", "RegRegOp",
649                                 { "code": "MiscDest = Op1",
650                                   "predicate_test": predicateTest },
651                                   ["IsSerializeAfter","IsNonSpeculative"])
652    header_output += RegRegOpDeclare.subst(mcr15UserIop)
653    decoder_output += RegRegOpConstructor.subst(mcr15UserIop)
654    exec_output += PredOpExecute.subst(mcr15UserIop)
655
656    enterxCode = '''
657        NextThumb = true;
658        NextJazelle = true;
659    '''
660    enterxIop = InstObjParams("enterx", "Enterx", "PredOp",
661                              { "code": enterxCode,
662                                "predicate_test": predicateTest }, [])
663    header_output += BasicDeclare.subst(enterxIop)
664    decoder_output += BasicConstructor.subst(enterxIop)
665    exec_output += PredOpExecute.subst(enterxIop)
666
667    leavexCode = '''
668        NextThumb = true;
669        NextJazelle = false;
670    '''
671    leavexIop = InstObjParams("leavex", "Leavex", "PredOp",
672                              { "code": leavexCode,
673                                "predicate_test": predicateTest }, [])
674    header_output += BasicDeclare.subst(leavexIop)
675    decoder_output += BasicConstructor.subst(leavexIop)
676    exec_output += PredOpExecute.subst(leavexIop)
677
678    setendCode = '''
679        CPSR cpsr = Cpsr;
680        cpsr.e = imm;
681        Cpsr = cpsr;
682    '''
683    setendIop = InstObjParams("setend", "Setend", "ImmOp",
684                              { "code": setendCode,
685                                "predicate_test": predicateTest },
686                              ["IsSerializeAfter","IsNonSpeculative"])
687    header_output += ImmOpDeclare.subst(setendIop)
688    decoder_output += ImmOpConstructor.subst(setendIop)
689    exec_output += PredOpExecute.subst(setendIop)
690
691    clrexCode = '''
692        LLSCLock = 0;
693    '''
694    clrexIop = InstObjParams("clrex", "Clrex","PredOp",
695                             { "code": clrexCode,
696                               "predicate_test": predicateTest },[])
697    header_output += BasicDeclare.subst(clrexIop)
698    decoder_output += BasicConstructor.subst(clrexIop)
699    exec_output += PredOpExecute.subst(clrexIop)
700
701    isbCode = '''
702        fault = new FlushPipe;
703    '''
704    isbIop = InstObjParams("isb", "Isb", "PredOp",
705                             {"code": isbCode,
706                               "predicate_test": predicateTest},
707                                ['IsSerializeAfter'])
708    header_output += BasicDeclare.subst(isbIop)
709    decoder_output += BasicConstructor.subst(isbIop)
710    exec_output += PredOpExecute.subst(isbIop)
711
712    dsbCode = '''
713        fault = new FlushPipe;
714    '''
715    dsbIop = InstObjParams("dsb", "Dsb", "PredOp",
716                             {"code": dsbCode,
717                               "predicate_test": predicateTest},
718                              ['IsMemBarrier', 'IsSerializeAfter'])
719    header_output += BasicDeclare.subst(dsbIop)
720    decoder_output += BasicConstructor.subst(dsbIop)
721    exec_output += PredOpExecute.subst(dsbIop)
722
723    dmbCode = '''
724    '''
725    dmbIop = InstObjParams("dmb", "Dmb", "PredOp",
726                             {"code": dmbCode,
727                               "predicate_test": predicateTest},
728                               ['IsMemBarrier'])
729    header_output += BasicDeclare.subst(dmbIop)
730    decoder_output += BasicConstructor.subst(dmbIop)
731    exec_output += PredOpExecute.subst(dmbIop)
732
733    dbgCode = '''
734    '''
735    dbgIop = InstObjParams("dbg", "Dbg", "PredOp",
736                             {"code": dbgCode,
737                               "predicate_test": predicateTest})
738    header_output += BasicDeclare.subst(dbgIop)
739    decoder_output += BasicConstructor.subst(dbgIop)
740    exec_output += PredOpExecute.subst(dbgIop)
741
742    cpsCode = '''
743    uint32_t mode = bits(imm, 4, 0);
744    uint32_t f = bits(imm, 5);
745    uint32_t i = bits(imm, 6);
746    uint32_t a = bits(imm, 7);
747    bool setMode = bits(imm, 8);
748    bool enable = bits(imm, 9);
749    CPSR cpsr = Cpsr;
750    SCTLR sctlr = Sctlr;
751    if (cpsr.mode != MODE_USER) {
752        if (enable) {
753            if (f) cpsr.f = 0;
754            if (i) cpsr.i = 0;
755            if (a) cpsr.a = 0;
756        } else {
757            if (f && !sctlr.nmfi) cpsr.f = 1;
758            if (i) cpsr.i = 1;
759            if (a) cpsr.a = 1;
760        }
761        if (setMode) {
762            cpsr.mode = mode;
763        }
764    }
765    Cpsr = cpsr;
766    '''
767    cpsIop = InstObjParams("cps", "Cps", "ImmOp",
768                           { "code": cpsCode,
769                             "predicate_test": predicateTest },
770                           ["IsSerializeAfter","IsNonSpeculative"])
771    header_output += ImmOpDeclare.subst(cpsIop)
772    decoder_output += ImmOpConstructor.subst(cpsIop)
773    exec_output += PredOpExecute.subst(cpsIop)
774}};
775