summaryrefslogtreecommitdiff
path: root/src/arch/arm
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2016-05-25 21:19:42 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2016-05-25 21:19:42 (GMT)
commit1b524ce0e645e451ca76723f4f86fe2a71c1adf2 (patch)
tree8d818f5ea77ad27fd6bbb261acdd0a968f7ec599 /src/arch/arm
parent0e2849345be5018152d60b5aa27eebb2de75e1df (diff)
Fixed various mistakes in the decoding of ARM instructions.
Diffstat (limited to 'src/arch/arm')
-rw-r--r--src/arch/arm/v7/arm.c144
-rw-r--r--src/arch/arm/v7/opcodes/opcodes_tmp_arm.h2
-rw-r--r--src/arch/arm/v7/pseudo.c6
3 files changed, 51 insertions, 101 deletions
diff --git a/src/arch/arm/v7/arm.c b/src/arch/arm/v7/arm.c
index af92096..9a29939 100644
--- a/src/arch/arm/v7/arm.c
+++ b/src/arch/arm/v7/arm.c
@@ -531,7 +531,7 @@ static GArchInstruction *process_armv7_arm_data_processing_immediate(uint32_t ra
* § A5.2.3 Data-processing (immediate)
*/
- if ((raw & 0x0e000000) != 0x04000000) return NULL;
+ if ((raw & 0x0e000000) != 0x02000000) return NULL;
result = NULL;
@@ -1101,7 +1101,7 @@ static GArchInstruction *process_armv7_arm_miscellaneous_instructions(uint32_t r
* § A5.2.12 Miscellaneous instructions
*/
- if ((raw & 0x0f900080) != 0x00100000) return NULL;
+ if ((raw & 0x0f900080) != 0x01000000) return NULL;
result = NULL;
@@ -1229,126 +1229,74 @@ static GArchInstruction *process_armv7_arm_load_store_word_and_unsigned_byte(uin
rn = (raw >> 16) & 0xf;
b = (raw >> 4) & 0x1;
- if ((op1 & b10111) == b00010)
+ if (a == b0)
{
- if (a == b0)
- {
- result = armv7_read_arm_instr_strt(raw);
- goto a53_done;
- }
- else if (/*a == b1 && */b == b0)
- goto a53_done;
- }
- else if ((op1 & b00101) == b00000)
- {
- if (a == b0)
- {
+ if ((op1 & b00101) == b00000 && (op1 & b10111) != b00010)
result = armv7_read_arm_instr_str_immediate_arm(raw);
- goto a53_done;
- }
- else if (/*a == b1 && */b == b0)
- {
- result = armv7_read_arm_instr_str_register(raw);
- goto a53_done;
- }
- }
- if ((op1 & b10111) == b00011)
- {
- if (a == b0)
- {
- result = armv7_read_arm_instr_ldrt(raw);
- goto a53_done;
- }
- else if (/*a == b1 && */b == b0)
- goto a53_done;
- }
- else if ((op1 & b00101) == b00001)
- {
- if (a == b0)
+ else if ((op1 & b10111) == b00010)
+ result = armv7_read_arm_instr_strt(raw);
+
+ else if ((op1 & b00101) == b00001 && (op1 & b10111) != b00011)
{
- if (rn == b1111)
- result = armv7_read_arm_instr_ldr_literal(raw);
- else
+ if (rn != b1111)
result = armv7_read_arm_instr_ldr_immediate_arm(raw);
+ else
+ result = armv7_read_arm_instr_ldr_literal(raw);
+ }
- goto a53_done;
+ else if ((op1 & b10111) == b00011)
+ result = armv7_read_arm_instr_ldrt(raw);
- }
- else if (/*a == b1 && */b == b0)
- {
- result = armv7_read_arm_instr_ldr_register(raw);
- goto a53_done;
- }
- }
+ else if ((op1 & b00101) == b00100 && (op1 & b10110) != b00110)
+ result = armv7_read_arm_instr_strb_immediate_arm(raw);
- if ((op1 & b10111) == b00110)
- {
- if (a == b0)
- {
+ else if ((op1 & b10110) == b00110)
result = armv7_read_arm_instr_strbt(raw);
- goto a53_done;
- }
- else if (/*a == b1 && */b == b0)
- goto a53_done;
- }
- else if ((op1 & b00101) == b00100)
- {
- if (a == b0)
- {
- result = armv7_read_arm_instr_strb_immediate_arm(raw);
- goto a53_done;
- }
- else if (/*a == b1 && */b == b0)
- {
- result = armv7_read_arm_instr_strb_register(raw);
- goto a53_done;
- }
- }
- if ((op1 & b10111) == b00111)
- {
- if (a == b0)
+ else if ((op1 & b00101) == b00101 && (op1 & b10111) != b00111)
{
- result = armv7_read_arm_instr_ldrbt(raw);
- goto a53_done;
- }
- else if (/*a == b1 && */b == b0)
- goto a53_done;
- }
- else if ((op1 & b00101) == b00101)
- {
- if (a == b0)
- {
- if (rn == b1111)
- result = armv7_read_arm_instr_ldrb_literal(raw);
- else
+ if (rn != b1111)
result = armv7_read_arm_instr_ldrb_immediate_arm(raw);
-
- goto a53_done;
-
- }
- else if (/*a == b1 && */b == b0)
- {
- result = armv7_read_arm_instr_ldrb_register(raw);
- goto a53_done;
+ else
+ result = armv7_read_arm_instr_ldrb_literal(raw);
}
- }
- a53_done:
+ else if ((op1 & b10111) == b00111)
+ result = armv7_read_arm_instr_ldrbt(raw);
- return result;
+ }
+ else /*if (a == b1)*/
+ {
+ if ((op1 & b00101) == b00000 && (op1 & b10111) != b00010 && b == b0)
+ result = armv7_read_arm_instr_str_register(raw);
-}
+ else if ((op1 & b10111) == b00010 && b == b0)
+ result = armv7_read_arm_instr_strt(raw);
+ else if ((op1 & b00101) == b00001 && (op1 & b10111) != b00011 && b == b0)
+ result = armv7_read_arm_instr_ldr_register_arm(raw);
+ else if ((op1 & b10111) == b00011 && b == b0)
+ result = armv7_read_arm_instr_ldrt(raw);
+ else if ((op1 & b00101) == b00100 && (op1 & b10110) != b00110 && b == b0)
+ result = armv7_read_arm_instr_strb_register(raw);
+ else if ((op1 & b10110) == b00110 && b == b0)
+ result = armv7_read_arm_instr_strbt(raw);
+ else if ((op1 & b00101) == b00101 && (op1 & b10111) != b00111 && b == b0)
+ result = armv7_read_arm_instr_ldrb_register(raw);
+ else if ((op1 & b10111) == b00111 && b == b0)
+ result = armv7_read_arm_instr_ldrbt(raw);
+ }
+ return result;
+}
/******************************************************************************
@@ -2291,7 +2239,7 @@ static GArchInstruction *process_armv7_arm_memory_hints_advanced_simd_instructio
result = armv7_read_arm_instr_dsb(raw);
else if (op2 == b0101)
- result = armv7_read_arm_instr_dmd(raw);
+ result = armv7_read_arm_instr_dmb(raw);
else if (op2 == b0110)
result = armv7_read_arm_instr_isb(raw);
diff --git a/src/arch/arm/v7/opcodes/opcodes_tmp_arm.h b/src/arch/arm/v7/opcodes/opcodes_tmp_arm.h
index ec8372a..dcfd635 100644
--- a/src/arch/arm/v7/opcodes/opcodes_tmp_arm.h
+++ b/src/arch/arm/v7/opcodes/opcodes_tmp_arm.h
@@ -1,7 +1,6 @@
#ifndef arm_def_tmp_h
#define arm_def_tmp_h
#define armv7_read_arm_instr_cps_arm(r) NULL
-#define armv7_read_arm_instr_dmd(r) NULL
#define armv7_read_arm_instr_eret(r) NULL
#define armv7_read_arm_instr_hvc(r) NULL
#define armv7_read_arm_instr_isb(r) NULL
@@ -13,7 +12,6 @@
#define armv7_read_arm_instr_ldmib_ldmed(r) NULL
#define armv7_read_arm_instr_ldm_ldmia_ldmfd_arm(r) NULL
#define armv7_read_arm_instr_ldm_user_registers(r) NULL
-#define armv7_read_arm_instr_ldr_register(r) NULL
#define armv7_read_arm_instr_mrs(r) NULL
#define armv7_read_arm_instr_mrs_banked_register(r) NULL
#define armv7_read_arm_instr_msr_banked_register(r) NULL
diff --git a/src/arch/arm/v7/pseudo.c b/src/arch/arm/v7/pseudo.c
index 03644e2..6f2451b 100644
--- a/src/arch/arm/v7/pseudo.c
+++ b/src/arch/arm/v7/pseudo.c
@@ -601,7 +601,11 @@ bool armv7_shift_c(uint32_t x, unsigned int n, SRType type, unsigned int amount,
if (type == SRType_RRX && amount != 1) return false;
- if (amount == 0) return true;
+ if (amount == 0)
+ {
+ *value = 0;
+ return true;
+ }
result = true; /* Pour GCC... */