summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCamil Staps2016-10-03 18:34:41 +0000
committerCamil Staps2016-10-03 18:34:41 +0000
commit9496e961ca74e80ce0aac975fc917bb2f84cd701 (patch)
tree91bd49fe1f39cc879c7e9b711c47a392eded1ae6
parentFix issue with halfword-aligned node entry points (diff)
IT blocks
-rw-r--r--cgthumb2was.c79
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);