data.isa revision 7185
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    instDecode = '''
40          case %(opcode)#x:
41            if (immShift) {
42                if (setCc) {
43                    return new %(className)sRegCc(machInst, %(dest)s, %(op1)s,
44                                                   rm, imm5, type);
45                } else {
46                    return new %(className)sReg(machInst, %(dest)s, %(op1)s,
47                                                 rm, imm5, type);
48                }
49            } else {
50                if (setCc) {
51                    return new %(className)sRegRegCc(machInst, %(dest)s,
52                                                      %(op1)s, rm, rs, type);
53                } else {
54                    return new %(className)sRegReg(machInst, %(dest)s,
55                                                    %(op1)s, rm, rs, type);
56                }
57            }
58            break;
59    '''
60
61    def instCode(opcode, mnem, dest="rd", op1="rn"):
62        global instDecode
63        return instDecode % { "className": mnem.capitalize(),
64                              "opcode": opcode,
65                              "dest": dest,
66                              "op1": op1 }
67
68    decode_block = '''
69    {
70        const bool immShift = (bits(machInst, 4) == 0);
71        const bool setCc = (bits(machInst, 20) == 1);
72        const uint32_t imm5 = bits(machInst, 11, 7);
73        const ArmShiftType type = (ArmShiftType)(uint32_t)bits(machInst, 6, 5);
74        const IntRegIndex rd = (IntRegIndex)(uint32_t)RD;
75        const IntRegIndex rn = (IntRegIndex)(uint32_t)RN;
76        const IntRegIndex rm = (IntRegIndex)(uint32_t)RM;
77        const IntRegIndex rs = (IntRegIndex)(uint32_t)RS;
78        switch (OPCODE) {
79    '''
80    decode_block += instCode(0x0, "and")
81    decode_block += instCode(0x1, "eor")
82    decode_block += instCode(0x2, "sub")
83    decode_block += instCode(0x3, "rsb")
84    decode_block += instCode(0x4, "add")
85    decode_block += instCode(0x5, "adc")
86    decode_block += instCode(0x6, "sbc")
87    decode_block += instCode(0x7, "rsc")
88    decode_block += instCode(0x8, "tst", dest="INTREG_ZERO")
89    decode_block += instCode(0x9, "teq", dest="INTREG_ZERO")
90    decode_block += instCode(0xa, "cmp", dest="INTREG_ZERO")
91    decode_block += instCode(0xb, "cmn", dest="INTREG_ZERO")
92    decode_block += instCode(0xc, "orr")
93    decode_block += instCode(0xd, "mov", op1="INTREG_ZERO")
94    decode_block += instCode(0xe, "bic")
95    decode_block += instCode(0xf, "mvn", op1="INTREG_ZERO")
96    decode_block += '''
97          default:
98            return new Unknown(machInst);
99        }
100    }
101    '''
102}};
103
104def format ArmDataProcImm() {{
105    instDecode = '''
106            if (setCc) {
107                return new %(className)sImmCc(machInst, %(dest)s, %(op1)s,
108                                               imm, rotC);
109            } else {
110                return new %(className)sImm(machInst, %(dest)s, %(op1)s,
111                                             imm, rotC);
112            }
113            break;
114    '''
115
116    def instCode(opcode, mnem, dest="rd", op1="rn"):
117        global instDecode
118        code = '''
119          case %(opcode)#x:
120        ''' + instDecode
121        return code % { "className": mnem.capitalize(),
122                        "opcode": opcode,
123                        "dest": dest,
124                        "op1": op1 }
125
126    def adrCode(opcode, mnem, dest="rd", op1="rn", add="1"):
127        global instDecode
128        code = '''
129          case %(opcode)#x:
130            if (rn == 0xf) {
131                return new AdrImm(machInst, %(dest)s, %(add)s,
132                                             imm, false);
133            } else {
134        ''' + instDecode + '''
135            }
136        '''
137        return code % { "className": mnem.capitalize(),
138                        "opcode": opcode,
139                        "dest": dest,
140                        "add": add,
141                        "op1": op1 }
142
143    decode_block = '''
144    {
145        const bool setCc = (bits(machInst, 20) == 1);
146        const uint32_t unrotated = bits(machInst, 7, 0);
147        const uint32_t rotation = (bits(machInst, 11, 8) << 1);
148        const bool rotC = (rotation != 0);
149        const uint32_t imm = rotate_imm(unrotated, rotation);
150        const IntRegIndex rd = (IntRegIndex)(uint32_t)RD;
151        const IntRegIndex rn = (IntRegIndex)(uint32_t)RN;
152        switch (OPCODE) {
153    '''
154    decode_block += instCode(0x0, "and")
155    decode_block += instCode(0x1, "eor")
156    decode_block += adrCode(0x2, "sub", add="(IntRegIndex)0")
157    decode_block += instCode(0x3, "rsb")
158    decode_block += adrCode(0x4, "add", add="(IntRegIndex)1")
159    decode_block += instCode(0x5, "adc")
160    decode_block += instCode(0x6, "sbc")
161    decode_block += instCode(0x7, "rsc")
162    decode_block += instCode(0x8, "tst", dest="INTREG_ZERO")
163    decode_block += instCode(0x9, "teq", dest="INTREG_ZERO")
164    decode_block += instCode(0xa, "cmp", dest="INTREG_ZERO")
165    decode_block += instCode(0xb, "cmn", dest="INTREG_ZERO")
166    decode_block += instCode(0xc, "orr")
167    decode_block += instCode(0xd, "mov", op1="INTREG_ZERO")
168    decode_block += instCode(0xe, "bic")
169    decode_block += instCode(0xf, "mvn", op1="INTREG_ZERO")
170    decode_block += '''
171          default:
172            return new Unknown(machInst);
173        }
174    }
175    '''
176}};
177
178def format Thumb16ShiftAddSubMoveCmp() {{
179    decode_block = '''
180    {
181        const uint32_t imm5 = bits(machInst, 10, 6);
182        const uint32_t imm3 = bits(machInst, 8, 6);
183        const uint32_t imm8 = bits(machInst, 7, 0);
184        const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 2, 0);
185        const IntRegIndex rd8 = (IntRegIndex)(uint32_t)bits(machInst, 10, 8);
186        const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 5, 3);
187        const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 8, 6);
188        switch (bits(machInst, 13, 11)) {
189          case 0x0: // lsl
190            return new MovRegCc(machInst, rd, INTREG_ZERO, rn, imm5, LSL);
191          case 0x1: // lsr
192            return new MovRegCc(machInst, rd, INTREG_ZERO, rn, imm5, LSR);
193          case 0x2: // asr
194            return new MovRegCc(machInst, rd, INTREG_ZERO, rn, imm5, ASR);
195          case 0x3:
196            switch (bits(machInst, 10, 9)) {
197              case 0x0:
198                return new AddRegCc(machInst, rd, rn, rm, 0, LSL);
199              case 0x1:
200                return new SubRegCc(machInst, rd, rn, rm, 0, LSL);
201              case 0x2:
202                return new AddImmCc(machInst, rd, rn, imm3, true);
203              case 0x3:
204                return new SubImmCc(machInst, rd, rn, imm3, true);
205            }
206          case 0x4:
207            return new MovImmCc(machInst, rd8, INTREG_ZERO, imm8, false);
208          case 0x5:
209            return new CmpImmCc(machInst, INTREG_ZERO, rd8, imm8, true);
210          case 0x6:
211            return new AddImmCc(machInst, rd8, rd8, imm8, true);
212          case 0x7:
213            return new SubImmCc(machInst, rd8, rd8, imm8, true);
214        }
215    }
216    '''
217}};
218
219def format Thumb16DataProcessing() {{
220    decode_block = '''
221    {
222        const IntRegIndex rdn = (IntRegIndex)(uint32_t)bits(machInst, 2, 0);
223        const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 5, 3);
224        switch (bits(machInst, 9, 6)) {
225          case 0x0:
226            return new AndRegCc(machInst, rdn, rdn, rm, 0, LSL);
227          case 0x1:
228            return new EorRegCc(machInst, rdn, rdn, rm, 0, LSL);
229          case 0x2: //lsl
230            return new MovRegRegCc(machInst, rdn, INTREG_ZERO, rdn, rm, LSL);
231          case 0x3: //lsr
232            return new MovRegRegCc(machInst, rdn, INTREG_ZERO, rdn, rm, LSR);
233          case 0x4: //asr
234            return new MovRegRegCc(machInst, rdn, INTREG_ZERO, rdn, rm, ASR);
235          case 0x5:
236            return new AdcRegCc(machInst, rdn, rdn, rm, 0, LSL);
237          case 0x6:
238            return new SbcRegCc(machInst, rdn, rdn, rm, 0, LSL);
239          case 0x7: // ror
240            return new MovRegRegCc(machInst, rdn, INTREG_ZERO, rdn, rm, ROR);
241          case 0x8:
242            return new TstRegCc(machInst, INTREG_ZERO, rdn, rm, 0, LSL);
243          case 0x9:
244            return new RsbImmCc(machInst, rdn, rm, 0, true);
245          case 0xa:
246            return new CmpRegCc(machInst, INTREG_ZERO, rdn, rm, 0, LSL);
247          case 0xb:
248            return new CmnRegCc(machInst, INTREG_ZERO, rdn, rm, 0, LSL);
249          case 0xc:
250            return new OrrRegCc(machInst, rdn, rdn, rm, 0, LSL);
251          case 0xd:
252            return new MulCc(machInst, rdn, rm, rdn);
253          case 0xe:
254            return new BicRegCc(machInst, rdn, rdn, rm, 0, LSL);
255          case 0xf:
256            return new MvnRegCc(machInst, rdn, INTREG_ZERO, rm, 0, LSL);
257        }
258    }
259    '''
260}};
261
262def format Thumb16SpecDataAndBx() {{
263    decode_block = '''
264    {
265        const IntRegIndex rdn =
266            (IntRegIndex)(uint32_t)(bits(machInst, 2, 0) |
267                                    (bits(machInst, 7) << 3));
268        const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 6, 3);
269        switch (bits(machInst, 9, 8)) {
270          case 0x0:
271            return new AddReg(machInst, rdn, rdn, rm, 0, LSL);
272          case 0x1:
273            return new CmpRegCc(machInst, INTREG_ZERO, rdn, rm, 0, LSL);
274          case 0x2:
275            return new MovReg(machInst, rdn, INTREG_ZERO, rm, 0, LSL);
276          case 0x3:
277            if (bits(machInst, 7) == 0) {
278                return new BxReg(machInst,
279                                 (IntRegIndex)(uint32_t)bits(machInst, 6, 3),
280                                 COND_UC);
281            } else {
282                return new BlxReg(machInst,
283                                  (IntRegIndex)(uint32_t)bits(machInst, 6, 3),
284                                  COND_UC);
285            }
286        }
287    }
288    '''
289}};
290
291def format Thumb16Adr() {{
292    decode_block = '''
293    {
294        const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 10, 8);
295        const uint32_t imm8 = bits(machInst, 7, 0) << 2;
296        return new AdrImm(machInst, rd, (IntRegIndex)1, imm8, false);
297    }
298    '''
299}};
300
301def format Thumb16AddSp() {{
302    decode_block = '''
303    {
304        const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 10, 8);
305        const uint32_t imm8 = bits(machInst, 7, 0) << 2;
306        return new AddImm(machInst, rd, INTREG_SP, imm8, true);
307    }
308    '''
309}};
310
311def format Thumb16Misc() {{
312    decode_block = '''
313    {
314        switch (bits(machInst, 11, 8)) {
315          case 0x0:
316            if (bits(machInst, 7)) {
317                return new SubImm(machInst, INTREG_SP, INTREG_SP,
318                                   bits(machInst, 6, 0) << 2, true);
319            } else {
320                return new AddImm(machInst, INTREG_SP, INTREG_SP,
321                                   bits(machInst, 6, 0) << 2, true);
322            }
323          case 0x1:
324            return new Cbz(machInst,
325                           (bits(machInst, 9) << 6) |
326                           (bits(machInst, 7, 3) << 1),
327                           (IntRegIndex)(uint32_t)bits(machInst, 2, 0));
328          case 0x2:
329            switch (bits(machInst, 7, 6)) {
330              case 0x0:
331                return new WarnUnimplemented("sxth", machInst);
332              case 0x1:
333                return new WarnUnimplemented("sxtb", machInst);
334              case 0x2:
335                return new WarnUnimplemented("uxth", machInst);
336              case 0x3:
337                return new WarnUnimplemented("uxtb", machInst);
338            }
339          case 0x3:
340            return new Cbz(machInst,
341                           (bits(machInst, 9) << 6) |
342                           (bits(machInst, 7, 3) << 1),
343                           (IntRegIndex)(uint32_t)bits(machInst, 2, 0));
344          case 0x4:
345          case 0x5:
346            return new WarnUnimplemented("push", machInst);
347          case 0x6:
348            {
349                const uint32_t opBits = bits(machInst, 7, 5);
350                if (opBits == 2) {
351                    return new WarnUnimplemented("setend", machInst);
352                } else if (opBits == 3) {
353                    return new WarnUnimplemented("cps", machInst);
354                }
355            }
356          case 0x9:
357            return new Cbnz(machInst,
358                            (bits(machInst, 9) << 6) |
359                            (bits(machInst, 7, 3) << 1),
360                            (IntRegIndex)(uint32_t)bits(machInst, 2, 0));
361          case 0xa:
362            switch (bits(machInst, 7, 5)) {
363              case 0x0:
364                return new WarnUnimplemented("rev", machInst);
365              case 0x1:
366                return new WarnUnimplemented("rev16", machInst);
367              case 0x3:
368                return new WarnUnimplemented("revsh", machInst);
369              default:
370                break;
371            }
372            break;
373          case 0xb:
374            return new Cbnz(machInst,
375                            (bits(machInst, 9) << 6) |
376                            (bits(machInst, 7, 3) << 1),
377                            (IntRegIndex)(uint32_t)bits(machInst, 2, 0));
378          case 0xc:
379          case 0xd:
380            return new WarnUnimplemented("pop", machInst);
381          case 0xe:
382            return new WarnUnimplemented("bkpt", machInst);
383          case 0xf:
384            if (bits(machInst, 3, 0) != 0)
385                return new WarnUnimplemented("it", machInst);
386            switch (bits(machInst, 7, 4)) {
387              case 0x0:
388                return new WarnUnimplemented("nop", machInst);
389              case 0x1:
390                return new WarnUnimplemented("yield", machInst);
391              case 0x2:
392                return new WarnUnimplemented("wfe", machInst);
393              case 0x3:
394                return new WarnUnimplemented("wfi", machInst);
395              case 0x4:
396                return new WarnUnimplemented("sev", machInst);
397              default:
398                return new WarnUnimplemented("unallocated_hint", machInst);
399            }
400          default:
401            break;
402        }
403        return new Unknown(machInst);
404    }
405    '''
406}};
407
408def format Thumb32DataProcModImm() {{
409
410    def decInst(mnem, dest="rd", op1="rn"):
411        return '''
412            if (s) {
413                return new %(mnem)sImmCc(machInst, %(dest)s,
414                                          %(op1)s, imm, rotC);
415            } else {
416                return new %(mnem)sImm(machInst, %(dest)s,
417                                        %(op1)s, imm, rotC);
418            }
419        ''' % {"mnem" : mnem, "dest" : dest, "op1" : op1}
420
421    decode_block = '''
422    {
423        const uint32_t op = bits(machInst, 24, 21);
424        const bool s = (bits(machInst, 20) == 1);
425        const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
426        const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
427        const uint32_t ctrlImm = bits(machInst.instBits, 26) << 3 |
428                                 bits(machInst, 14, 12);
429        const bool rotC = ctrlImm > 3;
430        const uint32_t dataImm = bits(machInst, 7, 0);
431        const uint32_t imm = modified_imm(ctrlImm, dataImm);
432        switch (op) {
433          case 0x0:
434            if (rd == INTREG_PC) {
435                %(tst)s
436            } else {
437                %(and)s
438            }
439          case 0x1:
440            %(bic)s
441          case 0x2:
442            if (rn == INTREG_PC) {
443                %(mov)s
444            } else {
445                %(orr)s
446            }
447          case 0x3:
448            if (rn == INTREG_PC) {
449                %(mvn)s
450            } else {
451                %(orn)s
452            }
453          case 0x4:
454            if (rd == INTREG_PC) {
455                %(teq)s
456            } else {
457                %(eor)s
458            }
459          case 0x8:
460            if (rd == INTREG_PC) {
461                %(cmn)s
462            } else {
463                %(add)s
464            }
465          case 0xa:
466            %(adc)s
467          case 0xb:
468            %(sbc)s
469          case 0xd:
470            if (rd == INTREG_PC) {
471                %(cmp)s
472            } else {
473                %(sub)s
474            }
475          case 0xe:
476            %(rsb)s
477          default:
478            return new Unknown(machInst);
479        }
480    }
481    ''' % {
482        "tst" : decInst("Tst", "INTREG_ZERO"),
483        "and" : decInst("And"),
484        "bic" : decInst("Bic"),
485        "mov" : decInst("Mov", op1="INTREG_ZERO"),
486        "orr" : decInst("Orr"),
487        "mvn" : decInst("Mvn", op1="INTREG_ZERO"),
488        "orn" : decInst("Orn"),
489        "teq" : decInst("Teq", dest="INTREG_ZERO"),
490        "eor" : decInst("Eor"),
491        "cmn" : decInst("Cmn", dest="INTREG_ZERO"),
492        "add" : decInst("Add"),
493        "adc" : decInst("Adc"),
494        "sbc" : decInst("Sbc"),
495        "cmp" : decInst("Cmp", dest="INTREG_ZERO"),
496        "sub" : decInst("Sub"),
497        "rsb" : decInst("Rsb")
498    }
499}};
500
501def format Thumb32DataProcPlainBin() {{
502    decode_block = '''
503    {
504        const uint32_t op = bits(machInst, 24, 20);
505        const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
506        const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
507        switch (op) {
508          case 0x0:
509            {
510                const uint32_t imm = bits(machInst, 7, 0) |
511                                     (bits(machInst, 14, 12) << 8) |
512                                     (bits(machInst, 26) << 11);
513                if (rn == 0xf) {
514                    return new AdrImm(machInst, rd, (IntRegIndex)1,
515                                      imm, false);
516                } else {
517                    return new AddImm(machInst, rd, rn, imm, true);
518                }
519            }
520          case 0x4:
521            {
522                const uint32_t imm = bits(machInst, 7, 0) |
523                                     (bits(machInst, 14, 12) << 8) |
524                                     (bits(machInst, 26) << 11) |
525                                     (bits(machInst, 19, 16) << 12);
526                return new MovImm(machInst, rd, INTREG_ZERO, imm, true);
527            }
528          case 0xa:
529            {
530                const uint32_t imm = bits(machInst, 7, 0) |
531                                     (bits(machInst, 14, 12) << 8) |
532                                     (bits(machInst, 26) << 11);
533                if (rn == 0xf) {
534                    return new AdrImm(machInst, rd, (IntRegIndex)0,
535                                      imm, false);
536                } else {
537                    return new SubImm(machInst, rd, rn, imm, true);
538                }
539            }
540          case 0xc:
541            {
542                const uint32_t imm = bits(machInst, 7, 0) |
543                                     (bits(machInst, 14, 12) << 8) |
544                                     (bits(machInst, 26) << 11) |
545                                     (bits(machInst, 19, 16) << 12);
546                return new MovtImm(machInst, rd, rd, imm, true);
547            }
548          case 0x12:
549            if (!(bits(machInst, 14, 12) || bits(machInst, 7, 6))) {
550                return new WarnUnimplemented("ssat16", machInst);
551            }
552            // Fall through on purpose...
553          case 0x10:
554            return new WarnUnimplemented("ssat", machInst);
555          case 0x14:
556            return new WarnUnimplemented("sbfx", machInst);
557          case 0x16:
558            if (rn == 0xf) {
559                return new WarnUnimplemented("bfc", machInst);
560            } else {
561                return new WarnUnimplemented("bfi", machInst);
562            }
563          case 0x1a:
564            if (!(bits(machInst, 14, 12) || bits(machInst, 7, 6))) {
565                return new WarnUnimplemented("usat16", machInst);
566            }
567            // Fall through on purpose...
568          case 0x18:
569            return new WarnUnimplemented("usat", machInst);
570          case 0x1c:
571            return new WarnUnimplemented("ubfx", machInst);
572          default:
573            return new Unknown(machInst);
574        }
575    }
576    '''
577}};
578
579def format Thumb32DataProcShiftReg() {{
580
581    def decInst(mnem, dest="rd", op1="rn"):
582        return '''
583            if (s) {
584                return new %(mnem)sRegCc(machInst, %(dest)s,
585                                          %(op1)s, rm, amt, type);
586            } else {
587                return new %(mnem)sReg(machInst, %(dest)s,
588                                        %(op1)s, rm, amt, type);
589            }
590        ''' % {"mnem" : mnem, "dest" : dest, "op1" : op1}
591
592    decode_block = '''
593    {
594        const uint32_t op = bits(machInst, 24, 21);
595        const bool s = (bits(machInst, 20) == 1);
596        const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
597        const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
598        const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
599        const uint32_t amt = (bits(machInst, 14, 12) << 2) |
600                              bits(machInst, 7, 6);
601        const ArmShiftType type = (ArmShiftType)(uint32_t)bits(machInst, 5, 4);
602        switch (op) {
603          case 0x0:
604            if (rd == INTREG_PC) {
605                %(tst)s
606            } else {
607                %(and)s
608            }
609          case 0x1:
610            %(bic)s
611          case 0x2:
612            if (rn == INTREG_PC) {
613                %(mov)s
614            } else {
615                %(orr)s
616            }
617          case 0x3:
618            if (rn == INTREG_PC) {
619                %(mvn)s
620            } else {
621                %(orn)s
622            }
623          case 0x4:
624            if (rd == INTREG_PC) {
625                %(teq)s
626            } else {
627                %(eor)s
628            }
629          case 0x6:
630            return new WarnUnimplemented("pkh", machInst);
631          case 0x8:
632            if (rd == INTREG_PC) {
633                %(cmn)s
634            } else {
635                %(add)s
636            }
637          case 0xa:
638            %(adc)s
639          case 0xb:
640            %(sbc)s
641          case 0xd:
642            if (rd == INTREG_PC) {
643                %(cmp)s
644            } else {
645                %(sub)s
646            }
647          case 0xe:
648            %(rsb)s
649          default:
650            return new Unknown(machInst);
651        }
652    }
653    ''' % {
654        "tst" : decInst("Tst", "INTREG_ZERO"),
655        "and" : decInst("And"),
656        "bic" : decInst("Bic"),
657        "mov" : decInst("Mov", op1="INTREG_ZERO"),
658        "orr" : decInst("Orr"),
659        "mvn" : decInst("Mvn", op1="INTREG_ZERO"),
660        "orn" : decInst("Orn"),
661        "teq" : decInst("Teq", "INTREG_ZERO"),
662        "eor" : decInst("Eor"),
663        "cmn" : decInst("Cmn", "INTREG_ZERO"),
664        "add" : decInst("Add"),
665        "adc" : decInst("Adc"),
666        "sbc" : decInst("Sbc"),
667        "cmp" : decInst("Cmp", "INTREG_ZERO"),
668        "sub" : decInst("Sub"),
669        "rsb" : decInst("Rsb")
670    }
671}};
672