data.isa revision 7250
17139Sgblack@eecs.umich.edu// Copyright (c) 2010 ARM Limited
27139Sgblack@eecs.umich.edu// All rights reserved
37139Sgblack@eecs.umich.edu//
47139Sgblack@eecs.umich.edu// The license below extends only to copyright in the software and shall
57139Sgblack@eecs.umich.edu// not be construed as granting a license to any other intellectual
67139Sgblack@eecs.umich.edu// property including but not limited to intellectual property relating
77139Sgblack@eecs.umich.edu// to a hardware implementation of the functionality of the software
87139Sgblack@eecs.umich.edu// licensed hereunder.  You may use the software subject to the license
97139Sgblack@eecs.umich.edu// terms below provided that you ensure that this notice is replicated
107139Sgblack@eecs.umich.edu// unmodified and in its entirety in all distributions of the software,
117139Sgblack@eecs.umich.edu// modified or unmodified, in source code or in binary form.
127139Sgblack@eecs.umich.edu//
137139Sgblack@eecs.umich.edu// Redistribution and use in source and binary forms, with or without
147139Sgblack@eecs.umich.edu// modification, are permitted provided that the following conditions are
157139Sgblack@eecs.umich.edu// met: redistributions of source code must retain the above copyright
167139Sgblack@eecs.umich.edu// notice, this list of conditions and the following disclaimer;
177139Sgblack@eecs.umich.edu// redistributions in binary form must reproduce the above copyright
187139Sgblack@eecs.umich.edu// notice, this list of conditions and the following disclaimer in the
197139Sgblack@eecs.umich.edu// documentation and/or other materials provided with the distribution;
207139Sgblack@eecs.umich.edu// neither the name of the copyright holders nor the names of its
217139Sgblack@eecs.umich.edu// contributors may be used to endorse or promote products derived from
227139Sgblack@eecs.umich.edu// this software without specific prior written permission.
237139Sgblack@eecs.umich.edu//
247139Sgblack@eecs.umich.edu// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
257139Sgblack@eecs.umich.edu// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
267139Sgblack@eecs.umich.edu// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
277139Sgblack@eecs.umich.edu// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
287139Sgblack@eecs.umich.edu// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
297139Sgblack@eecs.umich.edu// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
307139Sgblack@eecs.umich.edu// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
317139Sgblack@eecs.umich.edu// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
327139Sgblack@eecs.umich.edu// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
337139Sgblack@eecs.umich.edu// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
347139Sgblack@eecs.umich.edu// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
357139Sgblack@eecs.umich.edu//
367139Sgblack@eecs.umich.edu// Authors: Gabe Black
377139Sgblack@eecs.umich.edu
387243Sgblack@eecs.umich.edudef format ArmUsad() {{
397243Sgblack@eecs.umich.edu    decode_block = '''
407243Sgblack@eecs.umich.edu    {
417243Sgblack@eecs.umich.edu        const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
427243Sgblack@eecs.umich.edu        const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
437243Sgblack@eecs.umich.edu        const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
447243Sgblack@eecs.umich.edu        const IntRegIndex ra = (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
457243Sgblack@eecs.umich.edu        if (ra == 0xf) {
467243Sgblack@eecs.umich.edu            return new Usad8(machInst, rd, rn, rm);
477243Sgblack@eecs.umich.edu        } else {
487243Sgblack@eecs.umich.edu            return new Usada8(machInst, rd, rn, rm, ra);
497243Sgblack@eecs.umich.edu        }
507243Sgblack@eecs.umich.edu    }
517243Sgblack@eecs.umich.edu    '''
527243Sgblack@eecs.umich.edu}};
537243Sgblack@eecs.umich.edu
547139Sgblack@eecs.umich.edudef format ArmDataProcReg() {{
557188Sgblack@eecs.umich.edu    pclr = '''
567188Sgblack@eecs.umich.edu        return new %(className)ssRegPclr(machInst, %(dest)s,
577188Sgblack@eecs.umich.edu                                        %(op1)s, rm, imm5,
587188Sgblack@eecs.umich.edu                                        type);
597188Sgblack@eecs.umich.edu    '''
607139Sgblack@eecs.umich.edu    instDecode = '''
617139Sgblack@eecs.umich.edu          case %(opcode)#x:
627139Sgblack@eecs.umich.edu            if (immShift) {
637139Sgblack@eecs.umich.edu                if (setCc) {
647188Sgblack@eecs.umich.edu                    if (%(dest)s == INTREG_PC) {
657188Sgblack@eecs.umich.edu                        %(pclr)s
667188Sgblack@eecs.umich.edu                    } else {
677188Sgblack@eecs.umich.edu                        return new %(className)sRegCc(machInst, %(dest)s,
687188Sgblack@eecs.umich.edu                                                      %(op1)s, rm, imm5, type);
697188Sgblack@eecs.umich.edu                    }
707139Sgblack@eecs.umich.edu                } else {
717146Sgblack@eecs.umich.edu                    return new %(className)sReg(machInst, %(dest)s, %(op1)s,
727141Sgblack@eecs.umich.edu                                                 rm, imm5, type);
737139Sgblack@eecs.umich.edu                }
747139Sgblack@eecs.umich.edu            } else {
757139Sgblack@eecs.umich.edu                if (setCc) {
767146Sgblack@eecs.umich.edu                    return new %(className)sRegRegCc(machInst, %(dest)s,
777141Sgblack@eecs.umich.edu                                                      %(op1)s, rm, rs, type);
787139Sgblack@eecs.umich.edu                } else {
797146Sgblack@eecs.umich.edu                    return new %(className)sRegReg(machInst, %(dest)s,
807141Sgblack@eecs.umich.edu                                                    %(op1)s, rm, rs, type);
817139Sgblack@eecs.umich.edu                }
827139Sgblack@eecs.umich.edu            }
837139Sgblack@eecs.umich.edu            break;
847139Sgblack@eecs.umich.edu    '''
857139Sgblack@eecs.umich.edu
867188Sgblack@eecs.umich.edu    def instCode(opcode, mnem, useDest = True, useOp1 = True):
877188Sgblack@eecs.umich.edu        global pclr
887188Sgblack@eecs.umich.edu        if useDest:
897188Sgblack@eecs.umich.edu            dest = "rd"
907188Sgblack@eecs.umich.edu        else:
917188Sgblack@eecs.umich.edu            dest = "INTREG_ZERO"
927188Sgblack@eecs.umich.edu        if useOp1:
937188Sgblack@eecs.umich.edu            op1 = "rn"
947188Sgblack@eecs.umich.edu        else:
957188Sgblack@eecs.umich.edu            op1 = "INTREG_ZERO"
967188Sgblack@eecs.umich.edu        global instDecode, pclrCode
977188Sgblack@eecs.umich.edu        substDict = { "className": mnem.capitalize(),
987188Sgblack@eecs.umich.edu                      "opcode": opcode,
997188Sgblack@eecs.umich.edu                      "dest": dest,
1007188Sgblack@eecs.umich.edu                      "op1": op1 }
1017188Sgblack@eecs.umich.edu        if useDest:
1027188Sgblack@eecs.umich.edu            substDict["pclr"] = pclr % substDict
1037188Sgblack@eecs.umich.edu        else:
1047188Sgblack@eecs.umich.edu            substDict["pclr"] = ""
1057188Sgblack@eecs.umich.edu        return instDecode % substDict
1067139Sgblack@eecs.umich.edu
1077139Sgblack@eecs.umich.edu    decode_block = '''
1087139Sgblack@eecs.umich.edu    {
1097139Sgblack@eecs.umich.edu        const bool immShift = (bits(machInst, 4) == 0);
1107139Sgblack@eecs.umich.edu        const bool setCc = (bits(machInst, 20) == 1);
1117139Sgblack@eecs.umich.edu        const uint32_t imm5 = bits(machInst, 11, 7);
1127139Sgblack@eecs.umich.edu        const ArmShiftType type = (ArmShiftType)(uint32_t)bits(machInst, 6, 5);
1137139Sgblack@eecs.umich.edu        const IntRegIndex rd = (IntRegIndex)(uint32_t)RD;
1147139Sgblack@eecs.umich.edu        const IntRegIndex rn = (IntRegIndex)(uint32_t)RN;
1157139Sgblack@eecs.umich.edu        const IntRegIndex rm = (IntRegIndex)(uint32_t)RM;
1167139Sgblack@eecs.umich.edu        const IntRegIndex rs = (IntRegIndex)(uint32_t)RS;
1177139Sgblack@eecs.umich.edu        switch (OPCODE) {
1187139Sgblack@eecs.umich.edu    '''
1197139Sgblack@eecs.umich.edu    decode_block += instCode(0x0, "and")
1207139Sgblack@eecs.umich.edu    decode_block += instCode(0x1, "eor")
1217139Sgblack@eecs.umich.edu    decode_block += instCode(0x2, "sub")
1227139Sgblack@eecs.umich.edu    decode_block += instCode(0x3, "rsb")
1237139Sgblack@eecs.umich.edu    decode_block += instCode(0x4, "add")
1247139Sgblack@eecs.umich.edu    decode_block += instCode(0x5, "adc")
1257139Sgblack@eecs.umich.edu    decode_block += instCode(0x6, "sbc")
1267139Sgblack@eecs.umich.edu    decode_block += instCode(0x7, "rsc")
1277188Sgblack@eecs.umich.edu    decode_block += instCode(0x8, "tst", useDest = False)
1287188Sgblack@eecs.umich.edu    decode_block += instCode(0x9, "teq", useDest = False)
1297188Sgblack@eecs.umich.edu    decode_block += instCode(0xa, "cmp", useDest = False)
1307188Sgblack@eecs.umich.edu    decode_block += instCode(0xb, "cmn", useDest = False)
1317139Sgblack@eecs.umich.edu    decode_block += instCode(0xc, "orr")
1327188Sgblack@eecs.umich.edu    decode_block += instCode(0xd, "mov", useOp1 = False)
1337139Sgblack@eecs.umich.edu    decode_block += instCode(0xe, "bic")
1347188Sgblack@eecs.umich.edu    decode_block += instCode(0xf, "mvn", useOp1 = False)
1357139Sgblack@eecs.umich.edu    decode_block += '''
1367139Sgblack@eecs.umich.edu          default:
1377139Sgblack@eecs.umich.edu            return new Unknown(machInst);
1387139Sgblack@eecs.umich.edu        }
1397139Sgblack@eecs.umich.edu    }
1407139Sgblack@eecs.umich.edu    '''
1417139Sgblack@eecs.umich.edu}};
1427139Sgblack@eecs.umich.edu
1437210Sgblack@eecs.umich.edudef format ArmPackUnpackSatReverse() {{
1447210Sgblack@eecs.umich.edu    decode_block = '''
1457210Sgblack@eecs.umich.edu    {
1467210Sgblack@eecs.umich.edu        const uint32_t op1 = bits(machInst, 22, 20);
1477210Sgblack@eecs.umich.edu        const uint32_t a = bits(machInst, 19, 16);
1487210Sgblack@eecs.umich.edu        const uint32_t op2 = bits(machInst, 7, 5);
1497210Sgblack@eecs.umich.edu        if (bits(op2, 0) == 0) {
1507227Sgblack@eecs.umich.edu            const IntRegIndex rn =
1517227Sgblack@eecs.umich.edu                (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
1527227Sgblack@eecs.umich.edu            const IntRegIndex rd =
1537227Sgblack@eecs.umich.edu                (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
1547227Sgblack@eecs.umich.edu            const uint32_t satImm = bits(machInst, 20, 16);
1557227Sgblack@eecs.umich.edu            const uint32_t imm = bits(machInst, 11, 7);
1567227Sgblack@eecs.umich.edu            const ArmShiftType type =
1577227Sgblack@eecs.umich.edu                (ArmShiftType)(uint32_t)bits(machInst, 6, 5);
1587210Sgblack@eecs.umich.edu            if (op1 == 0) {
1597237Sgblack@eecs.umich.edu                if (type) {
1607237Sgblack@eecs.umich.edu                    return new PkhtbReg(machInst, rd, (IntRegIndex)a,
1617237Sgblack@eecs.umich.edu                                        rn, imm, type);
1627237Sgblack@eecs.umich.edu                } else {
1637237Sgblack@eecs.umich.edu                    return new PkhbtReg(machInst, rd, (IntRegIndex)a,
1647237Sgblack@eecs.umich.edu                                        rn, imm, type);
1657237Sgblack@eecs.umich.edu                }
1667210Sgblack@eecs.umich.edu            } else if (bits(op1, 2, 1) == 1) {
1677227Sgblack@eecs.umich.edu                return new Ssat(machInst, rd, satImm + 1, rn, imm, type);
1687210Sgblack@eecs.umich.edu            } else if (bits(op1, 2, 1) == 3) {
1697227Sgblack@eecs.umich.edu                return new Usat(machInst, rd, satImm, rn, imm, type);
1707210Sgblack@eecs.umich.edu            }
1717210Sgblack@eecs.umich.edu            return new Unknown(machInst);
1727210Sgblack@eecs.umich.edu        }
1737210Sgblack@eecs.umich.edu        switch (op1) {
1747210Sgblack@eecs.umich.edu          case 0x0:
1757240Sgblack@eecs.umich.edu            {
1767235Sgblack@eecs.umich.edu                const IntRegIndex rn =
1777235Sgblack@eecs.umich.edu                    (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
1787235Sgblack@eecs.umich.edu                const IntRegIndex rd =
1797235Sgblack@eecs.umich.edu                    (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
1807235Sgblack@eecs.umich.edu                const IntRegIndex rm =
1817235Sgblack@eecs.umich.edu                    (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
1827240Sgblack@eecs.umich.edu                if (op2 == 0x3) {
1837240Sgblack@eecs.umich.edu                    const uint32_t rotation =
1847240Sgblack@eecs.umich.edu                        (uint32_t)bits(machInst, 11, 10) << 3;
1857240Sgblack@eecs.umich.edu                    if (a == 0xf) {
1867240Sgblack@eecs.umich.edu                        return new Sxtb16(machInst, rd, rotation, rm);
1877240Sgblack@eecs.umich.edu                    } else {
1887240Sgblack@eecs.umich.edu                        return new Sxtab16(machInst, rd, rn, rm, rotation);
1897240Sgblack@eecs.umich.edu                    }
1907240Sgblack@eecs.umich.edu                } else if (op2 == 0x5) {
1917240Sgblack@eecs.umich.edu                    return new Sel(machInst, rd, rn, rm);
1927210Sgblack@eecs.umich.edu                }
1937210Sgblack@eecs.umich.edu            }
1947210Sgblack@eecs.umich.edu            break;
1957210Sgblack@eecs.umich.edu          case 0x2:
1967210Sgblack@eecs.umich.edu            if (op2 == 0x1) {
1977227Sgblack@eecs.umich.edu                const IntRegIndex rn =
1987227Sgblack@eecs.umich.edu                    (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
1997227Sgblack@eecs.umich.edu                const IntRegIndex rd =
2007227Sgblack@eecs.umich.edu                    (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
2017227Sgblack@eecs.umich.edu                const uint32_t satImm = bits(machInst, 20, 16);
2027227Sgblack@eecs.umich.edu                return new Ssat16(machInst, rd, satImm + 1, rn);
2037210Sgblack@eecs.umich.edu            } else if (op2 == 0x3) {
2047235Sgblack@eecs.umich.edu                const IntRegIndex rn =
2057235Sgblack@eecs.umich.edu                    (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
2067235Sgblack@eecs.umich.edu                const IntRegIndex rd =
2077235Sgblack@eecs.umich.edu                    (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
2087235Sgblack@eecs.umich.edu                const IntRegIndex rm =
2097235Sgblack@eecs.umich.edu                    (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
2107235Sgblack@eecs.umich.edu                const uint32_t rotation =
2117235Sgblack@eecs.umich.edu                    (uint32_t)bits(machInst, 11, 10) << 3;
2127210Sgblack@eecs.umich.edu                if (a == 0xf) {
2137235Sgblack@eecs.umich.edu                    return new Sxtb(machInst, rd, rotation, rm);
2147210Sgblack@eecs.umich.edu                } else {
2157235Sgblack@eecs.umich.edu                    return new Sxtab(machInst, rd, rn, rm, rotation);
2167210Sgblack@eecs.umich.edu                }
2177210Sgblack@eecs.umich.edu            }
2187210Sgblack@eecs.umich.edu            break;
2197210Sgblack@eecs.umich.edu          case 0x3:
2207210Sgblack@eecs.umich.edu            if (op2 == 0x1) {
2217211Sgblack@eecs.umich.edu                IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
2227211Sgblack@eecs.umich.edu                IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
2237211Sgblack@eecs.umich.edu                return new Rev(machInst, rd, rm);
2247210Sgblack@eecs.umich.edu            } else if (op2 == 0x3) {
2257235Sgblack@eecs.umich.edu                const IntRegIndex rn =
2267235Sgblack@eecs.umich.edu                    (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
2277235Sgblack@eecs.umich.edu                const IntRegIndex rd =
2287235Sgblack@eecs.umich.edu                    (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
2297235Sgblack@eecs.umich.edu                const IntRegIndex rm =
2307235Sgblack@eecs.umich.edu                    (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
2317235Sgblack@eecs.umich.edu                const uint32_t rotation =
2327235Sgblack@eecs.umich.edu                    (uint32_t)bits(machInst, 11, 10) << 3;
2337210Sgblack@eecs.umich.edu                if (a == 0xf) {
2347235Sgblack@eecs.umich.edu                    return new Sxth(machInst, rd, rotation, rm);
2357210Sgblack@eecs.umich.edu                } else {
2367235Sgblack@eecs.umich.edu                    return new Sxtah(machInst, rd, rn, rm, rotation);
2377210Sgblack@eecs.umich.edu                }
2387210Sgblack@eecs.umich.edu            } else if (op2 == 0x5) {
2397211Sgblack@eecs.umich.edu                IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
2407211Sgblack@eecs.umich.edu                IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
2417211Sgblack@eecs.umich.edu                return new Rev16(machInst, rd, rm);
2427210Sgblack@eecs.umich.edu            }
2437210Sgblack@eecs.umich.edu            break;
2447210Sgblack@eecs.umich.edu          case 0x4:
2457210Sgblack@eecs.umich.edu            if (op2 == 0x3) {
2467235Sgblack@eecs.umich.edu                const IntRegIndex rn =
2477235Sgblack@eecs.umich.edu                    (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
2487235Sgblack@eecs.umich.edu                const IntRegIndex rd =
2497235Sgblack@eecs.umich.edu                    (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
2507235Sgblack@eecs.umich.edu                const IntRegIndex rm =
2517235Sgblack@eecs.umich.edu                    (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
2527235Sgblack@eecs.umich.edu                const uint32_t rotation =
2537235Sgblack@eecs.umich.edu                    (uint32_t)bits(machInst, 11, 10) << 3;
2547210Sgblack@eecs.umich.edu                if (a == 0xf) {
2557235Sgblack@eecs.umich.edu                    return new Uxtb16(machInst, rd, rotation, rm);
2567210Sgblack@eecs.umich.edu                } else {
2577235Sgblack@eecs.umich.edu                    return new Uxtab16(machInst, rd, rn, rm, rotation);
2587210Sgblack@eecs.umich.edu                }
2597210Sgblack@eecs.umich.edu            }
2607210Sgblack@eecs.umich.edu            break;
2617210Sgblack@eecs.umich.edu          case 0x6:
2627210Sgblack@eecs.umich.edu            if (op2 == 0x1) {
2637227Sgblack@eecs.umich.edu                const IntRegIndex rn =
2647227Sgblack@eecs.umich.edu                    (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
2657227Sgblack@eecs.umich.edu                const IntRegIndex rd =
2667227Sgblack@eecs.umich.edu                    (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
2677227Sgblack@eecs.umich.edu                const uint32_t satImm = bits(machInst, 20, 16);
2687227Sgblack@eecs.umich.edu                return new Usat16(machInst, rd, satImm, rn);
2697210Sgblack@eecs.umich.edu            } else if (op2 == 0x3) {
2707235Sgblack@eecs.umich.edu                const IntRegIndex rn =
2717235Sgblack@eecs.umich.edu                    (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
2727235Sgblack@eecs.umich.edu                const IntRegIndex rd =
2737235Sgblack@eecs.umich.edu                    (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
2747235Sgblack@eecs.umich.edu                const IntRegIndex rm =
2757235Sgblack@eecs.umich.edu                    (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
2767235Sgblack@eecs.umich.edu                const uint32_t rotation =
2777235Sgblack@eecs.umich.edu                    (uint32_t)bits(machInst, 11, 10) << 3;
2787210Sgblack@eecs.umich.edu                if (a == 0xf) {
2797235Sgblack@eecs.umich.edu                    return new Uxtb(machInst, rd, rotation, rm);
2807210Sgblack@eecs.umich.edu                } else {
2817235Sgblack@eecs.umich.edu                    return new Uxtab(machInst, rd, rn, rm, rotation);
2827210Sgblack@eecs.umich.edu                }
2837210Sgblack@eecs.umich.edu            }
2847210Sgblack@eecs.umich.edu            break;
2857210Sgblack@eecs.umich.edu          case 0x7:
2867250Sgblack@eecs.umich.edu            {
2877235Sgblack@eecs.umich.edu                const IntRegIndex rn =
2887235Sgblack@eecs.umich.edu                    (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
2897235Sgblack@eecs.umich.edu                const IntRegIndex rd =
2907235Sgblack@eecs.umich.edu                    (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
2917235Sgblack@eecs.umich.edu                const IntRegIndex rm =
2927235Sgblack@eecs.umich.edu                    (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
2937250Sgblack@eecs.umich.edu                if (op2 == 0x1) {
2947250Sgblack@eecs.umich.edu                    return new Rbit(machInst, rd, rm);
2957250Sgblack@eecs.umich.edu                } else if (op2 == 0x3) {
2967250Sgblack@eecs.umich.edu                    const uint32_t rotation =
2977250Sgblack@eecs.umich.edu                        (uint32_t)bits(machInst, 11, 10) << 3;
2987250Sgblack@eecs.umich.edu                    if (a == 0xf) {
2997250Sgblack@eecs.umich.edu                        return new Uxth(machInst, rd, rotation, rm);
3007250Sgblack@eecs.umich.edu                    } else {
3017250Sgblack@eecs.umich.edu                        return new Uxtah(machInst, rd, rn, rm, rotation);
3027250Sgblack@eecs.umich.edu                    }
3037250Sgblack@eecs.umich.edu                } else if (op2 == 0x5) {
3047250Sgblack@eecs.umich.edu                    return new Revsh(machInst, rd, rm);
3057210Sgblack@eecs.umich.edu                }
3067210Sgblack@eecs.umich.edu            }
3077210Sgblack@eecs.umich.edu            break;
3087210Sgblack@eecs.umich.edu        }
3097210Sgblack@eecs.umich.edu        return new Unknown(machInst);
3107210Sgblack@eecs.umich.edu    }
3117210Sgblack@eecs.umich.edu    '''
3127210Sgblack@eecs.umich.edu}};
3137210Sgblack@eecs.umich.edu
3147194Sgblack@eecs.umich.edudef format ArmParallelAddSubtract() {{
3157194Sgblack@eecs.umich.edu    decode_block='''
3167194Sgblack@eecs.umich.edu    {
3177194Sgblack@eecs.umich.edu        const uint32_t op1 = bits(machInst, 21, 20);
3187194Sgblack@eecs.umich.edu        const uint32_t op2 = bits(machInst, 7, 5);
3197194Sgblack@eecs.umich.edu        const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
3207194Sgblack@eecs.umich.edu        const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
3217194Sgblack@eecs.umich.edu        const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
3227194Sgblack@eecs.umich.edu        if (bits(machInst, 22) == 0) {
3237194Sgblack@eecs.umich.edu            switch (op1) {
3247194Sgblack@eecs.umich.edu              case 0x1:
3257194Sgblack@eecs.umich.edu                switch (op2) {
3267194Sgblack@eecs.umich.edu                  case 0x0:
3277216Sgblack@eecs.umich.edu                    return new Sadd16RegCc(machInst, rd, rn, rm, 0, LSL);
3287194Sgblack@eecs.umich.edu                  case 0x1:
3297224Sgblack@eecs.umich.edu                    return new SasxRegCc(machInst, rd, rn, rm, 0, LSL);
3307194Sgblack@eecs.umich.edu                  case 0x2:
3317224Sgblack@eecs.umich.edu                    return new SsaxRegCc(machInst, rd, rn, rm, 0, LSL);
3327194Sgblack@eecs.umich.edu                  case 0x3:
3337218Sgblack@eecs.umich.edu                    return new Ssub16RegCc(machInst, rd, rn, rm, 0, LSL);
3347194Sgblack@eecs.umich.edu                  case 0x4:
3357216Sgblack@eecs.umich.edu                    return new Sadd8RegCc(machInst, rd, rn, rm, 0, LSL);
3367194Sgblack@eecs.umich.edu                  case 0x7:
3377218Sgblack@eecs.umich.edu                    return new Ssub8RegCc(machInst, rd, rn, rm, 0, LSL);
3387194Sgblack@eecs.umich.edu                }
3397194Sgblack@eecs.umich.edu                break;
3407194Sgblack@eecs.umich.edu              case 0x2:
3417194Sgblack@eecs.umich.edu                switch (op2) {
3427194Sgblack@eecs.umich.edu                  case 0x0:
3437194Sgblack@eecs.umich.edu                    return new Qadd16Reg(machInst, rd, rn, rm, 0, LSL);
3447194Sgblack@eecs.umich.edu                  case 0x1:
3457194Sgblack@eecs.umich.edu                    return new QasxReg(machInst, rd, rn, rm, 0, LSL);
3467194Sgblack@eecs.umich.edu                  case 0x2:
3477194Sgblack@eecs.umich.edu                    return new QsaxReg(machInst, rd, rn, rm, 0, LSL);
3487194Sgblack@eecs.umich.edu                  case 0x3:
3497194Sgblack@eecs.umich.edu                    return new Qsub16Reg(machInst, rd, rn, rm, 0, LSL);
3507194Sgblack@eecs.umich.edu                  case 0x4:
3517194Sgblack@eecs.umich.edu                    return new Qadd8Reg(machInst, rd, rn, rm, 0, LSL);
3527194Sgblack@eecs.umich.edu                  case 0x7:
3537194Sgblack@eecs.umich.edu                    return new Qsub8Reg(machInst, rd, rn, rm, 0, LSL);
3547194Sgblack@eecs.umich.edu                }
3557194Sgblack@eecs.umich.edu                break;
3567194Sgblack@eecs.umich.edu              case 0x3:
3577194Sgblack@eecs.umich.edu                switch (op2) {
3587194Sgblack@eecs.umich.edu                  case 0x0:
3597231Sgblack@eecs.umich.edu                    return new Shadd16Reg(machInst, rd, rn, rm, 0, LSL);
3607194Sgblack@eecs.umich.edu                  case 0x1:
3617231Sgblack@eecs.umich.edu                    return new ShasxReg(machInst, rd, rn, rm, 0, LSL);
3627194Sgblack@eecs.umich.edu                  case 0x2:
3637231Sgblack@eecs.umich.edu                    return new ShsaxReg(machInst, rd, rn, rm, 0, LSL);
3647194Sgblack@eecs.umich.edu                  case 0x3:
3657231Sgblack@eecs.umich.edu                    return new Shsub16Reg(machInst, rd, rn, rm, 0, LSL);
3667194Sgblack@eecs.umich.edu                  case 0x4:
3677231Sgblack@eecs.umich.edu                    return new Shadd8Reg(machInst, rd, rn, rm, 0, LSL);
3687194Sgblack@eecs.umich.edu                  case 0x7:
3697231Sgblack@eecs.umich.edu                    return new Shsub8Reg(machInst, rd, rn, rm, 0, LSL);
3707194Sgblack@eecs.umich.edu                }
3717194Sgblack@eecs.umich.edu                break;
3727194Sgblack@eecs.umich.edu            }
3737194Sgblack@eecs.umich.edu        } else {
3747194Sgblack@eecs.umich.edu            switch (op1) {
3757194Sgblack@eecs.umich.edu              case 0x1:
3767194Sgblack@eecs.umich.edu                switch (op2) {
3777194Sgblack@eecs.umich.edu                  case 0x0:
3787222Sgblack@eecs.umich.edu                    return new Uadd16RegCc(machInst, rd, rn, rm, 0, LSL);
3797194Sgblack@eecs.umich.edu                  case 0x1:
3807222Sgblack@eecs.umich.edu                    return new UasxRegCc(machInst, rd, rn, rm, 0, LSL);
3817194Sgblack@eecs.umich.edu                  case 0x2:
3827222Sgblack@eecs.umich.edu                    return new UsaxRegCc(machInst, rd, rn, rm, 0, LSL);
3837194Sgblack@eecs.umich.edu                  case 0x3:
3847222Sgblack@eecs.umich.edu                    return new Usub16RegCc(machInst, rd, rn, rm, 0, LSL);
3857194Sgblack@eecs.umich.edu                  case 0x4:
3867222Sgblack@eecs.umich.edu                    return new Uadd8RegCc(machInst, rd, rn, rm, 0, LSL);
3877194Sgblack@eecs.umich.edu                  case 0x7:
3887222Sgblack@eecs.umich.edu                    return new Usub8RegCc(machInst, rd, rn, rm, 0, LSL);
3897194Sgblack@eecs.umich.edu                }
3907194Sgblack@eecs.umich.edu                break;
3917194Sgblack@eecs.umich.edu              case 0x2:
3927194Sgblack@eecs.umich.edu                switch (op2) {
3937194Sgblack@eecs.umich.edu                  case 0x0:
3947220Sgblack@eecs.umich.edu                    return new Uqadd16Reg(machInst, rd, rn, rm, 0, LSL);
3957194Sgblack@eecs.umich.edu                  case 0x1:
3967220Sgblack@eecs.umich.edu                    return new UqasxReg(machInst, rd, rn, rm, 0, LSL);
3977194Sgblack@eecs.umich.edu                  case 0x2:
3987220Sgblack@eecs.umich.edu                    return new UqsaxReg(machInst, rd, rn, rm, 0, LSL);
3997194Sgblack@eecs.umich.edu                  case 0x3:
4007220Sgblack@eecs.umich.edu                    return new Uqsub16Reg(machInst, rd, rn, rm, 0, LSL);
4017194Sgblack@eecs.umich.edu                  case 0x4:
4027220Sgblack@eecs.umich.edu                    return new Uqadd8Reg(machInst, rd, rn, rm, 0, LSL);
4037194Sgblack@eecs.umich.edu                  case 0x7:
4047220Sgblack@eecs.umich.edu                    return new Uqsub8Reg(machInst, rd, rn, rm, 0, LSL);
4057194Sgblack@eecs.umich.edu                }
4067194Sgblack@eecs.umich.edu                break;
4077194Sgblack@eecs.umich.edu              case 0x3:
4087194Sgblack@eecs.umich.edu                switch (op2) {
4097194Sgblack@eecs.umich.edu                  case 0x0:
4107231Sgblack@eecs.umich.edu                    return new Uhadd16Reg(machInst, rd, rn, rm, 0, LSL);
4117194Sgblack@eecs.umich.edu                  case 0x1:
4127231Sgblack@eecs.umich.edu                    return new UhasxReg(machInst, rd, rn, rm, 0, LSL);
4137194Sgblack@eecs.umich.edu                  case 0x2:
4147231Sgblack@eecs.umich.edu                    return new UhsaxReg(machInst, rd, rn, rm, 0, LSL);
4157194Sgblack@eecs.umich.edu                  case 0x3:
4167231Sgblack@eecs.umich.edu                    return new Uhsub16Reg(machInst, rd, rn, rm, 0, LSL);
4177194Sgblack@eecs.umich.edu                  case 0x4:
4187231Sgblack@eecs.umich.edu                    return new Uhadd8Reg(machInst, rd, rn, rm, 0, LSL);
4197194Sgblack@eecs.umich.edu                  case 0x7:
4207231Sgblack@eecs.umich.edu                    return new Uhsub8Reg(machInst, rd, rn, rm, 0, LSL);
4217194Sgblack@eecs.umich.edu                }
4227194Sgblack@eecs.umich.edu                break;
4237194Sgblack@eecs.umich.edu            }
4247194Sgblack@eecs.umich.edu        }
4257194Sgblack@eecs.umich.edu        return new Unknown(machInst);
4267194Sgblack@eecs.umich.edu    }
4277194Sgblack@eecs.umich.edu    '''
4287194Sgblack@eecs.umich.edu}};
4297194Sgblack@eecs.umich.edu
4307139Sgblack@eecs.umich.edudef format ArmDataProcImm() {{
4317188Sgblack@eecs.umich.edu    pclr = '''
4327188Sgblack@eecs.umich.edu        return new %(className)ssImmPclr(machInst, %(dest)s,
4337188Sgblack@eecs.umich.edu                                        %(op1)s, imm, false);
4347188Sgblack@eecs.umich.edu    '''
4357188Sgblack@eecs.umich.edu    adr = '''
4367188Sgblack@eecs.umich.edu        return new AdrImm(machInst, %(dest)s, %(add)s,
4377188Sgblack@eecs.umich.edu                                     imm, false);
4387188Sgblack@eecs.umich.edu    '''
4397139Sgblack@eecs.umich.edu    instDecode = '''
4407188Sgblack@eecs.umich.edu          case %(opcode)#x:
4417139Sgblack@eecs.umich.edu            if (setCc) {
4427188Sgblack@eecs.umich.edu                if (%(pclrInst)s && %(dest)s == INTREG_PC) {
4437188Sgblack@eecs.umich.edu                    %(pclr)s
4447188Sgblack@eecs.umich.edu                } else {
4457188Sgblack@eecs.umich.edu                    return new %(className)sImmCc(machInst, %(dest)s, %(op1)s,
4467188Sgblack@eecs.umich.edu                                                   imm, rotC);
4477188Sgblack@eecs.umich.edu                }
4487139Sgblack@eecs.umich.edu            } else {
4497188Sgblack@eecs.umich.edu                if (%(adrInst)s && %(op1)s == INTREG_PC) {
4507188Sgblack@eecs.umich.edu                    %(adr)s
4517188Sgblack@eecs.umich.edu                } else {
4527188Sgblack@eecs.umich.edu                    return new %(className)sImm(machInst, %(dest)s, %(op1)s,
4537188Sgblack@eecs.umich.edu                                                 imm, rotC);
4547188Sgblack@eecs.umich.edu                }
4557139Sgblack@eecs.umich.edu            }
4567139Sgblack@eecs.umich.edu            break;
4577139Sgblack@eecs.umich.edu    '''
4587139Sgblack@eecs.umich.edu
4597188Sgblack@eecs.umich.edu    def instCode(opcode, mnem, useDest = True, useOp1 = True):
4607188Sgblack@eecs.umich.edu        global instDecode, pclr, adr
4617188Sgblack@eecs.umich.edu        if useDest:
4627188Sgblack@eecs.umich.edu            dest = "rd"
4637188Sgblack@eecs.umich.edu        else:
4647188Sgblack@eecs.umich.edu            dest = "INTREG_ZERO"
4657188Sgblack@eecs.umich.edu        if useOp1:
4667188Sgblack@eecs.umich.edu            op1 = "rn"
4677188Sgblack@eecs.umich.edu        else:
4687188Sgblack@eecs.umich.edu            op1 = "INTREG_ZERO"
4697188Sgblack@eecs.umich.edu        substDict = { "className": mnem.capitalize(),
4707188Sgblack@eecs.umich.edu                      "opcode": opcode,
4717188Sgblack@eecs.umich.edu                      "dest": dest,
4727188Sgblack@eecs.umich.edu                      "op1": op1,
4737188Sgblack@eecs.umich.edu                      "adr": "",
4747188Sgblack@eecs.umich.edu                      "adrInst": "false" }
4757188Sgblack@eecs.umich.edu        if useDest:
4767188Sgblack@eecs.umich.edu            substDict["pclrInst"] = "true"
4777188Sgblack@eecs.umich.edu            substDict["pclr"] = pclr % substDict
4787188Sgblack@eecs.umich.edu        else:
4797188Sgblack@eecs.umich.edu            substDict["pclrInst"] = "false"
4807188Sgblack@eecs.umich.edu            substDict["pclr"] = ""
4817188Sgblack@eecs.umich.edu        return instDecode % substDict
4827185Sgblack@eecs.umich.edu
4837188Sgblack@eecs.umich.edu    def adrCode(opcode, mnem, add="1"):
4847188Sgblack@eecs.umich.edu        global instDecode, pclr, adr
4857188Sgblack@eecs.umich.edu        substDict = { "className": mnem.capitalize(),
4867188Sgblack@eecs.umich.edu                      "opcode": opcode,
4877188Sgblack@eecs.umich.edu                      "dest": "rd",
4887188Sgblack@eecs.umich.edu                      "op1": "rn",
4897188Sgblack@eecs.umich.edu                      "add": add,
4907188Sgblack@eecs.umich.edu                      "pclrInst": "true",
4917188Sgblack@eecs.umich.edu                      "adrInst": "true" }
4927188Sgblack@eecs.umich.edu        substDict["pclr"] = pclr % substDict
4937188Sgblack@eecs.umich.edu        substDict["adr"] = adr % substDict
4947188Sgblack@eecs.umich.edu        return instDecode % substDict
4957139Sgblack@eecs.umich.edu
4967139Sgblack@eecs.umich.edu    decode_block = '''
4977139Sgblack@eecs.umich.edu    {
4987139Sgblack@eecs.umich.edu        const bool setCc = (bits(machInst, 20) == 1);
4997139Sgblack@eecs.umich.edu        const uint32_t unrotated = bits(machInst, 7, 0);
5007139Sgblack@eecs.umich.edu        const uint32_t rotation = (bits(machInst, 11, 8) << 1);
5017139Sgblack@eecs.umich.edu        const bool rotC = (rotation != 0);
5027139Sgblack@eecs.umich.edu        const uint32_t imm = rotate_imm(unrotated, rotation);
5037139Sgblack@eecs.umich.edu        const IntRegIndex rd = (IntRegIndex)(uint32_t)RD;
5047139Sgblack@eecs.umich.edu        const IntRegIndex rn = (IntRegIndex)(uint32_t)RN;
5057139Sgblack@eecs.umich.edu        switch (OPCODE) {
5067139Sgblack@eecs.umich.edu    '''
5077139Sgblack@eecs.umich.edu    decode_block += instCode(0x0, "and")
5087139Sgblack@eecs.umich.edu    decode_block += instCode(0x1, "eor")
5097185Sgblack@eecs.umich.edu    decode_block += adrCode(0x2, "sub", add="(IntRegIndex)0")
5107139Sgblack@eecs.umich.edu    decode_block += instCode(0x3, "rsb")
5117185Sgblack@eecs.umich.edu    decode_block += adrCode(0x4, "add", add="(IntRegIndex)1")
5127139Sgblack@eecs.umich.edu    decode_block += instCode(0x5, "adc")
5137139Sgblack@eecs.umich.edu    decode_block += instCode(0x6, "sbc")
5147139Sgblack@eecs.umich.edu    decode_block += instCode(0x7, "rsc")
5157188Sgblack@eecs.umich.edu    decode_block += instCode(0x8, "tst", useDest = False)
5167188Sgblack@eecs.umich.edu    decode_block += instCode(0x9, "teq", useDest = False)
5177188Sgblack@eecs.umich.edu    decode_block += instCode(0xa, "cmp", useDest = False)
5187188Sgblack@eecs.umich.edu    decode_block += instCode(0xb, "cmn", useDest = False)
5197139Sgblack@eecs.umich.edu    decode_block += instCode(0xc, "orr")
5207188Sgblack@eecs.umich.edu    decode_block += instCode(0xd, "mov", useOp1 = False)
5217139Sgblack@eecs.umich.edu    decode_block += instCode(0xe, "bic")
5227188Sgblack@eecs.umich.edu    decode_block += instCode(0xf, "mvn", useOp1 = False)
5237139Sgblack@eecs.umich.edu    decode_block += '''
5247139Sgblack@eecs.umich.edu          default:
5257139Sgblack@eecs.umich.edu            return new Unknown(machInst);
5267139Sgblack@eecs.umich.edu        }
5277139Sgblack@eecs.umich.edu    }
5287139Sgblack@eecs.umich.edu    '''
5297139Sgblack@eecs.umich.edu}};
5307141Sgblack@eecs.umich.edu
5317195Sgblack@eecs.umich.edudef format ArmSatAddSub() {{
5327195Sgblack@eecs.umich.edu    decode_block = '''
5337195Sgblack@eecs.umich.edu    {
5347195Sgblack@eecs.umich.edu        IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
5357195Sgblack@eecs.umich.edu        IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
5367195Sgblack@eecs.umich.edu        IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
5377195Sgblack@eecs.umich.edu        switch (OPCODE) {
5387195Sgblack@eecs.umich.edu          case 0x8:
5397195Sgblack@eecs.umich.edu            return new QaddRegCc(machInst, rd, rm, rn, 0, LSL);
5407195Sgblack@eecs.umich.edu          case 0x9:
5417195Sgblack@eecs.umich.edu            return new QsubRegCc(machInst, rd, rm, rn, 0, LSL);
5427195Sgblack@eecs.umich.edu          case 0xa:
5437195Sgblack@eecs.umich.edu            return new QdaddRegCc(machInst, rd, rm, rn, 0, LSL);
5447195Sgblack@eecs.umich.edu          case 0xb:
5457195Sgblack@eecs.umich.edu            return new QdsubRegCc(machInst, rd, rm, rn, 0, LSL);
5467195Sgblack@eecs.umich.edu          default:
5477195Sgblack@eecs.umich.edu            return new Unknown(machInst);
5487195Sgblack@eecs.umich.edu        }
5497195Sgblack@eecs.umich.edu    }
5507195Sgblack@eecs.umich.edu    '''
5517195Sgblack@eecs.umich.edu}};
5527195Sgblack@eecs.umich.edu
5537213Sgblack@eecs.umich.edudef format Thumb32DataProcReg() {{
5547213Sgblack@eecs.umich.edu    decode_block = '''
5557213Sgblack@eecs.umich.edu    {
5567213Sgblack@eecs.umich.edu        const uint32_t op1 = bits(machInst, 23, 20);
5577213Sgblack@eecs.umich.edu        const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
5587213Sgblack@eecs.umich.edu        const uint32_t op2 = bits(machInst, 7, 4);
5597213Sgblack@eecs.umich.edu        if (bits(op1, 3) != 1) {
5607213Sgblack@eecs.umich.edu            if (op2 == 0) {
5617213Sgblack@eecs.umich.edu                IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
5627213Sgblack@eecs.umich.edu                IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
5637213Sgblack@eecs.umich.edu                switch (bits(op1, 2, 0)) {
5647213Sgblack@eecs.umich.edu                  case 0x0:
5657213Sgblack@eecs.umich.edu                    return new MovRegReg(machInst, rd,
5667213Sgblack@eecs.umich.edu                            INTREG_ZERO, rn, rm, LSL);
5677213Sgblack@eecs.umich.edu                  case 0x1:
5687213Sgblack@eecs.umich.edu                    return new MovRegRegCc(machInst, rd,
5697213Sgblack@eecs.umich.edu                            INTREG_ZERO, rn, rm, LSL);
5707213Sgblack@eecs.umich.edu                  case 0x2:
5717213Sgblack@eecs.umich.edu                    return new MovRegReg(machInst, rd,
5727213Sgblack@eecs.umich.edu                            INTREG_ZERO, rn, rm, LSR);
5737213Sgblack@eecs.umich.edu                  case 0x3:
5747213Sgblack@eecs.umich.edu                    return new MovRegRegCc(machInst, rd,
5757213Sgblack@eecs.umich.edu                            INTREG_ZERO, rn, rm, LSR);
5767213Sgblack@eecs.umich.edu                  case 0x4:
5777213Sgblack@eecs.umich.edu                    return new MovRegReg(machInst, rd,
5787213Sgblack@eecs.umich.edu                            INTREG_ZERO, rn, rm, ASR);
5797213Sgblack@eecs.umich.edu                  case 0x5:
5807213Sgblack@eecs.umich.edu                    return new MovRegRegCc(machInst, rd,
5817213Sgblack@eecs.umich.edu                            INTREG_ZERO, rn, rm, ASR);
5827213Sgblack@eecs.umich.edu                  case 0x6:
5837213Sgblack@eecs.umich.edu                    return new MovRegReg(machInst, rd,
5847213Sgblack@eecs.umich.edu                            INTREG_ZERO, rn, rm, ROR);
5857213Sgblack@eecs.umich.edu                  case 0x7:
5867213Sgblack@eecs.umich.edu                    return new MovRegRegCc(machInst, rd,
5877213Sgblack@eecs.umich.edu                            INTREG_ZERO, rn, rm, ROR);
5887213Sgblack@eecs.umich.edu                }
5897213Sgblack@eecs.umich.edu            }
5907235Sgblack@eecs.umich.edu            {
5917235Sgblack@eecs.umich.edu                const IntRegIndex rd =
5927235Sgblack@eecs.umich.edu                    (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
5937235Sgblack@eecs.umich.edu                const IntRegIndex rm =
5947235Sgblack@eecs.umich.edu                    (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
5957235Sgblack@eecs.umich.edu                const uint32_t rotation =
5967235Sgblack@eecs.umich.edu                    (uint32_t)bits(machInst, 5, 4) << 3;
5977235Sgblack@eecs.umich.edu                switch (bits(op1, 2, 0)) {
5987235Sgblack@eecs.umich.edu                  case 0x0:
5997235Sgblack@eecs.umich.edu                    if (rn == 0xf) {
6007235Sgblack@eecs.umich.edu                        return new Sxth(machInst, rd, rotation, rm);
6017235Sgblack@eecs.umich.edu                    } else {
6027235Sgblack@eecs.umich.edu                        return new Sxtah(machInst, rd, rn, rm, rotation);
6037235Sgblack@eecs.umich.edu                    }
6047235Sgblack@eecs.umich.edu                  case 0x1:
6057235Sgblack@eecs.umich.edu                    if (rn == 0xf) {
6067235Sgblack@eecs.umich.edu                        return new Uxth(machInst, rd, rotation, rm);
6077235Sgblack@eecs.umich.edu                    } else {
6087235Sgblack@eecs.umich.edu                        return new Uxtah(machInst, rd, rn, rm, rotation);
6097235Sgblack@eecs.umich.edu                    }
6107235Sgblack@eecs.umich.edu                  case 0x2:
6117235Sgblack@eecs.umich.edu                    if (rn == 0xf) {
6127235Sgblack@eecs.umich.edu                        return new Sxtb16(machInst, rd, rotation, rm);
6137235Sgblack@eecs.umich.edu                    } else {
6147235Sgblack@eecs.umich.edu                        return new Sxtab16(machInst, rd, rn, rm, rotation);
6157235Sgblack@eecs.umich.edu                    }
6167235Sgblack@eecs.umich.edu                  case 0x3:
6177235Sgblack@eecs.umich.edu                    if (rn == 0xf) {
6187235Sgblack@eecs.umich.edu                        return new Uxtb16(machInst, rd, rotation, rm);
6197235Sgblack@eecs.umich.edu                    } else {
6207235Sgblack@eecs.umich.edu                        return new Uxtab16(machInst, rd, rn, rm, rotation);
6217235Sgblack@eecs.umich.edu                    }
6227235Sgblack@eecs.umich.edu                  case 0x4:
6237235Sgblack@eecs.umich.edu                    if (rn == 0xf) {
6247235Sgblack@eecs.umich.edu                        return new Sxtb(machInst, rd, rotation, rm);
6257235Sgblack@eecs.umich.edu                    } else {
6267235Sgblack@eecs.umich.edu                        return new Sxtab(machInst, rd, rn, rm, rotation);
6277235Sgblack@eecs.umich.edu                    }
6287235Sgblack@eecs.umich.edu                  case 0x5:
6297235Sgblack@eecs.umich.edu                    if (rn == 0xf) {
6307235Sgblack@eecs.umich.edu                        return new Uxtb(machInst, rd, rotation, rm);
6317235Sgblack@eecs.umich.edu                    } else {
6327235Sgblack@eecs.umich.edu                        return new Uxtab(machInst, rd, rn, rm, rotation);
6337235Sgblack@eecs.umich.edu                    }
6347235Sgblack@eecs.umich.edu                  default:
6357235Sgblack@eecs.umich.edu                    return new Unknown(machInst);
6367213Sgblack@eecs.umich.edu                }
6377213Sgblack@eecs.umich.edu            }
6387213Sgblack@eecs.umich.edu        } else {
6397213Sgblack@eecs.umich.edu            if (bits(op2, 3) == 0) {
6407220Sgblack@eecs.umich.edu                const IntRegIndex rd =
6417220Sgblack@eecs.umich.edu                    (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
6427220Sgblack@eecs.umich.edu                const IntRegIndex rm =
6437220Sgblack@eecs.umich.edu                    (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
6447213Sgblack@eecs.umich.edu                if (bits(op2, 2) == 0x0) {
6457213Sgblack@eecs.umich.edu                    const uint32_t op1 = bits(machInst, 22, 20);
6467213Sgblack@eecs.umich.edu                    const uint32_t op2 = bits(machInst, 5, 4);
6477213Sgblack@eecs.umich.edu                    switch (op2) {
6487213Sgblack@eecs.umich.edu                      case 0x0:
6497213Sgblack@eecs.umich.edu                        switch (op1) {
6507213Sgblack@eecs.umich.edu                          case 0x1:
6517216Sgblack@eecs.umich.edu                            return new Sadd16RegCc(machInst, rd,
6527216Sgblack@eecs.umich.edu                                                   rn, rm, 0, LSL);
6537213Sgblack@eecs.umich.edu                          case 0x2:
6547224Sgblack@eecs.umich.edu                            return new SasxRegCc(machInst, rd,
6557224Sgblack@eecs.umich.edu                                                 rn, rm, 0, LSL);
6567213Sgblack@eecs.umich.edu                          case 0x6:
6577224Sgblack@eecs.umich.edu                            return new SsaxRegCc(machInst, rd,
6587224Sgblack@eecs.umich.edu                                                 rn, rm, 0, LSL);
6597213Sgblack@eecs.umich.edu                          case 0x5:
6607218Sgblack@eecs.umich.edu                            return new Ssub16RegCc(machInst, rd,
6617218Sgblack@eecs.umich.edu                                                   rn, rm, 0, LSL);
6627213Sgblack@eecs.umich.edu                          case 0x0:
6637216Sgblack@eecs.umich.edu                            return new Sadd8RegCc(machInst, rd,
6647216Sgblack@eecs.umich.edu                                                  rn, rm, 0, LSL);
6657213Sgblack@eecs.umich.edu                          case 0x4:
6667218Sgblack@eecs.umich.edu                            return new Ssub8RegCc(machInst, rd,
6677218Sgblack@eecs.umich.edu                                                  rn, rm, 0, LSL);
6687213Sgblack@eecs.umich.edu                        }
6697213Sgblack@eecs.umich.edu                        break;
6707213Sgblack@eecs.umich.edu                      case 0x1:
6717216Sgblack@eecs.umich.edu                        switch (op1) {
6727216Sgblack@eecs.umich.edu                          case 0x1:
6737216Sgblack@eecs.umich.edu                            return new Qadd16Reg(machInst, rd, rn, rm, 0, LSL);
6747216Sgblack@eecs.umich.edu                          case 0x2:
6757216Sgblack@eecs.umich.edu                            return new QasxReg(machInst, rd, rn, rm, 0, LSL);
6767216Sgblack@eecs.umich.edu                          case 0x6:
6777216Sgblack@eecs.umich.edu                            return new QsaxReg(machInst, rd, rn, rm, 0, LSL);
6787216Sgblack@eecs.umich.edu                          case 0x5:
6797216Sgblack@eecs.umich.edu                            return new Qsub16Reg(machInst, rd, rn, rm, 0, LSL);
6807216Sgblack@eecs.umich.edu                          case 0x0:
6817216Sgblack@eecs.umich.edu                            return new Qadd8Reg(machInst, rd, rn, rm, 0, LSL);
6827216Sgblack@eecs.umich.edu                          case 0x4:
6837216Sgblack@eecs.umich.edu                            return new Qsub8Reg(machInst, rd, rn, rm, 0, LSL);
6847213Sgblack@eecs.umich.edu                        }
6857213Sgblack@eecs.umich.edu                        break;
6867213Sgblack@eecs.umich.edu                      case 0x2:
6877213Sgblack@eecs.umich.edu                        switch (op1) {
6887213Sgblack@eecs.umich.edu                          case 0x1:
6897231Sgblack@eecs.umich.edu                            return new Shadd16Reg(machInst, rd, rn, rm, 0, LSL);
6907213Sgblack@eecs.umich.edu                          case 0x2:
6917231Sgblack@eecs.umich.edu                            return new ShasxReg(machInst, rd, rn, rm, 0, LSL);
6927213Sgblack@eecs.umich.edu                          case 0x6:
6937231Sgblack@eecs.umich.edu                            return new ShsaxReg(machInst, rd, rn, rm, 0, LSL);
6947213Sgblack@eecs.umich.edu                          case 0x5:
6957231Sgblack@eecs.umich.edu                            return new Shsub16Reg(machInst, rd, rn, rm, 0, LSL);
6967213Sgblack@eecs.umich.edu                          case 0x0:
6977231Sgblack@eecs.umich.edu                            return new Shadd8Reg(machInst, rd, rn, rm, 0, LSL);
6987213Sgblack@eecs.umich.edu                          case 0x4:
6997231Sgblack@eecs.umich.edu                            return new Shsub8Reg(machInst, rd, rn, rm, 0, LSL);
7007213Sgblack@eecs.umich.edu                        }
7017213Sgblack@eecs.umich.edu                        break;
7027213Sgblack@eecs.umich.edu                    }
7037213Sgblack@eecs.umich.edu                } else {
7047213Sgblack@eecs.umich.edu                    const uint32_t op1 = bits(machInst, 22, 20);
7057213Sgblack@eecs.umich.edu                    const uint32_t op2 = bits(machInst, 5, 4);
7067213Sgblack@eecs.umich.edu                    switch (op2) {
7077213Sgblack@eecs.umich.edu                      case 0x0:
7087213Sgblack@eecs.umich.edu                        switch (op1) {
7097213Sgblack@eecs.umich.edu                          case 0x1:
7107222Sgblack@eecs.umich.edu                            return new Uadd16RegCc(machInst, rd,
7117222Sgblack@eecs.umich.edu                                                   rn, rm, 0, LSL);
7127213Sgblack@eecs.umich.edu                          case 0x2:
7137222Sgblack@eecs.umich.edu                            return new UasxRegCc(machInst, rd,
7147222Sgblack@eecs.umich.edu                                                 rn, rm, 0, LSL);
7157213Sgblack@eecs.umich.edu                          case 0x6:
7167222Sgblack@eecs.umich.edu                            return new UsaxRegCc(machInst, rd,
7177222Sgblack@eecs.umich.edu                                                 rn, rm, 0, LSL);
7187213Sgblack@eecs.umich.edu                          case 0x5:
7197222Sgblack@eecs.umich.edu                            return new Usub16RegCc(machInst, rd,
7207222Sgblack@eecs.umich.edu                                                   rn, rm, 0, LSL);
7217213Sgblack@eecs.umich.edu                          case 0x0:
7227222Sgblack@eecs.umich.edu                            return new Uadd8RegCc(machInst, rd,
7237222Sgblack@eecs.umich.edu                                                  rn, rm, 0, LSL);
7247213Sgblack@eecs.umich.edu                          case 0x4:
7257222Sgblack@eecs.umich.edu                            return new Usub8RegCc(machInst, rd,
7267222Sgblack@eecs.umich.edu                                                  rn, rm, 0, LSL);
7277213Sgblack@eecs.umich.edu                        }
7287213Sgblack@eecs.umich.edu                        break;
7297213Sgblack@eecs.umich.edu                      case 0x1:
7307213Sgblack@eecs.umich.edu                        switch (op1) {
7317213Sgblack@eecs.umich.edu                          case 0x1:
7327220Sgblack@eecs.umich.edu                            return new Uqadd16Reg(machInst, rd, rn, rm, 0, LSL);
7337213Sgblack@eecs.umich.edu                          case 0x2:
7347220Sgblack@eecs.umich.edu                            return new UqasxReg(machInst, rd, rn, rm, 0, LSL);
7357213Sgblack@eecs.umich.edu                          case 0x6:
7367220Sgblack@eecs.umich.edu                            return new UqsaxReg(machInst, rd, rn, rm, 0, LSL);
7377213Sgblack@eecs.umich.edu                          case 0x5:
7387220Sgblack@eecs.umich.edu                            return new Uqsub16Reg(machInst, rd, rn, rm, 0, LSL);
7397213Sgblack@eecs.umich.edu                          case 0x0:
7407220Sgblack@eecs.umich.edu                            return new Uqadd8Reg(machInst, rd, rn, rm, 0, LSL);
7417213Sgblack@eecs.umich.edu                          case 0x4:
7427220Sgblack@eecs.umich.edu                            return new Uqsub8Reg(machInst, rd, rn, rm, 0, LSL);
7437213Sgblack@eecs.umich.edu                        }
7447213Sgblack@eecs.umich.edu                        break;
7457213Sgblack@eecs.umich.edu                      case 0x2:
7467213Sgblack@eecs.umich.edu                        switch (op1) {
7477213Sgblack@eecs.umich.edu                          case 0x1:
7487231Sgblack@eecs.umich.edu                            return new Uhadd16Reg(machInst, rd, rn, rm, 0, LSL);
7497213Sgblack@eecs.umich.edu                          case 0x2:
7507231Sgblack@eecs.umich.edu                            return new UhasxReg(machInst, rd, rn, rm, 0, LSL);
7517213Sgblack@eecs.umich.edu                          case 0x6:
7527231Sgblack@eecs.umich.edu                            return new UhsaxReg(machInst, rd, rn, rm, 0, LSL);
7537213Sgblack@eecs.umich.edu                          case 0x5:
7547231Sgblack@eecs.umich.edu                            return new Uhsub16Reg(machInst, rd, rn, rm, 0, LSL);
7557213Sgblack@eecs.umich.edu                          case 0x0:
7567231Sgblack@eecs.umich.edu                            return new Uhadd8Reg(machInst, rd, rn, rm, 0, LSL);
7577213Sgblack@eecs.umich.edu                          case 0x4:
7587231Sgblack@eecs.umich.edu                            return new Uhsub8Reg(machInst, rd, rn, rm, 0, LSL);
7597213Sgblack@eecs.umich.edu                        }
7607213Sgblack@eecs.umich.edu                        break;
7617213Sgblack@eecs.umich.edu                    }
7627213Sgblack@eecs.umich.edu                }
7637213Sgblack@eecs.umich.edu            } else if (bits(op1, 3, 2) == 0x2 && bits(op2, 3, 2) == 0x2) {
7647213Sgblack@eecs.umich.edu                const uint32_t op1 = bits(machInst, 21, 20);
7657213Sgblack@eecs.umich.edu                const uint32_t op2 = bits(machInst, 5, 4);
7667240Sgblack@eecs.umich.edu                const IntRegIndex rd =
7677240Sgblack@eecs.umich.edu                    (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
7687240Sgblack@eecs.umich.edu                const IntRegIndex rm =
7697240Sgblack@eecs.umich.edu                    (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
7707213Sgblack@eecs.umich.edu                switch (op1) {
7717213Sgblack@eecs.umich.edu                  case 0x0:
7727240Sgblack@eecs.umich.edu                    switch (op2) {
7737240Sgblack@eecs.umich.edu                      case 0x0:
7747240Sgblack@eecs.umich.edu                        return new QaddRegCc(machInst, rd,
7757240Sgblack@eecs.umich.edu                                             rm, rn, 0, LSL);
7767240Sgblack@eecs.umich.edu                      case 0x1:
7777240Sgblack@eecs.umich.edu                        return new QdaddRegCc(machInst, rd,
7787240Sgblack@eecs.umich.edu                                              rm, rn, 0, LSL);
7797240Sgblack@eecs.umich.edu                      case 0x2:
7807240Sgblack@eecs.umich.edu                        return new QsubRegCc(machInst, rd,
7817240Sgblack@eecs.umich.edu                                             rm, rn, 0, LSL);
7827240Sgblack@eecs.umich.edu                      case 0x3:
7837240Sgblack@eecs.umich.edu                        return new QdsubRegCc(machInst, rd,
7847240Sgblack@eecs.umich.edu                                              rm, rn, 0, LSL);
7857213Sgblack@eecs.umich.edu                    }
7867213Sgblack@eecs.umich.edu                    break;
7877213Sgblack@eecs.umich.edu                  case 0x1:
7887240Sgblack@eecs.umich.edu                    switch (op2) {
7897240Sgblack@eecs.umich.edu                      case 0x0:
7907240Sgblack@eecs.umich.edu                        return new Rev(machInst, rd, rn);
7917240Sgblack@eecs.umich.edu                      case 0x1:
7927240Sgblack@eecs.umich.edu                        return new Rev16(machInst, rd, rn);
7937240Sgblack@eecs.umich.edu                      case 0x2:
7947250Sgblack@eecs.umich.edu                        return new Rbit(machInst, rd, rm);
7957240Sgblack@eecs.umich.edu                      case 0x3:
7967240Sgblack@eecs.umich.edu                        return new Revsh(machInst, rd, rn);
7977213Sgblack@eecs.umich.edu                    }
7987213Sgblack@eecs.umich.edu                    break;
7997213Sgblack@eecs.umich.edu                  case 0x2:
8007213Sgblack@eecs.umich.edu                    if (op2 == 0) {
8017240Sgblack@eecs.umich.edu                        return new Sel(machInst, rd, rn, rm);
8027213Sgblack@eecs.umich.edu                    }
8037213Sgblack@eecs.umich.edu                    break;
8047213Sgblack@eecs.umich.edu                  case 0x3:
8057213Sgblack@eecs.umich.edu                    if (op2 == 0) {
8067213Sgblack@eecs.umich.edu                        return new WarnUnimplemented("clz", machInst);
8077213Sgblack@eecs.umich.edu                    }
8087213Sgblack@eecs.umich.edu                }
8097213Sgblack@eecs.umich.edu            }
8107213Sgblack@eecs.umich.edu            return new Unknown(machInst);
8117213Sgblack@eecs.umich.edu        }
8127213Sgblack@eecs.umich.edu    }
8137213Sgblack@eecs.umich.edu    '''
8147213Sgblack@eecs.umich.edu}};
8157213Sgblack@eecs.umich.edu
8167141Sgblack@eecs.umich.edudef format Thumb16ShiftAddSubMoveCmp() {{
8177141Sgblack@eecs.umich.edu    decode_block = '''
8187141Sgblack@eecs.umich.edu    {
8197141Sgblack@eecs.umich.edu        const uint32_t imm5 = bits(machInst, 10, 6);
8207141Sgblack@eecs.umich.edu        const uint32_t imm3 = bits(machInst, 8, 6);
8217141Sgblack@eecs.umich.edu        const uint32_t imm8 = bits(machInst, 7, 0);
8227141Sgblack@eecs.umich.edu        const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 2, 0);
8237141Sgblack@eecs.umich.edu        const IntRegIndex rd8 = (IntRegIndex)(uint32_t)bits(machInst, 10, 8);
8247141Sgblack@eecs.umich.edu        const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 5, 3);
8257141Sgblack@eecs.umich.edu        const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 8, 6);
8267141Sgblack@eecs.umich.edu        switch (bits(machInst, 13, 11)) {
8277141Sgblack@eecs.umich.edu          case 0x0: // lsl
8287183Sgblack@eecs.umich.edu            return new MovRegCc(machInst, rd, INTREG_ZERO, rn, imm5, LSL);
8297141Sgblack@eecs.umich.edu          case 0x1: // lsr
8307183Sgblack@eecs.umich.edu            return new MovRegCc(machInst, rd, INTREG_ZERO, rn, imm5, LSR);
8317141Sgblack@eecs.umich.edu          case 0x2: // asr
8327183Sgblack@eecs.umich.edu            return new MovRegCc(machInst, rd, INTREG_ZERO, rn, imm5, ASR);
8337141Sgblack@eecs.umich.edu          case 0x3:
8347141Sgblack@eecs.umich.edu            switch (bits(machInst, 10, 9)) {
8357141Sgblack@eecs.umich.edu              case 0x0:
8367183Sgblack@eecs.umich.edu                return new AddRegCc(machInst, rd, rn, rm, 0, LSL);
8377141Sgblack@eecs.umich.edu              case 0x1:
8387183Sgblack@eecs.umich.edu                return new SubRegCc(machInst, rd, rn, rm, 0, LSL);
8397141Sgblack@eecs.umich.edu              case 0x2:
8407183Sgblack@eecs.umich.edu                return new AddImmCc(machInst, rd, rn, imm3, true);
8417141Sgblack@eecs.umich.edu              case 0x3:
8427183Sgblack@eecs.umich.edu                return new SubImmCc(machInst, rd, rn, imm3, true);
8437141Sgblack@eecs.umich.edu            }
8447141Sgblack@eecs.umich.edu          case 0x4:
8457183Sgblack@eecs.umich.edu            return new MovImmCc(machInst, rd8, INTREG_ZERO, imm8, false);
8467141Sgblack@eecs.umich.edu          case 0x5:
8477146Sgblack@eecs.umich.edu            return new CmpImmCc(machInst, INTREG_ZERO, rd8, imm8, true);
8487141Sgblack@eecs.umich.edu          case 0x6:
8497183Sgblack@eecs.umich.edu            return new AddImmCc(machInst, rd8, rd8, imm8, true);
8507141Sgblack@eecs.umich.edu          case 0x7:
8517183Sgblack@eecs.umich.edu            return new SubImmCc(machInst, rd8, rd8, imm8, true);
8527141Sgblack@eecs.umich.edu        }
8537141Sgblack@eecs.umich.edu    }
8547141Sgblack@eecs.umich.edu    '''
8557141Sgblack@eecs.umich.edu}};
8567141Sgblack@eecs.umich.edu
8577141Sgblack@eecs.umich.edudef format Thumb16DataProcessing() {{
8587141Sgblack@eecs.umich.edu    decode_block = '''
8597141Sgblack@eecs.umich.edu    {
8607141Sgblack@eecs.umich.edu        const IntRegIndex rdn = (IntRegIndex)(uint32_t)bits(machInst, 2, 0);
8617141Sgblack@eecs.umich.edu        const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 5, 3);
8627141Sgblack@eecs.umich.edu        switch (bits(machInst, 9, 6)) {
8637141Sgblack@eecs.umich.edu          case 0x0:
8647183Sgblack@eecs.umich.edu            return new AndRegCc(machInst, rdn, rdn, rm, 0, LSL);
8657141Sgblack@eecs.umich.edu          case 0x1:
8667183Sgblack@eecs.umich.edu            return new EorRegCc(machInst, rdn, rdn, rm, 0, LSL);
8677141Sgblack@eecs.umich.edu          case 0x2: //lsl
8687183Sgblack@eecs.umich.edu            return new MovRegRegCc(machInst, rdn, INTREG_ZERO, rdn, rm, LSL);
8697141Sgblack@eecs.umich.edu          case 0x3: //lsr
8707183Sgblack@eecs.umich.edu            return new MovRegRegCc(machInst, rdn, INTREG_ZERO, rdn, rm, LSR);
8717141Sgblack@eecs.umich.edu          case 0x4: //asr
8727183Sgblack@eecs.umich.edu            return new MovRegRegCc(machInst, rdn, INTREG_ZERO, rdn, rm, ASR);
8737141Sgblack@eecs.umich.edu          case 0x5:
8747183Sgblack@eecs.umich.edu            return new AdcRegCc(machInst, rdn, rdn, rm, 0, LSL);
8757141Sgblack@eecs.umich.edu          case 0x6:
8767183Sgblack@eecs.umich.edu            return new SbcRegCc(machInst, rdn, rdn, rm, 0, LSL);
8777141Sgblack@eecs.umich.edu          case 0x7: // ror
8787183Sgblack@eecs.umich.edu            return new MovRegRegCc(machInst, rdn, INTREG_ZERO, rdn, rm, ROR);
8797141Sgblack@eecs.umich.edu          case 0x8:
8807183Sgblack@eecs.umich.edu            return new TstRegCc(machInst, INTREG_ZERO, rdn, rm, 0, LSL);
8817141Sgblack@eecs.umich.edu          case 0x9:
8827183Sgblack@eecs.umich.edu            return new RsbImmCc(machInst, rdn, rm, 0, true);
8837141Sgblack@eecs.umich.edu          case 0xa:
8847183Sgblack@eecs.umich.edu            return new CmpRegCc(machInst, INTREG_ZERO, rdn, rm, 0, LSL);
8857141Sgblack@eecs.umich.edu          case 0xb:
8867183Sgblack@eecs.umich.edu            return new CmnRegCc(machInst, INTREG_ZERO, rdn, rm, 0, LSL);
8877141Sgblack@eecs.umich.edu          case 0xc:
8887183Sgblack@eecs.umich.edu            return new OrrRegCc(machInst, rdn, rdn, rm, 0, LSL);
8897141Sgblack@eecs.umich.edu          case 0xd:
8907183Sgblack@eecs.umich.edu            return new MulCc(machInst, rdn, rm, rdn);
8917141Sgblack@eecs.umich.edu          case 0xe:
8927183Sgblack@eecs.umich.edu            return new BicRegCc(machInst, rdn, rdn, rm, 0, LSL);
8937141Sgblack@eecs.umich.edu          case 0xf:
8947183Sgblack@eecs.umich.edu            return new MvnRegCc(machInst, rdn, INTREG_ZERO, rm, 0, LSL);
8957141Sgblack@eecs.umich.edu        }
8967141Sgblack@eecs.umich.edu    }
8977141Sgblack@eecs.umich.edu    '''
8987141Sgblack@eecs.umich.edu}};
8997141Sgblack@eecs.umich.edu
9007141Sgblack@eecs.umich.edudef format Thumb16SpecDataAndBx() {{
9017141Sgblack@eecs.umich.edu    decode_block = '''
9027141Sgblack@eecs.umich.edu    {
9037141Sgblack@eecs.umich.edu        const IntRegIndex rdn =
9047141Sgblack@eecs.umich.edu            (IntRegIndex)(uint32_t)(bits(machInst, 2, 0) |
9057141Sgblack@eecs.umich.edu                                    (bits(machInst, 7) << 3));
9067141Sgblack@eecs.umich.edu        const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 6, 3);
9077141Sgblack@eecs.umich.edu        switch (bits(machInst, 9, 8)) {
9087141Sgblack@eecs.umich.edu          case 0x0:
9097146Sgblack@eecs.umich.edu            return new AddReg(machInst, rdn, rdn, rm, 0, LSL);
9107141Sgblack@eecs.umich.edu          case 0x1:
9117183Sgblack@eecs.umich.edu            return new CmpRegCc(machInst, INTREG_ZERO, rdn, rm, 0, LSL);
9127141Sgblack@eecs.umich.edu          case 0x2:
9137146Sgblack@eecs.umich.edu            return new MovReg(machInst, rdn, INTREG_ZERO, rm, 0, LSL);
9147141Sgblack@eecs.umich.edu          case 0x3:
9157154Sgblack@eecs.umich.edu            if (bits(machInst, 7) == 0) {
9167154Sgblack@eecs.umich.edu                return new BxReg(machInst,
9177154Sgblack@eecs.umich.edu                                 (IntRegIndex)(uint32_t)bits(machInst, 6, 3),
9187154Sgblack@eecs.umich.edu                                 COND_UC);
9197154Sgblack@eecs.umich.edu            } else {
9207154Sgblack@eecs.umich.edu                return new BlxReg(machInst,
9217154Sgblack@eecs.umich.edu                                  (IntRegIndex)(uint32_t)bits(machInst, 6, 3),
9227154Sgblack@eecs.umich.edu                                  COND_UC);
9237154Sgblack@eecs.umich.edu            }
9247141Sgblack@eecs.umich.edu        }
9257141Sgblack@eecs.umich.edu    }
9267141Sgblack@eecs.umich.edu    '''
9277141Sgblack@eecs.umich.edu}};
9287141Sgblack@eecs.umich.edu
9297141Sgblack@eecs.umich.edudef format Thumb16Adr() {{
9307141Sgblack@eecs.umich.edu    decode_block = '''
9317141Sgblack@eecs.umich.edu    {
9327141Sgblack@eecs.umich.edu        const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 10, 8);
9337141Sgblack@eecs.umich.edu        const uint32_t imm8 = bits(machInst, 7, 0) << 2;
9347185Sgblack@eecs.umich.edu        return new AdrImm(machInst, rd, (IntRegIndex)1, imm8, false);
9357141Sgblack@eecs.umich.edu    }
9367141Sgblack@eecs.umich.edu    '''
9377141Sgblack@eecs.umich.edu}};
9387141Sgblack@eecs.umich.edu
9397141Sgblack@eecs.umich.edudef format Thumb16AddSp() {{
9407141Sgblack@eecs.umich.edu    decode_block = '''
9417141Sgblack@eecs.umich.edu    {
9427141Sgblack@eecs.umich.edu        const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 10, 8);
9437141Sgblack@eecs.umich.edu        const uint32_t imm8 = bits(machInst, 7, 0) << 2;
9447146Sgblack@eecs.umich.edu        return new AddImm(machInst, rd, INTREG_SP, imm8, true);
9457141Sgblack@eecs.umich.edu    }
9467141Sgblack@eecs.umich.edu    '''
9477141Sgblack@eecs.umich.edu}};
9487141Sgblack@eecs.umich.edu
9497141Sgblack@eecs.umich.edudef format Thumb16Misc() {{
9507141Sgblack@eecs.umich.edu    decode_block = '''
9517141Sgblack@eecs.umich.edu    {
9527141Sgblack@eecs.umich.edu        switch (bits(machInst, 11, 8)) {
9537141Sgblack@eecs.umich.edu          case 0x0:
9547141Sgblack@eecs.umich.edu            if (bits(machInst, 7)) {
9557146Sgblack@eecs.umich.edu                return new SubImm(machInst, INTREG_SP, INTREG_SP,
9567141Sgblack@eecs.umich.edu                                   bits(machInst, 6, 0) << 2, true);
9577141Sgblack@eecs.umich.edu            } else {
9587146Sgblack@eecs.umich.edu                return new AddImm(machInst, INTREG_SP, INTREG_SP,
9597141Sgblack@eecs.umich.edu                                   bits(machInst, 6, 0) << 2, true);
9607141Sgblack@eecs.umich.edu            }
9617141Sgblack@eecs.umich.edu          case 0x1:
9627154Sgblack@eecs.umich.edu            return new Cbz(machInst,
9637154Sgblack@eecs.umich.edu                           (bits(machInst, 9) << 6) |
9647154Sgblack@eecs.umich.edu                           (bits(machInst, 7, 3) << 1),
9657154Sgblack@eecs.umich.edu                           (IntRegIndex)(uint32_t)bits(machInst, 2, 0));
9667141Sgblack@eecs.umich.edu          case 0x2:
9677235Sgblack@eecs.umich.edu            {
9687235Sgblack@eecs.umich.edu                const IntRegIndex rd =
9697235Sgblack@eecs.umich.edu                    (IntRegIndex)(uint32_t)bits(machInst, 2, 0);
9707235Sgblack@eecs.umich.edu                const IntRegIndex rm =
9717235Sgblack@eecs.umich.edu                    (IntRegIndex)(uint32_t)bits(machInst, 5, 3);
9727235Sgblack@eecs.umich.edu                switch (bits(machInst, 7, 6)) {
9737235Sgblack@eecs.umich.edu                  case 0x0:
9747235Sgblack@eecs.umich.edu                    return new Sxth(machInst, rd, 0, rm);
9757235Sgblack@eecs.umich.edu                  case 0x1:
9767235Sgblack@eecs.umich.edu                    return new Sxtb(machInst, rd, 0, rm);
9777235Sgblack@eecs.umich.edu                  case 0x2:
9787235Sgblack@eecs.umich.edu                    return new Uxth(machInst, rd, 0, rm);
9797235Sgblack@eecs.umich.edu                  case 0x3:
9807235Sgblack@eecs.umich.edu                    return new Uxtb(machInst, rd, 0, rm);
9817235Sgblack@eecs.umich.edu                }
9827141Sgblack@eecs.umich.edu            }
9837141Sgblack@eecs.umich.edu          case 0x3:
9847154Sgblack@eecs.umich.edu            return new Cbz(machInst,
9857154Sgblack@eecs.umich.edu                           (bits(machInst, 9) << 6) |
9867154Sgblack@eecs.umich.edu                           (bits(machInst, 7, 3) << 1),
9877154Sgblack@eecs.umich.edu                           (IntRegIndex)(uint32_t)bits(machInst, 2, 0));
9887141Sgblack@eecs.umich.edu          case 0x4:
9897141Sgblack@eecs.umich.edu          case 0x5:
9907201Sgblack@eecs.umich.edu            {
9917201Sgblack@eecs.umich.edu                const uint32_t m = bits(machInst, 8);
9927201Sgblack@eecs.umich.edu                const uint32_t regList = bits(machInst, 7, 0) | (m << 14);
9937201Sgblack@eecs.umich.edu                return new LdmStm(machInst, INTREG_SP, false, false, false,
9947201Sgblack@eecs.umich.edu                                  true, false, regList);
9957201Sgblack@eecs.umich.edu            }
9967141Sgblack@eecs.umich.edu          case 0x6:
9977141Sgblack@eecs.umich.edu            {
9987141Sgblack@eecs.umich.edu                const uint32_t opBits = bits(machInst, 7, 5);
9997141Sgblack@eecs.umich.edu                if (opBits == 2) {
10007141Sgblack@eecs.umich.edu                    return new WarnUnimplemented("setend", machInst);
10017141Sgblack@eecs.umich.edu                } else if (opBits == 3) {
10027141Sgblack@eecs.umich.edu                    return new WarnUnimplemented("cps", machInst);
10037141Sgblack@eecs.umich.edu                }
10047141Sgblack@eecs.umich.edu            }
10057141Sgblack@eecs.umich.edu          case 0x9:
10067154Sgblack@eecs.umich.edu            return new Cbnz(machInst,
10077154Sgblack@eecs.umich.edu                            (bits(machInst, 9) << 6) |
10087154Sgblack@eecs.umich.edu                            (bits(machInst, 7, 3) << 1),
10097154Sgblack@eecs.umich.edu                            (IntRegIndex)(uint32_t)bits(machInst, 2, 0));
10107141Sgblack@eecs.umich.edu          case 0xa:
10117212Sgblack@eecs.umich.edu            {
10127212Sgblack@eecs.umich.edu                IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 2, 0);
10137212Sgblack@eecs.umich.edu                IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 5, 3);
10147212Sgblack@eecs.umich.edu                switch (bits(machInst, 7, 6)) {
10157212Sgblack@eecs.umich.edu                  case 0x0:
10167212Sgblack@eecs.umich.edu                    return new Rev(machInst, rd, rm);
10177212Sgblack@eecs.umich.edu                  case 0x1:
10187212Sgblack@eecs.umich.edu                    return new Rev16(machInst, rd, rm);
10197212Sgblack@eecs.umich.edu                  case 0x3:
10207212Sgblack@eecs.umich.edu                    return new Revsh(machInst, rd, rm);
10217212Sgblack@eecs.umich.edu                  default:
10227212Sgblack@eecs.umich.edu                    break;
10237212Sgblack@eecs.umich.edu                }
10247141Sgblack@eecs.umich.edu            }
10257141Sgblack@eecs.umich.edu            break;
10267141Sgblack@eecs.umich.edu          case 0xb:
10277154Sgblack@eecs.umich.edu            return new Cbnz(machInst,
10287154Sgblack@eecs.umich.edu                            (bits(machInst, 9) << 6) |
10297154Sgblack@eecs.umich.edu                            (bits(machInst, 7, 3) << 1),
10307154Sgblack@eecs.umich.edu                            (IntRegIndex)(uint32_t)bits(machInst, 2, 0));
10317141Sgblack@eecs.umich.edu          case 0xc:
10327141Sgblack@eecs.umich.edu          case 0xd:
10337201Sgblack@eecs.umich.edu            {
10347201Sgblack@eecs.umich.edu                const uint32_t p = bits(machInst, 8);
10357201Sgblack@eecs.umich.edu                const uint32_t regList = bits(machInst, 7, 0) | (p << 15);
10367201Sgblack@eecs.umich.edu                return new LdmStm(machInst, INTREG_SP, true, true, false,
10377201Sgblack@eecs.umich.edu                                  true, true, regList);
10387201Sgblack@eecs.umich.edu            }
10397141Sgblack@eecs.umich.edu          case 0xe:
10407141Sgblack@eecs.umich.edu            return new WarnUnimplemented("bkpt", machInst);
10417141Sgblack@eecs.umich.edu          case 0xf:
10427141Sgblack@eecs.umich.edu            if (bits(machInst, 3, 0) != 0)
10437141Sgblack@eecs.umich.edu                return new WarnUnimplemented("it", machInst);
10447141Sgblack@eecs.umich.edu            switch (bits(machInst, 7, 4)) {
10457141Sgblack@eecs.umich.edu              case 0x0:
10467248Sgblack@eecs.umich.edu                return new NopInst(machInst);
10477141Sgblack@eecs.umich.edu              case 0x1:
10487141Sgblack@eecs.umich.edu                return new WarnUnimplemented("yield", machInst);
10497141Sgblack@eecs.umich.edu              case 0x2:
10507141Sgblack@eecs.umich.edu                return new WarnUnimplemented("wfe", machInst);
10517141Sgblack@eecs.umich.edu              case 0x3:
10527141Sgblack@eecs.umich.edu                return new WarnUnimplemented("wfi", machInst);
10537141Sgblack@eecs.umich.edu              case 0x4:
10547141Sgblack@eecs.umich.edu                return new WarnUnimplemented("sev", machInst);
10557141Sgblack@eecs.umich.edu              default:
10567141Sgblack@eecs.umich.edu                return new WarnUnimplemented("unallocated_hint", machInst);
10577141Sgblack@eecs.umich.edu            }
10587141Sgblack@eecs.umich.edu          default:
10597141Sgblack@eecs.umich.edu            break;
10607141Sgblack@eecs.umich.edu        }
10617141Sgblack@eecs.umich.edu        return new Unknown(machInst);
10627141Sgblack@eecs.umich.edu    }
10637141Sgblack@eecs.umich.edu    '''
10647141Sgblack@eecs.umich.edu}};
10657141Sgblack@eecs.umich.edu
10667141Sgblack@eecs.umich.edudef format Thumb32DataProcModImm() {{
10677141Sgblack@eecs.umich.edu
10687141Sgblack@eecs.umich.edu    def decInst(mnem, dest="rd", op1="rn"):
10697141Sgblack@eecs.umich.edu        return '''
10707141Sgblack@eecs.umich.edu            if (s) {
10717146Sgblack@eecs.umich.edu                return new %(mnem)sImmCc(machInst, %(dest)s,
10727183Sgblack@eecs.umich.edu                                          %(op1)s, imm, rotC);
10737141Sgblack@eecs.umich.edu            } else {
10747146Sgblack@eecs.umich.edu                return new %(mnem)sImm(machInst, %(dest)s,
10757183Sgblack@eecs.umich.edu                                        %(op1)s, imm, rotC);
10767141Sgblack@eecs.umich.edu            }
10777141Sgblack@eecs.umich.edu        ''' % {"mnem" : mnem, "dest" : dest, "op1" : op1}
10787141Sgblack@eecs.umich.edu
10797141Sgblack@eecs.umich.edu    decode_block = '''
10807141Sgblack@eecs.umich.edu    {
10817141Sgblack@eecs.umich.edu        const uint32_t op = bits(machInst, 24, 21);
10827141Sgblack@eecs.umich.edu        const bool s = (bits(machInst, 20) == 1);
10837141Sgblack@eecs.umich.edu        const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
10847141Sgblack@eecs.umich.edu        const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
10857141Sgblack@eecs.umich.edu        const uint32_t ctrlImm = bits(machInst.instBits, 26) << 3 |
10867141Sgblack@eecs.umich.edu                                 bits(machInst, 14, 12);
10877183Sgblack@eecs.umich.edu        const bool rotC = ctrlImm > 3;
10887141Sgblack@eecs.umich.edu        const uint32_t dataImm = bits(machInst, 7, 0);
10897141Sgblack@eecs.umich.edu        const uint32_t imm = modified_imm(ctrlImm, dataImm);
10907141Sgblack@eecs.umich.edu        switch (op) {
10917141Sgblack@eecs.umich.edu          case 0x0:
10927141Sgblack@eecs.umich.edu            if (rd == INTREG_PC) {
10937141Sgblack@eecs.umich.edu                %(tst)s
10947141Sgblack@eecs.umich.edu            } else {
10957141Sgblack@eecs.umich.edu                %(and)s
10967141Sgblack@eecs.umich.edu            }
10977141Sgblack@eecs.umich.edu          case 0x1:
10987141Sgblack@eecs.umich.edu            %(bic)s
10997141Sgblack@eecs.umich.edu          case 0x2:
11007141Sgblack@eecs.umich.edu            if (rn == INTREG_PC) {
11017141Sgblack@eecs.umich.edu                %(mov)s
11027141Sgblack@eecs.umich.edu            } else {
11037141Sgblack@eecs.umich.edu                %(orr)s
11047141Sgblack@eecs.umich.edu            }
11057141Sgblack@eecs.umich.edu          case 0x3:
11067141Sgblack@eecs.umich.edu            if (rn == INTREG_PC) {
11077141Sgblack@eecs.umich.edu                %(mvn)s
11087141Sgblack@eecs.umich.edu            } else {
11097141Sgblack@eecs.umich.edu                %(orn)s
11107141Sgblack@eecs.umich.edu            }
11117141Sgblack@eecs.umich.edu          case 0x4:
11127141Sgblack@eecs.umich.edu            if (rd == INTREG_PC) {
11137141Sgblack@eecs.umich.edu                %(teq)s
11147141Sgblack@eecs.umich.edu            } else {
11157141Sgblack@eecs.umich.edu                %(eor)s
11167141Sgblack@eecs.umich.edu            }
11177141Sgblack@eecs.umich.edu          case 0x8:
11187141Sgblack@eecs.umich.edu            if (rd == INTREG_PC) {
11197141Sgblack@eecs.umich.edu                %(cmn)s
11207141Sgblack@eecs.umich.edu            } else {
11217141Sgblack@eecs.umich.edu                %(add)s
11227141Sgblack@eecs.umich.edu            }
11237141Sgblack@eecs.umich.edu          case 0xa:
11247141Sgblack@eecs.umich.edu            %(adc)s
11257141Sgblack@eecs.umich.edu          case 0xb:
11267141Sgblack@eecs.umich.edu            %(sbc)s
11277141Sgblack@eecs.umich.edu          case 0xd:
11287141Sgblack@eecs.umich.edu            if (rd == INTREG_PC) {
11297141Sgblack@eecs.umich.edu                %(cmp)s
11307141Sgblack@eecs.umich.edu            } else {
11317141Sgblack@eecs.umich.edu                %(sub)s
11327141Sgblack@eecs.umich.edu            }
11337141Sgblack@eecs.umich.edu          case 0xe:
11347141Sgblack@eecs.umich.edu            %(rsb)s
11357141Sgblack@eecs.umich.edu          default:
11367141Sgblack@eecs.umich.edu            return new Unknown(machInst);
11377141Sgblack@eecs.umich.edu        }
11387141Sgblack@eecs.umich.edu    }
11397141Sgblack@eecs.umich.edu    ''' % {
11407141Sgblack@eecs.umich.edu        "tst" : decInst("Tst", "INTREG_ZERO"),
11417141Sgblack@eecs.umich.edu        "and" : decInst("And"),
11427141Sgblack@eecs.umich.edu        "bic" : decInst("Bic"),
11437141Sgblack@eecs.umich.edu        "mov" : decInst("Mov", op1="INTREG_ZERO"),
11447141Sgblack@eecs.umich.edu        "orr" : decInst("Orr"),
11457141Sgblack@eecs.umich.edu        "mvn" : decInst("Mvn", op1="INTREG_ZERO"),
11467141Sgblack@eecs.umich.edu        "orn" : decInst("Orn"),
11477141Sgblack@eecs.umich.edu        "teq" : decInst("Teq", dest="INTREG_ZERO"),
11487141Sgblack@eecs.umich.edu        "eor" : decInst("Eor"),
11497141Sgblack@eecs.umich.edu        "cmn" : decInst("Cmn", dest="INTREG_ZERO"),
11507141Sgblack@eecs.umich.edu        "add" : decInst("Add"),
11517141Sgblack@eecs.umich.edu        "adc" : decInst("Adc"),
11527141Sgblack@eecs.umich.edu        "sbc" : decInst("Sbc"),
11537141Sgblack@eecs.umich.edu        "cmp" : decInst("Cmp", dest="INTREG_ZERO"),
11547141Sgblack@eecs.umich.edu        "sub" : decInst("Sub"),
11557141Sgblack@eecs.umich.edu        "rsb" : decInst("Rsb")
11567141Sgblack@eecs.umich.edu    }
11577141Sgblack@eecs.umich.edu}};
11587141Sgblack@eecs.umich.edu
11597157Sgblack@eecs.umich.edudef format Thumb32DataProcPlainBin() {{
11607157Sgblack@eecs.umich.edu    decode_block = '''
11617157Sgblack@eecs.umich.edu    {
11627157Sgblack@eecs.umich.edu        const uint32_t op = bits(machInst, 24, 20);
11637157Sgblack@eecs.umich.edu        const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
11647157Sgblack@eecs.umich.edu        const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
11657157Sgblack@eecs.umich.edu        switch (op) {
11667157Sgblack@eecs.umich.edu          case 0x0:
11677157Sgblack@eecs.umich.edu            {
11687157Sgblack@eecs.umich.edu                const uint32_t imm = bits(machInst, 7, 0) |
11697157Sgblack@eecs.umich.edu                                     (bits(machInst, 14, 12) << 8) |
11707157Sgblack@eecs.umich.edu                                     (bits(machInst, 26) << 11);
11717185Sgblack@eecs.umich.edu                if (rn == 0xf) {
11727185Sgblack@eecs.umich.edu                    return new AdrImm(machInst, rd, (IntRegIndex)1,
11737185Sgblack@eecs.umich.edu                                      imm, false);
11747185Sgblack@eecs.umich.edu                } else {
11757185Sgblack@eecs.umich.edu                    return new AddImm(machInst, rd, rn, imm, true);
11767185Sgblack@eecs.umich.edu                }
11777157Sgblack@eecs.umich.edu            }
11787157Sgblack@eecs.umich.edu          case 0x4:
11797157Sgblack@eecs.umich.edu            {
11807157Sgblack@eecs.umich.edu                const uint32_t imm = bits(machInst, 7, 0) |
11817157Sgblack@eecs.umich.edu                                     (bits(machInst, 14, 12) << 8) |
11827157Sgblack@eecs.umich.edu                                     (bits(machInst, 26) << 11) |
11837157Sgblack@eecs.umich.edu                                     (bits(machInst, 19, 16) << 12);
11847157Sgblack@eecs.umich.edu                return new MovImm(machInst, rd, INTREG_ZERO, imm, true);
11857157Sgblack@eecs.umich.edu            }
11867157Sgblack@eecs.umich.edu          case 0xa:
11877157Sgblack@eecs.umich.edu            {
11887157Sgblack@eecs.umich.edu                const uint32_t imm = bits(machInst, 7, 0) |
11897157Sgblack@eecs.umich.edu                                     (bits(machInst, 14, 12) << 8) |
11907157Sgblack@eecs.umich.edu                                     (bits(machInst, 26) << 11);
11917185Sgblack@eecs.umich.edu                if (rn == 0xf) {
11927185Sgblack@eecs.umich.edu                    return new AdrImm(machInst, rd, (IntRegIndex)0,
11937185Sgblack@eecs.umich.edu                                      imm, false);
11947185Sgblack@eecs.umich.edu                } else {
11957185Sgblack@eecs.umich.edu                    return new SubImm(machInst, rd, rn, imm, true);
11967185Sgblack@eecs.umich.edu                }
11977157Sgblack@eecs.umich.edu            }
11987157Sgblack@eecs.umich.edu          case 0xc:
11997157Sgblack@eecs.umich.edu            {
12007157Sgblack@eecs.umich.edu                const uint32_t imm = bits(machInst, 7, 0) |
12017157Sgblack@eecs.umich.edu                                     (bits(machInst, 14, 12) << 8) |
12027157Sgblack@eecs.umich.edu                                     (bits(machInst, 26) << 11) |
12037157Sgblack@eecs.umich.edu                                     (bits(machInst, 19, 16) << 12);
12047157Sgblack@eecs.umich.edu                return new MovtImm(machInst, rd, rd, imm, true);
12057157Sgblack@eecs.umich.edu            }
12067157Sgblack@eecs.umich.edu          case 0x12:
12077157Sgblack@eecs.umich.edu            if (!(bits(machInst, 14, 12) || bits(machInst, 7, 6))) {
12087227Sgblack@eecs.umich.edu                const uint32_t satImm = bits(machInst, 4, 0);
12097227Sgblack@eecs.umich.edu                return new Ssat16(machInst, rd, satImm + 1, rn);
12107157Sgblack@eecs.umich.edu            }
12117157Sgblack@eecs.umich.edu            // Fall through on purpose...
12127157Sgblack@eecs.umich.edu          case 0x10:
12137227Sgblack@eecs.umich.edu            {
12147227Sgblack@eecs.umich.edu                const uint32_t satImm = bits(machInst, 4, 0);
12157227Sgblack@eecs.umich.edu                const uint32_t imm = bits(machInst, 7, 6) |
12167227Sgblack@eecs.umich.edu                                     (bits(machInst, 14, 12) << 2);
12177227Sgblack@eecs.umich.edu                const ArmShiftType type =
12187227Sgblack@eecs.umich.edu                    (ArmShiftType)(uint32_t)bits(machInst, 21, 20);
12197227Sgblack@eecs.umich.edu                return new Ssat(machInst, rd, satImm + 1, rn, imm, type);
12207227Sgblack@eecs.umich.edu            }
12217157Sgblack@eecs.umich.edu          case 0x14:
12227157Sgblack@eecs.umich.edu            return new WarnUnimplemented("sbfx", machInst);
12237157Sgblack@eecs.umich.edu          case 0x16:
12247157Sgblack@eecs.umich.edu            if (rn == 0xf) {
12257157Sgblack@eecs.umich.edu                return new WarnUnimplemented("bfc", machInst);
12267157Sgblack@eecs.umich.edu            } else {
12277157Sgblack@eecs.umich.edu                return new WarnUnimplemented("bfi", machInst);
12287157Sgblack@eecs.umich.edu            }
12297157Sgblack@eecs.umich.edu          case 0x1a:
12307157Sgblack@eecs.umich.edu            if (!(bits(machInst, 14, 12) || bits(machInst, 7, 6))) {
12317227Sgblack@eecs.umich.edu                const uint32_t satImm = bits(machInst, 4, 0);
12327227Sgblack@eecs.umich.edu                return new Usat16(machInst, rd, satImm, rn);
12337157Sgblack@eecs.umich.edu            }
12347157Sgblack@eecs.umich.edu            // Fall through on purpose...
12357157Sgblack@eecs.umich.edu          case 0x18:
12367227Sgblack@eecs.umich.edu            {
12377227Sgblack@eecs.umich.edu                const uint32_t satImm = bits(machInst, 4, 0);
12387227Sgblack@eecs.umich.edu                const uint32_t imm = bits(machInst, 7, 6) |
12397227Sgblack@eecs.umich.edu                                     (bits(machInst, 14, 12) << 2);
12407227Sgblack@eecs.umich.edu                const ArmShiftType type =
12417227Sgblack@eecs.umich.edu                    (ArmShiftType)(uint32_t)bits(machInst, 21, 20);
12427227Sgblack@eecs.umich.edu                return new Usat(machInst, rd, satImm, rn, imm, type);
12437227Sgblack@eecs.umich.edu            }
12447157Sgblack@eecs.umich.edu          case 0x1c:
12457157Sgblack@eecs.umich.edu            return new WarnUnimplemented("ubfx", machInst);
12467157Sgblack@eecs.umich.edu          default:
12477157Sgblack@eecs.umich.edu            return new Unknown(machInst);
12487157Sgblack@eecs.umich.edu        }
12497157Sgblack@eecs.umich.edu    }
12507157Sgblack@eecs.umich.edu    '''
12517157Sgblack@eecs.umich.edu}};
12527157Sgblack@eecs.umich.edu
12537141Sgblack@eecs.umich.edudef format Thumb32DataProcShiftReg() {{
12547141Sgblack@eecs.umich.edu
12557141Sgblack@eecs.umich.edu    def decInst(mnem, dest="rd", op1="rn"):
12567141Sgblack@eecs.umich.edu        return '''
12577141Sgblack@eecs.umich.edu            if (s) {
12587146Sgblack@eecs.umich.edu                return new %(mnem)sRegCc(machInst, %(dest)s,
12597141Sgblack@eecs.umich.edu                                          %(op1)s, rm, amt, type);
12607141Sgblack@eecs.umich.edu            } else {
12617146Sgblack@eecs.umich.edu                return new %(mnem)sReg(machInst, %(dest)s,
12627141Sgblack@eecs.umich.edu                                        %(op1)s, rm, amt, type);
12637141Sgblack@eecs.umich.edu            }
12647141Sgblack@eecs.umich.edu        ''' % {"mnem" : mnem, "dest" : dest, "op1" : op1}
12657141Sgblack@eecs.umich.edu
12667141Sgblack@eecs.umich.edu    decode_block = '''
12677141Sgblack@eecs.umich.edu    {
12687141Sgblack@eecs.umich.edu        const uint32_t op = bits(machInst, 24, 21);
12697141Sgblack@eecs.umich.edu        const bool s = (bits(machInst, 20) == 1);
12707141Sgblack@eecs.umich.edu        const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
12717141Sgblack@eecs.umich.edu        const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
12727141Sgblack@eecs.umich.edu        const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
12737141Sgblack@eecs.umich.edu        const uint32_t amt = (bits(machInst, 14, 12) << 2) |
12747141Sgblack@eecs.umich.edu                              bits(machInst, 7, 6);
12757141Sgblack@eecs.umich.edu        const ArmShiftType type = (ArmShiftType)(uint32_t)bits(machInst, 5, 4);
12767141Sgblack@eecs.umich.edu        switch (op) {
12777141Sgblack@eecs.umich.edu          case 0x0:
12787141Sgblack@eecs.umich.edu            if (rd == INTREG_PC) {
12797141Sgblack@eecs.umich.edu                %(tst)s
12807141Sgblack@eecs.umich.edu            } else {
12817141Sgblack@eecs.umich.edu                %(and)s
12827141Sgblack@eecs.umich.edu            }
12837141Sgblack@eecs.umich.edu          case 0x1:
12847141Sgblack@eecs.umich.edu            %(bic)s
12857141Sgblack@eecs.umich.edu          case 0x2:
12867141Sgblack@eecs.umich.edu            if (rn == INTREG_PC) {
12877141Sgblack@eecs.umich.edu                %(mov)s
12887141Sgblack@eecs.umich.edu            } else {
12897141Sgblack@eecs.umich.edu                %(orr)s
12907141Sgblack@eecs.umich.edu            }
12917141Sgblack@eecs.umich.edu          case 0x3:
12927141Sgblack@eecs.umich.edu            if (rn == INTREG_PC) {
12937141Sgblack@eecs.umich.edu                %(mvn)s
12947141Sgblack@eecs.umich.edu            } else {
12957141Sgblack@eecs.umich.edu                %(orn)s
12967141Sgblack@eecs.umich.edu            }
12977141Sgblack@eecs.umich.edu          case 0x4:
12987141Sgblack@eecs.umich.edu            if (rd == INTREG_PC) {
12997141Sgblack@eecs.umich.edu                %(teq)s
13007141Sgblack@eecs.umich.edu            } else {
13017141Sgblack@eecs.umich.edu                %(eor)s
13027141Sgblack@eecs.umich.edu            }
13037141Sgblack@eecs.umich.edu          case 0x6:
13047237Sgblack@eecs.umich.edu            if (type) {
13057237Sgblack@eecs.umich.edu                return new PkhtbReg(machInst, rd, rn, rm, amt, type);
13067237Sgblack@eecs.umich.edu            } else {
13077237Sgblack@eecs.umich.edu                return new PkhbtReg(machInst, rd, rn, rm, amt, type);
13087237Sgblack@eecs.umich.edu            }
13097141Sgblack@eecs.umich.edu          case 0x8:
13107141Sgblack@eecs.umich.edu            if (rd == INTREG_PC) {
13117141Sgblack@eecs.umich.edu                %(cmn)s
13127141Sgblack@eecs.umich.edu            } else {
13137141Sgblack@eecs.umich.edu                %(add)s
13147141Sgblack@eecs.umich.edu            }
13157141Sgblack@eecs.umich.edu          case 0xa:
13167141Sgblack@eecs.umich.edu            %(adc)s
13177141Sgblack@eecs.umich.edu          case 0xb:
13187141Sgblack@eecs.umich.edu            %(sbc)s
13197141Sgblack@eecs.umich.edu          case 0xd:
13207141Sgblack@eecs.umich.edu            if (rd == INTREG_PC) {
13217141Sgblack@eecs.umich.edu                %(cmp)s
13227141Sgblack@eecs.umich.edu            } else {
13237141Sgblack@eecs.umich.edu                %(sub)s
13247141Sgblack@eecs.umich.edu            }
13257141Sgblack@eecs.umich.edu          case 0xe:
13267141Sgblack@eecs.umich.edu            %(rsb)s
13277141Sgblack@eecs.umich.edu          default:
13287141Sgblack@eecs.umich.edu            return new Unknown(machInst);
13297141Sgblack@eecs.umich.edu        }
13307141Sgblack@eecs.umich.edu    }
13317141Sgblack@eecs.umich.edu    ''' % {
13327141Sgblack@eecs.umich.edu        "tst" : decInst("Tst", "INTREG_ZERO"),
13337141Sgblack@eecs.umich.edu        "and" : decInst("And"),
13347141Sgblack@eecs.umich.edu        "bic" : decInst("Bic"),
13357141Sgblack@eecs.umich.edu        "mov" : decInst("Mov", op1="INTREG_ZERO"),
13367141Sgblack@eecs.umich.edu        "orr" : decInst("Orr"),
13377141Sgblack@eecs.umich.edu        "mvn" : decInst("Mvn", op1="INTREG_ZERO"),
13387141Sgblack@eecs.umich.edu        "orn" : decInst("Orn"),
13397141Sgblack@eecs.umich.edu        "teq" : decInst("Teq", "INTREG_ZERO"),
13407141Sgblack@eecs.umich.edu        "eor" : decInst("Eor"),
13417141Sgblack@eecs.umich.edu        "cmn" : decInst("Cmn", "INTREG_ZERO"),
13427141Sgblack@eecs.umich.edu        "add" : decInst("Add"),
13437141Sgblack@eecs.umich.edu        "adc" : decInst("Adc"),
13447141Sgblack@eecs.umich.edu        "sbc" : decInst("Sbc"),
13457141Sgblack@eecs.umich.edu        "cmp" : decInst("Cmp", "INTREG_ZERO"),
13467141Sgblack@eecs.umich.edu        "sub" : decInst("Sub"),
13477141Sgblack@eecs.umich.edu        "rsb" : decInst("Rsb")
13487141Sgblack@eecs.umich.edu    }
13497141Sgblack@eecs.umich.edu}};
1350