diff options
| author | Fabrice Desclaux <fabrice.desclaux@cea.fr> | 2019-02-25 09:27:13 +0100 |
|---|---|---|
| committer | Fabrice Desclaux <fabrice.desclaux@cea.fr> | 2019-03-07 21:06:33 +0100 |
| commit | ac08aad4efec127828988153b4b1ac618b9dbba9 (patch) | |
| tree | 1bff0297dcd0e66d650388c0a85ab07b96ed3ac3 | |
| parent | 4c2320b46250a8d6f8774e1218544b72a154cd8e (diff) | |
| download | miasm-ac08aad4efec127828988153b4b1ac618b9dbba9.tar.gz miasm-ac08aad4efec127828988153b4b1ac618b9dbba9.zip | |
pkhbt
| -rw-r--r-- | miasm/arch/arm/arch.py | 72 | ||||
| -rw-r--r-- | miasm/arch/arm/sem.py | 33 | ||||
| -rw-r--r-- | test/arch/arm/arch.py | 10 |
3 files changed, 115 insertions, 0 deletions
diff --git a/miasm/arch/arm/arch.py b/miasm/arch/arm/arch.py index 7668cf0a..497d6d68 100644 --- a/miasm/arch/arm/arch.py +++ b/miasm/arch/arm/arch.py @@ -181,6 +181,7 @@ all_binaryop_1_32_shifts_t = literal_list( all_unaryop_shifts_t = literal_list(['RRX']).setParseAction(op_shift2expr) ror_shifts_t = literal_list(['ROR']).setParseAction(op_shift2expr) +shl_shifts_t = literal_list(['SHL']).setParseAction(op_shift2expr) allshifts_t_armt = literal_list( @@ -215,6 +216,8 @@ rot2_expr = (gpregs.parser + Optional( )).setParseAction(cb_shift) +rot5_expr = shift_off + OP_LSL = Suppress("LSL") def cb_deref_reg_reg(tokens): @@ -1748,6 +1751,68 @@ class arm_rm_rot2(arm_arg): self.parent.rot2.value = value // 8 return True + + +class arm_rm_rot5_lsl(arm_arg): + parser = rot5_expr + index_op = 0 + def decode(self, v): + expr = gpregs.expr[v] + shift_value = self.parent.rot5.value + if shift_value: + expr = ExprOp(allshifts[self.index_op], expr, ExprInt(shift_value, 32)) + self.expr = expr + return True + def encode(self): + if self.expr in gpregs.expr: + self.value = gpregs.expr.index(self.expr) + self.parent.rot5.value = 0 + elif (isinstance(self.expr, ExprOp) and + self.expr.op == allshifts[self.index_op]): + reg, value = self.expr.args + if reg not in gpregs.expr: + return False + self.value = gpregs.expr.index(reg) + if not isinstance(value, ExprInt): + return False + value = int(value) + if not 0 <= value < 32: + return False + self.parent.rot5.value = value + return True + +class arm_rm_rot5_asr(arm_rm_rot5_lsl): + parser = rot5_expr + index_op = 2 + def decode(self, v): + expr = gpregs.expr[v] + shift_value = self.parent.rot5.value + if shift_value == 0: + expr = ExprOp(allshifts[self.index_op], expr, ExprInt(32, 32)) + else: + expr = ExprOp(allshifts[self.index_op], expr, ExprInt(shift_value, 32)) + self.expr = expr + return True + def encode(self): + if (isinstance(self.expr, ExprOp) and + self.expr.op == allshifts[self.index_op]): + reg, value = self.expr.args + if reg not in gpregs.expr: + return False + self.value = gpregs.expr.index(reg) + if not isinstance(value, ExprInt): + return False + value = int(value) + if not 0 < value <= 32: + return False + if value == 32: + value = 0 + self.parent.rot5.value = value + else: + return False + return True + + class arm_gpreg_nopc(reg_noarg): reg_info = gpregs_nopc parser = reg_info.parser @@ -1778,6 +1843,10 @@ class arm_gpreg_nosp(reg_noarg): rm_rot2 = bs(l=4, cls=(arm_rm_rot2,), fname="rm") rot2 = bs(l=2, fname="rot2") +rm_rot5_lsl = bs(l=4, cls=(arm_rm_rot5_lsl,), fname="rm") +rm_rot5_asr = bs(l=4, cls=(arm_rm_rot5_asr,), fname="rm") +rot5 = bs(l=5, fname="rot5") + widthm1 = bs(l=5, cls=(arm_widthm1, m_arg)) lsb = bs(l=5, cls=(arm_imm, m_arg)) @@ -1796,6 +1865,9 @@ armop("bfc", [bs('0111110'), widthm1, rd, lsb, bs('001'), bs('1111')], [rd, lsb, armop("uxtab", [bs('01101110'), rn_nopc, rd, rot2, bs('000111'), rm_rot2], [rd, rn_nopc, rm_rot2]) +armop("pkhbt", [bs('01101000'), rn, rd, rot5, bs('001'), rm_rot5_lsl], [rd, rn, rm_rot5_lsl]) +armop("pkhtb", [bs('01101000'), rn, rd, rot5, bs('101'), rm_rot5_asr], [rd, rn, rm_rot5_asr]) + # diff --git a/miasm/arch/arm/sem.py b/miasm/arch/arm/sem.py index bbffc05b..981a5060 100644 --- a/miasm/arch/arm/sem.py +++ b/miasm/arch/arm/sem.py @@ -1349,6 +1349,35 @@ def adr(ir, instr, arg1, arg2): e.append(ExprAssign(arg1, (PC & ExprInt(0xfffffffc, 32)) + arg2)) return e, [] + +def pkhbt(ir, instr, arg1, arg2, arg3): + e = [] + e.append( + ExprAssign( + arg1, + ExprCompose( + arg2[:16], + arg3[16:] + ) + ) + ) + return e, [] + + +def pkhtb(ir, instr, arg1, arg2, arg3): + e = [] + e.append( + ExprAssign( + arg1, + ExprCompose( + arg3[:16], + arg2[16:] + ) + ) + ) + return e, [] + + COND_EQ = 0 COND_NE = 1 COND_CS = 2 @@ -1526,6 +1555,10 @@ mnemo_condm0 = {'add': add, 'smultt': smul, 'smulwt': smulw, 'smulwb': smulw, + + 'pkhtb': pkhtb, + 'pkhbt': pkhbt, + } mnemo_condm1 = {'adds': add, diff --git a/test/arch/arm/arch.py b/test/arch/arm/arch.py index c8f2d433..5aa619ea 100644 --- a/test/arch/arm/arch.py +++ b/test/arch/arm/arch.py @@ -224,6 +224,16 @@ reg_tests_arm = [ '7854e2e6'), + ('XXXXXXXX PKHBT R1, R2, R3 LSL 0x8', + '131482e6'), + ('XXXXXXXX PKHBT R1, R2, R3', + '131082e6'), + ('XXXXXXXX PKHTB R1, R2, R3 ASR 0x8', + '531482e6'), + ('XXXXXXXX PKHTB R1, R2, R3 ASR 0x20', + '531082e6'), + + ] ts = time.time() |