mem.isa revision 7293:a907ebdb7ee9
15222Sksewell@umich.edu// -*- mode:c++ -*- 25222Sksewell@umich.edu 35222Sksewell@umich.edu// Copyright (c) 2010 ARM Limited 45222Sksewell@umich.edu// All rights reserved 55222Sksewell@umich.edu// 65222Sksewell@umich.edu// The license below extends only to copyright in the software and shall 75222Sksewell@umich.edu// not be construed as granting a license to any other intellectual 85222Sksewell@umich.edu// property including but not limited to intellectual property relating 95222Sksewell@umich.edu// to a hardware implementation of the functionality of the software 105222Sksewell@umich.edu// licensed hereunder. You may use the software subject to the license 115222Sksewell@umich.edu// terms below provided that you ensure that this notice is replicated 125222Sksewell@umich.edu// unmodified and in its entirety in all distributions of the software, 135222Sksewell@umich.edu// modified or unmodified, in source code or in binary form. 145222Sksewell@umich.edu// 155222Sksewell@umich.edu// Copyright (c) 2007-2008 The Florida State University 165222Sksewell@umich.edu// All rights reserved. 175222Sksewell@umich.edu// 185222Sksewell@umich.edu// Redistribution and use in source and binary forms, with or without 195222Sksewell@umich.edu// modification, are permitted provided that the following conditions are 205222Sksewell@umich.edu// met: redistributions of source code must retain the above copyright 215222Sksewell@umich.edu// notice, this list of conditions and the following disclaimer; 225222Sksewell@umich.edu// redistributions in binary form must reproduce the above copyright 235222Sksewell@umich.edu// notice, this list of conditions and the following disclaimer in the 245222Sksewell@umich.edu// documentation and/or other materials provided with the distribution; 255222Sksewell@umich.edu// neither the name of the copyright holders nor the names of its 265222Sksewell@umich.edu// contributors may be used to endorse or promote products derived from 275222Sksewell@umich.edu// this software without specific prior written permission. 285222Sksewell@umich.edu// 295222Sksewell@umich.edu// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 305222Sksewell@umich.edu// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 315222Sksewell@umich.edu// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 325222Sksewell@umich.edu// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 335222Sksewell@umich.edu// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 345222Sksewell@umich.edu// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 355222Sksewell@umich.edu// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 3611793Sbrandon.potter@amd.com// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 3711793Sbrandon.potter@amd.com// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 385222Sksewell@umich.edu// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 395222Sksewell@umich.edu// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 405222Sksewell@umich.edu// 415222Sksewell@umich.edu// Authors: Gabe Black 425222Sksewell@umich.edu 436658Snate@binkert.orgdef format AddrMode2(imm) {{ 445222Sksewell@umich.edu if eval(imm): 455222Sksewell@umich.edu imm = True 468739Sgblack@eecs.umich.edu else: 475222Sksewell@umich.edu imm = False 485222Sksewell@umich.edu 495222Sksewell@umich.edu def buildPUBWLCase(p, u, b, w, l): 505222Sksewell@umich.edu return (p << 4) + (u << 3) + (b << 2) + (w << 1) + (l << 0) 515222Sksewell@umich.edu 525222Sksewell@umich.edu header_output = decoder_output = exec_output = "" 535222Sksewell@umich.edu decode_block = "switch(PUBWL) {\n" 545222Sksewell@umich.edu 555222Sksewell@umich.edu # Loop over all the values of p, u, b, w and l and build instructions and 565222Sksewell@umich.edu # a decode block for them. 575222Sksewell@umich.edu for p in (0, 1): 585222Sksewell@umich.edu for u in (0, 1): 599808Sstever@gmail.com for b in (0, 1): 605222Sksewell@umich.edu for w in (0, 1): 616658Snate@binkert.org post = (p == 0) 625222Sksewell@umich.edu user = (p == 0 and w == 1) 635222Sksewell@umich.edu writeback = (p == 0 or w == 1) 645222Sksewell@umich.edu add = (u == 1) 655222Sksewell@umich.edu if b == 0: 665222Sksewell@umich.edu size = 4 675222Sksewell@umich.edu else: 685222Sksewell@umich.edu size = 1 695222Sksewell@umich.edu if add: 705222Sksewell@umich.edu addStr = "true" 715222Sksewell@umich.edu else: 725222Sksewell@umich.edu addStr = "false" 735222Sksewell@umich.edu if imm: 745222Sksewell@umich.edu newDecode = "return new %s(machInst, RD, RN," + \ 755222Sksewell@umich.edu "%s, machInst.immed11_0);" 765222Sksewell@umich.edu loadClass = loadImmClassName(post, add, writeback, 775222Sksewell@umich.edu size, False, user) 785222Sksewell@umich.edu storeClass = storeImmClassName(post, add, writeback, 795222Sksewell@umich.edu size, False, user) 805222Sksewell@umich.edu loadDecode = newDecode % (loadClass, addStr) 815222Sksewell@umich.edu storeDecode = newDecode % (storeClass, addStr) 825222Sksewell@umich.edu else: 835222Sksewell@umich.edu newDecode = "return new %s(machInst, RD, RN, %s," + \ 845222Sksewell@umich.edu "machInst.shiftSize," + \ 855222Sksewell@umich.edu "machInst.shift, RM);" 865222Sksewell@umich.edu loadClass = loadRegClassName(post, add, writeback, 875222Sksewell@umich.edu size, False, user) 885222Sksewell@umich.edu storeClass = storeRegClassName(post, add, writeback, 895222Sksewell@umich.edu size, False, user) 905222Sksewell@umich.edu loadDecode = newDecode % (loadClass, addStr) 915222Sksewell@umich.edu storeDecode = newDecode % (storeClass, addStr) 925222Sksewell@umich.edu decode = ''' 935222Sksewell@umich.edu case %#x: 945222Sksewell@umich.edu {%s} 955222Sksewell@umich.edu break; 965222Sksewell@umich.edu ''' 975222Sksewell@umich.edu decode_block += decode % \ 985222Sksewell@umich.edu (buildPUBWLCase(p,u,b,w,1), loadDecode) 995222Sksewell@umich.edu decode_block += decode % \ 1005222Sksewell@umich.edu (buildPUBWLCase(p,u,b,w,0), storeDecode) 1015222Sksewell@umich.edu decode_block += ''' 1025222Sksewell@umich.edu default: 1035222Sksewell@umich.edu return new Unknown(machInst); 1045222Sksewell@umich.edu break; 1055222Sksewell@umich.edu }''' 1065714Shsul@eecs.umich.edu}}; 1075222Sksewell@umich.edu 1085222Sksewell@umich.edudef format AddrMode3() {{ 1095222Sksewell@umich.edu decode = ''' 1105222Sksewell@umich.edu { 1115222Sksewell@umich.edu const uint32_t op1 = bits(machInst, 24, 20); 1125222Sksewell@umich.edu const uint32_t op2 = bits(machInst, 6, 5); 1135222Sksewell@umich.edu const uint32_t puiw = bits(machInst, 24, 21); 1145222Sksewell@umich.edu const uint32_t imm = IMMED_HI_11_8 << 4 | IMMED_LO_3_0; 1155222Sksewell@umich.edu switch (op2) { 1165222Sksewell@umich.edu case 0x1: 1175222Sksewell@umich.edu if (op1 & 0x1) { 1185222Sksewell@umich.edu %(ldrh)s 1195222Sksewell@umich.edu } else { 1205222Sksewell@umich.edu %(strh)s 1215222Sksewell@umich.edu } 1225222Sksewell@umich.edu case 0x2: 1235222Sksewell@umich.edu if (op1 & 0x1) { 1245222Sksewell@umich.edu %(ldrsb)s 1255222Sksewell@umich.edu } else { 1265222Sksewell@umich.edu %(ldrd)s 1275222Sksewell@umich.edu } 1285222Sksewell@umich.edu case 0x3: 1295222Sksewell@umich.edu if (op1 & 0x1) { 1305222Sksewell@umich.edu %(ldrsh)s 1315222Sksewell@umich.edu } else { 1325222Sksewell@umich.edu %(strd)s 1335222Sksewell@umich.edu } 1345222Sksewell@umich.edu default: 1355222Sksewell@umich.edu return new Unknown(machInst); 1365222Sksewell@umich.edu } 1375222Sksewell@umich.edu } 1385222Sksewell@umich.edu ''' 1395222Sksewell@umich.edu 1405222Sksewell@umich.edu def decodePuiwCase(load, d, p, u, i, w, size=4, sign=False): 1415222Sksewell@umich.edu post = (p == 0) 1425222Sksewell@umich.edu user = (p == 0 and w == 1) 1435222Sksewell@umich.edu writeback = (p == 0 or w == 1) 1445222Sksewell@umich.edu add = (u == 1) 1455222Sksewell@umich.edu caseVal = (p << 3) + (u << 2) + (i << 1) + (w << 0) 1465222Sksewell@umich.edu decode = ''' 1475222Sksewell@umich.edu case %#x: 1485222Sksewell@umich.edu return new '''% caseVal 1495222Sksewell@umich.edu if add: 1505222Sksewell@umich.edu addStr = "true" 1515222Sksewell@umich.edu else: 1525222Sksewell@umich.edu addStr = "false" 1535222Sksewell@umich.edu if d: 1545222Sksewell@umich.edu dests = "RT & ~1, RT | 1" 1555222Sksewell@umich.edu else: 1565222Sksewell@umich.edu dests = "RT" 1575222Sksewell@umich.edu if i: 1585222Sksewell@umich.edu if load: 1595222Sksewell@umich.edu if d: 1605222Sksewell@umich.edu className = loadDoubleImmClassName(post, add, writeback) 1615222Sksewell@umich.edu else: 1625222Sksewell@umich.edu className = loadImmClassName(post, add, writeback, \ 1635222Sksewell@umich.edu size=size, sign=sign, \ 1645222Sksewell@umich.edu user=user) 1655222Sksewell@umich.edu else: 1665222Sksewell@umich.edu if d: 1675222Sksewell@umich.edu className = storeDoubleImmClassName(post, add, writeback) 1685222Sksewell@umich.edu else: 1695222Sksewell@umich.edu className = storeImmClassName(post, add, writeback, \ 1705222Sksewell@umich.edu size=size, sign=sign, \ 1715222Sksewell@umich.edu user=user) 1725222Sksewell@umich.edu decode += ("%s(machInst, %s, RN, %s, imm);\n" % \ 1735222Sksewell@umich.edu (className, dests, addStr)) 1745222Sksewell@umich.edu else: 1755222Sksewell@umich.edu if load: 1765222Sksewell@umich.edu if d: 1775222Sksewell@umich.edu className = loadDoubleRegClassName(post, add, writeback) 1785222Sksewell@umich.edu else: 1795222Sksewell@umich.edu className = loadRegClassName(post, add, writeback, \ 1805222Sksewell@umich.edu size=size, sign=sign, \ 1815222Sksewell@umich.edu user=user) 1825222Sksewell@umich.edu else: 1835222Sksewell@umich.edu if d: 1845222Sksewell@umich.edu className = storeDoubleRegClassName(post, add, writeback) 1855222Sksewell@umich.edu else: 1865222Sksewell@umich.edu className = storeRegClassName(post, add, writeback, \ 1875222Sksewell@umich.edu size=size, sign=sign, \ 1885222Sksewell@umich.edu user=user) 1895222Sksewell@umich.edu decode += ("%s(machInst, %s, RN, %s, 0, LSL, RM);\n" % \ 1905222Sksewell@umich.edu (className, dests, addStr)) 1915222Sksewell@umich.edu return decode 1925222Sksewell@umich.edu 1935222Sksewell@umich.edu def decodePuiw(load, d, size=4, sign=False): 1945222Sksewell@umich.edu global decodePuiwCase 1955222Sksewell@umich.edu decode = "switch (puiw) {\n" 1965222Sksewell@umich.edu for p in (0, 1): 1975222Sksewell@umich.edu for u in (0, 1): 1985222Sksewell@umich.edu for i in (0, 1): 1995222Sksewell@umich.edu for w in (0, 1): 2005222Sksewell@umich.edu decode += decodePuiwCase(load, d, p, u, i, w, 2015222Sksewell@umich.edu size, sign) 2025222Sksewell@umich.edu decode += ''' 2035222Sksewell@umich.edu default: 2045222Sksewell@umich.edu return new Unknown(machInst); 2055222Sksewell@umich.edu } 2065222Sksewell@umich.edu ''' 2075222Sksewell@umich.edu return decode 2085222Sksewell@umich.edu 2095222Sksewell@umich.edu subs = { 2105222Sksewell@umich.edu "ldrh" : decodePuiw(True, False, size=2), 21111321Ssteve.reinhardt@amd.com "strh" : decodePuiw(False, False, size=2), 2125222Sksewell@umich.edu "ldrsb" : decodePuiw(True, False, size=1, sign=True), 2135222Sksewell@umich.edu "ldrd" : decodePuiw(True, True), 2145222Sksewell@umich.edu "ldrsh" : decodePuiw(True, False, size=2, sign=True), 2155222Sksewell@umich.edu "strd" : decodePuiw(False, True) 2165222Sksewell@umich.edu } 2175222Sksewell@umich.edu decode_block = decode % subs 21811321Ssteve.reinhardt@amd.com}}; 2195222Sksewell@umich.edu 2205222Sksewell@umich.edudef format ArmSyncMem() {{ 2215222Sksewell@umich.edu decode_block = ''' 2225222Sksewell@umich.edu { 2235222Sksewell@umich.edu const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16); 2245222Sksewell@umich.edu const IntRegIndex rt = (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 2255222Sksewell@umich.edu const IntRegIndex rt2 = (IntRegIndex)(uint32_t)bits(machInst, 3, 0); 2265222Sksewell@umich.edu switch (PUBWL) { 2275222Sksewell@umich.edu case 0x10: 2285222Sksewell@umich.edu return new Swp(machInst, rt, rt2, rn); 2295222Sksewell@umich.edu case 0x14: 2305222Sksewell@umich.edu return new Swpb(machInst, rt, rt2, rn); 2315222Sksewell@umich.edu case 0x18: 2325222Sksewell@umich.edu return new WarnUnimplemented("strex", machInst); 2335222Sksewell@umich.edu case 0x19: 2345222Sksewell@umich.edu return new %(ldrex)s(machInst, rt, rn, true, 0); 2355222Sksewell@umich.edu case 0x1a: 2365222Sksewell@umich.edu return new WarnUnimplemented("strexd", machInst); 2375222Sksewell@umich.edu case 0x1b: 2385222Sksewell@umich.edu return new WarnUnimplemented("ldrexd", machInst); 2395222Sksewell@umich.edu case 0x1c: 2405222Sksewell@umich.edu return new WarnUnimplemented("strexb", machInst); 2415222Sksewell@umich.edu case 0x1d: 2425222Sksewell@umich.edu return new %(ldrexb)s(machInst, rt, rn, true, 0); 2435222Sksewell@umich.edu case 0x1e: 2445222Sksewell@umich.edu return new WarnUnimplemented("strexh", machInst); 2455222Sksewell@umich.edu case 0x1f: 2465222Sksewell@umich.edu return new %(ldrexh)s(machInst, rt, rn, true, 0); 2475222Sksewell@umich.edu default: 2485222Sksewell@umich.edu return new Unknown(machInst); 2495222Sksewell@umich.edu } 2505222Sksewell@umich.edu } 2515222Sksewell@umich.edu ''' % { 2525222Sksewell@umich.edu "ldrex" : "LDREX_" + loadImmClassName(False, True, False, size=4), 2535222Sksewell@umich.edu "ldrexb" : "LDREXB_" + loadImmClassName(False, True, False, size=1), 2545222Sksewell@umich.edu "ldrexh" : "LDREXH_" + loadImmClassName(False, True, False, size=2) 2555222Sksewell@umich.edu } 2565222Sksewell@umich.edu}}; 2575222Sksewell@umich.edu 2585222Sksewell@umich.edudef format Thumb32SrsRfe() {{ 2595222Sksewell@umich.edu decode_block = ''' 2605222Sksewell@umich.edu { 2615222Sksewell@umich.edu if (bits(machInst, 20) == 1) { 2625222Sksewell@umich.edu const bool add = (bits(machInst, 24, 23) == 0x3); 2635222Sksewell@umich.edu // post == add 2645222Sksewell@umich.edu const bool wb = (bits(machInst, 21) == 1); 2655222Sksewell@umich.edu const IntRegIndex rn = 2665222Sksewell@umich.edu (IntRegIndex)(uint32_t)bits(machInst, 19, 16); 2675222Sksewell@umich.edu if (!add && !wb) { 2685222Sksewell@umich.edu return new %(rfe)s(machInst, rn, RfeOp::DecrementBefore, wb); 2695222Sksewell@umich.edu } else if (add && !wb) { 2705222Sksewell@umich.edu return new %(rfe_u)s(machInst, rn, RfeOp::IncrementAfter, wb); 2715222Sksewell@umich.edu } else if (!add && wb) { 2725222Sksewell@umich.edu return new %(rfe_w)s(machInst, rn, RfeOp::DecrementBefore, wb); 27311321Ssteve.reinhardt@amd.com } else { 2745222Sksewell@umich.edu return new %(rfe_uw)s(machInst, rn, RfeOp::IncrementAfter, wb); 2755222Sksewell@umich.edu } 2765222Sksewell@umich.edu } else { 2775222Sksewell@umich.edu return new WarnUnimplemented("srs", machInst); 2785222Sksewell@umich.edu } 2795222Sksewell@umich.edu } 2805222Sksewell@umich.edu ''' % { 2815222Sksewell@umich.edu "rfe" : "RFE_" + loadImmClassName(False, False, False, 8), 2825222Sksewell@umich.edu "rfe_u" : "RFE_" + loadImmClassName(True, True, False, 8), 2835222Sksewell@umich.edu "rfe_w" : "RFE_" + loadImmClassName(False, False, True, 8), 2845222Sksewell@umich.edu "rfe_uw" : "RFE_" + loadImmClassName(True, True, True, 8) 2855222Sksewell@umich.edu } 2865222Sksewell@umich.edu}}; 28711321Ssteve.reinhardt@amd.com 2885222Sksewell@umich.edudef format Thumb32LdrStrDExTbh() {{ 28911321Ssteve.reinhardt@amd.com decode_block = ''' 2905222Sksewell@umich.edu { 29111321Ssteve.reinhardt@amd.com const uint32_t op1 = bits(machInst, 24, 23); 2925222Sksewell@umich.edu const uint32_t op2 = bits(machInst, 21, 20); 2935222Sksewell@umich.edu const uint32_t op3 = bits(machInst, 7, 4); 2945222Sksewell@umich.edu const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16); 2955222Sksewell@umich.edu const IntRegIndex rt = (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 2965222Sksewell@umich.edu const IntRegIndex rt2 = (IntRegIndex)(uint32_t)bits(machInst, 11, 8); 2975222Sksewell@umich.edu const uint32_t imm8 = bits(machInst, 7, 0); 2985222Sksewell@umich.edu if (bits(op1, 1) == 0 && bits(op2, 1) == 0) { 2995222Sksewell@umich.edu if (op1 == 0) { 3005222Sksewell@umich.edu const uint32_t imm = bits(machInst, 7, 0) << 2; 3015222Sksewell@umich.edu if (op2 == 0) { 3025222Sksewell@umich.edu return new WarnUnimplemented("strex", machInst); 3035222Sksewell@umich.edu } else { 30411321Ssteve.reinhardt@amd.com return new %(ldrex)s(machInst, rt, rn, true, imm); 3055222Sksewell@umich.edu } 3065222Sksewell@umich.edu } else { 3075222Sksewell@umich.edu if (op2 == 0) { 3085222Sksewell@umich.edu switch (op3) { 3095222Sksewell@umich.edu case 0x4: 3105222Sksewell@umich.edu return new WarnUnimplemented("strexb", machInst); 31111321Ssteve.reinhardt@amd.com case 0x5: 3125222Sksewell@umich.edu return new WarnUnimplemented("strexh", machInst); 3135222Sksewell@umich.edu case 0x7: 3145222Sksewell@umich.edu return new WarnUnimplemented("strexd", machInst); 3155222Sksewell@umich.edu default: 3165222Sksewell@umich.edu return new Unknown(machInst); 3175222Sksewell@umich.edu } 3185222Sksewell@umich.edu } else { 3195222Sksewell@umich.edu switch (op3) { 3205222Sksewell@umich.edu case 0x0: 3215222Sksewell@umich.edu return new WarnUnimplemented("tbb", machInst); 3225222Sksewell@umich.edu case 0x1: 3235222Sksewell@umich.edu return new WarnUnimplemented("tbh", machInst); 3245222Sksewell@umich.edu case 0x4: 3255222Sksewell@umich.edu return new %(ldrexb)s(machInst, rt, rn, true, 0); 3265222Sksewell@umich.edu case 0x5: 3275222Sksewell@umich.edu return new %(ldrexh)s(machInst, rt, rn, true, 0); 3285222Sksewell@umich.edu case 0x7: 3295222Sksewell@umich.edu return new %(ldrexd)s(machInst, rt, rt2, rn, true, 0); 3305222Sksewell@umich.edu default: 3315222Sksewell@umich.edu return new Unknown(machInst); 3325222Sksewell@umich.edu } 3335222Sksewell@umich.edu } 3345222Sksewell@umich.edu } 3355222Sksewell@umich.edu } else { 3365222Sksewell@umich.edu const uint32_t puw = (bits(machInst, 24, 23) << 1) | 3375222Sksewell@umich.edu bits(machInst, 21); 3385222Sksewell@umich.edu const uint32_t dimm = imm8 << 2; 3395222Sksewell@umich.edu if (bits(op2, 0) == 0) { 3405222Sksewell@umich.edu switch (puw) { 3415222Sksewell@umich.edu case 0x1: 3425222Sksewell@umich.edu return new %(strd_w)s(machInst, rt, rt2, rn, false, dimm); 3435222Sksewell@umich.edu case 0x3: 3445222Sksewell@umich.edu return new %(strd_uw)s(machInst, rt, rt2, rn, true, dimm); 3455222Sksewell@umich.edu case 0x4: 3465222Sksewell@umich.edu return new %(strd_p)s(machInst, rt, rt2, rn, false, dimm); 3475222Sksewell@umich.edu case 0x5: 3485222Sksewell@umich.edu return new %(strd_pw)s(machInst, rt, rt2, rn, false, dimm); 3495222Sksewell@umich.edu case 0x6: 3505222Sksewell@umich.edu return new %(strd_pu)s(machInst, rt, rt2, rn, true, dimm); 3515222Sksewell@umich.edu case 0x7: 3525222Sksewell@umich.edu return new %(strd_puw)s(machInst, rt, rt2, rn, true, dimm); 3535222Sksewell@umich.edu default: 3545222Sksewell@umich.edu return new Unknown(machInst); 3555222Sksewell@umich.edu } 3565222Sksewell@umich.edu } else { 3575222Sksewell@umich.edu switch (puw) { 3585222Sksewell@umich.edu case 0x1: 3595222Sksewell@umich.edu return new %(ldrd_w)s(machInst, rt, rt2, rn, false, dimm); 3605222Sksewell@umich.edu case 0x3: 3615222Sksewell@umich.edu return new %(ldrd_uw)s(machInst, rt, rt2, rn, true, dimm); 3625222Sksewell@umich.edu case 0x4: 3635222Sksewell@umich.edu return new %(ldrd_p)s(machInst, rt, rt2, rn, false, dimm); 3645222Sksewell@umich.edu case 0x5: 3655222Sksewell@umich.edu return new %(ldrd_pw)s(machInst, rt, rt2, rn, false, dimm); 3665222Sksewell@umich.edu case 0x6: 3675222Sksewell@umich.edu return new %(ldrd_pu)s(machInst, rt, rt2, rn, true, dimm); 3685222Sksewell@umich.edu case 0x7: 3695222Sksewell@umich.edu return new %(ldrd_puw)s(machInst, rt, rt2, rn, true, dimm); 3705222Sksewell@umich.edu default: 3715222Sksewell@umich.edu return new Unknown(machInst); 3725222Sksewell@umich.edu } 3735222Sksewell@umich.edu } 3745222Sksewell@umich.edu } 3755222Sksewell@umich.edu } 3765222Sksewell@umich.edu ''' % { 3775222Sksewell@umich.edu "ldrex" : "LDREX_" + loadImmClassName(False, True, False, size=4), 3785222Sksewell@umich.edu "ldrexb" : "LDREXB_" + loadImmClassName(False, True, False, size=1), 3795222Sksewell@umich.edu "ldrexh" : "LDREXH_" + loadImmClassName(False, True, False, size=2), 3805222Sksewell@umich.edu "ldrexd" : "LDREXD_" + loadDoubleImmClassName(False, True, False), 3815222Sksewell@umich.edu "ldrd_w" : loadDoubleImmClassName(True, False, True), 3825222Sksewell@umich.edu "ldrd_uw" : loadDoubleImmClassName(True, True, True), 3835222Sksewell@umich.edu "ldrd_p" : loadDoubleImmClassName(False, False, False), 3845222Sksewell@umich.edu "ldrd_pw" : loadDoubleImmClassName(False, False, True), 3855222Sksewell@umich.edu "ldrd_pu" : loadDoubleImmClassName(False, True, False), 3865222Sksewell@umich.edu "ldrd_puw" : loadDoubleImmClassName(False, True, True), 3875222Sksewell@umich.edu "strd_w" : storeDoubleImmClassName(True, False, True), 3885222Sksewell@umich.edu "strd_uw" : storeDoubleImmClassName(True, True, True), 3895222Sksewell@umich.edu "strd_p" : storeDoubleImmClassName(False, False, False), 3905222Sksewell@umich.edu "strd_pw" : storeDoubleImmClassName(False, False, True), 3915222Sksewell@umich.edu "strd_pu" : storeDoubleImmClassName(False, True, False), 3925222Sksewell@umich.edu "strd_puw" : storeDoubleImmClassName(False, True, True) 3935222Sksewell@umich.edu } 3945222Sksewell@umich.edu}}; 3955222Sksewell@umich.edu 3965222Sksewell@umich.edudef format Thumb32LoadWord() {{ 3975222Sksewell@umich.edu decode = ''' 3985222Sksewell@umich.edu { 3995222Sksewell@umich.edu uint32_t op1 = bits(machInst, 24, 23); 4005222Sksewell@umich.edu if (bits(op1, 1) == 0) { 4015222Sksewell@umich.edu uint32_t op2 = bits(machInst, 11, 6); 4025222Sksewell@umich.edu if (HTRN == 0xF) { 4035222Sksewell@umich.edu if (UP) { 4045222Sksewell@umich.edu return new %(literal_u)s(machInst, RT, INTREG_PC, 4055222Sksewell@umich.edu true, IMMED_11_0); 4065222Sksewell@umich.edu } else { 4075222Sksewell@umich.edu return new %(literal)s(machInst, RT, INTREG_PC, 4085222Sksewell@umich.edu false, IMMED_11_0); 4095222Sksewell@umich.edu } 4105222Sksewell@umich.edu } else if (op1 == 0x1) { 4115222Sksewell@umich.edu return new %(imm_pu)s(machInst, RT, RN, true, IMMED_11_0); 4125222Sksewell@umich.edu } else if (op2 == 0) { 4135222Sksewell@umich.edu return new %(register)s(machInst, RT, RN, UP, 4145222Sksewell@umich.edu bits(machInst, 5, 4), LSL, RM); 4155222Sksewell@umich.edu } else if ((op2 & 0x3c) == 0x38) { 4165222Sksewell@umich.edu return new %(ldrt)s(machInst, RT, RN, true, IMMED_7_0); 4175222Sksewell@umich.edu } else if ((op2 & 0x3c) == 0x30 || //P 4185222Sksewell@umich.edu (op2 & 0x24) == 0x24) { //W 4195222Sksewell@umich.edu uint32_t puw = bits(machInst, 10, 8); 4205222Sksewell@umich.edu uint32_t imm = IMMED_7_0; 4215222Sksewell@umich.edu switch (puw) { 4225222Sksewell@umich.edu case 0: 4235222Sksewell@umich.edu case 2: 4245222Sksewell@umich.edu // If we're here, either P or W must have been set. 4255222Sksewell@umich.edu panic("Neither P or W set, but that " 4265222Sksewell@umich.edu "shouldn't be possible.\\n"); 4275222Sksewell@umich.edu case 1: 4285222Sksewell@umich.edu return new %(imm_w)s(machInst, RT, RN, false, imm); 4295222Sksewell@umich.edu case 3: 4305222Sksewell@umich.edu return new %(imm_uw)s(machInst, RT, RN, true, imm); 4315222Sksewell@umich.edu case 4: 4325222Sksewell@umich.edu return new %(imm_p)s(machInst, RT, RN, false, imm); 4335222Sksewell@umich.edu case 5: 4345222Sksewell@umich.edu return new %(imm_pw)s(machInst, RT, RN, false, imm); 4355222Sksewell@umich.edu case 6: 4365222Sksewell@umich.edu return new %(imm_pu)s(machInst, RT, RN, true, imm); 4375222Sksewell@umich.edu case 7: 4385222Sksewell@umich.edu return new %(imm_puw)s(machInst, RT, RN, true, imm); 4395222Sksewell@umich.edu } 4405222Sksewell@umich.edu } 4415222Sksewell@umich.edu } else { 4425222Sksewell@umich.edu return new Unknown(machInst); 4435222Sksewell@umich.edu } 4445222Sksewell@umich.edu } 4455222Sksewell@umich.edu ''' 4465222Sksewell@umich.edu classNames = { 4475222Sksewell@umich.edu "literal_u" : loadImmClassName(False, True, False), 4485222Sksewell@umich.edu "literal" : loadImmClassName(False, False, False), 4495222Sksewell@umich.edu "register" : loadRegClassName(False, True, False), 4505222Sksewell@umich.edu "ldrt" : loadImmClassName(False, True, False, user=True), 4515222Sksewell@umich.edu "imm_w" : loadImmClassName(True, False, True), 4525222Sksewell@umich.edu "imm_uw" : loadImmClassName(True, True, True), 4535222Sksewell@umich.edu "imm_p" : loadImmClassName(False, False, False), 4545222Sksewell@umich.edu "imm_pw" : loadImmClassName(False, False, True), 4555222Sksewell@umich.edu "imm_pu" : loadImmClassName(False, True, False), 4565222Sksewell@umich.edu "imm_puw" : loadImmClassName(False, True, True) 4575222Sksewell@umich.edu } 4585222Sksewell@umich.edu decode_block = decode % classNames 4595222Sksewell@umich.edu}}; 4605222Sksewell@umich.edu 4615222Sksewell@umich.edudef format Thumb32StoreSingle() {{ 4625222Sksewell@umich.edu def buildPuwDecode(size): 4635222Sksewell@umich.edu puwDecode = ''' 4645222Sksewell@umich.edu { 4655222Sksewell@umich.edu uint32_t puw = bits(machInst, 10, 8); 4665222Sksewell@umich.edu uint32_t imm = IMMED_7_0; 4675222Sksewell@umich.edu switch (puw) { 4685222Sksewell@umich.edu case 0: 4695222Sksewell@umich.edu case 2: 4705222Sksewell@umich.edu // If we're here, either P or W must have been set. 4715222Sksewell@umich.edu panic("Neither P or W set, but that " 4725222Sksewell@umich.edu "shouldn't be possible.\\n"); 4735222Sksewell@umich.edu case 1: 4745222Sksewell@umich.edu return new %(imm_w)s(machInst, RT, RN, false, imm); 4755222Sksewell@umich.edu case 3: 4765222Sksewell@umich.edu return new %(imm_uw)s(machInst, RT, RN, true, imm); 4775222Sksewell@umich.edu case 4: 4785222Sksewell@umich.edu return new %(imm_p)s(machInst, RT, RN, false, imm); 4795222Sksewell@umich.edu case 5: 48011321Ssteve.reinhardt@amd.com return new %(imm_pw)s(machInst, RT, RN, false, imm); 4815222Sksewell@umich.edu case 6: 4825222Sksewell@umich.edu return new %(imm_pu)s(machInst, RT, RN, true, imm); 4835222Sksewell@umich.edu case 7: 4845222Sksewell@umich.edu return new %(imm_puw)s(machInst, RT, RN, true, imm); 4855222Sksewell@umich.edu } 4865222Sksewell@umich.edu } 4875222Sksewell@umich.edu ''' 4885222Sksewell@umich.edu return puwDecode % { 4895222Sksewell@umich.edu "imm_w" : storeImmClassName(True, False, True, size=size), 4905222Sksewell@umich.edu "imm_uw" : storeImmClassName(True, True, True, size=size), 4915222Sksewell@umich.edu "imm_p" : storeImmClassName(False, False, False, size=size), 4925222Sksewell@umich.edu "imm_pw" : storeImmClassName(False, False, True, size=size), 4935222Sksewell@umich.edu "imm_pu" : storeImmClassName(False, True, False, size=size), 4945222Sksewell@umich.edu "imm_puw" : storeImmClassName(False, True, True, size=size) 49511321Ssteve.reinhardt@amd.com } 4965222Sksewell@umich.edu decode = ''' 4975222Sksewell@umich.edu { 4985222Sksewell@umich.edu uint32_t op1 = bits(machInst, 23, 21); 4995222Sksewell@umich.edu uint32_t op2 = bits(machInst, 11, 6); 5005222Sksewell@umich.edu bool op2Puw = ((op2 & 0x24) == 0x24 || 5015222Sksewell@umich.edu (op2 & 0x3c) == 0x30); 5025222Sksewell@umich.edu if (RN == 0xf) { 5035222Sksewell@umich.edu return new Unknown(machInst); 5045222Sksewell@umich.edu } 50510905Sandreas.sandberg@arm.com if (op1 == 4) { 5065222Sksewell@umich.edu return new %(strb_imm)s(machInst, RT, RN, true, IMMED_11_0); 5075222Sksewell@umich.edu } else if (op1 == 0 && op2Puw) { 5085222Sksewell@umich.edu %(strb_puw)s; 5095222Sksewell@umich.edu } else if (op1 == 0 && ((op2 & 0x3c) == 0x38)) { 5105222Sksewell@umich.edu return new %(strbt)s(machInst, RT, RN, true, IMMED_7_0); 5115222Sksewell@umich.edu } else if (op1 == 0 && op2 == 0) { 5125222Sksewell@umich.edu return new %(strb_reg)s(machInst, RT, RN, true, 5135222Sksewell@umich.edu bits(machInst, 5, 4), LSL, RM); 5145222Sksewell@umich.edu } else if (op1 == 5) { 51510905Sandreas.sandberg@arm.com return new %(strh_imm)s(machInst, RT, RN, true, IMMED_11_0); 5165222Sksewell@umich.edu } else if (op1 == 1 && op2Puw) { 5175222Sksewell@umich.edu %(strh_puw)s; 5185222Sksewell@umich.edu } else if (op1 == 1 && ((op2 & 0x3c) == 0x38)) { 5195222Sksewell@umich.edu return new %(strht)s(machInst, RT, RN, true, IMMED_7_0); 5205222Sksewell@umich.edu } else if (op1 == 1 && op2 == 0) { 5215222Sksewell@umich.edu return new %(strh_reg)s(machInst, RT, RN, true, 5225222Sksewell@umich.edu bits(machInst, 5, 4), LSL, RM); 5235222Sksewell@umich.edu } else if (op1 == 6) { 5245222Sksewell@umich.edu return new %(str_imm)s(machInst, RT, RN, true, IMMED_11_0); 5255222Sksewell@umich.edu } else if (op1 == 2 && op2Puw) { 5265222Sksewell@umich.edu %(str_puw)s; 5275222Sksewell@umich.edu } else if (op1 == 2 && ((op2 & 0x3c) == 0x38)) { 5285222Sksewell@umich.edu return new %(strt)s(machInst, RT, RN, true, IMMED_7_0); 5295222Sksewell@umich.edu } else if (op1 == 2 && op2 == 0) { 530 return new %(str_reg)s(machInst, RT, RN, true, 531 bits(machInst, 5, 4), LSL, RM); 532 } else { 533 return new Unknown(machInst); 534 } 535 } 536 ''' 537 classNames = { 538 "strb_imm" : storeImmClassName(False, True, False, size=1), 539 "strb_puw" : buildPuwDecode(1), 540 "strbt" : storeImmClassName(False, True, False, user=True, size=1), 541 "strb_reg" : storeRegClassName(False, True, False, size=1), 542 "strh_imm" : storeImmClassName(False, True, False, size=2), 543 "strh_puw" : buildPuwDecode(2), 544 "strht" : storeImmClassName(False, True, False, user=True, size=2), 545 "strh_reg" : storeRegClassName(False, True, False, size=2), 546 "str_imm" : storeImmClassName(False, True, False), 547 "str_puw" : buildPuwDecode(4), 548 "strt" : storeImmClassName(False, True, False, user=True), 549 "str_reg" : storeRegClassName(False, True, False) 550 } 551 decode_block = decode % classNames 552}}; 553 554def format LoadByteMemoryHints() {{ 555 decode = ''' 556 { 557 const uint32_t op1 = bits(machInst, 24, 23); 558 const uint32_t op2 = bits(machInst, 11, 6); 559 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16); 560 const IntRegIndex rt = (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 561 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0); 562 const uint32_t imm12 = bits(machInst, 11, 0); 563 const uint32_t imm8 = bits(machInst, 7, 0); 564 bool pldw = bits(machInst, 21); 565 const uint32_t imm2 = bits(machInst, 5, 4); 566 if (rn == 0xf) { 567 if (rt == 0xf) { 568 const bool add = bits(machInst, 23); 569 if (bits(op1, 1) == 1) { 570 if (add) { 571 return new %(pli_iulit)s(machInst, INTREG_ZERO, 572 INTREG_PC, true, imm12); 573 } else { 574 return new %(pli_ilit)s(machInst, INTREG_ZERO, 575 INTREG_PC, false, imm12); 576 } 577 } else { 578 if (add) { 579 return new %(pld_iulit)s(machInst, INTREG_ZERO, 580 INTREG_PC, true, imm12); 581 } else { 582 return new %(pld_ilit)s(machInst, INTREG_ZERO, 583 INTREG_PC, false, imm12); 584 } 585 } 586 } else { 587 if (bits(op1, 1) == 1) { 588 if (bits(machInst, 23)) { 589 return new %(ldrsb_lit_u)s(machInst, rt, INTREG_PC, 590 true, imm12); 591 } else { 592 return new %(ldrsb_lit)s(machInst, rt, INTREG_PC, 593 false, imm12); 594 } 595 } else { 596 if (bits(machInst, 23)) { 597 return new %(ldrb_lit_u)s(machInst, rt, INTREG_PC, 598 true, imm12); 599 } else { 600 return new %(ldrb_lit)s(machInst, rt, INTREG_PC, 601 false, imm12); 602 } 603 } 604 } 605 } else if (rt == 0xf) { 606 switch (op1) { 607 case 0x0: 608 if (op2 == 0x0) { 609 if (pldw) { 610 return new %(pldw_radd)s(machInst, INTREG_ZERO, 611 rn, true, imm2, LSL, rm); 612 } else { 613 return new %(pld_radd)s(machInst, INTREG_ZERO, 614 rn, true, imm2, LSL, rm); 615 } 616 } else if (bits(op2, 5, 2) == 0xc) { 617 if (pldw) { 618 return new %(pldw_isub)s(machInst, INTREG_ZERO, 619 rn, false, imm8); 620 } else { 621 return new %(pld_isub)s(machInst, INTREG_ZERO, 622 rn, false, imm8); 623 } 624 } 625 break; 626 case 0x1: 627 if (pldw) { 628 return new %(pldw_iadd)s(machInst, INTREG_ZERO, 629 rn, true, imm12); 630 } else { 631 return new %(pld_iadd)s(machInst, INTREG_ZERO, 632 rn, true, imm12); 633 } 634 case 0x2: 635 if (op2 == 0x0) { 636 return new %(pli_radd)s(machInst, INTREG_ZERO, rn, 637 true, imm2, LSL, rm); 638 } else if (bits(op2, 5, 2) == 0xc) { 639 return new %(pli_ilit)s(machInst, INTREG_ZERO, 640 INTREG_PC, false, imm8); 641 } 642 break; 643 case 0x3: 644 return new %(pli_iulit)s(machInst, INTREG_ZERO, 645 INTREG_PC, true, imm12); 646 } 647 return new Unknown(machInst); 648 } else { 649 switch (op1) { 650 case 0x0: 651 if (op2 == 0) { 652 return new %(ldrb_radd)s(machInst, rt, rn, true, 653 imm2, LSL, rm); 654 } else if (bits(op2, 5, 2) == 0xe) { 655 return new %(ldrbt)s(machInst, rt, rn, true, imm8); 656 } else if ((op2 & 0x24) == 0x24 || bits(op2, 5, 2) == 0xc) { 657 const uint32_t puw = bits(machInst, 10, 8); 658 switch (puw) { 659 case 0x1: 660 return new %(ldrb_iw)s(machInst, rt, 661 rn, false, imm8); 662 case 0x3: 663 return new %(ldrb_iuw)s(machInst, rt, 664 rn, true, imm8); 665 case 0x4: 666 return new %(ldrb_ip)s(machInst, rt, 667 rn, false, imm8); 668 case 0x5: 669 return new %(ldrb_ipw)s(machInst, rt, 670 rn, false, imm8); 671 case 0x7: 672 return new %(ldrb_ipuw)s(machInst, rt, 673 rn, true, imm8); 674 } 675 } 676 break; 677 case 0x1: 678 return new %(ldrb_iadd)s(machInst, rt, rn, true, imm12); 679 case 0x2: 680 if (op2 == 0) { 681 return new %(ldrsb_radd)s(machInst, rt, rn, true, 682 imm2, LSL, rm); 683 } else if (bits(op2, 5, 2) == 0xe) { 684 return new %(ldrsbt)s(machInst, rt, rn, true, imm8); 685 } else if ((op2 & 0x24) == 0x24 || bits(op2, 5, 2) == 0xc) { 686 const uint32_t puw = bits(machInst, 10, 8); 687 switch (puw) { 688 case 0x1: 689 return new %(ldrsb_iw)s(machInst, rt, 690 rn, false, imm8); 691 case 0x3: 692 return new %(ldrsb_iuw)s(machInst, rt, 693 rn, true, imm8); 694 case 0x4: 695 return new %(ldrsb_ip)s(machInst, rt, 696 rn, false, imm8); 697 case 0x5: 698 return new %(ldrsb_ipw)s(machInst, rt, 699 rn, false, imm8); 700 case 0x7: 701 return new %(ldrsb_ipuw)s(machInst, rt, 702 rn, true, imm8); 703 } 704 } 705 break; 706 case 0x3: 707 return new %(ldrsb_iadd)s(machInst, rt, rn, true, imm12); 708 } 709 return new Unknown(machInst); 710 } 711 } 712 ''' 713 substDict = { 714 "ldrsb_lit_u" : loadImmClassName(False, True, False, 1, True), 715 "ldrsb_lit" : loadImmClassName(False, False, False, 1, True), 716 "ldrb_lit_u" : loadImmClassName(False, True, False, 1), 717 "ldrb_lit" : loadImmClassName(False, False, False, 1), 718 "ldrsb_radd" : loadRegClassName(False, True, False, 1, True), 719 "ldrb_radd" : loadRegClassName(False, True, False, 1), 720 "ldrsb_iw" : loadImmClassName(True, False, True, 1, True), 721 "ldrsb_iuw" : loadImmClassName(True, True, True, 1, True), 722 "ldrsb_ip" : loadImmClassName(False, False, False, 1, True), 723 "ldrsb_ipw" : loadImmClassName(False, False, True, 1, True), 724 "ldrsb_ipuw" : loadImmClassName(False, True, True, 1, True), 725 "ldrsb_iadd" : loadImmClassName(False, True, False, 1, True), 726 "ldrb_iw" : loadImmClassName(True, False, True, 1), 727 "ldrb_iuw" : loadImmClassName(True, True, True, 1), 728 "ldrb_ip" : loadImmClassName(False, False, False, 1), 729 "ldrb_ipw" : loadImmClassName(False, False, True, 1), 730 "ldrb_ipuw" : loadImmClassName(False, True, True, 1), 731 "ldrb_iadd" : loadImmClassName(False, True, False, 1), 732 "ldrbt" : loadImmClassName(False, True, False, 1, user=True), 733 "ldrsbt" : loadImmClassName(False, True, False, 1, True, user=True), 734 "pldw_radd" : "PLDW_" + loadRegClassName(False, True, False, 1), 735 "pld_radd" : "PLD_" + loadRegClassName(False, True, False, 1), 736 "pldw_isub" : "PLDW_" + loadImmClassName(False, False, False, 1), 737 "pld_isub" : "PLD_" + loadImmClassName(False, False, False, 1), 738 "pldw_iadd" : "PLDW_" + loadImmClassName(False, True, False, 1), 739 "pld_iadd" : "PLD_" + loadImmClassName(False, True, False, 1), 740 "pld_iulit" : "PLD_" + loadImmClassName(False, True, False, 1), 741 "pld_ilit" : "PLD_" + loadImmClassName(False, False, False, 1), 742 "pli_iulit" : "PLI_" + loadImmClassName(False, True, False, 1), 743 "pli_ilit" : "PLI_" + loadImmClassName(False, False, False, 1), 744 "pli_radd" : "PLI_" + loadRegClassName(False, True, False, 1), 745 "pli_iulit" : "PLI_" + loadImmClassName(False, True, False, 1), 746 "pli_ilit" : "PLI_" + loadImmClassName(False, False, False, 1) 747 } 748 decode_block = decode % substDict 749}}; 750 751def format LoadHalfwordMemoryHints() {{ 752 decode = ''' 753 { 754 const uint32_t op1 = bits(machInst, 24, 23); 755 const uint32_t op2 = bits(machInst, 11, 6); 756 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16); 757 const IntRegIndex rt = (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 758 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0); 759 const uint32_t imm12 = bits(machInst, 11, 0); 760 const uint32_t imm8 = bits(machInst, 7, 0); 761 bool pldw = bits(machInst, 21); 762 const uint32_t imm2 = bits(machInst, 5, 4); 763 if (rn == 0xf) { 764 if (rt == 0xf) { 765 if (bits(op1, 1) == 1) { 766 // Unallocated memory hint 767 return new NopInst(machInst); 768 } else { 769 return new Unknown(machInst); 770 } 771 } else { 772 if (bits(op1, 1) == 1) { 773 if (bits(machInst, 23)) { 774 return new %(ldrsh_lit_u)s(machInst, rt, INTREG_PC, 775 true, imm12); 776 } else { 777 return new %(ldrsh_lit)s(machInst, rt, INTREG_PC, 778 false, imm12); 779 } 780 } else { 781 if (bits(machInst, 23)) { 782 return new %(ldrh_lit_u)s(machInst, rt, INTREG_PC, 783 true, imm12); 784 } else { 785 return new %(ldrh_lit)s(machInst, rt, INTREG_PC, 786 false, imm12); 787 } 788 } 789 } 790 } else if (rt == 0xf) { 791 switch (op1) { 792 case 0x0: 793 if (op2 == 0x0) { 794 if (pldw) { 795 return new %(pldw_radd)s(machInst, INTREG_ZERO, 796 rn, true, imm2, LSL, rm); 797 } else { 798 return new %(pld_radd)s(machInst, INTREG_ZERO, 799 rn, true, imm2, LSL, rm); 800 } 801 } else if (bits(op2, 5, 2) == 0xc) { 802 if (pldw) { 803 return new %(pldw_isub)s(machInst, INTREG_ZERO, 804 rn, false, imm8); 805 } else { 806 return new %(pld_isub)s(machInst, INTREG_ZERO, 807 rn, false, imm8); 808 } 809 } 810 break; 811 case 0x1: 812 if (pldw) { 813 return new %(pldw_iadd)s(machInst, INTREG_ZERO, 814 rn, true, imm12); 815 } else { 816 return new %(pld_iadd)s(machInst, INTREG_ZERO, 817 rn, true, imm12); 818 } 819 case 0x2: 820 if (op2 == 0x0 || bits(op2, 5, 2) == 0xc) { 821 // Unallocated memory hint 822 return new NopInst(machInst); 823 } 824 break; 825 case 0x3: 826 return new NopInst(machInst); 827 } 828 return new Unknown(machInst); 829 } else { 830 switch (op1) { 831 case 0x0: 832 if (op2 == 0) { 833 return new %(ldrh_radd)s(machInst, rt, rn, true, 834 imm2, LSL, rm); 835 } else if (bits(op2, 5, 2) == 0xe) { 836 return new %(ldrht)s(machInst, rt, rn, true, imm8); 837 } else if ((op2 & 0x24) == 0x24 || bits(op2, 5, 2) == 0xc) { 838 const uint32_t puw = bits(machInst, 10, 8); 839 switch (puw) { 840 case 0x1: 841 return new %(ldrh_iw)s(machInst, rt, 842 rn, false, imm8); 843 case 0x3: 844 return new %(ldrh_iuw)s(machInst, rt, 845 rn, true, imm8); 846 case 0x4: 847 return new %(ldrh_ip)s(machInst, rt, 848 rn, false, imm8); 849 case 0x5: 850 return new %(ldrh_ipw)s(machInst, rt, 851 rn, false, imm8); 852 case 0x7: 853 return new %(ldrh_ipuw)s(machInst, rt, 854 rn, true, imm8); 855 } 856 } 857 break; 858 case 0x1: 859 return new %(ldrh_iadd)s(machInst, rt, rn, true, imm12); 860 case 0x2: 861 if (op2 == 0) { 862 return new %(ldrsh_radd)s(machInst, rt, rn, true, 863 imm2, LSL, rm); 864 } else if (bits(op2, 5, 2) == 0xe) { 865 return new %(ldrsht)s(machInst, rt, rn, true, imm8); 866 } else if ((op2 & 0x24) == 0x24 || bits(op2, 5, 2) == 0xc) { 867 const uint32_t puw = bits(machInst, 10, 8); 868 switch (puw) { 869 case 0x1: 870 return new %(ldrsh_iw)s(machInst, rt, 871 rn, false, imm8); 872 case 0x3: 873 return new %(ldrsh_iuw)s(machInst, rt, 874 rn, true, imm8); 875 case 0x4: 876 return new %(ldrsh_ip)s(machInst, rt, 877 rn, false, imm8); 878 case 0x5: 879 return new %(ldrsh_ipw)s(machInst, rt, 880 rn, false, imm8); 881 case 0x7: 882 return new %(ldrsh_ipuw)s(machInst, rt, 883 rn, true, imm8); 884 } 885 } 886 break; 887 case 0x3: 888 return new %(ldrsh_iadd)s(machInst, rt, rn, true, imm12); 889 } 890 return new Unknown(machInst); 891 } 892 } 893 ''' 894 substDict = { 895 "ldrsh_lit_u" : loadImmClassName(False, True, False, 2, True), 896 "ldrsh_lit" : loadImmClassName(False, False, False, 2, True), 897 "ldrh_lit_u" : loadImmClassName(False, True, False, 2), 898 "ldrh_lit" : loadImmClassName(False, False, False, 2), 899 "ldrsh_radd" : loadRegClassName(False, True, False, 2, True), 900 "ldrh_radd" : loadRegClassName(False, True, False, 2), 901 "ldrsh_iw" : loadImmClassName(True, False, True, 2, True), 902 "ldrsh_iuw" : loadImmClassName(True, True, True, 2, True), 903 "ldrsh_ip" : loadImmClassName(False, False, False, 2, True), 904 "ldrsh_ipw" : loadImmClassName(False, False, True, 2, True), 905 "ldrsh_ipuw" : loadImmClassName(False, True, True, 2, True), 906 "ldrsh_iadd" : loadImmClassName(False, True, False, 2, True), 907 "ldrh_iw" : loadImmClassName(True, False, True, 2), 908 "ldrh_iuw" : loadImmClassName(True, True, True, 2), 909 "ldrh_ip" : loadImmClassName(False, False, False, 2), 910 "ldrh_ipw" : loadImmClassName(False, False, True, 2), 911 "ldrh_ipuw" : loadImmClassName(False, True, True, 2), 912 "ldrh_iadd" : loadImmClassName(False, True, False, 2), 913 "ldrht" : loadImmClassName(False, True, False, 2, user=True), 914 "ldrsht" : loadImmClassName(False, True, False, 2, True, user=True), 915 "pldw_radd" : "PLDW_" + loadRegClassName(False, True, False, 1), 916 "pld_radd" : "PLD_" + loadRegClassName(False, True, False, 1), 917 "pldw_isub" : "PLDW_" + loadImmClassName(False, False, False, 1), 918 "pld_isub" : "PLD_" + loadImmClassName(False, False, False, 1), 919 "pldw_iadd" : "PLDW_" + loadImmClassName(False, True, False, 1), 920 "pld_iadd" : "PLD_" + loadImmClassName(False, True, False, 1) 921 } 922 decode_block = decode % substDict 923}}; 924 925def format Thumb16MemReg() {{ 926 decode = ''' 927 { 928 const uint32_t opb = bits(machInst, 11, 9); 929 const uint32_t rt = bits(machInst, 2, 0); 930 const uint32_t rn = bits(machInst, 5, 3); 931 const uint32_t rm = bits(machInst, 8, 6); 932 switch (opb) { 933 case 0x0: 934 return new %(str)s(machInst, rt, rn, true, 0, LSL, rm); 935 case 0x1: 936 return new %(strh)s(machInst, rt, rn, true, 0, LSL, rm); 937 case 0x2: 938 return new %(strb)s(machInst, rt, rn, true, 0, LSL, rm); 939 case 0x3: 940 return new %(ldrsb)s(machInst, rt, rn, true, 0, LSL, rm); 941 case 0x4: 942 return new %(ldr)s(machInst, rt, rn, true, 0, LSL, rm); 943 case 0x5: 944 return new %(ldrh)s(machInst, rt, rn, true, 0, LSL, rm); 945 case 0x6: 946 return new %(ldrb)s(machInst, rt, rn, true, 0, LSL, rm); 947 case 0x7: 948 return new %(ldrsh)s(machInst, rt, rn, true, 0, LSL, rm); 949 } 950 } 951 ''' 952 classNames = { 953 "str" : storeRegClassName(False, True, False), 954 "strh" : storeRegClassName(False, True, False, size=2), 955 "strb" : storeRegClassName(False, True, False, size=1), 956 "ldrsb" : loadRegClassName(False, True, False, sign=True, size=1), 957 "ldr" : loadRegClassName(False, True, False), 958 "ldrh" : loadRegClassName(False, True, False, size=2), 959 "ldrb" : loadRegClassName(False, True, False, size=1), 960 "ldrsh" : loadRegClassName(False, True, False, sign=True, size=2), 961 } 962 decode_block = decode % classNames 963}}; 964 965def format Thumb16MemImm() {{ 966 decode = ''' 967 { 968 const uint32_t opa = bits(machInst, 15, 12); 969 const uint32_t opb = bits(machInst, 11, 9); 970 const uint32_t lrt = bits(machInst, 2, 0); 971 const uint32_t lrn = bits(machInst, 5, 3); 972 const uint32_t hrt = bits(machInst, 10, 8); 973 const uint32_t imm5 = bits(machInst, 10, 6); 974 const uint32_t imm8 = bits(machInst, 7, 0); 975 const bool load = bits(opb, 2); 976 switch (opa) { 977 case 0x6: 978 if (load) { 979 return new %(ldr)s(machInst, lrt, lrn, true, imm5 << 2); 980 } else { 981 return new %(str)s(machInst, lrt, lrn, true, imm5 << 2); 982 } 983 case 0x7: 984 if (load) { 985 return new %(ldrb)s(machInst, lrt, lrn, true, imm5); 986 } else { 987 return new %(strb)s(machInst, lrt, lrn, true, imm5); 988 } 989 case 0x8: 990 if (load) { 991 return new %(ldrh)s(machInst, lrt, lrn, true, imm5 << 1); 992 } else { 993 return new %(strh)s(machInst, lrt, lrn, true, imm5 << 1); 994 } 995 case 0x9: 996 if (load) { 997 return new %(ldr)s(machInst, hrt, INTREG_SP, true, imm8 << 2); 998 } else { 999 return new %(str)s(machInst, hrt, INTREG_SP, true, imm8 << 2); 1000 } 1001 default: 1002 return new Unknown(machInst); 1003 } 1004 } 1005 ''' 1006 classNames = { 1007 "ldr" : loadImmClassName(False, True, False), 1008 "str" : storeImmClassName(False, True, False), 1009 "ldrh" : loadImmClassName(False, True, False, size=2), 1010 "strh" : storeImmClassName(False, True, False, size=2), 1011 "ldrb" : loadImmClassName(False, True, False, size=1), 1012 "strb" : storeImmClassName(False, True, False, size=1), 1013 } 1014 decode_block = decode % classNames 1015}}; 1016 1017def format Thumb16MemLit() {{ 1018 decode_block = ''' 1019 { 1020 const uint32_t rt = bits(machInst, 10, 8); 1021 const uint32_t imm8 = bits(machInst, 7, 0); 1022 return new %s(machInst, rt, INTREG_PC, true, imm8 << 2); 1023 } 1024 ''' % loadImmClassName(False, True, False) 1025}}; 1026 1027