From 7c145226d22357b91fd4f80e7fc0c5dcf070a6d1 Mon Sep 17 00:00:00 2001 From: Sascha Schirra Date: Sun, 2 Aug 2015 15:38:35 -0700 Subject: [PATCH] Bugfix: movw/movt instructions are assembled to mov instruction --- libr/asm/arch/arm/armass.c | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/libr/asm/arch/arm/armass.c b/libr/asm/arch/arm/armass.c index c6bed17c66..d672da705b 100644 --- a/libr/asm/arch/arm/armass.c +++ b/libr/asm/arch/arm/armass.c @@ -34,6 +34,8 @@ enum { TYPE_MEM = 9, TYPE_BKP = 10, TYPE_SWP = 11, + TYPE_MOVW = 12, + TYPE_MOVT = 13, }; static int strcmpnull(const char *a, const char *b) { @@ -82,6 +84,8 @@ static ArmOp ops[] = { //{ "mov", 0x3, TYPE_MOV }, //{ "mov", 0x0a3, TYPE_MOV }, + { "movw", 0x3, TYPE_MOVW }, + { "movt", 0x4003, TYPE_MOVT }, { "mov", 0xa001, TYPE_MOV }, { "mvn", 0xe000, TYPE_MOV }, { "svc", 0xf, TYPE_SWI }, // ??? @@ -379,7 +383,7 @@ static int thumb_assemble(ArmOpcode *ao, const char *str) { eprintf("branch out of range or not even\n"); return 0; } - ut16 opcode = 0xe000 | ((delta / 2) & 0x7ff); //11bit offset>>1 + ut16 opcode = 0xe000 | ((delta / 2) & 0x7ff); //11bit offset>>1 ao->o = opcode >>8; ao->o |= (opcode & 0xff)<<8; // (ut32) ao->o holds the opcode in little-endian format !? return 2; @@ -785,6 +789,22 @@ static int arm_assemble(ArmOpcode *ao, const char *str) { if (ret!=-1) ao->o |= ret<<24; else ao->o |= 0xa003 | getnum (ao->a[1])<<24; break; + case TYPE_MOVW: + ao->o |= getreg (ao->a[0])<<20; + ret = getnum (ao->a[1]); + + ao->o |= 0x3 | ret << 24; + ao->o |= (ret & 0xf000) >> 4; + ao->o |= (ret & 0xf00) << 8; + break; + case TYPE_MOVT: + ao->o |= getreg (ao->a[0])<<20; + ret = getnum (ao->a[1]); + + ao->o |= 0x4003 | ret << 24; + ao->o |= (ret & 0xf000) >> 4; + ao->o |= (ret & 0xf00) << 8; + break; case TYPE_TST: a = getreg (ao->a[0]); b = getreg (ao->a[1]);