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