From 221bad879459752fdb365a68acf98788b530e06a Mon Sep 17 00:00:00 2001 From: Pierre Pronchery Date: Tue, 14 Jun 2011 22:25:24 +0000 Subject: [PATCH] Improving ARM support --- src/arch/arm.h | 75 ++++++++++++++++++++++++++++++++++++++++++++++---- test/arm.S | 12 ++++---- 2 files changed, 76 insertions(+), 11 deletions(-) diff --git a/src/arch/arm.h b/src/arch/arm.h index 4ae5a4d..cca51ed 100644 --- a/src/arch/arm.h +++ b/src/arch/arm.h @@ -37,9 +37,8 @@ static int _arm_write(ArchPlugin * plugin, ArchInstruction * instruction, ArchRegister * ar; char const * p; - switch(instruction->opcode & 0x0fffffff) + switch(instruction->opcode & 0x0fffffff) /* ignore condition code */ { -#if 1 /* FIXME implement */ case and: case eor: case sub: @@ -48,12 +47,77 @@ static int _arm_write(ArchPlugin * plugin, ArchInstruction * instruction, case adc: case sbc: case rsc: + case orr: + case bic: + case and | (0x1 << 20): /* ands */ + case eor | (0x1 << 20): /* eors */ + case sub | (0x1 << 20): /* subs */ + case rsb | (0x1 << 20): /* rsbs */ + case add | (0x1 << 20): /* adds */ + case adc | (0x1 << 20): /* adcs */ + case sbc | (0x1 << 20): /* sbcs */ + case rsc | (0x1 << 20): /* rscs */ + case orr | (0x1 << 20): /* orrs */ + case bic | (0x1 << 20): /* bics */ + /* first operand, Rd */ + p = call->operands[0].value._register.name; + if((ar = helper->get_register_by_name_size(helper->arch, + p, 32)) == NULL) + return -1; + opcode |= (ar->id << 12); + /* second operand, Rn */ + p = call->operands[1].value._register.name; + if((ar = helper->get_register_by_name_size(helper->arch, + p, 32)) == NULL) + return -1; + opcode |= (ar->id << 16); + /* third operand, Rm */ + p = call->operands[2].value._register.name; + if((ar = helper->get_register_by_name_size(helper->arch, + p, 32)) == NULL) + return -1; + opcode |= ar->id; + break; + case and | (0x1 << 25): + case eor | (0x1 << 25): + case sub | (0x1 << 25): + case rsb | (0x1 << 25): + case add | (0x1 << 25): + case adc | (0x1 << 25): + case sbc | (0x1 << 25): + case rsc | (0x1 << 25): + case orr | (0x1 << 25): + case bic | (0x1 << 25): + case and | (0x1 << 20) | (0x1 << 25): + case eor | (0x1 << 20) | (0x1 << 25): + case sub | (0x1 << 20) | (0x1 << 25): + case rsb | (0x1 << 20) | (0x1 << 25): + case add | (0x1 << 20) | (0x1 << 25): + case adc | (0x1 << 20) | (0x1 << 25): + case sbc | (0x1 << 20) | (0x1 << 25): + case rsc | (0x1 << 20) | (0x1 << 25): + case orr | (0x1 << 20) | (0x1 << 25): + case bic | (0x1 << 20) | (0x1 << 25): + /* first operand, Rd */ + p = call->operands[0].value._register.name; + if((ar = helper->get_register_by_name_size(helper->arch, + p, 32)) == NULL) + return -1; + opcode |= (ar->id << 12); + /* second operand, Rn */ + p = call->operands[1].value._register.name; + if((ar = helper->get_register_by_name_size(helper->arch, + p, 32)) == NULL) + return -1; + opcode |= (ar->id << 16); + /* third operand */ + opcode |= call->operands[2].value.immediate.value; + break; +#if 1 /* FIXME implement */ case tst: case teq: case cmp: case cmn: - case orr: - case bic: break; #endif case mov: @@ -87,7 +151,8 @@ static int _arm_write(ArchPlugin * plugin, ArchInstruction * instruction, p, 32)) == NULL) return -1; opcode |= (ar->id << 12); - /* FIXME immediate value */ + /* second operand */ + opcode |= call->operands[1].value.immediate.value; break; #if 1 /* FIXME really implement */ default: diff --git a/test/arm.S b/test/arm.S index 50ab4f5..21fb409 100644 --- a/test/arm.S +++ b/test/arm.S @@ -2,8 +2,8 @@ .text adc %r3, %r4, %r5 adceq %r3, %r4, %r5 - adc %r3, %r4, $0x0 - adceq %r3, %r4, $0x1 + adc %r4, %r5, $0x0 + adceq %r4, %r5, $0x1 adcs %r3, %r4, %r5 adceqs %r3, %r4, %r5 adcs %r3, %r4, $0x0 @@ -76,8 +76,8 @@ moveq %r7, $0x2 movs %r8, %r4 moveqs %r9, %r5 - movs %r10, $0x1 - moveqs %r11, $0x2 + movs %r10, $0x3 + moveqs %r11, $0x4 mrc %r0, %r0, %r0 mrceq %r0, %r0, %r0 mrs %r0, %cpsr @@ -96,8 +96,8 @@ mvneq %r5, $0x2 mvns %r5, %r4 mvneqs %r5, %r4 - mvns %r5, $0x1 - mvneqs %r5, $0x2 + mvns %r5, $0x3 + mvneqs %r5, $0x4 nop orr %r3, %r4, %r5 orreq %r3, %r4, %r5