diff options
-rw-r--r-- | cgthumb2was.c | 79 |
1 files changed, 56 insertions, 23 deletions
diff --git a/cgthumb2was.c b/cgthumb2was.c index 8e66c29..5c17e24 100644 --- a/cgthumb2was.c +++ b/cgthumb2was.c @@ -38,6 +38,11 @@ static void w_as_opcode (char *opcode) fprintf (assembly_file,"\t%s\t",opcode); } +static void w_as_opcode_condition (char *opcode,char *condition) +{ + fprintf (assembly_file,"\t%s%s\t",opcode,condition); +} + static void w_as_instruction_without_parameters (char *opcode) { fprintf (assembly_file,"\t%s\n",opcode); @@ -1526,28 +1531,56 @@ static void w_as_jsr_instruction (struct instruction *instruction) } } -static void w_as_set_condition_instruction (struct instruction *instruction,char *opcode1,char *opcode2) +static char *invert_condition(char *condition) +{ + if (!strcmp(condition,"eq")) return "ne"; + else if (!strcmp(condition,"ne")) return "eq"; + else if (!strcmp(condition,"hs")) return "lo"; + else if (!strcmp(condition,"lo")) return "hs"; + else if (!strcmp(condition,"cs")) return "cc"; + else if (!strcmp(condition,"cc")) return "cs"; + else if (!strcmp(condition,"mi")) return "pl"; + else if (!strcmp(condition,"pl")) return "mi"; + else if (!strcmp(condition,"vs")) return "vc"; + else if (!strcmp(condition,"vc")) return "vs"; + else if (!strcmp(condition,"hi")) return "ls"; + else if (!strcmp(condition,"ls")) return "hi"; + else if (!strcmp(condition,"ge")) return "lt"; + else if (!strcmp(condition,"lt")) return "ge"; + else if (!strcmp(condition,"gt")) return "le"; + else if (!strcmp(condition,"le")) return "gt"; + else + error ("unknown condition"); +} + +static void w_as_set_condition_instruction (struct instruction *instruction,char *condition,char *opcode) { int r; char *reg_s; r=instruction->instruction_parameters[0].parameter_data.reg.r; + + if (condition) { + w_as_opcode ("ite"); + fputs (condition,assembly_file); + w_as_newline_after_instruction(); + } - w_as_opcode (opcode1); + w_as_opcode_condition (opcode,condition); w_as_register (r); fprintf (assembly_file,",#1"); w_as_newline_after_instruction(); - w_as_opcode (opcode2); + w_as_opcode_condition (opcode,invert_condition(condition)); w_as_register (r); fprintf (assembly_file,",#0"); w_as_newline_after_instruction(); } -static void w_as_set_float_condition_instruction (struct instruction *instruction,char *opcode1,char *opcode2) +static void w_as_set_float_condition_instruction (struct instruction *instruction,char *condition,char *opcode) { as_test_floating_point_condition_code(); - w_as_set_condition_instruction (instruction,opcode1,opcode2); + w_as_set_condition_instruction (instruction,condition,opcode); } static void w_as_lsl_register_newline (int reg,int shift) @@ -2460,40 +2493,40 @@ static void w_as_instructions (struct instruction *instruction) w_as_reg_reg_imm_instruction (instruction,"lsl"); break; case ISEQ: - w_as_set_condition_instruction (instruction,"moveq","movne"); + w_as_set_condition_instruction (instruction,"eq","mov"); break; case ISGE: - w_as_set_condition_instruction (instruction,"movge","movlt"); + w_as_set_condition_instruction (instruction,"ge","mov"); break; case ISGEU: - w_as_set_condition_instruction (instruction,"movhs","movlo"); + w_as_set_condition_instruction (instruction,"hs","mov"); break; case ISGT: - w_as_set_condition_instruction (instruction,"movgt","movle"); + w_as_set_condition_instruction (instruction,"gt","mov"); break; case ISGTU: - w_as_set_condition_instruction (instruction,"movhi","movls"); + w_as_set_condition_instruction (instruction,"hi","mov"); break; case ISLE: - w_as_set_condition_instruction (instruction,"movle","movgt"); + w_as_set_condition_instruction (instruction,"le","mov"); break; case ISLEU: - w_as_set_condition_instruction (instruction,"movls","movhi"); + w_as_set_condition_instruction (instruction,"ls","mov"); break; case ISLT: - w_as_set_condition_instruction (instruction,"movlt","movge"); + w_as_set_condition_instruction (instruction,"lt","mov"); break; case ISLTU: - w_as_set_condition_instruction (instruction,"movlo","movhs"); + w_as_set_condition_instruction (instruction,"lo","mov"); break; case ISNE: - w_as_set_condition_instruction (instruction,"movne","moveq"); + w_as_set_condition_instruction (instruction,"ne","mov"); break; case ISO: - w_as_set_condition_instruction (instruction,"movvs","movvc"); + w_as_set_condition_instruction (instruction,"vs","mov"); break; case ISNO: - w_as_set_condition_instruction (instruction,"movvc","movvs"); + w_as_set_condition_instruction (instruction,"vc","mov"); break; case ITST: w_as_tst_instruction (instruction); @@ -2586,22 +2619,22 @@ static void w_as_instructions (struct instruction *instruction) w_as_monadic_float_instruction (instruction,"fabsd"); break; case IFSEQ: - w_as_set_float_condition_instruction (instruction,"moveq","movne"); + w_as_set_float_condition_instruction (instruction,"eq","mov"); break; case IFSGE: - w_as_set_float_condition_instruction (instruction,"bpl","bmi"); + w_as_set_float_condition_instruction (instruction,"pl","b"); break; case IFSGT: - w_as_set_float_condition_instruction (instruction,"movgt","movle"); + w_as_set_float_condition_instruction (instruction,"gt","mov"); break; case IFSLE: - w_as_set_float_condition_instruction (instruction,"movle","movgt"); + w_as_set_float_condition_instruction (instruction,"le","mov"); break; case IFSLT: - w_as_set_float_condition_instruction (instruction,"bmi","bpl"); + w_as_set_float_condition_instruction (instruction,"mi","b"); break; case IFSNE: - w_as_set_float_condition_instruction (instruction,"movne","moveq"); + w_as_set_float_condition_instruction (instruction,"ne","mov"); break; case IWORD: w_as_word_instruction (instruction); |