mirror of
https://github.com/radareorg/radare2.git
synced 2025-01-24 06:48:46 +00:00
* Apply two patches from flux (thanks!)
- Implement barrel shifter for the ARM assembler - fix type of bitwide ops (and, eor, ...)
This commit is contained in:
parent
0c5a3834f4
commit
b909e43976
@ -3,6 +3,7 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <r_util.h>
|
||||
|
||||
// TODO: only lo registers accessible in thumb arm
|
||||
|
||||
@ -74,12 +75,12 @@ static ArmOp ops[] = {
|
||||
{ "mvn", 0, TYPE_MOV },
|
||||
{ "svc", 0xf, TYPE_SWI }, // ???
|
||||
|
||||
{ "and", 0x0, TYPE_TST },
|
||||
{ "ands", 0x1000, TYPE_TST },
|
||||
{ "eor", 0x2000, TYPE_TST },
|
||||
{ "eors", 0x3000, TYPE_TST },
|
||||
{ "orr", 0x0, TYPE_TST },
|
||||
{ "bic", 0x0, TYPE_TST },
|
||||
{ "and", 0x0000, TYPE_ARI },
|
||||
{ "ands", 0x1000, TYPE_ARI },
|
||||
{ "eor", 0x2000, TYPE_ARI },
|
||||
{ "eors", 0x3000, TYPE_ARI },
|
||||
{ "orr", 0x0, TYPE_ARI },
|
||||
{ "bic", 0x0, TYPE_ARI },
|
||||
|
||||
{ "cmp", 0x4001, TYPE_TST },
|
||||
{ "cmn", 0x0, TYPE_TST },
|
||||
@ -148,11 +149,61 @@ static int getlist(char *op) {
|
||||
return list;
|
||||
}
|
||||
|
||||
static int getshift(const char *str) {
|
||||
if (!str) return 0;
|
||||
while (str && *str && !atoi (str))
|
||||
str++;
|
||||
return atoi (str)>>1;
|
||||
static ut32 getshift(const char *str) {
|
||||
char type[128];
|
||||
char arg[128];
|
||||
char *space;
|
||||
ut32 i=0, shift=0;
|
||||
const char *shifts[] = {
|
||||
"LSL", "LSR", "ASR", "ROR",
|
||||
0,
|
||||
"RRX" // alias for ROR #0
|
||||
};
|
||||
|
||||
strncpy (type, str, sizeof(type)-1);
|
||||
|
||||
// handle RRX alias case
|
||||
if (!strcasecmp (type, shifts[5])) {
|
||||
shift = 6;
|
||||
}
|
||||
// all other shift types
|
||||
else {
|
||||
// split the string into type and arg
|
||||
space = strchr(type, ' ');
|
||||
if (!space)
|
||||
return 0;
|
||||
*space = 0;
|
||||
strncpy (arg, ++space, sizeof(arg)-1);
|
||||
|
||||
for (i=0; shifts[i]; i++) {
|
||||
if (!strcasecmp (type, shifts[i])) {
|
||||
shift = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!shift)
|
||||
return 0;
|
||||
shift = (i*2);
|
||||
|
||||
if ((i = getreg(arg)) != -1) {
|
||||
shift |= 1;
|
||||
i = i<<4;
|
||||
}
|
||||
else {
|
||||
i = getnum (arg);
|
||||
// ensure only the bottom 5 bits are used
|
||||
i &= 0x1f;
|
||||
if (!i)
|
||||
i = 32;
|
||||
i = (i*8);
|
||||
}
|
||||
}
|
||||
|
||||
i += shift;
|
||||
i = i << 4;
|
||||
r_mem_copyendian(&shift, &i, sizeof(ut32), 0);
|
||||
|
||||
return shift;
|
||||
}
|
||||
|
||||
static void arm_opcode_parse(ArmOpcode *ao, const char *str) {
|
||||
@ -493,6 +544,8 @@ static int arm_assemble(ArmOpcode *ao, const char *str) {
|
||||
ao->o |= getreg (ao->a[1])<<8;
|
||||
ret = getreg (ao->a[2]);
|
||||
ao->o |= (ret!=-1)? ret<<24 : 2 | getnum(ao->a[2])<<24;
|
||||
if (ao->a[3])
|
||||
ao->o |= getshift (ao->a[3]);
|
||||
break;
|
||||
case TYPE_MOV:
|
||||
ao->o |= getreg (ao->a[0])<<20;
|
||||
@ -504,7 +557,8 @@ static int arm_assemble(ArmOpcode *ao, const char *str) {
|
||||
//ao->o |= getreg(ao->a[0])<<20; // ???
|
||||
ao->o |= getreg (ao->a[0])<<8;
|
||||
ao->o |= getreg (ao->a[1])<<24;
|
||||
ao->o |= getshift (ao->a[2])<<16; // shift
|
||||
if (ao->a[2])
|
||||
ao->o |= getshift (ao->a[2]);
|
||||
break;
|
||||
}
|
||||
return 1;
|
||||
|
Loading…
x
Reference in New Issue
Block a user