diff options
-rw-r--r-- | cgthumb2was.c | 44 |
1 files changed, 44 insertions, 0 deletions
diff --git a/cgthumb2was.c b/cgthumb2was.c index dade5a1..e03afe5 100644 --- a/cgthumb2was.c +++ b/cgthumb2was.c @@ -1181,8 +1181,52 @@ static void w_as_lea_instruction (struct instruction *instruction) internal_error_in_function ("w_as_lea_instruction"); } +int dyadic_instruction_allowed (struct instruction *instruction,char *opcode) +{ + if (strcmp("sp", register_name[instruction->instruction_parameters[1].parameter_data.reg.r+7])) + return 1; + if (!strcmp("mov", opcode) || + !strcmp("add", opcode) || + !strcmp("addw", opcode) || + !strcmp("adds", opcode) || + !strcmp("sub", opcode) || + !strcmp("subw", opcode) || + !strcmp("subs", opcode) || + !strcmp("cmn", opcode) || + !strcmp("cmp", opcode)) + return 1; + return 0; +} + +static void w_as_dyadic_instruction (struct instruction *instruction,char *opcode); + +static void w_as_dyadic_instruction_through_scratch (struct instruction *instruction,char *opcode) +{ + WORD r1 = instruction->instruction_parameters[1].parameter_data.reg.r; + + w_as_opcode_mov(); + w_as_scratch_register_comma(); + w_as_register (r1); + w_as_newline_after_instruction(); + + instruction->instruction_parameters[1].parameter_data.reg.r = 13-7; /* r12 */ + + w_as_dyadic_instruction (instruction, opcode); + + w_as_opcode_mov(); + w_as_register_comma (r1); + w_as_scratch_register(); + w_as_newline_after_instruction(); +} + static void w_as_dyadic_instruction (struct instruction *instruction,char *opcode) { + if (!dyadic_instruction_allowed(instruction, opcode)) + { + w_as_dyadic_instruction_through_scratch (instruction, opcode); + return; + } + if (instruction->instruction_parameters[0].parameter_type==P_IMMEDIATE && mov_or_mvn_immediate (instruction->instruction_parameters[0].parameter_data.i)) { |