data.isa revision 8782:10c9297e14d5
12SN/A// Copyright (c) 2010 ARM Limited
21762SN/A// All rights reserved
32SN/A//
42SN/A// The license below extends only to copyright in the software and shall
52SN/A// not be construed as granting a license to any other intellectual
62SN/A// property including but not limited to intellectual property relating
72SN/A// to a hardware implementation of the functionality of the software
82SN/A// licensed hereunder.  You may use the software subject to the license
92SN/A// terms below provided that you ensure that this notice is replicated
102SN/A// unmodified and in its entirety in all distributions of the software,
112SN/A// modified or unmodified, in source code or in binary form.
122SN/A//
132SN/A// Redistribution and use in source and binary forms, with or without
142SN/A// modification, are permitted provided that the following conditions are
152SN/A// met: redistributions of source code must retain the above copyright
162SN/A// notice, this list of conditions and the following disclaimer;
172SN/A// redistributions in binary form must reproduce the above copyright
182SN/A// notice, this list of conditions and the following disclaimer in the
192SN/A// documentation and/or other materials provided with the distribution;
202SN/A// neither the name of the copyright holders nor the names of its
212SN/A// contributors may be used to endorse or promote products derived from
222SN/A// this software without specific prior written permission.
232SN/A//
242SN/A// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
252SN/A// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
262SN/A// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
272665Ssaidi@eecs.umich.edu// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
282665Ssaidi@eecs.umich.edu// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
292SN/A// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
302SN/A// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
312439SN/A// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
322984Sgblack@eecs.umich.edu// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
33146SN/A// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
34146SN/A// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35146SN/A//
36146SN/A// Authors: Gabe Black
37146SN/A
38146SN/Adef format ArmMiscMedia() {{
391717SN/A    decode_block = '''
40146SN/A    {
411717SN/A        const uint32_t op1 = bits(machInst, 22, 20);
42146SN/A        const uint32_t op2 = bits(machInst, 7, 5);
431977SN/A        const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
442623SN/A        const IntRegIndex ra = (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
452683Sktlim@umich.edu        if (op1 == 0 && op2 == 0) {
461717SN/A            const IntRegIndex rd =
47146SN/A                (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
482683Sktlim@umich.edu            const IntRegIndex rm =
493348Sbinkertn@umich.edu                (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
502036SN/A            if (ra == 0xf) {
51146SN/A                return new Usad8(machInst, rd, rn, rm);
5256SN/A            } else {
5356SN/A                return new Usada8(machInst, rd, rn, rm, ra);
5456SN/A            }
55695SN/A        } else if (bits(op2, 1, 0) == 0x2) {
562901Ssaidi@eecs.umich.edu            const uint32_t lsb = bits(machInst, 11, 7);
572SN/A            const uint32_t msb = lsb + bits(machInst, 20, 16);
581858SN/A            if (bits(op1, 2, 1) == 0x3) {
593565Sgblack@eecs.umich.edu                return new Ubfx(machInst, ra, rn, lsb, msb);
603565Sgblack@eecs.umich.edu            } else if (bits(op1, 2, 1) == 0x1) {
612171SN/A                return new Sbfx(machInst, ra, rn, lsb, msb);
622170SN/A            }
633562Sgblack@eecs.umich.edu        } else if (bits(op2, 1, 0) == 0x0 && bits(op1, 2, 1) == 0x2) {
64146SN/A            const uint32_t lsb = bits(machInst, 11, 7);
652462SN/A            const uint32_t msb = bits(machInst, 20, 16);
66146SN/A            if (rn == 0xf) {
672SN/A                return new Bfc(machInst, ra, ra, lsb, msb);
682SN/A            } else {
692449SN/A                return new Bfi(machInst, ra, rn, lsb, msb);
701355SN/A            }
712623SN/A        }
724495Sacolyte@umich.edu        return new Unknown(machInst);
73224SN/A    }
741858SN/A    '''
752683Sktlim@umich.edu}};
762420SN/A
772683Sktlim@umich.edudef format ArmDataProcReg() {{
784997Sgblack@eecs.umich.edu    pclr = '''
792420SN/A        return new %(className)ssRegPclr(machInst, %(dest)s,
802SN/A                                        %(op1)s, rm, imm5,
814400Srdreslin@umich.edu                                        type);
822672Sktlim@umich.edu    '''
832683Sktlim@umich.edu    instDecode = '''
842SN/A          case %(opcode)#x:
852SN/A            if (immShift) {
86334SN/A                if (setCc) {
87140SN/A                    if (%(dest)s == INTREG_PC) {
88334SN/A                        %(pclr)s
892SN/A                    } else {
902SN/A                        return new %(className)sRegCc(machInst, %(dest)s,
912SN/A                                                      %(op1)s, rm, imm5, type);
922680Sktlim@umich.edu                    }
934377Sgblack@eecs.umich.edu                } else {
944377Sgblack@eecs.umich.edu                    return new %(className)sReg(machInst, %(dest)s, %(op1)s,
954377Sgblack@eecs.umich.edu                                                 rm, imm5, type);
962SN/A                }
972SN/A            } else {
982623SN/A                if (setCc) {
992SN/A                    return new %(className)sRegRegCc(machInst, %(dest)s,
1002SN/A                                                      %(op1)s, rm, rs, type);
1012SN/A                } else {
102180SN/A                    return new %(className)sRegReg(machInst, %(dest)s,
1032623SN/A                                                    %(op1)s, rm, rs, type);
104393SN/A                }
105393SN/A            }
106393SN/A            break;
107393SN/A    '''
108384SN/A
109384SN/A    def instCode(opcode, mnem, useDest = True, useOp1 = True):
110393SN/A        global pclr
1112623SN/A        if useDest:
112393SN/A            dest = "rd"
113393SN/A        else:
114393SN/A            dest = "INTREG_ZERO"
115393SN/A        if useOp1:
116384SN/A            op1 = "rn"
117189SN/A        else:
118189SN/A            op1 = "INTREG_ZERO"
1192623SN/A        global instDecode, pclrCode
1202SN/A        substDict = { "className": mnem.capitalize(),
121729SN/A                      "opcode": opcode,
122334SN/A                      "dest": dest,
1232SN/A                      "op1": op1 }
1242SN/A        if useDest:
1252SN/A            substDict["pclr"] = pclr % substDict
1262SN/A        else:
1272SN/A            substDict["pclr"] = ""
1282SN/A        return instDecode % substDict
1292SN/A
1302SN/A    decode_block = '''
1312SN/A    {
1322SN/A        const bool immShift = (bits(machInst, 4) == 0);
1332SN/A        const bool setCc = (bits(machInst, 20) == 1);
1342SN/A        const uint32_t imm5 = bits(machInst, 11, 7);
1351001SN/A        const ArmShiftType type = (ArmShiftType)(uint32_t)bits(machInst, 6, 5);
1361001SN/A        const IntRegIndex rd = (IntRegIndex)(uint32_t)RD;
1371001SN/A        const IntRegIndex rn = (IntRegIndex)(uint32_t)RN;
1381001SN/A        const IntRegIndex rm = (IntRegIndex)(uint32_t)RM;
1391001SN/A        const IntRegIndex rs = (IntRegIndex)(uint32_t)RS;
1402SN/A        switch (OPCODE) {
1412SN/A    '''
1422SN/A    decode_block += instCode(0x0, "and")
1432SN/A    decode_block += instCode(0x1, "eor")
1442SN/A    decode_block += instCode(0x2, "sub")
1452SN/A    decode_block += instCode(0x3, "rsb")
1462SN/A    decode_block += instCode(0x4, "add")
1472SN/A    decode_block += instCode(0x5, "adc")
1482SN/A    decode_block += instCode(0x6, "sbc")
1492SN/A    decode_block += instCode(0x7, "rsc")
1502SN/A    decode_block += instCode(0x8, "tst", useDest = False)
1512SN/A    decode_block += instCode(0x9, "teq", useDest = False)
1522SN/A    decode_block += instCode(0xa, "cmp", useDest = False)
1532SN/A    decode_block += instCode(0xb, "cmn", useDest = False)
1542SN/A    decode_block += instCode(0xc, "orr")
1552SN/A    decode_block += instCode(0xd, "mov", useOp1 = False)
1562SN/A    decode_block += instCode(0xe, "bic")
1572390SN/A    decode_block += instCode(0xf, "mvn", useOp1 = False)
1582390SN/A    decode_block += '''
1592390SN/A          default:
1602390SN/A            return new Unknown(machInst);
1612390SN/A        }
1622390SN/A    }
1632390SN/A    '''
1642390SN/A}};
1652390SN/A
1662390SN/Adef format ArmPackUnpackSatReverse() {{
1672390SN/A    decode_block = '''
1682390SN/A    {
169385SN/A        const uint32_t op1 = bits(machInst, 22, 20);
1702SN/A        const uint32_t a = bits(machInst, 19, 16);
1712SN/A        const uint32_t op2 = bits(machInst, 7, 5);
1722SN/A        if (bits(op2, 0) == 0) {
1732623SN/A            const IntRegIndex rn =
174334SN/A                (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
1752361SN/A            const IntRegIndex rd =
1762623SN/A                (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
177334SN/A            const uint32_t satImm = bits(machInst, 20, 16);
178334SN/A            const uint32_t imm = bits(machInst, 11, 7);
179334SN/A            const ArmShiftType type =
1802623SN/A                (ArmShiftType)(uint32_t)bits(machInst, 6, 5);
1812SN/A            if (op1 == 0) {
182921SN/A                if (type) {
1832915Sktlim@umich.edu                    return new PkhtbReg(machInst, rd, (IntRegIndex)a,
1842915Sktlim@umich.edu                                        rn, imm, type);
1852683Sktlim@umich.edu                } else {
1862SN/A                    return new PkhbtReg(machInst, rd, (IntRegIndex)a,
1872SN/A                                        rn, imm, type);
1882SN/A                }
1892623SN/A            } else if (bits(op1, 2, 1) == 1) {
1902SN/A                return new Ssat(machInst, rd, satImm + 1, rn, imm, type);
191921SN/A            } else if (bits(op1, 2, 1) == 3) {
1922915Sktlim@umich.edu                return new Usat(machInst, rd, satImm, rn, imm, type);
1932915Sktlim@umich.edu            }
1942SN/A            return new Unknown(machInst);
1952SN/A        }
1962SN/A        switch (op1) {
1972SN/A          case 0x0:
1982SN/A            {
1992SN/A                const IntRegIndex rn =
2002SN/A                    (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
201595SN/A                const IntRegIndex rd =
2022623SN/A                    (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
203595SN/A                const IntRegIndex rm =
2042390SN/A                    (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
2051080SN/A                if (op2 == 0x3) {
2061080SN/A                    const uint32_t rotation =
2071080SN/A                        (uint32_t)bits(machInst, 11, 10) << 3;
2081080SN/A                    if (a == 0xf) {
2091080SN/A                        return new Sxtb16(machInst, rd, rotation, rm);
2101080SN/A                    } else {
2111080SN/A                        return new Sxtab16(machInst, rd, rn, rm, rotation);
2121121SN/A                    }
2132107SN/A                } else if (op2 == 0x5) {
2141089SN/A                    return new Sel(machInst, rd, rn, rm);
2151089SN/A                }
2161080SN/A            }
2171080SN/A            break;
2181080SN/A          case 0x2:
2191080SN/A            if (op2 == 0x1) {
220595SN/A                const IntRegIndex rn =
2212623SN/A                    (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
2222683Sktlim@umich.edu                const IntRegIndex rd =
223595SN/A                    (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
2242090SN/A                const uint32_t satImm = bits(machInst, 20, 16);
2252683Sktlim@umich.edu                return new Ssat16(machInst, rd, satImm + 1, rn);
2262683Sktlim@umich.edu            } else if (op2 == 0x3) {
227595SN/A                const IntRegIndex rn =
2282205SN/A                    (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
2292205SN/A                const IntRegIndex rd =
2302683Sktlim@umich.edu                    (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
2312683Sktlim@umich.edu                const IntRegIndex rm =
232595SN/A                    (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
233595SN/A                const uint32_t rotation =
2342390SN/A                    (uint32_t)bits(machInst, 11, 10) << 3;
2352423SN/A                if (a == 0xf) {
2362390SN/A                    return new Sxtb(machInst, rd, rotation, rm);
237595SN/A                } else {
238595SN/A                    return new Sxtab(machInst, rd, rn, rm, rotation);
239595SN/A                }
2402623SN/A            }
241595SN/A            break;
2422390SN/A          case 0x3:
2431080SN/A            if (op2 == 0x1) {
244595SN/A                IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
2451080SN/A                IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
2461080SN/A                return new Rev(machInst, rd, rm);
247595SN/A            } else if (op2 == 0x3) {
2482683Sktlim@umich.edu                const IntRegIndex rn =
2491080SN/A                    (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
2501080SN/A                const IntRegIndex rd =
2511080SN/A                    (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
2521121SN/A                const IntRegIndex rm =
2532107SN/A                    (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
2541089SN/A                const uint32_t rotation =
2551080SN/A                    (uint32_t)bits(machInst, 11, 10) << 3;
2561089SN/A                if (a == 0xf) {
2571080SN/A                    return new Sxth(machInst, rd, rotation, rm);
2581080SN/A                } else {
2591080SN/A                    return new Sxtah(machInst, rd, rn, rm, rotation);
260595SN/A                }
2612683Sktlim@umich.edu            } else if (op2 == 0x5) {
2621080SN/A                IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
2632090SN/A                IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
2641080SN/A                return new Rev16(machInst, rd, rm);
265595SN/A            }
2662683Sktlim@umich.edu            break;
2672683Sktlim@umich.edu          case 0x4:
268595SN/A            if (op2 == 0x3) {
2692683Sktlim@umich.edu                const IntRegIndex rn =
2701098SN/A                    (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
2711098SN/A                const IntRegIndex rd =
2721098SN/A                    (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
2732683Sktlim@umich.edu                const IntRegIndex rm =
2741098SN/A                    (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
2751098SN/A                const uint32_t rotation =
2761098SN/A                    (uint32_t)bits(machInst, 11, 10) << 3;
2772012SN/A                if (a == 0xf) {
2781098SN/A                    return new Uxtb16(machInst, rd, rotation, rm);
2791098SN/A                } else {
280595SN/A                    return new Uxtab16(machInst, rd, rn, rm, rotation);
2812205SN/A                }
2822205SN/A            }
2832205SN/A            break;
284595SN/A          case 0x6:
2852390SN/A            if (op2 == 0x1) {
2862420SN/A                const IntRegIndex rn =
2872423SN/A                    (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
2882390SN/A                const IntRegIndex rd =
289595SN/A                    (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
290595SN/A                const uint32_t satImm = bits(machInst, 20, 16);
2911858SN/A                return new Usat16(machInst, rd, satImm, rn);
2922SN/A            } else if (op2 == 0x3) {
2932623SN/A                const IntRegIndex rn =
2942SN/A                    (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
2952680Sktlim@umich.edu                const IntRegIndex rd =
2962SN/A                    (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
2972SN/A                const IntRegIndex rm =
2982SN/A                    (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
2991858SN/A                const uint32_t rotation =
3002SN/A                    (uint32_t)bits(machInst, 11, 10) << 3;
3012623SN/A                if (a == 0xf) {
3022SN/A                    return new Uxtb(machInst, rd, rotation, rm);
3032SN/A                } else {
3042SN/A                    return new Uxtab(machInst, rd, rn, rm, rotation);
3052683Sktlim@umich.edu                }
3064216Ssaidi@eecs.umich.edu            }
3072683Sktlim@umich.edu            break;
3082SN/A          case 0x7:
3092SN/A            {
3102SN/A                const IntRegIndex rn =
3112SN/A                    (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
3122SN/A                const IntRegIndex rd =
3132623SN/A                    (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
3142SN/A                const IntRegIndex rm =
3151858SN/A                    (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
3163923Shsul@eecs.umich.edu                if (op2 == 0x1) {
3173520Sgblack@eecs.umich.edu                    return new Rbit(machInst, rd, rm);
3182SN/A                } else if (op2 == 0x3) {
3193520Sgblack@eecs.umich.edu                    const uint32_t rotation =
3203633Sktlim@umich.edu                        (uint32_t)bits(machInst, 11, 10) << 3;
3213520Sgblack@eecs.umich.edu                    if (a == 0xf) {
3222SN/A                        return new Uxth(machInst, rd, rotation, rm);
3232SN/A                    } else {
3242SN/A                        return new Uxtah(machInst, rd, rn, rm, rotation);
3252623SN/A                    }
3262SN/A                } else if (op2 == 0x5) {
3272623SN/A                    return new Revsh(machInst, rd, rm);
3282623SN/A                }
3292662Sstever@eecs.umich.edu            }
3302623SN/A            break;
3314514Ssaidi@eecs.umich.edu        }
3324495Sacolyte@umich.edu        return new Unknown(machInst);
3332623SN/A    }
3343093Sksewell@umich.edu    '''
3354495Sacolyte@umich.edu}};
3363093Sksewell@umich.edu
3373093Sksewell@umich.edudef format ArmParallelAddSubtract() {{
3384564Sgblack@eecs.umich.edu    decode_block='''
3392741Sksewell@umich.edu    {
3402741Sksewell@umich.edu        const uint32_t op1 = bits(machInst, 21, 20);
3412623SN/A        const uint32_t op2 = bits(machInst, 7, 5);
3424564Sgblack@eecs.umich.edu        const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
3434564Sgblack@eecs.umich.edu        const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
3442623SN/A        const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
3452683Sktlim@umich.edu        if (bits(machInst, 22) == 0) {
3462623SN/A            switch (op1) {
3472623SN/A              case 0x1:
3482623SN/A                switch (op2) {
3492623SN/A                  case 0x0:
3502623SN/A                    return new Sadd16RegCc(machInst, rd, rn, rm, 0, LSL);
3512623SN/A                  case 0x1:
3522623SN/A                    return new SasxRegCc(machInst, rd, rn, rm, 0, LSL);
3532623SN/A                  case 0x2:
3542SN/A                    return new SsaxRegCc(machInst, rd, rn, rm, 0, LSL);
3552683Sktlim@umich.edu                  case 0x3:
3562427SN/A                    return new Ssub16RegCc(machInst, rd, rn, rm, 0, LSL);
3572683Sktlim@umich.edu                  case 0x4:
3582427SN/A                    return new Sadd8RegCc(machInst, rd, rn, rm, 0, LSL);
3592SN/A                  case 0x7:
3602623SN/A                    return new Ssub8RegCc(machInst, rd, rn, rm, 0, LSL);
3612623SN/A                }
3622SN/A                break;
3632623SN/A              case 0x2:
3642623SN/A                switch (op2) {
3654377Sgblack@eecs.umich.edu                  case 0x0:
3663276Sgblack@eecs.umich.edu                    return new Qadd16Reg(machInst, rd, rn, rm, 0, LSL);
3673276Sgblack@eecs.umich.edu                  case 0x1:
3684377Sgblack@eecs.umich.edu                    return new QasxReg(machInst, rd, rn, rm, 0, LSL);
3694181Sgblack@eecs.umich.edu                  case 0x2:
3704181Sgblack@eecs.umich.edu                    return new QsaxReg(machInst, rd, rn, rm, 0, LSL);
3714181Sgblack@eecs.umich.edu                  case 0x3:
3724182Sgblack@eecs.umich.edu                    return new Qsub16Reg(machInst, rd, rn, rm, 0, LSL);
3734182Sgblack@eecs.umich.edu                  case 0x4:
3744182Sgblack@eecs.umich.edu                    return new Qadd8Reg(machInst, rd, rn, rm, 0, LSL);
3754593Sgblack@eecs.umich.edu                  case 0x7:
3764593Sgblack@eecs.umich.edu                    return new Qsub8Reg(machInst, rd, rn, rm, 0, LSL);
3774593Sgblack@eecs.umich.edu                }
3784593Sgblack@eecs.umich.edu                break;
3794593Sgblack@eecs.umich.edu              case 0x3:
3804377Sgblack@eecs.umich.edu                switch (op2) {
3814377Sgblack@eecs.umich.edu                  case 0x0:
3824377Sgblack@eecs.umich.edu                    return new Shadd16Reg(machInst, rd, rn, rm, 0, LSL);
3834377Sgblack@eecs.umich.edu                  case 0x1:
3844377Sgblack@eecs.umich.edu                    return new ShasxReg(machInst, rd, rn, rm, 0, LSL);
3854377Sgblack@eecs.umich.edu                  case 0x2:
3864377Sgblack@eecs.umich.edu                    return new ShsaxReg(machInst, rd, rn, rm, 0, LSL);
3874377Sgblack@eecs.umich.edu                  case 0x3:
3884572Sacolyte@umich.edu                    return new Shsub16Reg(machInst, rd, rn, rm, 0, LSL);
3894572Sacolyte@umich.edu                  case 0x4:
3904377Sgblack@eecs.umich.edu                    return new Shadd8Reg(machInst, rd, rn, rm, 0, LSL);
3914377Sgblack@eecs.umich.edu                  case 0x7:
3924377Sgblack@eecs.umich.edu                    return new Shsub8Reg(machInst, rd, rn, rm, 0, LSL);
3934377Sgblack@eecs.umich.edu                }
3944181Sgblack@eecs.umich.edu                break;
3954181Sgblack@eecs.umich.edu            }
3964181Sgblack@eecs.umich.edu        } else {
3974539Sgblack@eecs.umich.edu            switch (op1) {
3983276Sgblack@eecs.umich.edu              case 0x1:
3993442Sgblack@eecs.umich.edu                switch (op2) {
4004539Sgblack@eecs.umich.edu                  case 0x0:
4013280Sgblack@eecs.umich.edu                    return new Uadd16RegCc(machInst, rd, rn, rm, 0, LSL);
4023280Sgblack@eecs.umich.edu                  case 0x1:
4033276Sgblack@eecs.umich.edu                    return new UasxRegCc(machInst, rd, rn, rm, 0, LSL);
4043276Sgblack@eecs.umich.edu                  case 0x2:
4053276Sgblack@eecs.umich.edu                    return new UsaxRegCc(machInst, rd, rn, rm, 0, LSL);
4063442Sgblack@eecs.umich.edu                  case 0x3:
4074539Sgblack@eecs.umich.edu                    return new Usub16RegCc(machInst, rd, rn, rm, 0, LSL);
4083276Sgblack@eecs.umich.edu                  case 0x4:
4093276Sgblack@eecs.umich.edu                    return new Uadd8RegCc(machInst, rd, rn, rm, 0, LSL);
4104181Sgblack@eecs.umich.edu                  case 0x7:
4114181Sgblack@eecs.umich.edu                    return new Usub8RegCc(machInst, rd, rn, rm, 0, LSL);
4124181Sgblack@eecs.umich.edu                }
4134522Ssaidi@eecs.umich.edu                break;
4144776Sgblack@eecs.umich.edu              case 0x2:
4154181Sgblack@eecs.umich.edu                switch (op2) {
4162470SN/A                  case 0x0:
4174181Sgblack@eecs.umich.edu                    return new Uqadd16Reg(machInst, rd, rn, rm, 0, LSL);
4184181Sgblack@eecs.umich.edu                  case 0x1:
4194522Ssaidi@eecs.umich.edu                    return new UqasxReg(machInst, rd, rn, rm, 0, LSL);
4202623SN/A                  case 0x2:
4212623SN/A                    return new UqsaxReg(machInst, rd, rn, rm, 0, LSL);
4224181Sgblack@eecs.umich.edu                  case 0x3:
4232623SN/A                    return new Uqsub16Reg(machInst, rd, rn, rm, 0, LSL);
4244181Sgblack@eecs.umich.edu                  case 0x4:
4252623SN/A                    return new Uqadd8Reg(machInst, rd, rn, rm, 0, LSL);
4262623SN/A                  case 0x7:
4272623SN/A                    return new Uqsub8Reg(machInst, rd, rn, rm, 0, LSL);
4282623SN/A                }
4292623SN/A                break;
4302623SN/A              case 0x3:
4315086Sgblack@eecs.umich.edu                switch (op2) {
4323577Sgblack@eecs.umich.edu                  case 0x0:
4332683Sktlim@umich.edu                    return new Uhadd16Reg(machInst, rd, rn, rm, 0, LSL);
4345086Sgblack@eecs.umich.edu                  case 0x1:
4352623SN/A                    return new UhasxReg(machInst, rd, rn, rm, 0, LSL);
4362683Sktlim@umich.edu                  case 0x2:
4372623SN/A                    return new UhsaxReg(machInst, rd, rn, rm, 0, LSL);
4382420SN/A                  case 0x3:
4392SN/A                    return new Uhsub16Reg(machInst, rd, rn, rm, 0, LSL);
4402623SN/A                  case 0x4:
4412623SN/A                    return new Uhadd8Reg(machInst, rd, rn, rm, 0, LSL);
4422SN/A                  case 0x7:
4432SN/A                    return new Uhsub8Reg(machInst, rd, rn, rm, 0, LSL);
4442623SN/A                }
4452623SN/A                break;
4462623SN/A            }
4472623SN/A        }
4482SN/A        return new Unknown(machInst);
4492683Sktlim@umich.edu    }
4502644Sstever@eecs.umich.edu    '''
4512644Sstever@eecs.umich.edu}};
4524046Sbinkertn@umich.edu
4534046Sbinkertn@umich.edudef format ArmDataProcImm() {{
4544046Sbinkertn@umich.edu    pclr = '''
4552644Sstever@eecs.umich.edu        return new %(className)ssImmPclr(machInst, %(dest)s,
4562623SN/A                                        %(op1)s, imm, false);
4572SN/A    '''
4582SN/A    adr = '''
4592623SN/A        return new AdrImm(machInst, %(dest)s, %(add)s,
4602623SN/A                                     imm, false);
4612623SN/A    '''
4624377Sgblack@eecs.umich.edu    instDecode = '''
4634377Sgblack@eecs.umich.edu          case %(opcode)#x:
4642090SN/A            if (setCc) {
4653905Ssaidi@eecs.umich.edu                if (%(pclrInst)s && %(dest)s == INTREG_PC) {
4665120Sgblack@eecs.umich.edu                    %(pclr)s
4672680Sktlim@umich.edu                } else {
4683929Ssaidi@eecs.umich.edu                    return new %(className)sImmCc(machInst, %(dest)s, %(op1)s,
4693929Ssaidi@eecs.umich.edu                                                   imm, rotC);
4704377Sgblack@eecs.umich.edu                }
4713276Sgblack@eecs.umich.edu            } else {
4724539Sgblack@eecs.umich.edu                if (%(adrInst)s && %(op1)s == INTREG_PC) {
4733276Sgblack@eecs.umich.edu                    %(adr)s
4743276Sgblack@eecs.umich.edu                } else {
4753276Sgblack@eecs.umich.edu                    return new %(className)sImm(machInst, %(dest)s, %(op1)s,
4763276Sgblack@eecs.umich.edu                                                 imm, rotC);
4773280Sgblack@eecs.umich.edu                }
4783276Sgblack@eecs.umich.edu            }
4793280Sgblack@eecs.umich.edu            break;
4803276Sgblack@eecs.umich.edu    '''
4813276Sgblack@eecs.umich.edu
4823276Sgblack@eecs.umich.edu    def instCode(opcode, mnem, useDest = True, useOp1 = True):
4833276Sgblack@eecs.umich.edu        global instDecode, pclr, adr
4843280Sgblack@eecs.umich.edu        if useDest:
4853276Sgblack@eecs.umich.edu            dest = "rd"
4863276Sgblack@eecs.umich.edu        else:
4873280Sgblack@eecs.umich.edu            dest = "INTREG_ZERO"
4883276Sgblack@eecs.umich.edu        if useOp1:
4893276Sgblack@eecs.umich.edu            op1 = "rn"
4903276Sgblack@eecs.umich.edu        else:
4913276Sgblack@eecs.umich.edu            op1 = "INTREG_ZERO"
4923276Sgblack@eecs.umich.edu        substDict = { "className": mnem.capitalize(),
4933276Sgblack@eecs.umich.edu                      "opcode": opcode,
4943276Sgblack@eecs.umich.edu                      "dest": dest,
4952SN/A                      "op1": op1,
4962SN/A                      "adr": "",
4971858SN/A                      "adrInst": "false" }
4982SN/A        if useDest:
4992SN/A            substDict["pclrInst"] = "true"
5002683Sktlim@umich.edu            substDict["pclr"] = pclr % substDict
5012680Sktlim@umich.edu        else:
5022683Sktlim@umich.edu            substDict["pclrInst"] = "false"
5032SN/A            substDict["pclr"] = ""
5042SN/A        return instDecode % substDict
5052SN/A
506    def adrCode(opcode, mnem, add="1"):
507        global instDecode, pclr, adr
508        substDict = { "className": mnem.capitalize(),
509                      "opcode": opcode,
510                      "dest": "rd",
511                      "op1": "rn",
512                      "add": add,
513                      "pclrInst": "true",
514                      "adrInst": "true" }
515        substDict["pclr"] = pclr % substDict
516        substDict["adr"] = adr % substDict
517        return instDecode % substDict
518
519    decode_block = '''
520    {
521        const bool setCc = (bits(machInst, 20) == 1);
522        const uint32_t unrotated = bits(machInst, 7, 0);
523        const uint32_t rotation = (bits(machInst, 11, 8) << 1);
524        const bool rotC = (rotation != 0);
525        const uint32_t imm = rotate_imm(unrotated, rotation);
526        const IntRegIndex rd = (IntRegIndex)(uint32_t)RD;
527        const IntRegIndex rn = (IntRegIndex)(uint32_t)RN;
528        switch (OPCODE) {
529    '''
530    decode_block += instCode(0x0, "and")
531    decode_block += instCode(0x1, "eor")
532    decode_block += adrCode(0x2, "sub", add="(IntRegIndex)0")
533    decode_block += instCode(0x3, "rsb")
534    decode_block += adrCode(0x4, "add", add="(IntRegIndex)1")
535    decode_block += instCode(0x5, "adc")
536    decode_block += instCode(0x6, "sbc")
537    decode_block += instCode(0x7, "rsc")
538    decode_block += instCode(0x8, "tst", useDest = False)
539    decode_block += instCode(0x9, "teq", useDest = False)
540    decode_block += instCode(0xa, "cmp", useDest = False)
541    decode_block += instCode(0xb, "cmn", useDest = False)
542    decode_block += instCode(0xc, "orr")
543    decode_block += instCode(0xd, "mov", useOp1 = False)
544    decode_block += instCode(0xe, "bic")
545    decode_block += instCode(0xf, "mvn", useOp1 = False)
546    decode_block += '''
547          default:
548            return new Unknown(machInst);
549        }
550    }
551    '''
552}};
553
554def format ArmSatAddSub() {{
555    decode_block = '''
556    {
557        IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
558        IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
559        IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
560        switch (OPCODE) {
561          case 0x8:
562            return new QaddRegCc(machInst, rd, rm, rn, 0, LSL);
563          case 0x9:
564            return new QsubRegCc(machInst, rd, rm, rn, 0, LSL);
565          case 0xa:
566            return new QdaddRegCc(machInst, rd, rm, rn, 0, LSL);
567          case 0xb:
568            return new QdsubRegCc(machInst, rd, rm, rn, 0, LSL);
569          default:
570            return new Unknown(machInst);
571        }
572    }
573    '''
574}};
575
576def format Thumb32DataProcReg() {{
577    decode_block = '''
578    {
579        const uint32_t op1 = bits(machInst, 23, 20);
580        const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
581        const uint32_t op2 = bits(machInst, 7, 4);
582        if (bits(machInst, 15, 12) != 0xf) {
583            return new Unknown(machInst);
584        }
585        if (bits(op1, 3) != 1) {
586            if (op2 == 0) {
587                IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
588                IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
589                switch (bits(op1, 2, 0)) {
590                  case 0x0:
591                    return new MovRegReg(machInst, rd,
592                            INTREG_ZERO, rn, rm, LSL);
593                  case 0x1:
594                    return new MovRegRegCc(machInst, rd,
595                            INTREG_ZERO, rn, rm, LSL);
596                  case 0x2:
597                    return new MovRegReg(machInst, rd,
598                            INTREG_ZERO, rn, rm, LSR);
599                  case 0x3:
600                    return new MovRegRegCc(machInst, rd,
601                            INTREG_ZERO, rn, rm, LSR);
602                  case 0x4:
603                    return new MovRegReg(machInst, rd,
604                            INTREG_ZERO, rn, rm, ASR);
605                  case 0x5:
606                    return new MovRegRegCc(machInst, rd,
607                            INTREG_ZERO, rn, rm, ASR);
608                  case 0x6:
609                    return new MovRegReg(machInst, rd,
610                            INTREG_ZERO, rn, rm, ROR);
611                  case 0x7:
612                    return new MovRegRegCc(machInst, rd,
613                            INTREG_ZERO, rn, rm, ROR);
614                }
615            } else if (bits(op2, 3) == 0) {
616                return new Unknown(machInst);
617            } else {
618                const IntRegIndex rd =
619                    (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
620                const IntRegIndex rm =
621                    (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
622                const uint32_t rotation =
623                    (uint32_t)bits(machInst, 5, 4) << 3;
624                switch (bits(op1, 2, 0)) {
625                  case 0x0:
626                    if (rn == 0xf) {
627                        return new Sxth(machInst, rd, rotation, rm);
628                    } else {
629                        return new Sxtah(machInst, rd, rn, rm, rotation);
630                    }
631                  case 0x1:
632                    if (rn == 0xf) {
633                        return new Uxth(machInst, rd, rotation, rm);
634                    } else {
635                        return new Uxtah(machInst, rd, rn, rm, rotation);
636                    }
637                  case 0x2:
638                    if (rn == 0xf) {
639                        return new Sxtb16(machInst, rd, rotation, rm);
640                    } else {
641                        return new Sxtab16(machInst, rd, rn, rm, rotation);
642                    }
643                  case 0x3:
644                    if (rn == 0xf) {
645                        return new Uxtb16(machInst, rd, rotation, rm);
646                    } else {
647                        return new Uxtab16(machInst, rd, rn, rm, rotation);
648                    }
649                  case 0x4:
650                    if (rn == 0xf) {
651                        return new Sxtb(machInst, rd, rotation, rm);
652                    } else {
653                        return new Sxtab(machInst, rd, rn, rm, rotation);
654                    }
655                  case 0x5:
656                    if (rn == 0xf) {
657                        return new Uxtb(machInst, rd, rotation, rm);
658                    } else {
659                        return new Uxtab(machInst, rd, rn, rm, rotation);
660                    }
661                  default:
662                    return new Unknown(machInst);
663                }
664            }
665        } else {
666            if (bits(op2, 3) == 0) {
667                const IntRegIndex rd =
668                    (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
669                const IntRegIndex rm =
670                    (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
671                if (bits(op2, 2) == 0x0) {
672                    const uint32_t op1 = bits(machInst, 22, 20);
673                    const uint32_t op2 = bits(machInst, 5, 4);
674                    switch (op2) {
675                      case 0x0:
676                        switch (op1) {
677                          case 0x1:
678                            return new Sadd16RegCc(machInst, rd,
679                                                   rn, rm, 0, LSL);
680                          case 0x2:
681                            return new SasxRegCc(machInst, rd,
682                                                 rn, rm, 0, LSL);
683                          case 0x6:
684                            return new SsaxRegCc(machInst, rd,
685                                                 rn, rm, 0, LSL);
686                          case 0x5:
687                            return new Ssub16RegCc(machInst, rd,
688                                                   rn, rm, 0, LSL);
689                          case 0x0:
690                            return new Sadd8RegCc(machInst, rd,
691                                                  rn, rm, 0, LSL);
692                          case 0x4:
693                            return new Ssub8RegCc(machInst, rd,
694                                                  rn, rm, 0, LSL);
695                        }
696                        break;
697                      case 0x1:
698                        switch (op1) {
699                          case 0x1:
700                            return new Qadd16Reg(machInst, rd, rn, rm, 0, LSL);
701                          case 0x2:
702                            return new QasxReg(machInst, rd, rn, rm, 0, LSL);
703                          case 0x6:
704                            return new QsaxReg(machInst, rd, rn, rm, 0, LSL);
705                          case 0x5:
706                            return new Qsub16Reg(machInst, rd, rn, rm, 0, LSL);
707                          case 0x0:
708                            return new Qadd8Reg(machInst, rd, rn, rm, 0, LSL);
709                          case 0x4:
710                            return new Qsub8Reg(machInst, rd, rn, rm, 0, LSL);
711                        }
712                        break;
713                      case 0x2:
714                        switch (op1) {
715                          case 0x1:
716                            return new Shadd16Reg(machInst, rd, rn, rm, 0, LSL);
717                          case 0x2:
718                            return new ShasxReg(machInst, rd, rn, rm, 0, LSL);
719                          case 0x6:
720                            return new ShsaxReg(machInst, rd, rn, rm, 0, LSL);
721                          case 0x5:
722                            return new Shsub16Reg(machInst, rd, rn, rm, 0, LSL);
723                          case 0x0:
724                            return new Shadd8Reg(machInst, rd, rn, rm, 0, LSL);
725                          case 0x4:
726                            return new Shsub8Reg(machInst, rd, rn, rm, 0, LSL);
727                        }
728                        break;
729                    }
730                } else {
731                    const uint32_t op1 = bits(machInst, 22, 20);
732                    const uint32_t op2 = bits(machInst, 5, 4);
733                    switch (op2) {
734                      case 0x0:
735                        switch (op1) {
736                          case 0x1:
737                            return new Uadd16RegCc(machInst, rd,
738                                                   rn, rm, 0, LSL);
739                          case 0x2:
740                            return new UasxRegCc(machInst, rd,
741                                                 rn, rm, 0, LSL);
742                          case 0x6:
743                            return new UsaxRegCc(machInst, rd,
744                                                 rn, rm, 0, LSL);
745                          case 0x5:
746                            return new Usub16RegCc(machInst, rd,
747                                                   rn, rm, 0, LSL);
748                          case 0x0:
749                            return new Uadd8RegCc(machInst, rd,
750                                                  rn, rm, 0, LSL);
751                          case 0x4:
752                            return new Usub8RegCc(machInst, rd,
753                                                  rn, rm, 0, LSL);
754                        }
755                        break;
756                      case 0x1:
757                        switch (op1) {
758                          case 0x1:
759                            return new Uqadd16Reg(machInst, rd, rn, rm, 0, LSL);
760                          case 0x2:
761                            return new UqasxReg(machInst, rd, rn, rm, 0, LSL);
762                          case 0x6:
763                            return new UqsaxReg(machInst, rd, rn, rm, 0, LSL);
764                          case 0x5:
765                            return new Uqsub16Reg(machInst, rd, rn, rm, 0, LSL);
766                          case 0x0:
767                            return new Uqadd8Reg(machInst, rd, rn, rm, 0, LSL);
768                          case 0x4:
769                            return new Uqsub8Reg(machInst, rd, rn, rm, 0, LSL);
770                        }
771                        break;
772                      case 0x2:
773                        switch (op1) {
774                          case 0x1:
775                            return new Uhadd16Reg(machInst, rd, rn, rm, 0, LSL);
776                          case 0x2:
777                            return new UhasxReg(machInst, rd, rn, rm, 0, LSL);
778                          case 0x6:
779                            return new UhsaxReg(machInst, rd, rn, rm, 0, LSL);
780                          case 0x5:
781                            return new Uhsub16Reg(machInst, rd, rn, rm, 0, LSL);
782                          case 0x0:
783                            return new Uhadd8Reg(machInst, rd, rn, rm, 0, LSL);
784                          case 0x4:
785                            return new Uhsub8Reg(machInst, rd, rn, rm, 0, LSL);
786                        }
787                        break;
788                    }
789                }
790            } else if (bits(op1, 3, 2) == 0x2 && bits(op2, 3, 2) == 0x2) {
791                const uint32_t op1 = bits(machInst, 21, 20);
792                const uint32_t op2 = bits(machInst, 5, 4);
793                const IntRegIndex rd =
794                    (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
795                const IntRegIndex rm =
796                    (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
797                switch (op1) {
798                  case 0x0:
799                    switch (op2) {
800                      case 0x0:
801                        return new QaddRegCc(machInst, rd,
802                                             rm, rn, 0, LSL);
803                      case 0x1:
804                        return new QdaddRegCc(machInst, rd,
805                                              rm, rn, 0, LSL);
806                      case 0x2:
807                        return new QsubRegCc(machInst, rd,
808                                             rm, rn, 0, LSL);
809                      case 0x3:
810                        return new QdsubRegCc(machInst, rd,
811                                              rm, rn, 0, LSL);
812                    }
813                    break;
814                  case 0x1:
815                    switch (op2) {
816                      case 0x0:
817                        return new Rev(machInst, rd, rn);
818                      case 0x1:
819                        return new Rev16(machInst, rd, rn);
820                      case 0x2:
821                        return new Rbit(machInst, rd, rm);
822                      case 0x3:
823                        return new Revsh(machInst, rd, rn);
824                    }
825                    break;
826                  case 0x2:
827                    if (op2 == 0) {
828                        return new Sel(machInst, rd, rn, rm);
829                    }
830                    break;
831                  case 0x3:
832                    if (op2 == 0) {
833                        return new Clz(machInst, rd, rm);
834                    }
835                }
836            }
837            return new Unknown(machInst);
838        }
839    }
840    '''
841}};
842
843def format Thumb16ShiftAddSubMoveCmp() {{
844    decode_block = '''
845    {
846        const uint32_t imm5 = bits(machInst, 10, 6);
847        const uint32_t imm3 = bits(machInst, 8, 6);
848        const uint32_t imm8 = bits(machInst, 7, 0);
849        const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 2, 0);
850        const IntRegIndex rd8 = (IntRegIndex)(uint32_t)bits(machInst, 10, 8);
851        const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 5, 3);
852        const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 8, 6);
853        switch (bits(machInst, 13, 11)) {
854          case 0x0: // lsl
855            if (machInst.itstateMask) {
856                return new MovReg(machInst, rd, INTREG_ZERO, rn, imm5, LSL);
857            } else {
858                return new MovRegCc(machInst, rd, INTREG_ZERO, rn, imm5, LSL);
859            }
860          case 0x1: // lsr
861            if (machInst.itstateMask) {
862                return new MovReg(machInst, rd, INTREG_ZERO, rn, imm5, LSR);
863            } else {
864                return new MovRegCc(machInst, rd, INTREG_ZERO, rn, imm5, LSR);
865            }
866          case 0x2: // asr
867            if (machInst.itstateMask) {
868                return new MovReg(machInst, rd, INTREG_ZERO, rn, imm5, ASR);
869            } else {
870                return new MovRegCc(machInst, rd, INTREG_ZERO, rn, imm5, ASR);
871            }
872          case 0x3:
873            switch (bits(machInst, 10, 9)) {
874              case 0x0:
875                if (machInst.itstateMask) {
876                    return new AddReg(machInst, rd, rn, rm, 0, LSL);
877                } else {
878                    return new AddRegCc(machInst, rd, rn, rm, 0, LSL);
879                }
880              case 0x1:
881                if (machInst.itstateMask) {
882                    return new SubReg(machInst, rd, rn, rm, 0, LSL);
883                } else {
884                    return new SubRegCc(machInst, rd, rn, rm, 0, LSL);
885                }
886              case 0x2:
887                if (machInst.itstateMask) {
888                    return new AddImm(machInst, rd, rn, imm3, true);
889                } else {
890                    return new AddImmCc(machInst, rd, rn, imm3, true);
891                }
892              case 0x3:
893                if (machInst.itstateMask) {
894                    return new SubImm(machInst, rd, rn, imm3, true);
895                } else {
896                    return new SubImmCc(machInst, rd, rn, imm3, true);
897                }
898            }
899          case 0x4:
900            if (machInst.itstateMask) {
901                return new MovImm(machInst, rd8, INTREG_ZERO, imm8, false);
902            } else {
903                return new MovImmCc(machInst, rd8, INTREG_ZERO, imm8, false);
904            }
905          case 0x5:
906            return new CmpImmCc(machInst, INTREG_ZERO, rd8, imm8, true);
907          case 0x6:
908            if (machInst.itstateMask) {
909                return new AddImm(machInst, rd8, rd8, imm8, true);
910            } else {
911                return new AddImmCc(machInst, rd8, rd8, imm8, true);
912            }
913          case 0x7:
914            if (machInst.itstateMask) {
915                return new SubImm(machInst, rd8, rd8, imm8, true);
916            } else {
917                return new SubImmCc(machInst, rd8, rd8, imm8, true);
918            }
919        }
920    }
921    '''
922}};
923
924def format Thumb16DataProcessing() {{
925    decode_block = '''
926    {
927        const IntRegIndex rdn = (IntRegIndex)(uint32_t)bits(machInst, 2, 0);
928        const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 5, 3);
929        switch (bits(machInst, 9, 6)) {
930          case 0x0:
931            if (machInst.itstateMask) {
932                return new AndReg(machInst, rdn, rdn, rm, 0, LSL);
933            } else {
934                return new AndRegCc(machInst, rdn, rdn, rm, 0, LSL);
935            }
936          case 0x1:
937            if (machInst.itstateMask) {
938                return new EorReg(machInst, rdn, rdn, rm, 0, LSL);
939            } else {
940                return new EorRegCc(machInst, rdn, rdn, rm, 0, LSL);
941            }
942          case 0x2: //lsl
943            if (machInst.itstateMask) {
944                return new MovRegReg(machInst, rdn,
945                        INTREG_ZERO, rdn, rm, LSL);
946            } else {
947                return new MovRegRegCc(machInst, rdn,
948                        INTREG_ZERO, rdn, rm, LSL);
949            }
950          case 0x3: //lsr
951            if (machInst.itstateMask) {
952                return new MovRegReg(machInst, rdn,
953                        INTREG_ZERO, rdn, rm, LSR);
954            } else {
955                return new MovRegRegCc(machInst, rdn,
956                        INTREG_ZERO, rdn, rm, LSR);
957            }
958          case 0x4: //asr
959            if (machInst.itstateMask) {
960                return new MovRegReg(machInst, rdn,
961                        INTREG_ZERO, rdn, rm, ASR);
962            } else {
963                return new MovRegRegCc(machInst, rdn,
964                        INTREG_ZERO, rdn, rm, ASR);
965            }
966          case 0x5:
967            if (machInst.itstateMask) {
968                return new AdcReg(machInst, rdn, rdn, rm, 0, LSL);
969            } else {
970                return new AdcRegCc(machInst, rdn, rdn, rm, 0, LSL);
971            }
972          case 0x6:
973            if (machInst.itstateMask) {
974                return new SbcReg(machInst, rdn, rdn, rm, 0, LSL);
975            } else {
976                return new SbcRegCc(machInst, rdn, rdn, rm, 0, LSL);
977            }
978          case 0x7: // ror
979            if (machInst.itstateMask) {
980                return new MovRegReg(machInst, rdn,
981                        INTREG_ZERO, rdn, rm, ROR);
982            } else {
983                return new MovRegRegCc(machInst, rdn,
984                        INTREG_ZERO, rdn, rm, ROR);
985            }
986          case 0x8:
987            return new TstRegCc(machInst, INTREG_ZERO, rdn, rm, 0, LSL);
988          case 0x9:
989            if (machInst.itstateMask) {
990                return new RsbImm(machInst, rdn, rm, 0, true);
991            } else {
992                return new RsbImmCc(machInst, rdn, rm, 0, true);
993            }
994          case 0xa:
995            return new CmpRegCc(machInst, INTREG_ZERO, rdn, rm, 0, LSL);
996          case 0xb:
997            return new CmnRegCc(machInst, INTREG_ZERO, rdn, rm, 0, LSL);
998          case 0xc:
999            if (machInst.itstateMask) {
1000                return new OrrReg(machInst, rdn, rdn, rm, 0, LSL);
1001            } else {
1002                return new OrrRegCc(machInst, rdn, rdn, rm, 0, LSL);
1003            }
1004          case 0xd:
1005            if (machInst.itstateMask) {
1006                return new Mul(machInst, rdn, rm, rdn);
1007            } else {
1008                return new MulCc(machInst, rdn, rm, rdn);
1009            }
1010          case 0xe:
1011            if (machInst.itstateMask) {
1012                return new BicReg(machInst, rdn, rdn, rm, 0, LSL);
1013            } else {
1014                return new BicRegCc(machInst, rdn, rdn, rm, 0, LSL);
1015            }
1016          case 0xf:
1017            if (machInst.itstateMask) {
1018                return new MvnReg(machInst, rdn, INTREG_ZERO, rm, 0, LSL);
1019            } else {
1020                return new MvnRegCc(machInst, rdn, INTREG_ZERO, rm, 0, LSL);
1021            }
1022        }
1023    }
1024    '''
1025}};
1026
1027def format Thumb16SpecDataAndBx() {{
1028    decode_block = '''
1029    {
1030        const IntRegIndex rdn =
1031            (IntRegIndex)(uint32_t)(bits(machInst, 2, 0) |
1032                                    (bits(machInst, 7) << 3));
1033        const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 6, 3);
1034        switch (bits(machInst, 9, 8)) {
1035          case 0x0:
1036            return new AddReg(machInst, rdn, rdn, rm, 0, LSL);
1037          case 0x1:
1038            return new CmpRegCc(machInst, INTREG_ZERO, rdn, rm, 0, LSL);
1039          case 0x2:
1040            return new MovReg(machInst, rdn, INTREG_ZERO, rm, 0, LSL);
1041          case 0x3:
1042            if (bits(machInst, 7) == 0) {
1043                ConditionCode condCode;
1044                if(machInst.itstateMask) {
1045                  condCode = (ConditionCode)(uint8_t)machInst.itstateCond;
1046                } else {
1047                  condCode = COND_UC;
1048                }
1049                return new BxReg(machInst,
1050                                 (IntRegIndex)(uint32_t)bits(machInst, 6, 3),
1051                                 condCode);
1052            } else {
1053                ConditionCode condCode;
1054                if(machInst.itstateMask) {
1055                  condCode = (ConditionCode)(uint8_t)machInst.itstateCond;
1056                } else {
1057                  condCode = COND_UC;
1058                }
1059                return new BlxReg(machInst,
1060                                  (IntRegIndex)(uint32_t)bits(machInst, 6, 3),
1061                                  condCode);
1062            }
1063        }
1064    }
1065    '''
1066}};
1067
1068def format Thumb16Adr() {{
1069    decode_block = '''
1070    {
1071        const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 10, 8);
1072        const uint32_t imm8 = bits(machInst, 7, 0) << 2;
1073        return new AdrImm(machInst, rd, (IntRegIndex)1, imm8, false);
1074    }
1075    '''
1076}};
1077
1078def format Thumb16AddSp() {{
1079    decode_block = '''
1080    {
1081        const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 10, 8);
1082        const uint32_t imm8 = bits(machInst, 7, 0) << 2;
1083        return new AddImm(machInst, rd, INTREG_SP, imm8, true);
1084    }
1085    '''
1086}};
1087
1088def format ArmMisc() {{
1089    decode_block = '''
1090    {
1091        const uint32_t unrotated = bits(machInst, 7, 0);
1092        const uint32_t rotation = (bits(machInst, 11, 8) << 1);
1093        const uint32_t imm = rotate_imm(unrotated, rotation);
1094        const uint8_t byteMask = bits(machInst, 19, 16);
1095        switch (OPCODE) {
1096          case 0x8:
1097            return new MovImm(machInst, (IntRegIndex)(uint32_t)RD,
1098                    (IntRegIndex)INTREG_ZERO,
1099                    bits(machInst, 11, 0) | (bits(machInst, 19, 16) << 12),
1100                    false);
1101          case 0x9:
1102            if (RN == 0) {
1103                switch (IMM) {
1104                  case 0x0:
1105                    return new NopInst(machInst);
1106                  case 0x1:
1107                    return new YieldInst(machInst);
1108                  case 0x2:
1109                    return new WfeInst(machInst);
1110                  case 0x3:
1111                    return new WfiInst(machInst);
1112                  case 0x4:
1113                    return new SevInst(machInst);
1114                  default:
1115                    return new Unknown(machInst);
1116                }
1117            } else {
1118                return new MsrCpsrImm(machInst, imm, byteMask);
1119            }
1120          case 0xa:
1121            {
1122                const uint32_t timm = (bits(machInst, 19, 16) << 12) |
1123                                       bits(machInst, 11, 0);
1124                return new MovtImm(machInst, (IntRegIndex)(uint32_t)RD,
1125                                   (IntRegIndex)(uint32_t)RD, timm, true);
1126            }
1127          case 0xb:
1128            return new MsrSpsrImm(machInst, imm, byteMask);
1129          default:
1130            return new Unknown(machInst);
1131        }
1132    }
1133    '''
1134}};
1135
1136def format Thumb16Misc() {{
1137    decode_block = '''
1138    {
1139        switch (bits(machInst, 11, 8)) {
1140          case 0x0:
1141            if (bits(machInst, 7)) {
1142                return new SubImm(machInst, INTREG_SP, INTREG_SP,
1143                                   bits(machInst, 6, 0) << 2, true);
1144            } else {
1145                return new AddImm(machInst, INTREG_SP, INTREG_SP,
1146                                   bits(machInst, 6, 0) << 2, true);
1147            }
1148          case 0x2:
1149            {
1150                const IntRegIndex rd =
1151                    (IntRegIndex)(uint32_t)bits(machInst, 2, 0);
1152                const IntRegIndex rm =
1153                    (IntRegIndex)(uint32_t)bits(machInst, 5, 3);
1154                switch (bits(machInst, 7, 6)) {
1155                  case 0x0:
1156                    return new Sxth(machInst, rd, 0, rm);
1157                  case 0x1:
1158                    return new Sxtb(machInst, rd, 0, rm);
1159                  case 0x2:
1160                    return new Uxth(machInst, rd, 0, rm);
1161                  case 0x3:
1162                    return new Uxtb(machInst, rd, 0, rm);
1163                }
1164            }
1165          case 0x1:
1166          case 0x3:
1167            return new Cbz(machInst,
1168                           (bits(machInst, 9) << 6) |
1169                           (bits(machInst, 7, 3) << 1),
1170                           (IntRegIndex)(uint32_t)bits(machInst, 2, 0));
1171          case 0x4:
1172          case 0x5:
1173            {
1174                const uint32_t m = bits(machInst, 8);
1175                const uint32_t regList = bits(machInst, 7, 0) | (m << 14);
1176                return new LdmStm(machInst, INTREG_SP, false, false, false,
1177                                  true, false, regList);
1178            }
1179          case 0x6:
1180            {
1181                const uint32_t opBits = bits(machInst, 7, 5);
1182                if (opBits == 2) {
1183                    return new Setend(machInst, bits(machInst, 3));
1184                } else if (opBits == 3) {
1185                    const bool enable = (bits(machInst, 4) == 0);
1186                    const uint32_t mods = (bits(machInst, 2, 0) << 5) |
1187                                          ((enable ? 1 : 0) << 9);
1188                    return new Cps(machInst, mods);
1189                }
1190            }
1191          case 0xa:
1192            {
1193                IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 2, 0);
1194                IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 5, 3);
1195                switch (bits(machInst, 7, 6)) {
1196                  case 0x0:
1197                    return new Rev(machInst, rd, rm);
1198                  case 0x1:
1199                    return new Rev16(machInst, rd, rm);
1200                  case 0x3:
1201                    return new Revsh(machInst, rd, rm);
1202                  default:
1203                    break;
1204                }
1205            }
1206            break;
1207          case 0x9:
1208          case 0xb:
1209            return new Cbnz(machInst,
1210                            (bits(machInst, 9) << 6) |
1211                            (bits(machInst, 7, 3) << 1),
1212                            (IntRegIndex)(uint32_t)bits(machInst, 2, 0));
1213          case 0xc:
1214          case 0xd:
1215            {
1216                const uint32_t p = bits(machInst, 8);
1217                const uint32_t regList = bits(machInst, 7, 0) | (p << 15);
1218                return new LdmStm(machInst, INTREG_SP, true, true, false,
1219                                  true, true, regList);
1220            }
1221          case 0xe:
1222            return new BkptInst(machInst);
1223          case 0xf:
1224            if (bits(machInst, 3, 0) != 0)
1225                return new ItInst(machInst);
1226            switch (bits(machInst, 7, 4)) {
1227              case 0x0:
1228                return new NopInst(machInst);
1229              case 0x1:
1230                return new YieldInst(machInst);
1231              case 0x2:
1232                return new WfeInst(machInst);
1233              case 0x3:
1234                return new WfiInst(machInst);
1235              case 0x4:
1236                return new SevInst(machInst);
1237              default:
1238                return new WarnUnimplemented("unallocated_hint", machInst);
1239            }
1240          default:
1241            break;
1242        }
1243        return new Unknown(machInst);
1244    }
1245    '''
1246}};
1247
1248def format Thumb32DataProcModImm() {{
1249
1250    def decInst(mnem, dest="rd", op1="rn"):
1251        return '''
1252            if (s) {
1253                return new %(mnem)sImmCc(machInst, %(dest)s,
1254                                          %(op1)s, imm, rotC);
1255            } else {
1256                return new %(mnem)sImm(machInst, %(dest)s,
1257                                        %(op1)s, imm, rotC);
1258            }
1259        ''' % {"mnem" : mnem, "dest" : dest, "op1" : op1}
1260
1261    decode_block = '''
1262    {
1263        const uint32_t op = bits(machInst, 24, 21);
1264        const bool s = (bits(machInst, 20) == 1);
1265        const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
1266        const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
1267        const uint32_t ctrlImm = bits(machInst.instBits, 26) << 3 |
1268                                 bits(machInst, 14, 12);
1269        const bool rotC = ctrlImm > 3;
1270        const uint32_t dataImm = bits(machInst, 7, 0);
1271        const uint32_t imm = modified_imm(ctrlImm, dataImm);
1272        switch (op) {
1273          case 0x0:
1274            if (rd == INTREG_PC) {
1275                %(tst)s
1276            } else {
1277                %(and)s
1278            }
1279          case 0x1:
1280            %(bic)s
1281          case 0x2:
1282            if (rn == INTREG_PC) {
1283                %(mov)s
1284            } else {
1285                %(orr)s
1286            }
1287          case 0x3:
1288            if (rn == INTREG_PC) {
1289                %(mvn)s
1290            } else {
1291                %(orn)s
1292            }
1293          case 0x4:
1294            if (rd == INTREG_PC) {
1295                %(teq)s
1296            } else {
1297                %(eor)s
1298            }
1299          case 0x8:
1300            if (rd == INTREG_PC) {
1301                %(cmn)s
1302            } else {
1303                %(add)s
1304            }
1305          case 0xa:
1306            %(adc)s
1307          case 0xb:
1308            %(sbc)s
1309          case 0xd:
1310            if (rd == INTREG_PC) {
1311                %(cmp)s
1312            } else {
1313                %(sub)s
1314            }
1315          case 0xe:
1316            %(rsb)s
1317          default:
1318            return new Unknown(machInst);
1319        }
1320    }
1321    ''' % {
1322        "tst" : decInst("Tst", "INTREG_ZERO"),
1323        "and" : decInst("And"),
1324        "bic" : decInst("Bic"),
1325        "mov" : decInst("Mov", op1="INTREG_ZERO"),
1326        "orr" : decInst("Orr"),
1327        "mvn" : decInst("Mvn", op1="INTREG_ZERO"),
1328        "orn" : decInst("Orn"),
1329        "teq" : decInst("Teq", dest="INTREG_ZERO"),
1330        "eor" : decInst("Eor"),
1331        "cmn" : decInst("Cmn", dest="INTREG_ZERO"),
1332        "add" : decInst("Add"),
1333        "adc" : decInst("Adc"),
1334        "sbc" : decInst("Sbc"),
1335        "cmp" : decInst("Cmp", dest="INTREG_ZERO"),
1336        "sub" : decInst("Sub"),
1337        "rsb" : decInst("Rsb")
1338    }
1339}};
1340
1341def format Thumb32DataProcPlainBin() {{
1342    decode_block = '''
1343    {
1344        const uint32_t op = bits(machInst, 24, 20);
1345        const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
1346        const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
1347        switch (op) {
1348          case 0x0:
1349            {
1350                const uint32_t imm = bits(machInst, 7, 0) |
1351                                     (bits(machInst, 14, 12) << 8) |
1352                                     (bits(machInst, 26) << 11);
1353                if (rn == 0xf) {
1354                    return new AdrImm(machInst, rd, (IntRegIndex)1,
1355                                      imm, false);
1356                } else {
1357                    return new AddImm(machInst, rd, rn, imm, true);
1358                }
1359            }
1360          case 0x4:
1361            {
1362                const uint32_t imm = bits(machInst, 7, 0) |
1363                                     (bits(machInst, 14, 12) << 8) |
1364                                     (bits(machInst, 26) << 11) |
1365                                     (bits(machInst, 19, 16) << 12);
1366                return new MovImm(machInst, rd, INTREG_ZERO, imm, true);
1367            }
1368          case 0xa:
1369            {
1370                const uint32_t imm = bits(machInst, 7, 0) |
1371                                     (bits(machInst, 14, 12) << 8) |
1372                                     (bits(machInst, 26) << 11);
1373                if (rn == 0xf) {
1374                    return new AdrImm(machInst, rd, (IntRegIndex)0,
1375                                      imm, false);
1376                } else {
1377                    return new SubImm(machInst, rd, rn, imm, true);
1378                }
1379            }
1380          case 0xc:
1381            {
1382                const uint32_t imm = bits(machInst, 7, 0) |
1383                                     (bits(machInst, 14, 12) << 8) |
1384                                     (bits(machInst, 26) << 11) |
1385                                     (bits(machInst, 19, 16) << 12);
1386                return new MovtImm(machInst, rd, rd, imm, true);
1387            }
1388          case 0x12:
1389            if (!(bits(machInst, 14, 12) || bits(machInst, 7, 6))) {
1390                const uint32_t satImm = bits(machInst, 4, 0);
1391                return new Ssat16(machInst, rd, satImm + 1, rn);
1392            }
1393            // Fall through on purpose...
1394          case 0x10:
1395            {
1396                const uint32_t satImm = bits(machInst, 4, 0);
1397                const uint32_t imm = bits(machInst, 7, 6) |
1398                                     (bits(machInst, 14, 12) << 2);
1399                const ArmShiftType type =
1400                    (ArmShiftType)(uint32_t)bits(machInst, 21, 20);
1401                return new Ssat(machInst, rd, satImm + 1, rn, imm, type);
1402            }
1403          case 0x14:
1404            {
1405                const uint32_t lsb = bits(machInst, 7, 6) |
1406                                     (bits(machInst, 14, 12) << 2);
1407                const uint32_t msb = lsb + bits(machInst, 4, 0);
1408                return new Sbfx(machInst, rd, rn, lsb, msb);
1409            }
1410          case 0x16:
1411            {
1412                const uint32_t lsb = bits(machInst, 7, 6) |
1413                                     (bits(machInst, 14, 12) << 2);
1414                const uint32_t msb = bits(machInst, 4, 0);
1415                if (rn == 0xf) {
1416                    return new Bfc(machInst, rd, rd, lsb, msb);
1417                } else {
1418                    return new Bfi(machInst, rd, rn, lsb, msb);
1419                }
1420            }
1421          case 0x1a:
1422            if (!(bits(machInst, 14, 12) || bits(machInst, 7, 6))) {
1423                const uint32_t satImm = bits(machInst, 4, 0);
1424                return new Usat16(machInst, rd, satImm, rn);
1425            }
1426            // Fall through on purpose...
1427          case 0x18:
1428            {
1429                const uint32_t satImm = bits(machInst, 4, 0);
1430                const uint32_t imm = bits(machInst, 7, 6) |
1431                                     (bits(machInst, 14, 12) << 2);
1432                const ArmShiftType type =
1433                    (ArmShiftType)(uint32_t)bits(machInst, 21, 20);
1434                return new Usat(machInst, rd, satImm, rn, imm, type);
1435            }
1436          case 0x1c:
1437            {
1438                const uint32_t lsb = bits(machInst, 7, 6) |
1439                                     (bits(machInst, 14, 12) << 2);
1440                const uint32_t msb = lsb + bits(machInst, 4, 0);
1441                return new Ubfx(machInst, rd, rn, lsb, msb);
1442            }
1443          default:
1444            return new Unknown(machInst);
1445        }
1446    }
1447    '''
1448}};
1449
1450def format Thumb32DataProcShiftReg() {{
1451
1452    def decInst(mnem, dest="rd", op1="rn"):
1453        return '''
1454            if (s) {
1455                return new %(mnem)sRegCc(machInst, %(dest)s,
1456                                          %(op1)s, rm, amt, type);
1457            } else {
1458                return new %(mnem)sReg(machInst, %(dest)s,
1459                                        %(op1)s, rm, amt, type);
1460            }
1461        ''' % {"mnem" : mnem, "dest" : dest, "op1" : op1}
1462
1463    decode_block = '''
1464    {
1465        const uint32_t op = bits(machInst, 24, 21);
1466        const bool s = (bits(machInst, 20) == 1);
1467        const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
1468        const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
1469        const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
1470        const uint32_t amt = (bits(machInst, 14, 12) << 2) |
1471                              bits(machInst, 7, 6);
1472        const ArmShiftType type = (ArmShiftType)(uint32_t)bits(machInst, 5, 4);
1473        switch (op) {
1474          case 0x0:
1475            if (rd == INTREG_PC) {
1476                %(tst)s
1477            } else {
1478                %(and)s
1479            }
1480          case 0x1:
1481            %(bic)s
1482          case 0x2:
1483            if (rn == INTREG_PC) {
1484                %(mov)s
1485            } else {
1486                %(orr)s
1487            }
1488          case 0x3:
1489            if (rn == INTREG_PC) {
1490                %(mvn)s
1491            } else {
1492                %(orn)s
1493            }
1494          case 0x4:
1495            if (rd == INTREG_PC) {
1496                %(teq)s
1497            } else {
1498                %(eor)s
1499            }
1500          case 0x6:
1501            if (type) {
1502                return new PkhtbReg(machInst, rd, rn, rm, amt, type);
1503            } else {
1504                return new PkhbtReg(machInst, rd, rn, rm, amt, type);
1505            }
1506          case 0x8:
1507            if (rd == INTREG_PC) {
1508                %(cmn)s
1509            } else {
1510                %(add)s
1511            }
1512          case 0xa:
1513            %(adc)s
1514          case 0xb:
1515            %(sbc)s
1516          case 0xd:
1517            if (rd == INTREG_PC) {
1518                %(cmp)s
1519            } else {
1520                %(sub)s
1521            }
1522          case 0xe:
1523            %(rsb)s
1524          default:
1525            return new Unknown(machInst);
1526        }
1527    }
1528    ''' % {
1529        "tst" : decInst("Tst", "INTREG_ZERO"),
1530        "and" : decInst("And"),
1531        "bic" : decInst("Bic"),
1532        "mov" : decInst("Mov", op1="INTREG_ZERO"),
1533        "orr" : decInst("Orr"),
1534        "mvn" : decInst("Mvn", op1="INTREG_ZERO"),
1535        "orn" : decInst("Orn"),
1536        "teq" : decInst("Teq", "INTREG_ZERO"),
1537        "eor" : decInst("Eor"),
1538        "cmn" : decInst("Cmn", "INTREG_ZERO"),
1539        "add" : decInst("Add"),
1540        "adc" : decInst("Adc"),
1541        "sbc" : decInst("Sbc"),
1542        "cmp" : decInst("Cmp", "INTREG_ZERO"),
1543        "sub" : decInst("Sub"),
1544        "rsb" : decInst("Rsb")
1545    }
1546}};
1547