diff options
Diffstat (limited to 'src/arch/arm/v7/arm.c')
-rw-r--r-- | src/arch/arm/v7/arm.c | 201 |
1 files changed, 197 insertions, 4 deletions
diff --git a/src/arch/arm/v7/arm.c b/src/arch/arm/v7/arm.c index b7d4ff1..fb1dc3f 100644 --- a/src/arch/arm/v7/arm.c +++ b/src/arch/arm/v7/arm.c @@ -39,6 +39,12 @@ static GArchInstruction *process_armv7_data_processing_and_miscellaneous_instruc /* Désassemble une instruction ARMv7 de données de registre. */ static GArchInstruction *process_armv7_data_processing_register(uint32_t); +/* Désassemble une instruction ARMv7 de données de immédiate. */ +static GArchInstruction *process_armv7_data_processing_immediate(uint32_t); + +/* Désassemble une instruction ARMv7 liées aux multiplications. */ +static GArchInstruction *process_armv7_multiply_and_multiply_accumulate(uint32_t); + /* Désassemble une instruction ARMv7 de données ou autre. */ static GArchInstruction *process_armv7_branch_branch_with_link_and_block_data_transfer(uint32_t); @@ -60,11 +66,11 @@ static GArchInstruction *process_armv7_branch_branch_with_link_and_block_data_tr #define process_armv7_extra_load_store_instructions(raw) NULL #define process_armv7_miscellaneous_instructions(raw) NULL #define process_armv7_halfword_multiply_and_multiply_accumulate(raw) NULL -#define process_armv7_multiply_and_multiply_accumulate(raw) NULL +//#define process_armv7_multiply_and_multiply_accumulate(raw) NULL #define process_armv7_synchronization_primitives(raw) NULL #define process_armv7_extra_load_store_instructions_unprivileged(raw) NULL #define process_armv7_extra_load_store_instructions(raw) NULL -#define process_armv7_data_processing_immediate(raw) NULL +//#define process_armv7_data_processing_immediate(raw) NULL #define armv7_read_instr_mov_immediate(raw) NULL #define armv7_read_instr_movt(raw) NULL #define process_armv7_msr_immediate_and_hints(raw) NULL @@ -76,7 +82,7 @@ static GArchInstruction *process_armv7_branch_branch_with_link_and_block_data_tr #define armv7_read_instr_eor_register(raw) NULL #define armv7_read_instr_sub_register(raw) NULL #define armv7_read_instr_rsb_register(raw) NULL -#define armv7_read_instr_add_register(raw) NULL +#define armv7_read_instr_add_register_arm(raw) NULL #define armv7_read_instr_adc_register(raw) NULL #define armv7_read_instr_sbc_register(raw) NULL #define armv7_read_instr_rsc_register(raw) NULL @@ -117,6 +123,16 @@ static GArchInstruction *process_armv7_branch_branch_with_link_and_block_data_tr +#define armv7_read_instr_adr(raw) NULL + + + +// ??? +#define armv7_read_instr_yield(raw) NULL +#define armv7_read_instr_bx(raw) NULL + + + /****************************************************************************** @@ -349,7 +365,7 @@ static GArchInstruction *process_armv7_data_processing_register(uint32_t raw) result = armv7_read_instr_rsb_register(raw); else if ((op & b11110) == b01000) - result = armv7_read_instr_add_register(raw); + result = armv7_read_instr_add_register_arm(raw); else if ((op & b11110) == b01010) result = armv7_read_instr_adc_register(raw); @@ -427,6 +443,183 @@ static GArchInstruction *process_armv7_data_processing_register(uint32_t raw) +/****************************************************************************** +* * +* Paramètres : raw = donnée brute de 32 bits à désassembler. * +* * +* Description : Désassemble une instruction ARMv7 de données de immédiate. * +* * +* Retour : Instruction mise en place ou NULL en cas d'échec. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static GArchInstruction *process_armv7_data_processing_immediate(uint32_t raw) +{ + GArchInstruction *result; /* Instruction à retourner */ + uint32_t op; /* Champ 'op' à retrouver */ + uint32_t rn; /* Champ 'rn' à retrouver */ + + /** + * Suit les directives de : + * § A5.2.3 Data-processing (immediate) + */ + + result = NULL; + + op = (raw >> 20) & 0x1f; + rn = (raw >> 16) & 0xf; + + if ((op & b11110) == b00000) + result = armv7_read_instr_and_immediate(raw); + + else if ((op & b11110) == b00010) + result = armv7_read_instr_eor_immediate(raw); + + else if ((op & b11110) == b00100) + { + if (rn == b1111) + result = armv7_read_instr_adr(raw); + + else + result = armv7_read_instr_sub_immediate_arm(raw); + + } + + else if ((op & b11110) == b00110) + result = armv7_read_instr_rsb_immediate(raw); + + else if ((op & b11110) == b01000) + { + if (rn == b1111) + result = armv7_read_instr_adr(raw); + + else + result = armv7_read_instr_add_immediate_arm(raw); + + } + + else if ((op & b11110) == b01010) + result = armv7_read_instr_adc_immediate(raw); + + else if ((op & b11110) == b01100) + result = armv7_read_instr_sbc_immediate(raw); + + else if ((op & b11110) == b01110) + result = armv7_read_instr_rsc_immediate(raw); + + /* + else if ((op & b11110) == b10000) + result = process_armv7_data_processing_and_miscellaneous_instructions(raw); + */ + + else if (op == b10001) + result = armv7_read_instr_tst_immediate(raw); + + else if (op == b10011) + result = armv7_read_instr_teq_immediate(raw); + + else if (op == b10101) + result = armv7_read_instr_cmp_immediate(raw); + + else if (op == b10111) + result = armv7_read_instr_cmn_immediate(raw); + + else if ((op & b11110) == b11000) + result = armv7_read_instr_orr_immediate(raw); + + else if ((op & b11110) == b11010) + result = armv7_read_instr_mov_immediate(raw); + + else if ((op & b11110) == b11100) + result = armv7_read_instr_bic_immediate(raw); + + else if ((op & b11110) == b11110) + result = armv7_read_instr_mvn_immediate(raw); + + return result; + +} + + + + + + + + + + + + +/****************************************************************************** +* * +* Paramètres : raw = donnée brute de 32 bits à désassembler. * +* * +* Description : Désassemble une instruction ARMv7 liées aux multiplications. * +* * +* Retour : Instruction mise en place ou NULL en cas d'échec. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static GArchInstruction *process_armv7_multiply_and_multiply_accumulate(uint32_t raw) +{ + GArchInstruction *result; /* Instruction à retourner */ + uint32_t op; /* Champ 'op' à retrouver */ + + /** + * Suit les directives de : + * § A5.2.5 Multiply and multiply accumulate + */ + + result = NULL; + + if ((raw & 0x0f0000f0) == 0x00000090) + return NULL; + + op = (raw >> 20) & 0x1f; + + if ((op & b1110) == b0000) + result = armv7_read_instr_mul(raw); + + else if ((op & b1110) == b0010) + result = armv7_read_instr_mla(raw); + + else if (op == b0100) + result = armv7_read_instr_umaal(raw); + + else if (op == b0101) + result = NULL; /* Non défini */ + + else if (op == b0110) + result = armv7_read_instr_mls(raw); + + else if (op == b0111) + result = NULL; /* Non défini */ + + else if ((op & b1110) == b1000) + result = armv7_read_instr_umull(raw); + + else if ((op & b1110) == b1010) + result = armv7_read_instr_umlal(raw); + + else if ((op & b1110) == b1100) + result = armv7_read_instr_smull(raw); + + else if ((op & b1110) == b1110) + result = armv7_read_instr_smlal(raw); + + return result; + +} + + + + + |