about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorFabrice Desclaux <fabrice.desclaux@cea.fr>2019-02-25 09:27:13 +0100
committerFabrice Desclaux <fabrice.desclaux@cea.fr>2019-03-07 21:06:33 +0100
commitac08aad4efec127828988153b4b1ac618b9dbba9 (patch)
tree1bff0297dcd0e66d650388c0a85ab07b96ed3ac3
parent4c2320b46250a8d6f8774e1218544b72a154cd8e (diff)
downloadmiasm-ac08aad4efec127828988153b4b1ac618b9dbba9.tar.gz
miasm-ac08aad4efec127828988153b4b1ac618b9dbba9.zip
pkhbt
-rw-r--r--miasm/arch/arm/arch.py72
-rw-r--r--miasm/arch/arm/sem.py33
-rw-r--r--test/arch/arm/arch.py10
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()