summaryrefslogtreecommitdiff
path: root/cgthumb2was.c
diff options
context:
space:
mode:
Diffstat (limited to 'cgthumb2was.c')
-rw-r--r--cgthumb2was.c44
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))
{