data.isa revision 7224
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) {
1347210Sgblack@eecs.umich.edu            if (op1 == 0) {
1357210Sgblack@eecs.umich.edu                return new WarnUnimplemented("pkh", machInst);
1367210Sgblack@eecs.umich.edu            } else if (bits(op1, 2, 1) == 1) {
1377210Sgblack@eecs.umich.edu                return new WarnUnimplemented("ssat", machInst);
1387210Sgblack@eecs.umich.edu            } else if (bits(op1, 2, 1) == 3) {
1397210Sgblack@eecs.umich.edu                return new WarnUnimplemented("usat", machInst);
1407210Sgblack@eecs.umich.edu            }
1417210Sgblack@eecs.umich.edu            return new Unknown(machInst);
1427210Sgblack@eecs.umich.edu        }
1437210Sgblack@eecs.umich.edu        switch (op1) {
1447210Sgblack@eecs.umich.edu          case 0x0:
1457210Sgblack@eecs.umich.edu            if (op2 == 0x3) {
1467210Sgblack@eecs.umich.edu                if (a == 0xf) {
1477210Sgblack@eecs.umich.edu                    return new WarnUnimplemented("sxtb16", machInst);
1487210Sgblack@eecs.umich.edu                } else {
1497210Sgblack@eecs.umich.edu                    return new WarnUnimplemented("sxtab16", machInst);
1507210Sgblack@eecs.umich.edu                }
1517210Sgblack@eecs.umich.edu            } else if (op2 == 0x5) {
1527210Sgblack@eecs.umich.edu                return new WarnUnimplemented("sel", machInst);
1537210Sgblack@eecs.umich.edu            }
1547210Sgblack@eecs.umich.edu            break;
1557210Sgblack@eecs.umich.edu          case 0x2:
1567210Sgblack@eecs.umich.edu            if (op2 == 0x1) {
1577210Sgblack@eecs.umich.edu                return new WarnUnimplemented("ssat16", machInst);
1587210Sgblack@eecs.umich.edu            } else if (op2 == 0x3) {
1597210Sgblack@eecs.umich.edu                if (a == 0xf) {
1607210Sgblack@eecs.umich.edu                    return new WarnUnimplemented("sxtb", machInst);
1617210Sgblack@eecs.umich.edu                } else {
1627210Sgblack@eecs.umich.edu                    return new WarnUnimplemented("sxtab", machInst);
1637210Sgblack@eecs.umich.edu                }
1647210Sgblack@eecs.umich.edu            }
1657210Sgblack@eecs.umich.edu            break;
1667210Sgblack@eecs.umich.edu          case 0x3:
1677210Sgblack@eecs.umich.edu            if (op2 == 0x1) {
1687211Sgblack@eecs.umich.edu                IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
1697211Sgblack@eecs.umich.edu                IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
1707211Sgblack@eecs.umich.edu                return new Rev(machInst, rd, rm);
1717210Sgblack@eecs.umich.edu            } else if (op2 == 0x3) {
1727210Sgblack@eecs.umich.edu                if (a == 0xf) {
1737210Sgblack@eecs.umich.edu                    return new WarnUnimplemented("sxth", machInst);
1747210Sgblack@eecs.umich.edu                } else {
1757210Sgblack@eecs.umich.edu                    return new WarnUnimplemented("sxtah", machInst);
1767210Sgblack@eecs.umich.edu                }
1777210Sgblack@eecs.umich.edu            } else if (op2 == 0x5) {
1787211Sgblack@eecs.umich.edu                IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
1797211Sgblack@eecs.umich.edu                IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
1807211Sgblack@eecs.umich.edu                return new Rev16(machInst, rd, rm);
1817210Sgblack@eecs.umich.edu            }
1827210Sgblack@eecs.umich.edu            break;
1837210Sgblack@eecs.umich.edu          case 0x4:
1847210Sgblack@eecs.umich.edu            if (op2 == 0x3) {
1857210Sgblack@eecs.umich.edu                if (a == 0xf) {
1867210Sgblack@eecs.umich.edu                    return new WarnUnimplemented("uxtb16", machInst);
1877210Sgblack@eecs.umich.edu                } else {
1887210Sgblack@eecs.umich.edu                    return new WarnUnimplemented("uxtab16", machInst);
1897210Sgblack@eecs.umich.edu                }
1907210Sgblack@eecs.umich.edu            }
1917210Sgblack@eecs.umich.edu            break;
1927210Sgblack@eecs.umich.edu          case 0x6:
1937210Sgblack@eecs.umich.edu            if (op2 == 0x1) {
1947210Sgblack@eecs.umich.edu                return new WarnUnimplemented("usat16", machInst);
1957210Sgblack@eecs.umich.edu            } else if (op2 == 0x3) {
1967210Sgblack@eecs.umich.edu                if (a == 0xf) {
1977210Sgblack@eecs.umich.edu                    return new WarnUnimplemented("uxtb", machInst);
1987210Sgblack@eecs.umich.edu                } else {
1997210Sgblack@eecs.umich.edu                    return new WarnUnimplemented("uxtab", machInst);
2007210Sgblack@eecs.umich.edu                }
2017210Sgblack@eecs.umich.edu            }
2027210Sgblack@eecs.umich.edu            break;
2037210Sgblack@eecs.umich.edu          case 0x7:
2047210Sgblack@eecs.umich.edu            if (op2 == 0x1) {
2057210Sgblack@eecs.umich.edu                return new WarnUnimplemented("rbit", machInst);
2067210Sgblack@eecs.umich.edu            } else if (op2 == 0x3) {
2077210Sgblack@eecs.umich.edu                if (a == 0xf) {
2087210Sgblack@eecs.umich.edu                    return new WarnUnimplemented("uxth", machInst);
2097210Sgblack@eecs.umich.edu                } else {
2107210Sgblack@eecs.umich.edu                    return new WarnUnimplemented("uxtah", machInst);
2117210Sgblack@eecs.umich.edu                }
2127210Sgblack@eecs.umich.edu            } else if (op2 == 0x5) {
2137211Sgblack@eecs.umich.edu                IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
2147211Sgblack@eecs.umich.edu                IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
2157211Sgblack@eecs.umich.edu                return new Revsh(machInst, rd, rm);
2167210Sgblack@eecs.umich.edu            }
2177210Sgblack@eecs.umich.edu            break;
2187210Sgblack@eecs.umich.edu        }
2197210Sgblack@eecs.umich.edu        return new Unknown(machInst);
2207210Sgblack@eecs.umich.edu    }
2217210Sgblack@eecs.umich.edu    '''
2227210Sgblack@eecs.umich.edu}};
2237210Sgblack@eecs.umich.edu
2247194Sgblack@eecs.umich.edudef format ArmParallelAddSubtract() {{
2257194Sgblack@eecs.umich.edu    decode_block='''
2267194Sgblack@eecs.umich.edu    {
2277194Sgblack@eecs.umich.edu        const uint32_t op1 = bits(machInst, 21, 20);
2287194Sgblack@eecs.umich.edu        const uint32_t op2 = bits(machInst, 7, 5);
2297194Sgblack@eecs.umich.edu        const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
2307194Sgblack@eecs.umich.edu        const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
2317194Sgblack@eecs.umich.edu        const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
2327194Sgblack@eecs.umich.edu        if (bits(machInst, 22) == 0) {
2337194Sgblack@eecs.umich.edu            switch (op1) {
2347194Sgblack@eecs.umich.edu              case 0x1:
2357194Sgblack@eecs.umich.edu                switch (op2) {
2367194Sgblack@eecs.umich.edu                  case 0x0:
2377216Sgblack@eecs.umich.edu                    return new Sadd16RegCc(machInst, rd, rn, rm, 0, LSL);
2387194Sgblack@eecs.umich.edu                  case 0x1:
2397224Sgblack@eecs.umich.edu                    return new SasxRegCc(machInst, rd, rn, rm, 0, LSL);
2407194Sgblack@eecs.umich.edu                  case 0x2:
2417224Sgblack@eecs.umich.edu                    return new SsaxRegCc(machInst, rd, rn, rm, 0, LSL);
2427194Sgblack@eecs.umich.edu                  case 0x3:
2437218Sgblack@eecs.umich.edu                    return new Ssub16RegCc(machInst, rd, rn, rm, 0, LSL);
2447194Sgblack@eecs.umich.edu                  case 0x4:
2457216Sgblack@eecs.umich.edu                    return new Sadd8RegCc(machInst, rd, rn, rm, 0, LSL);
2467194Sgblack@eecs.umich.edu                  case 0x7:
2477218Sgblack@eecs.umich.edu                    return new Ssub8RegCc(machInst, rd, rn, rm, 0, LSL);
2487194Sgblack@eecs.umich.edu                }
2497194Sgblack@eecs.umich.edu                break;
2507194Sgblack@eecs.umich.edu              case 0x2:
2517194Sgblack@eecs.umich.edu                switch (op2) {
2527194Sgblack@eecs.umich.edu                  case 0x0:
2537194Sgblack@eecs.umich.edu                    return new Qadd16Reg(machInst, rd, rn, rm, 0, LSL);
2547194Sgblack@eecs.umich.edu                  case 0x1:
2557194Sgblack@eecs.umich.edu                    return new QasxReg(machInst, rd, rn, rm, 0, LSL);
2567194Sgblack@eecs.umich.edu                  case 0x2:
2577194Sgblack@eecs.umich.edu                    return new QsaxReg(machInst, rd, rn, rm, 0, LSL);
2587194Sgblack@eecs.umich.edu                  case 0x3:
2597194Sgblack@eecs.umich.edu                    return new Qsub16Reg(machInst, rd, rn, rm, 0, LSL);
2607194Sgblack@eecs.umich.edu                  case 0x4:
2617194Sgblack@eecs.umich.edu                    return new Qadd8Reg(machInst, rd, rn, rm, 0, LSL);
2627194Sgblack@eecs.umich.edu                  case 0x7:
2637194Sgblack@eecs.umich.edu                    return new Qsub8Reg(machInst, rd, rn, rm, 0, LSL);
2647194Sgblack@eecs.umich.edu                }
2657194Sgblack@eecs.umich.edu                break;
2667194Sgblack@eecs.umich.edu              case 0x3:
2677194Sgblack@eecs.umich.edu                switch (op2) {
2687194Sgblack@eecs.umich.edu                  case 0x0:
2697194Sgblack@eecs.umich.edu                    return new WarnUnimplemented("shadd16", machInst);
2707194Sgblack@eecs.umich.edu                  case 0x1:
2717194Sgblack@eecs.umich.edu                    return new WarnUnimplemented("shasx", machInst);
2727194Sgblack@eecs.umich.edu                  case 0x2:
2737194Sgblack@eecs.umich.edu                    return new WarnUnimplemented("shsax", machInst);
2747194Sgblack@eecs.umich.edu                  case 0x3:
2757194Sgblack@eecs.umich.edu                    return new WarnUnimplemented("shsub16", machInst);
2767194Sgblack@eecs.umich.edu                  case 0x4:
2777194Sgblack@eecs.umich.edu                    return new WarnUnimplemented("shadd8", machInst);
2787194Sgblack@eecs.umich.edu                  case 0x7:
2797194Sgblack@eecs.umich.edu                    return new WarnUnimplemented("shsub8", machInst);
2807194Sgblack@eecs.umich.edu                }
2817194Sgblack@eecs.umich.edu                break;
2827194Sgblack@eecs.umich.edu            }
2837194Sgblack@eecs.umich.edu        } else {
2847194Sgblack@eecs.umich.edu            switch (op1) {
2857194Sgblack@eecs.umich.edu              case 0x1:
2867194Sgblack@eecs.umich.edu                switch (op2) {
2877194Sgblack@eecs.umich.edu                  case 0x0:
2887222Sgblack@eecs.umich.edu                    return new Uadd16RegCc(machInst, rd, rn, rm, 0, LSL);
2897194Sgblack@eecs.umich.edu                  case 0x1:
2907222Sgblack@eecs.umich.edu                    return new UasxRegCc(machInst, rd, rn, rm, 0, LSL);
2917194Sgblack@eecs.umich.edu                  case 0x2:
2927222Sgblack@eecs.umich.edu                    return new UsaxRegCc(machInst, rd, rn, rm, 0, LSL);
2937194Sgblack@eecs.umich.edu                  case 0x3:
2947222Sgblack@eecs.umich.edu                    return new Usub16RegCc(machInst, rd, rn, rm, 0, LSL);
2957194Sgblack@eecs.umich.edu                  case 0x4:
2967222Sgblack@eecs.umich.edu                    return new Uadd8RegCc(machInst, rd, rn, rm, 0, LSL);
2977194Sgblack@eecs.umich.edu                  case 0x7:
2987222Sgblack@eecs.umich.edu                    return new Usub8RegCc(machInst, rd, rn, rm, 0, LSL);
2997194Sgblack@eecs.umich.edu                }
3007194Sgblack@eecs.umich.edu                break;
3017194Sgblack@eecs.umich.edu              case 0x2:
3027194Sgblack@eecs.umich.edu                switch (op2) {
3037194Sgblack@eecs.umich.edu                  case 0x0:
3047220Sgblack@eecs.umich.edu                    return new Uqadd16Reg(machInst, rd, rn, rm, 0, LSL);
3057194Sgblack@eecs.umich.edu                  case 0x1:
3067220Sgblack@eecs.umich.edu                    return new UqasxReg(machInst, rd, rn, rm, 0, LSL);
3077194Sgblack@eecs.umich.edu                  case 0x2:
3087220Sgblack@eecs.umich.edu                    return new UqsaxReg(machInst, rd, rn, rm, 0, LSL);
3097194Sgblack@eecs.umich.edu                  case 0x3:
3107220Sgblack@eecs.umich.edu                    return new Uqsub16Reg(machInst, rd, rn, rm, 0, LSL);
3117194Sgblack@eecs.umich.edu                  case 0x4:
3127220Sgblack@eecs.umich.edu                    return new Uqadd8Reg(machInst, rd, rn, rm, 0, LSL);
3137194Sgblack@eecs.umich.edu                  case 0x7:
3147220Sgblack@eecs.umich.edu                    return new Uqsub8Reg(machInst, rd, rn, rm, 0, LSL);
3157194Sgblack@eecs.umich.edu                }
3167194Sgblack@eecs.umich.edu                break;
3177194Sgblack@eecs.umich.edu              case 0x3:
3187194Sgblack@eecs.umich.edu                switch (op2) {
3197194Sgblack@eecs.umich.edu                  case 0x0:
3207194Sgblack@eecs.umich.edu                    return new WarnUnimplemented("uhadd16", machInst);
3217194Sgblack@eecs.umich.edu                  case 0x1:
3227194Sgblack@eecs.umich.edu                    return new WarnUnimplemented("uhasx", machInst);
3237194Sgblack@eecs.umich.edu                  case 0x2:
3247194Sgblack@eecs.umich.edu                    return new WarnUnimplemented("uhsax", machInst);
3257194Sgblack@eecs.umich.edu                  case 0x3:
3267194Sgblack@eecs.umich.edu                    return new WarnUnimplemented("uhsub16", machInst);
3277194Sgblack@eecs.umich.edu                  case 0x4:
3287194Sgblack@eecs.umich.edu                    return new WarnUnimplemented("uhadd8", machInst);
3297194Sgblack@eecs.umich.edu                  case 0x7:
3307194Sgblack@eecs.umich.edu                    return new WarnUnimplemented("uhsub8", machInst);
3317194Sgblack@eecs.umich.edu                }
3327194Sgblack@eecs.umich.edu                break;
3337194Sgblack@eecs.umich.edu            }
3347194Sgblack@eecs.umich.edu        }
3357194Sgblack@eecs.umich.edu        return new Unknown(machInst);
3367194Sgblack@eecs.umich.edu    }
3377194Sgblack@eecs.umich.edu    '''
3387194Sgblack@eecs.umich.edu}};
3397194Sgblack@eecs.umich.edu
3407139Sgblack@eecs.umich.edudef format ArmDataProcImm() {{
3417188Sgblack@eecs.umich.edu    pclr = '''
3427188Sgblack@eecs.umich.edu        return new %(className)ssImmPclr(machInst, %(dest)s,
3437188Sgblack@eecs.umich.edu                                        %(op1)s, imm, false);
3447188Sgblack@eecs.umich.edu    '''
3457188Sgblack@eecs.umich.edu    adr = '''
3467188Sgblack@eecs.umich.edu        return new AdrImm(machInst, %(dest)s, %(add)s,
3477188Sgblack@eecs.umich.edu                                     imm, false);
3487188Sgblack@eecs.umich.edu    '''
3497139Sgblack@eecs.umich.edu    instDecode = '''
3507188Sgblack@eecs.umich.edu          case %(opcode)#x:
3517139Sgblack@eecs.umich.edu            if (setCc) {
3527188Sgblack@eecs.umich.edu                if (%(pclrInst)s && %(dest)s == INTREG_PC) {
3537188Sgblack@eecs.umich.edu                    %(pclr)s
3547188Sgblack@eecs.umich.edu                } else {
3557188Sgblack@eecs.umich.edu                    return new %(className)sImmCc(machInst, %(dest)s, %(op1)s,
3567188Sgblack@eecs.umich.edu                                                   imm, rotC);
3577188Sgblack@eecs.umich.edu                }
3587139Sgblack@eecs.umich.edu            } else {
3597188Sgblack@eecs.umich.edu                if (%(adrInst)s && %(op1)s == INTREG_PC) {
3607188Sgblack@eecs.umich.edu                    %(adr)s
3617188Sgblack@eecs.umich.edu                } else {
3627188Sgblack@eecs.umich.edu                    return new %(className)sImm(machInst, %(dest)s, %(op1)s,
3637188Sgblack@eecs.umich.edu                                                 imm, rotC);
3647188Sgblack@eecs.umich.edu                }
3657139Sgblack@eecs.umich.edu            }
3667139Sgblack@eecs.umich.edu            break;
3677139Sgblack@eecs.umich.edu    '''
3687139Sgblack@eecs.umich.edu
3697188Sgblack@eecs.umich.edu    def instCode(opcode, mnem, useDest = True, useOp1 = True):
3707188Sgblack@eecs.umich.edu        global instDecode, pclr, adr
3717188Sgblack@eecs.umich.edu        if useDest:
3727188Sgblack@eecs.umich.edu            dest = "rd"
3737188Sgblack@eecs.umich.edu        else:
3747188Sgblack@eecs.umich.edu            dest = "INTREG_ZERO"
3757188Sgblack@eecs.umich.edu        if useOp1:
3767188Sgblack@eecs.umich.edu            op1 = "rn"
3777188Sgblack@eecs.umich.edu        else:
3787188Sgblack@eecs.umich.edu            op1 = "INTREG_ZERO"
3797188Sgblack@eecs.umich.edu        substDict = { "className": mnem.capitalize(),
3807188Sgblack@eecs.umich.edu                      "opcode": opcode,
3817188Sgblack@eecs.umich.edu                      "dest": dest,
3827188Sgblack@eecs.umich.edu                      "op1": op1,
3837188Sgblack@eecs.umich.edu                      "adr": "",
3847188Sgblack@eecs.umich.edu                      "adrInst": "false" }
3857188Sgblack@eecs.umich.edu        if useDest:
3867188Sgblack@eecs.umich.edu            substDict["pclrInst"] = "true"
3877188Sgblack@eecs.umich.edu            substDict["pclr"] = pclr % substDict
3887188Sgblack@eecs.umich.edu        else:
3897188Sgblack@eecs.umich.edu            substDict["pclrInst"] = "false"
3907188Sgblack@eecs.umich.edu            substDict["pclr"] = ""
3917188Sgblack@eecs.umich.edu        return instDecode % substDict
3927185Sgblack@eecs.umich.edu
3937188Sgblack@eecs.umich.edu    def adrCode(opcode, mnem, add="1"):
3947188Sgblack@eecs.umich.edu        global instDecode, pclr, adr
3957188Sgblack@eecs.umich.edu        substDict = { "className": mnem.capitalize(),
3967188Sgblack@eecs.umich.edu                      "opcode": opcode,
3977188Sgblack@eecs.umich.edu                      "dest": "rd",
3987188Sgblack@eecs.umich.edu                      "op1": "rn",
3997188Sgblack@eecs.umich.edu                      "add": add,
4007188Sgblack@eecs.umich.edu                      "pclrInst": "true",
4017188Sgblack@eecs.umich.edu                      "adrInst": "true" }
4027188Sgblack@eecs.umich.edu        substDict["pclr"] = pclr % substDict
4037188Sgblack@eecs.umich.edu        substDict["adr"] = adr % substDict
4047188Sgblack@eecs.umich.edu        return instDecode % substDict
4057139Sgblack@eecs.umich.edu
4067139Sgblack@eecs.umich.edu    decode_block = '''
4077139Sgblack@eecs.umich.edu    {
4087139Sgblack@eecs.umich.edu        const bool setCc = (bits(machInst, 20) == 1);
4097139Sgblack@eecs.umich.edu        const uint32_t unrotated = bits(machInst, 7, 0);
4107139Sgblack@eecs.umich.edu        const uint32_t rotation = (bits(machInst, 11, 8) << 1);
4117139Sgblack@eecs.umich.edu        const bool rotC = (rotation != 0);
4127139Sgblack@eecs.umich.edu        const uint32_t imm = rotate_imm(unrotated, rotation);
4137139Sgblack@eecs.umich.edu        const IntRegIndex rd = (IntRegIndex)(uint32_t)RD;
4147139Sgblack@eecs.umich.edu        const IntRegIndex rn = (IntRegIndex)(uint32_t)RN;
4157139Sgblack@eecs.umich.edu        switch (OPCODE) {
4167139Sgblack@eecs.umich.edu    '''
4177139Sgblack@eecs.umich.edu    decode_block += instCode(0x0, "and")
4187139Sgblack@eecs.umich.edu    decode_block += instCode(0x1, "eor")
4197185Sgblack@eecs.umich.edu    decode_block += adrCode(0x2, "sub", add="(IntRegIndex)0")
4207139Sgblack@eecs.umich.edu    decode_block += instCode(0x3, "rsb")
4217185Sgblack@eecs.umich.edu    decode_block += adrCode(0x4, "add", add="(IntRegIndex)1")
4227139Sgblack@eecs.umich.edu    decode_block += instCode(0x5, "adc")
4237139Sgblack@eecs.umich.edu    decode_block += instCode(0x6, "sbc")
4247139Sgblack@eecs.umich.edu    decode_block += instCode(0x7, "rsc")
4257188Sgblack@eecs.umich.edu    decode_block += instCode(0x8, "tst", useDest = False)
4267188Sgblack@eecs.umich.edu    decode_block += instCode(0x9, "teq", useDest = False)
4277188Sgblack@eecs.umich.edu    decode_block += instCode(0xa, "cmp", useDest = False)
4287188Sgblack@eecs.umich.edu    decode_block += instCode(0xb, "cmn", useDest = False)
4297139Sgblack@eecs.umich.edu    decode_block += instCode(0xc, "orr")
4307188Sgblack@eecs.umich.edu    decode_block += instCode(0xd, "mov", useOp1 = False)
4317139Sgblack@eecs.umich.edu    decode_block += instCode(0xe, "bic")
4327188Sgblack@eecs.umich.edu    decode_block += instCode(0xf, "mvn", useOp1 = False)
4337139Sgblack@eecs.umich.edu    decode_block += '''
4347139Sgblack@eecs.umich.edu          default:
4357139Sgblack@eecs.umich.edu            return new Unknown(machInst);
4367139Sgblack@eecs.umich.edu        }
4377139Sgblack@eecs.umich.edu    }
4387139Sgblack@eecs.umich.edu    '''
4397139Sgblack@eecs.umich.edu}};
4407141Sgblack@eecs.umich.edu
4417195Sgblack@eecs.umich.edudef format ArmSatAddSub() {{
4427195Sgblack@eecs.umich.edu    decode_block = '''
4437195Sgblack@eecs.umich.edu    {
4447195Sgblack@eecs.umich.edu        IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
4457195Sgblack@eecs.umich.edu        IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
4467195Sgblack@eecs.umich.edu        IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
4477195Sgblack@eecs.umich.edu        switch (OPCODE) {
4487195Sgblack@eecs.umich.edu          case 0x8:
4497195Sgblack@eecs.umich.edu            return new QaddRegCc(machInst, rd, rm, rn, 0, LSL);
4507195Sgblack@eecs.umich.edu          case 0x9:
4517195Sgblack@eecs.umich.edu            return new QsubRegCc(machInst, rd, rm, rn, 0, LSL);
4527195Sgblack@eecs.umich.edu          case 0xa:
4537195Sgblack@eecs.umich.edu            return new QdaddRegCc(machInst, rd, rm, rn, 0, LSL);
4547195Sgblack@eecs.umich.edu          case 0xb:
4557195Sgblack@eecs.umich.edu            return new QdsubRegCc(machInst, rd, rm, rn, 0, LSL);
4567195Sgblack@eecs.umich.edu          default:
4577195Sgblack@eecs.umich.edu            return new Unknown(machInst);
4587195Sgblack@eecs.umich.edu        }
4597195Sgblack@eecs.umich.edu    }
4607195Sgblack@eecs.umich.edu    '''
4617195Sgblack@eecs.umich.edu}};
4627195Sgblack@eecs.umich.edu
4637213Sgblack@eecs.umich.edudef format Thumb32DataProcReg() {{
4647213Sgblack@eecs.umich.edu    decode_block = '''
4657213Sgblack@eecs.umich.edu    {
4667213Sgblack@eecs.umich.edu        const uint32_t op1 = bits(machInst, 23, 20);
4677213Sgblack@eecs.umich.edu        const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
4687213Sgblack@eecs.umich.edu        const uint32_t op2 = bits(machInst, 7, 4);
4697213Sgblack@eecs.umich.edu        if (bits(op1, 3) != 1) {
4707213Sgblack@eecs.umich.edu            if (op2 == 0) {
4717213Sgblack@eecs.umich.edu                IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
4727213Sgblack@eecs.umich.edu                IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
4737213Sgblack@eecs.umich.edu                switch (bits(op1, 2, 0)) {
4747213Sgblack@eecs.umich.edu                  case 0x0:
4757213Sgblack@eecs.umich.edu                    return new MovRegReg(machInst, rd,
4767213Sgblack@eecs.umich.edu                            INTREG_ZERO, rn, rm, LSL);
4777213Sgblack@eecs.umich.edu                  case 0x1:
4787213Sgblack@eecs.umich.edu                    return new MovRegRegCc(machInst, rd,
4797213Sgblack@eecs.umich.edu                            INTREG_ZERO, rn, rm, LSL);
4807213Sgblack@eecs.umich.edu                  case 0x2:
4817213Sgblack@eecs.umich.edu                    return new MovRegReg(machInst, rd,
4827213Sgblack@eecs.umich.edu                            INTREG_ZERO, rn, rm, LSR);
4837213Sgblack@eecs.umich.edu                  case 0x3:
4847213Sgblack@eecs.umich.edu                    return new MovRegRegCc(machInst, rd,
4857213Sgblack@eecs.umich.edu                            INTREG_ZERO, rn, rm, LSR);
4867213Sgblack@eecs.umich.edu                  case 0x4:
4877213Sgblack@eecs.umich.edu                    return new MovRegReg(machInst, rd,
4887213Sgblack@eecs.umich.edu                            INTREG_ZERO, rn, rm, ASR);
4897213Sgblack@eecs.umich.edu                  case 0x5:
4907213Sgblack@eecs.umich.edu                    return new MovRegRegCc(machInst, rd,
4917213Sgblack@eecs.umich.edu                            INTREG_ZERO, rn, rm, ASR);
4927213Sgblack@eecs.umich.edu                  case 0x6:
4937213Sgblack@eecs.umich.edu                    return new MovRegReg(machInst, rd,
4947213Sgblack@eecs.umich.edu                            INTREG_ZERO, rn, rm, ROR);
4957213Sgblack@eecs.umich.edu                  case 0x7:
4967213Sgblack@eecs.umich.edu                    return new MovRegRegCc(machInst, rd,
4977213Sgblack@eecs.umich.edu                            INTREG_ZERO, rn, rm, ROR);
4987213Sgblack@eecs.umich.edu                }
4997213Sgblack@eecs.umich.edu            }
5007213Sgblack@eecs.umich.edu            switch (bits(op1, 2, 0)) {
5017213Sgblack@eecs.umich.edu              case 0x0:
5027213Sgblack@eecs.umich.edu                if (rn == 0xf) {
5037213Sgblack@eecs.umich.edu                    return new WarnUnimplemented("sxth", machInst);
5047213Sgblack@eecs.umich.edu                } else {
5057213Sgblack@eecs.umich.edu                    return new WarnUnimplemented("sxtah", machInst);
5067213Sgblack@eecs.umich.edu                }
5077213Sgblack@eecs.umich.edu              case 0x1:
5087213Sgblack@eecs.umich.edu                if (rn == 0xf) {
5097213Sgblack@eecs.umich.edu                    return new WarnUnimplemented("uxth", machInst);
5107213Sgblack@eecs.umich.edu                } else {
5117213Sgblack@eecs.umich.edu                    return new WarnUnimplemented("uxtah", machInst);
5127213Sgblack@eecs.umich.edu                }
5137213Sgblack@eecs.umich.edu              case 0x2:
5147213Sgblack@eecs.umich.edu                if (rn == 0xf) {
5157213Sgblack@eecs.umich.edu                    return new WarnUnimplemented("sxtb16", machInst);
5167213Sgblack@eecs.umich.edu                } else {
5177213Sgblack@eecs.umich.edu                    return new WarnUnimplemented("sxtab16", machInst);
5187213Sgblack@eecs.umich.edu                }
5197213Sgblack@eecs.umich.edu              case 0x3:
5207213Sgblack@eecs.umich.edu                if (rn == 0xf) {
5217213Sgblack@eecs.umich.edu                    return new WarnUnimplemented("uxtb16", machInst);
5227213Sgblack@eecs.umich.edu                } else {
5237213Sgblack@eecs.umich.edu                    return new WarnUnimplemented("uxtab16", machInst);
5247213Sgblack@eecs.umich.edu                }
5257213Sgblack@eecs.umich.edu              case 0x4:
5267213Sgblack@eecs.umich.edu                if (rn == 0xf) {
5277213Sgblack@eecs.umich.edu                    return new WarnUnimplemented("sxtb", machInst);
5287213Sgblack@eecs.umich.edu                } else {
5297213Sgblack@eecs.umich.edu                    return new WarnUnimplemented("sxtab", machInst);
5307213Sgblack@eecs.umich.edu                }
5317213Sgblack@eecs.umich.edu              case 0x5:
5327213Sgblack@eecs.umich.edu                if (rn == 0xf) {
5337213Sgblack@eecs.umich.edu                    return new WarnUnimplemented("uxtb", machInst);
5347213Sgblack@eecs.umich.edu                } else {
5357213Sgblack@eecs.umich.edu                    return new WarnUnimplemented("uxtab", machInst);
5367213Sgblack@eecs.umich.edu                }
5377213Sgblack@eecs.umich.edu              default:
5387213Sgblack@eecs.umich.edu                return new Unknown(machInst);
5397213Sgblack@eecs.umich.edu            }
5407213Sgblack@eecs.umich.edu        } else {
5417213Sgblack@eecs.umich.edu            if (bits(op2, 3) == 0) {
5427220Sgblack@eecs.umich.edu                const IntRegIndex rd =
5437220Sgblack@eecs.umich.edu                    (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
5447220Sgblack@eecs.umich.edu                const IntRegIndex rm =
5457220Sgblack@eecs.umich.edu                    (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
5467213Sgblack@eecs.umich.edu                if (bits(op2, 2) == 0x0) {
5477213Sgblack@eecs.umich.edu                    const uint32_t op1 = bits(machInst, 22, 20);
5487213Sgblack@eecs.umich.edu                    const uint32_t op2 = bits(machInst, 5, 4);
5497213Sgblack@eecs.umich.edu                    switch (op2) {
5507213Sgblack@eecs.umich.edu                      case 0x0:
5517213Sgblack@eecs.umich.edu                        switch (op1) {
5527213Sgblack@eecs.umich.edu                          case 0x1:
5537216Sgblack@eecs.umich.edu                            return new Sadd16RegCc(machInst, rd,
5547216Sgblack@eecs.umich.edu                                                   rn, rm, 0, LSL);
5557213Sgblack@eecs.umich.edu                          case 0x2:
5567224Sgblack@eecs.umich.edu                            return new SasxRegCc(machInst, rd,
5577224Sgblack@eecs.umich.edu                                                 rn, rm, 0, LSL);
5587213Sgblack@eecs.umich.edu                          case 0x6:
5597224Sgblack@eecs.umich.edu                            return new SsaxRegCc(machInst, rd,
5607224Sgblack@eecs.umich.edu                                                 rn, rm, 0, LSL);
5617213Sgblack@eecs.umich.edu                          case 0x5:
5627218Sgblack@eecs.umich.edu                            return new Ssub16RegCc(machInst, rd,
5637218Sgblack@eecs.umich.edu                                                   rn, rm, 0, LSL);
5647213Sgblack@eecs.umich.edu                          case 0x0:
5657216Sgblack@eecs.umich.edu                            return new Sadd8RegCc(machInst, rd,
5667216Sgblack@eecs.umich.edu                                                  rn, rm, 0, LSL);
5677213Sgblack@eecs.umich.edu                          case 0x4:
5687218Sgblack@eecs.umich.edu                            return new Ssub8RegCc(machInst, rd,
5697218Sgblack@eecs.umich.edu                                                  rn, rm, 0, LSL);
5707213Sgblack@eecs.umich.edu                        }
5717213Sgblack@eecs.umich.edu                        break;
5727213Sgblack@eecs.umich.edu                      case 0x1:
5737216Sgblack@eecs.umich.edu                        switch (op1) {
5747216Sgblack@eecs.umich.edu                          case 0x1:
5757216Sgblack@eecs.umich.edu                            return new Qadd16Reg(machInst, rd, rn, rm, 0, LSL);
5767216Sgblack@eecs.umich.edu                          case 0x2:
5777216Sgblack@eecs.umich.edu                            return new QasxReg(machInst, rd, rn, rm, 0, LSL);
5787216Sgblack@eecs.umich.edu                          case 0x6:
5797216Sgblack@eecs.umich.edu                            return new QsaxReg(machInst, rd, rn, rm, 0, LSL);
5807216Sgblack@eecs.umich.edu                          case 0x5:
5817216Sgblack@eecs.umich.edu                            return new Qsub16Reg(machInst, rd, rn, rm, 0, LSL);
5827216Sgblack@eecs.umich.edu                          case 0x0:
5837216Sgblack@eecs.umich.edu                            return new Qadd8Reg(machInst, rd, rn, rm, 0, LSL);
5847216Sgblack@eecs.umich.edu                          case 0x4:
5857216Sgblack@eecs.umich.edu                            return new Qsub8Reg(machInst, rd, rn, rm, 0, LSL);
5867213Sgblack@eecs.umich.edu                        }
5877213Sgblack@eecs.umich.edu                        break;
5887213Sgblack@eecs.umich.edu                      case 0x2:
5897213Sgblack@eecs.umich.edu                        switch (op1) {
5907213Sgblack@eecs.umich.edu                          case 0x1:
5917213Sgblack@eecs.umich.edu                            return new WarnUnimplemented("shadd16", machInst);
5927213Sgblack@eecs.umich.edu                          case 0x2:
5937213Sgblack@eecs.umich.edu                            return new WarnUnimplemented("shasx", machInst);
5947213Sgblack@eecs.umich.edu                          case 0x6:
5957213Sgblack@eecs.umich.edu                            return new WarnUnimplemented("shsax", machInst);
5967213Sgblack@eecs.umich.edu                          case 0x5:
5977213Sgblack@eecs.umich.edu                            return new WarnUnimplemented("shsub16", machInst);
5987213Sgblack@eecs.umich.edu                          case 0x0:
5997213Sgblack@eecs.umich.edu                            return new WarnUnimplemented("shadd8", machInst);
6007213Sgblack@eecs.umich.edu                          case 0x4:
6017213Sgblack@eecs.umich.edu                            return new WarnUnimplemented("shsub8", machInst);
6027213Sgblack@eecs.umich.edu                        }
6037213Sgblack@eecs.umich.edu                        break;
6047213Sgblack@eecs.umich.edu                    }
6057213Sgblack@eecs.umich.edu                } else {
6067213Sgblack@eecs.umich.edu                    const uint32_t op1 = bits(machInst, 22, 20);
6077213Sgblack@eecs.umich.edu                    const uint32_t op2 = bits(machInst, 5, 4);
6087213Sgblack@eecs.umich.edu                    switch (op2) {
6097213Sgblack@eecs.umich.edu                      case 0x0:
6107213Sgblack@eecs.umich.edu                        switch (op1) {
6117213Sgblack@eecs.umich.edu                          case 0x1:
6127222Sgblack@eecs.umich.edu                            return new Uadd16RegCc(machInst, rd,
6137222Sgblack@eecs.umich.edu                                                   rn, rm, 0, LSL);
6147213Sgblack@eecs.umich.edu                          case 0x2:
6157222Sgblack@eecs.umich.edu                            return new UasxRegCc(machInst, rd,
6167222Sgblack@eecs.umich.edu                                                 rn, rm, 0, LSL);
6177213Sgblack@eecs.umich.edu                          case 0x6:
6187222Sgblack@eecs.umich.edu                            return new UsaxRegCc(machInst, rd,
6197222Sgblack@eecs.umich.edu                                                 rn, rm, 0, LSL);
6207213Sgblack@eecs.umich.edu                          case 0x5:
6217222Sgblack@eecs.umich.edu                            return new Usub16RegCc(machInst, rd,
6227222Sgblack@eecs.umich.edu                                                   rn, rm, 0, LSL);
6237213Sgblack@eecs.umich.edu                          case 0x0:
6247222Sgblack@eecs.umich.edu                            return new Uadd8RegCc(machInst, rd,
6257222Sgblack@eecs.umich.edu                                                  rn, rm, 0, LSL);
6267213Sgblack@eecs.umich.edu                          case 0x4:
6277222Sgblack@eecs.umich.edu                            return new Usub8RegCc(machInst, rd,
6287222Sgblack@eecs.umich.edu                                                  rn, rm, 0, LSL);
6297213Sgblack@eecs.umich.edu                        }
6307213Sgblack@eecs.umich.edu                        break;
6317213Sgblack@eecs.umich.edu                      case 0x1:
6327213Sgblack@eecs.umich.edu                        switch (op1) {
6337213Sgblack@eecs.umich.edu                          case 0x1:
6347220Sgblack@eecs.umich.edu                            return new Uqadd16Reg(machInst, rd, rn, rm, 0, LSL);
6357213Sgblack@eecs.umich.edu                          case 0x2:
6367220Sgblack@eecs.umich.edu                            return new UqasxReg(machInst, rd, rn, rm, 0, LSL);
6377213Sgblack@eecs.umich.edu                          case 0x6:
6387220Sgblack@eecs.umich.edu                            return new UqsaxReg(machInst, rd, rn, rm, 0, LSL);
6397213Sgblack@eecs.umich.edu                          case 0x5:
6407220Sgblack@eecs.umich.edu                            return new Uqsub16Reg(machInst, rd, rn, rm, 0, LSL);
6417213Sgblack@eecs.umich.edu                          case 0x0:
6427220Sgblack@eecs.umich.edu                            return new Uqadd8Reg(machInst, rd, rn, rm, 0, LSL);
6437213Sgblack@eecs.umich.edu                          case 0x4:
6447220Sgblack@eecs.umich.edu                            return new Uqsub8Reg(machInst, rd, rn, rm, 0, LSL);
6457213Sgblack@eecs.umich.edu                        }
6467213Sgblack@eecs.umich.edu                        break;
6477213Sgblack@eecs.umich.edu                      case 0x2:
6487213Sgblack@eecs.umich.edu                        switch (op1) {
6497213Sgblack@eecs.umich.edu                          case 0x1:
6507213Sgblack@eecs.umich.edu                            return new WarnUnimplemented("uhadd16", machInst);
6517213Sgblack@eecs.umich.edu                          case 0x2:
6527213Sgblack@eecs.umich.edu                            return new WarnUnimplemented("uhasx", machInst);
6537213Sgblack@eecs.umich.edu                          case 0x6:
6547213Sgblack@eecs.umich.edu                            return new WarnUnimplemented("uhsax", machInst);
6557213Sgblack@eecs.umich.edu                          case 0x5:
6567213Sgblack@eecs.umich.edu                            return new WarnUnimplemented("uhsub16", machInst);
6577213Sgblack@eecs.umich.edu                          case 0x0:
6587213Sgblack@eecs.umich.edu                            return new WarnUnimplemented("uhadd8", machInst);
6597213Sgblack@eecs.umich.edu                          case 0x4:
6607213Sgblack@eecs.umich.edu                            return new WarnUnimplemented("uhsub8", machInst);
6617213Sgblack@eecs.umich.edu                        }
6627213Sgblack@eecs.umich.edu                        break;
6637213Sgblack@eecs.umich.edu                    }
6647213Sgblack@eecs.umich.edu                }
6657213Sgblack@eecs.umich.edu            } else if (bits(op1, 3, 2) == 0x2 && bits(op2, 3, 2) == 0x2) {
6667213Sgblack@eecs.umich.edu                const uint32_t op1 = bits(machInst, 21, 20);
6677213Sgblack@eecs.umich.edu                const uint32_t op2 = bits(machInst, 5, 4);
6687213Sgblack@eecs.umich.edu                switch (op1) {
6697213Sgblack@eecs.umich.edu                  case 0x0:
6707213Sgblack@eecs.umich.edu                    {
6717213Sgblack@eecs.umich.edu                        IntRegIndex rd =
6727213Sgblack@eecs.umich.edu                            (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
6737213Sgblack@eecs.umich.edu                        IntRegIndex rm =
6747213Sgblack@eecs.umich.edu                            (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
6757213Sgblack@eecs.umich.edu                        switch (op2) {
6767213Sgblack@eecs.umich.edu                          case 0x0:
6777213Sgblack@eecs.umich.edu                            return new QaddRegCc(machInst, rd,
6787213Sgblack@eecs.umich.edu                                                 rm, rn, 0, LSL);
6797213Sgblack@eecs.umich.edu                          case 0x1:
6807213Sgblack@eecs.umich.edu                            return new QdaddRegCc(machInst, rd,
6817213Sgblack@eecs.umich.edu                                                  rm, rn, 0, LSL);
6827213Sgblack@eecs.umich.edu                          case 0x2:
6837213Sgblack@eecs.umich.edu                            return new QsubRegCc(machInst, rd,
6847213Sgblack@eecs.umich.edu                                                 rm, rn, 0, LSL);
6857213Sgblack@eecs.umich.edu                          case 0x3:
6867213Sgblack@eecs.umich.edu                            return new QdsubRegCc(machInst, rd,
6877213Sgblack@eecs.umich.edu                                                  rm, rn, 0, LSL);
6887213Sgblack@eecs.umich.edu                        }
6897213Sgblack@eecs.umich.edu                    }
6907213Sgblack@eecs.umich.edu                    break;
6917213Sgblack@eecs.umich.edu                  case 0x1:
6927213Sgblack@eecs.umich.edu                    {
6937213Sgblack@eecs.umich.edu                        IntRegIndex rd =
6947213Sgblack@eecs.umich.edu                            (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
6957213Sgblack@eecs.umich.edu                        IntRegIndex rm = rn;
6967213Sgblack@eecs.umich.edu                        switch (op2) {
6977213Sgblack@eecs.umich.edu                          case 0x0:
6987213Sgblack@eecs.umich.edu                            return new Rev(machInst, rd, rm);
6997213Sgblack@eecs.umich.edu                          case 0x1:
7007213Sgblack@eecs.umich.edu                            return new Rev16(machInst, rd, rm);
7017213Sgblack@eecs.umich.edu                          case 0x2:
7027213Sgblack@eecs.umich.edu                            return new WarnUnimplemented("rbit", machInst);
7037213Sgblack@eecs.umich.edu                          case 0x3:
7047213Sgblack@eecs.umich.edu                            return new Revsh(machInst, rd, rm);
7057213Sgblack@eecs.umich.edu                        }
7067213Sgblack@eecs.umich.edu                    }
7077213Sgblack@eecs.umich.edu                    break;
7087213Sgblack@eecs.umich.edu                  case 0x2:
7097213Sgblack@eecs.umich.edu                    if (op2 == 0) {
7107213Sgblack@eecs.umich.edu                        return new WarnUnimplemented("sel", machInst);
7117213Sgblack@eecs.umich.edu                    }
7127213Sgblack@eecs.umich.edu                    break;
7137213Sgblack@eecs.umich.edu                  case 0x3:
7147213Sgblack@eecs.umich.edu                    if (op2 == 0) {
7157213Sgblack@eecs.umich.edu                        return new WarnUnimplemented("clz", machInst);
7167213Sgblack@eecs.umich.edu                    }
7177213Sgblack@eecs.umich.edu                }
7187213Sgblack@eecs.umich.edu            }
7197213Sgblack@eecs.umich.edu            return new Unknown(machInst);
7207213Sgblack@eecs.umich.edu        }
7217213Sgblack@eecs.umich.edu    }
7227213Sgblack@eecs.umich.edu    '''
7237213Sgblack@eecs.umich.edu}};
7247213Sgblack@eecs.umich.edu
7257141Sgblack@eecs.umich.edudef format Thumb16ShiftAddSubMoveCmp() {{
7267141Sgblack@eecs.umich.edu    decode_block = '''
7277141Sgblack@eecs.umich.edu    {
7287141Sgblack@eecs.umich.edu        const uint32_t imm5 = bits(machInst, 10, 6);
7297141Sgblack@eecs.umich.edu        const uint32_t imm3 = bits(machInst, 8, 6);
7307141Sgblack@eecs.umich.edu        const uint32_t imm8 = bits(machInst, 7, 0);
7317141Sgblack@eecs.umich.edu        const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 2, 0);
7327141Sgblack@eecs.umich.edu        const IntRegIndex rd8 = (IntRegIndex)(uint32_t)bits(machInst, 10, 8);
7337141Sgblack@eecs.umich.edu        const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 5, 3);
7347141Sgblack@eecs.umich.edu        const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 8, 6);
7357141Sgblack@eecs.umich.edu        switch (bits(machInst, 13, 11)) {
7367141Sgblack@eecs.umich.edu          case 0x0: // lsl
7377183Sgblack@eecs.umich.edu            return new MovRegCc(machInst, rd, INTREG_ZERO, rn, imm5, LSL);
7387141Sgblack@eecs.umich.edu          case 0x1: // lsr
7397183Sgblack@eecs.umich.edu            return new MovRegCc(machInst, rd, INTREG_ZERO, rn, imm5, LSR);
7407141Sgblack@eecs.umich.edu          case 0x2: // asr
7417183Sgblack@eecs.umich.edu            return new MovRegCc(machInst, rd, INTREG_ZERO, rn, imm5, ASR);
7427141Sgblack@eecs.umich.edu          case 0x3:
7437141Sgblack@eecs.umich.edu            switch (bits(machInst, 10, 9)) {
7447141Sgblack@eecs.umich.edu              case 0x0:
7457183Sgblack@eecs.umich.edu                return new AddRegCc(machInst, rd, rn, rm, 0, LSL);
7467141Sgblack@eecs.umich.edu              case 0x1:
7477183Sgblack@eecs.umich.edu                return new SubRegCc(machInst, rd, rn, rm, 0, LSL);
7487141Sgblack@eecs.umich.edu              case 0x2:
7497183Sgblack@eecs.umich.edu                return new AddImmCc(machInst, rd, rn, imm3, true);
7507141Sgblack@eecs.umich.edu              case 0x3:
7517183Sgblack@eecs.umich.edu                return new SubImmCc(machInst, rd, rn, imm3, true);
7527141Sgblack@eecs.umich.edu            }
7537141Sgblack@eecs.umich.edu          case 0x4:
7547183Sgblack@eecs.umich.edu            return new MovImmCc(machInst, rd8, INTREG_ZERO, imm8, false);
7557141Sgblack@eecs.umich.edu          case 0x5:
7567146Sgblack@eecs.umich.edu            return new CmpImmCc(machInst, INTREG_ZERO, rd8, imm8, true);
7577141Sgblack@eecs.umich.edu          case 0x6:
7587183Sgblack@eecs.umich.edu            return new AddImmCc(machInst, rd8, rd8, imm8, true);
7597141Sgblack@eecs.umich.edu          case 0x7:
7607183Sgblack@eecs.umich.edu            return new SubImmCc(machInst, rd8, rd8, imm8, true);
7617141Sgblack@eecs.umich.edu        }
7627141Sgblack@eecs.umich.edu    }
7637141Sgblack@eecs.umich.edu    '''
7647141Sgblack@eecs.umich.edu}};
7657141Sgblack@eecs.umich.edu
7667141Sgblack@eecs.umich.edudef format Thumb16DataProcessing() {{
7677141Sgblack@eecs.umich.edu    decode_block = '''
7687141Sgblack@eecs.umich.edu    {
7697141Sgblack@eecs.umich.edu        const IntRegIndex rdn = (IntRegIndex)(uint32_t)bits(machInst, 2, 0);
7707141Sgblack@eecs.umich.edu        const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 5, 3);
7717141Sgblack@eecs.umich.edu        switch (bits(machInst, 9, 6)) {
7727141Sgblack@eecs.umich.edu          case 0x0:
7737183Sgblack@eecs.umich.edu            return new AndRegCc(machInst, rdn, rdn, rm, 0, LSL);
7747141Sgblack@eecs.umich.edu          case 0x1:
7757183Sgblack@eecs.umich.edu            return new EorRegCc(machInst, rdn, rdn, rm, 0, LSL);
7767141Sgblack@eecs.umich.edu          case 0x2: //lsl
7777183Sgblack@eecs.umich.edu            return new MovRegRegCc(machInst, rdn, INTREG_ZERO, rdn, rm, LSL);
7787141Sgblack@eecs.umich.edu          case 0x3: //lsr
7797183Sgblack@eecs.umich.edu            return new MovRegRegCc(machInst, rdn, INTREG_ZERO, rdn, rm, LSR);
7807141Sgblack@eecs.umich.edu          case 0x4: //asr
7817183Sgblack@eecs.umich.edu            return new MovRegRegCc(machInst, rdn, INTREG_ZERO, rdn, rm, ASR);
7827141Sgblack@eecs.umich.edu          case 0x5:
7837183Sgblack@eecs.umich.edu            return new AdcRegCc(machInst, rdn, rdn, rm, 0, LSL);
7847141Sgblack@eecs.umich.edu          case 0x6:
7857183Sgblack@eecs.umich.edu            return new SbcRegCc(machInst, rdn, rdn, rm, 0, LSL);
7867141Sgblack@eecs.umich.edu          case 0x7: // ror
7877183Sgblack@eecs.umich.edu            return new MovRegRegCc(machInst, rdn, INTREG_ZERO, rdn, rm, ROR);
7887141Sgblack@eecs.umich.edu          case 0x8:
7897183Sgblack@eecs.umich.edu            return new TstRegCc(machInst, INTREG_ZERO, rdn, rm, 0, LSL);
7907141Sgblack@eecs.umich.edu          case 0x9:
7917183Sgblack@eecs.umich.edu            return new RsbImmCc(machInst, rdn, rm, 0, true);
7927141Sgblack@eecs.umich.edu          case 0xa:
7937183Sgblack@eecs.umich.edu            return new CmpRegCc(machInst, INTREG_ZERO, rdn, rm, 0, LSL);
7947141Sgblack@eecs.umich.edu          case 0xb:
7957183Sgblack@eecs.umich.edu            return new CmnRegCc(machInst, INTREG_ZERO, rdn, rm, 0, LSL);
7967141Sgblack@eecs.umich.edu          case 0xc:
7977183Sgblack@eecs.umich.edu            return new OrrRegCc(machInst, rdn, rdn, rm, 0, LSL);
7987141Sgblack@eecs.umich.edu          case 0xd:
7997183Sgblack@eecs.umich.edu            return new MulCc(machInst, rdn, rm, rdn);
8007141Sgblack@eecs.umich.edu          case 0xe:
8017183Sgblack@eecs.umich.edu            return new BicRegCc(machInst, rdn, rdn, rm, 0, LSL);
8027141Sgblack@eecs.umich.edu          case 0xf:
8037183Sgblack@eecs.umich.edu            return new MvnRegCc(machInst, rdn, INTREG_ZERO, rm, 0, LSL);
8047141Sgblack@eecs.umich.edu        }
8057141Sgblack@eecs.umich.edu    }
8067141Sgblack@eecs.umich.edu    '''
8077141Sgblack@eecs.umich.edu}};
8087141Sgblack@eecs.umich.edu
8097141Sgblack@eecs.umich.edudef format Thumb16SpecDataAndBx() {{
8107141Sgblack@eecs.umich.edu    decode_block = '''
8117141Sgblack@eecs.umich.edu    {
8127141Sgblack@eecs.umich.edu        const IntRegIndex rdn =
8137141Sgblack@eecs.umich.edu            (IntRegIndex)(uint32_t)(bits(machInst, 2, 0) |
8147141Sgblack@eecs.umich.edu                                    (bits(machInst, 7) << 3));
8157141Sgblack@eecs.umich.edu        const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 6, 3);
8167141Sgblack@eecs.umich.edu        switch (bits(machInst, 9, 8)) {
8177141Sgblack@eecs.umich.edu          case 0x0:
8187146Sgblack@eecs.umich.edu            return new AddReg(machInst, rdn, rdn, rm, 0, LSL);
8197141Sgblack@eecs.umich.edu          case 0x1:
8207183Sgblack@eecs.umich.edu            return new CmpRegCc(machInst, INTREG_ZERO, rdn, rm, 0, LSL);
8217141Sgblack@eecs.umich.edu          case 0x2:
8227146Sgblack@eecs.umich.edu            return new MovReg(machInst, rdn, INTREG_ZERO, rm, 0, LSL);
8237141Sgblack@eecs.umich.edu          case 0x3:
8247154Sgblack@eecs.umich.edu            if (bits(machInst, 7) == 0) {
8257154Sgblack@eecs.umich.edu                return new BxReg(machInst,
8267154Sgblack@eecs.umich.edu                                 (IntRegIndex)(uint32_t)bits(machInst, 6, 3),
8277154Sgblack@eecs.umich.edu                                 COND_UC);
8287154Sgblack@eecs.umich.edu            } else {
8297154Sgblack@eecs.umich.edu                return new BlxReg(machInst,
8307154Sgblack@eecs.umich.edu                                  (IntRegIndex)(uint32_t)bits(machInst, 6, 3),
8317154Sgblack@eecs.umich.edu                                  COND_UC);
8327154Sgblack@eecs.umich.edu            }
8337141Sgblack@eecs.umich.edu        }
8347141Sgblack@eecs.umich.edu    }
8357141Sgblack@eecs.umich.edu    '''
8367141Sgblack@eecs.umich.edu}};
8377141Sgblack@eecs.umich.edu
8387141Sgblack@eecs.umich.edudef format Thumb16Adr() {{
8397141Sgblack@eecs.umich.edu    decode_block = '''
8407141Sgblack@eecs.umich.edu    {
8417141Sgblack@eecs.umich.edu        const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 10, 8);
8427141Sgblack@eecs.umich.edu        const uint32_t imm8 = bits(machInst, 7, 0) << 2;
8437185Sgblack@eecs.umich.edu        return new AdrImm(machInst, rd, (IntRegIndex)1, imm8, false);
8447141Sgblack@eecs.umich.edu    }
8457141Sgblack@eecs.umich.edu    '''
8467141Sgblack@eecs.umich.edu}};
8477141Sgblack@eecs.umich.edu
8487141Sgblack@eecs.umich.edudef format Thumb16AddSp() {{
8497141Sgblack@eecs.umich.edu    decode_block = '''
8507141Sgblack@eecs.umich.edu    {
8517141Sgblack@eecs.umich.edu        const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 10, 8);
8527141Sgblack@eecs.umich.edu        const uint32_t imm8 = bits(machInst, 7, 0) << 2;
8537146Sgblack@eecs.umich.edu        return new AddImm(machInst, rd, INTREG_SP, imm8, true);
8547141Sgblack@eecs.umich.edu    }
8557141Sgblack@eecs.umich.edu    '''
8567141Sgblack@eecs.umich.edu}};
8577141Sgblack@eecs.umich.edu
8587141Sgblack@eecs.umich.edudef format Thumb16Misc() {{
8597141Sgblack@eecs.umich.edu    decode_block = '''
8607141Sgblack@eecs.umich.edu    {
8617141Sgblack@eecs.umich.edu        switch (bits(machInst, 11, 8)) {
8627141Sgblack@eecs.umich.edu          case 0x0:
8637141Sgblack@eecs.umich.edu            if (bits(machInst, 7)) {
8647146Sgblack@eecs.umich.edu                return new SubImm(machInst, INTREG_SP, INTREG_SP,
8657141Sgblack@eecs.umich.edu                                   bits(machInst, 6, 0) << 2, true);
8667141Sgblack@eecs.umich.edu            } else {
8677146Sgblack@eecs.umich.edu                return new AddImm(machInst, INTREG_SP, INTREG_SP,
8687141Sgblack@eecs.umich.edu                                   bits(machInst, 6, 0) << 2, true);
8697141Sgblack@eecs.umich.edu            }
8707141Sgblack@eecs.umich.edu          case 0x1:
8717154Sgblack@eecs.umich.edu            return new Cbz(machInst,
8727154Sgblack@eecs.umich.edu                           (bits(machInst, 9) << 6) |
8737154Sgblack@eecs.umich.edu                           (bits(machInst, 7, 3) << 1),
8747154Sgblack@eecs.umich.edu                           (IntRegIndex)(uint32_t)bits(machInst, 2, 0));
8757141Sgblack@eecs.umich.edu          case 0x2:
8767141Sgblack@eecs.umich.edu            switch (bits(machInst, 7, 6)) {
8777141Sgblack@eecs.umich.edu              case 0x0:
8787141Sgblack@eecs.umich.edu                return new WarnUnimplemented("sxth", machInst);
8797141Sgblack@eecs.umich.edu              case 0x1:
8807141Sgblack@eecs.umich.edu                return new WarnUnimplemented("sxtb", machInst);
8817141Sgblack@eecs.umich.edu              case 0x2:
8827141Sgblack@eecs.umich.edu                return new WarnUnimplemented("uxth", machInst);
8837141Sgblack@eecs.umich.edu              case 0x3:
8847141Sgblack@eecs.umich.edu                return new WarnUnimplemented("uxtb", machInst);
8857141Sgblack@eecs.umich.edu            }
8867141Sgblack@eecs.umich.edu          case 0x3:
8877154Sgblack@eecs.umich.edu            return new Cbz(machInst,
8887154Sgblack@eecs.umich.edu                           (bits(machInst, 9) << 6) |
8897154Sgblack@eecs.umich.edu                           (bits(machInst, 7, 3) << 1),
8907154Sgblack@eecs.umich.edu                           (IntRegIndex)(uint32_t)bits(machInst, 2, 0));
8917141Sgblack@eecs.umich.edu          case 0x4:
8927141Sgblack@eecs.umich.edu          case 0x5:
8937201Sgblack@eecs.umich.edu            {
8947201Sgblack@eecs.umich.edu                const uint32_t m = bits(machInst, 8);
8957201Sgblack@eecs.umich.edu                const uint32_t regList = bits(machInst, 7, 0) | (m << 14);
8967201Sgblack@eecs.umich.edu                return new LdmStm(machInst, INTREG_SP, false, false, false,
8977201Sgblack@eecs.umich.edu                                  true, false, regList);
8987201Sgblack@eecs.umich.edu            }
8997141Sgblack@eecs.umich.edu          case 0x6:
9007141Sgblack@eecs.umich.edu            {
9017141Sgblack@eecs.umich.edu                const uint32_t opBits = bits(machInst, 7, 5);
9027141Sgblack@eecs.umich.edu                if (opBits == 2) {
9037141Sgblack@eecs.umich.edu                    return new WarnUnimplemented("setend", machInst);
9047141Sgblack@eecs.umich.edu                } else if (opBits == 3) {
9057141Sgblack@eecs.umich.edu                    return new WarnUnimplemented("cps", machInst);
9067141Sgblack@eecs.umich.edu                }
9077141Sgblack@eecs.umich.edu            }
9087141Sgblack@eecs.umich.edu          case 0x9:
9097154Sgblack@eecs.umich.edu            return new Cbnz(machInst,
9107154Sgblack@eecs.umich.edu                            (bits(machInst, 9) << 6) |
9117154Sgblack@eecs.umich.edu                            (bits(machInst, 7, 3) << 1),
9127154Sgblack@eecs.umich.edu                            (IntRegIndex)(uint32_t)bits(machInst, 2, 0));
9137141Sgblack@eecs.umich.edu          case 0xa:
9147212Sgblack@eecs.umich.edu            {
9157212Sgblack@eecs.umich.edu                IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 2, 0);
9167212Sgblack@eecs.umich.edu                IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 5, 3);
9177212Sgblack@eecs.umich.edu                switch (bits(machInst, 7, 6)) {
9187212Sgblack@eecs.umich.edu                  case 0x0:
9197212Sgblack@eecs.umich.edu                    return new Rev(machInst, rd, rm);
9207212Sgblack@eecs.umich.edu                  case 0x1:
9217212Sgblack@eecs.umich.edu                    return new Rev16(machInst, rd, rm);
9227212Sgblack@eecs.umich.edu                  case 0x3:
9237212Sgblack@eecs.umich.edu                    return new Revsh(machInst, rd, rm);
9247212Sgblack@eecs.umich.edu                  default:
9257212Sgblack@eecs.umich.edu                    break;
9267212Sgblack@eecs.umich.edu                }
9277141Sgblack@eecs.umich.edu            }
9287141Sgblack@eecs.umich.edu            break;
9297141Sgblack@eecs.umich.edu          case 0xb:
9307154Sgblack@eecs.umich.edu            return new Cbnz(machInst,
9317154Sgblack@eecs.umich.edu                            (bits(machInst, 9) << 6) |
9327154Sgblack@eecs.umich.edu                            (bits(machInst, 7, 3) << 1),
9337154Sgblack@eecs.umich.edu                            (IntRegIndex)(uint32_t)bits(machInst, 2, 0));
9347141Sgblack@eecs.umich.edu          case 0xc:
9357141Sgblack@eecs.umich.edu          case 0xd:
9367201Sgblack@eecs.umich.edu            {
9377201Sgblack@eecs.umich.edu                const uint32_t p = bits(machInst, 8);
9387201Sgblack@eecs.umich.edu                const uint32_t regList = bits(machInst, 7, 0) | (p << 15);
9397201Sgblack@eecs.umich.edu                return new LdmStm(machInst, INTREG_SP, true, true, false,
9407201Sgblack@eecs.umich.edu                                  true, true, regList);
9417201Sgblack@eecs.umich.edu            }
9427141Sgblack@eecs.umich.edu          case 0xe:
9437141Sgblack@eecs.umich.edu            return new WarnUnimplemented("bkpt", machInst);
9447141Sgblack@eecs.umich.edu          case 0xf:
9457141Sgblack@eecs.umich.edu            if (bits(machInst, 3, 0) != 0)
9467141Sgblack@eecs.umich.edu                return new WarnUnimplemented("it", machInst);
9477141Sgblack@eecs.umich.edu            switch (bits(machInst, 7, 4)) {
9487141Sgblack@eecs.umich.edu              case 0x0:
9497141Sgblack@eecs.umich.edu                return new WarnUnimplemented("nop", machInst);
9507141Sgblack@eecs.umich.edu              case 0x1:
9517141Sgblack@eecs.umich.edu                return new WarnUnimplemented("yield", machInst);
9527141Sgblack@eecs.umich.edu              case 0x2:
9537141Sgblack@eecs.umich.edu                return new WarnUnimplemented("wfe", machInst);
9547141Sgblack@eecs.umich.edu              case 0x3:
9557141Sgblack@eecs.umich.edu                return new WarnUnimplemented("wfi", machInst);
9567141Sgblack@eecs.umich.edu              case 0x4:
9577141Sgblack@eecs.umich.edu                return new WarnUnimplemented("sev", machInst);
9587141Sgblack@eecs.umich.edu              default:
9597141Sgblack@eecs.umich.edu                return new WarnUnimplemented("unallocated_hint", machInst);
9607141Sgblack@eecs.umich.edu            }
9617141Sgblack@eecs.umich.edu          default:
9627141Sgblack@eecs.umich.edu            break;
9637141Sgblack@eecs.umich.edu        }
9647141Sgblack@eecs.umich.edu        return new Unknown(machInst);
9657141Sgblack@eecs.umich.edu    }
9667141Sgblack@eecs.umich.edu    '''
9677141Sgblack@eecs.umich.edu}};
9687141Sgblack@eecs.umich.edu
9697141Sgblack@eecs.umich.edudef format Thumb32DataProcModImm() {{
9707141Sgblack@eecs.umich.edu
9717141Sgblack@eecs.umich.edu    def decInst(mnem, dest="rd", op1="rn"):
9727141Sgblack@eecs.umich.edu        return '''
9737141Sgblack@eecs.umich.edu            if (s) {
9747146Sgblack@eecs.umich.edu                return new %(mnem)sImmCc(machInst, %(dest)s,
9757183Sgblack@eecs.umich.edu                                          %(op1)s, imm, rotC);
9767141Sgblack@eecs.umich.edu            } else {
9777146Sgblack@eecs.umich.edu                return new %(mnem)sImm(machInst, %(dest)s,
9787183Sgblack@eecs.umich.edu                                        %(op1)s, imm, rotC);
9797141Sgblack@eecs.umich.edu            }
9807141Sgblack@eecs.umich.edu        ''' % {"mnem" : mnem, "dest" : dest, "op1" : op1}
9817141Sgblack@eecs.umich.edu
9827141Sgblack@eecs.umich.edu    decode_block = '''
9837141Sgblack@eecs.umich.edu    {
9847141Sgblack@eecs.umich.edu        const uint32_t op = bits(machInst, 24, 21);
9857141Sgblack@eecs.umich.edu        const bool s = (bits(machInst, 20) == 1);
9867141Sgblack@eecs.umich.edu        const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
9877141Sgblack@eecs.umich.edu        const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
9887141Sgblack@eecs.umich.edu        const uint32_t ctrlImm = bits(machInst.instBits, 26) << 3 |
9897141Sgblack@eecs.umich.edu                                 bits(machInst, 14, 12);
9907183Sgblack@eecs.umich.edu        const bool rotC = ctrlImm > 3;
9917141Sgblack@eecs.umich.edu        const uint32_t dataImm = bits(machInst, 7, 0);
9927141Sgblack@eecs.umich.edu        const uint32_t imm = modified_imm(ctrlImm, dataImm);
9937141Sgblack@eecs.umich.edu        switch (op) {
9947141Sgblack@eecs.umich.edu          case 0x0:
9957141Sgblack@eecs.umich.edu            if (rd == INTREG_PC) {
9967141Sgblack@eecs.umich.edu                %(tst)s
9977141Sgblack@eecs.umich.edu            } else {
9987141Sgblack@eecs.umich.edu                %(and)s
9997141Sgblack@eecs.umich.edu            }
10007141Sgblack@eecs.umich.edu          case 0x1:
10017141Sgblack@eecs.umich.edu            %(bic)s
10027141Sgblack@eecs.umich.edu          case 0x2:
10037141Sgblack@eecs.umich.edu            if (rn == INTREG_PC) {
10047141Sgblack@eecs.umich.edu                %(mov)s
10057141Sgblack@eecs.umich.edu            } else {
10067141Sgblack@eecs.umich.edu                %(orr)s
10077141Sgblack@eecs.umich.edu            }
10087141Sgblack@eecs.umich.edu          case 0x3:
10097141Sgblack@eecs.umich.edu            if (rn == INTREG_PC) {
10107141Sgblack@eecs.umich.edu                %(mvn)s
10117141Sgblack@eecs.umich.edu            } else {
10127141Sgblack@eecs.umich.edu                %(orn)s
10137141Sgblack@eecs.umich.edu            }
10147141Sgblack@eecs.umich.edu          case 0x4:
10157141Sgblack@eecs.umich.edu            if (rd == INTREG_PC) {
10167141Sgblack@eecs.umich.edu                %(teq)s
10177141Sgblack@eecs.umich.edu            } else {
10187141Sgblack@eecs.umich.edu                %(eor)s
10197141Sgblack@eecs.umich.edu            }
10207141Sgblack@eecs.umich.edu          case 0x8:
10217141Sgblack@eecs.umich.edu            if (rd == INTREG_PC) {
10227141Sgblack@eecs.umich.edu                %(cmn)s
10237141Sgblack@eecs.umich.edu            } else {
10247141Sgblack@eecs.umich.edu                %(add)s
10257141Sgblack@eecs.umich.edu            }
10267141Sgblack@eecs.umich.edu          case 0xa:
10277141Sgblack@eecs.umich.edu            %(adc)s
10287141Sgblack@eecs.umich.edu          case 0xb:
10297141Sgblack@eecs.umich.edu            %(sbc)s
10307141Sgblack@eecs.umich.edu          case 0xd:
10317141Sgblack@eecs.umich.edu            if (rd == INTREG_PC) {
10327141Sgblack@eecs.umich.edu                %(cmp)s
10337141Sgblack@eecs.umich.edu            } else {
10347141Sgblack@eecs.umich.edu                %(sub)s
10357141Sgblack@eecs.umich.edu            }
10367141Sgblack@eecs.umich.edu          case 0xe:
10377141Sgblack@eecs.umich.edu            %(rsb)s
10387141Sgblack@eecs.umich.edu          default:
10397141Sgblack@eecs.umich.edu            return new Unknown(machInst);
10407141Sgblack@eecs.umich.edu        }
10417141Sgblack@eecs.umich.edu    }
10427141Sgblack@eecs.umich.edu    ''' % {
10437141Sgblack@eecs.umich.edu        "tst" : decInst("Tst", "INTREG_ZERO"),
10447141Sgblack@eecs.umich.edu        "and" : decInst("And"),
10457141Sgblack@eecs.umich.edu        "bic" : decInst("Bic"),
10467141Sgblack@eecs.umich.edu        "mov" : decInst("Mov", op1="INTREG_ZERO"),
10477141Sgblack@eecs.umich.edu        "orr" : decInst("Orr"),
10487141Sgblack@eecs.umich.edu        "mvn" : decInst("Mvn", op1="INTREG_ZERO"),
10497141Sgblack@eecs.umich.edu        "orn" : decInst("Orn"),
10507141Sgblack@eecs.umich.edu        "teq" : decInst("Teq", dest="INTREG_ZERO"),
10517141Sgblack@eecs.umich.edu        "eor" : decInst("Eor"),
10527141Sgblack@eecs.umich.edu        "cmn" : decInst("Cmn", dest="INTREG_ZERO"),
10537141Sgblack@eecs.umich.edu        "add" : decInst("Add"),
10547141Sgblack@eecs.umich.edu        "adc" : decInst("Adc"),
10557141Sgblack@eecs.umich.edu        "sbc" : decInst("Sbc"),
10567141Sgblack@eecs.umich.edu        "cmp" : decInst("Cmp", dest="INTREG_ZERO"),
10577141Sgblack@eecs.umich.edu        "sub" : decInst("Sub"),
10587141Sgblack@eecs.umich.edu        "rsb" : decInst("Rsb")
10597141Sgblack@eecs.umich.edu    }
10607141Sgblack@eecs.umich.edu}};
10617141Sgblack@eecs.umich.edu
10627157Sgblack@eecs.umich.edudef format Thumb32DataProcPlainBin() {{
10637157Sgblack@eecs.umich.edu    decode_block = '''
10647157Sgblack@eecs.umich.edu    {
10657157Sgblack@eecs.umich.edu        const uint32_t op = bits(machInst, 24, 20);
10667157Sgblack@eecs.umich.edu        const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
10677157Sgblack@eecs.umich.edu        const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
10687157Sgblack@eecs.umich.edu        switch (op) {
10697157Sgblack@eecs.umich.edu          case 0x0:
10707157Sgblack@eecs.umich.edu            {
10717157Sgblack@eecs.umich.edu                const uint32_t imm = bits(machInst, 7, 0) |
10727157Sgblack@eecs.umich.edu                                     (bits(machInst, 14, 12) << 8) |
10737157Sgblack@eecs.umich.edu                                     (bits(machInst, 26) << 11);
10747185Sgblack@eecs.umich.edu                if (rn == 0xf) {
10757185Sgblack@eecs.umich.edu                    return new AdrImm(machInst, rd, (IntRegIndex)1,
10767185Sgblack@eecs.umich.edu                                      imm, false);
10777185Sgblack@eecs.umich.edu                } else {
10787185Sgblack@eecs.umich.edu                    return new AddImm(machInst, rd, rn, imm, true);
10797185Sgblack@eecs.umich.edu                }
10807157Sgblack@eecs.umich.edu            }
10817157Sgblack@eecs.umich.edu          case 0x4:
10827157Sgblack@eecs.umich.edu            {
10837157Sgblack@eecs.umich.edu                const uint32_t imm = bits(machInst, 7, 0) |
10847157Sgblack@eecs.umich.edu                                     (bits(machInst, 14, 12) << 8) |
10857157Sgblack@eecs.umich.edu                                     (bits(machInst, 26) << 11) |
10867157Sgblack@eecs.umich.edu                                     (bits(machInst, 19, 16) << 12);
10877157Sgblack@eecs.umich.edu                return new MovImm(machInst, rd, INTREG_ZERO, imm, true);
10887157Sgblack@eecs.umich.edu            }
10897157Sgblack@eecs.umich.edu          case 0xa:
10907157Sgblack@eecs.umich.edu            {
10917157Sgblack@eecs.umich.edu                const uint32_t imm = bits(machInst, 7, 0) |
10927157Sgblack@eecs.umich.edu                                     (bits(machInst, 14, 12) << 8) |
10937157Sgblack@eecs.umich.edu                                     (bits(machInst, 26) << 11);
10947185Sgblack@eecs.umich.edu                if (rn == 0xf) {
10957185Sgblack@eecs.umich.edu                    return new AdrImm(machInst, rd, (IntRegIndex)0,
10967185Sgblack@eecs.umich.edu                                      imm, false);
10977185Sgblack@eecs.umich.edu                } else {
10987185Sgblack@eecs.umich.edu                    return new SubImm(machInst, rd, rn, imm, true);
10997185Sgblack@eecs.umich.edu                }
11007157Sgblack@eecs.umich.edu            }
11017157Sgblack@eecs.umich.edu          case 0xc:
11027157Sgblack@eecs.umich.edu            {
11037157Sgblack@eecs.umich.edu                const uint32_t imm = bits(machInst, 7, 0) |
11047157Sgblack@eecs.umich.edu                                     (bits(machInst, 14, 12) << 8) |
11057157Sgblack@eecs.umich.edu                                     (bits(machInst, 26) << 11) |
11067157Sgblack@eecs.umich.edu                                     (bits(machInst, 19, 16) << 12);
11077157Sgblack@eecs.umich.edu                return new MovtImm(machInst, rd, rd, imm, true);
11087157Sgblack@eecs.umich.edu            }
11097157Sgblack@eecs.umich.edu          case 0x12:
11107157Sgblack@eecs.umich.edu            if (!(bits(machInst, 14, 12) || bits(machInst, 7, 6))) {
11117157Sgblack@eecs.umich.edu                return new WarnUnimplemented("ssat16", machInst);
11127157Sgblack@eecs.umich.edu            }
11137157Sgblack@eecs.umich.edu            // Fall through on purpose...
11147157Sgblack@eecs.umich.edu          case 0x10:
11157157Sgblack@eecs.umich.edu            return new WarnUnimplemented("ssat", machInst);
11167157Sgblack@eecs.umich.edu          case 0x14:
11177157Sgblack@eecs.umich.edu            return new WarnUnimplemented("sbfx", machInst);
11187157Sgblack@eecs.umich.edu          case 0x16:
11197157Sgblack@eecs.umich.edu            if (rn == 0xf) {
11207157Sgblack@eecs.umich.edu                return new WarnUnimplemented("bfc", machInst);
11217157Sgblack@eecs.umich.edu            } else {
11227157Sgblack@eecs.umich.edu                return new WarnUnimplemented("bfi", machInst);
11237157Sgblack@eecs.umich.edu            }
11247157Sgblack@eecs.umich.edu          case 0x1a:
11257157Sgblack@eecs.umich.edu            if (!(bits(machInst, 14, 12) || bits(machInst, 7, 6))) {
11267157Sgblack@eecs.umich.edu                return new WarnUnimplemented("usat16", machInst);
11277157Sgblack@eecs.umich.edu            }
11287157Sgblack@eecs.umich.edu            // Fall through on purpose...
11297157Sgblack@eecs.umich.edu          case 0x18:
11307157Sgblack@eecs.umich.edu            return new WarnUnimplemented("usat", machInst);
11317157Sgblack@eecs.umich.edu          case 0x1c:
11327157Sgblack@eecs.umich.edu            return new WarnUnimplemented("ubfx", machInst);
11337157Sgblack@eecs.umich.edu          default:
11347157Sgblack@eecs.umich.edu            return new Unknown(machInst);
11357157Sgblack@eecs.umich.edu        }
11367157Sgblack@eecs.umich.edu    }
11377157Sgblack@eecs.umich.edu    '''
11387157Sgblack@eecs.umich.edu}};
11397157Sgblack@eecs.umich.edu
11407141Sgblack@eecs.umich.edudef format Thumb32DataProcShiftReg() {{
11417141Sgblack@eecs.umich.edu
11427141Sgblack@eecs.umich.edu    def decInst(mnem, dest="rd", op1="rn"):
11437141Sgblack@eecs.umich.edu        return '''
11447141Sgblack@eecs.umich.edu            if (s) {
11457146Sgblack@eecs.umich.edu                return new %(mnem)sRegCc(machInst, %(dest)s,
11467141Sgblack@eecs.umich.edu                                          %(op1)s, rm, amt, type);
11477141Sgblack@eecs.umich.edu            } else {
11487146Sgblack@eecs.umich.edu                return new %(mnem)sReg(machInst, %(dest)s,
11497141Sgblack@eecs.umich.edu                                        %(op1)s, rm, amt, type);
11507141Sgblack@eecs.umich.edu            }
11517141Sgblack@eecs.umich.edu        ''' % {"mnem" : mnem, "dest" : dest, "op1" : op1}
11527141Sgblack@eecs.umich.edu
11537141Sgblack@eecs.umich.edu    decode_block = '''
11547141Sgblack@eecs.umich.edu    {
11557141Sgblack@eecs.umich.edu        const uint32_t op = bits(machInst, 24, 21);
11567141Sgblack@eecs.umich.edu        const bool s = (bits(machInst, 20) == 1);
11577141Sgblack@eecs.umich.edu        const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
11587141Sgblack@eecs.umich.edu        const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
11597141Sgblack@eecs.umich.edu        const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
11607141Sgblack@eecs.umich.edu        const uint32_t amt = (bits(machInst, 14, 12) << 2) |
11617141Sgblack@eecs.umich.edu                              bits(machInst, 7, 6);
11627141Sgblack@eecs.umich.edu        const ArmShiftType type = (ArmShiftType)(uint32_t)bits(machInst, 5, 4);
11637141Sgblack@eecs.umich.edu        switch (op) {
11647141Sgblack@eecs.umich.edu          case 0x0:
11657141Sgblack@eecs.umich.edu            if (rd == INTREG_PC) {
11667141Sgblack@eecs.umich.edu                %(tst)s
11677141Sgblack@eecs.umich.edu            } else {
11687141Sgblack@eecs.umich.edu                %(and)s
11697141Sgblack@eecs.umich.edu            }
11707141Sgblack@eecs.umich.edu          case 0x1:
11717141Sgblack@eecs.umich.edu            %(bic)s
11727141Sgblack@eecs.umich.edu          case 0x2:
11737141Sgblack@eecs.umich.edu            if (rn == INTREG_PC) {
11747141Sgblack@eecs.umich.edu                %(mov)s
11757141Sgblack@eecs.umich.edu            } else {
11767141Sgblack@eecs.umich.edu                %(orr)s
11777141Sgblack@eecs.umich.edu            }
11787141Sgblack@eecs.umich.edu          case 0x3:
11797141Sgblack@eecs.umich.edu            if (rn == INTREG_PC) {
11807141Sgblack@eecs.umich.edu                %(mvn)s
11817141Sgblack@eecs.umich.edu            } else {
11827141Sgblack@eecs.umich.edu                %(orn)s
11837141Sgblack@eecs.umich.edu            }
11847141Sgblack@eecs.umich.edu          case 0x4:
11857141Sgblack@eecs.umich.edu            if (rd == INTREG_PC) {
11867141Sgblack@eecs.umich.edu                %(teq)s
11877141Sgblack@eecs.umich.edu            } else {
11887141Sgblack@eecs.umich.edu                %(eor)s
11897141Sgblack@eecs.umich.edu            }
11907141Sgblack@eecs.umich.edu          case 0x6:
11917141Sgblack@eecs.umich.edu            return new WarnUnimplemented("pkh", machInst);
11927141Sgblack@eecs.umich.edu          case 0x8:
11937141Sgblack@eecs.umich.edu            if (rd == INTREG_PC) {
11947141Sgblack@eecs.umich.edu                %(cmn)s
11957141Sgblack@eecs.umich.edu            } else {
11967141Sgblack@eecs.umich.edu                %(add)s
11977141Sgblack@eecs.umich.edu            }
11987141Sgblack@eecs.umich.edu          case 0xa:
11997141Sgblack@eecs.umich.edu            %(adc)s
12007141Sgblack@eecs.umich.edu          case 0xb:
12017141Sgblack@eecs.umich.edu            %(sbc)s
12027141Sgblack@eecs.umich.edu          case 0xd:
12037141Sgblack@eecs.umich.edu            if (rd == INTREG_PC) {
12047141Sgblack@eecs.umich.edu                %(cmp)s
12057141Sgblack@eecs.umich.edu            } else {
12067141Sgblack@eecs.umich.edu                %(sub)s
12077141Sgblack@eecs.umich.edu            }
12087141Sgblack@eecs.umich.edu          case 0xe:
12097141Sgblack@eecs.umich.edu            %(rsb)s
12107141Sgblack@eecs.umich.edu          default:
12117141Sgblack@eecs.umich.edu            return new Unknown(machInst);
12127141Sgblack@eecs.umich.edu        }
12137141Sgblack@eecs.umich.edu    }
12147141Sgblack@eecs.umich.edu    ''' % {
12157141Sgblack@eecs.umich.edu        "tst" : decInst("Tst", "INTREG_ZERO"),
12167141Sgblack@eecs.umich.edu        "and" : decInst("And"),
12177141Sgblack@eecs.umich.edu        "bic" : decInst("Bic"),
12187141Sgblack@eecs.umich.edu        "mov" : decInst("Mov", op1="INTREG_ZERO"),
12197141Sgblack@eecs.umich.edu        "orr" : decInst("Orr"),
12207141Sgblack@eecs.umich.edu        "mvn" : decInst("Mvn", op1="INTREG_ZERO"),
12217141Sgblack@eecs.umich.edu        "orn" : decInst("Orn"),
12227141Sgblack@eecs.umich.edu        "teq" : decInst("Teq", "INTREG_ZERO"),
12237141Sgblack@eecs.umich.edu        "eor" : decInst("Eor"),
12247141Sgblack@eecs.umich.edu        "cmn" : decInst("Cmn", "INTREG_ZERO"),
12257141Sgblack@eecs.umich.edu        "add" : decInst("Add"),
12267141Sgblack@eecs.umich.edu        "adc" : decInst("Adc"),
12277141Sgblack@eecs.umich.edu        "sbc" : decInst("Sbc"),
12287141Sgblack@eecs.umich.edu        "cmp" : decInst("Cmp", "INTREG_ZERO"),
12297141Sgblack@eecs.umich.edu        "sub" : decInst("Sub"),
12307141Sgblack@eecs.umich.edu        "rsb" : decInst("Rsb")
12317141Sgblack@eecs.umich.edu    }
12327141Sgblack@eecs.umich.edu}};
1233