data.isa revision 7235
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
387139Sgblack@eecs.umich.edudef format ArmDataProcReg() {{
397188Sgblack@eecs.umich.edu    pclr = '''
407188Sgblack@eecs.umich.edu        return new %(className)ssRegPclr(machInst, %(dest)s,
417188Sgblack@eecs.umich.edu                                        %(op1)s, rm, imm5,
427188Sgblack@eecs.umich.edu                                        type);
437188Sgblack@eecs.umich.edu    '''
447139Sgblack@eecs.umich.edu    instDecode = '''
457139Sgblack@eecs.umich.edu          case %(opcode)#x:
467139Sgblack@eecs.umich.edu            if (immShift) {
477139Sgblack@eecs.umich.edu                if (setCc) {
487188Sgblack@eecs.umich.edu                    if (%(dest)s == INTREG_PC) {
497188Sgblack@eecs.umich.edu                        %(pclr)s
507188Sgblack@eecs.umich.edu                    } else {
517188Sgblack@eecs.umich.edu                        return new %(className)sRegCc(machInst, %(dest)s,
527188Sgblack@eecs.umich.edu                                                      %(op1)s, rm, imm5, type);
537188Sgblack@eecs.umich.edu                    }
547139Sgblack@eecs.umich.edu                } else {
557146Sgblack@eecs.umich.edu                    return new %(className)sReg(machInst, %(dest)s, %(op1)s,
567141Sgblack@eecs.umich.edu                                                 rm, imm5, type);
577139Sgblack@eecs.umich.edu                }
587139Sgblack@eecs.umich.edu            } else {
597139Sgblack@eecs.umich.edu                if (setCc) {
607146Sgblack@eecs.umich.edu                    return new %(className)sRegRegCc(machInst, %(dest)s,
617141Sgblack@eecs.umich.edu                                                      %(op1)s, rm, rs, type);
627139Sgblack@eecs.umich.edu                } else {
637146Sgblack@eecs.umich.edu                    return new %(className)sRegReg(machInst, %(dest)s,
647141Sgblack@eecs.umich.edu                                                    %(op1)s, rm, rs, type);
657139Sgblack@eecs.umich.edu                }
667139Sgblack@eecs.umich.edu            }
677139Sgblack@eecs.umich.edu            break;
687139Sgblack@eecs.umich.edu    '''
697139Sgblack@eecs.umich.edu
707188Sgblack@eecs.umich.edu    def instCode(opcode, mnem, useDest = True, useOp1 = True):
717188Sgblack@eecs.umich.edu        global pclr
727188Sgblack@eecs.umich.edu        if useDest:
737188Sgblack@eecs.umich.edu            dest = "rd"
747188Sgblack@eecs.umich.edu        else:
757188Sgblack@eecs.umich.edu            dest = "INTREG_ZERO"
767188Sgblack@eecs.umich.edu        if useOp1:
777188Sgblack@eecs.umich.edu            op1 = "rn"
787188Sgblack@eecs.umich.edu        else:
797188Sgblack@eecs.umich.edu            op1 = "INTREG_ZERO"
807188Sgblack@eecs.umich.edu        global instDecode, pclrCode
817188Sgblack@eecs.umich.edu        substDict = { "className": mnem.capitalize(),
827188Sgblack@eecs.umich.edu                      "opcode": opcode,
837188Sgblack@eecs.umich.edu                      "dest": dest,
847188Sgblack@eecs.umich.edu                      "op1": op1 }
857188Sgblack@eecs.umich.edu        if useDest:
867188Sgblack@eecs.umich.edu            substDict["pclr"] = pclr % substDict
877188Sgblack@eecs.umich.edu        else:
887188Sgblack@eecs.umich.edu            substDict["pclr"] = ""
897188Sgblack@eecs.umich.edu        return instDecode % substDict
907139Sgblack@eecs.umich.edu
917139Sgblack@eecs.umich.edu    decode_block = '''
927139Sgblack@eecs.umich.edu    {
937139Sgblack@eecs.umich.edu        const bool immShift = (bits(machInst, 4) == 0);
947139Sgblack@eecs.umich.edu        const bool setCc = (bits(machInst, 20) == 1);
957139Sgblack@eecs.umich.edu        const uint32_t imm5 = bits(machInst, 11, 7);
967139Sgblack@eecs.umich.edu        const ArmShiftType type = (ArmShiftType)(uint32_t)bits(machInst, 6, 5);
977139Sgblack@eecs.umich.edu        const IntRegIndex rd = (IntRegIndex)(uint32_t)RD;
987139Sgblack@eecs.umich.edu        const IntRegIndex rn = (IntRegIndex)(uint32_t)RN;
997139Sgblack@eecs.umich.edu        const IntRegIndex rm = (IntRegIndex)(uint32_t)RM;
1007139Sgblack@eecs.umich.edu        const IntRegIndex rs = (IntRegIndex)(uint32_t)RS;
1017139Sgblack@eecs.umich.edu        switch (OPCODE) {
1027139Sgblack@eecs.umich.edu    '''
1037139Sgblack@eecs.umich.edu    decode_block += instCode(0x0, "and")
1047139Sgblack@eecs.umich.edu    decode_block += instCode(0x1, "eor")
1057139Sgblack@eecs.umich.edu    decode_block += instCode(0x2, "sub")
1067139Sgblack@eecs.umich.edu    decode_block += instCode(0x3, "rsb")
1077139Sgblack@eecs.umich.edu    decode_block += instCode(0x4, "add")
1087139Sgblack@eecs.umich.edu    decode_block += instCode(0x5, "adc")
1097139Sgblack@eecs.umich.edu    decode_block += instCode(0x6, "sbc")
1107139Sgblack@eecs.umich.edu    decode_block += instCode(0x7, "rsc")
1117188Sgblack@eecs.umich.edu    decode_block += instCode(0x8, "tst", useDest = False)
1127188Sgblack@eecs.umich.edu    decode_block += instCode(0x9, "teq", useDest = False)
1137188Sgblack@eecs.umich.edu    decode_block += instCode(0xa, "cmp", useDest = False)
1147188Sgblack@eecs.umich.edu    decode_block += instCode(0xb, "cmn", useDest = False)
1157139Sgblack@eecs.umich.edu    decode_block += instCode(0xc, "orr")
1167188Sgblack@eecs.umich.edu    decode_block += instCode(0xd, "mov", useOp1 = False)
1177139Sgblack@eecs.umich.edu    decode_block += instCode(0xe, "bic")
1187188Sgblack@eecs.umich.edu    decode_block += instCode(0xf, "mvn", useOp1 = False)
1197139Sgblack@eecs.umich.edu    decode_block += '''
1207139Sgblack@eecs.umich.edu          default:
1217139Sgblack@eecs.umich.edu            return new Unknown(machInst);
1227139Sgblack@eecs.umich.edu        }
1237139Sgblack@eecs.umich.edu    }
1247139Sgblack@eecs.umich.edu    '''
1257139Sgblack@eecs.umich.edu}};
1267139Sgblack@eecs.umich.edu
1277210Sgblack@eecs.umich.edudef format ArmPackUnpackSatReverse() {{
1287210Sgblack@eecs.umich.edu    decode_block = '''
1297210Sgblack@eecs.umich.edu    {
1307210Sgblack@eecs.umich.edu        const uint32_t op1 = bits(machInst, 22, 20);
1317210Sgblack@eecs.umich.edu        const uint32_t a = bits(machInst, 19, 16);
1327210Sgblack@eecs.umich.edu        const uint32_t op2 = bits(machInst, 7, 5);
1337210Sgblack@eecs.umich.edu        if (bits(op2, 0) == 0) {
1347227Sgblack@eecs.umich.edu            const IntRegIndex rn =
1357227Sgblack@eecs.umich.edu                (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
1367227Sgblack@eecs.umich.edu            const IntRegIndex rd =
1377227Sgblack@eecs.umich.edu                (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
1387227Sgblack@eecs.umich.edu            const uint32_t satImm = bits(machInst, 20, 16);
1397227Sgblack@eecs.umich.edu            const uint32_t imm = bits(machInst, 11, 7);
1407227Sgblack@eecs.umich.edu            const ArmShiftType type =
1417227Sgblack@eecs.umich.edu                (ArmShiftType)(uint32_t)bits(machInst, 6, 5);
1427210Sgblack@eecs.umich.edu            if (op1 == 0) {
1437210Sgblack@eecs.umich.edu                return new WarnUnimplemented("pkh", machInst);
1447210Sgblack@eecs.umich.edu            } else if (bits(op1, 2, 1) == 1) {
1457227Sgblack@eecs.umich.edu                return new Ssat(machInst, rd, satImm + 1, rn, imm, type);
1467210Sgblack@eecs.umich.edu            } else if (bits(op1, 2, 1) == 3) {
1477227Sgblack@eecs.umich.edu                return new Usat(machInst, rd, satImm, rn, imm, type);
1487210Sgblack@eecs.umich.edu            }
1497210Sgblack@eecs.umich.edu            return new Unknown(machInst);
1507210Sgblack@eecs.umich.edu        }
1517210Sgblack@eecs.umich.edu        switch (op1) {
1527210Sgblack@eecs.umich.edu          case 0x0:
1537210Sgblack@eecs.umich.edu            if (op2 == 0x3) {
1547235Sgblack@eecs.umich.edu                const IntRegIndex rn =
1557235Sgblack@eecs.umich.edu                    (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
1567235Sgblack@eecs.umich.edu                const IntRegIndex rd =
1577235Sgblack@eecs.umich.edu                    (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
1587235Sgblack@eecs.umich.edu                const IntRegIndex rm =
1597235Sgblack@eecs.umich.edu                    (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
1607235Sgblack@eecs.umich.edu                const uint32_t rotation =
1617235Sgblack@eecs.umich.edu                    (uint32_t)bits(machInst, 11, 10) << 3;
1627210Sgblack@eecs.umich.edu                if (a == 0xf) {
1637235Sgblack@eecs.umich.edu                    return new Sxtb16(machInst, rd, rotation, rm);
1647210Sgblack@eecs.umich.edu                } else {
1657235Sgblack@eecs.umich.edu                    return new Sxtab16(machInst, rd, rn, rm, rotation);
1667210Sgblack@eecs.umich.edu                }
1677210Sgblack@eecs.umich.edu            } else if (op2 == 0x5) {
1687210Sgblack@eecs.umich.edu                return new WarnUnimplemented("sel", machInst);
1697210Sgblack@eecs.umich.edu            }
1707210Sgblack@eecs.umich.edu            break;
1717210Sgblack@eecs.umich.edu          case 0x2:
1727210Sgblack@eecs.umich.edu            if (op2 == 0x1) {
1737227Sgblack@eecs.umich.edu                const IntRegIndex rn =
1747227Sgblack@eecs.umich.edu                    (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
1757227Sgblack@eecs.umich.edu                const IntRegIndex rd =
1767227Sgblack@eecs.umich.edu                    (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
1777227Sgblack@eecs.umich.edu                const uint32_t satImm = bits(machInst, 20, 16);
1787227Sgblack@eecs.umich.edu                return new Ssat16(machInst, rd, satImm + 1, rn);
1797210Sgblack@eecs.umich.edu            } else if (op2 == 0x3) {
1807235Sgblack@eecs.umich.edu                const IntRegIndex rn =
1817235Sgblack@eecs.umich.edu                    (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
1827235Sgblack@eecs.umich.edu                const IntRegIndex rd =
1837235Sgblack@eecs.umich.edu                    (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
1847235Sgblack@eecs.umich.edu                const IntRegIndex rm =
1857235Sgblack@eecs.umich.edu                    (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
1867235Sgblack@eecs.umich.edu                const uint32_t rotation =
1877235Sgblack@eecs.umich.edu                    (uint32_t)bits(machInst, 11, 10) << 3;
1887210Sgblack@eecs.umich.edu                if (a == 0xf) {
1897235Sgblack@eecs.umich.edu                    return new Sxtb(machInst, rd, rotation, rm);
1907210Sgblack@eecs.umich.edu                } else {
1917235Sgblack@eecs.umich.edu                    return new Sxtab(machInst, rd, rn, rm, rotation);
1927210Sgblack@eecs.umich.edu                }
1937210Sgblack@eecs.umich.edu            }
1947210Sgblack@eecs.umich.edu            break;
1957210Sgblack@eecs.umich.edu          case 0x3:
1967210Sgblack@eecs.umich.edu            if (op2 == 0x1) {
1977211Sgblack@eecs.umich.edu                IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
1987211Sgblack@eecs.umich.edu                IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
1997211Sgblack@eecs.umich.edu                return new Rev(machInst, rd, rm);
2007210Sgblack@eecs.umich.edu            } else if (op2 == 0x3) {
2017235Sgblack@eecs.umich.edu                const IntRegIndex rn =
2027235Sgblack@eecs.umich.edu                    (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
2037235Sgblack@eecs.umich.edu                const IntRegIndex rd =
2047235Sgblack@eecs.umich.edu                    (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
2057235Sgblack@eecs.umich.edu                const IntRegIndex rm =
2067235Sgblack@eecs.umich.edu                    (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
2077235Sgblack@eecs.umich.edu                const uint32_t rotation =
2087235Sgblack@eecs.umich.edu                    (uint32_t)bits(machInst, 11, 10) << 3;
2097210Sgblack@eecs.umich.edu                if (a == 0xf) {
2107235Sgblack@eecs.umich.edu                    return new Sxth(machInst, rd, rotation, rm);
2117210Sgblack@eecs.umich.edu                } else {
2127235Sgblack@eecs.umich.edu                    return new Sxtah(machInst, rd, rn, rm, rotation);
2137210Sgblack@eecs.umich.edu                }
2147210Sgblack@eecs.umich.edu            } else if (op2 == 0x5) {
2157211Sgblack@eecs.umich.edu                IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
2167211Sgblack@eecs.umich.edu                IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
2177211Sgblack@eecs.umich.edu                return new Rev16(machInst, rd, rm);
2187210Sgblack@eecs.umich.edu            }
2197210Sgblack@eecs.umich.edu            break;
2207210Sgblack@eecs.umich.edu          case 0x4:
2217210Sgblack@eecs.umich.edu            if (op2 == 0x3) {
2227235Sgblack@eecs.umich.edu                const IntRegIndex rn =
2237235Sgblack@eecs.umich.edu                    (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
2247235Sgblack@eecs.umich.edu                const IntRegIndex rd =
2257235Sgblack@eecs.umich.edu                    (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
2267235Sgblack@eecs.umich.edu                const IntRegIndex rm =
2277235Sgblack@eecs.umich.edu                    (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
2287235Sgblack@eecs.umich.edu                const uint32_t rotation =
2297235Sgblack@eecs.umich.edu                    (uint32_t)bits(machInst, 11, 10) << 3;
2307210Sgblack@eecs.umich.edu                if (a == 0xf) {
2317235Sgblack@eecs.umich.edu                    return new Uxtb16(machInst, rd, rotation, rm);
2327210Sgblack@eecs.umich.edu                } else {
2337235Sgblack@eecs.umich.edu                    return new Uxtab16(machInst, rd, rn, rm, rotation);
2347210Sgblack@eecs.umich.edu                }
2357210Sgblack@eecs.umich.edu            }
2367210Sgblack@eecs.umich.edu            break;
2377210Sgblack@eecs.umich.edu          case 0x6:
2387210Sgblack@eecs.umich.edu            if (op2 == 0x1) {
2397227Sgblack@eecs.umich.edu                const IntRegIndex rn =
2407227Sgblack@eecs.umich.edu                    (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
2417227Sgblack@eecs.umich.edu                const IntRegIndex rd =
2427227Sgblack@eecs.umich.edu                    (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
2437227Sgblack@eecs.umich.edu                const uint32_t satImm = bits(machInst, 20, 16);
2447227Sgblack@eecs.umich.edu                return new Usat16(machInst, rd, satImm, rn);
2457210Sgblack@eecs.umich.edu            } else 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 Uxtb(machInst, rd, rotation, rm);
2567210Sgblack@eecs.umich.edu                } else {
2577235Sgblack@eecs.umich.edu                    return new Uxtab(machInst, rd, rn, rm, rotation);
2587210Sgblack@eecs.umich.edu                }
2597210Sgblack@eecs.umich.edu            }
2607210Sgblack@eecs.umich.edu            break;
2617210Sgblack@eecs.umich.edu          case 0x7:
2627210Sgblack@eecs.umich.edu            if (op2 == 0x1) {
2637210Sgblack@eecs.umich.edu                return new WarnUnimplemented("rbit", machInst);
2647210Sgblack@eecs.umich.edu            } else if (op2 == 0x3) {
2657235Sgblack@eecs.umich.edu                const IntRegIndex rn =
2667235Sgblack@eecs.umich.edu                    (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
2677235Sgblack@eecs.umich.edu                const IntRegIndex rd =
2687235Sgblack@eecs.umich.edu                    (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
2697235Sgblack@eecs.umich.edu                const IntRegIndex rm =
2707235Sgblack@eecs.umich.edu                    (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
2717235Sgblack@eecs.umich.edu                const uint32_t rotation =
2727235Sgblack@eecs.umich.edu                    (uint32_t)bits(machInst, 11, 10) << 3;
2737210Sgblack@eecs.umich.edu                if (a == 0xf) {
2747235Sgblack@eecs.umich.edu                    return new Uxth(machInst, rd, rotation, rm);
2757210Sgblack@eecs.umich.edu                } else {
2767235Sgblack@eecs.umich.edu                    return new Uxtah(machInst, rd, rn, rm, rotation);
2777210Sgblack@eecs.umich.edu                }
2787210Sgblack@eecs.umich.edu            } else if (op2 == 0x5) {
2797211Sgblack@eecs.umich.edu                IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
2807211Sgblack@eecs.umich.edu                IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
2817211Sgblack@eecs.umich.edu                return new Revsh(machInst, rd, rm);
2827210Sgblack@eecs.umich.edu            }
2837210Sgblack@eecs.umich.edu            break;
2847210Sgblack@eecs.umich.edu        }
2857210Sgblack@eecs.umich.edu        return new Unknown(machInst);
2867210Sgblack@eecs.umich.edu    }
2877210Sgblack@eecs.umich.edu    '''
2887210Sgblack@eecs.umich.edu}};
2897210Sgblack@eecs.umich.edu
2907194Sgblack@eecs.umich.edudef format ArmParallelAddSubtract() {{
2917194Sgblack@eecs.umich.edu    decode_block='''
2927194Sgblack@eecs.umich.edu    {
2937194Sgblack@eecs.umich.edu        const uint32_t op1 = bits(machInst, 21, 20);
2947194Sgblack@eecs.umich.edu        const uint32_t op2 = bits(machInst, 7, 5);
2957194Sgblack@eecs.umich.edu        const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
2967194Sgblack@eecs.umich.edu        const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
2977194Sgblack@eecs.umich.edu        const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
2987194Sgblack@eecs.umich.edu        if (bits(machInst, 22) == 0) {
2997194Sgblack@eecs.umich.edu            switch (op1) {
3007194Sgblack@eecs.umich.edu              case 0x1:
3017194Sgblack@eecs.umich.edu                switch (op2) {
3027194Sgblack@eecs.umich.edu                  case 0x0:
3037216Sgblack@eecs.umich.edu                    return new Sadd16RegCc(machInst, rd, rn, rm, 0, LSL);
3047194Sgblack@eecs.umich.edu                  case 0x1:
3057224Sgblack@eecs.umich.edu                    return new SasxRegCc(machInst, rd, rn, rm, 0, LSL);
3067194Sgblack@eecs.umich.edu                  case 0x2:
3077224Sgblack@eecs.umich.edu                    return new SsaxRegCc(machInst, rd, rn, rm, 0, LSL);
3087194Sgblack@eecs.umich.edu                  case 0x3:
3097218Sgblack@eecs.umich.edu                    return new Ssub16RegCc(machInst, rd, rn, rm, 0, LSL);
3107194Sgblack@eecs.umich.edu                  case 0x4:
3117216Sgblack@eecs.umich.edu                    return new Sadd8RegCc(machInst, rd, rn, rm, 0, LSL);
3127194Sgblack@eecs.umich.edu                  case 0x7:
3137218Sgblack@eecs.umich.edu                    return new Ssub8RegCc(machInst, rd, rn, rm, 0, LSL);
3147194Sgblack@eecs.umich.edu                }
3157194Sgblack@eecs.umich.edu                break;
3167194Sgblack@eecs.umich.edu              case 0x2:
3177194Sgblack@eecs.umich.edu                switch (op2) {
3187194Sgblack@eecs.umich.edu                  case 0x0:
3197194Sgblack@eecs.umich.edu                    return new Qadd16Reg(machInst, rd, rn, rm, 0, LSL);
3207194Sgblack@eecs.umich.edu                  case 0x1:
3217194Sgblack@eecs.umich.edu                    return new QasxReg(machInst, rd, rn, rm, 0, LSL);
3227194Sgblack@eecs.umich.edu                  case 0x2:
3237194Sgblack@eecs.umich.edu                    return new QsaxReg(machInst, rd, rn, rm, 0, LSL);
3247194Sgblack@eecs.umich.edu                  case 0x3:
3257194Sgblack@eecs.umich.edu                    return new Qsub16Reg(machInst, rd, rn, rm, 0, LSL);
3267194Sgblack@eecs.umich.edu                  case 0x4:
3277194Sgblack@eecs.umich.edu                    return new Qadd8Reg(machInst, rd, rn, rm, 0, LSL);
3287194Sgblack@eecs.umich.edu                  case 0x7:
3297194Sgblack@eecs.umich.edu                    return new Qsub8Reg(machInst, rd, rn, rm, 0, LSL);
3307194Sgblack@eecs.umich.edu                }
3317194Sgblack@eecs.umich.edu                break;
3327194Sgblack@eecs.umich.edu              case 0x3:
3337194Sgblack@eecs.umich.edu                switch (op2) {
3347194Sgblack@eecs.umich.edu                  case 0x0:
3357231Sgblack@eecs.umich.edu                    return new Shadd16Reg(machInst, rd, rn, rm, 0, LSL);
3367194Sgblack@eecs.umich.edu                  case 0x1:
3377231Sgblack@eecs.umich.edu                    return new ShasxReg(machInst, rd, rn, rm, 0, LSL);
3387194Sgblack@eecs.umich.edu                  case 0x2:
3397231Sgblack@eecs.umich.edu                    return new ShsaxReg(machInst, rd, rn, rm, 0, LSL);
3407194Sgblack@eecs.umich.edu                  case 0x3:
3417231Sgblack@eecs.umich.edu                    return new Shsub16Reg(machInst, rd, rn, rm, 0, LSL);
3427194Sgblack@eecs.umich.edu                  case 0x4:
3437231Sgblack@eecs.umich.edu                    return new Shadd8Reg(machInst, rd, rn, rm, 0, LSL);
3447194Sgblack@eecs.umich.edu                  case 0x7:
3457231Sgblack@eecs.umich.edu                    return new Shsub8Reg(machInst, rd, rn, rm, 0, LSL);
3467194Sgblack@eecs.umich.edu                }
3477194Sgblack@eecs.umich.edu                break;
3487194Sgblack@eecs.umich.edu            }
3497194Sgblack@eecs.umich.edu        } else {
3507194Sgblack@eecs.umich.edu            switch (op1) {
3517194Sgblack@eecs.umich.edu              case 0x1:
3527194Sgblack@eecs.umich.edu                switch (op2) {
3537194Sgblack@eecs.umich.edu                  case 0x0:
3547222Sgblack@eecs.umich.edu                    return new Uadd16RegCc(machInst, rd, rn, rm, 0, LSL);
3557194Sgblack@eecs.umich.edu                  case 0x1:
3567222Sgblack@eecs.umich.edu                    return new UasxRegCc(machInst, rd, rn, rm, 0, LSL);
3577194Sgblack@eecs.umich.edu                  case 0x2:
3587222Sgblack@eecs.umich.edu                    return new UsaxRegCc(machInst, rd, rn, rm, 0, LSL);
3597194Sgblack@eecs.umich.edu                  case 0x3:
3607222Sgblack@eecs.umich.edu                    return new Usub16RegCc(machInst, rd, rn, rm, 0, LSL);
3617194Sgblack@eecs.umich.edu                  case 0x4:
3627222Sgblack@eecs.umich.edu                    return new Uadd8RegCc(machInst, rd, rn, rm, 0, LSL);
3637194Sgblack@eecs.umich.edu                  case 0x7:
3647222Sgblack@eecs.umich.edu                    return new Usub8RegCc(machInst, rd, rn, rm, 0, LSL);
3657194Sgblack@eecs.umich.edu                }
3667194Sgblack@eecs.umich.edu                break;
3677194Sgblack@eecs.umich.edu              case 0x2:
3687194Sgblack@eecs.umich.edu                switch (op2) {
3697194Sgblack@eecs.umich.edu                  case 0x0:
3707220Sgblack@eecs.umich.edu                    return new Uqadd16Reg(machInst, rd, rn, rm, 0, LSL);
3717194Sgblack@eecs.umich.edu                  case 0x1:
3727220Sgblack@eecs.umich.edu                    return new UqasxReg(machInst, rd, rn, rm, 0, LSL);
3737194Sgblack@eecs.umich.edu                  case 0x2:
3747220Sgblack@eecs.umich.edu                    return new UqsaxReg(machInst, rd, rn, rm, 0, LSL);
3757194Sgblack@eecs.umich.edu                  case 0x3:
3767220Sgblack@eecs.umich.edu                    return new Uqsub16Reg(machInst, rd, rn, rm, 0, LSL);
3777194Sgblack@eecs.umich.edu                  case 0x4:
3787220Sgblack@eecs.umich.edu                    return new Uqadd8Reg(machInst, rd, rn, rm, 0, LSL);
3797194Sgblack@eecs.umich.edu                  case 0x7:
3807220Sgblack@eecs.umich.edu                    return new Uqsub8Reg(machInst, rd, rn, rm, 0, LSL);
3817194Sgblack@eecs.umich.edu                }
3827194Sgblack@eecs.umich.edu                break;
3837194Sgblack@eecs.umich.edu              case 0x3:
3847194Sgblack@eecs.umich.edu                switch (op2) {
3857194Sgblack@eecs.umich.edu                  case 0x0:
3867231Sgblack@eecs.umich.edu                    return new Uhadd16Reg(machInst, rd, rn, rm, 0, LSL);
3877194Sgblack@eecs.umich.edu                  case 0x1:
3887231Sgblack@eecs.umich.edu                    return new UhasxReg(machInst, rd, rn, rm, 0, LSL);
3897194Sgblack@eecs.umich.edu                  case 0x2:
3907231Sgblack@eecs.umich.edu                    return new UhsaxReg(machInst, rd, rn, rm, 0, LSL);
3917194Sgblack@eecs.umich.edu                  case 0x3:
3927231Sgblack@eecs.umich.edu                    return new Uhsub16Reg(machInst, rd, rn, rm, 0, LSL);
3937194Sgblack@eecs.umich.edu                  case 0x4:
3947231Sgblack@eecs.umich.edu                    return new Uhadd8Reg(machInst, rd, rn, rm, 0, LSL);
3957194Sgblack@eecs.umich.edu                  case 0x7:
3967231Sgblack@eecs.umich.edu                    return new Uhsub8Reg(machInst, rd, rn, rm, 0, LSL);
3977194Sgblack@eecs.umich.edu                }
3987194Sgblack@eecs.umich.edu                break;
3997194Sgblack@eecs.umich.edu            }
4007194Sgblack@eecs.umich.edu        }
4017194Sgblack@eecs.umich.edu        return new Unknown(machInst);
4027194Sgblack@eecs.umich.edu    }
4037194Sgblack@eecs.umich.edu    '''
4047194Sgblack@eecs.umich.edu}};
4057194Sgblack@eecs.umich.edu
4067139Sgblack@eecs.umich.edudef format ArmDataProcImm() {{
4077188Sgblack@eecs.umich.edu    pclr = '''
4087188Sgblack@eecs.umich.edu        return new %(className)ssImmPclr(machInst, %(dest)s,
4097188Sgblack@eecs.umich.edu                                        %(op1)s, imm, false);
4107188Sgblack@eecs.umich.edu    '''
4117188Sgblack@eecs.umich.edu    adr = '''
4127188Sgblack@eecs.umich.edu        return new AdrImm(machInst, %(dest)s, %(add)s,
4137188Sgblack@eecs.umich.edu                                     imm, false);
4147188Sgblack@eecs.umich.edu    '''
4157139Sgblack@eecs.umich.edu    instDecode = '''
4167188Sgblack@eecs.umich.edu          case %(opcode)#x:
4177139Sgblack@eecs.umich.edu            if (setCc) {
4187188Sgblack@eecs.umich.edu                if (%(pclrInst)s && %(dest)s == INTREG_PC) {
4197188Sgblack@eecs.umich.edu                    %(pclr)s
4207188Sgblack@eecs.umich.edu                } else {
4217188Sgblack@eecs.umich.edu                    return new %(className)sImmCc(machInst, %(dest)s, %(op1)s,
4227188Sgblack@eecs.umich.edu                                                   imm, rotC);
4237188Sgblack@eecs.umich.edu                }
4247139Sgblack@eecs.umich.edu            } else {
4257188Sgblack@eecs.umich.edu                if (%(adrInst)s && %(op1)s == INTREG_PC) {
4267188Sgblack@eecs.umich.edu                    %(adr)s
4277188Sgblack@eecs.umich.edu                } else {
4287188Sgblack@eecs.umich.edu                    return new %(className)sImm(machInst, %(dest)s, %(op1)s,
4297188Sgblack@eecs.umich.edu                                                 imm, rotC);
4307188Sgblack@eecs.umich.edu                }
4317139Sgblack@eecs.umich.edu            }
4327139Sgblack@eecs.umich.edu            break;
4337139Sgblack@eecs.umich.edu    '''
4347139Sgblack@eecs.umich.edu
4357188Sgblack@eecs.umich.edu    def instCode(opcode, mnem, useDest = True, useOp1 = True):
4367188Sgblack@eecs.umich.edu        global instDecode, pclr, adr
4377188Sgblack@eecs.umich.edu        if useDest:
4387188Sgblack@eecs.umich.edu            dest = "rd"
4397188Sgblack@eecs.umich.edu        else:
4407188Sgblack@eecs.umich.edu            dest = "INTREG_ZERO"
4417188Sgblack@eecs.umich.edu        if useOp1:
4427188Sgblack@eecs.umich.edu            op1 = "rn"
4437188Sgblack@eecs.umich.edu        else:
4447188Sgblack@eecs.umich.edu            op1 = "INTREG_ZERO"
4457188Sgblack@eecs.umich.edu        substDict = { "className": mnem.capitalize(),
4467188Sgblack@eecs.umich.edu                      "opcode": opcode,
4477188Sgblack@eecs.umich.edu                      "dest": dest,
4487188Sgblack@eecs.umich.edu                      "op1": op1,
4497188Sgblack@eecs.umich.edu                      "adr": "",
4507188Sgblack@eecs.umich.edu                      "adrInst": "false" }
4517188Sgblack@eecs.umich.edu        if useDest:
4527188Sgblack@eecs.umich.edu            substDict["pclrInst"] = "true"
4537188Sgblack@eecs.umich.edu            substDict["pclr"] = pclr % substDict
4547188Sgblack@eecs.umich.edu        else:
4557188Sgblack@eecs.umich.edu            substDict["pclrInst"] = "false"
4567188Sgblack@eecs.umich.edu            substDict["pclr"] = ""
4577188Sgblack@eecs.umich.edu        return instDecode % substDict
4587185Sgblack@eecs.umich.edu
4597188Sgblack@eecs.umich.edu    def adrCode(opcode, mnem, add="1"):
4607188Sgblack@eecs.umich.edu        global instDecode, pclr, adr
4617188Sgblack@eecs.umich.edu        substDict = { "className": mnem.capitalize(),
4627188Sgblack@eecs.umich.edu                      "opcode": opcode,
4637188Sgblack@eecs.umich.edu                      "dest": "rd",
4647188Sgblack@eecs.umich.edu                      "op1": "rn",
4657188Sgblack@eecs.umich.edu                      "add": add,
4667188Sgblack@eecs.umich.edu                      "pclrInst": "true",
4677188Sgblack@eecs.umich.edu                      "adrInst": "true" }
4687188Sgblack@eecs.umich.edu        substDict["pclr"] = pclr % substDict
4697188Sgblack@eecs.umich.edu        substDict["adr"] = adr % substDict
4707188Sgblack@eecs.umich.edu        return instDecode % substDict
4717139Sgblack@eecs.umich.edu
4727139Sgblack@eecs.umich.edu    decode_block = '''
4737139Sgblack@eecs.umich.edu    {
4747139Sgblack@eecs.umich.edu        const bool setCc = (bits(machInst, 20) == 1);
4757139Sgblack@eecs.umich.edu        const uint32_t unrotated = bits(machInst, 7, 0);
4767139Sgblack@eecs.umich.edu        const uint32_t rotation = (bits(machInst, 11, 8) << 1);
4777139Sgblack@eecs.umich.edu        const bool rotC = (rotation != 0);
4787139Sgblack@eecs.umich.edu        const uint32_t imm = rotate_imm(unrotated, rotation);
4797139Sgblack@eecs.umich.edu        const IntRegIndex rd = (IntRegIndex)(uint32_t)RD;
4807139Sgblack@eecs.umich.edu        const IntRegIndex rn = (IntRegIndex)(uint32_t)RN;
4817139Sgblack@eecs.umich.edu        switch (OPCODE) {
4827139Sgblack@eecs.umich.edu    '''
4837139Sgblack@eecs.umich.edu    decode_block += instCode(0x0, "and")
4847139Sgblack@eecs.umich.edu    decode_block += instCode(0x1, "eor")
4857185Sgblack@eecs.umich.edu    decode_block += adrCode(0x2, "sub", add="(IntRegIndex)0")
4867139Sgblack@eecs.umich.edu    decode_block += instCode(0x3, "rsb")
4877185Sgblack@eecs.umich.edu    decode_block += adrCode(0x4, "add", add="(IntRegIndex)1")
4887139Sgblack@eecs.umich.edu    decode_block += instCode(0x5, "adc")
4897139Sgblack@eecs.umich.edu    decode_block += instCode(0x6, "sbc")
4907139Sgblack@eecs.umich.edu    decode_block += instCode(0x7, "rsc")
4917188Sgblack@eecs.umich.edu    decode_block += instCode(0x8, "tst", useDest = False)
4927188Sgblack@eecs.umich.edu    decode_block += instCode(0x9, "teq", useDest = False)
4937188Sgblack@eecs.umich.edu    decode_block += instCode(0xa, "cmp", useDest = False)
4947188Sgblack@eecs.umich.edu    decode_block += instCode(0xb, "cmn", useDest = False)
4957139Sgblack@eecs.umich.edu    decode_block += instCode(0xc, "orr")
4967188Sgblack@eecs.umich.edu    decode_block += instCode(0xd, "mov", useOp1 = False)
4977139Sgblack@eecs.umich.edu    decode_block += instCode(0xe, "bic")
4987188Sgblack@eecs.umich.edu    decode_block += instCode(0xf, "mvn", useOp1 = False)
4997139Sgblack@eecs.umich.edu    decode_block += '''
5007139Sgblack@eecs.umich.edu          default:
5017139Sgblack@eecs.umich.edu            return new Unknown(machInst);
5027139Sgblack@eecs.umich.edu        }
5037139Sgblack@eecs.umich.edu    }
5047139Sgblack@eecs.umich.edu    '''
5057139Sgblack@eecs.umich.edu}};
5067141Sgblack@eecs.umich.edu
5077195Sgblack@eecs.umich.edudef format ArmSatAddSub() {{
5087195Sgblack@eecs.umich.edu    decode_block = '''
5097195Sgblack@eecs.umich.edu    {
5107195Sgblack@eecs.umich.edu        IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
5117195Sgblack@eecs.umich.edu        IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
5127195Sgblack@eecs.umich.edu        IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
5137195Sgblack@eecs.umich.edu        switch (OPCODE) {
5147195Sgblack@eecs.umich.edu          case 0x8:
5157195Sgblack@eecs.umich.edu            return new QaddRegCc(machInst, rd, rm, rn, 0, LSL);
5167195Sgblack@eecs.umich.edu          case 0x9:
5177195Sgblack@eecs.umich.edu            return new QsubRegCc(machInst, rd, rm, rn, 0, LSL);
5187195Sgblack@eecs.umich.edu          case 0xa:
5197195Sgblack@eecs.umich.edu            return new QdaddRegCc(machInst, rd, rm, rn, 0, LSL);
5207195Sgblack@eecs.umich.edu          case 0xb:
5217195Sgblack@eecs.umich.edu            return new QdsubRegCc(machInst, rd, rm, rn, 0, LSL);
5227195Sgblack@eecs.umich.edu          default:
5237195Sgblack@eecs.umich.edu            return new Unknown(machInst);
5247195Sgblack@eecs.umich.edu        }
5257195Sgblack@eecs.umich.edu    }
5267195Sgblack@eecs.umich.edu    '''
5277195Sgblack@eecs.umich.edu}};
5287195Sgblack@eecs.umich.edu
5297213Sgblack@eecs.umich.edudef format Thumb32DataProcReg() {{
5307213Sgblack@eecs.umich.edu    decode_block = '''
5317213Sgblack@eecs.umich.edu    {
5327213Sgblack@eecs.umich.edu        const uint32_t op1 = bits(machInst, 23, 20);
5337213Sgblack@eecs.umich.edu        const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
5347213Sgblack@eecs.umich.edu        const uint32_t op2 = bits(machInst, 7, 4);
5357213Sgblack@eecs.umich.edu        if (bits(op1, 3) != 1) {
5367213Sgblack@eecs.umich.edu            if (op2 == 0) {
5377213Sgblack@eecs.umich.edu                IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
5387213Sgblack@eecs.umich.edu                IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
5397213Sgblack@eecs.umich.edu                switch (bits(op1, 2, 0)) {
5407213Sgblack@eecs.umich.edu                  case 0x0:
5417213Sgblack@eecs.umich.edu                    return new MovRegReg(machInst, rd,
5427213Sgblack@eecs.umich.edu                            INTREG_ZERO, rn, rm, LSL);
5437213Sgblack@eecs.umich.edu                  case 0x1:
5447213Sgblack@eecs.umich.edu                    return new MovRegRegCc(machInst, rd,
5457213Sgblack@eecs.umich.edu                            INTREG_ZERO, rn, rm, LSL);
5467213Sgblack@eecs.umich.edu                  case 0x2:
5477213Sgblack@eecs.umich.edu                    return new MovRegReg(machInst, rd,
5487213Sgblack@eecs.umich.edu                            INTREG_ZERO, rn, rm, LSR);
5497213Sgblack@eecs.umich.edu                  case 0x3:
5507213Sgblack@eecs.umich.edu                    return new MovRegRegCc(machInst, rd,
5517213Sgblack@eecs.umich.edu                            INTREG_ZERO, rn, rm, LSR);
5527213Sgblack@eecs.umich.edu                  case 0x4:
5537213Sgblack@eecs.umich.edu                    return new MovRegReg(machInst, rd,
5547213Sgblack@eecs.umich.edu                            INTREG_ZERO, rn, rm, ASR);
5557213Sgblack@eecs.umich.edu                  case 0x5:
5567213Sgblack@eecs.umich.edu                    return new MovRegRegCc(machInst, rd,
5577213Sgblack@eecs.umich.edu                            INTREG_ZERO, rn, rm, ASR);
5587213Sgblack@eecs.umich.edu                  case 0x6:
5597213Sgblack@eecs.umich.edu                    return new MovRegReg(machInst, rd,
5607213Sgblack@eecs.umich.edu                            INTREG_ZERO, rn, rm, ROR);
5617213Sgblack@eecs.umich.edu                  case 0x7:
5627213Sgblack@eecs.umich.edu                    return new MovRegRegCc(machInst, rd,
5637213Sgblack@eecs.umich.edu                            INTREG_ZERO, rn, rm, ROR);
5647213Sgblack@eecs.umich.edu                }
5657213Sgblack@eecs.umich.edu            }
5667235Sgblack@eecs.umich.edu            {
5677235Sgblack@eecs.umich.edu                const IntRegIndex rd =
5687235Sgblack@eecs.umich.edu                    (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
5697235Sgblack@eecs.umich.edu                const IntRegIndex rm =
5707235Sgblack@eecs.umich.edu                    (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
5717235Sgblack@eecs.umich.edu                const uint32_t rotation =
5727235Sgblack@eecs.umich.edu                    (uint32_t)bits(machInst, 5, 4) << 3;
5737235Sgblack@eecs.umich.edu                switch (bits(op1, 2, 0)) {
5747235Sgblack@eecs.umich.edu                  case 0x0:
5757235Sgblack@eecs.umich.edu                    if (rn == 0xf) {
5767235Sgblack@eecs.umich.edu                        return new Sxth(machInst, rd, rotation, rm);
5777235Sgblack@eecs.umich.edu                    } else {
5787235Sgblack@eecs.umich.edu                        return new Sxtah(machInst, rd, rn, rm, rotation);
5797235Sgblack@eecs.umich.edu                    }
5807235Sgblack@eecs.umich.edu                  case 0x1:
5817235Sgblack@eecs.umich.edu                    if (rn == 0xf) {
5827235Sgblack@eecs.umich.edu                        return new Uxth(machInst, rd, rotation, rm);
5837235Sgblack@eecs.umich.edu                    } else {
5847235Sgblack@eecs.umich.edu                        return new Uxtah(machInst, rd, rn, rm, rotation);
5857235Sgblack@eecs.umich.edu                    }
5867235Sgblack@eecs.umich.edu                  case 0x2:
5877235Sgblack@eecs.umich.edu                    if (rn == 0xf) {
5887235Sgblack@eecs.umich.edu                        return new Sxtb16(machInst, rd, rotation, rm);
5897235Sgblack@eecs.umich.edu                    } else {
5907235Sgblack@eecs.umich.edu                        return new Sxtab16(machInst, rd, rn, rm, rotation);
5917235Sgblack@eecs.umich.edu                    }
5927235Sgblack@eecs.umich.edu                  case 0x3:
5937235Sgblack@eecs.umich.edu                    if (rn == 0xf) {
5947235Sgblack@eecs.umich.edu                        return new Uxtb16(machInst, rd, rotation, rm);
5957235Sgblack@eecs.umich.edu                    } else {
5967235Sgblack@eecs.umich.edu                        return new Uxtab16(machInst, rd, rn, rm, rotation);
5977235Sgblack@eecs.umich.edu                    }
5987235Sgblack@eecs.umich.edu                  case 0x4:
5997235Sgblack@eecs.umich.edu                    if (rn == 0xf) {
6007235Sgblack@eecs.umich.edu                        return new Sxtb(machInst, rd, rotation, rm);
6017235Sgblack@eecs.umich.edu                    } else {
6027235Sgblack@eecs.umich.edu                        return new Sxtab(machInst, rd, rn, rm, rotation);
6037235Sgblack@eecs.umich.edu                    }
6047235Sgblack@eecs.umich.edu                  case 0x5:
6057235Sgblack@eecs.umich.edu                    if (rn == 0xf) {
6067235Sgblack@eecs.umich.edu                        return new Uxtb(machInst, rd, rotation, rm);
6077235Sgblack@eecs.umich.edu                    } else {
6087235Sgblack@eecs.umich.edu                        return new Uxtab(machInst, rd, rn, rm, rotation);
6097235Sgblack@eecs.umich.edu                    }
6107235Sgblack@eecs.umich.edu                  default:
6117235Sgblack@eecs.umich.edu                    return new Unknown(machInst);
6127213Sgblack@eecs.umich.edu                }
6137213Sgblack@eecs.umich.edu            }
6147213Sgblack@eecs.umich.edu        } else {
6157213Sgblack@eecs.umich.edu            if (bits(op2, 3) == 0) {
6167220Sgblack@eecs.umich.edu                const IntRegIndex rd =
6177220Sgblack@eecs.umich.edu                    (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
6187220Sgblack@eecs.umich.edu                const IntRegIndex rm =
6197220Sgblack@eecs.umich.edu                    (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
6207213Sgblack@eecs.umich.edu                if (bits(op2, 2) == 0x0) {
6217213Sgblack@eecs.umich.edu                    const uint32_t op1 = bits(machInst, 22, 20);
6227213Sgblack@eecs.umich.edu                    const uint32_t op2 = bits(machInst, 5, 4);
6237213Sgblack@eecs.umich.edu                    switch (op2) {
6247213Sgblack@eecs.umich.edu                      case 0x0:
6257213Sgblack@eecs.umich.edu                        switch (op1) {
6267213Sgblack@eecs.umich.edu                          case 0x1:
6277216Sgblack@eecs.umich.edu                            return new Sadd16RegCc(machInst, rd,
6287216Sgblack@eecs.umich.edu                                                   rn, rm, 0, LSL);
6297213Sgblack@eecs.umich.edu                          case 0x2:
6307224Sgblack@eecs.umich.edu                            return new SasxRegCc(machInst, rd,
6317224Sgblack@eecs.umich.edu                                                 rn, rm, 0, LSL);
6327213Sgblack@eecs.umich.edu                          case 0x6:
6337224Sgblack@eecs.umich.edu                            return new SsaxRegCc(machInst, rd,
6347224Sgblack@eecs.umich.edu                                                 rn, rm, 0, LSL);
6357213Sgblack@eecs.umich.edu                          case 0x5:
6367218Sgblack@eecs.umich.edu                            return new Ssub16RegCc(machInst, rd,
6377218Sgblack@eecs.umich.edu                                                   rn, rm, 0, LSL);
6387213Sgblack@eecs.umich.edu                          case 0x0:
6397216Sgblack@eecs.umich.edu                            return new Sadd8RegCc(machInst, rd,
6407216Sgblack@eecs.umich.edu                                                  rn, rm, 0, LSL);
6417213Sgblack@eecs.umich.edu                          case 0x4:
6427218Sgblack@eecs.umich.edu                            return new Ssub8RegCc(machInst, rd,
6437218Sgblack@eecs.umich.edu                                                  rn, rm, 0, LSL);
6447213Sgblack@eecs.umich.edu                        }
6457213Sgblack@eecs.umich.edu                        break;
6467213Sgblack@eecs.umich.edu                      case 0x1:
6477216Sgblack@eecs.umich.edu                        switch (op1) {
6487216Sgblack@eecs.umich.edu                          case 0x1:
6497216Sgblack@eecs.umich.edu                            return new Qadd16Reg(machInst, rd, rn, rm, 0, LSL);
6507216Sgblack@eecs.umich.edu                          case 0x2:
6517216Sgblack@eecs.umich.edu                            return new QasxReg(machInst, rd, rn, rm, 0, LSL);
6527216Sgblack@eecs.umich.edu                          case 0x6:
6537216Sgblack@eecs.umich.edu                            return new QsaxReg(machInst, rd, rn, rm, 0, LSL);
6547216Sgblack@eecs.umich.edu                          case 0x5:
6557216Sgblack@eecs.umich.edu                            return new Qsub16Reg(machInst, rd, rn, rm, 0, LSL);
6567216Sgblack@eecs.umich.edu                          case 0x0:
6577216Sgblack@eecs.umich.edu                            return new Qadd8Reg(machInst, rd, rn, rm, 0, LSL);
6587216Sgblack@eecs.umich.edu                          case 0x4:
6597216Sgblack@eecs.umich.edu                            return new Qsub8Reg(machInst, rd, rn, rm, 0, LSL);
6607213Sgblack@eecs.umich.edu                        }
6617213Sgblack@eecs.umich.edu                        break;
6627213Sgblack@eecs.umich.edu                      case 0x2:
6637213Sgblack@eecs.umich.edu                        switch (op1) {
6647213Sgblack@eecs.umich.edu                          case 0x1:
6657231Sgblack@eecs.umich.edu                            return new Shadd16Reg(machInst, rd, rn, rm, 0, LSL);
6667213Sgblack@eecs.umich.edu                          case 0x2:
6677231Sgblack@eecs.umich.edu                            return new ShasxReg(machInst, rd, rn, rm, 0, LSL);
6687213Sgblack@eecs.umich.edu                          case 0x6:
6697231Sgblack@eecs.umich.edu                            return new ShsaxReg(machInst, rd, rn, rm, 0, LSL);
6707213Sgblack@eecs.umich.edu                          case 0x5:
6717231Sgblack@eecs.umich.edu                            return new Shsub16Reg(machInst, rd, rn, rm, 0, LSL);
6727213Sgblack@eecs.umich.edu                          case 0x0:
6737231Sgblack@eecs.umich.edu                            return new Shadd8Reg(machInst, rd, rn, rm, 0, LSL);
6747213Sgblack@eecs.umich.edu                          case 0x4:
6757231Sgblack@eecs.umich.edu                            return new Shsub8Reg(machInst, rd, rn, rm, 0, LSL);
6767213Sgblack@eecs.umich.edu                        }
6777213Sgblack@eecs.umich.edu                        break;
6787213Sgblack@eecs.umich.edu                    }
6797213Sgblack@eecs.umich.edu                } else {
6807213Sgblack@eecs.umich.edu                    const uint32_t op1 = bits(machInst, 22, 20);
6817213Sgblack@eecs.umich.edu                    const uint32_t op2 = bits(machInst, 5, 4);
6827213Sgblack@eecs.umich.edu                    switch (op2) {
6837213Sgblack@eecs.umich.edu                      case 0x0:
6847213Sgblack@eecs.umich.edu                        switch (op1) {
6857213Sgblack@eecs.umich.edu                          case 0x1:
6867222Sgblack@eecs.umich.edu                            return new Uadd16RegCc(machInst, rd,
6877222Sgblack@eecs.umich.edu                                                   rn, rm, 0, LSL);
6887213Sgblack@eecs.umich.edu                          case 0x2:
6897222Sgblack@eecs.umich.edu                            return new UasxRegCc(machInst, rd,
6907222Sgblack@eecs.umich.edu                                                 rn, rm, 0, LSL);
6917213Sgblack@eecs.umich.edu                          case 0x6:
6927222Sgblack@eecs.umich.edu                            return new UsaxRegCc(machInst, rd,
6937222Sgblack@eecs.umich.edu                                                 rn, rm, 0, LSL);
6947213Sgblack@eecs.umich.edu                          case 0x5:
6957222Sgblack@eecs.umich.edu                            return new Usub16RegCc(machInst, rd,
6967222Sgblack@eecs.umich.edu                                                   rn, rm, 0, LSL);
6977213Sgblack@eecs.umich.edu                          case 0x0:
6987222Sgblack@eecs.umich.edu                            return new Uadd8RegCc(machInst, rd,
6997222Sgblack@eecs.umich.edu                                                  rn, rm, 0, LSL);
7007213Sgblack@eecs.umich.edu                          case 0x4:
7017222Sgblack@eecs.umich.edu                            return new Usub8RegCc(machInst, rd,
7027222Sgblack@eecs.umich.edu                                                  rn, rm, 0, LSL);
7037213Sgblack@eecs.umich.edu                        }
7047213Sgblack@eecs.umich.edu                        break;
7057213Sgblack@eecs.umich.edu                      case 0x1:
7067213Sgblack@eecs.umich.edu                        switch (op1) {
7077213Sgblack@eecs.umich.edu                          case 0x1:
7087220Sgblack@eecs.umich.edu                            return new Uqadd16Reg(machInst, rd, rn, rm, 0, LSL);
7097213Sgblack@eecs.umich.edu                          case 0x2:
7107220Sgblack@eecs.umich.edu                            return new UqasxReg(machInst, rd, rn, rm, 0, LSL);
7117213Sgblack@eecs.umich.edu                          case 0x6:
7127220Sgblack@eecs.umich.edu                            return new UqsaxReg(machInst, rd, rn, rm, 0, LSL);
7137213Sgblack@eecs.umich.edu                          case 0x5:
7147220Sgblack@eecs.umich.edu                            return new Uqsub16Reg(machInst, rd, rn, rm, 0, LSL);
7157213Sgblack@eecs.umich.edu                          case 0x0:
7167220Sgblack@eecs.umich.edu                            return new Uqadd8Reg(machInst, rd, rn, rm, 0, LSL);
7177213Sgblack@eecs.umich.edu                          case 0x4:
7187220Sgblack@eecs.umich.edu                            return new Uqsub8Reg(machInst, rd, rn, rm, 0, LSL);
7197213Sgblack@eecs.umich.edu                        }
7207213Sgblack@eecs.umich.edu                        break;
7217213Sgblack@eecs.umich.edu                      case 0x2:
7227213Sgblack@eecs.umich.edu                        switch (op1) {
7237213Sgblack@eecs.umich.edu                          case 0x1:
7247231Sgblack@eecs.umich.edu                            return new Uhadd16Reg(machInst, rd, rn, rm, 0, LSL);
7257213Sgblack@eecs.umich.edu                          case 0x2:
7267231Sgblack@eecs.umich.edu                            return new UhasxReg(machInst, rd, rn, rm, 0, LSL);
7277213Sgblack@eecs.umich.edu                          case 0x6:
7287231Sgblack@eecs.umich.edu                            return new UhsaxReg(machInst, rd, rn, rm, 0, LSL);
7297213Sgblack@eecs.umich.edu                          case 0x5:
7307231Sgblack@eecs.umich.edu                            return new Uhsub16Reg(machInst, rd, rn, rm, 0, LSL);
7317213Sgblack@eecs.umich.edu                          case 0x0:
7327231Sgblack@eecs.umich.edu                            return new Uhadd8Reg(machInst, rd, rn, rm, 0, LSL);
7337213Sgblack@eecs.umich.edu                          case 0x4:
7347231Sgblack@eecs.umich.edu                            return new Uhsub8Reg(machInst, rd, rn, rm, 0, LSL);
7357213Sgblack@eecs.umich.edu                        }
7367213Sgblack@eecs.umich.edu                        break;
7377213Sgblack@eecs.umich.edu                    }
7387213Sgblack@eecs.umich.edu                }
7397213Sgblack@eecs.umich.edu            } else if (bits(op1, 3, 2) == 0x2 && bits(op2, 3, 2) == 0x2) {
7407213Sgblack@eecs.umich.edu                const uint32_t op1 = bits(machInst, 21, 20);
7417213Sgblack@eecs.umich.edu                const uint32_t op2 = bits(machInst, 5, 4);
7427213Sgblack@eecs.umich.edu                switch (op1) {
7437213Sgblack@eecs.umich.edu                  case 0x0:
7447213Sgblack@eecs.umich.edu                    {
7457213Sgblack@eecs.umich.edu                        IntRegIndex rd =
7467213Sgblack@eecs.umich.edu                            (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
7477213Sgblack@eecs.umich.edu                        IntRegIndex rm =
7487213Sgblack@eecs.umich.edu                            (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
7497213Sgblack@eecs.umich.edu                        switch (op2) {
7507213Sgblack@eecs.umich.edu                          case 0x0:
7517213Sgblack@eecs.umich.edu                            return new QaddRegCc(machInst, rd,
7527213Sgblack@eecs.umich.edu                                                 rm, rn, 0, LSL);
7537213Sgblack@eecs.umich.edu                          case 0x1:
7547213Sgblack@eecs.umich.edu                            return new QdaddRegCc(machInst, rd,
7557213Sgblack@eecs.umich.edu                                                  rm, rn, 0, LSL);
7567213Sgblack@eecs.umich.edu                          case 0x2:
7577213Sgblack@eecs.umich.edu                            return new QsubRegCc(machInst, rd,
7587213Sgblack@eecs.umich.edu                                                 rm, rn, 0, LSL);
7597213Sgblack@eecs.umich.edu                          case 0x3:
7607213Sgblack@eecs.umich.edu                            return new QdsubRegCc(machInst, rd,
7617213Sgblack@eecs.umich.edu                                                  rm, rn, 0, LSL);
7627213Sgblack@eecs.umich.edu                        }
7637213Sgblack@eecs.umich.edu                    }
7647213Sgblack@eecs.umich.edu                    break;
7657213Sgblack@eecs.umich.edu                  case 0x1:
7667213Sgblack@eecs.umich.edu                    {
7677213Sgblack@eecs.umich.edu                        IntRegIndex rd =
7687213Sgblack@eecs.umich.edu                            (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
7697213Sgblack@eecs.umich.edu                        IntRegIndex rm = rn;
7707213Sgblack@eecs.umich.edu                        switch (op2) {
7717213Sgblack@eecs.umich.edu                          case 0x0:
7727213Sgblack@eecs.umich.edu                            return new Rev(machInst, rd, rm);
7737213Sgblack@eecs.umich.edu                          case 0x1:
7747213Sgblack@eecs.umich.edu                            return new Rev16(machInst, rd, rm);
7757213Sgblack@eecs.umich.edu                          case 0x2:
7767213Sgblack@eecs.umich.edu                            return new WarnUnimplemented("rbit", machInst);
7777213Sgblack@eecs.umich.edu                          case 0x3:
7787213Sgblack@eecs.umich.edu                            return new Revsh(machInst, rd, rm);
7797213Sgblack@eecs.umich.edu                        }
7807213Sgblack@eecs.umich.edu                    }
7817213Sgblack@eecs.umich.edu                    break;
7827213Sgblack@eecs.umich.edu                  case 0x2:
7837213Sgblack@eecs.umich.edu                    if (op2 == 0) {
7847213Sgblack@eecs.umich.edu                        return new WarnUnimplemented("sel", machInst);
7857213Sgblack@eecs.umich.edu                    }
7867213Sgblack@eecs.umich.edu                    break;
7877213Sgblack@eecs.umich.edu                  case 0x3:
7887213Sgblack@eecs.umich.edu                    if (op2 == 0) {
7897213Sgblack@eecs.umich.edu                        return new WarnUnimplemented("clz", machInst);
7907213Sgblack@eecs.umich.edu                    }
7917213Sgblack@eecs.umich.edu                }
7927213Sgblack@eecs.umich.edu            }
7937213Sgblack@eecs.umich.edu            return new Unknown(machInst);
7947213Sgblack@eecs.umich.edu        }
7957213Sgblack@eecs.umich.edu    }
7967213Sgblack@eecs.umich.edu    '''
7977213Sgblack@eecs.umich.edu}};
7987213Sgblack@eecs.umich.edu
7997141Sgblack@eecs.umich.edudef format Thumb16ShiftAddSubMoveCmp() {{
8007141Sgblack@eecs.umich.edu    decode_block = '''
8017141Sgblack@eecs.umich.edu    {
8027141Sgblack@eecs.umich.edu        const uint32_t imm5 = bits(machInst, 10, 6);
8037141Sgblack@eecs.umich.edu        const uint32_t imm3 = bits(machInst, 8, 6);
8047141Sgblack@eecs.umich.edu        const uint32_t imm8 = bits(machInst, 7, 0);
8057141Sgblack@eecs.umich.edu        const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 2, 0);
8067141Sgblack@eecs.umich.edu        const IntRegIndex rd8 = (IntRegIndex)(uint32_t)bits(machInst, 10, 8);
8077141Sgblack@eecs.umich.edu        const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 5, 3);
8087141Sgblack@eecs.umich.edu        const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 8, 6);
8097141Sgblack@eecs.umich.edu        switch (bits(machInst, 13, 11)) {
8107141Sgblack@eecs.umich.edu          case 0x0: // lsl
8117183Sgblack@eecs.umich.edu            return new MovRegCc(machInst, rd, INTREG_ZERO, rn, imm5, LSL);
8127141Sgblack@eecs.umich.edu          case 0x1: // lsr
8137183Sgblack@eecs.umich.edu            return new MovRegCc(machInst, rd, INTREG_ZERO, rn, imm5, LSR);
8147141Sgblack@eecs.umich.edu          case 0x2: // asr
8157183Sgblack@eecs.umich.edu            return new MovRegCc(machInst, rd, INTREG_ZERO, rn, imm5, ASR);
8167141Sgblack@eecs.umich.edu          case 0x3:
8177141Sgblack@eecs.umich.edu            switch (bits(machInst, 10, 9)) {
8187141Sgblack@eecs.umich.edu              case 0x0:
8197183Sgblack@eecs.umich.edu                return new AddRegCc(machInst, rd, rn, rm, 0, LSL);
8207141Sgblack@eecs.umich.edu              case 0x1:
8217183Sgblack@eecs.umich.edu                return new SubRegCc(machInst, rd, rn, rm, 0, LSL);
8227141Sgblack@eecs.umich.edu              case 0x2:
8237183Sgblack@eecs.umich.edu                return new AddImmCc(machInst, rd, rn, imm3, true);
8247141Sgblack@eecs.umich.edu              case 0x3:
8257183Sgblack@eecs.umich.edu                return new SubImmCc(machInst, rd, rn, imm3, true);
8267141Sgblack@eecs.umich.edu            }
8277141Sgblack@eecs.umich.edu          case 0x4:
8287183Sgblack@eecs.umich.edu            return new MovImmCc(machInst, rd8, INTREG_ZERO, imm8, false);
8297141Sgblack@eecs.umich.edu          case 0x5:
8307146Sgblack@eecs.umich.edu            return new CmpImmCc(machInst, INTREG_ZERO, rd8, imm8, true);
8317141Sgblack@eecs.umich.edu          case 0x6:
8327183Sgblack@eecs.umich.edu            return new AddImmCc(machInst, rd8, rd8, imm8, true);
8337141Sgblack@eecs.umich.edu          case 0x7:
8347183Sgblack@eecs.umich.edu            return new SubImmCc(machInst, rd8, rd8, imm8, true);
8357141Sgblack@eecs.umich.edu        }
8367141Sgblack@eecs.umich.edu    }
8377141Sgblack@eecs.umich.edu    '''
8387141Sgblack@eecs.umich.edu}};
8397141Sgblack@eecs.umich.edu
8407141Sgblack@eecs.umich.edudef format Thumb16DataProcessing() {{
8417141Sgblack@eecs.umich.edu    decode_block = '''
8427141Sgblack@eecs.umich.edu    {
8437141Sgblack@eecs.umich.edu        const IntRegIndex rdn = (IntRegIndex)(uint32_t)bits(machInst, 2, 0);
8447141Sgblack@eecs.umich.edu        const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 5, 3);
8457141Sgblack@eecs.umich.edu        switch (bits(machInst, 9, 6)) {
8467141Sgblack@eecs.umich.edu          case 0x0:
8477183Sgblack@eecs.umich.edu            return new AndRegCc(machInst, rdn, rdn, rm, 0, LSL);
8487141Sgblack@eecs.umich.edu          case 0x1:
8497183Sgblack@eecs.umich.edu            return new EorRegCc(machInst, rdn, rdn, rm, 0, LSL);
8507141Sgblack@eecs.umich.edu          case 0x2: //lsl
8517183Sgblack@eecs.umich.edu            return new MovRegRegCc(machInst, rdn, INTREG_ZERO, rdn, rm, LSL);
8527141Sgblack@eecs.umich.edu          case 0x3: //lsr
8537183Sgblack@eecs.umich.edu            return new MovRegRegCc(machInst, rdn, INTREG_ZERO, rdn, rm, LSR);
8547141Sgblack@eecs.umich.edu          case 0x4: //asr
8557183Sgblack@eecs.umich.edu            return new MovRegRegCc(machInst, rdn, INTREG_ZERO, rdn, rm, ASR);
8567141Sgblack@eecs.umich.edu          case 0x5:
8577183Sgblack@eecs.umich.edu            return new AdcRegCc(machInst, rdn, rdn, rm, 0, LSL);
8587141Sgblack@eecs.umich.edu          case 0x6:
8597183Sgblack@eecs.umich.edu            return new SbcRegCc(machInst, rdn, rdn, rm, 0, LSL);
8607141Sgblack@eecs.umich.edu          case 0x7: // ror
8617183Sgblack@eecs.umich.edu            return new MovRegRegCc(machInst, rdn, INTREG_ZERO, rdn, rm, ROR);
8627141Sgblack@eecs.umich.edu          case 0x8:
8637183Sgblack@eecs.umich.edu            return new TstRegCc(machInst, INTREG_ZERO, rdn, rm, 0, LSL);
8647141Sgblack@eecs.umich.edu          case 0x9:
8657183Sgblack@eecs.umich.edu            return new RsbImmCc(machInst, rdn, rm, 0, true);
8667141Sgblack@eecs.umich.edu          case 0xa:
8677183Sgblack@eecs.umich.edu            return new CmpRegCc(machInst, INTREG_ZERO, rdn, rm, 0, LSL);
8687141Sgblack@eecs.umich.edu          case 0xb:
8697183Sgblack@eecs.umich.edu            return new CmnRegCc(machInst, INTREG_ZERO, rdn, rm, 0, LSL);
8707141Sgblack@eecs.umich.edu          case 0xc:
8717183Sgblack@eecs.umich.edu            return new OrrRegCc(machInst, rdn, rdn, rm, 0, LSL);
8727141Sgblack@eecs.umich.edu          case 0xd:
8737183Sgblack@eecs.umich.edu            return new MulCc(machInst, rdn, rm, rdn);
8747141Sgblack@eecs.umich.edu          case 0xe:
8757183Sgblack@eecs.umich.edu            return new BicRegCc(machInst, rdn, rdn, rm, 0, LSL);
8767141Sgblack@eecs.umich.edu          case 0xf:
8777183Sgblack@eecs.umich.edu            return new MvnRegCc(machInst, rdn, INTREG_ZERO, rm, 0, LSL);
8787141Sgblack@eecs.umich.edu        }
8797141Sgblack@eecs.umich.edu    }
8807141Sgblack@eecs.umich.edu    '''
8817141Sgblack@eecs.umich.edu}};
8827141Sgblack@eecs.umich.edu
8837141Sgblack@eecs.umich.edudef format Thumb16SpecDataAndBx() {{
8847141Sgblack@eecs.umich.edu    decode_block = '''
8857141Sgblack@eecs.umich.edu    {
8867141Sgblack@eecs.umich.edu        const IntRegIndex rdn =
8877141Sgblack@eecs.umich.edu            (IntRegIndex)(uint32_t)(bits(machInst, 2, 0) |
8887141Sgblack@eecs.umich.edu                                    (bits(machInst, 7) << 3));
8897141Sgblack@eecs.umich.edu        const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 6, 3);
8907141Sgblack@eecs.umich.edu        switch (bits(machInst, 9, 8)) {
8917141Sgblack@eecs.umich.edu          case 0x0:
8927146Sgblack@eecs.umich.edu            return new AddReg(machInst, rdn, rdn, rm, 0, LSL);
8937141Sgblack@eecs.umich.edu          case 0x1:
8947183Sgblack@eecs.umich.edu            return new CmpRegCc(machInst, INTREG_ZERO, rdn, rm, 0, LSL);
8957141Sgblack@eecs.umich.edu          case 0x2:
8967146Sgblack@eecs.umich.edu            return new MovReg(machInst, rdn, INTREG_ZERO, rm, 0, LSL);
8977141Sgblack@eecs.umich.edu          case 0x3:
8987154Sgblack@eecs.umich.edu            if (bits(machInst, 7) == 0) {
8997154Sgblack@eecs.umich.edu                return new BxReg(machInst,
9007154Sgblack@eecs.umich.edu                                 (IntRegIndex)(uint32_t)bits(machInst, 6, 3),
9017154Sgblack@eecs.umich.edu                                 COND_UC);
9027154Sgblack@eecs.umich.edu            } else {
9037154Sgblack@eecs.umich.edu                return new BlxReg(machInst,
9047154Sgblack@eecs.umich.edu                                  (IntRegIndex)(uint32_t)bits(machInst, 6, 3),
9057154Sgblack@eecs.umich.edu                                  COND_UC);
9067154Sgblack@eecs.umich.edu            }
9077141Sgblack@eecs.umich.edu        }
9087141Sgblack@eecs.umich.edu    }
9097141Sgblack@eecs.umich.edu    '''
9107141Sgblack@eecs.umich.edu}};
9117141Sgblack@eecs.umich.edu
9127141Sgblack@eecs.umich.edudef format Thumb16Adr() {{
9137141Sgblack@eecs.umich.edu    decode_block = '''
9147141Sgblack@eecs.umich.edu    {
9157141Sgblack@eecs.umich.edu        const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 10, 8);
9167141Sgblack@eecs.umich.edu        const uint32_t imm8 = bits(machInst, 7, 0) << 2;
9177185Sgblack@eecs.umich.edu        return new AdrImm(machInst, rd, (IntRegIndex)1, imm8, false);
9187141Sgblack@eecs.umich.edu    }
9197141Sgblack@eecs.umich.edu    '''
9207141Sgblack@eecs.umich.edu}};
9217141Sgblack@eecs.umich.edu
9227141Sgblack@eecs.umich.edudef format Thumb16AddSp() {{
9237141Sgblack@eecs.umich.edu    decode_block = '''
9247141Sgblack@eecs.umich.edu    {
9257141Sgblack@eecs.umich.edu        const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 10, 8);
9267141Sgblack@eecs.umich.edu        const uint32_t imm8 = bits(machInst, 7, 0) << 2;
9277146Sgblack@eecs.umich.edu        return new AddImm(machInst, rd, INTREG_SP, imm8, true);
9287141Sgblack@eecs.umich.edu    }
9297141Sgblack@eecs.umich.edu    '''
9307141Sgblack@eecs.umich.edu}};
9317141Sgblack@eecs.umich.edu
9327141Sgblack@eecs.umich.edudef format Thumb16Misc() {{
9337141Sgblack@eecs.umich.edu    decode_block = '''
9347141Sgblack@eecs.umich.edu    {
9357141Sgblack@eecs.umich.edu        switch (bits(machInst, 11, 8)) {
9367141Sgblack@eecs.umich.edu          case 0x0:
9377141Sgblack@eecs.umich.edu            if (bits(machInst, 7)) {
9387146Sgblack@eecs.umich.edu                return new SubImm(machInst, INTREG_SP, INTREG_SP,
9397141Sgblack@eecs.umich.edu                                   bits(machInst, 6, 0) << 2, true);
9407141Sgblack@eecs.umich.edu            } else {
9417146Sgblack@eecs.umich.edu                return new AddImm(machInst, INTREG_SP, INTREG_SP,
9427141Sgblack@eecs.umich.edu                                   bits(machInst, 6, 0) << 2, true);
9437141Sgblack@eecs.umich.edu            }
9447141Sgblack@eecs.umich.edu          case 0x1:
9457154Sgblack@eecs.umich.edu            return new Cbz(machInst,
9467154Sgblack@eecs.umich.edu                           (bits(machInst, 9) << 6) |
9477154Sgblack@eecs.umich.edu                           (bits(machInst, 7, 3) << 1),
9487154Sgblack@eecs.umich.edu                           (IntRegIndex)(uint32_t)bits(machInst, 2, 0));
9497141Sgblack@eecs.umich.edu          case 0x2:
9507235Sgblack@eecs.umich.edu            {
9517235Sgblack@eecs.umich.edu                const IntRegIndex rd =
9527235Sgblack@eecs.umich.edu                    (IntRegIndex)(uint32_t)bits(machInst, 2, 0);
9537235Sgblack@eecs.umich.edu                const IntRegIndex rm =
9547235Sgblack@eecs.umich.edu                    (IntRegIndex)(uint32_t)bits(machInst, 5, 3);
9557235Sgblack@eecs.umich.edu                switch (bits(machInst, 7, 6)) {
9567235Sgblack@eecs.umich.edu                  case 0x0:
9577235Sgblack@eecs.umich.edu                    return new Sxth(machInst, rd, 0, rm);
9587235Sgblack@eecs.umich.edu                  case 0x1:
9597235Sgblack@eecs.umich.edu                    return new Sxtb(machInst, rd, 0, rm);
9607235Sgblack@eecs.umich.edu                  case 0x2:
9617235Sgblack@eecs.umich.edu                    return new Uxth(machInst, rd, 0, rm);
9627235Sgblack@eecs.umich.edu                  case 0x3:
9637235Sgblack@eecs.umich.edu                    return new Uxtb(machInst, rd, 0, rm);
9647235Sgblack@eecs.umich.edu                }
9657141Sgblack@eecs.umich.edu            }
9667141Sgblack@eecs.umich.edu          case 0x3:
9677154Sgblack@eecs.umich.edu            return new Cbz(machInst,
9687154Sgblack@eecs.umich.edu                           (bits(machInst, 9) << 6) |
9697154Sgblack@eecs.umich.edu                           (bits(machInst, 7, 3) << 1),
9707154Sgblack@eecs.umich.edu                           (IntRegIndex)(uint32_t)bits(machInst, 2, 0));
9717141Sgblack@eecs.umich.edu          case 0x4:
9727141Sgblack@eecs.umich.edu          case 0x5:
9737201Sgblack@eecs.umich.edu            {
9747201Sgblack@eecs.umich.edu                const uint32_t m = bits(machInst, 8);
9757201Sgblack@eecs.umich.edu                const uint32_t regList = bits(machInst, 7, 0) | (m << 14);
9767201Sgblack@eecs.umich.edu                return new LdmStm(machInst, INTREG_SP, false, false, false,
9777201Sgblack@eecs.umich.edu                                  true, false, regList);
9787201Sgblack@eecs.umich.edu            }
9797141Sgblack@eecs.umich.edu          case 0x6:
9807141Sgblack@eecs.umich.edu            {
9817141Sgblack@eecs.umich.edu                const uint32_t opBits = bits(machInst, 7, 5);
9827141Sgblack@eecs.umich.edu                if (opBits == 2) {
9837141Sgblack@eecs.umich.edu                    return new WarnUnimplemented("setend", machInst);
9847141Sgblack@eecs.umich.edu                } else if (opBits == 3) {
9857141Sgblack@eecs.umich.edu                    return new WarnUnimplemented("cps", machInst);
9867141Sgblack@eecs.umich.edu                }
9877141Sgblack@eecs.umich.edu            }
9887141Sgblack@eecs.umich.edu          case 0x9:
9897154Sgblack@eecs.umich.edu            return new Cbnz(machInst,
9907154Sgblack@eecs.umich.edu                            (bits(machInst, 9) << 6) |
9917154Sgblack@eecs.umich.edu                            (bits(machInst, 7, 3) << 1),
9927154Sgblack@eecs.umich.edu                            (IntRegIndex)(uint32_t)bits(machInst, 2, 0));
9937141Sgblack@eecs.umich.edu          case 0xa:
9947212Sgblack@eecs.umich.edu            {
9957212Sgblack@eecs.umich.edu                IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 2, 0);
9967212Sgblack@eecs.umich.edu                IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 5, 3);
9977212Sgblack@eecs.umich.edu                switch (bits(machInst, 7, 6)) {
9987212Sgblack@eecs.umich.edu                  case 0x0:
9997212Sgblack@eecs.umich.edu                    return new Rev(machInst, rd, rm);
10007212Sgblack@eecs.umich.edu                  case 0x1:
10017212Sgblack@eecs.umich.edu                    return new Rev16(machInst, rd, rm);
10027212Sgblack@eecs.umich.edu                  case 0x3:
10037212Sgblack@eecs.umich.edu                    return new Revsh(machInst, rd, rm);
10047212Sgblack@eecs.umich.edu                  default:
10057212Sgblack@eecs.umich.edu                    break;
10067212Sgblack@eecs.umich.edu                }
10077141Sgblack@eecs.umich.edu            }
10087141Sgblack@eecs.umich.edu            break;
10097141Sgblack@eecs.umich.edu          case 0xb:
10107154Sgblack@eecs.umich.edu            return new Cbnz(machInst,
10117154Sgblack@eecs.umich.edu                            (bits(machInst, 9) << 6) |
10127154Sgblack@eecs.umich.edu                            (bits(machInst, 7, 3) << 1),
10137154Sgblack@eecs.umich.edu                            (IntRegIndex)(uint32_t)bits(machInst, 2, 0));
10147141Sgblack@eecs.umich.edu          case 0xc:
10157141Sgblack@eecs.umich.edu          case 0xd:
10167201Sgblack@eecs.umich.edu            {
10177201Sgblack@eecs.umich.edu                const uint32_t p = bits(machInst, 8);
10187201Sgblack@eecs.umich.edu                const uint32_t regList = bits(machInst, 7, 0) | (p << 15);
10197201Sgblack@eecs.umich.edu                return new LdmStm(machInst, INTREG_SP, true, true, false,
10207201Sgblack@eecs.umich.edu                                  true, true, regList);
10217201Sgblack@eecs.umich.edu            }
10227141Sgblack@eecs.umich.edu          case 0xe:
10237141Sgblack@eecs.umich.edu            return new WarnUnimplemented("bkpt", machInst);
10247141Sgblack@eecs.umich.edu          case 0xf:
10257141Sgblack@eecs.umich.edu            if (bits(machInst, 3, 0) != 0)
10267141Sgblack@eecs.umich.edu                return new WarnUnimplemented("it", machInst);
10277141Sgblack@eecs.umich.edu            switch (bits(machInst, 7, 4)) {
10287141Sgblack@eecs.umich.edu              case 0x0:
10297141Sgblack@eecs.umich.edu                return new WarnUnimplemented("nop", machInst);
10307141Sgblack@eecs.umich.edu              case 0x1:
10317141Sgblack@eecs.umich.edu                return new WarnUnimplemented("yield", machInst);
10327141Sgblack@eecs.umich.edu              case 0x2:
10337141Sgblack@eecs.umich.edu                return new WarnUnimplemented("wfe", machInst);
10347141Sgblack@eecs.umich.edu              case 0x3:
10357141Sgblack@eecs.umich.edu                return new WarnUnimplemented("wfi", machInst);
10367141Sgblack@eecs.umich.edu              case 0x4:
10377141Sgblack@eecs.umich.edu                return new WarnUnimplemented("sev", machInst);
10387141Sgblack@eecs.umich.edu              default:
10397141Sgblack@eecs.umich.edu                return new WarnUnimplemented("unallocated_hint", machInst);
10407141Sgblack@eecs.umich.edu            }
10417141Sgblack@eecs.umich.edu          default:
10427141Sgblack@eecs.umich.edu            break;
10437141Sgblack@eecs.umich.edu        }
10447141Sgblack@eecs.umich.edu        return new Unknown(machInst);
10457141Sgblack@eecs.umich.edu    }
10467141Sgblack@eecs.umich.edu    '''
10477141Sgblack@eecs.umich.edu}};
10487141Sgblack@eecs.umich.edu
10497141Sgblack@eecs.umich.edudef format Thumb32DataProcModImm() {{
10507141Sgblack@eecs.umich.edu
10517141Sgblack@eecs.umich.edu    def decInst(mnem, dest="rd", op1="rn"):
10527141Sgblack@eecs.umich.edu        return '''
10537141Sgblack@eecs.umich.edu            if (s) {
10547146Sgblack@eecs.umich.edu                return new %(mnem)sImmCc(machInst, %(dest)s,
10557183Sgblack@eecs.umich.edu                                          %(op1)s, imm, rotC);
10567141Sgblack@eecs.umich.edu            } else {
10577146Sgblack@eecs.umich.edu                return new %(mnem)sImm(machInst, %(dest)s,
10587183Sgblack@eecs.umich.edu                                        %(op1)s, imm, rotC);
10597141Sgblack@eecs.umich.edu            }
10607141Sgblack@eecs.umich.edu        ''' % {"mnem" : mnem, "dest" : dest, "op1" : op1}
10617141Sgblack@eecs.umich.edu
10627141Sgblack@eecs.umich.edu    decode_block = '''
10637141Sgblack@eecs.umich.edu    {
10647141Sgblack@eecs.umich.edu        const uint32_t op = bits(machInst, 24, 21);
10657141Sgblack@eecs.umich.edu        const bool s = (bits(machInst, 20) == 1);
10667141Sgblack@eecs.umich.edu        const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
10677141Sgblack@eecs.umich.edu        const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
10687141Sgblack@eecs.umich.edu        const uint32_t ctrlImm = bits(machInst.instBits, 26) << 3 |
10697141Sgblack@eecs.umich.edu                                 bits(machInst, 14, 12);
10707183Sgblack@eecs.umich.edu        const bool rotC = ctrlImm > 3;
10717141Sgblack@eecs.umich.edu        const uint32_t dataImm = bits(machInst, 7, 0);
10727141Sgblack@eecs.umich.edu        const uint32_t imm = modified_imm(ctrlImm, dataImm);
10737141Sgblack@eecs.umich.edu        switch (op) {
10747141Sgblack@eecs.umich.edu          case 0x0:
10757141Sgblack@eecs.umich.edu            if (rd == INTREG_PC) {
10767141Sgblack@eecs.umich.edu                %(tst)s
10777141Sgblack@eecs.umich.edu            } else {
10787141Sgblack@eecs.umich.edu                %(and)s
10797141Sgblack@eecs.umich.edu            }
10807141Sgblack@eecs.umich.edu          case 0x1:
10817141Sgblack@eecs.umich.edu            %(bic)s
10827141Sgblack@eecs.umich.edu          case 0x2:
10837141Sgblack@eecs.umich.edu            if (rn == INTREG_PC) {
10847141Sgblack@eecs.umich.edu                %(mov)s
10857141Sgblack@eecs.umich.edu            } else {
10867141Sgblack@eecs.umich.edu                %(orr)s
10877141Sgblack@eecs.umich.edu            }
10887141Sgblack@eecs.umich.edu          case 0x3:
10897141Sgblack@eecs.umich.edu            if (rn == INTREG_PC) {
10907141Sgblack@eecs.umich.edu                %(mvn)s
10917141Sgblack@eecs.umich.edu            } else {
10927141Sgblack@eecs.umich.edu                %(orn)s
10937141Sgblack@eecs.umich.edu            }
10947141Sgblack@eecs.umich.edu          case 0x4:
10957141Sgblack@eecs.umich.edu            if (rd == INTREG_PC) {
10967141Sgblack@eecs.umich.edu                %(teq)s
10977141Sgblack@eecs.umich.edu            } else {
10987141Sgblack@eecs.umich.edu                %(eor)s
10997141Sgblack@eecs.umich.edu            }
11007141Sgblack@eecs.umich.edu          case 0x8:
11017141Sgblack@eecs.umich.edu            if (rd == INTREG_PC) {
11027141Sgblack@eecs.umich.edu                %(cmn)s
11037141Sgblack@eecs.umich.edu            } else {
11047141Sgblack@eecs.umich.edu                %(add)s
11057141Sgblack@eecs.umich.edu            }
11067141Sgblack@eecs.umich.edu          case 0xa:
11077141Sgblack@eecs.umich.edu            %(adc)s
11087141Sgblack@eecs.umich.edu          case 0xb:
11097141Sgblack@eecs.umich.edu            %(sbc)s
11107141Sgblack@eecs.umich.edu          case 0xd:
11117141Sgblack@eecs.umich.edu            if (rd == INTREG_PC) {
11127141Sgblack@eecs.umich.edu                %(cmp)s
11137141Sgblack@eecs.umich.edu            } else {
11147141Sgblack@eecs.umich.edu                %(sub)s
11157141Sgblack@eecs.umich.edu            }
11167141Sgblack@eecs.umich.edu          case 0xe:
11177141Sgblack@eecs.umich.edu            %(rsb)s
11187141Sgblack@eecs.umich.edu          default:
11197141Sgblack@eecs.umich.edu            return new Unknown(machInst);
11207141Sgblack@eecs.umich.edu        }
11217141Sgblack@eecs.umich.edu    }
11227141Sgblack@eecs.umich.edu    ''' % {
11237141Sgblack@eecs.umich.edu        "tst" : decInst("Tst", "INTREG_ZERO"),
11247141Sgblack@eecs.umich.edu        "and" : decInst("And"),
11257141Sgblack@eecs.umich.edu        "bic" : decInst("Bic"),
11267141Sgblack@eecs.umich.edu        "mov" : decInst("Mov", op1="INTREG_ZERO"),
11277141Sgblack@eecs.umich.edu        "orr" : decInst("Orr"),
11287141Sgblack@eecs.umich.edu        "mvn" : decInst("Mvn", op1="INTREG_ZERO"),
11297141Sgblack@eecs.umich.edu        "orn" : decInst("Orn"),
11307141Sgblack@eecs.umich.edu        "teq" : decInst("Teq", dest="INTREG_ZERO"),
11317141Sgblack@eecs.umich.edu        "eor" : decInst("Eor"),
11327141Sgblack@eecs.umich.edu        "cmn" : decInst("Cmn", dest="INTREG_ZERO"),
11337141Sgblack@eecs.umich.edu        "add" : decInst("Add"),
11347141Sgblack@eecs.umich.edu        "adc" : decInst("Adc"),
11357141Sgblack@eecs.umich.edu        "sbc" : decInst("Sbc"),
11367141Sgblack@eecs.umich.edu        "cmp" : decInst("Cmp", dest="INTREG_ZERO"),
11377141Sgblack@eecs.umich.edu        "sub" : decInst("Sub"),
11387141Sgblack@eecs.umich.edu        "rsb" : decInst("Rsb")
11397141Sgblack@eecs.umich.edu    }
11407141Sgblack@eecs.umich.edu}};
11417141Sgblack@eecs.umich.edu
11427157Sgblack@eecs.umich.edudef format Thumb32DataProcPlainBin() {{
11437157Sgblack@eecs.umich.edu    decode_block = '''
11447157Sgblack@eecs.umich.edu    {
11457157Sgblack@eecs.umich.edu        const uint32_t op = bits(machInst, 24, 20);
11467157Sgblack@eecs.umich.edu        const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
11477157Sgblack@eecs.umich.edu        const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
11487157Sgblack@eecs.umich.edu        switch (op) {
11497157Sgblack@eecs.umich.edu          case 0x0:
11507157Sgblack@eecs.umich.edu            {
11517157Sgblack@eecs.umich.edu                const uint32_t imm = bits(machInst, 7, 0) |
11527157Sgblack@eecs.umich.edu                                     (bits(machInst, 14, 12) << 8) |
11537157Sgblack@eecs.umich.edu                                     (bits(machInst, 26) << 11);
11547185Sgblack@eecs.umich.edu                if (rn == 0xf) {
11557185Sgblack@eecs.umich.edu                    return new AdrImm(machInst, rd, (IntRegIndex)1,
11567185Sgblack@eecs.umich.edu                                      imm, false);
11577185Sgblack@eecs.umich.edu                } else {
11587185Sgblack@eecs.umich.edu                    return new AddImm(machInst, rd, rn, imm, true);
11597185Sgblack@eecs.umich.edu                }
11607157Sgblack@eecs.umich.edu            }
11617157Sgblack@eecs.umich.edu          case 0x4:
11627157Sgblack@eecs.umich.edu            {
11637157Sgblack@eecs.umich.edu                const uint32_t imm = bits(machInst, 7, 0) |
11647157Sgblack@eecs.umich.edu                                     (bits(machInst, 14, 12) << 8) |
11657157Sgblack@eecs.umich.edu                                     (bits(machInst, 26) << 11) |
11667157Sgblack@eecs.umich.edu                                     (bits(machInst, 19, 16) << 12);
11677157Sgblack@eecs.umich.edu                return new MovImm(machInst, rd, INTREG_ZERO, imm, true);
11687157Sgblack@eecs.umich.edu            }
11697157Sgblack@eecs.umich.edu          case 0xa:
11707157Sgblack@eecs.umich.edu            {
11717157Sgblack@eecs.umich.edu                const uint32_t imm = bits(machInst, 7, 0) |
11727157Sgblack@eecs.umich.edu                                     (bits(machInst, 14, 12) << 8) |
11737157Sgblack@eecs.umich.edu                                     (bits(machInst, 26) << 11);
11747185Sgblack@eecs.umich.edu                if (rn == 0xf) {
11757185Sgblack@eecs.umich.edu                    return new AdrImm(machInst, rd, (IntRegIndex)0,
11767185Sgblack@eecs.umich.edu                                      imm, false);
11777185Sgblack@eecs.umich.edu                } else {
11787185Sgblack@eecs.umich.edu                    return new SubImm(machInst, rd, rn, imm, true);
11797185Sgblack@eecs.umich.edu                }
11807157Sgblack@eecs.umich.edu            }
11817157Sgblack@eecs.umich.edu          case 0xc:
11827157Sgblack@eecs.umich.edu            {
11837157Sgblack@eecs.umich.edu                const uint32_t imm = bits(machInst, 7, 0) |
11847157Sgblack@eecs.umich.edu                                     (bits(machInst, 14, 12) << 8) |
11857157Sgblack@eecs.umich.edu                                     (bits(machInst, 26) << 11) |
11867157Sgblack@eecs.umich.edu                                     (bits(machInst, 19, 16) << 12);
11877157Sgblack@eecs.umich.edu                return new MovtImm(machInst, rd, rd, imm, true);
11887157Sgblack@eecs.umich.edu            }
11897157Sgblack@eecs.umich.edu          case 0x12:
11907157Sgblack@eecs.umich.edu            if (!(bits(machInst, 14, 12) || bits(machInst, 7, 6))) {
11917227Sgblack@eecs.umich.edu                const uint32_t satImm = bits(machInst, 4, 0);
11927227Sgblack@eecs.umich.edu                return new Ssat16(machInst, rd, satImm + 1, rn);
11937157Sgblack@eecs.umich.edu            }
11947157Sgblack@eecs.umich.edu            // Fall through on purpose...
11957157Sgblack@eecs.umich.edu          case 0x10:
11967227Sgblack@eecs.umich.edu            {
11977227Sgblack@eecs.umich.edu                const uint32_t satImm = bits(machInst, 4, 0);
11987227Sgblack@eecs.umich.edu                const uint32_t imm = bits(machInst, 7, 6) |
11997227Sgblack@eecs.umich.edu                                     (bits(machInst, 14, 12) << 2);
12007227Sgblack@eecs.umich.edu                const ArmShiftType type =
12017227Sgblack@eecs.umich.edu                    (ArmShiftType)(uint32_t)bits(machInst, 21, 20);
12027227Sgblack@eecs.umich.edu                return new Ssat(machInst, rd, satImm + 1, rn, imm, type);
12037227Sgblack@eecs.umich.edu            }
12047157Sgblack@eecs.umich.edu          case 0x14:
12057157Sgblack@eecs.umich.edu            return new WarnUnimplemented("sbfx", machInst);
12067157Sgblack@eecs.umich.edu          case 0x16:
12077157Sgblack@eecs.umich.edu            if (rn == 0xf) {
12087157Sgblack@eecs.umich.edu                return new WarnUnimplemented("bfc", machInst);
12097157Sgblack@eecs.umich.edu            } else {
12107157Sgblack@eecs.umich.edu                return new WarnUnimplemented("bfi", machInst);
12117157Sgblack@eecs.umich.edu            }
12127157Sgblack@eecs.umich.edu          case 0x1a:
12137157Sgblack@eecs.umich.edu            if (!(bits(machInst, 14, 12) || bits(machInst, 7, 6))) {
12147227Sgblack@eecs.umich.edu                const uint32_t satImm = bits(machInst, 4, 0);
12157227Sgblack@eecs.umich.edu                return new Usat16(machInst, rd, satImm, rn);
12167157Sgblack@eecs.umich.edu            }
12177157Sgblack@eecs.umich.edu            // Fall through on purpose...
12187157Sgblack@eecs.umich.edu          case 0x18:
12197227Sgblack@eecs.umich.edu            {
12207227Sgblack@eecs.umich.edu                const uint32_t satImm = bits(machInst, 4, 0);
12217227Sgblack@eecs.umich.edu                const uint32_t imm = bits(machInst, 7, 6) |
12227227Sgblack@eecs.umich.edu                                     (bits(machInst, 14, 12) << 2);
12237227Sgblack@eecs.umich.edu                const ArmShiftType type =
12247227Sgblack@eecs.umich.edu                    (ArmShiftType)(uint32_t)bits(machInst, 21, 20);
12257227Sgblack@eecs.umich.edu                return new Usat(machInst, rd, satImm, rn, imm, type);
12267227Sgblack@eecs.umich.edu            }
12277157Sgblack@eecs.umich.edu          case 0x1c:
12287157Sgblack@eecs.umich.edu            return new WarnUnimplemented("ubfx", machInst);
12297157Sgblack@eecs.umich.edu          default:
12307157Sgblack@eecs.umich.edu            return new Unknown(machInst);
12317157Sgblack@eecs.umich.edu        }
12327157Sgblack@eecs.umich.edu    }
12337157Sgblack@eecs.umich.edu    '''
12347157Sgblack@eecs.umich.edu}};
12357157Sgblack@eecs.umich.edu
12367141Sgblack@eecs.umich.edudef format Thumb32DataProcShiftReg() {{
12377141Sgblack@eecs.umich.edu
12387141Sgblack@eecs.umich.edu    def decInst(mnem, dest="rd", op1="rn"):
12397141Sgblack@eecs.umich.edu        return '''
12407141Sgblack@eecs.umich.edu            if (s) {
12417146Sgblack@eecs.umich.edu                return new %(mnem)sRegCc(machInst, %(dest)s,
12427141Sgblack@eecs.umich.edu                                          %(op1)s, rm, amt, type);
12437141Sgblack@eecs.umich.edu            } else {
12447146Sgblack@eecs.umich.edu                return new %(mnem)sReg(machInst, %(dest)s,
12457141Sgblack@eecs.umich.edu                                        %(op1)s, rm, amt, type);
12467141Sgblack@eecs.umich.edu            }
12477141Sgblack@eecs.umich.edu        ''' % {"mnem" : mnem, "dest" : dest, "op1" : op1}
12487141Sgblack@eecs.umich.edu
12497141Sgblack@eecs.umich.edu    decode_block = '''
12507141Sgblack@eecs.umich.edu    {
12517141Sgblack@eecs.umich.edu        const uint32_t op = bits(machInst, 24, 21);
12527141Sgblack@eecs.umich.edu        const bool s = (bits(machInst, 20) == 1);
12537141Sgblack@eecs.umich.edu        const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
12547141Sgblack@eecs.umich.edu        const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
12557141Sgblack@eecs.umich.edu        const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
12567141Sgblack@eecs.umich.edu        const uint32_t amt = (bits(machInst, 14, 12) << 2) |
12577141Sgblack@eecs.umich.edu                              bits(machInst, 7, 6);
12587141Sgblack@eecs.umich.edu        const ArmShiftType type = (ArmShiftType)(uint32_t)bits(machInst, 5, 4);
12597141Sgblack@eecs.umich.edu        switch (op) {
12607141Sgblack@eecs.umich.edu          case 0x0:
12617141Sgblack@eecs.umich.edu            if (rd == INTREG_PC) {
12627141Sgblack@eecs.umich.edu                %(tst)s
12637141Sgblack@eecs.umich.edu            } else {
12647141Sgblack@eecs.umich.edu                %(and)s
12657141Sgblack@eecs.umich.edu            }
12667141Sgblack@eecs.umich.edu          case 0x1:
12677141Sgblack@eecs.umich.edu            %(bic)s
12687141Sgblack@eecs.umich.edu          case 0x2:
12697141Sgblack@eecs.umich.edu            if (rn == INTREG_PC) {
12707141Sgblack@eecs.umich.edu                %(mov)s
12717141Sgblack@eecs.umich.edu            } else {
12727141Sgblack@eecs.umich.edu                %(orr)s
12737141Sgblack@eecs.umich.edu            }
12747141Sgblack@eecs.umich.edu          case 0x3:
12757141Sgblack@eecs.umich.edu            if (rn == INTREG_PC) {
12767141Sgblack@eecs.umich.edu                %(mvn)s
12777141Sgblack@eecs.umich.edu            } else {
12787141Sgblack@eecs.umich.edu                %(orn)s
12797141Sgblack@eecs.umich.edu            }
12807141Sgblack@eecs.umich.edu          case 0x4:
12817141Sgblack@eecs.umich.edu            if (rd == INTREG_PC) {
12827141Sgblack@eecs.umich.edu                %(teq)s
12837141Sgblack@eecs.umich.edu            } else {
12847141Sgblack@eecs.umich.edu                %(eor)s
12857141Sgblack@eecs.umich.edu            }
12867141Sgblack@eecs.umich.edu          case 0x6:
12877141Sgblack@eecs.umich.edu            return new WarnUnimplemented("pkh", machInst);
12887141Sgblack@eecs.umich.edu          case 0x8:
12897141Sgblack@eecs.umich.edu            if (rd == INTREG_PC) {
12907141Sgblack@eecs.umich.edu                %(cmn)s
12917141Sgblack@eecs.umich.edu            } else {
12927141Sgblack@eecs.umich.edu                %(add)s
12937141Sgblack@eecs.umich.edu            }
12947141Sgblack@eecs.umich.edu          case 0xa:
12957141Sgblack@eecs.umich.edu            %(adc)s
12967141Sgblack@eecs.umich.edu          case 0xb:
12977141Sgblack@eecs.umich.edu            %(sbc)s
12987141Sgblack@eecs.umich.edu          case 0xd:
12997141Sgblack@eecs.umich.edu            if (rd == INTREG_PC) {
13007141Sgblack@eecs.umich.edu                %(cmp)s
13017141Sgblack@eecs.umich.edu            } else {
13027141Sgblack@eecs.umich.edu                %(sub)s
13037141Sgblack@eecs.umich.edu            }
13047141Sgblack@eecs.umich.edu          case 0xe:
13057141Sgblack@eecs.umich.edu            %(rsb)s
13067141Sgblack@eecs.umich.edu          default:
13077141Sgblack@eecs.umich.edu            return new Unknown(machInst);
13087141Sgblack@eecs.umich.edu        }
13097141Sgblack@eecs.umich.edu    }
13107141Sgblack@eecs.umich.edu    ''' % {
13117141Sgblack@eecs.umich.edu        "tst" : decInst("Tst", "INTREG_ZERO"),
13127141Sgblack@eecs.umich.edu        "and" : decInst("And"),
13137141Sgblack@eecs.umich.edu        "bic" : decInst("Bic"),
13147141Sgblack@eecs.umich.edu        "mov" : decInst("Mov", op1="INTREG_ZERO"),
13157141Sgblack@eecs.umich.edu        "orr" : decInst("Orr"),
13167141Sgblack@eecs.umich.edu        "mvn" : decInst("Mvn", op1="INTREG_ZERO"),
13177141Sgblack@eecs.umich.edu        "orn" : decInst("Orn"),
13187141Sgblack@eecs.umich.edu        "teq" : decInst("Teq", "INTREG_ZERO"),
13197141Sgblack@eecs.umich.edu        "eor" : decInst("Eor"),
13207141Sgblack@eecs.umich.edu        "cmn" : decInst("Cmn", "INTREG_ZERO"),
13217141Sgblack@eecs.umich.edu        "add" : decInst("Add"),
13227141Sgblack@eecs.umich.edu        "adc" : decInst("Adc"),
13237141Sgblack@eecs.umich.edu        "sbc" : decInst("Sbc"),
13247141Sgblack@eecs.umich.edu        "cmp" : decInst("Cmp", "INTREG_ZERO"),
13257141Sgblack@eecs.umich.edu        "sub" : decInst("Sub"),
13267141Sgblack@eecs.umich.edu        "rsb" : decInst("Rsb")
13277141Sgblack@eecs.umich.edu    }
13287141Sgblack@eecs.umich.edu}};
1329