data.isa revision 7231:a9fa4128c5c9
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 ArmPackUnpackSatReverse() {{
128    decode_block = '''
129    {
130        const uint32_t op1 = bits(machInst, 22, 20);
131        const uint32_t a = bits(machInst, 19, 16);
132        const uint32_t op2 = bits(machInst, 7, 5);
133        if (bits(op2, 0) == 0) {
134            const IntRegIndex rn =
135                (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
136            const IntRegIndex rd =
137                (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
138            const uint32_t satImm = bits(machInst, 20, 16);
139            const uint32_t imm = bits(machInst, 11, 7);
140            const ArmShiftType type =
141                (ArmShiftType)(uint32_t)bits(machInst, 6, 5);
142            if (op1 == 0) {
143                return new WarnUnimplemented("pkh", machInst);
144            } else if (bits(op1, 2, 1) == 1) {
145                return new Ssat(machInst, rd, satImm + 1, rn, imm, type);
146            } else if (bits(op1, 2, 1) == 3) {
147                return new Usat(machInst, rd, satImm, rn, imm, type);
148            }
149            return new Unknown(machInst);
150        }
151        switch (op1) {
152          case 0x0:
153            if (op2 == 0x3) {
154                if (a == 0xf) {
155                    return new WarnUnimplemented("sxtb16", machInst);
156                } else {
157                    return new WarnUnimplemented("sxtab16", machInst);
158                }
159            } else if (op2 == 0x5) {
160                return new WarnUnimplemented("sel", machInst);
161            }
162            break;
163          case 0x2:
164            if (op2 == 0x1) {
165                const IntRegIndex rn =
166                    (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
167                const IntRegIndex rd =
168                    (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
169                const uint32_t satImm = bits(machInst, 20, 16);
170                return new Ssat16(machInst, rd, satImm + 1, rn);
171            } else if (op2 == 0x3) {
172                if (a == 0xf) {
173                    return new WarnUnimplemented("sxtb", machInst);
174                } else {
175                    return new WarnUnimplemented("sxtab", machInst);
176                }
177            }
178            break;
179          case 0x3:
180            if (op2 == 0x1) {
181                IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
182                IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
183                return new Rev(machInst, rd, rm);
184            } else if (op2 == 0x3) {
185                if (a == 0xf) {
186                    return new WarnUnimplemented("sxth", machInst);
187                } else {
188                    return new WarnUnimplemented("sxtah", machInst);
189                }
190            } else if (op2 == 0x5) {
191                IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
192                IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
193                return new Rev16(machInst, rd, rm);
194            }
195            break;
196          case 0x4:
197            if (op2 == 0x3) {
198                if (a == 0xf) {
199                    return new WarnUnimplemented("uxtb16", machInst);
200                } else {
201                    return new WarnUnimplemented("uxtab16", machInst);
202                }
203            }
204            break;
205          case 0x6:
206            if (op2 == 0x1) {
207                const IntRegIndex rn =
208                    (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
209                const IntRegIndex rd =
210                    (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
211                const uint32_t satImm = bits(machInst, 20, 16);
212                return new Usat16(machInst, rd, satImm, rn);
213            } else if (op2 == 0x3) {
214                if (a == 0xf) {
215                    return new WarnUnimplemented("uxtb", machInst);
216                } else {
217                    return new WarnUnimplemented("uxtab", machInst);
218                }
219            }
220            break;
221          case 0x7:
222            if (op2 == 0x1) {
223                return new WarnUnimplemented("rbit", machInst);
224            } else if (op2 == 0x3) {
225                if (a == 0xf) {
226                    return new WarnUnimplemented("uxth", machInst);
227                } else {
228                    return new WarnUnimplemented("uxtah", machInst);
229                }
230            } else if (op2 == 0x5) {
231                IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
232                IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
233                return new Revsh(machInst, rd, rm);
234            }
235            break;
236        }
237        return new Unknown(machInst);
238    }
239    '''
240}};
241
242def format ArmParallelAddSubtract() {{
243    decode_block='''
244    {
245        const uint32_t op1 = bits(machInst, 21, 20);
246        const uint32_t op2 = bits(machInst, 7, 5);
247        const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
248        const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
249        const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
250        if (bits(machInst, 22) == 0) {
251            switch (op1) {
252              case 0x1:
253                switch (op2) {
254                  case 0x0:
255                    return new Sadd16RegCc(machInst, rd, rn, rm, 0, LSL);
256                  case 0x1:
257                    return new SasxRegCc(machInst, rd, rn, rm, 0, LSL);
258                  case 0x2:
259                    return new SsaxRegCc(machInst, rd, rn, rm, 0, LSL);
260                  case 0x3:
261                    return new Ssub16RegCc(machInst, rd, rn, rm, 0, LSL);
262                  case 0x4:
263                    return new Sadd8RegCc(machInst, rd, rn, rm, 0, LSL);
264                  case 0x7:
265                    return new Ssub8RegCc(machInst, rd, rn, rm, 0, LSL);
266                }
267                break;
268              case 0x2:
269                switch (op2) {
270                  case 0x0:
271                    return new Qadd16Reg(machInst, rd, rn, rm, 0, LSL);
272                  case 0x1:
273                    return new QasxReg(machInst, rd, rn, rm, 0, LSL);
274                  case 0x2:
275                    return new QsaxReg(machInst, rd, rn, rm, 0, LSL);
276                  case 0x3:
277                    return new Qsub16Reg(machInst, rd, rn, rm, 0, LSL);
278                  case 0x4:
279                    return new Qadd8Reg(machInst, rd, rn, rm, 0, LSL);
280                  case 0x7:
281                    return new Qsub8Reg(machInst, rd, rn, rm, 0, LSL);
282                }
283                break;
284              case 0x3:
285                switch (op2) {
286                  case 0x0:
287                    return new Shadd16Reg(machInst, rd, rn, rm, 0, LSL);
288                  case 0x1:
289                    return new ShasxReg(machInst, rd, rn, rm, 0, LSL);
290                  case 0x2:
291                    return new ShsaxReg(machInst, rd, rn, rm, 0, LSL);
292                  case 0x3:
293                    return new Shsub16Reg(machInst, rd, rn, rm, 0, LSL);
294                  case 0x4:
295                    return new Shadd8Reg(machInst, rd, rn, rm, 0, LSL);
296                  case 0x7:
297                    return new Shsub8Reg(machInst, rd, rn, rm, 0, LSL);
298                }
299                break;
300            }
301        } else {
302            switch (op1) {
303              case 0x1:
304                switch (op2) {
305                  case 0x0:
306                    return new Uadd16RegCc(machInst, rd, rn, rm, 0, LSL);
307                  case 0x1:
308                    return new UasxRegCc(machInst, rd, rn, rm, 0, LSL);
309                  case 0x2:
310                    return new UsaxRegCc(machInst, rd, rn, rm, 0, LSL);
311                  case 0x3:
312                    return new Usub16RegCc(machInst, rd, rn, rm, 0, LSL);
313                  case 0x4:
314                    return new Uadd8RegCc(machInst, rd, rn, rm, 0, LSL);
315                  case 0x7:
316                    return new Usub8RegCc(machInst, rd, rn, rm, 0, LSL);
317                }
318                break;
319              case 0x2:
320                switch (op2) {
321                  case 0x0:
322                    return new Uqadd16Reg(machInst, rd, rn, rm, 0, LSL);
323                  case 0x1:
324                    return new UqasxReg(machInst, rd, rn, rm, 0, LSL);
325                  case 0x2:
326                    return new UqsaxReg(machInst, rd, rn, rm, 0, LSL);
327                  case 0x3:
328                    return new Uqsub16Reg(machInst, rd, rn, rm, 0, LSL);
329                  case 0x4:
330                    return new Uqadd8Reg(machInst, rd, rn, rm, 0, LSL);
331                  case 0x7:
332                    return new Uqsub8Reg(machInst, rd, rn, rm, 0, LSL);
333                }
334                break;
335              case 0x3:
336                switch (op2) {
337                  case 0x0:
338                    return new Uhadd16Reg(machInst, rd, rn, rm, 0, LSL);
339                  case 0x1:
340                    return new UhasxReg(machInst, rd, rn, rm, 0, LSL);
341                  case 0x2:
342                    return new UhsaxReg(machInst, rd, rn, rm, 0, LSL);
343                  case 0x3:
344                    return new Uhsub16Reg(machInst, rd, rn, rm, 0, LSL);
345                  case 0x4:
346                    return new Uhadd8Reg(machInst, rd, rn, rm, 0, LSL);
347                  case 0x7:
348                    return new Uhsub8Reg(machInst, rd, rn, rm, 0, LSL);
349                }
350                break;
351            }
352        }
353        return new Unknown(machInst);
354    }
355    '''
356}};
357
358def format ArmDataProcImm() {{
359    pclr = '''
360        return new %(className)ssImmPclr(machInst, %(dest)s,
361                                        %(op1)s, imm, false);
362    '''
363    adr = '''
364        return new AdrImm(machInst, %(dest)s, %(add)s,
365                                     imm, false);
366    '''
367    instDecode = '''
368          case %(opcode)#x:
369            if (setCc) {
370                if (%(pclrInst)s && %(dest)s == INTREG_PC) {
371                    %(pclr)s
372                } else {
373                    return new %(className)sImmCc(machInst, %(dest)s, %(op1)s,
374                                                   imm, rotC);
375                }
376            } else {
377                if (%(adrInst)s && %(op1)s == INTREG_PC) {
378                    %(adr)s
379                } else {
380                    return new %(className)sImm(machInst, %(dest)s, %(op1)s,
381                                                 imm, rotC);
382                }
383            }
384            break;
385    '''
386
387    def instCode(opcode, mnem, useDest = True, useOp1 = True):
388        global instDecode, pclr, adr
389        if useDest:
390            dest = "rd"
391        else:
392            dest = "INTREG_ZERO"
393        if useOp1:
394            op1 = "rn"
395        else:
396            op1 = "INTREG_ZERO"
397        substDict = { "className": mnem.capitalize(),
398                      "opcode": opcode,
399                      "dest": dest,
400                      "op1": op1,
401                      "adr": "",
402                      "adrInst": "false" }
403        if useDest:
404            substDict["pclrInst"] = "true"
405            substDict["pclr"] = pclr % substDict
406        else:
407            substDict["pclrInst"] = "false"
408            substDict["pclr"] = ""
409        return instDecode % substDict
410
411    def adrCode(opcode, mnem, add="1"):
412        global instDecode, pclr, adr
413        substDict = { "className": mnem.capitalize(),
414                      "opcode": opcode,
415                      "dest": "rd",
416                      "op1": "rn",
417                      "add": add,
418                      "pclrInst": "true",
419                      "adrInst": "true" }
420        substDict["pclr"] = pclr % substDict
421        substDict["adr"] = adr % substDict
422        return instDecode % substDict
423
424    decode_block = '''
425    {
426        const bool setCc = (bits(machInst, 20) == 1);
427        const uint32_t unrotated = bits(machInst, 7, 0);
428        const uint32_t rotation = (bits(machInst, 11, 8) << 1);
429        const bool rotC = (rotation != 0);
430        const uint32_t imm = rotate_imm(unrotated, rotation);
431        const IntRegIndex rd = (IntRegIndex)(uint32_t)RD;
432        const IntRegIndex rn = (IntRegIndex)(uint32_t)RN;
433        switch (OPCODE) {
434    '''
435    decode_block += instCode(0x0, "and")
436    decode_block += instCode(0x1, "eor")
437    decode_block += adrCode(0x2, "sub", add="(IntRegIndex)0")
438    decode_block += instCode(0x3, "rsb")
439    decode_block += adrCode(0x4, "add", add="(IntRegIndex)1")
440    decode_block += instCode(0x5, "adc")
441    decode_block += instCode(0x6, "sbc")
442    decode_block += instCode(0x7, "rsc")
443    decode_block += instCode(0x8, "tst", useDest = False)
444    decode_block += instCode(0x9, "teq", useDest = False)
445    decode_block += instCode(0xa, "cmp", useDest = False)
446    decode_block += instCode(0xb, "cmn", useDest = False)
447    decode_block += instCode(0xc, "orr")
448    decode_block += instCode(0xd, "mov", useOp1 = False)
449    decode_block += instCode(0xe, "bic")
450    decode_block += instCode(0xf, "mvn", useOp1 = False)
451    decode_block += '''
452          default:
453            return new Unknown(machInst);
454        }
455    }
456    '''
457}};
458
459def format ArmSatAddSub() {{
460    decode_block = '''
461    {
462        IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
463        IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
464        IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
465        switch (OPCODE) {
466          case 0x8:
467            return new QaddRegCc(machInst, rd, rm, rn, 0, LSL);
468          case 0x9:
469            return new QsubRegCc(machInst, rd, rm, rn, 0, LSL);
470          case 0xa:
471            return new QdaddRegCc(machInst, rd, rm, rn, 0, LSL);
472          case 0xb:
473            return new QdsubRegCc(machInst, rd, rm, rn, 0, LSL);
474          default:
475            return new Unknown(machInst);
476        }
477    }
478    '''
479}};
480
481def format Thumb32DataProcReg() {{
482    decode_block = '''
483    {
484        const uint32_t op1 = bits(machInst, 23, 20);
485        const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
486        const uint32_t op2 = bits(machInst, 7, 4);
487        if (bits(op1, 3) != 1) {
488            if (op2 == 0) {
489                IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
490                IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
491                switch (bits(op1, 2, 0)) {
492                  case 0x0:
493                    return new MovRegReg(machInst, rd,
494                            INTREG_ZERO, rn, rm, LSL);
495                  case 0x1:
496                    return new MovRegRegCc(machInst, rd,
497                            INTREG_ZERO, rn, rm, LSL);
498                  case 0x2:
499                    return new MovRegReg(machInst, rd,
500                            INTREG_ZERO, rn, rm, LSR);
501                  case 0x3:
502                    return new MovRegRegCc(machInst, rd,
503                            INTREG_ZERO, rn, rm, LSR);
504                  case 0x4:
505                    return new MovRegReg(machInst, rd,
506                            INTREG_ZERO, rn, rm, ASR);
507                  case 0x5:
508                    return new MovRegRegCc(machInst, rd,
509                            INTREG_ZERO, rn, rm, ASR);
510                  case 0x6:
511                    return new MovRegReg(machInst, rd,
512                            INTREG_ZERO, rn, rm, ROR);
513                  case 0x7:
514                    return new MovRegRegCc(machInst, rd,
515                            INTREG_ZERO, rn, rm, ROR);
516                }
517            }
518            switch (bits(op1, 2, 0)) {
519              case 0x0:
520                if (rn == 0xf) {
521                    return new WarnUnimplemented("sxth", machInst);
522                } else {
523                    return new WarnUnimplemented("sxtah", machInst);
524                }
525              case 0x1:
526                if (rn == 0xf) {
527                    return new WarnUnimplemented("uxth", machInst);
528                } else {
529                    return new WarnUnimplemented("uxtah", machInst);
530                }
531              case 0x2:
532                if (rn == 0xf) {
533                    return new WarnUnimplemented("sxtb16", machInst);
534                } else {
535                    return new WarnUnimplemented("sxtab16", machInst);
536                }
537              case 0x3:
538                if (rn == 0xf) {
539                    return new WarnUnimplemented("uxtb16", machInst);
540                } else {
541                    return new WarnUnimplemented("uxtab16", machInst);
542                }
543              case 0x4:
544                if (rn == 0xf) {
545                    return new WarnUnimplemented("sxtb", machInst);
546                } else {
547                    return new WarnUnimplemented("sxtab", machInst);
548                }
549              case 0x5:
550                if (rn == 0xf) {
551                    return new WarnUnimplemented("uxtb", machInst);
552                } else {
553                    return new WarnUnimplemented("uxtab", machInst);
554                }
555              default:
556                return new Unknown(machInst);
557            }
558        } else {
559            if (bits(op2, 3) == 0) {
560                const IntRegIndex rd =
561                    (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
562                const IntRegIndex rm =
563                    (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
564                if (bits(op2, 2) == 0x0) {
565                    const uint32_t op1 = bits(machInst, 22, 20);
566                    const uint32_t op2 = bits(machInst, 5, 4);
567                    switch (op2) {
568                      case 0x0:
569                        switch (op1) {
570                          case 0x1:
571                            return new Sadd16RegCc(machInst, rd,
572                                                   rn, rm, 0, LSL);
573                          case 0x2:
574                            return new SasxRegCc(machInst, rd,
575                                                 rn, rm, 0, LSL);
576                          case 0x6:
577                            return new SsaxRegCc(machInst, rd,
578                                                 rn, rm, 0, LSL);
579                          case 0x5:
580                            return new Ssub16RegCc(machInst, rd,
581                                                   rn, rm, 0, LSL);
582                          case 0x0:
583                            return new Sadd8RegCc(machInst, rd,
584                                                  rn, rm, 0, LSL);
585                          case 0x4:
586                            return new Ssub8RegCc(machInst, rd,
587                                                  rn, rm, 0, LSL);
588                        }
589                        break;
590                      case 0x1:
591                        switch (op1) {
592                          case 0x1:
593                            return new Qadd16Reg(machInst, rd, rn, rm, 0, LSL);
594                          case 0x2:
595                            return new QasxReg(machInst, rd, rn, rm, 0, LSL);
596                          case 0x6:
597                            return new QsaxReg(machInst, rd, rn, rm, 0, LSL);
598                          case 0x5:
599                            return new Qsub16Reg(machInst, rd, rn, rm, 0, LSL);
600                          case 0x0:
601                            return new Qadd8Reg(machInst, rd, rn, rm, 0, LSL);
602                          case 0x4:
603                            return new Qsub8Reg(machInst, rd, rn, rm, 0, LSL);
604                        }
605                        break;
606                      case 0x2:
607                        switch (op1) {
608                          case 0x1:
609                            return new Shadd16Reg(machInst, rd, rn, rm, 0, LSL);
610                          case 0x2:
611                            return new ShasxReg(machInst, rd, rn, rm, 0, LSL);
612                          case 0x6:
613                            return new ShsaxReg(machInst, rd, rn, rm, 0, LSL);
614                          case 0x5:
615                            return new Shsub16Reg(machInst, rd, rn, rm, 0, LSL);
616                          case 0x0:
617                            return new Shadd8Reg(machInst, rd, rn, rm, 0, LSL);
618                          case 0x4:
619                            return new Shsub8Reg(machInst, rd, rn, rm, 0, LSL);
620                        }
621                        break;
622                    }
623                } else {
624                    const uint32_t op1 = bits(machInst, 22, 20);
625                    const uint32_t op2 = bits(machInst, 5, 4);
626                    switch (op2) {
627                      case 0x0:
628                        switch (op1) {
629                          case 0x1:
630                            return new Uadd16RegCc(machInst, rd,
631                                                   rn, rm, 0, LSL);
632                          case 0x2:
633                            return new UasxRegCc(machInst, rd,
634                                                 rn, rm, 0, LSL);
635                          case 0x6:
636                            return new UsaxRegCc(machInst, rd,
637                                                 rn, rm, 0, LSL);
638                          case 0x5:
639                            return new Usub16RegCc(machInst, rd,
640                                                   rn, rm, 0, LSL);
641                          case 0x0:
642                            return new Uadd8RegCc(machInst, rd,
643                                                  rn, rm, 0, LSL);
644                          case 0x4:
645                            return new Usub8RegCc(machInst, rd,
646                                                  rn, rm, 0, LSL);
647                        }
648                        break;
649                      case 0x1:
650                        switch (op1) {
651                          case 0x1:
652                            return new Uqadd16Reg(machInst, rd, rn, rm, 0, LSL);
653                          case 0x2:
654                            return new UqasxReg(machInst, rd, rn, rm, 0, LSL);
655                          case 0x6:
656                            return new UqsaxReg(machInst, rd, rn, rm, 0, LSL);
657                          case 0x5:
658                            return new Uqsub16Reg(machInst, rd, rn, rm, 0, LSL);
659                          case 0x0:
660                            return new Uqadd8Reg(machInst, rd, rn, rm, 0, LSL);
661                          case 0x4:
662                            return new Uqsub8Reg(machInst, rd, rn, rm, 0, LSL);
663                        }
664                        break;
665                      case 0x2:
666                        switch (op1) {
667                          case 0x1:
668                            return new Uhadd16Reg(machInst, rd, rn, rm, 0, LSL);
669                          case 0x2:
670                            return new UhasxReg(machInst, rd, rn, rm, 0, LSL);
671                          case 0x6:
672                            return new UhsaxReg(machInst, rd, rn, rm, 0, LSL);
673                          case 0x5:
674                            return new Uhsub16Reg(machInst, rd, rn, rm, 0, LSL);
675                          case 0x0:
676                            return new Uhadd8Reg(machInst, rd, rn, rm, 0, LSL);
677                          case 0x4:
678                            return new Uhsub8Reg(machInst, rd, rn, rm, 0, LSL);
679                        }
680                        break;
681                    }
682                }
683            } else if (bits(op1, 3, 2) == 0x2 && bits(op2, 3, 2) == 0x2) {
684                const uint32_t op1 = bits(machInst, 21, 20);
685                const uint32_t op2 = bits(machInst, 5, 4);
686                switch (op1) {
687                  case 0x0:
688                    {
689                        IntRegIndex rd =
690                            (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
691                        IntRegIndex rm =
692                            (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
693                        switch (op2) {
694                          case 0x0:
695                            return new QaddRegCc(machInst, rd,
696                                                 rm, rn, 0, LSL);
697                          case 0x1:
698                            return new QdaddRegCc(machInst, rd,
699                                                  rm, rn, 0, LSL);
700                          case 0x2:
701                            return new QsubRegCc(machInst, rd,
702                                                 rm, rn, 0, LSL);
703                          case 0x3:
704                            return new QdsubRegCc(machInst, rd,
705                                                  rm, rn, 0, LSL);
706                        }
707                    }
708                    break;
709                  case 0x1:
710                    {
711                        IntRegIndex rd =
712                            (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
713                        IntRegIndex rm = rn;
714                        switch (op2) {
715                          case 0x0:
716                            return new Rev(machInst, rd, rm);
717                          case 0x1:
718                            return new Rev16(machInst, rd, rm);
719                          case 0x2:
720                            return new WarnUnimplemented("rbit", machInst);
721                          case 0x3:
722                            return new Revsh(machInst, rd, rm);
723                        }
724                    }
725                    break;
726                  case 0x2:
727                    if (op2 == 0) {
728                        return new WarnUnimplemented("sel", machInst);
729                    }
730                    break;
731                  case 0x3:
732                    if (op2 == 0) {
733                        return new WarnUnimplemented("clz", machInst);
734                    }
735                }
736            }
737            return new Unknown(machInst);
738        }
739    }
740    '''
741}};
742
743def format Thumb16ShiftAddSubMoveCmp() {{
744    decode_block = '''
745    {
746        const uint32_t imm5 = bits(machInst, 10, 6);
747        const uint32_t imm3 = bits(machInst, 8, 6);
748        const uint32_t imm8 = bits(machInst, 7, 0);
749        const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 2, 0);
750        const IntRegIndex rd8 = (IntRegIndex)(uint32_t)bits(machInst, 10, 8);
751        const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 5, 3);
752        const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 8, 6);
753        switch (bits(machInst, 13, 11)) {
754          case 0x0: // lsl
755            return new MovRegCc(machInst, rd, INTREG_ZERO, rn, imm5, LSL);
756          case 0x1: // lsr
757            return new MovRegCc(machInst, rd, INTREG_ZERO, rn, imm5, LSR);
758          case 0x2: // asr
759            return new MovRegCc(machInst, rd, INTREG_ZERO, rn, imm5, ASR);
760          case 0x3:
761            switch (bits(machInst, 10, 9)) {
762              case 0x0:
763                return new AddRegCc(machInst, rd, rn, rm, 0, LSL);
764              case 0x1:
765                return new SubRegCc(machInst, rd, rn, rm, 0, LSL);
766              case 0x2:
767                return new AddImmCc(machInst, rd, rn, imm3, true);
768              case 0x3:
769                return new SubImmCc(machInst, rd, rn, imm3, true);
770            }
771          case 0x4:
772            return new MovImmCc(machInst, rd8, INTREG_ZERO, imm8, false);
773          case 0x5:
774            return new CmpImmCc(machInst, INTREG_ZERO, rd8, imm8, true);
775          case 0x6:
776            return new AddImmCc(machInst, rd8, rd8, imm8, true);
777          case 0x7:
778            return new SubImmCc(machInst, rd8, rd8, imm8, true);
779        }
780    }
781    '''
782}};
783
784def format Thumb16DataProcessing() {{
785    decode_block = '''
786    {
787        const IntRegIndex rdn = (IntRegIndex)(uint32_t)bits(machInst, 2, 0);
788        const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 5, 3);
789        switch (bits(machInst, 9, 6)) {
790          case 0x0:
791            return new AndRegCc(machInst, rdn, rdn, rm, 0, LSL);
792          case 0x1:
793            return new EorRegCc(machInst, rdn, rdn, rm, 0, LSL);
794          case 0x2: //lsl
795            return new MovRegRegCc(machInst, rdn, INTREG_ZERO, rdn, rm, LSL);
796          case 0x3: //lsr
797            return new MovRegRegCc(machInst, rdn, INTREG_ZERO, rdn, rm, LSR);
798          case 0x4: //asr
799            return new MovRegRegCc(machInst, rdn, INTREG_ZERO, rdn, rm, ASR);
800          case 0x5:
801            return new AdcRegCc(machInst, rdn, rdn, rm, 0, LSL);
802          case 0x6:
803            return new SbcRegCc(machInst, rdn, rdn, rm, 0, LSL);
804          case 0x7: // ror
805            return new MovRegRegCc(machInst, rdn, INTREG_ZERO, rdn, rm, ROR);
806          case 0x8:
807            return new TstRegCc(machInst, INTREG_ZERO, rdn, rm, 0, LSL);
808          case 0x9:
809            return new RsbImmCc(machInst, rdn, rm, 0, true);
810          case 0xa:
811            return new CmpRegCc(machInst, INTREG_ZERO, rdn, rm, 0, LSL);
812          case 0xb:
813            return new CmnRegCc(machInst, INTREG_ZERO, rdn, rm, 0, LSL);
814          case 0xc:
815            return new OrrRegCc(machInst, rdn, rdn, rm, 0, LSL);
816          case 0xd:
817            return new MulCc(machInst, rdn, rm, rdn);
818          case 0xe:
819            return new BicRegCc(machInst, rdn, rdn, rm, 0, LSL);
820          case 0xf:
821            return new MvnRegCc(machInst, rdn, INTREG_ZERO, rm, 0, LSL);
822        }
823    }
824    '''
825}};
826
827def format Thumb16SpecDataAndBx() {{
828    decode_block = '''
829    {
830        const IntRegIndex rdn =
831            (IntRegIndex)(uint32_t)(bits(machInst, 2, 0) |
832                                    (bits(machInst, 7) << 3));
833        const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 6, 3);
834        switch (bits(machInst, 9, 8)) {
835          case 0x0:
836            return new AddReg(machInst, rdn, rdn, rm, 0, LSL);
837          case 0x1:
838            return new CmpRegCc(machInst, INTREG_ZERO, rdn, rm, 0, LSL);
839          case 0x2:
840            return new MovReg(machInst, rdn, INTREG_ZERO, rm, 0, LSL);
841          case 0x3:
842            if (bits(machInst, 7) == 0) {
843                return new BxReg(machInst,
844                                 (IntRegIndex)(uint32_t)bits(machInst, 6, 3),
845                                 COND_UC);
846            } else {
847                return new BlxReg(machInst,
848                                  (IntRegIndex)(uint32_t)bits(machInst, 6, 3),
849                                  COND_UC);
850            }
851        }
852    }
853    '''
854}};
855
856def format Thumb16Adr() {{
857    decode_block = '''
858    {
859        const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 10, 8);
860        const uint32_t imm8 = bits(machInst, 7, 0) << 2;
861        return new AdrImm(machInst, rd, (IntRegIndex)1, imm8, false);
862    }
863    '''
864}};
865
866def format Thumb16AddSp() {{
867    decode_block = '''
868    {
869        const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 10, 8);
870        const uint32_t imm8 = bits(machInst, 7, 0) << 2;
871        return new AddImm(machInst, rd, INTREG_SP, imm8, true);
872    }
873    '''
874}};
875
876def format Thumb16Misc() {{
877    decode_block = '''
878    {
879        switch (bits(machInst, 11, 8)) {
880          case 0x0:
881            if (bits(machInst, 7)) {
882                return new SubImm(machInst, INTREG_SP, INTREG_SP,
883                                   bits(machInst, 6, 0) << 2, true);
884            } else {
885                return new AddImm(machInst, INTREG_SP, INTREG_SP,
886                                   bits(machInst, 6, 0) << 2, true);
887            }
888          case 0x1:
889            return new Cbz(machInst,
890                           (bits(machInst, 9) << 6) |
891                           (bits(machInst, 7, 3) << 1),
892                           (IntRegIndex)(uint32_t)bits(machInst, 2, 0));
893          case 0x2:
894            switch (bits(machInst, 7, 6)) {
895              case 0x0:
896                return new WarnUnimplemented("sxth", machInst);
897              case 0x1:
898                return new WarnUnimplemented("sxtb", machInst);
899              case 0x2:
900                return new WarnUnimplemented("uxth", machInst);
901              case 0x3:
902                return new WarnUnimplemented("uxtb", machInst);
903            }
904          case 0x3:
905            return new Cbz(machInst,
906                           (bits(machInst, 9) << 6) |
907                           (bits(machInst, 7, 3) << 1),
908                           (IntRegIndex)(uint32_t)bits(machInst, 2, 0));
909          case 0x4:
910          case 0x5:
911            {
912                const uint32_t m = bits(machInst, 8);
913                const uint32_t regList = bits(machInst, 7, 0) | (m << 14);
914                return new LdmStm(machInst, INTREG_SP, false, false, false,
915                                  true, false, regList);
916            }
917          case 0x6:
918            {
919                const uint32_t opBits = bits(machInst, 7, 5);
920                if (opBits == 2) {
921                    return new WarnUnimplemented("setend", machInst);
922                } else if (opBits == 3) {
923                    return new WarnUnimplemented("cps", machInst);
924                }
925            }
926          case 0x9:
927            return new Cbnz(machInst,
928                            (bits(machInst, 9) << 6) |
929                            (bits(machInst, 7, 3) << 1),
930                            (IntRegIndex)(uint32_t)bits(machInst, 2, 0));
931          case 0xa:
932            {
933                IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 2, 0);
934                IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 5, 3);
935                switch (bits(machInst, 7, 6)) {
936                  case 0x0:
937                    return new Rev(machInst, rd, rm);
938                  case 0x1:
939                    return new Rev16(machInst, rd, rm);
940                  case 0x3:
941                    return new Revsh(machInst, rd, rm);
942                  default:
943                    break;
944                }
945            }
946            break;
947          case 0xb:
948            return new Cbnz(machInst,
949                            (bits(machInst, 9) << 6) |
950                            (bits(machInst, 7, 3) << 1),
951                            (IntRegIndex)(uint32_t)bits(machInst, 2, 0));
952          case 0xc:
953          case 0xd:
954            {
955                const uint32_t p = bits(machInst, 8);
956                const uint32_t regList = bits(machInst, 7, 0) | (p << 15);
957                return new LdmStm(machInst, INTREG_SP, true, true, false,
958                                  true, true, regList);
959            }
960          case 0xe:
961            return new WarnUnimplemented("bkpt", machInst);
962          case 0xf:
963            if (bits(machInst, 3, 0) != 0)
964                return new WarnUnimplemented("it", machInst);
965            switch (bits(machInst, 7, 4)) {
966              case 0x0:
967                return new WarnUnimplemented("nop", machInst);
968              case 0x1:
969                return new WarnUnimplemented("yield", machInst);
970              case 0x2:
971                return new WarnUnimplemented("wfe", machInst);
972              case 0x3:
973                return new WarnUnimplemented("wfi", machInst);
974              case 0x4:
975                return new WarnUnimplemented("sev", machInst);
976              default:
977                return new WarnUnimplemented("unallocated_hint", machInst);
978            }
979          default:
980            break;
981        }
982        return new Unknown(machInst);
983    }
984    '''
985}};
986
987def format Thumb32DataProcModImm() {{
988
989    def decInst(mnem, dest="rd", op1="rn"):
990        return '''
991            if (s) {
992                return new %(mnem)sImmCc(machInst, %(dest)s,
993                                          %(op1)s, imm, rotC);
994            } else {
995                return new %(mnem)sImm(machInst, %(dest)s,
996                                        %(op1)s, imm, rotC);
997            }
998        ''' % {"mnem" : mnem, "dest" : dest, "op1" : op1}
999
1000    decode_block = '''
1001    {
1002        const uint32_t op = bits(machInst, 24, 21);
1003        const bool s = (bits(machInst, 20) == 1);
1004        const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
1005        const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
1006        const uint32_t ctrlImm = bits(machInst.instBits, 26) << 3 |
1007                                 bits(machInst, 14, 12);
1008        const bool rotC = ctrlImm > 3;
1009        const uint32_t dataImm = bits(machInst, 7, 0);
1010        const uint32_t imm = modified_imm(ctrlImm, dataImm);
1011        switch (op) {
1012          case 0x0:
1013            if (rd == INTREG_PC) {
1014                %(tst)s
1015            } else {
1016                %(and)s
1017            }
1018          case 0x1:
1019            %(bic)s
1020          case 0x2:
1021            if (rn == INTREG_PC) {
1022                %(mov)s
1023            } else {
1024                %(orr)s
1025            }
1026          case 0x3:
1027            if (rn == INTREG_PC) {
1028                %(mvn)s
1029            } else {
1030                %(orn)s
1031            }
1032          case 0x4:
1033            if (rd == INTREG_PC) {
1034                %(teq)s
1035            } else {
1036                %(eor)s
1037            }
1038          case 0x8:
1039            if (rd == INTREG_PC) {
1040                %(cmn)s
1041            } else {
1042                %(add)s
1043            }
1044          case 0xa:
1045            %(adc)s
1046          case 0xb:
1047            %(sbc)s
1048          case 0xd:
1049            if (rd == INTREG_PC) {
1050                %(cmp)s
1051            } else {
1052                %(sub)s
1053            }
1054          case 0xe:
1055            %(rsb)s
1056          default:
1057            return new Unknown(machInst);
1058        }
1059    }
1060    ''' % {
1061        "tst" : decInst("Tst", "INTREG_ZERO"),
1062        "and" : decInst("And"),
1063        "bic" : decInst("Bic"),
1064        "mov" : decInst("Mov", op1="INTREG_ZERO"),
1065        "orr" : decInst("Orr"),
1066        "mvn" : decInst("Mvn", op1="INTREG_ZERO"),
1067        "orn" : decInst("Orn"),
1068        "teq" : decInst("Teq", dest="INTREG_ZERO"),
1069        "eor" : decInst("Eor"),
1070        "cmn" : decInst("Cmn", dest="INTREG_ZERO"),
1071        "add" : decInst("Add"),
1072        "adc" : decInst("Adc"),
1073        "sbc" : decInst("Sbc"),
1074        "cmp" : decInst("Cmp", dest="INTREG_ZERO"),
1075        "sub" : decInst("Sub"),
1076        "rsb" : decInst("Rsb")
1077    }
1078}};
1079
1080def format Thumb32DataProcPlainBin() {{
1081    decode_block = '''
1082    {
1083        const uint32_t op = bits(machInst, 24, 20);
1084        const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
1085        const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
1086        switch (op) {
1087          case 0x0:
1088            {
1089                const uint32_t imm = bits(machInst, 7, 0) |
1090                                     (bits(machInst, 14, 12) << 8) |
1091                                     (bits(machInst, 26) << 11);
1092                if (rn == 0xf) {
1093                    return new AdrImm(machInst, rd, (IntRegIndex)1,
1094                                      imm, false);
1095                } else {
1096                    return new AddImm(machInst, rd, rn, imm, true);
1097                }
1098            }
1099          case 0x4:
1100            {
1101                const uint32_t imm = bits(machInst, 7, 0) |
1102                                     (bits(machInst, 14, 12) << 8) |
1103                                     (bits(machInst, 26) << 11) |
1104                                     (bits(machInst, 19, 16) << 12);
1105                return new MovImm(machInst, rd, INTREG_ZERO, imm, true);
1106            }
1107          case 0xa:
1108            {
1109                const uint32_t imm = bits(machInst, 7, 0) |
1110                                     (bits(machInst, 14, 12) << 8) |
1111                                     (bits(machInst, 26) << 11);
1112                if (rn == 0xf) {
1113                    return new AdrImm(machInst, rd, (IntRegIndex)0,
1114                                      imm, false);
1115                } else {
1116                    return new SubImm(machInst, rd, rn, imm, true);
1117                }
1118            }
1119          case 0xc:
1120            {
1121                const uint32_t imm = bits(machInst, 7, 0) |
1122                                     (bits(machInst, 14, 12) << 8) |
1123                                     (bits(machInst, 26) << 11) |
1124                                     (bits(machInst, 19, 16) << 12);
1125                return new MovtImm(machInst, rd, rd, imm, true);
1126            }
1127          case 0x12:
1128            if (!(bits(machInst, 14, 12) || bits(machInst, 7, 6))) {
1129                const uint32_t satImm = bits(machInst, 4, 0);
1130                return new Ssat16(machInst, rd, satImm + 1, rn);
1131            }
1132            // Fall through on purpose...
1133          case 0x10:
1134            {
1135                const uint32_t satImm = bits(machInst, 4, 0);
1136                const uint32_t imm = bits(machInst, 7, 6) |
1137                                     (bits(machInst, 14, 12) << 2);
1138                const ArmShiftType type =
1139                    (ArmShiftType)(uint32_t)bits(machInst, 21, 20);
1140                return new Ssat(machInst, rd, satImm + 1, rn, imm, type);
1141            }
1142          case 0x14:
1143            return new WarnUnimplemented("sbfx", machInst);
1144          case 0x16:
1145            if (rn == 0xf) {
1146                return new WarnUnimplemented("bfc", machInst);
1147            } else {
1148                return new WarnUnimplemented("bfi", machInst);
1149            }
1150          case 0x1a:
1151            if (!(bits(machInst, 14, 12) || bits(machInst, 7, 6))) {
1152                const uint32_t satImm = bits(machInst, 4, 0);
1153                return new Usat16(machInst, rd, satImm, rn);
1154            }
1155            // Fall through on purpose...
1156          case 0x18:
1157            {
1158                const uint32_t satImm = bits(machInst, 4, 0);
1159                const uint32_t imm = bits(machInst, 7, 6) |
1160                                     (bits(machInst, 14, 12) << 2);
1161                const ArmShiftType type =
1162                    (ArmShiftType)(uint32_t)bits(machInst, 21, 20);
1163                return new Usat(machInst, rd, satImm, rn, imm, type);
1164            }
1165          case 0x1c:
1166            return new WarnUnimplemented("ubfx", machInst);
1167          default:
1168            return new Unknown(machInst);
1169        }
1170    }
1171    '''
1172}};
1173
1174def format Thumb32DataProcShiftReg() {{
1175
1176    def decInst(mnem, dest="rd", op1="rn"):
1177        return '''
1178            if (s) {
1179                return new %(mnem)sRegCc(machInst, %(dest)s,
1180                                          %(op1)s, rm, amt, type);
1181            } else {
1182                return new %(mnem)sReg(machInst, %(dest)s,
1183                                        %(op1)s, rm, amt, type);
1184            }
1185        ''' % {"mnem" : mnem, "dest" : dest, "op1" : op1}
1186
1187    decode_block = '''
1188    {
1189        const uint32_t op = bits(machInst, 24, 21);
1190        const bool s = (bits(machInst, 20) == 1);
1191        const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
1192        const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
1193        const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
1194        const uint32_t amt = (bits(machInst, 14, 12) << 2) |
1195                              bits(machInst, 7, 6);
1196        const ArmShiftType type = (ArmShiftType)(uint32_t)bits(machInst, 5, 4);
1197        switch (op) {
1198          case 0x0:
1199            if (rd == INTREG_PC) {
1200                %(tst)s
1201            } else {
1202                %(and)s
1203            }
1204          case 0x1:
1205            %(bic)s
1206          case 0x2:
1207            if (rn == INTREG_PC) {
1208                %(mov)s
1209            } else {
1210                %(orr)s
1211            }
1212          case 0x3:
1213            if (rn == INTREG_PC) {
1214                %(mvn)s
1215            } else {
1216                %(orn)s
1217            }
1218          case 0x4:
1219            if (rd == INTREG_PC) {
1220                %(teq)s
1221            } else {
1222                %(eor)s
1223            }
1224          case 0x6:
1225            return new WarnUnimplemented("pkh", machInst);
1226          case 0x8:
1227            if (rd == INTREG_PC) {
1228                %(cmn)s
1229            } else {
1230                %(add)s
1231            }
1232          case 0xa:
1233            %(adc)s
1234          case 0xb:
1235            %(sbc)s
1236          case 0xd:
1237            if (rd == INTREG_PC) {
1238                %(cmp)s
1239            } else {
1240                %(sub)s
1241            }
1242          case 0xe:
1243            %(rsb)s
1244          default:
1245            return new Unknown(machInst);
1246        }
1247    }
1248    ''' % {
1249        "tst" : decInst("Tst", "INTREG_ZERO"),
1250        "and" : decInst("And"),
1251        "bic" : decInst("Bic"),
1252        "mov" : decInst("Mov", op1="INTREG_ZERO"),
1253        "orr" : decInst("Orr"),
1254        "mvn" : decInst("Mvn", op1="INTREG_ZERO"),
1255        "orn" : decInst("Orn"),
1256        "teq" : decInst("Teq", "INTREG_ZERO"),
1257        "eor" : decInst("Eor"),
1258        "cmn" : decInst("Cmn", "INTREG_ZERO"),
1259        "add" : decInst("Add"),
1260        "adc" : decInst("Adc"),
1261        "sbc" : decInst("Sbc"),
1262        "cmp" : decInst("Cmp", "INTREG_ZERO"),
1263        "sub" : decInst("Sub"),
1264        "rsb" : decInst("Rsb")
1265    }
1266}};
1267