data.isa revision 7185
12817Sksewell@umich.edu// Copyright (c) 2010 ARM Limited
22817Sksewell@umich.edu// All rights reserved
32817Sksewell@umich.edu//
42817Sksewell@umich.edu// The license below extends only to copyright in the software and shall
52817Sksewell@umich.edu// not be construed as granting a license to any other intellectual
62817Sksewell@umich.edu// property including but not limited to intellectual property relating
72817Sksewell@umich.edu// to a hardware implementation of the functionality of the software
82817Sksewell@umich.edu// licensed hereunder.  You may use the software subject to the license
92817Sksewell@umich.edu// terms below provided that you ensure that this notice is replicated
102817Sksewell@umich.edu// unmodified and in its entirety in all distributions of the software,
112817Sksewell@umich.edu// modified or unmodified, in source code or in binary form.
122817Sksewell@umich.edu//
132817Sksewell@umich.edu// Redistribution and use in source and binary forms, with or without
142817Sksewell@umich.edu// modification, are permitted provided that the following conditions are
152817Sksewell@umich.edu// met: redistributions of source code must retain the above copyright
162817Sksewell@umich.edu// notice, this list of conditions and the following disclaimer;
172817Sksewell@umich.edu// redistributions in binary form must reproduce the above copyright
182817Sksewell@umich.edu// notice, this list of conditions and the following disclaimer in the
192817Sksewell@umich.edu// documentation and/or other materials provided with the distribution;
202817Sksewell@umich.edu// neither the name of the copyright holders nor the names of its
212817Sksewell@umich.edu// contributors may be used to endorse or promote products derived from
222817Sksewell@umich.edu// this software without specific prior written permission.
232817Sksewell@umich.edu//
242817Sksewell@umich.edu// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
252817Sksewell@umich.edu// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
262817Sksewell@umich.edu// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
272817Sksewell@umich.edu// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
282817Sksewell@umich.edu// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
292817Sksewell@umich.edu// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
302817Sksewell@umich.edu// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
312817Sksewell@umich.edu// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
323776Sgblack@eecs.umich.edu// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
332817Sksewell@umich.edu// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
342834Sksewell@umich.edu// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
352817Sksewell@umich.edu//
362817Sksewell@umich.edu// Authors: Gabe Black
372817Sksewell@umich.edu
382817Sksewell@umich.edudef format ArmDataProcReg() {{
392817Sksewell@umich.edu    instDecode = '''
402817Sksewell@umich.edu          case %(opcode)#x:
412817Sksewell@umich.edu            if (immShift) {
422817Sksewell@umich.edu                if (setCc) {
432817Sksewell@umich.edu                    return new %(className)sRegCc(machInst, %(dest)s, %(op1)s,
442817Sksewell@umich.edu                                                   rm, imm5, type);
452817Sksewell@umich.edu                } else {
462817Sksewell@umich.edu                    return new %(className)sReg(machInst, %(dest)s, %(op1)s,
473675Sktlim@umich.edu                                                 rm, imm5, type);
482817Sksewell@umich.edu                }
492817Sksewell@umich.edu            } else {
502817Sksewell@umich.edu                if (setCc) {
512817Sksewell@umich.edu                    return new %(className)sRegRegCc(machInst, %(dest)s,
522817Sksewell@umich.edu                                                      %(op1)s, rm, rs, type);
532817Sksewell@umich.edu                } else {
542817Sksewell@umich.edu                    return new %(className)sRegReg(machInst, %(dest)s,
553126Sktlim@umich.edu                                                    %(op1)s, rm, rs, type);
562817Sksewell@umich.edu                }
572817Sksewell@umich.edu            }
582817Sksewell@umich.edu            break;
592817Sksewell@umich.edu    '''
602817Sksewell@umich.edu
612817Sksewell@umich.edu    def instCode(opcode, mnem, dest="rd", op1="rn"):
622817Sksewell@umich.edu        global instDecode
632817Sksewell@umich.edu        return instDecode % { "className": mnem.capitalize(),
642817Sksewell@umich.edu                              "opcode": opcode,
652817Sksewell@umich.edu                              "dest": dest,
662817Sksewell@umich.edu                              "op1": op1 }
672817Sksewell@umich.edu
682817Sksewell@umich.edu    decode_block = '''
692817Sksewell@umich.edu    {
702817Sksewell@umich.edu        const bool immShift = (bits(machInst, 4) == 0);
712817Sksewell@umich.edu        const bool setCc = (bits(machInst, 20) == 1);
722817Sksewell@umich.edu        const uint32_t imm5 = bits(machInst, 11, 7);
732817Sksewell@umich.edu        const ArmShiftType type = (ArmShiftType)(uint32_t)bits(machInst, 6, 5);
742817Sksewell@umich.edu        const IntRegIndex rd = (IntRegIndex)(uint32_t)RD;
752817Sksewell@umich.edu        const IntRegIndex rn = (IntRegIndex)(uint32_t)RN;
762817Sksewell@umich.edu        const IntRegIndex rm = (IntRegIndex)(uint32_t)RM;
772817Sksewell@umich.edu        const IntRegIndex rs = (IntRegIndex)(uint32_t)RS;
782817Sksewell@umich.edu        switch (OPCODE) {
792817Sksewell@umich.edu    '''
802817Sksewell@umich.edu    decode_block += instCode(0x0, "and")
812817Sksewell@umich.edu    decode_block += instCode(0x1, "eor")
822817Sksewell@umich.edu    decode_block += instCode(0x2, "sub")
832817Sksewell@umich.edu    decode_block += instCode(0x3, "rsb")
842817Sksewell@umich.edu    decode_block += instCode(0x4, "add")
852817Sksewell@umich.edu    decode_block += instCode(0x5, "adc")
862817Sksewell@umich.edu    decode_block += instCode(0x6, "sbc")
872817Sksewell@umich.edu    decode_block += instCode(0x7, "rsc")
882817Sksewell@umich.edu    decode_block += instCode(0x8, "tst", dest="INTREG_ZERO")
892817Sksewell@umich.edu    decode_block += instCode(0x9, "teq", dest="INTREG_ZERO")
902817Sksewell@umich.edu    decode_block += instCode(0xa, "cmp", dest="INTREG_ZERO")
912817Sksewell@umich.edu    decode_block += instCode(0xb, "cmn", dest="INTREG_ZERO")
922817Sksewell@umich.edu    decode_block += instCode(0xc, "orr")
932817Sksewell@umich.edu    decode_block += instCode(0xd, "mov", op1="INTREG_ZERO")
942817Sksewell@umich.edu    decode_block += instCode(0xe, "bic")
952817Sksewell@umich.edu    decode_block += instCode(0xf, "mvn", op1="INTREG_ZERO")
962817Sksewell@umich.edu    decode_block += '''
972817Sksewell@umich.edu          default:
982817Sksewell@umich.edu            return new Unknown(machInst);
992817Sksewell@umich.edu        }
1002817Sksewell@umich.edu    }
1012817Sksewell@umich.edu    '''
1022817Sksewell@umich.edu}};
1032817Sksewell@umich.edu
1042817Sksewell@umich.edudef format ArmDataProcImm() {{
1053686Sktlim@umich.edu    instDecode = '''
1064217Ssaidi@eecs.umich.edu            if (setCc) {
1073686Sktlim@umich.edu                return new %(className)sImmCc(machInst, %(dest)s, %(op1)s,
1083686Sktlim@umich.edu                                               imm, rotC);
1092817Sksewell@umich.edu            } else {
1102817Sksewell@umich.edu                return new %(className)sImm(machInst, %(dest)s, %(op1)s,
1112817Sksewell@umich.edu                                             imm, rotC);
1122817Sksewell@umich.edu            }
1132817Sksewell@umich.edu            break;
1142817Sksewell@umich.edu    '''
1152817Sksewell@umich.edu
1162875Sksewell@umich.edu    def instCode(opcode, mnem, dest="rd", op1="rn"):
1172875Sksewell@umich.edu        global instDecode
1182817Sksewell@umich.edu        code = '''
1192817Sksewell@umich.edu          case %(opcode)#x:
1202817Sksewell@umich.edu        ''' + instDecode
1212817Sksewell@umich.edu        return code % { "className": mnem.capitalize(),
1222817Sksewell@umich.edu                        "opcode": opcode,
1232817Sksewell@umich.edu                        "dest": dest,
1242817Sksewell@umich.edu                        "op1": op1 }
1252817Sksewell@umich.edu
1262817Sksewell@umich.edu    def adrCode(opcode, mnem, dest="rd", op1="rn", add="1"):
1272817Sksewell@umich.edu        global instDecode
1282817Sksewell@umich.edu        code = '''
1292817Sksewell@umich.edu          case %(opcode)#x:
1302817Sksewell@umich.edu            if (rn == 0xf) {
1312817Sksewell@umich.edu                return new AdrImm(machInst, %(dest)s, %(add)s,
1322817Sksewell@umich.edu                                             imm, false);
1332817Sksewell@umich.edu            } else {
1342817Sksewell@umich.edu        ''' + instDecode + '''
1352817Sksewell@umich.edu            }
1362817Sksewell@umich.edu        '''
1372817Sksewell@umich.edu        return code % { "className": mnem.capitalize(),
1382817Sksewell@umich.edu                        "opcode": opcode,
1392817Sksewell@umich.edu                        "dest": dest,
1402817Sksewell@umich.edu                        "add": add,
1412875Sksewell@umich.edu                        "op1": op1 }
1422875Sksewell@umich.edu
1432817Sksewell@umich.edu    decode_block = '''
1442817Sksewell@umich.edu    {
1452817Sksewell@umich.edu        const bool setCc = (bits(machInst, 20) == 1);
1462817Sksewell@umich.edu        const uint32_t unrotated = bits(machInst, 7, 0);
1472817Sksewell@umich.edu        const uint32_t rotation = (bits(machInst, 11, 8) << 1);
1482817Sksewell@umich.edu        const bool rotC = (rotation != 0);
1492817Sksewell@umich.edu        const uint32_t imm = rotate_imm(unrotated, rotation);
1502817Sksewell@umich.edu        const IntRegIndex rd = (IntRegIndex)(uint32_t)RD;
1512817Sksewell@umich.edu        const IntRegIndex rn = (IntRegIndex)(uint32_t)RN;
1522817Sksewell@umich.edu        switch (OPCODE) {
1532817Sksewell@umich.edu    '''
1542817Sksewell@umich.edu    decode_block += instCode(0x0, "and")
1552817Sksewell@umich.edu    decode_block += instCode(0x1, "eor")
1562817Sksewell@umich.edu    decode_block += adrCode(0x2, "sub", add="(IntRegIndex)0")
1572817Sksewell@umich.edu    decode_block += instCode(0x3, "rsb")
1582817Sksewell@umich.edu    decode_block += adrCode(0x4, "add", add="(IntRegIndex)1")
1592817Sksewell@umich.edu    decode_block += instCode(0x5, "adc")
1602817Sksewell@umich.edu    decode_block += instCode(0x6, "sbc")
1612817Sksewell@umich.edu    decode_block += instCode(0x7, "rsc")
1622817Sksewell@umich.edu    decode_block += instCode(0x8, "tst", dest="INTREG_ZERO")
1632817Sksewell@umich.edu    decode_block += instCode(0x9, "teq", dest="INTREG_ZERO")
1642817Sksewell@umich.edu    decode_block += instCode(0xa, "cmp", dest="INTREG_ZERO")
1652817Sksewell@umich.edu    decode_block += instCode(0xb, "cmn", dest="INTREG_ZERO")
1662875Sksewell@umich.edu    decode_block += instCode(0xc, "orr")
1672817Sksewell@umich.edu    decode_block += instCode(0xd, "mov", op1="INTREG_ZERO")
1683221Sktlim@umich.edu    decode_block += instCode(0xe, "bic")
1693221Sktlim@umich.edu    decode_block += instCode(0xf, "mvn", op1="INTREG_ZERO")
1702817Sksewell@umich.edu    decode_block += '''
1712817Sksewell@umich.edu          default:
1722817Sksewell@umich.edu            return new Unknown(machInst);
1732817Sksewell@umich.edu        }
1742817Sksewell@umich.edu    }
1753221Sktlim@umich.edu    '''
1762817Sksewell@umich.edu}};
1772817Sksewell@umich.edu
1782817Sksewell@umich.edudef format Thumb16ShiftAddSubMoveCmp() {{
1792817Sksewell@umich.edu    decode_block = '''
1802817Sksewell@umich.edu    {
1812817Sksewell@umich.edu        const uint32_t imm5 = bits(machInst, 10, 6);
1822875Sksewell@umich.edu        const uint32_t imm3 = bits(machInst, 8, 6);
1832875Sksewell@umich.edu        const uint32_t imm8 = bits(machInst, 7, 0);
1842817Sksewell@umich.edu        const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 2, 0);
1852817Sksewell@umich.edu        const IntRegIndex rd8 = (IntRegIndex)(uint32_t)bits(machInst, 10, 8);
1862817Sksewell@umich.edu        const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 5, 3);
1872817Sksewell@umich.edu        const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 8, 6);
1882817Sksewell@umich.edu        switch (bits(machInst, 13, 11)) {
1892817Sksewell@umich.edu          case 0x0: // lsl
1902817Sksewell@umich.edu            return new MovRegCc(machInst, rd, INTREG_ZERO, rn, imm5, LSL);
1912817Sksewell@umich.edu          case 0x1: // lsr
1922817Sksewell@umich.edu            return new MovRegCc(machInst, rd, INTREG_ZERO, rn, imm5, LSR);
1932817Sksewell@umich.edu          case 0x2: // asr
1942817Sksewell@umich.edu            return new MovRegCc(machInst, rd, INTREG_ZERO, rn, imm5, ASR);
1952817Sksewell@umich.edu          case 0x3:
1962817Sksewell@umich.edu            switch (bits(machInst, 10, 9)) {
1973548Sgblack@eecs.umich.edu              case 0x0:
1982817Sksewell@umich.edu                return new AddRegCc(machInst, rd, rn, rm, 0, LSL);
1992817Sksewell@umich.edu              case 0x1:
2002817Sksewell@umich.edu                return new SubRegCc(machInst, rd, rn, rm, 0, LSL);
2012817Sksewell@umich.edu              case 0x2:
2022817Sksewell@umich.edu                return new AddImmCc(machInst, rd, rn, imm3, true);
2032817Sksewell@umich.edu              case 0x3:
2042817Sksewell@umich.edu                return new SubImmCc(machInst, rd, rn, imm3, true);
2052817Sksewell@umich.edu            }
2062817Sksewell@umich.edu          case 0x4:
2072817Sksewell@umich.edu            return new MovImmCc(machInst, rd8, INTREG_ZERO, imm8, false);
2082817Sksewell@umich.edu          case 0x5:
2092817Sksewell@umich.edu            return new CmpImmCc(machInst, INTREG_ZERO, rd8, imm8, true);
2102817Sksewell@umich.edu          case 0x6:
2112817Sksewell@umich.edu            return new AddImmCc(machInst, rd8, rd8, imm8, true);
2122817Sksewell@umich.edu          case 0x7:
2132817Sksewell@umich.edu            return new SubImmCc(machInst, rd8, rd8, imm8, true);
2142817Sksewell@umich.edu        }
2152817Sksewell@umich.edu    }
2162817Sksewell@umich.edu    '''
2172817Sksewell@umich.edu}};
2182817Sksewell@umich.edu
2192817Sksewell@umich.edudef format Thumb16DataProcessing() {{
2202817Sksewell@umich.edu    decode_block = '''
2212817Sksewell@umich.edu    {
2222817Sksewell@umich.edu        const IntRegIndex rdn = (IntRegIndex)(uint32_t)bits(machInst, 2, 0);
2232817Sksewell@umich.edu        const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 5, 3);
2242817Sksewell@umich.edu        switch (bits(machInst, 9, 6)) {
2252817Sksewell@umich.edu          case 0x0:
2262817Sksewell@umich.edu            return new AndRegCc(machInst, rdn, rdn, rm, 0, LSL);
2272817Sksewell@umich.edu          case 0x1:
2282817Sksewell@umich.edu            return new EorRegCc(machInst, rdn, rdn, rm, 0, LSL);
2292817Sksewell@umich.edu          case 0x2: //lsl
2302817Sksewell@umich.edu            return new MovRegRegCc(machInst, rdn, INTREG_ZERO, rdn, rm, LSL);
2312817Sksewell@umich.edu          case 0x3: //lsr
2322817Sksewell@umich.edu            return new MovRegRegCc(machInst, rdn, INTREG_ZERO, rdn, rm, LSR);
2332817Sksewell@umich.edu          case 0x4: //asr
2342817Sksewell@umich.edu            return new MovRegRegCc(machInst, rdn, INTREG_ZERO, rdn, rm, ASR);
2352817Sksewell@umich.edu          case 0x5:
2362817Sksewell@umich.edu            return new AdcRegCc(machInst, rdn, rdn, rm, 0, LSL);
2372817Sksewell@umich.edu          case 0x6:
2382817Sksewell@umich.edu            return new SbcRegCc(machInst, rdn, rdn, rm, 0, LSL);
2392817Sksewell@umich.edu          case 0x7: // ror
2402817Sksewell@umich.edu            return new MovRegRegCc(machInst, rdn, INTREG_ZERO, rdn, rm, ROR);
2412817Sksewell@umich.edu          case 0x8:
2423126Sktlim@umich.edu            return new TstRegCc(machInst, INTREG_ZERO, rdn, rm, 0, LSL);
2433126Sktlim@umich.edu          case 0x9:
2443126Sktlim@umich.edu            return new RsbImmCc(machInst, rdn, rm, 0, true);
2452817Sksewell@umich.edu          case 0xa:
2462817Sksewell@umich.edu            return new CmpRegCc(machInst, INTREG_ZERO, rdn, rm, 0, LSL);
2472817Sksewell@umich.edu          case 0xb:
2482817Sksewell@umich.edu            return new CmnRegCc(machInst, INTREG_ZERO, rdn, rm, 0, LSL);
2493126Sktlim@umich.edu          case 0xc:
2503126Sktlim@umich.edu            return new OrrRegCc(machInst, rdn, rdn, rm, 0, LSL);
2513126Sktlim@umich.edu          case 0xd:
2522817Sksewell@umich.edu            return new MulCc(machInst, rdn, rm, rdn);
2532817Sksewell@umich.edu          case 0xe:
2542817Sksewell@umich.edu            return new BicRegCc(machInst, rdn, rdn, rm, 0, LSL);
2552817Sksewell@umich.edu          case 0xf:
2562817Sksewell@umich.edu            return new MvnRegCc(machInst, rdn, INTREG_ZERO, rm, 0, LSL);
2572817Sksewell@umich.edu        }
2582817Sksewell@umich.edu    }
2592817Sksewell@umich.edu    '''
2602817Sksewell@umich.edu}};
2612817Sksewell@umich.edu
2622817Sksewell@umich.edudef format Thumb16SpecDataAndBx() {{
2632817Sksewell@umich.edu    decode_block = '''
2642817Sksewell@umich.edu    {
2652817Sksewell@umich.edu        const IntRegIndex rdn =
2662817Sksewell@umich.edu            (IntRegIndex)(uint32_t)(bits(machInst, 2, 0) |
2672817Sksewell@umich.edu                                    (bits(machInst, 7) << 3));
2682817Sksewell@umich.edu        const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 6, 3);
2692817Sksewell@umich.edu        switch (bits(machInst, 9, 8)) {
2702817Sksewell@umich.edu          case 0x0:
2712817Sksewell@umich.edu            return new AddReg(machInst, rdn, rdn, rm, 0, LSL);
2722817Sksewell@umich.edu          case 0x1:
2732817Sksewell@umich.edu            return new CmpRegCc(machInst, INTREG_ZERO, rdn, rm, 0, LSL);
2742817Sksewell@umich.edu          case 0x2:
2752817Sksewell@umich.edu            return new MovReg(machInst, rdn, INTREG_ZERO, rm, 0, LSL);
2762817Sksewell@umich.edu          case 0x3:
2772817Sksewell@umich.edu            if (bits(machInst, 7) == 0) {
2782817Sksewell@umich.edu                return new BxReg(machInst,
2792817Sksewell@umich.edu                                 (IntRegIndex)(uint32_t)bits(machInst, 6, 3),
2802817Sksewell@umich.edu                                 COND_UC);
2812817Sksewell@umich.edu            } else {
2822817Sksewell@umich.edu                return new BlxReg(machInst,
2832817Sksewell@umich.edu                                  (IntRegIndex)(uint32_t)bits(machInst, 6, 3),
2842817Sksewell@umich.edu                                  COND_UC);
2852817Sksewell@umich.edu            }
2862817Sksewell@umich.edu        }
2872817Sksewell@umich.edu    }
2882817Sksewell@umich.edu    '''
2892817Sksewell@umich.edu}};
2902986Sgblack@eecs.umich.edu
2912817Sksewell@umich.edudef format Thumb16Adr() {{
2922817Sksewell@umich.edu    decode_block = '''
2932817Sksewell@umich.edu    {
2942817Sksewell@umich.edu        const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 10, 8);
2952817Sksewell@umich.edu        const uint32_t imm8 = bits(machInst, 7, 0) << 2;
2962817Sksewell@umich.edu        return new AdrImm(machInst, rd, (IntRegIndex)1, imm8, false);
2972817Sksewell@umich.edu    }
2982817Sksewell@umich.edu    '''
2992817Sksewell@umich.edu}};
3002817Sksewell@umich.edu
3012817Sksewell@umich.edudef format Thumb16AddSp() {{
3022817Sksewell@umich.edu    decode_block = '''
3032817Sksewell@umich.edu    {
3042817Sksewell@umich.edu        const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 10, 8);
3052817Sksewell@umich.edu        const uint32_t imm8 = bits(machInst, 7, 0) << 2;
3062817Sksewell@umich.edu        return new AddImm(machInst, rd, INTREG_SP, imm8, true);
3072817Sksewell@umich.edu    }
3082817Sksewell@umich.edu    '''
3093776Sgblack@eecs.umich.edu}};
3102817Sksewell@umich.edu
3112817Sksewell@umich.edudef format Thumb16Misc() {{
3122817Sksewell@umich.edu    decode_block = '''
3132817Sksewell@umich.edu    {
3142986Sgblack@eecs.umich.edu        switch (bits(machInst, 11, 8)) {
3152817Sksewell@umich.edu          case 0x0:
3162817Sksewell@umich.edu            if (bits(machInst, 7)) {
3172817Sksewell@umich.edu                return new SubImm(machInst, INTREG_SP, INTREG_SP,
3182817Sksewell@umich.edu                                   bits(machInst, 6, 0) << 2, true);
3192817Sksewell@umich.edu            } else {
3202817Sksewell@umich.edu                return new AddImm(machInst, INTREG_SP, INTREG_SP,
3212817Sksewell@umich.edu                                   bits(machInst, 6, 0) << 2, true);
3222817Sksewell@umich.edu            }
3232817Sksewell@umich.edu          case 0x1:
3242817Sksewell@umich.edu            return new Cbz(machInst,
3252817Sksewell@umich.edu                           (bits(machInst, 9) << 6) |
3262817Sksewell@umich.edu                           (bits(machInst, 7, 3) << 1),
3272817Sksewell@umich.edu                           (IntRegIndex)(uint32_t)bits(machInst, 2, 0));
3282817Sksewell@umich.edu          case 0x2:
3292986Sgblack@eecs.umich.edu            switch (bits(machInst, 7, 6)) {
3302817Sksewell@umich.edu              case 0x0:
3312817Sksewell@umich.edu                return new WarnUnimplemented("sxth", machInst);
3322817Sksewell@umich.edu              case 0x1:
3332817Sksewell@umich.edu                return new WarnUnimplemented("sxtb", machInst);
3342817Sksewell@umich.edu              case 0x2:
3352817Sksewell@umich.edu                return new WarnUnimplemented("uxth", machInst);
3362986Sgblack@eecs.umich.edu              case 0x3:
3372817Sksewell@umich.edu                return new WarnUnimplemented("uxtb", machInst);
3382817Sksewell@umich.edu            }
3392817Sksewell@umich.edu          case 0x3:
3402817Sksewell@umich.edu            return new Cbz(machInst,
3412817Sksewell@umich.edu                           (bits(machInst, 9) << 6) |
3422817Sksewell@umich.edu                           (bits(machInst, 7, 3) << 1),
3432817Sksewell@umich.edu                           (IntRegIndex)(uint32_t)bits(machInst, 2, 0));
3442986Sgblack@eecs.umich.edu          case 0x4:
3452817Sksewell@umich.edu          case 0x5:
3462817Sksewell@umich.edu            return new WarnUnimplemented("push", machInst);
3472817Sksewell@umich.edu          case 0x6:
3482817Sksewell@umich.edu            {
3492817Sksewell@umich.edu                const uint32_t opBits = bits(machInst, 7, 5);
3502817Sksewell@umich.edu                if (opBits == 2) {
3512817Sksewell@umich.edu                    return new WarnUnimplemented("setend", machInst);
3522817Sksewell@umich.edu                } else if (opBits == 3) {
3532817Sksewell@umich.edu                    return new WarnUnimplemented("cps", machInst);
3543776Sgblack@eecs.umich.edu                }
3552817Sksewell@umich.edu            }
3562817Sksewell@umich.edu          case 0x9:
3572817Sksewell@umich.edu            return new Cbnz(machInst,
3582817Sksewell@umich.edu                            (bits(machInst, 9) << 6) |
3592817Sksewell@umich.edu                            (bits(machInst, 7, 3) << 1),
3602817Sksewell@umich.edu                            (IntRegIndex)(uint32_t)bits(machInst, 2, 0));
3612817Sksewell@umich.edu          case 0xa:
3622817Sksewell@umich.edu            switch (bits(machInst, 7, 5)) {
3632817Sksewell@umich.edu              case 0x0:
3642817Sksewell@umich.edu                return new WarnUnimplemented("rev", machInst);
3652817Sksewell@umich.edu              case 0x1:
3662817Sksewell@umich.edu                return new WarnUnimplemented("rev16", machInst);
3672817Sksewell@umich.edu              case 0x3:
3682817Sksewell@umich.edu                return new WarnUnimplemented("revsh", machInst);
3692817Sksewell@umich.edu              default:
3702817Sksewell@umich.edu                break;
3712817Sksewell@umich.edu            }
3722817Sksewell@umich.edu            break;
3732817Sksewell@umich.edu          case 0xb:
3742817Sksewell@umich.edu            return new Cbnz(machInst,
3752817Sksewell@umich.edu                            (bits(machInst, 9) << 6) |
3762817Sksewell@umich.edu                            (bits(machInst, 7, 3) << 1),
3772817Sksewell@umich.edu                            (IntRegIndex)(uint32_t)bits(machInst, 2, 0));
3782817Sksewell@umich.edu          case 0xc:
3792817Sksewell@umich.edu          case 0xd:
3802817Sksewell@umich.edu            return new WarnUnimplemented("pop", machInst);
3812817Sksewell@umich.edu          case 0xe:
3822817Sksewell@umich.edu            return new WarnUnimplemented("bkpt", machInst);
3832817Sksewell@umich.edu          case 0xf:
3842817Sksewell@umich.edu            if (bits(machInst, 3, 0) != 0)
3852817Sksewell@umich.edu                return new WarnUnimplemented("it", machInst);
3862817Sksewell@umich.edu            switch (bits(machInst, 7, 4)) {
3872817Sksewell@umich.edu              case 0x0:
3882817Sksewell@umich.edu                return new WarnUnimplemented("nop", machInst);
3892817Sksewell@umich.edu              case 0x1:
3902817Sksewell@umich.edu                return new WarnUnimplemented("yield", machInst);
3912817Sksewell@umich.edu              case 0x2:
3922817Sksewell@umich.edu                return new WarnUnimplemented("wfe", machInst);
3932817Sksewell@umich.edu              case 0x3:
3942817Sksewell@umich.edu                return new WarnUnimplemented("wfi", machInst);
3952817Sksewell@umich.edu              case 0x4:
3962817Sksewell@umich.edu                return new WarnUnimplemented("sev", machInst);
3972817Sksewell@umich.edu              default:
3982817Sksewell@umich.edu                return new WarnUnimplemented("unallocated_hint", machInst);
3992817Sksewell@umich.edu            }
4002817Sksewell@umich.edu          default:
4012817Sksewell@umich.edu            break;
4022817Sksewell@umich.edu        }
4032817Sksewell@umich.edu        return new Unknown(machInst);
4042817Sksewell@umich.edu    }
4052817Sksewell@umich.edu    '''
4062817Sksewell@umich.edu}};
4072817Sksewell@umich.edu
4082817Sksewell@umich.edudef format Thumb32DataProcModImm() {{
4092817Sksewell@umich.edu
4102817Sksewell@umich.edu    def decInst(mnem, dest="rd", op1="rn"):
4112817Sksewell@umich.edu        return '''
4122817Sksewell@umich.edu            if (s) {
4132817Sksewell@umich.edu                return new %(mnem)sImmCc(machInst, %(dest)s,
4142817Sksewell@umich.edu                                          %(op1)s, imm, rotC);
4152817Sksewell@umich.edu            } else {
4162817Sksewell@umich.edu                return new %(mnem)sImm(machInst, %(dest)s,
4172817Sksewell@umich.edu                                        %(op1)s, imm, rotC);
4182817Sksewell@umich.edu            }
4192817Sksewell@umich.edu        ''' % {"mnem" : mnem, "dest" : dest, "op1" : op1}
4202817Sksewell@umich.edu
4212817Sksewell@umich.edu    decode_block = '''
4222817Sksewell@umich.edu    {
4232817Sksewell@umich.edu        const uint32_t op = bits(machInst, 24, 21);
4242817Sksewell@umich.edu        const bool s = (bits(machInst, 20) == 1);
4252817Sksewell@umich.edu        const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
4262817Sksewell@umich.edu        const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
4272817Sksewell@umich.edu        const uint32_t ctrlImm = bits(machInst.instBits, 26) << 3 |
4282817Sksewell@umich.edu                                 bits(machInst, 14, 12);
4292817Sksewell@umich.edu        const bool rotC = ctrlImm > 3;
4302817Sksewell@umich.edu        const uint32_t dataImm = bits(machInst, 7, 0);
4312817Sksewell@umich.edu        const uint32_t imm = modified_imm(ctrlImm, dataImm);
4322817Sksewell@umich.edu        switch (op) {
4332817Sksewell@umich.edu          case 0x0:
4342817Sksewell@umich.edu            if (rd == INTREG_PC) {
4352817Sksewell@umich.edu                %(tst)s
4362817Sksewell@umich.edu            } else {
4372817Sksewell@umich.edu                %(and)s
4382817Sksewell@umich.edu            }
4392817Sksewell@umich.edu          case 0x1:
4402817Sksewell@umich.edu            %(bic)s
4412817Sksewell@umich.edu          case 0x2:
4422817Sksewell@umich.edu            if (rn == INTREG_PC) {
4432817Sksewell@umich.edu                %(mov)s
4443468Sgblack@eecs.umich.edu            } else {
4454172Ssaidi@eecs.umich.edu                %(orr)s
4462817Sksewell@umich.edu            }
4474172Ssaidi@eecs.umich.edu          case 0x3:
4482817Sksewell@umich.edu            if (rn == INTREG_PC) {
4492817Sksewell@umich.edu                %(mvn)s
4502817Sksewell@umich.edu            } else {
4512817Sksewell@umich.edu                %(orn)s
4522817Sksewell@umich.edu            }
4532817Sksewell@umich.edu          case 0x4:
4542817Sksewell@umich.edu            if (rd == INTREG_PC) {
4552817Sksewell@umich.edu                %(teq)s
4563468Sgblack@eecs.umich.edu            } else {
4574172Ssaidi@eecs.umich.edu                %(eor)s
4582817Sksewell@umich.edu            }
4592817Sksewell@umich.edu          case 0x8:
4604172Ssaidi@eecs.umich.edu            if (rd == INTREG_PC) {
4612817Sksewell@umich.edu                %(cmn)s
4622817Sksewell@umich.edu            } else {
4632817Sksewell@umich.edu                %(add)s
4642817Sksewell@umich.edu            }
4652817Sksewell@umich.edu          case 0xa:
4662817Sksewell@umich.edu            %(adc)s
4672817Sksewell@umich.edu          case 0xb:
4682817Sksewell@umich.edu            %(sbc)s
4692817Sksewell@umich.edu          case 0xd:
4702817Sksewell@umich.edu            if (rd == INTREG_PC) {
4712817Sksewell@umich.edu                %(cmp)s
4722817Sksewell@umich.edu            } else {
4732817Sksewell@umich.edu                %(sub)s
4742817Sksewell@umich.edu            }
4752817Sksewell@umich.edu          case 0xe:
4762817Sksewell@umich.edu            %(rsb)s
4772817Sksewell@umich.edu          default:
4782817Sksewell@umich.edu            return new Unknown(machInst);
4792817Sksewell@umich.edu        }
4802817Sksewell@umich.edu    }
4812817Sksewell@umich.edu    ''' % {
4822817Sksewell@umich.edu        "tst" : decInst("Tst", "INTREG_ZERO"),
4832817Sksewell@umich.edu        "and" : decInst("And"),
4842817Sksewell@umich.edu        "bic" : decInst("Bic"),
4852817Sksewell@umich.edu        "mov" : decInst("Mov", op1="INTREG_ZERO"),
4862817Sksewell@umich.edu        "orr" : decInst("Orr"),
4872817Sksewell@umich.edu        "mvn" : decInst("Mvn", op1="INTREG_ZERO"),
4882817Sksewell@umich.edu        "orn" : decInst("Orn"),
4892817Sksewell@umich.edu        "teq" : decInst("Teq", dest="INTREG_ZERO"),
4902817Sksewell@umich.edu        "eor" : decInst("Eor"),
4912817Sksewell@umich.edu        "cmn" : decInst("Cmn", dest="INTREG_ZERO"),
4922817Sksewell@umich.edu        "add" : decInst("Add"),
493        "adc" : decInst("Adc"),
494        "sbc" : decInst("Sbc"),
495        "cmp" : decInst("Cmp", dest="INTREG_ZERO"),
496        "sub" : decInst("Sub"),
497        "rsb" : decInst("Rsb")
498    }
499}};
500
501def format Thumb32DataProcPlainBin() {{
502    decode_block = '''
503    {
504        const uint32_t op = bits(machInst, 24, 20);
505        const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
506        const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
507        switch (op) {
508          case 0x0:
509            {
510                const uint32_t imm = bits(machInst, 7, 0) |
511                                     (bits(machInst, 14, 12) << 8) |
512                                     (bits(machInst, 26) << 11);
513                if (rn == 0xf) {
514                    return new AdrImm(machInst, rd, (IntRegIndex)1,
515                                      imm, false);
516                } else {
517                    return new AddImm(machInst, rd, rn, imm, true);
518                }
519            }
520          case 0x4:
521            {
522                const uint32_t imm = bits(machInst, 7, 0) |
523                                     (bits(machInst, 14, 12) << 8) |
524                                     (bits(machInst, 26) << 11) |
525                                     (bits(machInst, 19, 16) << 12);
526                return new MovImm(machInst, rd, INTREG_ZERO, imm, true);
527            }
528          case 0xa:
529            {
530                const uint32_t imm = bits(machInst, 7, 0) |
531                                     (bits(machInst, 14, 12) << 8) |
532                                     (bits(machInst, 26) << 11);
533                if (rn == 0xf) {
534                    return new AdrImm(machInst, rd, (IntRegIndex)0,
535                                      imm, false);
536                } else {
537                    return new SubImm(machInst, rd, rn, imm, true);
538                }
539            }
540          case 0xc:
541            {
542                const uint32_t imm = bits(machInst, 7, 0) |
543                                     (bits(machInst, 14, 12) << 8) |
544                                     (bits(machInst, 26) << 11) |
545                                     (bits(machInst, 19, 16) << 12);
546                return new MovtImm(machInst, rd, rd, imm, true);
547            }
548          case 0x12:
549            if (!(bits(machInst, 14, 12) || bits(machInst, 7, 6))) {
550                return new WarnUnimplemented("ssat16", machInst);
551            }
552            // Fall through on purpose...
553          case 0x10:
554            return new WarnUnimplemented("ssat", machInst);
555          case 0x14:
556            return new WarnUnimplemented("sbfx", machInst);
557          case 0x16:
558            if (rn == 0xf) {
559                return new WarnUnimplemented("bfc", machInst);
560            } else {
561                return new WarnUnimplemented("bfi", machInst);
562            }
563          case 0x1a:
564            if (!(bits(machInst, 14, 12) || bits(machInst, 7, 6))) {
565                return new WarnUnimplemented("usat16", machInst);
566            }
567            // Fall through on purpose...
568          case 0x18:
569            return new WarnUnimplemented("usat", machInst);
570          case 0x1c:
571            return new WarnUnimplemented("ubfx", machInst);
572          default:
573            return new Unknown(machInst);
574        }
575    }
576    '''
577}};
578
579def format Thumb32DataProcShiftReg() {{
580
581    def decInst(mnem, dest="rd", op1="rn"):
582        return '''
583            if (s) {
584                return new %(mnem)sRegCc(machInst, %(dest)s,
585                                          %(op1)s, rm, amt, type);
586            } else {
587                return new %(mnem)sReg(machInst, %(dest)s,
588                                        %(op1)s, rm, amt, type);
589            }
590        ''' % {"mnem" : mnem, "dest" : dest, "op1" : op1}
591
592    decode_block = '''
593    {
594        const uint32_t op = bits(machInst, 24, 21);
595        const bool s = (bits(machInst, 20) == 1);
596        const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
597        const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
598        const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
599        const uint32_t amt = (bits(machInst, 14, 12) << 2) |
600                              bits(machInst, 7, 6);
601        const ArmShiftType type = (ArmShiftType)(uint32_t)bits(machInst, 5, 4);
602        switch (op) {
603          case 0x0:
604            if (rd == INTREG_PC) {
605                %(tst)s
606            } else {
607                %(and)s
608            }
609          case 0x1:
610            %(bic)s
611          case 0x2:
612            if (rn == INTREG_PC) {
613                %(mov)s
614            } else {
615                %(orr)s
616            }
617          case 0x3:
618            if (rn == INTREG_PC) {
619                %(mvn)s
620            } else {
621                %(orn)s
622            }
623          case 0x4:
624            if (rd == INTREG_PC) {
625                %(teq)s
626            } else {
627                %(eor)s
628            }
629          case 0x6:
630            return new WarnUnimplemented("pkh", machInst);
631          case 0x8:
632            if (rd == INTREG_PC) {
633                %(cmn)s
634            } else {
635                %(add)s
636            }
637          case 0xa:
638            %(adc)s
639          case 0xb:
640            %(sbc)s
641          case 0xd:
642            if (rd == INTREG_PC) {
643                %(cmp)s
644            } else {
645                %(sub)s
646            }
647          case 0xe:
648            %(rsb)s
649          default:
650            return new Unknown(machInst);
651        }
652    }
653    ''' % {
654        "tst" : decInst("Tst", "INTREG_ZERO"),
655        "and" : decInst("And"),
656        "bic" : decInst("Bic"),
657        "mov" : decInst("Mov", op1="INTREG_ZERO"),
658        "orr" : decInst("Orr"),
659        "mvn" : decInst("Mvn", op1="INTREG_ZERO"),
660        "orn" : decInst("Orn"),
661        "teq" : decInst("Teq", "INTREG_ZERO"),
662        "eor" : decInst("Eor"),
663        "cmn" : decInst("Cmn", "INTREG_ZERO"),
664        "add" : decInst("Add"),
665        "adc" : decInst("Adc"),
666        "sbc" : decInst("Sbc"),
667        "cmp" : decInst("Cmp", "INTREG_ZERO"),
668        "sub" : decInst("Sub"),
669        "rsb" : decInst("Rsb")
670    }
671}};
672