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