diff --git a/src/arch/arm.h b/src/arch/arm.h index eb52b05..e4b2281 100644 --- a/src/arch/arm.h +++ b/src/arch/arm.h @@ -39,6 +39,11 @@ static int _arm_write(ArchPlugin * plugin, ArchInstruction * instruction, switch(instruction->opcode & 0x0fffffff) /* ignore condition code */ { + /* branch, branch with link */ + case OPB(0): + case OPBL(0): + opcode |= call->operands[0].value.immediate.value; + break; /* branch and exchange */ case OPBX(0): /* first operand, Rn */ @@ -195,6 +200,23 @@ static int _arm_write(ArchPlugin * plugin, ArchInstruction * instruction, /* second operand */ opcode |= call->operands[1].value.immediate.value; break; + /* psr transfer */ + case OPPT(0): + /* 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); + break; + case OPPTI(0): + /* second operand, Rm */ + 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; + break; #if 1 /* FIXME really implement */ default: break; diff --git a/test/arm.S b/test/arm.S index b5e3aba..aa85556 100644 --- a/test/arm.S +++ b/test/arm.S @@ -81,13 +81,13 @@ mrc %r0, %r0, %r0 mrceq %r0, %r0, %r0 mrs %r0, %cpsr - mrseq %r0, %cpsr - mrs %r0, %spsr - mrseq %r0, %spsr - msr %cpsr, %r0 - msreq %cpsr, %r1 - msr %spsr, %r0 - msreq %spsr, %r1 + mrseq %r1, %cpsr + mrs %r2, %spsr + mrseq %r3, %spsr + msr %cpsr, %r4 + msreq %cpsr, %r5 + msr %spsr, %r6 + msreq %spsr, %r7 mul %r0, %r1, %r2 muls %r0, %r1, %r2 mvn %r5, %r4