data.isa revision 7195
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
1277194Sgblack@eecs.umich.edudef format ArmParallelAddSubtract() {{
1287194Sgblack@eecs.umich.edu    decode_block='''
1297194Sgblack@eecs.umich.edu    {
1307194Sgblack@eecs.umich.edu        const uint32_t op1 = bits(machInst, 21, 20);
1317194Sgblack@eecs.umich.edu        const uint32_t op2 = bits(machInst, 7, 5);
1327194Sgblack@eecs.umich.edu        const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
1337194Sgblack@eecs.umich.edu        const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
1347194Sgblack@eecs.umich.edu        const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
1357194Sgblack@eecs.umich.edu        if (bits(machInst, 22) == 0) {
1367194Sgblack@eecs.umich.edu            switch (op1) {
1377194Sgblack@eecs.umich.edu              case 0x1:
1387194Sgblack@eecs.umich.edu                switch (op2) {
1397194Sgblack@eecs.umich.edu                  case 0x0:
1407194Sgblack@eecs.umich.edu                    return new WarnUnimplemented("sadd16", machInst);
1417194Sgblack@eecs.umich.edu                  case 0x1:
1427194Sgblack@eecs.umich.edu                    return new WarnUnimplemented("sasx", machInst);
1437194Sgblack@eecs.umich.edu                  case 0x2:
1447194Sgblack@eecs.umich.edu                    return new WarnUnimplemented("ssax", machInst);
1457194Sgblack@eecs.umich.edu                  case 0x3:
1467194Sgblack@eecs.umich.edu                    return new WarnUnimplemented("ssub16", machInst);
1477194Sgblack@eecs.umich.edu                  case 0x4:
1487194Sgblack@eecs.umich.edu                    return new WarnUnimplemented("sadd8", machInst);
1497194Sgblack@eecs.umich.edu                  case 0x7:
1507194Sgblack@eecs.umich.edu                    return new WarnUnimplemented("ssub8", machInst);
1517194Sgblack@eecs.umich.edu                }
1527194Sgblack@eecs.umich.edu                break;
1537194Sgblack@eecs.umich.edu              case 0x2:
1547194Sgblack@eecs.umich.edu                switch (op2) {
1557194Sgblack@eecs.umich.edu                  case 0x0:
1567194Sgblack@eecs.umich.edu                    return new Qadd16Reg(machInst, rd, rn, rm, 0, LSL);
1577194Sgblack@eecs.umich.edu                  case 0x1:
1587194Sgblack@eecs.umich.edu                    return new QasxReg(machInst, rd, rn, rm, 0, LSL);
1597194Sgblack@eecs.umich.edu                  case 0x2:
1607194Sgblack@eecs.umich.edu                    return new QsaxReg(machInst, rd, rn, rm, 0, LSL);
1617194Sgblack@eecs.umich.edu                  case 0x3:
1627194Sgblack@eecs.umich.edu                    return new Qsub16Reg(machInst, rd, rn, rm, 0, LSL);
1637194Sgblack@eecs.umich.edu                  case 0x4:
1647194Sgblack@eecs.umich.edu                    return new Qadd8Reg(machInst, rd, rn, rm, 0, LSL);
1657194Sgblack@eecs.umich.edu                  case 0x7:
1667194Sgblack@eecs.umich.edu                    return new Qsub8Reg(machInst, rd, rn, rm, 0, LSL);
1677194Sgblack@eecs.umich.edu                }
1687194Sgblack@eecs.umich.edu                break;
1697194Sgblack@eecs.umich.edu              case 0x3:
1707194Sgblack@eecs.umich.edu                switch (op2) {
1717194Sgblack@eecs.umich.edu                  case 0x0:
1727194Sgblack@eecs.umich.edu                    return new WarnUnimplemented("shadd16", machInst);
1737194Sgblack@eecs.umich.edu                  case 0x1:
1747194Sgblack@eecs.umich.edu                    return new WarnUnimplemented("shasx", machInst);
1757194Sgblack@eecs.umich.edu                  case 0x2:
1767194Sgblack@eecs.umich.edu                    return new WarnUnimplemented("shsax", machInst);
1777194Sgblack@eecs.umich.edu                  case 0x3:
1787194Sgblack@eecs.umich.edu                    return new WarnUnimplemented("shsub16", machInst);
1797194Sgblack@eecs.umich.edu                  case 0x4:
1807194Sgblack@eecs.umich.edu                    return new WarnUnimplemented("shadd8", machInst);
1817194Sgblack@eecs.umich.edu                  case 0x7:
1827194Sgblack@eecs.umich.edu                    return new WarnUnimplemented("shsub8", machInst);
1837194Sgblack@eecs.umich.edu                }
1847194Sgblack@eecs.umich.edu                break;
1857194Sgblack@eecs.umich.edu            }
1867194Sgblack@eecs.umich.edu        } else {
1877194Sgblack@eecs.umich.edu            switch (op1) {
1887194Sgblack@eecs.umich.edu              case 0x1:
1897194Sgblack@eecs.umich.edu                switch (op2) {
1907194Sgblack@eecs.umich.edu                  case 0x0:
1917194Sgblack@eecs.umich.edu                    return new WarnUnimplemented("uadd16", machInst);
1927194Sgblack@eecs.umich.edu                  case 0x1:
1937194Sgblack@eecs.umich.edu                    return new WarnUnimplemented("uasx", machInst);
1947194Sgblack@eecs.umich.edu                  case 0x2:
1957194Sgblack@eecs.umich.edu                    return new WarnUnimplemented("usax", machInst);
1967194Sgblack@eecs.umich.edu                  case 0x3:
1977194Sgblack@eecs.umich.edu                    return new WarnUnimplemented("usub16", machInst);
1987194Sgblack@eecs.umich.edu                  case 0x4:
1997194Sgblack@eecs.umich.edu                    return new WarnUnimplemented("uadd8", machInst);
2007194Sgblack@eecs.umich.edu                  case 0x7:
2017194Sgblack@eecs.umich.edu                    return new WarnUnimplemented("usub8", machInst);
2027194Sgblack@eecs.umich.edu                }
2037194Sgblack@eecs.umich.edu                break;
2047194Sgblack@eecs.umich.edu              case 0x2:
2057194Sgblack@eecs.umich.edu                switch (op2) {
2067194Sgblack@eecs.umich.edu                  case 0x0:
2077194Sgblack@eecs.umich.edu                    return new WarnUnimplemented("uqadd16", machInst);
2087194Sgblack@eecs.umich.edu                  case 0x1:
2097194Sgblack@eecs.umich.edu                    return new WarnUnimplemented("uqasx", machInst);
2107194Sgblack@eecs.umich.edu                  case 0x2:
2117194Sgblack@eecs.umich.edu                    return new WarnUnimplemented("uqsax", machInst);
2127194Sgblack@eecs.umich.edu                  case 0x3:
2137194Sgblack@eecs.umich.edu                    return new WarnUnimplemented("uqsub16", machInst);
2147194Sgblack@eecs.umich.edu                  case 0x4:
2157194Sgblack@eecs.umich.edu                    return new WarnUnimplemented("uqadd8", machInst);
2167194Sgblack@eecs.umich.edu                  case 0x7:
2177194Sgblack@eecs.umich.edu                    return new WarnUnimplemented("uqsub8", machInst);
2187194Sgblack@eecs.umich.edu                }
2197194Sgblack@eecs.umich.edu                break;
2207194Sgblack@eecs.umich.edu              case 0x3:
2217194Sgblack@eecs.umich.edu                switch (op2) {
2227194Sgblack@eecs.umich.edu                  case 0x0:
2237194Sgblack@eecs.umich.edu                    return new WarnUnimplemented("uhadd16", machInst);
2247194Sgblack@eecs.umich.edu                  case 0x1:
2257194Sgblack@eecs.umich.edu                    return new WarnUnimplemented("uhasx", machInst);
2267194Sgblack@eecs.umich.edu                  case 0x2:
2277194Sgblack@eecs.umich.edu                    return new WarnUnimplemented("uhsax", machInst);
2287194Sgblack@eecs.umich.edu                  case 0x3:
2297194Sgblack@eecs.umich.edu                    return new WarnUnimplemented("uhsub16", machInst);
2307194Sgblack@eecs.umich.edu                  case 0x4:
2317194Sgblack@eecs.umich.edu                    return new WarnUnimplemented("uhadd8", machInst);
2327194Sgblack@eecs.umich.edu                  case 0x7:
2337194Sgblack@eecs.umich.edu                    return new WarnUnimplemented("uhsub8", machInst);
2347194Sgblack@eecs.umich.edu                }
2357194Sgblack@eecs.umich.edu                break;
2367194Sgblack@eecs.umich.edu            }
2377194Sgblack@eecs.umich.edu        }
2387194Sgblack@eecs.umich.edu        return new Unknown(machInst);
2397194Sgblack@eecs.umich.edu    }
2407194Sgblack@eecs.umich.edu    '''
2417194Sgblack@eecs.umich.edu}};
2427194Sgblack@eecs.umich.edu
2437139Sgblack@eecs.umich.edudef format ArmDataProcImm() {{
2447188Sgblack@eecs.umich.edu    pclr = '''
2457188Sgblack@eecs.umich.edu        return new %(className)ssImmPclr(machInst, %(dest)s,
2467188Sgblack@eecs.umich.edu                                        %(op1)s, imm, false);
2477188Sgblack@eecs.umich.edu    '''
2487188Sgblack@eecs.umich.edu    adr = '''
2497188Sgblack@eecs.umich.edu        return new AdrImm(machInst, %(dest)s, %(add)s,
2507188Sgblack@eecs.umich.edu                                     imm, false);
2517188Sgblack@eecs.umich.edu    '''
2527139Sgblack@eecs.umich.edu    instDecode = '''
2537188Sgblack@eecs.umich.edu          case %(opcode)#x:
2547139Sgblack@eecs.umich.edu            if (setCc) {
2557188Sgblack@eecs.umich.edu                if (%(pclrInst)s && %(dest)s == INTREG_PC) {
2567188Sgblack@eecs.umich.edu                    %(pclr)s
2577188Sgblack@eecs.umich.edu                } else {
2587188Sgblack@eecs.umich.edu                    return new %(className)sImmCc(machInst, %(dest)s, %(op1)s,
2597188Sgblack@eecs.umich.edu                                                   imm, rotC);
2607188Sgblack@eecs.umich.edu                }
2617139Sgblack@eecs.umich.edu            } else {
2627188Sgblack@eecs.umich.edu                if (%(adrInst)s && %(op1)s == INTREG_PC) {
2637188Sgblack@eecs.umich.edu                    %(adr)s
2647188Sgblack@eecs.umich.edu                } else {
2657188Sgblack@eecs.umich.edu                    return new %(className)sImm(machInst, %(dest)s, %(op1)s,
2667188Sgblack@eecs.umich.edu                                                 imm, rotC);
2677188Sgblack@eecs.umich.edu                }
2687139Sgblack@eecs.umich.edu            }
2697139Sgblack@eecs.umich.edu            break;
2707139Sgblack@eecs.umich.edu    '''
2717139Sgblack@eecs.umich.edu
2727188Sgblack@eecs.umich.edu    def instCode(opcode, mnem, useDest = True, useOp1 = True):
2737188Sgblack@eecs.umich.edu        global instDecode, pclr, adr
2747188Sgblack@eecs.umich.edu        if useDest:
2757188Sgblack@eecs.umich.edu            dest = "rd"
2767188Sgblack@eecs.umich.edu        else:
2777188Sgblack@eecs.umich.edu            dest = "INTREG_ZERO"
2787188Sgblack@eecs.umich.edu        if useOp1:
2797188Sgblack@eecs.umich.edu            op1 = "rn"
2807188Sgblack@eecs.umich.edu        else:
2817188Sgblack@eecs.umich.edu            op1 = "INTREG_ZERO"
2827188Sgblack@eecs.umich.edu        substDict = { "className": mnem.capitalize(),
2837188Sgblack@eecs.umich.edu                      "opcode": opcode,
2847188Sgblack@eecs.umich.edu                      "dest": dest,
2857188Sgblack@eecs.umich.edu                      "op1": op1,
2867188Sgblack@eecs.umich.edu                      "adr": "",
2877188Sgblack@eecs.umich.edu                      "adrInst": "false" }
2887188Sgblack@eecs.umich.edu        if useDest:
2897188Sgblack@eecs.umich.edu            substDict["pclrInst"] = "true"
2907188Sgblack@eecs.umich.edu            substDict["pclr"] = pclr % substDict
2917188Sgblack@eecs.umich.edu        else:
2927188Sgblack@eecs.umich.edu            substDict["pclrInst"] = "false"
2937188Sgblack@eecs.umich.edu            substDict["pclr"] = ""
2947188Sgblack@eecs.umich.edu        return instDecode % substDict
2957185Sgblack@eecs.umich.edu
2967188Sgblack@eecs.umich.edu    def adrCode(opcode, mnem, add="1"):
2977188Sgblack@eecs.umich.edu        global instDecode, pclr, adr
2987188Sgblack@eecs.umich.edu        substDict = { "className": mnem.capitalize(),
2997188Sgblack@eecs.umich.edu                      "opcode": opcode,
3007188Sgblack@eecs.umich.edu                      "dest": "rd",
3017188Sgblack@eecs.umich.edu                      "op1": "rn",
3027188Sgblack@eecs.umich.edu                      "add": add,
3037188Sgblack@eecs.umich.edu                      "pclrInst": "true",
3047188Sgblack@eecs.umich.edu                      "adrInst": "true" }
3057188Sgblack@eecs.umich.edu        substDict["pclr"] = pclr % substDict
3067188Sgblack@eecs.umich.edu        substDict["adr"] = adr % substDict
3077188Sgblack@eecs.umich.edu        return instDecode % substDict
3087139Sgblack@eecs.umich.edu
3097139Sgblack@eecs.umich.edu    decode_block = '''
3107139Sgblack@eecs.umich.edu    {
3117139Sgblack@eecs.umich.edu        const bool setCc = (bits(machInst, 20) == 1);
3127139Sgblack@eecs.umich.edu        const uint32_t unrotated = bits(machInst, 7, 0);
3137139Sgblack@eecs.umich.edu        const uint32_t rotation = (bits(machInst, 11, 8) << 1);
3147139Sgblack@eecs.umich.edu        const bool rotC = (rotation != 0);
3157139Sgblack@eecs.umich.edu        const uint32_t imm = rotate_imm(unrotated, rotation);
3167139Sgblack@eecs.umich.edu        const IntRegIndex rd = (IntRegIndex)(uint32_t)RD;
3177139Sgblack@eecs.umich.edu        const IntRegIndex rn = (IntRegIndex)(uint32_t)RN;
3187139Sgblack@eecs.umich.edu        switch (OPCODE) {
3197139Sgblack@eecs.umich.edu    '''
3207139Sgblack@eecs.umich.edu    decode_block += instCode(0x0, "and")
3217139Sgblack@eecs.umich.edu    decode_block += instCode(0x1, "eor")
3227185Sgblack@eecs.umich.edu    decode_block += adrCode(0x2, "sub", add="(IntRegIndex)0")
3237139Sgblack@eecs.umich.edu    decode_block += instCode(0x3, "rsb")
3247185Sgblack@eecs.umich.edu    decode_block += adrCode(0x4, "add", add="(IntRegIndex)1")
3257139Sgblack@eecs.umich.edu    decode_block += instCode(0x5, "adc")
3267139Sgblack@eecs.umich.edu    decode_block += instCode(0x6, "sbc")
3277139Sgblack@eecs.umich.edu    decode_block += instCode(0x7, "rsc")
3287188Sgblack@eecs.umich.edu    decode_block += instCode(0x8, "tst", useDest = False)
3297188Sgblack@eecs.umich.edu    decode_block += instCode(0x9, "teq", useDest = False)
3307188Sgblack@eecs.umich.edu    decode_block += instCode(0xa, "cmp", useDest = False)
3317188Sgblack@eecs.umich.edu    decode_block += instCode(0xb, "cmn", useDest = False)
3327139Sgblack@eecs.umich.edu    decode_block += instCode(0xc, "orr")
3337188Sgblack@eecs.umich.edu    decode_block += instCode(0xd, "mov", useOp1 = False)
3347139Sgblack@eecs.umich.edu    decode_block += instCode(0xe, "bic")
3357188Sgblack@eecs.umich.edu    decode_block += instCode(0xf, "mvn", useOp1 = False)
3367139Sgblack@eecs.umich.edu    decode_block += '''
3377139Sgblack@eecs.umich.edu          default:
3387139Sgblack@eecs.umich.edu            return new Unknown(machInst);
3397139Sgblack@eecs.umich.edu        }
3407139Sgblack@eecs.umich.edu    }
3417139Sgblack@eecs.umich.edu    '''
3427139Sgblack@eecs.umich.edu}};
3437141Sgblack@eecs.umich.edu
3447195Sgblack@eecs.umich.edudef format ArmSatAddSub() {{
3457195Sgblack@eecs.umich.edu    decode_block = '''
3467195Sgblack@eecs.umich.edu    {
3477195Sgblack@eecs.umich.edu        IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
3487195Sgblack@eecs.umich.edu        IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
3497195Sgblack@eecs.umich.edu        IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
3507195Sgblack@eecs.umich.edu        switch (OPCODE) {
3517195Sgblack@eecs.umich.edu          case 0x8:
3527195Sgblack@eecs.umich.edu            return new QaddRegCc(machInst, rd, rm, rn, 0, LSL);
3537195Sgblack@eecs.umich.edu          case 0x9:
3547195Sgblack@eecs.umich.edu            return new QsubRegCc(machInst, rd, rm, rn, 0, LSL);
3557195Sgblack@eecs.umich.edu          case 0xa:
3567195Sgblack@eecs.umich.edu            return new QdaddRegCc(machInst, rd, rm, rn, 0, LSL);
3577195Sgblack@eecs.umich.edu          case 0xb:
3587195Sgblack@eecs.umich.edu            return new QdsubRegCc(machInst, rd, rm, rn, 0, LSL);
3597195Sgblack@eecs.umich.edu          default:
3607195Sgblack@eecs.umich.edu            return new Unknown(machInst);
3617195Sgblack@eecs.umich.edu        }
3627195Sgblack@eecs.umich.edu    }
3637195Sgblack@eecs.umich.edu    '''
3647195Sgblack@eecs.umich.edu}};
3657195Sgblack@eecs.umich.edu
3667141Sgblack@eecs.umich.edudef format Thumb16ShiftAddSubMoveCmp() {{
3677141Sgblack@eecs.umich.edu    decode_block = '''
3687141Sgblack@eecs.umich.edu    {
3697141Sgblack@eecs.umich.edu        const uint32_t imm5 = bits(machInst, 10, 6);
3707141Sgblack@eecs.umich.edu        const uint32_t imm3 = bits(machInst, 8, 6);
3717141Sgblack@eecs.umich.edu        const uint32_t imm8 = bits(machInst, 7, 0);
3727141Sgblack@eecs.umich.edu        const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 2, 0);
3737141Sgblack@eecs.umich.edu        const IntRegIndex rd8 = (IntRegIndex)(uint32_t)bits(machInst, 10, 8);
3747141Sgblack@eecs.umich.edu        const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 5, 3);
3757141Sgblack@eecs.umich.edu        const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 8, 6);
3767141Sgblack@eecs.umich.edu        switch (bits(machInst, 13, 11)) {
3777141Sgblack@eecs.umich.edu          case 0x0: // lsl
3787183Sgblack@eecs.umich.edu            return new MovRegCc(machInst, rd, INTREG_ZERO, rn, imm5, LSL);
3797141Sgblack@eecs.umich.edu          case 0x1: // lsr
3807183Sgblack@eecs.umich.edu            return new MovRegCc(machInst, rd, INTREG_ZERO, rn, imm5, LSR);
3817141Sgblack@eecs.umich.edu          case 0x2: // asr
3827183Sgblack@eecs.umich.edu            return new MovRegCc(machInst, rd, INTREG_ZERO, rn, imm5, ASR);
3837141Sgblack@eecs.umich.edu          case 0x3:
3847141Sgblack@eecs.umich.edu            switch (bits(machInst, 10, 9)) {
3857141Sgblack@eecs.umich.edu              case 0x0:
3867183Sgblack@eecs.umich.edu                return new AddRegCc(machInst, rd, rn, rm, 0, LSL);
3877141Sgblack@eecs.umich.edu              case 0x1:
3887183Sgblack@eecs.umich.edu                return new SubRegCc(machInst, rd, rn, rm, 0, LSL);
3897141Sgblack@eecs.umich.edu              case 0x2:
3907183Sgblack@eecs.umich.edu                return new AddImmCc(machInst, rd, rn, imm3, true);
3917141Sgblack@eecs.umich.edu              case 0x3:
3927183Sgblack@eecs.umich.edu                return new SubImmCc(machInst, rd, rn, imm3, true);
3937141Sgblack@eecs.umich.edu            }
3947141Sgblack@eecs.umich.edu          case 0x4:
3957183Sgblack@eecs.umich.edu            return new MovImmCc(machInst, rd8, INTREG_ZERO, imm8, false);
3967141Sgblack@eecs.umich.edu          case 0x5:
3977146Sgblack@eecs.umich.edu            return new CmpImmCc(machInst, INTREG_ZERO, rd8, imm8, true);
3987141Sgblack@eecs.umich.edu          case 0x6:
3997183Sgblack@eecs.umich.edu            return new AddImmCc(machInst, rd8, rd8, imm8, true);
4007141Sgblack@eecs.umich.edu          case 0x7:
4017183Sgblack@eecs.umich.edu            return new SubImmCc(machInst, rd8, rd8, imm8, true);
4027141Sgblack@eecs.umich.edu        }
4037141Sgblack@eecs.umich.edu    }
4047141Sgblack@eecs.umich.edu    '''
4057141Sgblack@eecs.umich.edu}};
4067141Sgblack@eecs.umich.edu
4077141Sgblack@eecs.umich.edudef format Thumb16DataProcessing() {{
4087141Sgblack@eecs.umich.edu    decode_block = '''
4097141Sgblack@eecs.umich.edu    {
4107141Sgblack@eecs.umich.edu        const IntRegIndex rdn = (IntRegIndex)(uint32_t)bits(machInst, 2, 0);
4117141Sgblack@eecs.umich.edu        const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 5, 3);
4127141Sgblack@eecs.umich.edu        switch (bits(machInst, 9, 6)) {
4137141Sgblack@eecs.umich.edu          case 0x0:
4147183Sgblack@eecs.umich.edu            return new AndRegCc(machInst, rdn, rdn, rm, 0, LSL);
4157141Sgblack@eecs.umich.edu          case 0x1:
4167183Sgblack@eecs.umich.edu            return new EorRegCc(machInst, rdn, rdn, rm, 0, LSL);
4177141Sgblack@eecs.umich.edu          case 0x2: //lsl
4187183Sgblack@eecs.umich.edu            return new MovRegRegCc(machInst, rdn, INTREG_ZERO, rdn, rm, LSL);
4197141Sgblack@eecs.umich.edu          case 0x3: //lsr
4207183Sgblack@eecs.umich.edu            return new MovRegRegCc(machInst, rdn, INTREG_ZERO, rdn, rm, LSR);
4217141Sgblack@eecs.umich.edu          case 0x4: //asr
4227183Sgblack@eecs.umich.edu            return new MovRegRegCc(machInst, rdn, INTREG_ZERO, rdn, rm, ASR);
4237141Sgblack@eecs.umich.edu          case 0x5:
4247183Sgblack@eecs.umich.edu            return new AdcRegCc(machInst, rdn, rdn, rm, 0, LSL);
4257141Sgblack@eecs.umich.edu          case 0x6:
4267183Sgblack@eecs.umich.edu            return new SbcRegCc(machInst, rdn, rdn, rm, 0, LSL);
4277141Sgblack@eecs.umich.edu          case 0x7: // ror
4287183Sgblack@eecs.umich.edu            return new MovRegRegCc(machInst, rdn, INTREG_ZERO, rdn, rm, ROR);
4297141Sgblack@eecs.umich.edu          case 0x8:
4307183Sgblack@eecs.umich.edu            return new TstRegCc(machInst, INTREG_ZERO, rdn, rm, 0, LSL);
4317141Sgblack@eecs.umich.edu          case 0x9:
4327183Sgblack@eecs.umich.edu            return new RsbImmCc(machInst, rdn, rm, 0, true);
4337141Sgblack@eecs.umich.edu          case 0xa:
4347183Sgblack@eecs.umich.edu            return new CmpRegCc(machInst, INTREG_ZERO, rdn, rm, 0, LSL);
4357141Sgblack@eecs.umich.edu          case 0xb:
4367183Sgblack@eecs.umich.edu            return new CmnRegCc(machInst, INTREG_ZERO, rdn, rm, 0, LSL);
4377141Sgblack@eecs.umich.edu          case 0xc:
4387183Sgblack@eecs.umich.edu            return new OrrRegCc(machInst, rdn, rdn, rm, 0, LSL);
4397141Sgblack@eecs.umich.edu          case 0xd:
4407183Sgblack@eecs.umich.edu            return new MulCc(machInst, rdn, rm, rdn);
4417141Sgblack@eecs.umich.edu          case 0xe:
4427183Sgblack@eecs.umich.edu            return new BicRegCc(machInst, rdn, rdn, rm, 0, LSL);
4437141Sgblack@eecs.umich.edu          case 0xf:
4447183Sgblack@eecs.umich.edu            return new MvnRegCc(machInst, rdn, INTREG_ZERO, rm, 0, LSL);
4457141Sgblack@eecs.umich.edu        }
4467141Sgblack@eecs.umich.edu    }
4477141Sgblack@eecs.umich.edu    '''
4487141Sgblack@eecs.umich.edu}};
4497141Sgblack@eecs.umich.edu
4507141Sgblack@eecs.umich.edudef format Thumb16SpecDataAndBx() {{
4517141Sgblack@eecs.umich.edu    decode_block = '''
4527141Sgblack@eecs.umich.edu    {
4537141Sgblack@eecs.umich.edu        const IntRegIndex rdn =
4547141Sgblack@eecs.umich.edu            (IntRegIndex)(uint32_t)(bits(machInst, 2, 0) |
4557141Sgblack@eecs.umich.edu                                    (bits(machInst, 7) << 3));
4567141Sgblack@eecs.umich.edu        const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 6, 3);
4577141Sgblack@eecs.umich.edu        switch (bits(machInst, 9, 8)) {
4587141Sgblack@eecs.umich.edu          case 0x0:
4597146Sgblack@eecs.umich.edu            return new AddReg(machInst, rdn, rdn, rm, 0, LSL);
4607141Sgblack@eecs.umich.edu          case 0x1:
4617183Sgblack@eecs.umich.edu            return new CmpRegCc(machInst, INTREG_ZERO, rdn, rm, 0, LSL);
4627141Sgblack@eecs.umich.edu          case 0x2:
4637146Sgblack@eecs.umich.edu            return new MovReg(machInst, rdn, INTREG_ZERO, rm, 0, LSL);
4647141Sgblack@eecs.umich.edu          case 0x3:
4657154Sgblack@eecs.umich.edu            if (bits(machInst, 7) == 0) {
4667154Sgblack@eecs.umich.edu                return new BxReg(machInst,
4677154Sgblack@eecs.umich.edu                                 (IntRegIndex)(uint32_t)bits(machInst, 6, 3),
4687154Sgblack@eecs.umich.edu                                 COND_UC);
4697154Sgblack@eecs.umich.edu            } else {
4707154Sgblack@eecs.umich.edu                return new BlxReg(machInst,
4717154Sgblack@eecs.umich.edu                                  (IntRegIndex)(uint32_t)bits(machInst, 6, 3),
4727154Sgblack@eecs.umich.edu                                  COND_UC);
4737154Sgblack@eecs.umich.edu            }
4747141Sgblack@eecs.umich.edu        }
4757141Sgblack@eecs.umich.edu    }
4767141Sgblack@eecs.umich.edu    '''
4777141Sgblack@eecs.umich.edu}};
4787141Sgblack@eecs.umich.edu
4797141Sgblack@eecs.umich.edudef format Thumb16Adr() {{
4807141Sgblack@eecs.umich.edu    decode_block = '''
4817141Sgblack@eecs.umich.edu    {
4827141Sgblack@eecs.umich.edu        const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 10, 8);
4837141Sgblack@eecs.umich.edu        const uint32_t imm8 = bits(machInst, 7, 0) << 2;
4847185Sgblack@eecs.umich.edu        return new AdrImm(machInst, rd, (IntRegIndex)1, imm8, false);
4857141Sgblack@eecs.umich.edu    }
4867141Sgblack@eecs.umich.edu    '''
4877141Sgblack@eecs.umich.edu}};
4887141Sgblack@eecs.umich.edu
4897141Sgblack@eecs.umich.edudef format Thumb16AddSp() {{
4907141Sgblack@eecs.umich.edu    decode_block = '''
4917141Sgblack@eecs.umich.edu    {
4927141Sgblack@eecs.umich.edu        const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 10, 8);
4937141Sgblack@eecs.umich.edu        const uint32_t imm8 = bits(machInst, 7, 0) << 2;
4947146Sgblack@eecs.umich.edu        return new AddImm(machInst, rd, INTREG_SP, imm8, true);
4957141Sgblack@eecs.umich.edu    }
4967141Sgblack@eecs.umich.edu    '''
4977141Sgblack@eecs.umich.edu}};
4987141Sgblack@eecs.umich.edu
4997141Sgblack@eecs.umich.edudef format Thumb16Misc() {{
5007141Sgblack@eecs.umich.edu    decode_block = '''
5017141Sgblack@eecs.umich.edu    {
5027141Sgblack@eecs.umich.edu        switch (bits(machInst, 11, 8)) {
5037141Sgblack@eecs.umich.edu          case 0x0:
5047141Sgblack@eecs.umich.edu            if (bits(machInst, 7)) {
5057146Sgblack@eecs.umich.edu                return new SubImm(machInst, INTREG_SP, INTREG_SP,
5067141Sgblack@eecs.umich.edu                                   bits(machInst, 6, 0) << 2, true);
5077141Sgblack@eecs.umich.edu            } else {
5087146Sgblack@eecs.umich.edu                return new AddImm(machInst, INTREG_SP, INTREG_SP,
5097141Sgblack@eecs.umich.edu                                   bits(machInst, 6, 0) << 2, true);
5107141Sgblack@eecs.umich.edu            }
5117141Sgblack@eecs.umich.edu          case 0x1:
5127154Sgblack@eecs.umich.edu            return new Cbz(machInst,
5137154Sgblack@eecs.umich.edu                           (bits(machInst, 9) << 6) |
5147154Sgblack@eecs.umich.edu                           (bits(machInst, 7, 3) << 1),
5157154Sgblack@eecs.umich.edu                           (IntRegIndex)(uint32_t)bits(machInst, 2, 0));
5167141Sgblack@eecs.umich.edu          case 0x2:
5177141Sgblack@eecs.umich.edu            switch (bits(machInst, 7, 6)) {
5187141Sgblack@eecs.umich.edu              case 0x0:
5197141Sgblack@eecs.umich.edu                return new WarnUnimplemented("sxth", machInst);
5207141Sgblack@eecs.umich.edu              case 0x1:
5217141Sgblack@eecs.umich.edu                return new WarnUnimplemented("sxtb", machInst);
5227141Sgblack@eecs.umich.edu              case 0x2:
5237141Sgblack@eecs.umich.edu                return new WarnUnimplemented("uxth", machInst);
5247141Sgblack@eecs.umich.edu              case 0x3:
5257141Sgblack@eecs.umich.edu                return new WarnUnimplemented("uxtb", machInst);
5267141Sgblack@eecs.umich.edu            }
5277141Sgblack@eecs.umich.edu          case 0x3:
5287154Sgblack@eecs.umich.edu            return new Cbz(machInst,
5297154Sgblack@eecs.umich.edu                           (bits(machInst, 9) << 6) |
5307154Sgblack@eecs.umich.edu                           (bits(machInst, 7, 3) << 1),
5317154Sgblack@eecs.umich.edu                           (IntRegIndex)(uint32_t)bits(machInst, 2, 0));
5327141Sgblack@eecs.umich.edu          case 0x4:
5337141Sgblack@eecs.umich.edu          case 0x5:
5347141Sgblack@eecs.umich.edu            return new WarnUnimplemented("push", machInst);
5357141Sgblack@eecs.umich.edu          case 0x6:
5367141Sgblack@eecs.umich.edu            {
5377141Sgblack@eecs.umich.edu                const uint32_t opBits = bits(machInst, 7, 5);
5387141Sgblack@eecs.umich.edu                if (opBits == 2) {
5397141Sgblack@eecs.umich.edu                    return new WarnUnimplemented("setend", machInst);
5407141Sgblack@eecs.umich.edu                } else if (opBits == 3) {
5417141Sgblack@eecs.umich.edu                    return new WarnUnimplemented("cps", machInst);
5427141Sgblack@eecs.umich.edu                }
5437141Sgblack@eecs.umich.edu            }
5447141Sgblack@eecs.umich.edu          case 0x9:
5457154Sgblack@eecs.umich.edu            return new Cbnz(machInst,
5467154Sgblack@eecs.umich.edu                            (bits(machInst, 9) << 6) |
5477154Sgblack@eecs.umich.edu                            (bits(machInst, 7, 3) << 1),
5487154Sgblack@eecs.umich.edu                            (IntRegIndex)(uint32_t)bits(machInst, 2, 0));
5497141Sgblack@eecs.umich.edu          case 0xa:
5507141Sgblack@eecs.umich.edu            switch (bits(machInst, 7, 5)) {
5517141Sgblack@eecs.umich.edu              case 0x0:
5527141Sgblack@eecs.umich.edu                return new WarnUnimplemented("rev", machInst);
5537141Sgblack@eecs.umich.edu              case 0x1:
5547141Sgblack@eecs.umich.edu                return new WarnUnimplemented("rev16", machInst);
5557141Sgblack@eecs.umich.edu              case 0x3:
5567141Sgblack@eecs.umich.edu                return new WarnUnimplemented("revsh", machInst);
5577141Sgblack@eecs.umich.edu              default:
5587141Sgblack@eecs.umich.edu                break;
5597141Sgblack@eecs.umich.edu            }
5607141Sgblack@eecs.umich.edu            break;
5617141Sgblack@eecs.umich.edu          case 0xb:
5627154Sgblack@eecs.umich.edu            return new Cbnz(machInst,
5637154Sgblack@eecs.umich.edu                            (bits(machInst, 9) << 6) |
5647154Sgblack@eecs.umich.edu                            (bits(machInst, 7, 3) << 1),
5657154Sgblack@eecs.umich.edu                            (IntRegIndex)(uint32_t)bits(machInst, 2, 0));
5667141Sgblack@eecs.umich.edu          case 0xc:
5677141Sgblack@eecs.umich.edu          case 0xd:
5687141Sgblack@eecs.umich.edu            return new WarnUnimplemented("pop", machInst);
5697141Sgblack@eecs.umich.edu          case 0xe:
5707141Sgblack@eecs.umich.edu            return new WarnUnimplemented("bkpt", machInst);
5717141Sgblack@eecs.umich.edu          case 0xf:
5727141Sgblack@eecs.umich.edu            if (bits(machInst, 3, 0) != 0)
5737141Sgblack@eecs.umich.edu                return new WarnUnimplemented("it", machInst);
5747141Sgblack@eecs.umich.edu            switch (bits(machInst, 7, 4)) {
5757141Sgblack@eecs.umich.edu              case 0x0:
5767141Sgblack@eecs.umich.edu                return new WarnUnimplemented("nop", machInst);
5777141Sgblack@eecs.umich.edu              case 0x1:
5787141Sgblack@eecs.umich.edu                return new WarnUnimplemented("yield", machInst);
5797141Sgblack@eecs.umich.edu              case 0x2:
5807141Sgblack@eecs.umich.edu                return new WarnUnimplemented("wfe", machInst);
5817141Sgblack@eecs.umich.edu              case 0x3:
5827141Sgblack@eecs.umich.edu                return new WarnUnimplemented("wfi", machInst);
5837141Sgblack@eecs.umich.edu              case 0x4:
5847141Sgblack@eecs.umich.edu                return new WarnUnimplemented("sev", machInst);
5857141Sgblack@eecs.umich.edu              default:
5867141Sgblack@eecs.umich.edu                return new WarnUnimplemented("unallocated_hint", machInst);
5877141Sgblack@eecs.umich.edu            }
5887141Sgblack@eecs.umich.edu          default:
5897141Sgblack@eecs.umich.edu            break;
5907141Sgblack@eecs.umich.edu        }
5917141Sgblack@eecs.umich.edu        return new Unknown(machInst);
5927141Sgblack@eecs.umich.edu    }
5937141Sgblack@eecs.umich.edu    '''
5947141Sgblack@eecs.umich.edu}};
5957141Sgblack@eecs.umich.edu
5967141Sgblack@eecs.umich.edudef format Thumb32DataProcModImm() {{
5977141Sgblack@eecs.umich.edu
5987141Sgblack@eecs.umich.edu    def decInst(mnem, dest="rd", op1="rn"):
5997141Sgblack@eecs.umich.edu        return '''
6007141Sgblack@eecs.umich.edu            if (s) {
6017146Sgblack@eecs.umich.edu                return new %(mnem)sImmCc(machInst, %(dest)s,
6027183Sgblack@eecs.umich.edu                                          %(op1)s, imm, rotC);
6037141Sgblack@eecs.umich.edu            } else {
6047146Sgblack@eecs.umich.edu                return new %(mnem)sImm(machInst, %(dest)s,
6057183Sgblack@eecs.umich.edu                                        %(op1)s, imm, rotC);
6067141Sgblack@eecs.umich.edu            }
6077141Sgblack@eecs.umich.edu        ''' % {"mnem" : mnem, "dest" : dest, "op1" : op1}
6087141Sgblack@eecs.umich.edu
6097141Sgblack@eecs.umich.edu    decode_block = '''
6107141Sgblack@eecs.umich.edu    {
6117141Sgblack@eecs.umich.edu        const uint32_t op = bits(machInst, 24, 21);
6127141Sgblack@eecs.umich.edu        const bool s = (bits(machInst, 20) == 1);
6137141Sgblack@eecs.umich.edu        const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
6147141Sgblack@eecs.umich.edu        const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
6157141Sgblack@eecs.umich.edu        const uint32_t ctrlImm = bits(machInst.instBits, 26) << 3 |
6167141Sgblack@eecs.umich.edu                                 bits(machInst, 14, 12);
6177183Sgblack@eecs.umich.edu        const bool rotC = ctrlImm > 3;
6187141Sgblack@eecs.umich.edu        const uint32_t dataImm = bits(machInst, 7, 0);
6197141Sgblack@eecs.umich.edu        const uint32_t imm = modified_imm(ctrlImm, dataImm);
6207141Sgblack@eecs.umich.edu        switch (op) {
6217141Sgblack@eecs.umich.edu          case 0x0:
6227141Sgblack@eecs.umich.edu            if (rd == INTREG_PC) {
6237141Sgblack@eecs.umich.edu                %(tst)s
6247141Sgblack@eecs.umich.edu            } else {
6257141Sgblack@eecs.umich.edu                %(and)s
6267141Sgblack@eecs.umich.edu            }
6277141Sgblack@eecs.umich.edu          case 0x1:
6287141Sgblack@eecs.umich.edu            %(bic)s
6297141Sgblack@eecs.umich.edu          case 0x2:
6307141Sgblack@eecs.umich.edu            if (rn == INTREG_PC) {
6317141Sgblack@eecs.umich.edu                %(mov)s
6327141Sgblack@eecs.umich.edu            } else {
6337141Sgblack@eecs.umich.edu                %(orr)s
6347141Sgblack@eecs.umich.edu            }
6357141Sgblack@eecs.umich.edu          case 0x3:
6367141Sgblack@eecs.umich.edu            if (rn == INTREG_PC) {
6377141Sgblack@eecs.umich.edu                %(mvn)s
6387141Sgblack@eecs.umich.edu            } else {
6397141Sgblack@eecs.umich.edu                %(orn)s
6407141Sgblack@eecs.umich.edu            }
6417141Sgblack@eecs.umich.edu          case 0x4:
6427141Sgblack@eecs.umich.edu            if (rd == INTREG_PC) {
6437141Sgblack@eecs.umich.edu                %(teq)s
6447141Sgblack@eecs.umich.edu            } else {
6457141Sgblack@eecs.umich.edu                %(eor)s
6467141Sgblack@eecs.umich.edu            }
6477141Sgblack@eecs.umich.edu          case 0x8:
6487141Sgblack@eecs.umich.edu            if (rd == INTREG_PC) {
6497141Sgblack@eecs.umich.edu                %(cmn)s
6507141Sgblack@eecs.umich.edu            } else {
6517141Sgblack@eecs.umich.edu                %(add)s
6527141Sgblack@eecs.umich.edu            }
6537141Sgblack@eecs.umich.edu          case 0xa:
6547141Sgblack@eecs.umich.edu            %(adc)s
6557141Sgblack@eecs.umich.edu          case 0xb:
6567141Sgblack@eecs.umich.edu            %(sbc)s
6577141Sgblack@eecs.umich.edu          case 0xd:
6587141Sgblack@eecs.umich.edu            if (rd == INTREG_PC) {
6597141Sgblack@eecs.umich.edu                %(cmp)s
6607141Sgblack@eecs.umich.edu            } else {
6617141Sgblack@eecs.umich.edu                %(sub)s
6627141Sgblack@eecs.umich.edu            }
6637141Sgblack@eecs.umich.edu          case 0xe:
6647141Sgblack@eecs.umich.edu            %(rsb)s
6657141Sgblack@eecs.umich.edu          default:
6667141Sgblack@eecs.umich.edu            return new Unknown(machInst);
6677141Sgblack@eecs.umich.edu        }
6687141Sgblack@eecs.umich.edu    }
6697141Sgblack@eecs.umich.edu    ''' % {
6707141Sgblack@eecs.umich.edu        "tst" : decInst("Tst", "INTREG_ZERO"),
6717141Sgblack@eecs.umich.edu        "and" : decInst("And"),
6727141Sgblack@eecs.umich.edu        "bic" : decInst("Bic"),
6737141Sgblack@eecs.umich.edu        "mov" : decInst("Mov", op1="INTREG_ZERO"),
6747141Sgblack@eecs.umich.edu        "orr" : decInst("Orr"),
6757141Sgblack@eecs.umich.edu        "mvn" : decInst("Mvn", op1="INTREG_ZERO"),
6767141Sgblack@eecs.umich.edu        "orn" : decInst("Orn"),
6777141Sgblack@eecs.umich.edu        "teq" : decInst("Teq", dest="INTREG_ZERO"),
6787141Sgblack@eecs.umich.edu        "eor" : decInst("Eor"),
6797141Sgblack@eecs.umich.edu        "cmn" : decInst("Cmn", dest="INTREG_ZERO"),
6807141Sgblack@eecs.umich.edu        "add" : decInst("Add"),
6817141Sgblack@eecs.umich.edu        "adc" : decInst("Adc"),
6827141Sgblack@eecs.umich.edu        "sbc" : decInst("Sbc"),
6837141Sgblack@eecs.umich.edu        "cmp" : decInst("Cmp", dest="INTREG_ZERO"),
6847141Sgblack@eecs.umich.edu        "sub" : decInst("Sub"),
6857141Sgblack@eecs.umich.edu        "rsb" : decInst("Rsb")
6867141Sgblack@eecs.umich.edu    }
6877141Sgblack@eecs.umich.edu}};
6887141Sgblack@eecs.umich.edu
6897157Sgblack@eecs.umich.edudef format Thumb32DataProcPlainBin() {{
6907157Sgblack@eecs.umich.edu    decode_block = '''
6917157Sgblack@eecs.umich.edu    {
6927157Sgblack@eecs.umich.edu        const uint32_t op = bits(machInst, 24, 20);
6937157Sgblack@eecs.umich.edu        const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
6947157Sgblack@eecs.umich.edu        const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
6957157Sgblack@eecs.umich.edu        switch (op) {
6967157Sgblack@eecs.umich.edu          case 0x0:
6977157Sgblack@eecs.umich.edu            {
6987157Sgblack@eecs.umich.edu                const uint32_t imm = bits(machInst, 7, 0) |
6997157Sgblack@eecs.umich.edu                                     (bits(machInst, 14, 12) << 8) |
7007157Sgblack@eecs.umich.edu                                     (bits(machInst, 26) << 11);
7017185Sgblack@eecs.umich.edu                if (rn == 0xf) {
7027185Sgblack@eecs.umich.edu                    return new AdrImm(machInst, rd, (IntRegIndex)1,
7037185Sgblack@eecs.umich.edu                                      imm, false);
7047185Sgblack@eecs.umich.edu                } else {
7057185Sgblack@eecs.umich.edu                    return new AddImm(machInst, rd, rn, imm, true);
7067185Sgblack@eecs.umich.edu                }
7077157Sgblack@eecs.umich.edu            }
7087157Sgblack@eecs.umich.edu          case 0x4:
7097157Sgblack@eecs.umich.edu            {
7107157Sgblack@eecs.umich.edu                const uint32_t imm = bits(machInst, 7, 0) |
7117157Sgblack@eecs.umich.edu                                     (bits(machInst, 14, 12) << 8) |
7127157Sgblack@eecs.umich.edu                                     (bits(machInst, 26) << 11) |
7137157Sgblack@eecs.umich.edu                                     (bits(machInst, 19, 16) << 12);
7147157Sgblack@eecs.umich.edu                return new MovImm(machInst, rd, INTREG_ZERO, imm, true);
7157157Sgblack@eecs.umich.edu            }
7167157Sgblack@eecs.umich.edu          case 0xa:
7177157Sgblack@eecs.umich.edu            {
7187157Sgblack@eecs.umich.edu                const uint32_t imm = bits(machInst, 7, 0) |
7197157Sgblack@eecs.umich.edu                                     (bits(machInst, 14, 12) << 8) |
7207157Sgblack@eecs.umich.edu                                     (bits(machInst, 26) << 11);
7217185Sgblack@eecs.umich.edu                if (rn == 0xf) {
7227185Sgblack@eecs.umich.edu                    return new AdrImm(machInst, rd, (IntRegIndex)0,
7237185Sgblack@eecs.umich.edu                                      imm, false);
7247185Sgblack@eecs.umich.edu                } else {
7257185Sgblack@eecs.umich.edu                    return new SubImm(machInst, rd, rn, imm, true);
7267185Sgblack@eecs.umich.edu                }
7277157Sgblack@eecs.umich.edu            }
7287157Sgblack@eecs.umich.edu          case 0xc:
7297157Sgblack@eecs.umich.edu            {
7307157Sgblack@eecs.umich.edu                const uint32_t imm = bits(machInst, 7, 0) |
7317157Sgblack@eecs.umich.edu                                     (bits(machInst, 14, 12) << 8) |
7327157Sgblack@eecs.umich.edu                                     (bits(machInst, 26) << 11) |
7337157Sgblack@eecs.umich.edu                                     (bits(machInst, 19, 16) << 12);
7347157Sgblack@eecs.umich.edu                return new MovtImm(machInst, rd, rd, imm, true);
7357157Sgblack@eecs.umich.edu            }
7367157Sgblack@eecs.umich.edu          case 0x12:
7377157Sgblack@eecs.umich.edu            if (!(bits(machInst, 14, 12) || bits(machInst, 7, 6))) {
7387157Sgblack@eecs.umich.edu                return new WarnUnimplemented("ssat16", machInst);
7397157Sgblack@eecs.umich.edu            }
7407157Sgblack@eecs.umich.edu            // Fall through on purpose...
7417157Sgblack@eecs.umich.edu          case 0x10:
7427157Sgblack@eecs.umich.edu            return new WarnUnimplemented("ssat", machInst);
7437157Sgblack@eecs.umich.edu          case 0x14:
7447157Sgblack@eecs.umich.edu            return new WarnUnimplemented("sbfx", machInst);
7457157Sgblack@eecs.umich.edu          case 0x16:
7467157Sgblack@eecs.umich.edu            if (rn == 0xf) {
7477157Sgblack@eecs.umich.edu                return new WarnUnimplemented("bfc", machInst);
7487157Sgblack@eecs.umich.edu            } else {
7497157Sgblack@eecs.umich.edu                return new WarnUnimplemented("bfi", machInst);
7507157Sgblack@eecs.umich.edu            }
7517157Sgblack@eecs.umich.edu          case 0x1a:
7527157Sgblack@eecs.umich.edu            if (!(bits(machInst, 14, 12) || bits(machInst, 7, 6))) {
7537157Sgblack@eecs.umich.edu                return new WarnUnimplemented("usat16", machInst);
7547157Sgblack@eecs.umich.edu            }
7557157Sgblack@eecs.umich.edu            // Fall through on purpose...
7567157Sgblack@eecs.umich.edu          case 0x18:
7577157Sgblack@eecs.umich.edu            return new WarnUnimplemented("usat", machInst);
7587157Sgblack@eecs.umich.edu          case 0x1c:
7597157Sgblack@eecs.umich.edu            return new WarnUnimplemented("ubfx", machInst);
7607157Sgblack@eecs.umich.edu          default:
7617157Sgblack@eecs.umich.edu            return new Unknown(machInst);
7627157Sgblack@eecs.umich.edu        }
7637157Sgblack@eecs.umich.edu    }
7647157Sgblack@eecs.umich.edu    '''
7657157Sgblack@eecs.umich.edu}};
7667157Sgblack@eecs.umich.edu
7677141Sgblack@eecs.umich.edudef format Thumb32DataProcShiftReg() {{
7687141Sgblack@eecs.umich.edu
7697141Sgblack@eecs.umich.edu    def decInst(mnem, dest="rd", op1="rn"):
7707141Sgblack@eecs.umich.edu        return '''
7717141Sgblack@eecs.umich.edu            if (s) {
7727146Sgblack@eecs.umich.edu                return new %(mnem)sRegCc(machInst, %(dest)s,
7737141Sgblack@eecs.umich.edu                                          %(op1)s, rm, amt, type);
7747141Sgblack@eecs.umich.edu            } else {
7757146Sgblack@eecs.umich.edu                return new %(mnem)sReg(machInst, %(dest)s,
7767141Sgblack@eecs.umich.edu                                        %(op1)s, rm, amt, type);
7777141Sgblack@eecs.umich.edu            }
7787141Sgblack@eecs.umich.edu        ''' % {"mnem" : mnem, "dest" : dest, "op1" : op1}
7797141Sgblack@eecs.umich.edu
7807141Sgblack@eecs.umich.edu    decode_block = '''
7817141Sgblack@eecs.umich.edu    {
7827141Sgblack@eecs.umich.edu        const uint32_t op = bits(machInst, 24, 21);
7837141Sgblack@eecs.umich.edu        const bool s = (bits(machInst, 20) == 1);
7847141Sgblack@eecs.umich.edu        const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
7857141Sgblack@eecs.umich.edu        const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
7867141Sgblack@eecs.umich.edu        const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
7877141Sgblack@eecs.umich.edu        const uint32_t amt = (bits(machInst, 14, 12) << 2) |
7887141Sgblack@eecs.umich.edu                              bits(machInst, 7, 6);
7897141Sgblack@eecs.umich.edu        const ArmShiftType type = (ArmShiftType)(uint32_t)bits(machInst, 5, 4);
7907141Sgblack@eecs.umich.edu        switch (op) {
7917141Sgblack@eecs.umich.edu          case 0x0:
7927141Sgblack@eecs.umich.edu            if (rd == INTREG_PC) {
7937141Sgblack@eecs.umich.edu                %(tst)s
7947141Sgblack@eecs.umich.edu            } else {
7957141Sgblack@eecs.umich.edu                %(and)s
7967141Sgblack@eecs.umich.edu            }
7977141Sgblack@eecs.umich.edu          case 0x1:
7987141Sgblack@eecs.umich.edu            %(bic)s
7997141Sgblack@eecs.umich.edu          case 0x2:
8007141Sgblack@eecs.umich.edu            if (rn == INTREG_PC) {
8017141Sgblack@eecs.umich.edu                %(mov)s
8027141Sgblack@eecs.umich.edu            } else {
8037141Sgblack@eecs.umich.edu                %(orr)s
8047141Sgblack@eecs.umich.edu            }
8057141Sgblack@eecs.umich.edu          case 0x3:
8067141Sgblack@eecs.umich.edu            if (rn == INTREG_PC) {
8077141Sgblack@eecs.umich.edu                %(mvn)s
8087141Sgblack@eecs.umich.edu            } else {
8097141Sgblack@eecs.umich.edu                %(orn)s
8107141Sgblack@eecs.umich.edu            }
8117141Sgblack@eecs.umich.edu          case 0x4:
8127141Sgblack@eecs.umich.edu            if (rd == INTREG_PC) {
8137141Sgblack@eecs.umich.edu                %(teq)s
8147141Sgblack@eecs.umich.edu            } else {
8157141Sgblack@eecs.umich.edu                %(eor)s
8167141Sgblack@eecs.umich.edu            }
8177141Sgblack@eecs.umich.edu          case 0x6:
8187141Sgblack@eecs.umich.edu            return new WarnUnimplemented("pkh", machInst);
8197141Sgblack@eecs.umich.edu          case 0x8:
8207141Sgblack@eecs.umich.edu            if (rd == INTREG_PC) {
8217141Sgblack@eecs.umich.edu                %(cmn)s
8227141Sgblack@eecs.umich.edu            } else {
8237141Sgblack@eecs.umich.edu                %(add)s
8247141Sgblack@eecs.umich.edu            }
8257141Sgblack@eecs.umich.edu          case 0xa:
8267141Sgblack@eecs.umich.edu            %(adc)s
8277141Sgblack@eecs.umich.edu          case 0xb:
8287141Sgblack@eecs.umich.edu            %(sbc)s
8297141Sgblack@eecs.umich.edu          case 0xd:
8307141Sgblack@eecs.umich.edu            if (rd == INTREG_PC) {
8317141Sgblack@eecs.umich.edu                %(cmp)s
8327141Sgblack@eecs.umich.edu            } else {
8337141Sgblack@eecs.umich.edu                %(sub)s
8347141Sgblack@eecs.umich.edu            }
8357141Sgblack@eecs.umich.edu          case 0xe:
8367141Sgblack@eecs.umich.edu            %(rsb)s
8377141Sgblack@eecs.umich.edu          default:
8387141Sgblack@eecs.umich.edu            return new Unknown(machInst);
8397141Sgblack@eecs.umich.edu        }
8407141Sgblack@eecs.umich.edu    }
8417141Sgblack@eecs.umich.edu    ''' % {
8427141Sgblack@eecs.umich.edu        "tst" : decInst("Tst", "INTREG_ZERO"),
8437141Sgblack@eecs.umich.edu        "and" : decInst("And"),
8447141Sgblack@eecs.umich.edu        "bic" : decInst("Bic"),
8457141Sgblack@eecs.umich.edu        "mov" : decInst("Mov", op1="INTREG_ZERO"),
8467141Sgblack@eecs.umich.edu        "orr" : decInst("Orr"),
8477141Sgblack@eecs.umich.edu        "mvn" : decInst("Mvn", op1="INTREG_ZERO"),
8487141Sgblack@eecs.umich.edu        "orn" : decInst("Orn"),
8497141Sgblack@eecs.umich.edu        "teq" : decInst("Teq", "INTREG_ZERO"),
8507141Sgblack@eecs.umich.edu        "eor" : decInst("Eor"),
8517141Sgblack@eecs.umich.edu        "cmn" : decInst("Cmn", "INTREG_ZERO"),
8527141Sgblack@eecs.umich.edu        "add" : decInst("Add"),
8537141Sgblack@eecs.umich.edu        "adc" : decInst("Adc"),
8547141Sgblack@eecs.umich.edu        "sbc" : decInst("Sbc"),
8557141Sgblack@eecs.umich.edu        "cmp" : decInst("Cmp", "INTREG_ZERO"),
8567141Sgblack@eecs.umich.edu        "sub" : decInst("Sub"),
8577141Sgblack@eecs.umich.edu        "rsb" : decInst("Rsb")
8587141Sgblack@eecs.umich.edu    }
8597141Sgblack@eecs.umich.edu}};
860