data.isa revision 7237:4c1445a9e72b
12689Sktlim@umich.edu// Copyright (c) 2010 ARM Limited
22689Sktlim@umich.edu// All rights reserved
32689Sktlim@umich.edu//
42689Sktlim@umich.edu// The license below extends only to copyright in the software and shall
52689Sktlim@umich.edu// not be construed as granting a license to any other intellectual
62689Sktlim@umich.edu// property including but not limited to intellectual property relating
72689Sktlim@umich.edu// to a hardware implementation of the functionality of the software
82689Sktlim@umich.edu// licensed hereunder.  You may use the software subject to the license
92689Sktlim@umich.edu// terms below provided that you ensure that this notice is replicated
102689Sktlim@umich.edu// unmodified and in its entirety in all distributions of the software,
112689Sktlim@umich.edu// modified or unmodified, in source code or in binary form.
122689Sktlim@umich.edu//
132689Sktlim@umich.edu// Redistribution and use in source and binary forms, with or without
142689Sktlim@umich.edu// modification, are permitted provided that the following conditions are
152689Sktlim@umich.edu// met: redistributions of source code must retain the above copyright
162689Sktlim@umich.edu// notice, this list of conditions and the following disclaimer;
172689Sktlim@umich.edu// redistributions in binary form must reproduce the above copyright
182689Sktlim@umich.edu// notice, this list of conditions and the following disclaimer in the
192689Sktlim@umich.edu// documentation and/or other materials provided with the distribution;
202689Sktlim@umich.edu// neither the name of the copyright holders nor the names of its
212689Sktlim@umich.edu// contributors may be used to endorse or promote products derived from
222689Sktlim@umich.edu// this software without specific prior written permission.
232689Sktlim@umich.edu//
242689Sktlim@umich.edu// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
252689Sktlim@umich.edu// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
262689Sktlim@umich.edu// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
272689Sktlim@umich.edu// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
282689Sktlim@umich.edu// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
292689Sktlim@umich.edu// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
302326SN/A// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
312326SN/A// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
322326SN/A// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
332326SN/A// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
342326SN/A// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
352326SN/A//
362348SN/A// Authors: Gabe Black
372326SN/A
382326SN/Adef format ArmDataProcReg() {{
392326SN/A    pclr = '''
402326SN/A        return new %(className)ssRegPclr(machInst, %(dest)s,
412326SN/A                                        %(op1)s, rm, imm5,
422326SN/A                                        type);
432326SN/A    '''
442326SN/A    instDecode = '''
452326SN/A          case %(opcode)#x:
462326SN/A            if (immShift) {
472326SN/A                if (setCc) {
482326SN/A                    if (%(dest)s == INTREG_PC) {
492326SN/A                        %(pclr)s
502326SN/A                    } else {
512348SN/A                        return new %(className)sRegCc(machInst, %(dest)s,
522348SN/A                                                      %(op1)s, rm, imm5, type);
532348SN/A                    }
542348SN/A                } else {
552348SN/A                    return new %(className)sReg(machInst, %(dest)s, %(op1)s,
562348SN/A                                                 rm, imm5, type);
572348SN/A                }
582348SN/A            } else {
592348SN/A                if (setCc) {
602326SN/A                    return new %(className)sRegRegCc(machInst, %(dest)s,
612326SN/A                                                      %(op1)s, rm, rs, type);
622326SN/A                } else {
632326SN/A                    return new %(className)sRegReg(machInst, %(dest)s,
642326SN/A                                                    %(op1)s, rm, rs, type);
652326SN/A                }
662348SN/A            }
672326SN/A            break;
682326SN/A    '''
692326SN/A
702326SN/A    def instCode(opcode, mnem, useDest = True, useOp1 = True):
712734Sktlim@umich.edu        global pclr
722734Sktlim@umich.edu        if useDest:
732348SN/A            dest = "rd"
742326SN/A        else:
752326SN/A            dest = "INTREG_ZERO"
762348SN/A        if useOp1:
772326SN/A            op1 = "rn"
782326SN/A        else:
792348SN/A            op1 = "INTREG_ZERO"
802326SN/A        global instDecode, pclrCode
812326SN/A        substDict = { "className": mnem.capitalize(),
822348SN/A                      "opcode": opcode,
832326SN/A                      "dest": dest,
842326SN/A                      "op1": op1 }
852326SN/A        if useDest:
862348SN/A            substDict["pclr"] = pclr % substDict
872326SN/A        else:
882326SN/A            substDict["pclr"] = ""
892326SN/A        return instDecode % substDict
902348SN/A
912326SN/A    decode_block = '''
922326SN/A    {
932348SN/A        const bool immShift = (bits(machInst, 4) == 0);
942326SN/A        const bool setCc = (bits(machInst, 20) == 1);
952326SN/A        const uint32_t imm5 = bits(machInst, 11, 7);
962348SN/A        const ArmShiftType type = (ArmShiftType)(uint32_t)bits(machInst, 6, 5);
972326SN/A        const IntRegIndex rd = (IntRegIndex)(uint32_t)RD;
982326SN/A        const IntRegIndex rn = (IntRegIndex)(uint32_t)RN;
992326SN/A        const IntRegIndex rm = (IntRegIndex)(uint32_t)RM;
1002326SN/A        const IntRegIndex rs = (IntRegIndex)(uint32_t)RS;
1012326SN/A        switch (OPCODE) {
1022326SN/A    '''
1032326SN/A    decode_block += instCode(0x0, "and")
1042326SN/A    decode_block += instCode(0x1, "eor")
1052326SN/A    decode_block += instCode(0x2, "sub")
1062326SN/A    decode_block += instCode(0x3, "rsb")
1072326SN/A    decode_block += instCode(0x4, "add")
1082326SN/A    decode_block += instCode(0x5, "adc")
1092326SN/A    decode_block += instCode(0x6, "sbc")
1102326SN/A    decode_block += instCode(0x7, "rsc")
1112326SN/A    decode_block += instCode(0x8, "tst", useDest = False)
1122348SN/A    decode_block += instCode(0x9, "teq", useDest = False)
1132326SN/A    decode_block += instCode(0xa, "cmp", useDest = False)
1142326SN/A    decode_block += instCode(0xb, "cmn", useDest = False)
1152326SN/A    decode_block += instCode(0xc, "orr")
1162326SN/A    decode_block += instCode(0xd, "mov", useOp1 = False)
1172326SN/A    decode_block += instCode(0xe, "bic")
1182326SN/A    decode_block += instCode(0xf, "mvn", useOp1 = False)
1192348SN/A    decode_block += '''
1202326SN/A          default:
1212348SN/A            return new Unknown(machInst);
1222326SN/A        }
1232326SN/A    }
1242326SN/A    '''
1252326SN/A}};
1262734Sktlim@umich.edu
1272734Sktlim@umich.edudef format ArmPackUnpackSatReverse() {{
1282734Sktlim@umich.edu    decode_block = '''
1292734Sktlim@umich.edu    {
1302734Sktlim@umich.edu        const uint32_t op1 = bits(machInst, 22, 20);
1312734Sktlim@umich.edu        const uint32_t a = bits(machInst, 19, 16);
1322326SN/A        const uint32_t op2 = bits(machInst, 7, 5);
1332326SN/A        if (bits(op2, 0) == 0) {
1342326SN/A            const IntRegIndex rn =
1352326SN/A                (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
1362326SN/A            const IntRegIndex rd =
1372326SN/A                (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
1382326SN/A            const uint32_t satImm = bits(machInst, 20, 16);
1392326SN/A            const uint32_t imm = bits(machInst, 11, 7);
1402326SN/A            const ArmShiftType type =
1412326SN/A                (ArmShiftType)(uint32_t)bits(machInst, 6, 5);
1422326SN/A            if (op1 == 0) {
1432326SN/A                if (type) {
1442326SN/A                    return new PkhtbReg(machInst, rd, (IntRegIndex)a,
1452326SN/A                                        rn, imm, type);
1462326SN/A                } else {
1472326SN/A                    return new PkhbtReg(machInst, rd, (IntRegIndex)a,
1482326SN/A                                        rn, imm, type);
1492326SN/A                }
1502326SN/A            } else if (bits(op1, 2, 1) == 1) {
1512326SN/A                return new Ssat(machInst, rd, satImm + 1, rn, imm, type);
1522326SN/A            } else if (bits(op1, 2, 1) == 3) {
1532326SN/A                return new Usat(machInst, rd, satImm, rn, imm, type);
1542326SN/A            }
1552326SN/A            return new Unknown(machInst);
1562326SN/A        }
1572326SN/A        switch (op1) {
1582326SN/A          case 0x0:
1592326SN/A            if (op2 == 0x3) {
1602326SN/A                const IntRegIndex rn =
1612326SN/A                    (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
1622326SN/A                const IntRegIndex rd =
1632326SN/A                    (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
1642326SN/A                const IntRegIndex rm =
1652326SN/A                    (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
1662326SN/A                const uint32_t rotation =
1672326SN/A                    (uint32_t)bits(machInst, 11, 10) << 3;
1682326SN/A                if (a == 0xf) {
1692326SN/A                    return new Sxtb16(machInst, rd, rotation, rm);
1702326SN/A                } else {
1712326SN/A                    return new Sxtab16(machInst, rd, rn, rm, rotation);
1722326SN/A                }
1732326SN/A            } else if (op2 == 0x5) {
1742326SN/A                return new WarnUnimplemented("sel", machInst);
1752326SN/A            }
1762326SN/A            break;
1772326SN/A          case 0x2:
1782326SN/A            if (op2 == 0x1) {
1792326SN/A                const IntRegIndex rn =
1802326SN/A                    (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
1812326SN/A                const IntRegIndex rd =
1822326SN/A                    (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
1832326SN/A                const uint32_t satImm = bits(machInst, 20, 16);
1842326SN/A                return new Ssat16(machInst, rd, satImm + 1, rn);
1852326SN/A            } else if (op2 == 0x3) {
1862326SN/A                const IntRegIndex rn =
1872326SN/A                    (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
1882326SN/A                const IntRegIndex rd =
1892326SN/A                    (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
1902326SN/A                const IntRegIndex rm =
1912326SN/A                    (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
1922326SN/A                const uint32_t rotation =
1932326SN/A                    (uint32_t)bits(machInst, 11, 10) << 3;
1942326SN/A                if (a == 0xf) {
1952326SN/A                    return new Sxtb(machInst, rd, rotation, rm);
1962326SN/A                } else {
1972326SN/A                    return new Sxtab(machInst, rd, rn, rm, rotation);
1982326SN/A                }
1992326SN/A            }
2002326SN/A            break;
2012326SN/A          case 0x3:
2022326SN/A            if (op2 == 0x1) {
2032326SN/A                IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
2042326SN/A                IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
2052326SN/A                return new Rev(machInst, rd, rm);
2062326SN/A            } else if (op2 == 0x3) {
2072326SN/A                const IntRegIndex rn =
2082326SN/A                    (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
2092326SN/A                const IntRegIndex rd =
2102326SN/A                    (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
2112326SN/A                const IntRegIndex rm =
2122326SN/A                    (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
2132326SN/A                const uint32_t rotation =
2142326SN/A                    (uint32_t)bits(machInst, 11, 10) << 3;
2152326SN/A                if (a == 0xf) {
2162326SN/A                    return new Sxth(machInst, rd, rotation, rm);
2172326SN/A                } else {
2182326SN/A                    return new Sxtah(machInst, rd, rn, rm, rotation);
2192326SN/A                }
2202326SN/A            } else if (op2 == 0x5) {
2212326SN/A                IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
2222326SN/A                IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
2232326SN/A                return new Rev16(machInst, rd, rm);
2242326SN/A            }
2252326SN/A            break;
2262326SN/A          case 0x4:
2272326SN/A            if (op2 == 0x3) {
2282326SN/A                const IntRegIndex rn =
2292326SN/A                    (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
2302326SN/A                const IntRegIndex rd =
2312326SN/A                    (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
2322326SN/A                const IntRegIndex rm =
2332326SN/A                    (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
2342326SN/A                const uint32_t rotation =
2352326SN/A                    (uint32_t)bits(machInst, 11, 10) << 3;
2362326SN/A                if (a == 0xf) {
2372326SN/A                    return new Uxtb16(machInst, rd, rotation, rm);
2382326SN/A                } else {
2392326SN/A                    return new Uxtab16(machInst, rd, rn, rm, rotation);
2402326SN/A                }
2412326SN/A            }
2422326SN/A            break;
2432326SN/A          case 0x6:
2442326SN/A            if (op2 == 0x1) {
2452326SN/A                const IntRegIndex rn =
2462326SN/A                    (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
2472326SN/A                const IntRegIndex rd =
2482326SN/A                    (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
2492326SN/A                const uint32_t satImm = bits(machInst, 20, 16);
2502326SN/A                return new Usat16(machInst, rd, satImm, rn);
2512326SN/A            } else if (op2 == 0x3) {
2522326SN/A                const IntRegIndex rn =
2532326SN/A                    (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
2542326SN/A                const IntRegIndex rd =
2552326SN/A                    (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
2562326SN/A                const IntRegIndex rm =
2572326SN/A                    (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
2582326SN/A                const uint32_t rotation =
2592326SN/A                    (uint32_t)bits(machInst, 11, 10) << 3;
2602326SN/A                if (a == 0xf) {
2612326SN/A                    return new Uxtb(machInst, rd, rotation, rm);
2622326SN/A                } else {
2632326SN/A                    return new Uxtab(machInst, rd, rn, rm, rotation);
2642326SN/A                }
2652326SN/A            }
2662326SN/A            break;
2672326SN/A          case 0x7:
2682326SN/A            if (op2 == 0x1) {
2692326SN/A                return new WarnUnimplemented("rbit", machInst);
2702326SN/A            } else if (op2 == 0x3) {
2712326SN/A                const IntRegIndex rn =
2722326SN/A                    (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
273                const IntRegIndex rd =
274                    (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
275                const IntRegIndex rm =
276                    (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
277                const uint32_t rotation =
278                    (uint32_t)bits(machInst, 11, 10) << 3;
279                if (a == 0xf) {
280                    return new Uxth(machInst, rd, rotation, rm);
281                } else {
282                    return new Uxtah(machInst, rd, rn, rm, rotation);
283                }
284            } else if (op2 == 0x5) {
285                IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
286                IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
287                return new Revsh(machInst, rd, rm);
288            }
289            break;
290        }
291        return new Unknown(machInst);
292    }
293    '''
294}};
295
296def format ArmParallelAddSubtract() {{
297    decode_block='''
298    {
299        const uint32_t op1 = bits(machInst, 21, 20);
300        const uint32_t op2 = bits(machInst, 7, 5);
301        const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
302        const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
303        const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
304        if (bits(machInst, 22) == 0) {
305            switch (op1) {
306              case 0x1:
307                switch (op2) {
308                  case 0x0:
309                    return new Sadd16RegCc(machInst, rd, rn, rm, 0, LSL);
310                  case 0x1:
311                    return new SasxRegCc(machInst, rd, rn, rm, 0, LSL);
312                  case 0x2:
313                    return new SsaxRegCc(machInst, rd, rn, rm, 0, LSL);
314                  case 0x3:
315                    return new Ssub16RegCc(machInst, rd, rn, rm, 0, LSL);
316                  case 0x4:
317                    return new Sadd8RegCc(machInst, rd, rn, rm, 0, LSL);
318                  case 0x7:
319                    return new Ssub8RegCc(machInst, rd, rn, rm, 0, LSL);
320                }
321                break;
322              case 0x2:
323                switch (op2) {
324                  case 0x0:
325                    return new Qadd16Reg(machInst, rd, rn, rm, 0, LSL);
326                  case 0x1:
327                    return new QasxReg(machInst, rd, rn, rm, 0, LSL);
328                  case 0x2:
329                    return new QsaxReg(machInst, rd, rn, rm, 0, LSL);
330                  case 0x3:
331                    return new Qsub16Reg(machInst, rd, rn, rm, 0, LSL);
332                  case 0x4:
333                    return new Qadd8Reg(machInst, rd, rn, rm, 0, LSL);
334                  case 0x7:
335                    return new Qsub8Reg(machInst, rd, rn, rm, 0, LSL);
336                }
337                break;
338              case 0x3:
339                switch (op2) {
340                  case 0x0:
341                    return new Shadd16Reg(machInst, rd, rn, rm, 0, LSL);
342                  case 0x1:
343                    return new ShasxReg(machInst, rd, rn, rm, 0, LSL);
344                  case 0x2:
345                    return new ShsaxReg(machInst, rd, rn, rm, 0, LSL);
346                  case 0x3:
347                    return new Shsub16Reg(machInst, rd, rn, rm, 0, LSL);
348                  case 0x4:
349                    return new Shadd8Reg(machInst, rd, rn, rm, 0, LSL);
350                  case 0x7:
351                    return new Shsub8Reg(machInst, rd, rn, rm, 0, LSL);
352                }
353                break;
354            }
355        } else {
356            switch (op1) {
357              case 0x1:
358                switch (op2) {
359                  case 0x0:
360                    return new Uadd16RegCc(machInst, rd, rn, rm, 0, LSL);
361                  case 0x1:
362                    return new UasxRegCc(machInst, rd, rn, rm, 0, LSL);
363                  case 0x2:
364                    return new UsaxRegCc(machInst, rd, rn, rm, 0, LSL);
365                  case 0x3:
366                    return new Usub16RegCc(machInst, rd, rn, rm, 0, LSL);
367                  case 0x4:
368                    return new Uadd8RegCc(machInst, rd, rn, rm, 0, LSL);
369                  case 0x7:
370                    return new Usub8RegCc(machInst, rd, rn, rm, 0, LSL);
371                }
372                break;
373              case 0x2:
374                switch (op2) {
375                  case 0x0:
376                    return new Uqadd16Reg(machInst, rd, rn, rm, 0, LSL);
377                  case 0x1:
378                    return new UqasxReg(machInst, rd, rn, rm, 0, LSL);
379                  case 0x2:
380                    return new UqsaxReg(machInst, rd, rn, rm, 0, LSL);
381                  case 0x3:
382                    return new Uqsub16Reg(machInst, rd, rn, rm, 0, LSL);
383                  case 0x4:
384                    return new Uqadd8Reg(machInst, rd, rn, rm, 0, LSL);
385                  case 0x7:
386                    return new Uqsub8Reg(machInst, rd, rn, rm, 0, LSL);
387                }
388                break;
389              case 0x3:
390                switch (op2) {
391                  case 0x0:
392                    return new Uhadd16Reg(machInst, rd, rn, rm, 0, LSL);
393                  case 0x1:
394                    return new UhasxReg(machInst, rd, rn, rm, 0, LSL);
395                  case 0x2:
396                    return new UhsaxReg(machInst, rd, rn, rm, 0, LSL);
397                  case 0x3:
398                    return new Uhsub16Reg(machInst, rd, rn, rm, 0, LSL);
399                  case 0x4:
400                    return new Uhadd8Reg(machInst, rd, rn, rm, 0, LSL);
401                  case 0x7:
402                    return new Uhsub8Reg(machInst, rd, rn, rm, 0, LSL);
403                }
404                break;
405            }
406        }
407        return new Unknown(machInst);
408    }
409    '''
410}};
411
412def format ArmDataProcImm() {{
413    pclr = '''
414        return new %(className)ssImmPclr(machInst, %(dest)s,
415                                        %(op1)s, imm, false);
416    '''
417    adr = '''
418        return new AdrImm(machInst, %(dest)s, %(add)s,
419                                     imm, false);
420    '''
421    instDecode = '''
422          case %(opcode)#x:
423            if (setCc) {
424                if (%(pclrInst)s && %(dest)s == INTREG_PC) {
425                    %(pclr)s
426                } else {
427                    return new %(className)sImmCc(machInst, %(dest)s, %(op1)s,
428                                                   imm, rotC);
429                }
430            } else {
431                if (%(adrInst)s && %(op1)s == INTREG_PC) {
432                    %(adr)s
433                } else {
434                    return new %(className)sImm(machInst, %(dest)s, %(op1)s,
435                                                 imm, rotC);
436                }
437            }
438            break;
439    '''
440
441    def instCode(opcode, mnem, useDest = True, useOp1 = True):
442        global instDecode, pclr, adr
443        if useDest:
444            dest = "rd"
445        else:
446            dest = "INTREG_ZERO"
447        if useOp1:
448            op1 = "rn"
449        else:
450            op1 = "INTREG_ZERO"
451        substDict = { "className": mnem.capitalize(),
452                      "opcode": opcode,
453                      "dest": dest,
454                      "op1": op1,
455                      "adr": "",
456                      "adrInst": "false" }
457        if useDest:
458            substDict["pclrInst"] = "true"
459            substDict["pclr"] = pclr % substDict
460        else:
461            substDict["pclrInst"] = "false"
462            substDict["pclr"] = ""
463        return instDecode % substDict
464
465    def adrCode(opcode, mnem, add="1"):
466        global instDecode, pclr, adr
467        substDict = { "className": mnem.capitalize(),
468                      "opcode": opcode,
469                      "dest": "rd",
470                      "op1": "rn",
471                      "add": add,
472                      "pclrInst": "true",
473                      "adrInst": "true" }
474        substDict["pclr"] = pclr % substDict
475        substDict["adr"] = adr % substDict
476        return instDecode % substDict
477
478    decode_block = '''
479    {
480        const bool setCc = (bits(machInst, 20) == 1);
481        const uint32_t unrotated = bits(machInst, 7, 0);
482        const uint32_t rotation = (bits(machInst, 11, 8) << 1);
483        const bool rotC = (rotation != 0);
484        const uint32_t imm = rotate_imm(unrotated, rotation);
485        const IntRegIndex rd = (IntRegIndex)(uint32_t)RD;
486        const IntRegIndex rn = (IntRegIndex)(uint32_t)RN;
487        switch (OPCODE) {
488    '''
489    decode_block += instCode(0x0, "and")
490    decode_block += instCode(0x1, "eor")
491    decode_block += adrCode(0x2, "sub", add="(IntRegIndex)0")
492    decode_block += instCode(0x3, "rsb")
493    decode_block += adrCode(0x4, "add", add="(IntRegIndex)1")
494    decode_block += instCode(0x5, "adc")
495    decode_block += instCode(0x6, "sbc")
496    decode_block += instCode(0x7, "rsc")
497    decode_block += instCode(0x8, "tst", useDest = False)
498    decode_block += instCode(0x9, "teq", useDest = False)
499    decode_block += instCode(0xa, "cmp", useDest = False)
500    decode_block += instCode(0xb, "cmn", useDest = False)
501    decode_block += instCode(0xc, "orr")
502    decode_block += instCode(0xd, "mov", useOp1 = False)
503    decode_block += instCode(0xe, "bic")
504    decode_block += instCode(0xf, "mvn", useOp1 = False)
505    decode_block += '''
506          default:
507            return new Unknown(machInst);
508        }
509    }
510    '''
511}};
512
513def format ArmSatAddSub() {{
514    decode_block = '''
515    {
516        IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
517        IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
518        IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
519        switch (OPCODE) {
520          case 0x8:
521            return new QaddRegCc(machInst, rd, rm, rn, 0, LSL);
522          case 0x9:
523            return new QsubRegCc(machInst, rd, rm, rn, 0, LSL);
524          case 0xa:
525            return new QdaddRegCc(machInst, rd, rm, rn, 0, LSL);
526          case 0xb:
527            return new QdsubRegCc(machInst, rd, rm, rn, 0, LSL);
528          default:
529            return new Unknown(machInst);
530        }
531    }
532    '''
533}};
534
535def format Thumb32DataProcReg() {{
536    decode_block = '''
537    {
538        const uint32_t op1 = bits(machInst, 23, 20);
539        const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
540        const uint32_t op2 = bits(machInst, 7, 4);
541        if (bits(op1, 3) != 1) {
542            if (op2 == 0) {
543                IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
544                IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
545                switch (bits(op1, 2, 0)) {
546                  case 0x0:
547                    return new MovRegReg(machInst, rd,
548                            INTREG_ZERO, rn, rm, LSL);
549                  case 0x1:
550                    return new MovRegRegCc(machInst, rd,
551                            INTREG_ZERO, rn, rm, LSL);
552                  case 0x2:
553                    return new MovRegReg(machInst, rd,
554                            INTREG_ZERO, rn, rm, LSR);
555                  case 0x3:
556                    return new MovRegRegCc(machInst, rd,
557                            INTREG_ZERO, rn, rm, LSR);
558                  case 0x4:
559                    return new MovRegReg(machInst, rd,
560                            INTREG_ZERO, rn, rm, ASR);
561                  case 0x5:
562                    return new MovRegRegCc(machInst, rd,
563                            INTREG_ZERO, rn, rm, ASR);
564                  case 0x6:
565                    return new MovRegReg(machInst, rd,
566                            INTREG_ZERO, rn, rm, ROR);
567                  case 0x7:
568                    return new MovRegRegCc(machInst, rd,
569                            INTREG_ZERO, rn, rm, ROR);
570                }
571            }
572            {
573                const IntRegIndex rd =
574                    (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
575                const IntRegIndex rm =
576                    (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
577                const uint32_t rotation =
578                    (uint32_t)bits(machInst, 5, 4) << 3;
579                switch (bits(op1, 2, 0)) {
580                  case 0x0:
581                    if (rn == 0xf) {
582                        return new Sxth(machInst, rd, rotation, rm);
583                    } else {
584                        return new Sxtah(machInst, rd, rn, rm, rotation);
585                    }
586                  case 0x1:
587                    if (rn == 0xf) {
588                        return new Uxth(machInst, rd, rotation, rm);
589                    } else {
590                        return new Uxtah(machInst, rd, rn, rm, rotation);
591                    }
592                  case 0x2:
593                    if (rn == 0xf) {
594                        return new Sxtb16(machInst, rd, rotation, rm);
595                    } else {
596                        return new Sxtab16(machInst, rd, rn, rm, rotation);
597                    }
598                  case 0x3:
599                    if (rn == 0xf) {
600                        return new Uxtb16(machInst, rd, rotation, rm);
601                    } else {
602                        return new Uxtab16(machInst, rd, rn, rm, rotation);
603                    }
604                  case 0x4:
605                    if (rn == 0xf) {
606                        return new Sxtb(machInst, rd, rotation, rm);
607                    } else {
608                        return new Sxtab(machInst, rd, rn, rm, rotation);
609                    }
610                  case 0x5:
611                    if (rn == 0xf) {
612                        return new Uxtb(machInst, rd, rotation, rm);
613                    } else {
614                        return new Uxtab(machInst, rd, rn, rm, rotation);
615                    }
616                  default:
617                    return new Unknown(machInst);
618                }
619            }
620        } else {
621            if (bits(op2, 3) == 0) {
622                const IntRegIndex rd =
623                    (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
624                const IntRegIndex rm =
625                    (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
626                if (bits(op2, 2) == 0x0) {
627                    const uint32_t op1 = bits(machInst, 22, 20);
628                    const uint32_t op2 = bits(machInst, 5, 4);
629                    switch (op2) {
630                      case 0x0:
631                        switch (op1) {
632                          case 0x1:
633                            return new Sadd16RegCc(machInst, rd,
634                                                   rn, rm, 0, LSL);
635                          case 0x2:
636                            return new SasxRegCc(machInst, rd,
637                                                 rn, rm, 0, LSL);
638                          case 0x6:
639                            return new SsaxRegCc(machInst, rd,
640                                                 rn, rm, 0, LSL);
641                          case 0x5:
642                            return new Ssub16RegCc(machInst, rd,
643                                                   rn, rm, 0, LSL);
644                          case 0x0:
645                            return new Sadd8RegCc(machInst, rd,
646                                                  rn, rm, 0, LSL);
647                          case 0x4:
648                            return new Ssub8RegCc(machInst, rd,
649                                                  rn, rm, 0, LSL);
650                        }
651                        break;
652                      case 0x1:
653                        switch (op1) {
654                          case 0x1:
655                            return new Qadd16Reg(machInst, rd, rn, rm, 0, LSL);
656                          case 0x2:
657                            return new QasxReg(machInst, rd, rn, rm, 0, LSL);
658                          case 0x6:
659                            return new QsaxReg(machInst, rd, rn, rm, 0, LSL);
660                          case 0x5:
661                            return new Qsub16Reg(machInst, rd, rn, rm, 0, LSL);
662                          case 0x0:
663                            return new Qadd8Reg(machInst, rd, rn, rm, 0, LSL);
664                          case 0x4:
665                            return new Qsub8Reg(machInst, rd, rn, rm, 0, LSL);
666                        }
667                        break;
668                      case 0x2:
669                        switch (op1) {
670                          case 0x1:
671                            return new Shadd16Reg(machInst, rd, rn, rm, 0, LSL);
672                          case 0x2:
673                            return new ShasxReg(machInst, rd, rn, rm, 0, LSL);
674                          case 0x6:
675                            return new ShsaxReg(machInst, rd, rn, rm, 0, LSL);
676                          case 0x5:
677                            return new Shsub16Reg(machInst, rd, rn, rm, 0, LSL);
678                          case 0x0:
679                            return new Shadd8Reg(machInst, rd, rn, rm, 0, LSL);
680                          case 0x4:
681                            return new Shsub8Reg(machInst, rd, rn, rm, 0, LSL);
682                        }
683                        break;
684                    }
685                } else {
686                    const uint32_t op1 = bits(machInst, 22, 20);
687                    const uint32_t op2 = bits(machInst, 5, 4);
688                    switch (op2) {
689                      case 0x0:
690                        switch (op1) {
691                          case 0x1:
692                            return new Uadd16RegCc(machInst, rd,
693                                                   rn, rm, 0, LSL);
694                          case 0x2:
695                            return new UasxRegCc(machInst, rd,
696                                                 rn, rm, 0, LSL);
697                          case 0x6:
698                            return new UsaxRegCc(machInst, rd,
699                                                 rn, rm, 0, LSL);
700                          case 0x5:
701                            return new Usub16RegCc(machInst, rd,
702                                                   rn, rm, 0, LSL);
703                          case 0x0:
704                            return new Uadd8RegCc(machInst, rd,
705                                                  rn, rm, 0, LSL);
706                          case 0x4:
707                            return new Usub8RegCc(machInst, rd,
708                                                  rn, rm, 0, LSL);
709                        }
710                        break;
711                      case 0x1:
712                        switch (op1) {
713                          case 0x1:
714                            return new Uqadd16Reg(machInst, rd, rn, rm, 0, LSL);
715                          case 0x2:
716                            return new UqasxReg(machInst, rd, rn, rm, 0, LSL);
717                          case 0x6:
718                            return new UqsaxReg(machInst, rd, rn, rm, 0, LSL);
719                          case 0x5:
720                            return new Uqsub16Reg(machInst, rd, rn, rm, 0, LSL);
721                          case 0x0:
722                            return new Uqadd8Reg(machInst, rd, rn, rm, 0, LSL);
723                          case 0x4:
724                            return new Uqsub8Reg(machInst, rd, rn, rm, 0, LSL);
725                        }
726                        break;
727                      case 0x2:
728                        switch (op1) {
729                          case 0x1:
730                            return new Uhadd16Reg(machInst, rd, rn, rm, 0, LSL);
731                          case 0x2:
732                            return new UhasxReg(machInst, rd, rn, rm, 0, LSL);
733                          case 0x6:
734                            return new UhsaxReg(machInst, rd, rn, rm, 0, LSL);
735                          case 0x5:
736                            return new Uhsub16Reg(machInst, rd, rn, rm, 0, LSL);
737                          case 0x0:
738                            return new Uhadd8Reg(machInst, rd, rn, rm, 0, LSL);
739                          case 0x4:
740                            return new Uhsub8Reg(machInst, rd, rn, rm, 0, LSL);
741                        }
742                        break;
743                    }
744                }
745            } else if (bits(op1, 3, 2) == 0x2 && bits(op2, 3, 2) == 0x2) {
746                const uint32_t op1 = bits(machInst, 21, 20);
747                const uint32_t op2 = bits(machInst, 5, 4);
748                switch (op1) {
749                  case 0x0:
750                    {
751                        IntRegIndex rd =
752                            (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
753                        IntRegIndex rm =
754                            (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
755                        switch (op2) {
756                          case 0x0:
757                            return new QaddRegCc(machInst, rd,
758                                                 rm, rn, 0, LSL);
759                          case 0x1:
760                            return new QdaddRegCc(machInst, rd,
761                                                  rm, rn, 0, LSL);
762                          case 0x2:
763                            return new QsubRegCc(machInst, rd,
764                                                 rm, rn, 0, LSL);
765                          case 0x3:
766                            return new QdsubRegCc(machInst, rd,
767                                                  rm, rn, 0, LSL);
768                        }
769                    }
770                    break;
771                  case 0x1:
772                    {
773                        IntRegIndex rd =
774                            (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
775                        IntRegIndex rm = rn;
776                        switch (op2) {
777                          case 0x0:
778                            return new Rev(machInst, rd, rm);
779                          case 0x1:
780                            return new Rev16(machInst, rd, rm);
781                          case 0x2:
782                            return new WarnUnimplemented("rbit", machInst);
783                          case 0x3:
784                            return new Revsh(machInst, rd, rm);
785                        }
786                    }
787                    break;
788                  case 0x2:
789                    if (op2 == 0) {
790                        return new WarnUnimplemented("sel", machInst);
791                    }
792                    break;
793                  case 0x3:
794                    if (op2 == 0) {
795                        return new WarnUnimplemented("clz", machInst);
796                    }
797                }
798            }
799            return new Unknown(machInst);
800        }
801    }
802    '''
803}};
804
805def format Thumb16ShiftAddSubMoveCmp() {{
806    decode_block = '''
807    {
808        const uint32_t imm5 = bits(machInst, 10, 6);
809        const uint32_t imm3 = bits(machInst, 8, 6);
810        const uint32_t imm8 = bits(machInst, 7, 0);
811        const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 2, 0);
812        const IntRegIndex rd8 = (IntRegIndex)(uint32_t)bits(machInst, 10, 8);
813        const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 5, 3);
814        const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 8, 6);
815        switch (bits(machInst, 13, 11)) {
816          case 0x0: // lsl
817            return new MovRegCc(machInst, rd, INTREG_ZERO, rn, imm5, LSL);
818          case 0x1: // lsr
819            return new MovRegCc(machInst, rd, INTREG_ZERO, rn, imm5, LSR);
820          case 0x2: // asr
821            return new MovRegCc(machInst, rd, INTREG_ZERO, rn, imm5, ASR);
822          case 0x3:
823            switch (bits(machInst, 10, 9)) {
824              case 0x0:
825                return new AddRegCc(machInst, rd, rn, rm, 0, LSL);
826              case 0x1:
827                return new SubRegCc(machInst, rd, rn, rm, 0, LSL);
828              case 0x2:
829                return new AddImmCc(machInst, rd, rn, imm3, true);
830              case 0x3:
831                return new SubImmCc(machInst, rd, rn, imm3, true);
832            }
833          case 0x4:
834            return new MovImmCc(machInst, rd8, INTREG_ZERO, imm8, false);
835          case 0x5:
836            return new CmpImmCc(machInst, INTREG_ZERO, rd8, imm8, true);
837          case 0x6:
838            return new AddImmCc(machInst, rd8, rd8, imm8, true);
839          case 0x7:
840            return new SubImmCc(machInst, rd8, rd8, imm8, true);
841        }
842    }
843    '''
844}};
845
846def format Thumb16DataProcessing() {{
847    decode_block = '''
848    {
849        const IntRegIndex rdn = (IntRegIndex)(uint32_t)bits(machInst, 2, 0);
850        const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 5, 3);
851        switch (bits(machInst, 9, 6)) {
852          case 0x0:
853            return new AndRegCc(machInst, rdn, rdn, rm, 0, LSL);
854          case 0x1:
855            return new EorRegCc(machInst, rdn, rdn, rm, 0, LSL);
856          case 0x2: //lsl
857            return new MovRegRegCc(machInst, rdn, INTREG_ZERO, rdn, rm, LSL);
858          case 0x3: //lsr
859            return new MovRegRegCc(machInst, rdn, INTREG_ZERO, rdn, rm, LSR);
860          case 0x4: //asr
861            return new MovRegRegCc(machInst, rdn, INTREG_ZERO, rdn, rm, ASR);
862          case 0x5:
863            return new AdcRegCc(machInst, rdn, rdn, rm, 0, LSL);
864          case 0x6:
865            return new SbcRegCc(machInst, rdn, rdn, rm, 0, LSL);
866          case 0x7: // ror
867            return new MovRegRegCc(machInst, rdn, INTREG_ZERO, rdn, rm, ROR);
868          case 0x8:
869            return new TstRegCc(machInst, INTREG_ZERO, rdn, rm, 0, LSL);
870          case 0x9:
871            return new RsbImmCc(machInst, rdn, rm, 0, true);
872          case 0xa:
873            return new CmpRegCc(machInst, INTREG_ZERO, rdn, rm, 0, LSL);
874          case 0xb:
875            return new CmnRegCc(machInst, INTREG_ZERO, rdn, rm, 0, LSL);
876          case 0xc:
877            return new OrrRegCc(machInst, rdn, rdn, rm, 0, LSL);
878          case 0xd:
879            return new MulCc(machInst, rdn, rm, rdn);
880          case 0xe:
881            return new BicRegCc(machInst, rdn, rdn, rm, 0, LSL);
882          case 0xf:
883            return new MvnRegCc(machInst, rdn, INTREG_ZERO, rm, 0, LSL);
884        }
885    }
886    '''
887}};
888
889def format Thumb16SpecDataAndBx() {{
890    decode_block = '''
891    {
892        const IntRegIndex rdn =
893            (IntRegIndex)(uint32_t)(bits(machInst, 2, 0) |
894                                    (bits(machInst, 7) << 3));
895        const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 6, 3);
896        switch (bits(machInst, 9, 8)) {
897          case 0x0:
898            return new AddReg(machInst, rdn, rdn, rm, 0, LSL);
899          case 0x1:
900            return new CmpRegCc(machInst, INTREG_ZERO, rdn, rm, 0, LSL);
901          case 0x2:
902            return new MovReg(machInst, rdn, INTREG_ZERO, rm, 0, LSL);
903          case 0x3:
904            if (bits(machInst, 7) == 0) {
905                return new BxReg(machInst,
906                                 (IntRegIndex)(uint32_t)bits(machInst, 6, 3),
907                                 COND_UC);
908            } else {
909                return new BlxReg(machInst,
910                                  (IntRegIndex)(uint32_t)bits(machInst, 6, 3),
911                                  COND_UC);
912            }
913        }
914    }
915    '''
916}};
917
918def format Thumb16Adr() {{
919    decode_block = '''
920    {
921        const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 10, 8);
922        const uint32_t imm8 = bits(machInst, 7, 0) << 2;
923        return new AdrImm(machInst, rd, (IntRegIndex)1, imm8, false);
924    }
925    '''
926}};
927
928def format Thumb16AddSp() {{
929    decode_block = '''
930    {
931        const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 10, 8);
932        const uint32_t imm8 = bits(machInst, 7, 0) << 2;
933        return new AddImm(machInst, rd, INTREG_SP, imm8, true);
934    }
935    '''
936}};
937
938def format Thumb16Misc() {{
939    decode_block = '''
940    {
941        switch (bits(machInst, 11, 8)) {
942          case 0x0:
943            if (bits(machInst, 7)) {
944                return new SubImm(machInst, INTREG_SP, INTREG_SP,
945                                   bits(machInst, 6, 0) << 2, true);
946            } else {
947                return new AddImm(machInst, INTREG_SP, INTREG_SP,
948                                   bits(machInst, 6, 0) << 2, true);
949            }
950          case 0x1:
951            return new Cbz(machInst,
952                           (bits(machInst, 9) << 6) |
953                           (bits(machInst, 7, 3) << 1),
954                           (IntRegIndex)(uint32_t)bits(machInst, 2, 0));
955          case 0x2:
956            {
957                const IntRegIndex rd =
958                    (IntRegIndex)(uint32_t)bits(machInst, 2, 0);
959                const IntRegIndex rm =
960                    (IntRegIndex)(uint32_t)bits(machInst, 5, 3);
961                switch (bits(machInst, 7, 6)) {
962                  case 0x0:
963                    return new Sxth(machInst, rd, 0, rm);
964                  case 0x1:
965                    return new Sxtb(machInst, rd, 0, rm);
966                  case 0x2:
967                    return new Uxth(machInst, rd, 0, rm);
968                  case 0x3:
969                    return new Uxtb(machInst, rd, 0, rm);
970                }
971            }
972          case 0x3:
973            return new Cbz(machInst,
974                           (bits(machInst, 9) << 6) |
975                           (bits(machInst, 7, 3) << 1),
976                           (IntRegIndex)(uint32_t)bits(machInst, 2, 0));
977          case 0x4:
978          case 0x5:
979            {
980                const uint32_t m = bits(machInst, 8);
981                const uint32_t regList = bits(machInst, 7, 0) | (m << 14);
982                return new LdmStm(machInst, INTREG_SP, false, false, false,
983                                  true, false, regList);
984            }
985          case 0x6:
986            {
987                const uint32_t opBits = bits(machInst, 7, 5);
988                if (opBits == 2) {
989                    return new WarnUnimplemented("setend", machInst);
990                } else if (opBits == 3) {
991                    return new WarnUnimplemented("cps", machInst);
992                }
993            }
994          case 0x9:
995            return new Cbnz(machInst,
996                            (bits(machInst, 9) << 6) |
997                            (bits(machInst, 7, 3) << 1),
998                            (IntRegIndex)(uint32_t)bits(machInst, 2, 0));
999          case 0xa:
1000            {
1001                IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 2, 0);
1002                IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 5, 3);
1003                switch (bits(machInst, 7, 6)) {
1004                  case 0x0:
1005                    return new Rev(machInst, rd, rm);
1006                  case 0x1:
1007                    return new Rev16(machInst, rd, rm);
1008                  case 0x3:
1009                    return new Revsh(machInst, rd, rm);
1010                  default:
1011                    break;
1012                }
1013            }
1014            break;
1015          case 0xb:
1016            return new Cbnz(machInst,
1017                            (bits(machInst, 9) << 6) |
1018                            (bits(machInst, 7, 3) << 1),
1019                            (IntRegIndex)(uint32_t)bits(machInst, 2, 0));
1020          case 0xc:
1021          case 0xd:
1022            {
1023                const uint32_t p = bits(machInst, 8);
1024                const uint32_t regList = bits(machInst, 7, 0) | (p << 15);
1025                return new LdmStm(machInst, INTREG_SP, true, true, false,
1026                                  true, true, regList);
1027            }
1028          case 0xe:
1029            return new WarnUnimplemented("bkpt", machInst);
1030          case 0xf:
1031            if (bits(machInst, 3, 0) != 0)
1032                return new WarnUnimplemented("it", machInst);
1033            switch (bits(machInst, 7, 4)) {
1034              case 0x0:
1035                return new WarnUnimplemented("nop", machInst);
1036              case 0x1:
1037                return new WarnUnimplemented("yield", machInst);
1038              case 0x2:
1039                return new WarnUnimplemented("wfe", machInst);
1040              case 0x3:
1041                return new WarnUnimplemented("wfi", machInst);
1042              case 0x4:
1043                return new WarnUnimplemented("sev", machInst);
1044              default:
1045                return new WarnUnimplemented("unallocated_hint", machInst);
1046            }
1047          default:
1048            break;
1049        }
1050        return new Unknown(machInst);
1051    }
1052    '''
1053}};
1054
1055def format Thumb32DataProcModImm() {{
1056
1057    def decInst(mnem, dest="rd", op1="rn"):
1058        return '''
1059            if (s) {
1060                return new %(mnem)sImmCc(machInst, %(dest)s,
1061                                          %(op1)s, imm, rotC);
1062            } else {
1063                return new %(mnem)sImm(machInst, %(dest)s,
1064                                        %(op1)s, imm, rotC);
1065            }
1066        ''' % {"mnem" : mnem, "dest" : dest, "op1" : op1}
1067
1068    decode_block = '''
1069    {
1070        const uint32_t op = bits(machInst, 24, 21);
1071        const bool s = (bits(machInst, 20) == 1);
1072        const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
1073        const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
1074        const uint32_t ctrlImm = bits(machInst.instBits, 26) << 3 |
1075                                 bits(machInst, 14, 12);
1076        const bool rotC = ctrlImm > 3;
1077        const uint32_t dataImm = bits(machInst, 7, 0);
1078        const uint32_t imm = modified_imm(ctrlImm, dataImm);
1079        switch (op) {
1080          case 0x0:
1081            if (rd == INTREG_PC) {
1082                %(tst)s
1083            } else {
1084                %(and)s
1085            }
1086          case 0x1:
1087            %(bic)s
1088          case 0x2:
1089            if (rn == INTREG_PC) {
1090                %(mov)s
1091            } else {
1092                %(orr)s
1093            }
1094          case 0x3:
1095            if (rn == INTREG_PC) {
1096                %(mvn)s
1097            } else {
1098                %(orn)s
1099            }
1100          case 0x4:
1101            if (rd == INTREG_PC) {
1102                %(teq)s
1103            } else {
1104                %(eor)s
1105            }
1106          case 0x8:
1107            if (rd == INTREG_PC) {
1108                %(cmn)s
1109            } else {
1110                %(add)s
1111            }
1112          case 0xa:
1113            %(adc)s
1114          case 0xb:
1115            %(sbc)s
1116          case 0xd:
1117            if (rd == INTREG_PC) {
1118                %(cmp)s
1119            } else {
1120                %(sub)s
1121            }
1122          case 0xe:
1123            %(rsb)s
1124          default:
1125            return new Unknown(machInst);
1126        }
1127    }
1128    ''' % {
1129        "tst" : decInst("Tst", "INTREG_ZERO"),
1130        "and" : decInst("And"),
1131        "bic" : decInst("Bic"),
1132        "mov" : decInst("Mov", op1="INTREG_ZERO"),
1133        "orr" : decInst("Orr"),
1134        "mvn" : decInst("Mvn", op1="INTREG_ZERO"),
1135        "orn" : decInst("Orn"),
1136        "teq" : decInst("Teq", dest="INTREG_ZERO"),
1137        "eor" : decInst("Eor"),
1138        "cmn" : decInst("Cmn", dest="INTREG_ZERO"),
1139        "add" : decInst("Add"),
1140        "adc" : decInst("Adc"),
1141        "sbc" : decInst("Sbc"),
1142        "cmp" : decInst("Cmp", dest="INTREG_ZERO"),
1143        "sub" : decInst("Sub"),
1144        "rsb" : decInst("Rsb")
1145    }
1146}};
1147
1148def format Thumb32DataProcPlainBin() {{
1149    decode_block = '''
1150    {
1151        const uint32_t op = bits(machInst, 24, 20);
1152        const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
1153        const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
1154        switch (op) {
1155          case 0x0:
1156            {
1157                const uint32_t imm = bits(machInst, 7, 0) |
1158                                     (bits(machInst, 14, 12) << 8) |
1159                                     (bits(machInst, 26) << 11);
1160                if (rn == 0xf) {
1161                    return new AdrImm(machInst, rd, (IntRegIndex)1,
1162                                      imm, false);
1163                } else {
1164                    return new AddImm(machInst, rd, rn, imm, true);
1165                }
1166            }
1167          case 0x4:
1168            {
1169                const uint32_t imm = bits(machInst, 7, 0) |
1170                                     (bits(machInst, 14, 12) << 8) |
1171                                     (bits(machInst, 26) << 11) |
1172                                     (bits(machInst, 19, 16) << 12);
1173                return new MovImm(machInst, rd, INTREG_ZERO, imm, true);
1174            }
1175          case 0xa:
1176            {
1177                const uint32_t imm = bits(machInst, 7, 0) |
1178                                     (bits(machInst, 14, 12) << 8) |
1179                                     (bits(machInst, 26) << 11);
1180                if (rn == 0xf) {
1181                    return new AdrImm(machInst, rd, (IntRegIndex)0,
1182                                      imm, false);
1183                } else {
1184                    return new SubImm(machInst, rd, rn, imm, true);
1185                }
1186            }
1187          case 0xc:
1188            {
1189                const uint32_t imm = bits(machInst, 7, 0) |
1190                                     (bits(machInst, 14, 12) << 8) |
1191                                     (bits(machInst, 26) << 11) |
1192                                     (bits(machInst, 19, 16) << 12);
1193                return new MovtImm(machInst, rd, rd, imm, true);
1194            }
1195          case 0x12:
1196            if (!(bits(machInst, 14, 12) || bits(machInst, 7, 6))) {
1197                const uint32_t satImm = bits(machInst, 4, 0);
1198                return new Ssat16(machInst, rd, satImm + 1, rn);
1199            }
1200            // Fall through on purpose...
1201          case 0x10:
1202            {
1203                const uint32_t satImm = bits(machInst, 4, 0);
1204                const uint32_t imm = bits(machInst, 7, 6) |
1205                                     (bits(machInst, 14, 12) << 2);
1206                const ArmShiftType type =
1207                    (ArmShiftType)(uint32_t)bits(machInst, 21, 20);
1208                return new Ssat(machInst, rd, satImm + 1, rn, imm, type);
1209            }
1210          case 0x14:
1211            return new WarnUnimplemented("sbfx", machInst);
1212          case 0x16:
1213            if (rn == 0xf) {
1214                return new WarnUnimplemented("bfc", machInst);
1215            } else {
1216                return new WarnUnimplemented("bfi", machInst);
1217            }
1218          case 0x1a:
1219            if (!(bits(machInst, 14, 12) || bits(machInst, 7, 6))) {
1220                const uint32_t satImm = bits(machInst, 4, 0);
1221                return new Usat16(machInst, rd, satImm, rn);
1222            }
1223            // Fall through on purpose...
1224          case 0x18:
1225            {
1226                const uint32_t satImm = bits(machInst, 4, 0);
1227                const uint32_t imm = bits(machInst, 7, 6) |
1228                                     (bits(machInst, 14, 12) << 2);
1229                const ArmShiftType type =
1230                    (ArmShiftType)(uint32_t)bits(machInst, 21, 20);
1231                return new Usat(machInst, rd, satImm, rn, imm, type);
1232            }
1233          case 0x1c:
1234            return new WarnUnimplemented("ubfx", machInst);
1235          default:
1236            return new Unknown(machInst);
1237        }
1238    }
1239    '''
1240}};
1241
1242def format Thumb32DataProcShiftReg() {{
1243
1244    def decInst(mnem, dest="rd", op1="rn"):
1245        return '''
1246            if (s) {
1247                return new %(mnem)sRegCc(machInst, %(dest)s,
1248                                          %(op1)s, rm, amt, type);
1249            } else {
1250                return new %(mnem)sReg(machInst, %(dest)s,
1251                                        %(op1)s, rm, amt, type);
1252            }
1253        ''' % {"mnem" : mnem, "dest" : dest, "op1" : op1}
1254
1255    decode_block = '''
1256    {
1257        const uint32_t op = bits(machInst, 24, 21);
1258        const bool s = (bits(machInst, 20) == 1);
1259        const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
1260        const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
1261        const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
1262        const uint32_t amt = (bits(machInst, 14, 12) << 2) |
1263                              bits(machInst, 7, 6);
1264        const ArmShiftType type = (ArmShiftType)(uint32_t)bits(machInst, 5, 4);
1265        switch (op) {
1266          case 0x0:
1267            if (rd == INTREG_PC) {
1268                %(tst)s
1269            } else {
1270                %(and)s
1271            }
1272          case 0x1:
1273            %(bic)s
1274          case 0x2:
1275            if (rn == INTREG_PC) {
1276                %(mov)s
1277            } else {
1278                %(orr)s
1279            }
1280          case 0x3:
1281            if (rn == INTREG_PC) {
1282                %(mvn)s
1283            } else {
1284                %(orn)s
1285            }
1286          case 0x4:
1287            if (rd == INTREG_PC) {
1288                %(teq)s
1289            } else {
1290                %(eor)s
1291            }
1292          case 0x6:
1293            if (type) {
1294                return new PkhtbReg(machInst, rd, rn, rm, amt, type);
1295            } else {
1296                return new PkhbtReg(machInst, rd, rn, rm, amt, type);
1297            }
1298          case 0x8:
1299            if (rd == INTREG_PC) {
1300                %(cmn)s
1301            } else {
1302                %(add)s
1303            }
1304          case 0xa:
1305            %(adc)s
1306          case 0xb:
1307            %(sbc)s
1308          case 0xd:
1309            if (rd == INTREG_PC) {
1310                %(cmp)s
1311            } else {
1312                %(sub)s
1313            }
1314          case 0xe:
1315            %(rsb)s
1316          default:
1317            return new Unknown(machInst);
1318        }
1319    }
1320    ''' % {
1321        "tst" : decInst("Tst", "INTREG_ZERO"),
1322        "and" : decInst("And"),
1323        "bic" : decInst("Bic"),
1324        "mov" : decInst("Mov", op1="INTREG_ZERO"),
1325        "orr" : decInst("Orr"),
1326        "mvn" : decInst("Mvn", op1="INTREG_ZERO"),
1327        "orn" : decInst("Orn"),
1328        "teq" : decInst("Teq", "INTREG_ZERO"),
1329        "eor" : decInst("Eor"),
1330        "cmn" : decInst("Cmn", "INTREG_ZERO"),
1331        "add" : decInst("Add"),
1332        "adc" : decInst("Adc"),
1333        "sbc" : decInst("Sbc"),
1334        "cmp" : decInst("Cmp", "INTREG_ZERO"),
1335        "sub" : decInst("Sub"),
1336        "rsb" : decInst("Rsb")
1337    }
1338}};
1339