FreeCalypso > hg > freecalypso-reveng
changeset 91:daf69d5edb3f
armdis: ldr/str decoding implemented (but not PC-relative ldr yet)
author | Michael Spacefalcon <msokolov@ivan.Harhan.ORG> |
---|---|
date | Sun, 30 Mar 2014 00:27:25 +0000 |
parents | f68d8e7a904f |
children | 708f2452d1ae |
files | arm7dis/armdis.c |
diffstat | 1 files changed, 86 insertions(+), 7 deletions(-) [+] |
line wrap: on
line diff
--- a/arm7dis/armdis.c Sat Mar 29 22:19:21 2014 +0000 +++ b/arm7dis/armdis.c Sun Mar 30 00:27:25 2014 +0000 @@ -58,23 +58,23 @@ if (!c) { switch (t) { case 0: - printf("%s\n", regnames[word&0xF]); + printf("%s", regnames[word&0xF]); return; case 3: - printf("%s, rrx\n", regnames[word&0xF]); + printf("%s, rrx", regnames[word&0xF]); return; default: c = 32; } } - printf("%s, %s #%u\n", regnames[word&0xF], shift_types[t], c); + printf("%s, %s #%u", regnames[word&0xF], shift_types[t], c); } static void op2_regbyreg(word) unsigned word; { - printf("%s, %s %s\n", regnames[word&0xF], shift_types[(word>>5)&3], + printf("%s, %s %s", regnames[word&0xF], shift_types[(word>>5)&3], regnames[(word>>8)&0xF]); } @@ -86,6 +86,7 @@ op2_regbyreg(word); else op2_regbyconst(word); + putchar('\n'); } static void @@ -209,6 +210,80 @@ } static void +ldr_str_imm_pre(off, word) + unsigned off, word; +{ + unsigned loff = word & 0xFFF; + + /* check for literal pool fetches will go here */ + printf("%s%s%s\t%s, [%s", word&0x100000 ? "ldr" : "str", + condition_decode[word>>28], word&0x400000 ? "b" : "", + regnames[(word>>12)&0xF], regnames[(word>>16)&0xF]); + if (loff || word&0x200000) + printf(", #%s%u", word&0x800000 ? "" : "-", loff); + putchar(']'); + if (word & 0x200000) + putchar('!'); + if (loff >= 10) + printf("\t; 0x%x", loff); + putchar('\n'); +} + +static void +ldr_str_imm_post(word) + unsigned word; +{ + unsigned loff = word & 0xFFF; + + printf("%s%s%s%s\t%s, [%s], #%s%u", word&0x100000 ? "ldr" : "str", + condition_decode[word>>28], word&0x400000 ? "b" : "", + word&0x200000 ? "t" : "", + regnames[(word>>12)&0xF], regnames[(word>>16)&0xF], + word&0x800000 ? "" : "-", loff); + if (loff >= 10) + printf("\t; 0x%x", loff); + putchar('\n'); +} + +static void +ldr_str_reg_pre(word) + unsigned word; +{ + if (word & 0x10) { + printf("<invalid ldr/str: offset reg shift by reg>\n"); + return; + } + printf("%s%s%s\t%s, [%s, ", word&0x100000 ? "ldr" : "str", + condition_decode[word>>28], word&0x400000 ? "b" : "", + regnames[(word>>12)&0xF], regnames[(word>>16)&0xF]); + if (!(word & 0x800000)) + putchar('-'); + op2_regbyconst(word); + putchar(']'); + if (word & 0x200000) + putchar('!'); + putchar('\n'); +} + +static void +ldr_str_reg_post(word) + unsigned word; +{ + if (word & 0x10) { + printf("<invalid ldr/str: offset reg shift by reg>\n"); + return; + } + printf("%s%s%s%s\t%s, [%s], ", word&0x100000 ? "ldr" : "str", + condition_decode[word>>28], word&0x400000 ? "b" : "", + word&0x200000 ? "t" : "", + regnames[(word>>12)&0xF], regnames[(word>>16)&0xF]); + if (!(word & 0x800000)) + putchar('-'); + op2_regbyconst(word); + putchar('\n'); +} + +static void ldr_str_ext(off, word) unsigned off, word; { @@ -234,7 +309,7 @@ word = get_u32(filemap + off); printf("%8x:\t%08x\t", base_vma + off, word); if ((word >> 28) == 0xF) { - printf("invalid-F\n"); + printf("<invalid-F>\n"); return; } switch ((word >> 24) & 0xF) { @@ -250,12 +325,16 @@ dataproc(word); return; case 4: + ldr_str_imm_post(word); + return; case 5: - printf("<ldr/str, immediate offset>\n"); + ldr_str_imm_pre(off, word); return; case 6: + ldr_str_reg_post(word); + return; case 7: - printf("<ldr/str, register offset>\n"); + ldr_str_reg_pre(word); return; case 8: case 9: