data.isa revision 7188:1310866e4ed5
1// Copyright (c) 2010 ARM Limited
2// All rights reserved
3//
4// The license below extends only to copyright in the software and shall
5// not be construed as granting a license to any other intellectual
6// property including but not limited to intellectual property relating
7// to a hardware implementation of the functionality of the software
8// licensed hereunder.  You may use the software subject to the license
9// terms below provided that you ensure that this notice is replicated
10// unmodified and in its entirety in all distributions of the software,
11// modified or unmodified, in source code or in binary form.
12//
13// Redistribution and use in source and binary forms, with or without
14// modification, are permitted provided that the following conditions are
15// met: redistributions of source code must retain the above copyright
16// notice, this list of conditions and the following disclaimer;
17// redistributions in binary form must reproduce the above copyright
18// notice, this list of conditions and the following disclaimer in the
19// documentation and/or other materials provided with the distribution;
20// neither the name of the copyright holders nor the names of its
21// contributors may be used to endorse or promote products derived from
22// this software without specific prior written permission.
23//
24// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
25// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
26// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
27// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
28// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
29// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
30// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
31// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
32// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
33// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
34// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35//
36// Authors: Gabe Black
37
38def format ArmDataProcReg() {{
39    pclr = '''
40        return new %(className)ssRegPclr(machInst, %(dest)s,
41                                        %(op1)s, rm, imm5,
42                                        type);
43    '''
44    instDecode = '''
45          case %(opcode)#x:
46            if (immShift) {
47                if (setCc) {
48                    if (%(dest)s == INTREG_PC) {
49                        %(pclr)s
50                    } else {
51                        return new %(className)sRegCc(machInst, %(dest)s,
52                                                      %(op1)s, rm, imm5, type);
53                    }
54                } else {
55                    return new %(className)sReg(machInst, %(dest)s, %(op1)s,
56                                                 rm, imm5, type);
57                }
58            } else {
59                if (setCc) {
60                    return new %(className)sRegRegCc(machInst, %(dest)s,
61                                                      %(op1)s, rm, rs, type);
62                } else {
63                    return new %(className)sRegReg(machInst, %(dest)s,
64                                                    %(op1)s, rm, rs, type);
65                }
66            }
67            break;
68    '''
69
70    def instCode(opcode, mnem, useDest = True, useOp1 = True):
71        global pclr
72        if useDest:
73            dest = "rd"
74        else:
75            dest = "INTREG_ZERO"
76        if useOp1:
77            op1 = "rn"
78        else:
79            op1 = "INTREG_ZERO"
80        global instDecode, pclrCode
81        substDict = { "className": mnem.capitalize(),
82                      "opcode": opcode,
83                      "dest": dest,
84                      "op1": op1 }
85        if useDest:
86            substDict["pclr"] = pclr % substDict
87        else:
88            substDict["pclr"] = ""
89        return instDecode % substDict
90
91    decode_block = '''
92    {
93        const bool immShift = (bits(machInst, 4) == 0);
94        const bool setCc = (bits(machInst, 20) == 1);
95        const uint32_t imm5 = bits(machInst, 11, 7);
96        const ArmShiftType type = (ArmShiftType)(uint32_t)bits(machInst, 6, 5);
97        const IntRegIndex rd = (IntRegIndex)(uint32_t)RD;
98        const IntRegIndex rn = (IntRegIndex)(uint32_t)RN;
99        const IntRegIndex rm = (IntRegIndex)(uint32_t)RM;
100        const IntRegIndex rs = (IntRegIndex)(uint32_t)RS;
101        switch (OPCODE) {
102    '''
103    decode_block += instCode(0x0, "and")
104    decode_block += instCode(0x1, "eor")
105    decode_block += instCode(0x2, "sub")
106    decode_block += instCode(0x3, "rsb")
107    decode_block += instCode(0x4, "add")
108    decode_block += instCode(0x5, "adc")
109    decode_block += instCode(0x6, "sbc")
110    decode_block += instCode(0x7, "rsc")
111    decode_block += instCode(0x8, "tst", useDest = False)
112    decode_block += instCode(0x9, "teq", useDest = False)
113    decode_block += instCode(0xa, "cmp", useDest = False)
114    decode_block += instCode(0xb, "cmn", useDest = False)
115    decode_block += instCode(0xc, "orr")
116    decode_block += instCode(0xd, "mov", useOp1 = False)
117    decode_block += instCode(0xe, "bic")
118    decode_block += instCode(0xf, "mvn", useOp1 = False)
119    decode_block += '''
120          default:
121            return new Unknown(machInst);
122        }
123    }
124    '''
125}};
126
127def format ArmDataProcImm() {{
128    pclr = '''
129        return new %(className)ssImmPclr(machInst, %(dest)s,
130                                        %(op1)s, imm, false);
131    '''
132    adr = '''
133        return new AdrImm(machInst, %(dest)s, %(add)s,
134                                     imm, false);
135    '''
136    instDecode = '''
137          case %(opcode)#x:
138            if (setCc) {
139                if (%(pclrInst)s && %(dest)s == INTREG_PC) {
140                    %(pclr)s
141                } else {
142                    return new %(className)sImmCc(machInst, %(dest)s, %(op1)s,
143                                                   imm, rotC);
144                }
145            } else {
146                if (%(adrInst)s && %(op1)s == INTREG_PC) {
147                    %(adr)s
148                } else {
149                    return new %(className)sImm(machInst, %(dest)s, %(op1)s,
150                                                 imm, rotC);
151                }
152            }
153            break;
154    '''
155
156    def instCode(opcode, mnem, useDest = True, useOp1 = True):
157        global instDecode, pclr, adr
158        if useDest:
159            dest = "rd"
160        else:
161            dest = "INTREG_ZERO"
162        if useOp1:
163            op1 = "rn"
164        else:
165            op1 = "INTREG_ZERO"
166        substDict = { "className": mnem.capitalize(),
167                      "opcode": opcode,
168                      "dest": dest,
169                      "op1": op1,
170                      "adr": "",
171                      "adrInst": "false" }
172        if useDest:
173            substDict["pclrInst"] = "true"
174            substDict["pclr"] = pclr % substDict
175        else:
176            substDict["pclrInst"] = "false"
177            substDict["pclr"] = ""
178        return instDecode % substDict
179
180    def adrCode(opcode, mnem, add="1"):
181        global instDecode, pclr, adr
182        substDict = { "className": mnem.capitalize(),
183                      "opcode": opcode,
184                      "dest": "rd",
185                      "op1": "rn",
186                      "add": add,
187                      "pclrInst": "true",
188                      "adrInst": "true" }
189        substDict["pclr"] = pclr % substDict
190        substDict["adr"] = adr % substDict
191        return instDecode % substDict
192
193    decode_block = '''
194    {
195        const bool setCc = (bits(machInst, 20) == 1);
196        const uint32_t unrotated = bits(machInst, 7, 0);
197        const uint32_t rotation = (bits(machInst, 11, 8) << 1);
198        const bool rotC = (rotation != 0);
199        const uint32_t imm = rotate_imm(unrotated, rotation);
200        const IntRegIndex rd = (IntRegIndex)(uint32_t)RD;
201        const IntRegIndex rn = (IntRegIndex)(uint32_t)RN;
202        switch (OPCODE) {
203    '''
204    decode_block += instCode(0x0, "and")
205    decode_block += instCode(0x1, "eor")
206    decode_block += adrCode(0x2, "sub", add="(IntRegIndex)0")
207    decode_block += instCode(0x3, "rsb")
208    decode_block += adrCode(0x4, "add", add="(IntRegIndex)1")
209    decode_block += instCode(0x5, "adc")
210    decode_block += instCode(0x6, "sbc")
211    decode_block += instCode(0x7, "rsc")
212    decode_block += instCode(0x8, "tst", useDest = False)
213    decode_block += instCode(0x9, "teq", useDest = False)
214    decode_block += instCode(0xa, "cmp", useDest = False)
215    decode_block += instCode(0xb, "cmn", useDest = False)
216    decode_block += instCode(0xc, "orr")
217    decode_block += instCode(0xd, "mov", useOp1 = False)
218    decode_block += instCode(0xe, "bic")
219    decode_block += instCode(0xf, "mvn", useOp1 = False)
220    decode_block += '''
221          default:
222            return new Unknown(machInst);
223        }
224    }
225    '''
226}};
227
228def format Thumb16ShiftAddSubMoveCmp() {{
229    decode_block = '''
230    {
231        const uint32_t imm5 = bits(machInst, 10, 6);
232        const uint32_t imm3 = bits(machInst, 8, 6);
233        const uint32_t imm8 = bits(machInst, 7, 0);
234        const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 2, 0);
235        const IntRegIndex rd8 = (IntRegIndex)(uint32_t)bits(machInst, 10, 8);
236        const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 5, 3);
237        const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 8, 6);
238        switch (bits(machInst, 13, 11)) {
239          case 0x0: // lsl
240            return new MovRegCc(machInst, rd, INTREG_ZERO, rn, imm5, LSL);
241          case 0x1: // lsr
242            return new MovRegCc(machInst, rd, INTREG_ZERO, rn, imm5, LSR);
243          case 0x2: // asr
244            return new MovRegCc(machInst, rd, INTREG_ZERO, rn, imm5, ASR);
245          case 0x3:
246            switch (bits(machInst, 10, 9)) {
247              case 0x0:
248                return new AddRegCc(machInst, rd, rn, rm, 0, LSL);
249              case 0x1:
250                return new SubRegCc(machInst, rd, rn, rm, 0, LSL);
251              case 0x2:
252                return new AddImmCc(machInst, rd, rn, imm3, true);
253              case 0x3:
254                return new SubImmCc(machInst, rd, rn, imm3, true);
255            }
256          case 0x4:
257            return new MovImmCc(machInst, rd8, INTREG_ZERO, imm8, false);
258          case 0x5:
259            return new CmpImmCc(machInst, INTREG_ZERO, rd8, imm8, true);
260          case 0x6:
261            return new AddImmCc(machInst, rd8, rd8, imm8, true);
262          case 0x7:
263            return new SubImmCc(machInst, rd8, rd8, imm8, true);
264        }
265    }
266    '''
267}};
268
269def format Thumb16DataProcessing() {{
270    decode_block = '''
271    {
272        const IntRegIndex rdn = (IntRegIndex)(uint32_t)bits(machInst, 2, 0);
273        const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 5, 3);
274        switch (bits(machInst, 9, 6)) {
275          case 0x0:
276            return new AndRegCc(machInst, rdn, rdn, rm, 0, LSL);
277          case 0x1:
278            return new EorRegCc(machInst, rdn, rdn, rm, 0, LSL);
279          case 0x2: //lsl
280            return new MovRegRegCc(machInst, rdn, INTREG_ZERO, rdn, rm, LSL);
281          case 0x3: //lsr
282            return new MovRegRegCc(machInst, rdn, INTREG_ZERO, rdn, rm, LSR);
283          case 0x4: //asr
284            return new MovRegRegCc(machInst, rdn, INTREG_ZERO, rdn, rm, ASR);
285          case 0x5:
286            return new AdcRegCc(machInst, rdn, rdn, rm, 0, LSL);
287          case 0x6:
288            return new SbcRegCc(machInst, rdn, rdn, rm, 0, LSL);
289          case 0x7: // ror
290            return new MovRegRegCc(machInst, rdn, INTREG_ZERO, rdn, rm, ROR);
291          case 0x8:
292            return new TstRegCc(machInst, INTREG_ZERO, rdn, rm, 0, LSL);
293          case 0x9:
294            return new RsbImmCc(machInst, rdn, rm, 0, true);
295          case 0xa:
296            return new CmpRegCc(machInst, INTREG_ZERO, rdn, rm, 0, LSL);
297          case 0xb:
298            return new CmnRegCc(machInst, INTREG_ZERO, rdn, rm, 0, LSL);
299          case 0xc:
300            return new OrrRegCc(machInst, rdn, rdn, rm, 0, LSL);
301          case 0xd:
302            return new MulCc(machInst, rdn, rm, rdn);
303          case 0xe:
304            return new BicRegCc(machInst, rdn, rdn, rm, 0, LSL);
305          case 0xf:
306            return new MvnRegCc(machInst, rdn, INTREG_ZERO, rm, 0, LSL);
307        }
308    }
309    '''
310}};
311
312def format Thumb16SpecDataAndBx() {{
313    decode_block = '''
314    {
315        const IntRegIndex rdn =
316            (IntRegIndex)(uint32_t)(bits(machInst, 2, 0) |
317                                    (bits(machInst, 7) << 3));
318        const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 6, 3);
319        switch (bits(machInst, 9, 8)) {
320          case 0x0:
321            return new AddReg(machInst, rdn, rdn, rm, 0, LSL);
322          case 0x1:
323            return new CmpRegCc(machInst, INTREG_ZERO, rdn, rm, 0, LSL);
324          case 0x2:
325            return new MovReg(machInst, rdn, INTREG_ZERO, rm, 0, LSL);
326          case 0x3:
327            if (bits(machInst, 7) == 0) {
328                return new BxReg(machInst,
329                                 (IntRegIndex)(uint32_t)bits(machInst, 6, 3),
330                                 COND_UC);
331            } else {
332                return new BlxReg(machInst,
333                                  (IntRegIndex)(uint32_t)bits(machInst, 6, 3),
334                                  COND_UC);
335            }
336        }
337    }
338    '''
339}};
340
341def format Thumb16Adr() {{
342    decode_block = '''
343    {
344        const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 10, 8);
345        const uint32_t imm8 = bits(machInst, 7, 0) << 2;
346        return new AdrImm(machInst, rd, (IntRegIndex)1, imm8, false);
347    }
348    '''
349}};
350
351def format Thumb16AddSp() {{
352    decode_block = '''
353    {
354        const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 10, 8);
355        const uint32_t imm8 = bits(machInst, 7, 0) << 2;
356        return new AddImm(machInst, rd, INTREG_SP, imm8, true);
357    }
358    '''
359}};
360
361def format Thumb16Misc() {{
362    decode_block = '''
363    {
364        switch (bits(machInst, 11, 8)) {
365          case 0x0:
366            if (bits(machInst, 7)) {
367                return new SubImm(machInst, INTREG_SP, INTREG_SP,
368                                   bits(machInst, 6, 0) << 2, true);
369            } else {
370                return new AddImm(machInst, INTREG_SP, INTREG_SP,
371                                   bits(machInst, 6, 0) << 2, true);
372            }
373          case 0x1:
374            return new Cbz(machInst,
375                           (bits(machInst, 9) << 6) |
376                           (bits(machInst, 7, 3) << 1),
377                           (IntRegIndex)(uint32_t)bits(machInst, 2, 0));
378          case 0x2:
379            switch (bits(machInst, 7, 6)) {
380              case 0x0:
381                return new WarnUnimplemented("sxth", machInst);
382              case 0x1:
383                return new WarnUnimplemented("sxtb", machInst);
384              case 0x2:
385                return new WarnUnimplemented("uxth", machInst);
386              case 0x3:
387                return new WarnUnimplemented("uxtb", machInst);
388            }
389          case 0x3:
390            return new Cbz(machInst,
391                           (bits(machInst, 9) << 6) |
392                           (bits(machInst, 7, 3) << 1),
393                           (IntRegIndex)(uint32_t)bits(machInst, 2, 0));
394          case 0x4:
395          case 0x5:
396            return new WarnUnimplemented("push", machInst);
397          case 0x6:
398            {
399                const uint32_t opBits = bits(machInst, 7, 5);
400                if (opBits == 2) {
401                    return new WarnUnimplemented("setend", machInst);
402                } else if (opBits == 3) {
403                    return new WarnUnimplemented("cps", machInst);
404                }
405            }
406          case 0x9:
407            return new Cbnz(machInst,
408                            (bits(machInst, 9) << 6) |
409                            (bits(machInst, 7, 3) << 1),
410                            (IntRegIndex)(uint32_t)bits(machInst, 2, 0));
411          case 0xa:
412            switch (bits(machInst, 7, 5)) {
413              case 0x0:
414                return new WarnUnimplemented("rev", machInst);
415              case 0x1:
416                return new WarnUnimplemented("rev16", machInst);
417              case 0x3:
418                return new WarnUnimplemented("revsh", machInst);
419              default:
420                break;
421            }
422            break;
423          case 0xb:
424            return new Cbnz(machInst,
425                            (bits(machInst, 9) << 6) |
426                            (bits(machInst, 7, 3) << 1),
427                            (IntRegIndex)(uint32_t)bits(machInst, 2, 0));
428          case 0xc:
429          case 0xd:
430            return new WarnUnimplemented("pop", machInst);
431          case 0xe:
432            return new WarnUnimplemented("bkpt", machInst);
433          case 0xf:
434            if (bits(machInst, 3, 0) != 0)
435                return new WarnUnimplemented("it", machInst);
436            switch (bits(machInst, 7, 4)) {
437              case 0x0:
438                return new WarnUnimplemented("nop", machInst);
439              case 0x1:
440                return new WarnUnimplemented("yield", machInst);
441              case 0x2:
442                return new WarnUnimplemented("wfe", machInst);
443              case 0x3:
444                return new WarnUnimplemented("wfi", machInst);
445              case 0x4:
446                return new WarnUnimplemented("sev", machInst);
447              default:
448                return new WarnUnimplemented("unallocated_hint", machInst);
449            }
450          default:
451            break;
452        }
453        return new Unknown(machInst);
454    }
455    '''
456}};
457
458def format Thumb32DataProcModImm() {{
459
460    def decInst(mnem, dest="rd", op1="rn"):
461        return '''
462            if (s) {
463                return new %(mnem)sImmCc(machInst, %(dest)s,
464                                          %(op1)s, imm, rotC);
465            } else {
466                return new %(mnem)sImm(machInst, %(dest)s,
467                                        %(op1)s, imm, rotC);
468            }
469        ''' % {"mnem" : mnem, "dest" : dest, "op1" : op1}
470
471    decode_block = '''
472    {
473        const uint32_t op = bits(machInst, 24, 21);
474        const bool s = (bits(machInst, 20) == 1);
475        const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
476        const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
477        const uint32_t ctrlImm = bits(machInst.instBits, 26) << 3 |
478                                 bits(machInst, 14, 12);
479        const bool rotC = ctrlImm > 3;
480        const uint32_t dataImm = bits(machInst, 7, 0);
481        const uint32_t imm = modified_imm(ctrlImm, dataImm);
482        switch (op) {
483          case 0x0:
484            if (rd == INTREG_PC) {
485                %(tst)s
486            } else {
487                %(and)s
488            }
489          case 0x1:
490            %(bic)s
491          case 0x2:
492            if (rn == INTREG_PC) {
493                %(mov)s
494            } else {
495                %(orr)s
496            }
497          case 0x3:
498            if (rn == INTREG_PC) {
499                %(mvn)s
500            } else {
501                %(orn)s
502            }
503          case 0x4:
504            if (rd == INTREG_PC) {
505                %(teq)s
506            } else {
507                %(eor)s
508            }
509          case 0x8:
510            if (rd == INTREG_PC) {
511                %(cmn)s
512            } else {
513                %(add)s
514            }
515          case 0xa:
516            %(adc)s
517          case 0xb:
518            %(sbc)s
519          case 0xd:
520            if (rd == INTREG_PC) {
521                %(cmp)s
522            } else {
523                %(sub)s
524            }
525          case 0xe:
526            %(rsb)s
527          default:
528            return new Unknown(machInst);
529        }
530    }
531    ''' % {
532        "tst" : decInst("Tst", "INTREG_ZERO"),
533        "and" : decInst("And"),
534        "bic" : decInst("Bic"),
535        "mov" : decInst("Mov", op1="INTREG_ZERO"),
536        "orr" : decInst("Orr"),
537        "mvn" : decInst("Mvn", op1="INTREG_ZERO"),
538        "orn" : decInst("Orn"),
539        "teq" : decInst("Teq", dest="INTREG_ZERO"),
540        "eor" : decInst("Eor"),
541        "cmn" : decInst("Cmn", dest="INTREG_ZERO"),
542        "add" : decInst("Add"),
543        "adc" : decInst("Adc"),
544        "sbc" : decInst("Sbc"),
545        "cmp" : decInst("Cmp", dest="INTREG_ZERO"),
546        "sub" : decInst("Sub"),
547        "rsb" : decInst("Rsb")
548    }
549}};
550
551def format Thumb32DataProcPlainBin() {{
552    decode_block = '''
553    {
554        const uint32_t op = bits(machInst, 24, 20);
555        const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
556        const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
557        switch (op) {
558          case 0x0:
559            {
560                const uint32_t imm = bits(machInst, 7, 0) |
561                                     (bits(machInst, 14, 12) << 8) |
562                                     (bits(machInst, 26) << 11);
563                if (rn == 0xf) {
564                    return new AdrImm(machInst, rd, (IntRegIndex)1,
565                                      imm, false);
566                } else {
567                    return new AddImm(machInst, rd, rn, imm, true);
568                }
569            }
570          case 0x4:
571            {
572                const uint32_t imm = bits(machInst, 7, 0) |
573                                     (bits(machInst, 14, 12) << 8) |
574                                     (bits(machInst, 26) << 11) |
575                                     (bits(machInst, 19, 16) << 12);
576                return new MovImm(machInst, rd, INTREG_ZERO, imm, true);
577            }
578          case 0xa:
579            {
580                const uint32_t imm = bits(machInst, 7, 0) |
581                                     (bits(machInst, 14, 12) << 8) |
582                                     (bits(machInst, 26) << 11);
583                if (rn == 0xf) {
584                    return new AdrImm(machInst, rd, (IntRegIndex)0,
585                                      imm, false);
586                } else {
587                    return new SubImm(machInst, rd, rn, imm, true);
588                }
589            }
590          case 0xc:
591            {
592                const uint32_t imm = bits(machInst, 7, 0) |
593                                     (bits(machInst, 14, 12) << 8) |
594                                     (bits(machInst, 26) << 11) |
595                                     (bits(machInst, 19, 16) << 12);
596                return new MovtImm(machInst, rd, rd, imm, true);
597            }
598          case 0x12:
599            if (!(bits(machInst, 14, 12) || bits(machInst, 7, 6))) {
600                return new WarnUnimplemented("ssat16", machInst);
601            }
602            // Fall through on purpose...
603          case 0x10:
604            return new WarnUnimplemented("ssat", machInst);
605          case 0x14:
606            return new WarnUnimplemented("sbfx", machInst);
607          case 0x16:
608            if (rn == 0xf) {
609                return new WarnUnimplemented("bfc", machInst);
610            } else {
611                return new WarnUnimplemented("bfi", machInst);
612            }
613          case 0x1a:
614            if (!(bits(machInst, 14, 12) || bits(machInst, 7, 6))) {
615                return new WarnUnimplemented("usat16", machInst);
616            }
617            // Fall through on purpose...
618          case 0x18:
619            return new WarnUnimplemented("usat", machInst);
620          case 0x1c:
621            return new WarnUnimplemented("ubfx", machInst);
622          default:
623            return new Unknown(machInst);
624        }
625    }
626    '''
627}};
628
629def format Thumb32DataProcShiftReg() {{
630
631    def decInst(mnem, dest="rd", op1="rn"):
632        return '''
633            if (s) {
634                return new %(mnem)sRegCc(machInst, %(dest)s,
635                                          %(op1)s, rm, amt, type);
636            } else {
637                return new %(mnem)sReg(machInst, %(dest)s,
638                                        %(op1)s, rm, amt, type);
639            }
640        ''' % {"mnem" : mnem, "dest" : dest, "op1" : op1}
641
642    decode_block = '''
643    {
644        const uint32_t op = bits(machInst, 24, 21);
645        const bool s = (bits(machInst, 20) == 1);
646        const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
647        const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
648        const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
649        const uint32_t amt = (bits(machInst, 14, 12) << 2) |
650                              bits(machInst, 7, 6);
651        const ArmShiftType type = (ArmShiftType)(uint32_t)bits(machInst, 5, 4);
652        switch (op) {
653          case 0x0:
654            if (rd == INTREG_PC) {
655                %(tst)s
656            } else {
657                %(and)s
658            }
659          case 0x1:
660            %(bic)s
661          case 0x2:
662            if (rn == INTREG_PC) {
663                %(mov)s
664            } else {
665                %(orr)s
666            }
667          case 0x3:
668            if (rn == INTREG_PC) {
669                %(mvn)s
670            } else {
671                %(orn)s
672            }
673          case 0x4:
674            if (rd == INTREG_PC) {
675                %(teq)s
676            } else {
677                %(eor)s
678            }
679          case 0x6:
680            return new WarnUnimplemented("pkh", machInst);
681          case 0x8:
682            if (rd == INTREG_PC) {
683                %(cmn)s
684            } else {
685                %(add)s
686            }
687          case 0xa:
688            %(adc)s
689          case 0xb:
690            %(sbc)s
691          case 0xd:
692            if (rd == INTREG_PC) {
693                %(cmp)s
694            } else {
695                %(sub)s
696            }
697          case 0xe:
698            %(rsb)s
699          default:
700            return new Unknown(machInst);
701        }
702    }
703    ''' % {
704        "tst" : decInst("Tst", "INTREG_ZERO"),
705        "and" : decInst("And"),
706        "bic" : decInst("Bic"),
707        "mov" : decInst("Mov", op1="INTREG_ZERO"),
708        "orr" : decInst("Orr"),
709        "mvn" : decInst("Mvn", op1="INTREG_ZERO"),
710        "orn" : decInst("Orn"),
711        "teq" : decInst("Teq", "INTREG_ZERO"),
712        "eor" : decInst("Eor"),
713        "cmn" : decInst("Cmn", "INTREG_ZERO"),
714        "add" : decInst("Add"),
715        "adc" : decInst("Adc"),
716        "sbc" : decInst("Sbc"),
717        "cmp" : decInst("Cmp", "INTREG_ZERO"),
718        "sub" : decInst("Sub"),
719        "rsb" : decInst("Rsb")
720    }
721}};
722