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