More arm instructions

This commit is contained in:
moom 2024-04-07 23:53:28 +08:00
parent 0fffa143ce
commit 67d0b838e4
5 changed files with 416 additions and 10 deletions

View file

@ -50,6 +50,21 @@ gpregs_nosp = reg_info(regs_str[:13] + [str(reg_dum), regs_str[14], regs_str[15]
regs_expr[:13] + [reg_dum, regs_expr[14], regs_expr[15]])
# Single-Precision
spregs_str = ['S%d' % r for r in range(32)]
spregs_expr = [ExprId(x, 32) for x in spregs_str]
spregs = reg_info(spregs_str, spregs_expr)
# Double-Precision
dpregs_str = ['D%d' % r for r in range(32)]
dpregs_expr = [ExprId(x, 64) for x in dpregs_str]
dpregs = reg_info(dpregs_str, dpregs_expr)
# Quadword
qpregs_str = ['Q%d' % r for r in range(16)]
qpregs_expr = [ExprId(x, 128) for x in qpregs_str]
qpregs = reg_info(qpregs_str, qpregs_expr)
# psr
sr_flags = "cxsf"
cpsr_regs_str = []
@ -1834,6 +1849,7 @@ armop("pld", [bs8(0xF5), bs_addi, bs_rw, bs('01'), mem_rn_imm, bs('1111'), imm12
armop("dsb", [bs('111101010111'), bs('1111'), bs('1111'), bs('0000'), bs('0100'), barrier_option])
armop("isb", [bs('111101010111'), bs('1111'), bs('1111'), bs('0000'), bs('0110'), barrier_option])
armop("dmb", [bs('111101010111'), bs('1111'), bs('1111'), bs('0000'), bs('0101'), barrier_option])
armop("nop", [bs8(0xE3), bs8(0x20), bs8(0xF0), bs8(0)])
class arm_widthm1(arm_imm, m_arg):
@ -2127,6 +2143,13 @@ class arm_off8sppc(arm_imm):
def encodeval(self, v):
return v >> 2
class arm_off8(arm_imm):
def decodeval(self, v):
return v << 2
def encodeval(self, v):
return v >> 2
class arm_off7(arm_imm):
@ -2137,11 +2160,16 @@ class arm_off7(arm_imm):
return v >> 2
class arm_deref_reg_imm(arm_arg):
reg_info = gpregs
parser = deref_reg_imm
def decode(self, v):
v = v & self.lmask
rbase = regs_expr[v]
# We should not use regs_expr direct
# subclass overwrite reg_info in some case
if regs_expr[v] not in self.reg_info.expr:
return False
rbase = self.reg_info.expr[v]
e = ExprOp('preinc', rbase, self.parent.off.expr)
self.expr = ExprMem(e, 32)
return True
@ -2164,9 +2192,6 @@ class arm_deref_reg_imm(arm_arg):
log.debug('cannot encode off %r', off)
return False
self.value = gpregs.expr.index(e.args[0])
if self.value >= 1 << self.l:
log.debug('cannot encode reg %r', off)
return False
return True
class arm_derefl(arm_deref_reg_imm):
@ -2440,8 +2465,9 @@ class arm_sp(arm_reg):
off5 = bs(l=5, cls=(arm_imm,), fname="off")
off3 = bs(l=3, cls=(arm_imm,), fname="off")
off8 = bs(l=8, cls=(arm_imm,), fname="off")
imm8 = bs(l=8, cls=(arm_imm,), fname="off")
off7 = bs(l=7, cls=(arm_off7,), fname="off")
off8 = bs(l=8, cls=(arm_off8,), fname="off", order=-1)
rdl = bs(l=3, cls=(arm_gpreg_l,), fname="rd")
rnl = bs(l=3, cls=(arm_gpreg_l,), fname="rn")
@ -2543,7 +2569,7 @@ bs_br_name = bs_name(l=4, name=br_name)
armtop("mshift", [bs('000'), bs_mshift_name, off5, rsl, rdl], [rdl, rsl, off5])
armtop("addsubr", [bs('000110'), bs_addsub_name, rnl, rsl, rdl], [rdl, rsl, rnl])
armtop("addsubi", [bs('000111'), bs_addsub_name, off3, rsl, rdl], [rdl, rsl, off3])
armtop("mcas", [bs('001'), bs_mov_cmp_add_sub_name, rnl, off8])
armtop("mcas", [bs('001'), bs_mov_cmp_add_sub_name, rnl, imm8])
armtop("alu", [bs('010000'), bs_alu_name, rsl, rdl], [rdl, rsl])
# should not be used ??
armtop("hiregop00", [bs('010001'), bs_hiregop_name, bs('00'), rsl, rdl], [rdl, rsl])
@ -3436,9 +3462,69 @@ armtop("strd", [bs('1110100'), ppi, updown, bs('1'), wback_no_t, bs('0'), rn_nop
armtop("ldrd", [bs('1110100'), ppi, updown, bs('1'), wback_no_t, bs('1'), rn_nopc_noarg, rt, rt2, deref_immpuw00], [rt, rt2, deref_immpuw00])
armtop("ldr", [bs('111110001101'), rn_deref, rt, off12], [rt, rn_deref])
armtop("ldr", [bs('111110000101'), rn_noarg, rt, bs('1'), ppi, updown, wback_no_t, deref_immpuw], [rt, deref_immpuw])
armtop("ldr", [bs('111110000101'), rn_noarg, rt, bs('000000'), imm2_noarg, rm_deref_reg], [rt, rm_deref_reg])
class armt_rn_deref_up(arm_arg):
parser = deref_reg_imm
def decode(self, v):
v = v & self.lmask
rbase = regs_expr[v]
e = None
if self.parent.updown.value == 1:
e = ExprOp('preinc', rbase, self.parent.off.expr)
else:
e = ExprOp('preinc', rbase, -self.parent.off.expr)
self.expr = ExprMem(e, 32)
return True
def encode(self):
self.parent.off.expr = None
e = self.expr
if not isinstance(e, ExprMem):
return False
e = e.ptr
if not (isinstance(e, ExprOp) and e.op == 'preinc'):
log.debug('cannot encode %r', e)
return False
off = e.args[1]
if not isinstance(off, ExprInt):
log.debug('cannot encode off %r', off)
return False
v = int(off)
if v < 0 or v & (1 << 31):
self.parent.updown.value = 0
v = (-v) & 0xFFFFFFFF
else:
self.parent.updown.value = 1
self.parent.off.expr = ExprInt(v, 32)
self.value = gpregs.expr.index(e.args[0])
return True
class arm_gpreg_nopc_noarg(reg_noarg):
reg_info = gpregs_nopc
parser = reg_info.parser
class arm_nopc_deref(arm_deref_reg_imm):
reg_info = gpregs_nopc
class armt_pc_deref_up(armt_rn_deref_up):
parser = deref_pc
class armt_nopc_deref_up(armt_rn_deref_up):
pass
rn_nopc_noarg = bs(l=4, cls=(arm_gpreg_nopc_noarg,), fname="rn")
rn_nopc_deref = bs(l=4, cls=(arm_nopc_deref,), fname="rt")
rn_nopc_deref_up = bs(l=4, cls=(armt_nopc_deref_up,))
pc_deref_up = bs("1111", l=4, cls=(armt_pc_deref_up,))
armtop("ldr", [bs('11111000'), updown, bs('101'), pc_deref_up, rt, off12], [rt, pc_deref_up])
armtop("ldr", [bs('111110001101'), rn_nopc_deref, rt, off12], [rt, rn_nopc_deref])
armtop("ldr", [bs('111110000101'), rn_nopc_noarg, rt, bs('1'), ppi, updown, wback_no_t, deref_immpuw], [rt, deref_immpuw])
armtop("ldr", [bs('111110000101'), rn_nopc_noarg, rt, bs('000000'), imm2_noarg, rm_deref_reg], [rt, rm_deref_reg])
armtop("ldrb", [bs('111110000001'), rn_noarg, rt, bs('000000'), imm2_noarg, rm_deref_reg], [rt, rm_deref_reg])
armtop("ldrb", [bs('111110000001'), rn_noarg, rt, bs('1'), ppi, updown, wback_no_t, deref_immpuw], [rt, deref_immpuw])
armtop("ldrb", [bs('111110001001'), rn_deref, rt_nopc, off12], [rt_nopc, rn_deref])
@ -3456,3 +3542,106 @@ armtop("tbh", [bs('111010001101'), rn_noarg, bs('11110000000'), bs('1'), bs_der
armtop("dsb", [bs('111100111011'), bs('1111'), bs('1000'), bs('1111'), bs('0100'), barrier_option])
armtop("adr", [bs('11110'), imm12_1, bs('100000'), bs('1111'), bs('0'), imm12_3, rd, imm12_8_t4], [rd, imm12_8_t4])
class arm_dpregs_1_4(reg_noarg):
reg_info = dpregs
parser = reg_info.parser
def decode(self, v):
v = v & self.lmask
v = self.parent.dpregs_1_x.value << 4 | v
self.expr = self.reg_info.expr[v]
return True
def encode(self):
if not self.expr in self.reg_info.expr:
log.debug("cannot encode reg %r", self.expr)
return False
self.value = self.reg_info.expr.index(self.expr)
self.parent.dpregs_1_x.value = self.value >> 4 & self.parent.dpregs_1_x.lmask
return True
class arm_spregs_4_1(reg_noarg):
reg_info = spregs
parser = reg_info.parser
def decode(self, v):
v = v & self.lmask
v = self.parent.spregs_x_1.value | (v << 1)
self.expr = self.reg_info.expr[v]
return True
def encode(self):
if not self.expr in self.reg_info.expr:
log.debug("cannot encode reg %r", self.expr)
return False
self.value = self.reg_info.expr.index(self.expr)
self.parent.spregs_x_1.value = self.value & self.parent.spregs_x_1.lmask
return True
class arm_dpregs_4_1:
reg_info = dpregs
parser = reg_info.parser
def decode(self, v):
v = v & self.lmask
v = self.parent.dpregs_x_1.value | v << 1
self.expr = self.reg_info.expr[v]
return True
def encode(self):
if not self.expr in self.reg_info.expr:
log.debug("cannot encode reg %r", self.expr)
return False
self.value = self.reg_info.expr.index(self.expr)
self.parent.dpregs_x_1.value = self.value & self.parent.dpregs_x_1.lmask
return True
sn_4_1 = bs(l=4, cls=(arm_spregs_4_1, arm_arg))
sn_x_1 = bs(l=1, fname="spregs_x_1", order=-1)
sm_4_1 = bs(l=4, cls=(arm_spregs_4_1, arm_arg))
sm_x_1 = bs(l=1, fname="spregs_x_1", order=-1)
dn_1_4 = bs(l=4, cls=(arm_dpregs_1_4, arm_arg))
dn_1_x = bs(l=1, fname="dpregs_1_x", order=-1)
dm_4_1 = bs(l=4, cls=(arm_dpregs_4_1, arm_arg))
dm_x_1 = bs(l=1, fname="dpregs_x_1", order=-1)
round_zero = bs('1', l=1, fname="round_zero")
vunsigned = bs(l=1, fname="unsigned")
rt2_nopc = bs(l=4, cls=(arm_gpreg_nopc, arm_arg), fname="rt")
rn_sp_nowb = bs("1101", cls=(arm_gpreg,), fname='rnsp')
armtop("dmb", [bs('111100111011'), bs('1111'), bs('1000'), bs('1111'), bs('0101'), barrier_option])
armtop("teq", [bs('111010101001'), rn_nosppc, bs('0'), imm5_3, bs('1111'), imm5_2, imm_stype, rm_sh])
armtop("btransfersp", [bs('1110100010'), wback, bs_tbtransfer_name, rn_wb, pc_in, lr_in, bs('0'), trlist13pclr])
armtop("add", [bs('11110'), imm12_1, bs('10000'), bs('0'), rn_sp_nowb, bs('0'), imm12_3, rd, imm12_8_t4], [rd, rn_sp_nowb, imm12_8_t4])
armtop("strb", [bs('111110000000'), rn_noarg, rt, bs('000000'), imm2_noarg, rm_deref_reg], [rt, rm_deref_reg])
armtop("strex", [bs('111010000100'), rn_deref, rt, rd, off8], [rd, rt, rn_deref])
armtop("ldrex",[bs('111010000101'), rn_deref, rt, bs('1111'), off8], [rt, rn_deref])
# DDI0406C.d, A8.8.344
armtop("vmov", [bs('11101110000'), bs('1'), sn_4_1, rt_nopc, bs('1010'), sn_x_1, bs('0010000')], [rt_nopc, sn_4_1])
armtop("vmov", [bs('11101110000'), bs('0'), sn_4_1, rt_nopc, bs('1010'), sn_x_1, bs('0010000')], [sn_4_1, rt_nopc])
# DDI0406C.d, A8.8.346
armtop("vmov", [bs('11101100010'), bs('1'), rt2_nopc, rt_nopc, bs('101100'), dn_1_x, bs('1'), dn_1_4], [rt_nopc, rt2_nopc, dn_1_4])
armtop("vmov", [bs('11101100010'), bs('0'), rt2_nopc, rt_nopc, bs('101100'), dn_1_x, bs('1'), dn_1_4], [dn_1_4, rt_nopc, rt2_nopc])
# DDI0406C.d, A8.8.310
armtop("vcvt", [bs('111011101'), sn_x_1, bs('111'), bs("101"), sn_4_1, bs('101'), bs('1'), round_zero, bs('1'), dn_1_x, bs('0'), dn_1_4], [sn_4_1, dn_1_4])
armtop("vcvt", [bs('111011101'), sn_x_1, bs('111'), bs("101"), sn_4_1, bs('101'), bs('0'), round_zero, bs('1'), sm_x_1, bs('0'), sm_4_1], [sn_4_1, sm_4_1])
armtop("vcvt", [bs('111011101'), sn_x_1, bs('111'), bs("100"), sn_4_1, bs('101'), bs('1'), round_zero, bs('1'), dn_1_x, bs('0'), dn_1_4], [sn_4_1, dn_1_4])
armtop("vcvt", [bs('111011101'), sn_x_1, bs('111'), bs("100"), sn_4_1, bs('101'), bs('0'), round_zero, bs('1'), sm_x_1, bs('0'), sm_4_1], [sn_4_1, sm_4_1])
armtop("vcvt", [bs('111011101'), dn_1_x, bs('111'), bs("000"), dn_1_4, bs('101'), bs('1'), bs('1'), bs('1'), sm_x_1, bs('0'), sm_4_1], [dn_1_4, sm_4_1])
armtop("vcvt", [bs('111011101'), dn_1_x, bs('111'), bs("000"), dn_1_4, bs('101'), bs('1'), bs('0'), bs('1'), sm_x_1, bs('0'), sm_4_1], [dn_1_4, sm_4_1])
armtop("vcvt", [bs('111011101'), sn_x_1, bs('111'), bs("000"), sn_4_1, bs('101'), bs('0'), bs('1'), bs('1'), sm_x_1, bs('0'), sm_4_1], [sn_4_1, sm_4_1])
armtop("vcvt", [bs('111011101'), sn_x_1, bs('111'), bs("000"), sn_4_1, bs('101'), bs('0'), bs('0'), bs('1'), sm_x_1, bs('0'), sm_4_1], [sn_4_1, sm_4_1])
# DDI0406C.d, A8.8.414
armtop("vstr", [bs('11101101'), updown, dn_1_x, bs('00'), rn_nopc_deref_up, dn_1_4, bs('1011'), off8], [dn_1_4, rn_nopc_deref_up])
armtop("vstr", [bs('11101101'), updown, sn_x_1, bs('00'), rn_nopc_deref_up, sn_4_1, bs('1010'), off8], [sn_4_1, rn_nopc_deref_up])

View file

@ -4,6 +4,101 @@ from builtins import range
from miasm.expression.expression import *
from miasm.core.cpu import gen_reg, gen_regs
# SP, DP, QP
spregs_str = ['S%d' % r for r in range(32)]
spregs_expr = [ExprId(x, 32) for x in spregs_str]
dpregs_str = ['D%d' % r for r in range(32)]
dpregs_expr = [ExprId(x, 64) for x in dpregs_str]
qpregs_str = ['Q%d' % r for r in range(16)]
qpregs_expr = [ExprId(x, 128) for x in qpregs_str]
D0 = dpregs_expr[0]
D1 = dpregs_expr[1]
D2 = dpregs_expr[2]
D3 = dpregs_expr[3]
D4 = dpregs_expr[4]
D5 = dpregs_expr[5]
D6 = dpregs_expr[6]
D7 = dpregs_expr[7]
D8 = dpregs_expr[8]
D9 = dpregs_expr[9]
D10 = dpregs_expr[10]
D11 = dpregs_expr[11]
D12 = dpregs_expr[12]
D13 = dpregs_expr[13]
D14 = dpregs_expr[14]
D15 = dpregs_expr[15]
D16 = dpregs_expr[16]
D17 = dpregs_expr[17]
D18 = dpregs_expr[18]
D19 = dpregs_expr[19]
D20 = dpregs_expr[20]
D21 = dpregs_expr[21]
D22 = dpregs_expr[22]
D23 = dpregs_expr[23]
D24 = dpregs_expr[24]
D25 = dpregs_expr[25]
D26 = dpregs_expr[26]
D27 = dpregs_expr[27]
D28 = dpregs_expr[28]
D29 = dpregs_expr[29]
D30 = dpregs_expr[30]
D31 = dpregs_expr[31]
S0 = spregs_expr[0]
S1 = spregs_expr[1]
S2 = spregs_expr[2]
S3 = spregs_expr[3]
S4 = spregs_expr[4]
S5 = spregs_expr[5]
S6 = spregs_expr[6]
S7 = spregs_expr[7]
S8 = spregs_expr[8]
S9 = spregs_expr[9]
S10 = spregs_expr[10]
S11 = spregs_expr[11]
S12 = spregs_expr[12]
S13 = spregs_expr[13]
S14 = spregs_expr[14]
S15 = spregs_expr[15]
S16 = spregs_expr[16]
S17 = spregs_expr[17]
S18 = spregs_expr[18]
S19 = spregs_expr[19]
S20 = spregs_expr[20]
S21 = spregs_expr[21]
S22 = spregs_expr[22]
S23 = spregs_expr[23]
S24 = spregs_expr[24]
S25 = spregs_expr[25]
S26 = spregs_expr[26]
S27 = spregs_expr[27]
S28 = spregs_expr[28]
S29 = spregs_expr[29]
S30 = spregs_expr[30]
S31 = spregs_expr[31]
Q0 = qpregs_expr[0]
Q1 = qpregs_expr[1]
Q2 = qpregs_expr[2]
Q3 = qpregs_expr[3]
Q4 = qpregs_expr[4]
Q5 = qpregs_expr[5]
Q6 = qpregs_expr[6]
Q7 = qpregs_expr[7]
Q8 = qpregs_expr[8]
Q9 = qpregs_expr[9]
Q10 = qpregs_expr[10]
Q11 = qpregs_expr[11]
Q12 = qpregs_expr[12]
Q13 = qpregs_expr[13]
Q14 = qpregs_expr[14]
Q15 = qpregs_expr[15]
# GP
regs32_str = ["R%d" % i for i in range(13)] + ["SP", "LR", "PC"]

View file

@ -6,6 +6,7 @@ from miasm.expression.simplifications import expr_simp
from miasm.ir.ir import Lifter, IRBlock, AssignBlock
from miasm.arch.arm.arch import mn_arm, mn_armt
from miasm.arch.arm.regs import *
from miasm.arch.arm.arch import regs_expr
from miasm.jitter.csts import EXCEPT_DIV_BY_ZERO, EXCEPT_INT_XX
@ -1139,6 +1140,60 @@ def blx(ir, instr, a):
e.append(ExprAssign(LR, l))
return e, []
def vmov(ir, instr, a, b, c=None):
e = []
if c is None:
if a not in spregs_expr and b not in spregs_expr:
raise NotImplementedError('Not implemented')
e.append(ExprAssign(a, b))
else:
if a in dpregs_expr:
# two gp to one dp
# a[:32] = b
# a[32:] = c
e.append(ExprAssign(a, (c.zeroExtend(a.size) << ExprInt(32, 64) | b.zeroExtend(a.size))))
elif a in regs_expr:
# one dp to two gp
# a = c[:32]
# b = c[32:]
e.append(ExprAssign(a, c[:32]))
e.append(ExprAssign(b, c[32:]))
else:
raise NotImplementedError('Not implemented')
return e, []
def vstr(ir, instr, a, b):
e = []
if a in spregs_expr:
e.append(ExprAssign(b, a))
elif a in dpregs_expr:
if instr.mode == 'l':
e.append(ExprAssign(b, a[:32]))
e.append(ExprAssign(ExprMem(b.ptr + ExprInt(4, 32), 32), a[32:]))
else:
e.append(ExprAssign(b, a[32:]))
e.append(ExprAssign(ExprMem(b.ptr + ExprInt(4, 32), 32), a[:32]))
else:
raise NotImplementedError('Not implemented')
return e, []
# todo
def vcvt(ir, instr, a, b):
raise NotImplementedError('Not implemented')
# todo
def strex(ir, instr, a, b, c=None):
raise NotImplementedError('Not implemented')
# todo
def ldrex(ir, instr, a, b):
raise NotImplementedError('Not implemented')
def dmb(ir, instr, a):
"""Memory barrier"""
e = []
return e, []
def st_ld_r(ir, instr, a, a2, b, store=False, size=32, s_ext=False, z_ext=False):
e = []
@ -1930,6 +1985,8 @@ mnemo_condm0 = {'add': add,
'pkhtb': pkhtb,
'pkhbt': pkhbt,
'ldrex': ldrex,
'strex': strex,
}
mnemo_condm1 = {'adds': add,
@ -1959,6 +2016,10 @@ mnemo_condm1 = {'adds': add,
'ldrb': ldrb,
'ldsb': ldrsb,
'strb': strb,
'vmov': vmov,
'vstr': vstr,
'vcvt': vcvt
}
mnemo_condm2 = {'ldmia': ldmia,
@ -2014,6 +2075,7 @@ mnemo_nocond = {'lsr': lsr,
'smlatt': smlatt,
'uadd8': uadd8,
'sel': sel,
'dmb': dmb
}
mn_cond_x = [mnemo_condm0,

View file

@ -719,6 +719,48 @@ reg_tests_armt = [
"B5EB102F"),
("xxxxxxxx LDMIA R0, {R2, R3, R6, R7}",
"90E8CC00"),
("xxxxxxxx DMB SY",
"BFF35F8F"),
("xxxxxxxx STRB R3, [R4, R8]",
"04F80830"),
("xxxxxxxx STRB R2, [R3, R9]",
"03F80920"),
("xxxxxxxx LDREX R3, [R1]",
"51E8003F"),
("xxxxxxxx LDREX R2, [R12]",
"5CE8002F"),
("xxxxxxxx STREX LR, R1, [R3]",
"43E8001E"),
("xxxxxxxx STREX R0, LR, [R2]",
"42E800E0"),
("xxxxxxxx TEQ R0, R1",
"90EA010F"),
("xxxxxxxx ADD R0, SP, 0x714",
"0DF21470"),
("xxxxxxxx VMOV S0, R0",
"00EE100A"),
("xxxxxxxx VMOV R2, R3, D0",
"53EC102B"),
("xxxxxxxx VCVT D0, S0",
"B8EEC00B"),
("xxxxxxxx VMOV R2, R3, D0",
"53EC102B"),
("xxxxxxxx VMOV D0, R0, R1",
"41EC100B"),
("xxxxxxxx VCVT S0, D0",
"BDEEC00B"),
("xxxxxxxx VSTR S0, [SP, 0x30]",
"8DED0C0A"),
("xxxxxxxx VSTR D0, [SP, 0x90]",
"8DED240B"),
("xxxxxxxx ADD R7, SP, 0xC",
"03af"),
("xxxxxxxx LDR R5, [PC, 0xF80]",
"DFF8805F"),
("xxxxxxxx LDR R1, [PC, 0xFFFFF970]",
"5FF89016"),
]
print("#" * 40, 'armthumb', '#' * 40)

View file

@ -8,7 +8,7 @@ import logging
from future.utils import viewitems
from miasm.ir.symbexec import SymbolicExecutionEngine
from miasm.arch.arm.arch import mn_arm as mn
from miasm.arch.arm.arch import mn_arm, mn_armt
from miasm.arch.arm.sem import Lifter_Arml as Lifter
from miasm.arch.arm.regs import *
from miasm.expression.expression import *
@ -23,8 +23,14 @@ EXCLUDE_REGS = set([Lifter(loc_db).IRDst])
def M(addr):
return ExprMem(ExprInt(addr, 16), 16)
# compute for armt
def compute_t(asm, inputstate={}, debug=False):
return _compute(asm, mn_armt, inputstate, debug)
def compute(asm, inputstate={}, debug=False):
return _compute(asm, mn_arm, inputstate, debug)
def _compute(asm, mn, inputstate={}, debug=False):
loc_db = LocationDB()
sympool = dict(regs_init)
sympool.update({k: ExprInt(v, k.size) for k, v in viewitems(inputstate)})
@ -546,6 +552,18 @@ class TestARMSemantic(unittest.TestCase):
self.assertEqual(compute('SMLAL R2, R3, R4, R5', {R2: 0xffffffff, R3: 0x0, R4: 0x12345678, R5: 0x87654321}), {R2: 0x70b88d77, R3: 0xf76c768e, R4: 0x12345678, R5: 0x87654321})
self.assertEqual(compute('SMLAL R2, R3, R4, R5', {R2: 0xffffffff, R3: 0x00000002, R4: 0x12345678, R5: 0x87654321}), {R2: 0x70b88d77, R3: 0xf76c7690, R4: 0x12345678, R5: 0x87654321})
def test_vmov(self):
self.assertEqual(compute_t('VMOV S0, R0', {S0: 0x1, R0: 0x2}), {S0: 0x2, R0: 0x2})
self.assertEqual(compute_t('VMOV R0, S0', {S0: 0x1, R0: 0x2}), {S0: 0x1, R0: 0x1})
self.assertEqual(compute_t('VMOV D0, R0, R1', {D0: 0x1, R0: 0x2, R1:0x3}), {D0: 0x2 | (0x3 << 32), R0: 0x2, R1: 0x3})
self.assertEqual(compute_t('VMOV R0, R1, D0', {D0: 0xfffffffcfffffffe, R0: 0x2, R1:0x3}), {D0: 0xfffffffcfffffffe, R0: 0xfffffffe, R1: 0xfffffffc})
self.assertEqual(compute_t('VSTR S0, [SP, 0x30]',
{S0: 0x10000, SP: 0x20000, ExprMem(ExprOp('preinc', ExprInt(0x20000, 32), ExprInt(0x30, 32)), 32): 0x50}),
{S0: 0x10000, SP: 0x20000, ExprMem(ExprOp('preinc', ExprInt(0x20000, 32), ExprInt(0x30, 32)), 32): 0x10000})
self.assertEqual(compute_t('VSTR D0, [SP, 0x30]',
{D0: 0x1000000020000000, SP: 0x20000, ExprMem(ExprOp('preinc', ExprInt(0x20000, 32), ExprInt(0x30, 32)), 32): 0x50 , ExprMem(ExprOp('+', ExprOp('preinc', ExprInt(0x20000, 32), ExprInt(0x30, 32)), ExprInt(4, 32)), 32): 0x50}),
{D0: 0x1000000020000000, SP: 0x20000, ExprMem(ExprOp('preinc', ExprInt(0x20000, 32), ExprInt(0x30, 32)), 32): 0x20000000, ExprMem(ExprOp('+', ExprOp('preinc', ExprInt(0x20000, 32), ExprInt(0x30, 32)), ExprInt(4, 32)), 32): 0x10000000})
if __name__ == '__main__':
testsuite = unittest.TestLoader().loadTestsFromTestCase(TestARMSemantic)
report = unittest.TextTestRunner(verbosity=2).run(testsuite)