data.isa revision 7408
12817Sksewell@umich.edu// Copyright (c) 2010 ARM Limited
29426SAndreas.Sandberg@ARM.com// All rights reserved
37763SAli.Saidi@ARM.com//
47763SAli.Saidi@ARM.com// The license below extends only to copyright in the software and shall
57763SAli.Saidi@ARM.com// not be construed as granting a license to any other intellectual
67763SAli.Saidi@ARM.com// property including but not limited to intellectual property relating
77763SAli.Saidi@ARM.com// to a hardware implementation of the functionality of the software
87763SAli.Saidi@ARM.com// licensed hereunder.  You may use the software subject to the license
97763SAli.Saidi@ARM.com// terms below provided that you ensure that this notice is replicated
107763SAli.Saidi@ARM.com// unmodified and in its entirety in all distributions of the software,
117763SAli.Saidi@ARM.com// modified or unmodified, in source code or in binary form.
127763SAli.Saidi@ARM.com//
137763SAli.Saidi@ARM.com// 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
322817Sksewell@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
342817Sksewell@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 ArmMiscMedia() {{
392817Sksewell@umich.edu    decode_block = '''
402817Sksewell@umich.edu    {
412817Sksewell@umich.edu        const uint32_t op1 = bits(machInst, 22, 20);
422817Sksewell@umich.edu        const uint32_t op2 = bits(machInst, 7, 5);
432817Sksewell@umich.edu        const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
448793Sgblack@eecs.umich.edu        const IntRegIndex ra = (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
456329Sgblack@eecs.umich.edu        if (op1 == 0 && op2 == 0) {
466658Snate@binkert.org            const IntRegIndex rd =
472817Sksewell@umich.edu                (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
482834Sksewell@umich.edu            const IntRegIndex rm =
498232Snate@binkert.org                (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
502817Sksewell@umich.edu            if (ra == 0xf) {
512817Sksewell@umich.edu                return new Usad8(machInst, rd, rn, rm);
528852Sandreas.hansson@arm.com            } else {
538706Sandreas.hansson@arm.com                return new Usada8(machInst, rd, rn, rm, ra);
542817Sksewell@umich.edu            }
558706Sandreas.hansson@arm.com        } else if (bits(op2, 1, 0) == 0x2) {
562817Sksewell@umich.edu            const uint32_t lsb = bits(machInst, 11, 7);
572817Sksewell@umich.edu            const uint32_t msb = lsb + bits(machInst, 20, 16);
582817Sksewell@umich.edu            if (bits(op1, 2, 1) == 0x3) {
592817Sksewell@umich.edu                return new Ubfx(machInst, ra, rn, lsb, msb);
602817Sksewell@umich.edu            } else if (bits(op1, 2, 1) == 0x1) {
612817Sksewell@umich.edu                return new Sbfx(machInst, ra, rn, lsb, msb);
623126Sktlim@umich.edu            }
632817Sksewell@umich.edu        } else if (bits(op2, 1, 0) == 0x0 && bits(op1, 2, 1) == 0x2) {
642817Sksewell@umich.edu            const uint32_t lsb = bits(machInst, 11, 7);
652817Sksewell@umich.edu            const uint32_t msb = bits(machInst, 20, 16);
662817Sksewell@umich.edu            if (rn == 0xf) {
672817Sksewell@umich.edu                return new Bfc(machInst, ra, ra, lsb, msb);
682817Sksewell@umich.edu            } else {
692817Sksewell@umich.edu                return new Bfi(machInst, ra, rn, lsb, msb);
702817Sksewell@umich.edu            }
712817Sksewell@umich.edu        }
722817Sksewell@umich.edu        return new Unknown(machInst);
732817Sksewell@umich.edu    }
742817Sksewell@umich.edu    '''
752817Sksewell@umich.edu}};
765714Shsul@eecs.umich.edu
775715Shsul@eecs.umich.edudef format ArmDataProcReg() {{
782817Sksewell@umich.edu    pclr = '''
798793Sgblack@eecs.umich.edu        return new %(className)ssRegPclr(machInst, %(dest)s,
808793Sgblack@eecs.umich.edu                                        %(op1)s, rm, imm5,
818793Sgblack@eecs.umich.edu                                        type);
828793Sgblack@eecs.umich.edu    '''
838793Sgblack@eecs.umich.edu    instDecode = '''
848793Sgblack@eecs.umich.edu          case %(opcode)#x:
858793Sgblack@eecs.umich.edu            if (immShift) {
868793Sgblack@eecs.umich.edu                if (setCc) {
878793Sgblack@eecs.umich.edu                    if (%(dest)s == INTREG_PC) {
888793Sgblack@eecs.umich.edu                        %(pclr)s
898793Sgblack@eecs.umich.edu                    } else {
908793Sgblack@eecs.umich.edu                        return new %(className)sRegCc(machInst, %(dest)s,
918793Sgblack@eecs.umich.edu                                                      %(op1)s, rm, imm5, type);
928793Sgblack@eecs.umich.edu                    }
938793Sgblack@eecs.umich.edu                } else {
948793Sgblack@eecs.umich.edu                    return new %(className)sReg(machInst, %(dest)s, %(op1)s,
952817Sksewell@umich.edu                                                 rm, imm5, type);
962817Sksewell@umich.edu                }
976029Ssteve.reinhardt@amd.com            } else {
982817Sksewell@umich.edu                if (setCc) {
999382SAli.Saidi@ARM.com                    return new %(className)sRegRegCc(machInst, %(dest)s,
1002817Sksewell@umich.edu                                                      %(op1)s, rm, rs, type);
1012817Sksewell@umich.edu                } else {
1022817Sksewell@umich.edu                    return new %(className)sRegReg(machInst, %(dest)s,
1032817Sksewell@umich.edu                                                    %(op1)s, rm, rs, type);
1042817Sksewell@umich.edu                }
1059180Sandreas.hansson@arm.com            }
1062817Sksewell@umich.edu            break;
1072875Sksewell@umich.edu    '''
1085715Shsul@eecs.umich.edu
1092817Sksewell@umich.edu    def instCode(opcode, mnem, useDest = True, useOp1 = True):
1102817Sksewell@umich.edu        global pclr
1112817Sksewell@umich.edu        if useDest:
1122817Sksewell@umich.edu            dest = "rd"
1137823Ssteve.reinhardt@amd.com        else:
1142817Sksewell@umich.edu            dest = "INTREG_ZERO"
1152817Sksewell@umich.edu        if useOp1:
1162817Sksewell@umich.edu            op1 = "rn"
1175715Shsul@eecs.umich.edu        else:
1182817Sksewell@umich.edu            op1 = "INTREG_ZERO"
1192817Sksewell@umich.edu        global instDecode, pclrCode
1202817Sksewell@umich.edu        substDict = { "className": mnem.capitalize(),
1212817Sksewell@umich.edu                      "opcode": opcode,
1229180Sandreas.hansson@arm.com                      "dest": dest,
1232817Sksewell@umich.edu                      "op1": op1 }
1242875Sksewell@umich.edu        if useDest:
1255715Shsul@eecs.umich.edu            substDict["pclr"] = pclr % substDict
1262817Sksewell@umich.edu        else:
1272817Sksewell@umich.edu            substDict["pclr"] = ""
1282817Sksewell@umich.edu        return instDecode % substDict
1292817Sksewell@umich.edu
1307823Ssteve.reinhardt@amd.com    decode_block = '''
1317823Ssteve.reinhardt@amd.com    {
1328793Sgblack@eecs.umich.edu        const bool immShift = (bits(machInst, 4) == 0);
1332817Sksewell@umich.edu        const bool setCc = (bits(machInst, 20) == 1);
1345715Shsul@eecs.umich.edu        const uint32_t imm5 = bits(machInst, 11, 7);
1352817Sksewell@umich.edu        const ArmShiftType type = (ArmShiftType)(uint32_t)bits(machInst, 6, 5);
1362817Sksewell@umich.edu        const IntRegIndex rd = (IntRegIndex)(uint32_t)RD;
1372817Sksewell@umich.edu        const IntRegIndex rn = (IntRegIndex)(uint32_t)RN;
1382817Sksewell@umich.edu        const IntRegIndex rm = (IntRegIndex)(uint32_t)RM;
1399180Sandreas.hansson@arm.com        const IntRegIndex rs = (IntRegIndex)(uint32_t)RS;
1402817Sksewell@umich.edu        switch (OPCODE) {
1412875Sksewell@umich.edu    '''
1425715Shsul@eecs.umich.edu    decode_block += instCode(0x0, "and")
1432817Sksewell@umich.edu    decode_block += instCode(0x1, "eor")
1442817Sksewell@umich.edu    decode_block += instCode(0x2, "sub")
1452817Sksewell@umich.edu    decode_block += instCode(0x3, "rsb")
1462817Sksewell@umich.edu    decode_block += instCode(0x4, "add")
1472817Sksewell@umich.edu    decode_block += instCode(0x5, "adc")
1485715Shsul@eecs.umich.edu    decode_block += instCode(0x6, "sbc")
1492817Sksewell@umich.edu    decode_block += instCode(0x7, "rsc")
1502817Sksewell@umich.edu    decode_block += instCode(0x8, "tst", useDest = False)
1512817Sksewell@umich.edu    decode_block += instCode(0x9, "teq", useDest = False)
1522817Sksewell@umich.edu    decode_block += instCode(0xa, "cmp", useDest = False)
1532817Sksewell@umich.edu    decode_block += instCode(0xb, "cmn", useDest = False)
1542817Sksewell@umich.edu    decode_block += instCode(0xc, "orr")
1558793Sgblack@eecs.umich.edu    decode_block += instCode(0xd, "mov", useOp1 = False)
1568793Sgblack@eecs.umich.edu    decode_block += instCode(0xe, "bic")
1578793Sgblack@eecs.umich.edu    decode_block += instCode(0xf, "mvn", useOp1 = False)
1588793Sgblack@eecs.umich.edu    decode_block += '''
1592817Sksewell@umich.edu          default:
1602817Sksewell@umich.edu            return new Unknown(machInst);
1612817Sksewell@umich.edu        }
1622817Sksewell@umich.edu    }
1632817Sksewell@umich.edu    '''
1642817Sksewell@umich.edu}};
1658793Sgblack@eecs.umich.edu
1662817Sksewell@umich.edudef format ArmPackUnpackSatReverse() {{
1672817Sksewell@umich.edu    decode_block = '''
1682817Sksewell@umich.edu    {
1692817Sksewell@umich.edu        const uint32_t op1 = bits(machInst, 22, 20);
1702817Sksewell@umich.edu        const uint32_t a = bits(machInst, 19, 16);
1712817Sksewell@umich.edu        const uint32_t op2 = bits(machInst, 7, 5);
1722817Sksewell@umich.edu        if (bits(op2, 0) == 0) {
1738793Sgblack@eecs.umich.edu            const IntRegIndex rn =
1742817Sksewell@umich.edu                (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
1752817Sksewell@umich.edu            const IntRegIndex rd =
1762817Sksewell@umich.edu                (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
1772817Sksewell@umich.edu            const uint32_t satImm = bits(machInst, 20, 16);
1782817Sksewell@umich.edu            const uint32_t imm = bits(machInst, 11, 7);
1792817Sksewell@umich.edu            const ArmShiftType type =
1802817Sksewell@umich.edu                (ArmShiftType)(uint32_t)bits(machInst, 6, 5);
1812817Sksewell@umich.edu            if (op1 == 0) {
1822817Sksewell@umich.edu                if (type) {
1832817Sksewell@umich.edu                    return new PkhtbReg(machInst, rd, (IntRegIndex)a,
1842817Sksewell@umich.edu                                        rn, imm, type);
1852817Sksewell@umich.edu                } else {
1862817Sksewell@umich.edu                    return new PkhbtReg(machInst, rd, (IntRegIndex)a,
1872817Sksewell@umich.edu                                        rn, imm, type);
1882817Sksewell@umich.edu                }
1892817Sksewell@umich.edu            } else if (bits(op1, 2, 1) == 1) {
1902817Sksewell@umich.edu                return new Ssat(machInst, rd, satImm + 1, rn, imm, type);
1912817Sksewell@umich.edu            } else if (bits(op1, 2, 1) == 3) {
1922817Sksewell@umich.edu                return new Usat(machInst, rd, satImm, rn, imm, type);
1932817Sksewell@umich.edu            }
1943126Sktlim@umich.edu            return new Unknown(machInst);
1953126Sktlim@umich.edu        }
1963126Sktlim@umich.edu        switch (op1) {
1972817Sksewell@umich.edu          case 0x0:
1982817Sksewell@umich.edu            {
1992817Sksewell@umich.edu                const IntRegIndex rn =
2002817Sksewell@umich.edu                    (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
2013126Sktlim@umich.edu                const IntRegIndex rd =
2023126Sktlim@umich.edu                    (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
2033126Sktlim@umich.edu                const IntRegIndex rm =
2042817Sksewell@umich.edu                    (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
2052817Sksewell@umich.edu                if (op2 == 0x3) {
2062817Sksewell@umich.edu                    const uint32_t rotation =
2072817Sksewell@umich.edu                        (uint32_t)bits(machInst, 11, 10) << 3;
2082817Sksewell@umich.edu                    if (a == 0xf) {
2098208SAli.Saidi@ARM.com                        return new Sxtb16(machInst, rd, rotation, rm);
2109382SAli.Saidi@ARM.com                    } else {
2118208SAli.Saidi@ARM.com                        return new Sxtab16(machInst, rd, rn, rm, rotation);
2129382SAli.Saidi@ARM.com                    }
2132817Sksewell@umich.edu                } else if (op2 == 0x5) {
2148793Sgblack@eecs.umich.edu                    return new Sel(machInst, rd, rn, rm);
2158793Sgblack@eecs.umich.edu                }
2162817Sksewell@umich.edu            }
2172817Sksewell@umich.edu            break;
2182817Sksewell@umich.edu          case 0x2:
2192817Sksewell@umich.edu            if (op2 == 0x1) {
2202817Sksewell@umich.edu                const IntRegIndex rn =
2217763SAli.Saidi@ARM.com                    (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
2229384SAndreas.Sandberg@arm.com                const IntRegIndex rd =
2237763SAli.Saidi@ARM.com                    (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
2242817Sksewell@umich.edu                const uint32_t satImm = bits(machInst, 20, 16);
2252817Sksewell@umich.edu                return new Ssat16(machInst, rd, satImm + 1, rn);
2262817Sksewell@umich.edu            } else if (op2 == 0x3) {
2279426SAndreas.Sandberg@ARM.com                const IntRegIndex rn =
2282817Sksewell@umich.edu                    (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
2295715Shsul@eecs.umich.edu                const IntRegIndex rd =
2302817Sksewell@umich.edu                    (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
2312817Sksewell@umich.edu                const IntRegIndex rm =
2322817Sksewell@umich.edu                    (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
2332986Sgblack@eecs.umich.edu                const uint32_t rotation =
2349426SAndreas.Sandberg@ARM.com                    (uint32_t)bits(machInst, 11, 10) << 3;
2352817Sksewell@umich.edu                if (a == 0xf) {
2366314Sgblack@eecs.umich.edu                    return new Sxtb(machInst, rd, rotation, rm);
2372817Sksewell@umich.edu                } else {
2382817Sksewell@umich.edu                    return new Sxtab(machInst, rd, rn, rm, rotation);
2392817Sksewell@umich.edu                }
2402986Sgblack@eecs.umich.edu            }
2419426SAndreas.Sandberg@ARM.com            break;
2422817Sksewell@umich.edu          case 0x3:
2435715Shsul@eecs.umich.edu            if (op2 == 0x1) {
2442817Sksewell@umich.edu                IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
2452817Sksewell@umich.edu                IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
2462817Sksewell@umich.edu                return new Rev(machInst, rd, rm);
2472817Sksewell@umich.edu            } else if (op2 == 0x3) {
2489426SAndreas.Sandberg@ARM.com                const IntRegIndex rn =
2492817Sksewell@umich.edu                    (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
2505715Shsul@eecs.umich.edu                const IntRegIndex rd =
2512817Sksewell@umich.edu                    (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
2529382SAli.Saidi@ARM.com                const IntRegIndex rm =
2532817Sksewell@umich.edu                    (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
2542817Sksewell@umich.edu                const uint32_t rotation =
2552817Sksewell@umich.edu                    (uint32_t)bits(machInst, 11, 10) << 3;
2562817Sksewell@umich.edu                if (a == 0xf) {
2579426SAndreas.Sandberg@ARM.com                    return new Sxth(machInst, rd, rotation, rm);
2582817Sksewell@umich.edu                } else {
2596314Sgblack@eecs.umich.edu                    return new Sxtah(machInst, rd, rn, rm, rotation);
2602817Sksewell@umich.edu                }
2619382SAli.Saidi@ARM.com            } else if (op2 == 0x5) {
2622817Sksewell@umich.edu                IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
2632817Sksewell@umich.edu                IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
2642817Sksewell@umich.edu                return new Rev16(machInst, rd, rm);
2652817Sksewell@umich.edu            }
2669426SAndreas.Sandberg@ARM.com            break;
2672817Sksewell@umich.edu          case 0x4:
2685715Shsul@eecs.umich.edu            if (op2 == 0x3) {
2692817Sksewell@umich.edu                const IntRegIndex rn =
2709382SAli.Saidi@ARM.com                    (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
2712817Sksewell@umich.edu                const IntRegIndex rd =
2722817Sksewell@umich.edu                    (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
2732817Sksewell@umich.edu                const IntRegIndex rm =
2742817Sksewell@umich.edu                    (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
2757720Sgblack@eecs.umich.edu                const uint32_t rotation =
2762817Sksewell@umich.edu                    (uint32_t)bits(machInst, 11, 10) << 3;
2777720Sgblack@eecs.umich.edu                if (a == 0xf) {
2785258Sksewell@umich.edu                    return new Uxtb16(machInst, rd, rotation, rm);
2799382SAli.Saidi@ARM.com                } else {
2805258Sksewell@umich.edu                    return new Uxtab16(machInst, rd, rn, rm, rotation);
2815258Sksewell@umich.edu                }
2828733Sgeoffrey.blake@arm.com            }
2838733Sgeoffrey.blake@arm.com            break;
2848733Sgeoffrey.blake@arm.com          case 0x6:
2858733Sgeoffrey.blake@arm.com            if (op2 == 0x1) {
2868733Sgeoffrey.blake@arm.com                const IntRegIndex rn =
2878733Sgeoffrey.blake@arm.com                    (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
2889382SAli.Saidi@ARM.com                const IntRegIndex rd =
2898733Sgeoffrey.blake@arm.com                    (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
2908733Sgeoffrey.blake@arm.com                const uint32_t satImm = bits(machInst, 20, 16);
2915258Sksewell@umich.edu                return new Usat16(machInst, rd, satImm, rn);
2926313Sgblack@eecs.umich.edu            } else if (op2 == 0x3) {
2936313Sgblack@eecs.umich.edu                const IntRegIndex rn =
2946313Sgblack@eecs.umich.edu                    (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
2959384SAndreas.Sandberg@arm.com                const IntRegIndex rd =
2966313Sgblack@eecs.umich.edu                    (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
2976313Sgblack@eecs.umich.edu                const IntRegIndex rm =
2986313Sgblack@eecs.umich.edu                    (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
2996313Sgblack@eecs.umich.edu                const uint32_t rotation =
3006313Sgblack@eecs.umich.edu                    (uint32_t)bits(machInst, 11, 10) << 3;
3016313Sgblack@eecs.umich.edu                if (a == 0xf) {
3029384SAndreas.Sandberg@arm.com                    return new Uxtb(machInst, rd, rotation, rm);
3036313Sgblack@eecs.umich.edu                } else {
3046313Sgblack@eecs.umich.edu                    return new Uxtab(machInst, rd, rn, rm, rotation);
3056313Sgblack@eecs.umich.edu                }
3065258Sksewell@umich.edu            }
3074172Ssaidi@eecs.umich.edu            break;
3082817Sksewell@umich.edu          case 0x7:
3095715Shsul@eecs.umich.edu            {
3102817Sksewell@umich.edu                const IntRegIndex rn =
3119382SAli.Saidi@ARM.com                    (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
3122817Sksewell@umich.edu                const IntRegIndex rd =
3132817Sksewell@umich.edu                    (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
3142817Sksewell@umich.edu                const IntRegIndex rm =
3153468Sgblack@eecs.umich.edu                    (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
3168518Sgeoffrey.blake@arm.com                if (op2 == 0x1) {
3172817Sksewell@umich.edu                    return new Rbit(machInst, rd, rm);
3185715Shsul@eecs.umich.edu                } else if (op2 == 0x3) {
3192817Sksewell@umich.edu                    const uint32_t rotation =
3209382SAli.Saidi@ARM.com                        (uint32_t)bits(machInst, 11, 10) << 3;
3212817Sksewell@umich.edu                    if (a == 0xf) {
3222817Sksewell@umich.edu                        return new Uxth(machInst, rd, rotation, rm);
323                    } else {
324                        return new Uxtah(machInst, rd, rn, rm, rotation);
325                    }
326                } else if (op2 == 0x5) {
327                    return new Revsh(machInst, rd, rm);
328                }
329            }
330            break;
331        }
332        return new Unknown(machInst);
333    }
334    '''
335}};
336
337def format ArmParallelAddSubtract() {{
338    decode_block='''
339    {
340        const uint32_t op1 = bits(machInst, 21, 20);
341        const uint32_t op2 = bits(machInst, 7, 5);
342        const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
343        const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
344        const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
345        if (bits(machInst, 22) == 0) {
346            switch (op1) {
347              case 0x1:
348                switch (op2) {
349                  case 0x0:
350                    return new Sadd16RegCc(machInst, rd, rn, rm, 0, LSL);
351                  case 0x1:
352                    return new SasxRegCc(machInst, rd, rn, rm, 0, LSL);
353                  case 0x2:
354                    return new SsaxRegCc(machInst, rd, rn, rm, 0, LSL);
355                  case 0x3:
356                    return new Ssub16RegCc(machInst, rd, rn, rm, 0, LSL);
357                  case 0x4:
358                    return new Sadd8RegCc(machInst, rd, rn, rm, 0, LSL);
359                  case 0x7:
360                    return new Ssub8RegCc(machInst, rd, rn, rm, 0, LSL);
361                }
362                break;
363              case 0x2:
364                switch (op2) {
365                  case 0x0:
366                    return new Qadd16Reg(machInst, rd, rn, rm, 0, LSL);
367                  case 0x1:
368                    return new QasxReg(machInst, rd, rn, rm, 0, LSL);
369                  case 0x2:
370                    return new QsaxReg(machInst, rd, rn, rm, 0, LSL);
371                  case 0x3:
372                    return new Qsub16Reg(machInst, rd, rn, rm, 0, LSL);
373                  case 0x4:
374                    return new Qadd8Reg(machInst, rd, rn, rm, 0, LSL);
375                  case 0x7:
376                    return new Qsub8Reg(machInst, rd, rn, rm, 0, LSL);
377                }
378                break;
379              case 0x3:
380                switch (op2) {
381                  case 0x0:
382                    return new Shadd16Reg(machInst, rd, rn, rm, 0, LSL);
383                  case 0x1:
384                    return new ShasxReg(machInst, rd, rn, rm, 0, LSL);
385                  case 0x2:
386                    return new ShsaxReg(machInst, rd, rn, rm, 0, LSL);
387                  case 0x3:
388                    return new Shsub16Reg(machInst, rd, rn, rm, 0, LSL);
389                  case 0x4:
390                    return new Shadd8Reg(machInst, rd, rn, rm, 0, LSL);
391                  case 0x7:
392                    return new Shsub8Reg(machInst, rd, rn, rm, 0, LSL);
393                }
394                break;
395            }
396        } else {
397            switch (op1) {
398              case 0x1:
399                switch (op2) {
400                  case 0x0:
401                    return new Uadd16RegCc(machInst, rd, rn, rm, 0, LSL);
402                  case 0x1:
403                    return new UasxRegCc(machInst, rd, rn, rm, 0, LSL);
404                  case 0x2:
405                    return new UsaxRegCc(machInst, rd, rn, rm, 0, LSL);
406                  case 0x3:
407                    return new Usub16RegCc(machInst, rd, rn, rm, 0, LSL);
408                  case 0x4:
409                    return new Uadd8RegCc(machInst, rd, rn, rm, 0, LSL);
410                  case 0x7:
411                    return new Usub8RegCc(machInst, rd, rn, rm, 0, LSL);
412                }
413                break;
414              case 0x2:
415                switch (op2) {
416                  case 0x0:
417                    return new Uqadd16Reg(machInst, rd, rn, rm, 0, LSL);
418                  case 0x1:
419                    return new UqasxReg(machInst, rd, rn, rm, 0, LSL);
420                  case 0x2:
421                    return new UqsaxReg(machInst, rd, rn, rm, 0, LSL);
422                  case 0x3:
423                    return new Uqsub16Reg(machInst, rd, rn, rm, 0, LSL);
424                  case 0x4:
425                    return new Uqadd8Reg(machInst, rd, rn, rm, 0, LSL);
426                  case 0x7:
427                    return new Uqsub8Reg(machInst, rd, rn, rm, 0, LSL);
428                }
429                break;
430              case 0x3:
431                switch (op2) {
432                  case 0x0:
433                    return new Uhadd16Reg(machInst, rd, rn, rm, 0, LSL);
434                  case 0x1:
435                    return new UhasxReg(machInst, rd, rn, rm, 0, LSL);
436                  case 0x2:
437                    return new UhsaxReg(machInst, rd, rn, rm, 0, LSL);
438                  case 0x3:
439                    return new Uhsub16Reg(machInst, rd, rn, rm, 0, LSL);
440                  case 0x4:
441                    return new Uhadd8Reg(machInst, rd, rn, rm, 0, LSL);
442                  case 0x7:
443                    return new Uhsub8Reg(machInst, rd, rn, rm, 0, LSL);
444                }
445                break;
446            }
447        }
448        return new Unknown(machInst);
449    }
450    '''
451}};
452
453def format ArmDataProcImm() {{
454    pclr = '''
455        return new %(className)ssImmPclr(machInst, %(dest)s,
456                                        %(op1)s, imm, false);
457    '''
458    adr = '''
459        return new AdrImm(machInst, %(dest)s, %(add)s,
460                                     imm, false);
461    '''
462    instDecode = '''
463          case %(opcode)#x:
464            if (setCc) {
465                if (%(pclrInst)s && %(dest)s == INTREG_PC) {
466                    %(pclr)s
467                } else {
468                    return new %(className)sImmCc(machInst, %(dest)s, %(op1)s,
469                                                   imm, rotC);
470                }
471            } else {
472                if (%(adrInst)s && %(op1)s == INTREG_PC) {
473                    %(adr)s
474                } else {
475                    return new %(className)sImm(machInst, %(dest)s, %(op1)s,
476                                                 imm, rotC);
477                }
478            }
479            break;
480    '''
481
482    def instCode(opcode, mnem, useDest = True, useOp1 = True):
483        global instDecode, pclr, adr
484        if useDest:
485            dest = "rd"
486        else:
487            dest = "INTREG_ZERO"
488        if useOp1:
489            op1 = "rn"
490        else:
491            op1 = "INTREG_ZERO"
492        substDict = { "className": mnem.capitalize(),
493                      "opcode": opcode,
494                      "dest": dest,
495                      "op1": op1,
496                      "adr": "",
497                      "adrInst": "false" }
498        if useDest:
499            substDict["pclrInst"] = "true"
500            substDict["pclr"] = pclr % substDict
501        else:
502            substDict["pclrInst"] = "false"
503            substDict["pclr"] = ""
504        return instDecode % substDict
505
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                return new BxReg(machInst,
1044                                 (IntRegIndex)(uint32_t)bits(machInst, 6, 3),
1045                                 COND_UC);
1046            } else {
1047                return new BlxReg(machInst,
1048                                  (IntRegIndex)(uint32_t)bits(machInst, 6, 3),
1049                                  COND_UC);
1050            }
1051        }
1052    }
1053    '''
1054}};
1055
1056def format Thumb16Adr() {{
1057    decode_block = '''
1058    {
1059        const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 10, 8);
1060        const uint32_t imm8 = bits(machInst, 7, 0) << 2;
1061        return new AdrImm(machInst, rd, (IntRegIndex)1, imm8, false);
1062    }
1063    '''
1064}};
1065
1066def format Thumb16AddSp() {{
1067    decode_block = '''
1068    {
1069        const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 10, 8);
1070        const uint32_t imm8 = bits(machInst, 7, 0) << 2;
1071        return new AddImm(machInst, rd, INTREG_SP, imm8, true);
1072    }
1073    '''
1074}};
1075
1076def format Thumb16Misc() {{
1077    decode_block = '''
1078    {
1079        switch (bits(machInst, 11, 8)) {
1080          case 0x0:
1081            if (bits(machInst, 7)) {
1082                return new SubImm(machInst, INTREG_SP, INTREG_SP,
1083                                   bits(machInst, 6, 0) << 2, true);
1084            } else {
1085                return new AddImm(machInst, INTREG_SP, INTREG_SP,
1086                                   bits(machInst, 6, 0) << 2, true);
1087            }
1088          case 0x1:
1089            return new Cbz(machInst,
1090                           (bits(machInst, 9) << 6) |
1091                           (bits(machInst, 7, 3) << 1),
1092                           (IntRegIndex)(uint32_t)bits(machInst, 2, 0));
1093          case 0x2:
1094            {
1095                const IntRegIndex rd =
1096                    (IntRegIndex)(uint32_t)bits(machInst, 2, 0);
1097                const IntRegIndex rm =
1098                    (IntRegIndex)(uint32_t)bits(machInst, 5, 3);
1099                switch (bits(machInst, 7, 6)) {
1100                  case 0x0:
1101                    return new Sxth(machInst, rd, 0, rm);
1102                  case 0x1:
1103                    return new Sxtb(machInst, rd, 0, rm);
1104                  case 0x2:
1105                    return new Uxth(machInst, rd, 0, rm);
1106                  case 0x3:
1107                    return new Uxtb(machInst, rd, 0, rm);
1108                }
1109            }
1110          case 0x3:
1111            return new Cbz(machInst,
1112                           (bits(machInst, 9) << 6) |
1113                           (bits(machInst, 7, 3) << 1),
1114                           (IntRegIndex)(uint32_t)bits(machInst, 2, 0));
1115          case 0x4:
1116          case 0x5:
1117            {
1118                const uint32_t m = bits(machInst, 8);
1119                const uint32_t regList = bits(machInst, 7, 0) | (m << 14);
1120                return new LdmStm(machInst, INTREG_SP, false, false, false,
1121                                  true, false, regList);
1122            }
1123          case 0x6:
1124            {
1125                const uint32_t opBits = bits(machInst, 7, 5);
1126                if (opBits == 2) {
1127                    return new Setend(machInst, bits(machInst, 3));
1128                } else if (opBits == 3) {
1129                    const bool enable = (bits(machInst, 4) == 0);
1130                    const uint32_t mods = (bits(machInst, 2, 0) << 5) |
1131                                          ((enable ? 1 : 0) << 9);
1132                    return new Cps(machInst, mods);
1133                }
1134            }
1135          case 0x9:
1136            return new Cbnz(machInst,
1137                            (bits(machInst, 9) << 6) |
1138                            (bits(machInst, 7, 3) << 1),
1139                            (IntRegIndex)(uint32_t)bits(machInst, 2, 0));
1140          case 0xa:
1141            {
1142                IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 2, 0);
1143                IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 5, 3);
1144                switch (bits(machInst, 7, 6)) {
1145                  case 0x0:
1146                    return new Rev(machInst, rd, rm);
1147                  case 0x1:
1148                    return new Rev16(machInst, rd, rm);
1149                  case 0x3:
1150                    return new Revsh(machInst, rd, rm);
1151                  default:
1152                    break;
1153                }
1154            }
1155            break;
1156          case 0xb:
1157            return new Cbnz(machInst,
1158                            (bits(machInst, 9) << 6) |
1159                            (bits(machInst, 7, 3) << 1),
1160                            (IntRegIndex)(uint32_t)bits(machInst, 2, 0));
1161          case 0xc:
1162          case 0xd:
1163            {
1164                const uint32_t p = bits(machInst, 8);
1165                const uint32_t regList = bits(machInst, 7, 0) | (p << 15);
1166                return new LdmStm(machInst, INTREG_SP, true, true, false,
1167                                  true, true, regList);
1168            }
1169          case 0xe:
1170            return new WarnUnimplemented("bkpt", machInst);
1171          case 0xf:
1172            if (bits(machInst, 3, 0) != 0)
1173                return new ItInst(machInst);
1174            switch (bits(machInst, 7, 4)) {
1175              case 0x0:
1176                return new NopInst(machInst);
1177              case 0x1:
1178                return new WarnUnimplemented("yield", machInst);
1179              case 0x2:
1180                return new WarnUnimplemented("wfe", machInst);
1181              case 0x3:
1182                return new WarnUnimplemented("wfi", machInst);
1183              case 0x4:
1184                return new WarnUnimplemented("sev", machInst);
1185              default:
1186                return new WarnUnimplemented("unallocated_hint", machInst);
1187            }
1188          default:
1189            break;
1190        }
1191        return new Unknown(machInst);
1192    }
1193    '''
1194}};
1195
1196def format Thumb32DataProcModImm() {{
1197
1198    def decInst(mnem, dest="rd", op1="rn"):
1199        return '''
1200            if (s) {
1201                return new %(mnem)sImmCc(machInst, %(dest)s,
1202                                          %(op1)s, imm, rotC);
1203            } else {
1204                return new %(mnem)sImm(machInst, %(dest)s,
1205                                        %(op1)s, imm, rotC);
1206            }
1207        ''' % {"mnem" : mnem, "dest" : dest, "op1" : op1}
1208
1209    decode_block = '''
1210    {
1211        const uint32_t op = bits(machInst, 24, 21);
1212        const bool s = (bits(machInst, 20) == 1);
1213        const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
1214        const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
1215        const uint32_t ctrlImm = bits(machInst.instBits, 26) << 3 |
1216                                 bits(machInst, 14, 12);
1217        const bool rotC = ctrlImm > 3;
1218        const uint32_t dataImm = bits(machInst, 7, 0);
1219        const uint32_t imm = modified_imm(ctrlImm, dataImm);
1220        switch (op) {
1221          case 0x0:
1222            if (rd == INTREG_PC) {
1223                %(tst)s
1224            } else {
1225                %(and)s
1226            }
1227          case 0x1:
1228            %(bic)s
1229          case 0x2:
1230            if (rn == INTREG_PC) {
1231                %(mov)s
1232            } else {
1233                %(orr)s
1234            }
1235          case 0x3:
1236            if (rn == INTREG_PC) {
1237                %(mvn)s
1238            } else {
1239                %(orn)s
1240            }
1241          case 0x4:
1242            if (rd == INTREG_PC) {
1243                %(teq)s
1244            } else {
1245                %(eor)s
1246            }
1247          case 0x8:
1248            if (rd == INTREG_PC) {
1249                %(cmn)s
1250            } else {
1251                %(add)s
1252            }
1253          case 0xa:
1254            %(adc)s
1255          case 0xb:
1256            %(sbc)s
1257          case 0xd:
1258            if (rd == INTREG_PC) {
1259                %(cmp)s
1260            } else {
1261                %(sub)s
1262            }
1263          case 0xe:
1264            %(rsb)s
1265          default:
1266            return new Unknown(machInst);
1267        }
1268    }
1269    ''' % {
1270        "tst" : decInst("Tst", "INTREG_ZERO"),
1271        "and" : decInst("And"),
1272        "bic" : decInst("Bic"),
1273        "mov" : decInst("Mov", op1="INTREG_ZERO"),
1274        "orr" : decInst("Orr"),
1275        "mvn" : decInst("Mvn", op1="INTREG_ZERO"),
1276        "orn" : decInst("Orn"),
1277        "teq" : decInst("Teq", dest="INTREG_ZERO"),
1278        "eor" : decInst("Eor"),
1279        "cmn" : decInst("Cmn", dest="INTREG_ZERO"),
1280        "add" : decInst("Add"),
1281        "adc" : decInst("Adc"),
1282        "sbc" : decInst("Sbc"),
1283        "cmp" : decInst("Cmp", dest="INTREG_ZERO"),
1284        "sub" : decInst("Sub"),
1285        "rsb" : decInst("Rsb")
1286    }
1287}};
1288
1289def format Thumb32DataProcPlainBin() {{
1290    decode_block = '''
1291    {
1292        const uint32_t op = bits(machInst, 24, 20);
1293        const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
1294        const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
1295        switch (op) {
1296          case 0x0:
1297            {
1298                const uint32_t imm = bits(machInst, 7, 0) |
1299                                     (bits(machInst, 14, 12) << 8) |
1300                                     (bits(machInst, 26) << 11);
1301                if (rn == 0xf) {
1302                    return new AdrImm(machInst, rd, (IntRegIndex)1,
1303                                      imm, false);
1304                } else {
1305                    return new AddImm(machInst, rd, rn, imm, true);
1306                }
1307            }
1308          case 0x4:
1309            {
1310                const uint32_t imm = bits(machInst, 7, 0) |
1311                                     (bits(machInst, 14, 12) << 8) |
1312                                     (bits(machInst, 26) << 11) |
1313                                     (bits(machInst, 19, 16) << 12);
1314                return new MovImm(machInst, rd, INTREG_ZERO, imm, true);
1315            }
1316          case 0xa:
1317            {
1318                const uint32_t imm = bits(machInst, 7, 0) |
1319                                     (bits(machInst, 14, 12) << 8) |
1320                                     (bits(machInst, 26) << 11);
1321                if (rn == 0xf) {
1322                    return new AdrImm(machInst, rd, (IntRegIndex)0,
1323                                      imm, false);
1324                } else {
1325                    return new SubImm(machInst, rd, rn, imm, true);
1326                }
1327            }
1328          case 0xc:
1329            {
1330                const uint32_t imm = bits(machInst, 7, 0) |
1331                                     (bits(machInst, 14, 12) << 8) |
1332                                     (bits(machInst, 26) << 11) |
1333                                     (bits(machInst, 19, 16) << 12);
1334                return new MovtImm(machInst, rd, rd, imm, true);
1335            }
1336          case 0x12:
1337            if (!(bits(machInst, 14, 12) || bits(machInst, 7, 6))) {
1338                const uint32_t satImm = bits(machInst, 4, 0);
1339                return new Ssat16(machInst, rd, satImm + 1, rn);
1340            }
1341            // Fall through on purpose...
1342          case 0x10:
1343            {
1344                const uint32_t satImm = bits(machInst, 4, 0);
1345                const uint32_t imm = bits(machInst, 7, 6) |
1346                                     (bits(machInst, 14, 12) << 2);
1347                const ArmShiftType type =
1348                    (ArmShiftType)(uint32_t)bits(machInst, 21, 20);
1349                return new Ssat(machInst, rd, satImm + 1, rn, imm, type);
1350            }
1351          case 0x14:
1352            {
1353                const uint32_t lsb = bits(machInst, 7, 6) |
1354                                     (bits(machInst, 14, 12) << 2);
1355                const uint32_t msb = lsb + bits(machInst, 4, 0);
1356                return new Sbfx(machInst, rd, rn, lsb, msb);
1357            }
1358          case 0x16:
1359            {
1360                const uint32_t lsb = bits(machInst, 7, 6) |
1361                                     (bits(machInst, 14, 12) << 2);
1362                const uint32_t msb = bits(machInst, 4, 0);
1363                if (rn == 0xf) {
1364                    return new Bfc(machInst, rd, rd, lsb, msb);
1365                } else {
1366                    return new Bfi(machInst, rd, rn, lsb, msb);
1367                }
1368            }
1369          case 0x1a:
1370            if (!(bits(machInst, 14, 12) || bits(machInst, 7, 6))) {
1371                const uint32_t satImm = bits(machInst, 4, 0);
1372                return new Usat16(machInst, rd, satImm, rn);
1373            }
1374            // Fall through on purpose...
1375          case 0x18:
1376            {
1377                const uint32_t satImm = bits(machInst, 4, 0);
1378                const uint32_t imm = bits(machInst, 7, 6) |
1379                                     (bits(machInst, 14, 12) << 2);
1380                const ArmShiftType type =
1381                    (ArmShiftType)(uint32_t)bits(machInst, 21, 20);
1382                return new Usat(machInst, rd, satImm, rn, imm, type);
1383            }
1384          case 0x1c:
1385            {
1386                const uint32_t lsb = bits(machInst, 7, 6) |
1387                                     (bits(machInst, 14, 12) << 2);
1388                const uint32_t msb = lsb + bits(machInst, 4, 0);
1389                return new Ubfx(machInst, rd, rn, lsb, msb);
1390            }
1391          default:
1392            return new Unknown(machInst);
1393        }
1394    }
1395    '''
1396}};
1397
1398def format Thumb32DataProcShiftReg() {{
1399
1400    def decInst(mnem, dest="rd", op1="rn"):
1401        return '''
1402            if (s) {
1403                return new %(mnem)sRegCc(machInst, %(dest)s,
1404                                          %(op1)s, rm, amt, type);
1405            } else {
1406                return new %(mnem)sReg(machInst, %(dest)s,
1407                                        %(op1)s, rm, amt, type);
1408            }
1409        ''' % {"mnem" : mnem, "dest" : dest, "op1" : op1}
1410
1411    decode_block = '''
1412    {
1413        const uint32_t op = bits(machInst, 24, 21);
1414        const bool s = (bits(machInst, 20) == 1);
1415        const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
1416        const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
1417        const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
1418        const uint32_t amt = (bits(machInst, 14, 12) << 2) |
1419                              bits(machInst, 7, 6);
1420        const ArmShiftType type = (ArmShiftType)(uint32_t)bits(machInst, 5, 4);
1421        switch (op) {
1422          case 0x0:
1423            if (rd == INTREG_PC) {
1424                %(tst)s
1425            } else {
1426                %(and)s
1427            }
1428          case 0x1:
1429            %(bic)s
1430          case 0x2:
1431            if (rn == INTREG_PC) {
1432                %(mov)s
1433            } else {
1434                %(orr)s
1435            }
1436          case 0x3:
1437            if (rn == INTREG_PC) {
1438                %(mvn)s
1439            } else {
1440                %(orn)s
1441            }
1442          case 0x4:
1443            if (rd == INTREG_PC) {
1444                %(teq)s
1445            } else {
1446                %(eor)s
1447            }
1448          case 0x6:
1449            if (type) {
1450                return new PkhtbReg(machInst, rd, rn, rm, amt, type);
1451            } else {
1452                return new PkhbtReg(machInst, rd, rn, rm, amt, type);
1453            }
1454          case 0x8:
1455            if (rd == INTREG_PC) {
1456                %(cmn)s
1457            } else {
1458                %(add)s
1459            }
1460          case 0xa:
1461            %(adc)s
1462          case 0xb:
1463            %(sbc)s
1464          case 0xd:
1465            if (rd == INTREG_PC) {
1466                %(cmp)s
1467            } else {
1468                %(sub)s
1469            }
1470          case 0xe:
1471            %(rsb)s
1472          default:
1473            return new Unknown(machInst);
1474        }
1475    }
1476    ''' % {
1477        "tst" : decInst("Tst", "INTREG_ZERO"),
1478        "and" : decInst("And"),
1479        "bic" : decInst("Bic"),
1480        "mov" : decInst("Mov", op1="INTREG_ZERO"),
1481        "orr" : decInst("Orr"),
1482        "mvn" : decInst("Mvn", op1="INTREG_ZERO"),
1483        "orn" : decInst("Orn"),
1484        "teq" : decInst("Teq", "INTREG_ZERO"),
1485        "eor" : decInst("Eor"),
1486        "cmn" : decInst("Cmn", "INTREG_ZERO"),
1487        "add" : decInst("Add"),
1488        "adc" : decInst("Adc"),
1489        "sbc" : decInst("Sbc"),
1490        "cmp" : decInst("Cmp", "INTREG_ZERO"),
1491        "sub" : decInst("Sub"),
1492        "rsb" : decInst("Rsb")
1493    }
1494}};
1495