summaryrefslogtreecommitdiff
path: root/cglin.c
diff options
context:
space:
mode:
authorJohn van Groningen2004-07-12 14:26:40 +0000
committerJohn van Groningen2004-07-12 14:26:40 +0000
commit5fd3638b200ddd7c901449347ae3b003bb31683b (patch)
treef7ea535d8601c15d5e3ba52290226f4bab849200 /cglin.c
parentuse transition vector for calling functions with ccall "F" (diff)
add absR, negI, unsigned compare, divU, remU and faster not
instructions for IA32 add loop optimization code (speeds up jmp to a cmp and branch instruction), not yet enabled
Diffstat (limited to 'cglin.c')
-rw-r--r--cglin.c127
1 files changed, 104 insertions, 23 deletions
diff --git a/cglin.c b/cglin.c
index b9b9f32..b293c9a 100644
--- a/cglin.c
+++ b/cglin.c
@@ -3068,7 +3068,8 @@ static int compare_node (INSTRUCTION_GRAPH graph,int i_test_1,int i_test_2)
}
enum {
- CEQ, CNE, CGT, CLT, CGE, CLE, CO, CNO,
+ CEQ, CNE, CGT, CLT, CGE, CLE,
+ CO, CNO, CGTU, CLTU, CGEU, CLEU,
CFEQ, CFNE, CFGT, CFLT, CFGE, CFLE
};
@@ -3076,19 +3077,22 @@ enum {
int condition_to_set_instruction[]=
{
- ISEQ, ISNE, ISGT, ISLT, ISGE, ISLE, ISO, ISNO,
+ ISEQ, ISNE, ISGT, ISLT, ISGE, ISLE,
+ ISO, ISNO, ISGTU, ISLTU, ISGEU, ISLEU,
IFSEQ, IFSNE, IFSGT, IFSLT, IFSGE, IFSLE
};
static int condition_to_branch_false_instruction[]=
{
- IBNE, IBEQ, IBLE, IBGE, IBLT, IBGT, IBNO, IBO,
+ IBNE, IBEQ, IBLE, IBGE, IBLT, IBGT,
+ IBNO, IBO, IBLEU, IBGEU, IBLTU, IBGTU,
IFBNE, IFBEQ, IFBLE, IFBGE, IFBLT, IFBGT
};
static int condition_to_branch_true_instruction[]=
{
- IBEQ, IBNE, IBGT, IBLT, IBGE, IBLE, IBO, IBNO,
+ IBEQ, IBNE, IBGT, IBLT, IBGE, IBLE,
+ IBO, IBNO, IBGTU, IBLTU, IBGEU, IBLEU,
IFBEQ, IFBNE, IFBGT, IFBLT, IFBGE, IFBLE
};
@@ -3125,9 +3129,15 @@ static int linearize_condition (INSTRUCTION_GRAPH graph)
case GCMP_LT:
condition=compare_node (graph,CLT,CGT);
break;
+ case GCMP_LTU:
+ condition=compare_node (graph,CLTU,CGTU);
+ break;
case GCMP_GT:
condition=compare_node (graph,CGT,CLT);
break;
+ case GCMP_GTU:
+ condition=compare_node (graph,CGTU,CLTU);
+ break;
case GFCMP_EQ:
condition=float_compare_node (graph,CFEQ,CFEQ);
break;
@@ -3186,9 +3196,15 @@ static int linearize_not_condition (INSTRUCTION_GRAPH graph)
case GCMP_LT:
condition=compare_node (graph,CGE,CLE);
break;
+ case GCMP_LTU:
+ condition=compare_node (graph,CGEU,CLEU);
+ break;
case GCMP_GT:
condition=compare_node (graph,CLE,CGE);
break;
+ case GCMP_GTU:
+ condition=compare_node (graph,CLEU,CGEU);
+ break;
case GFCMP_EQ:
condition=float_compare_node (graph,CFNE,CFNE);
break;
@@ -3364,8 +3380,41 @@ static void linearize_dyadic_non_commutative_data_operator (int i_instruction_co
register_node (graph,reg_1);
}
+#ifdef I486
+static void linearize_monadic_data_operator (int i_instruction_code,INSTRUCTION_GRAPH graph,ADDRESS *ad_p)
+{
+ INSTRUCTION_GRAPH graph_1;
+ ADDRESS ad_1;
+ int reg_1;
+
+ graph_1=graph->instruction_parameters[0].p;
+
+ linearize_graph (graph_1,&ad_1);
+
+ in_alterable_data_register (&ad_1);
+ reg_1=ad_1.ad_register;
+ instruction_r (i_instruction_code,reg_1);
+
+ if (graph->instruction_d_min_a_cost>0){
+ int areg;
+
+ areg=get_aregister();
+ i_move_r_r (reg_1,areg);
+ free_dregister (reg_1);
+ reg_1=areg;
+ }
+
+ ad_p->ad_mode=P_REGISTER;
+ ad_p->ad_register=reg_1;
+
+ ad_p->ad_count_p=&graph->node_count;
+ if (*ad_p->ad_count_p>1)
+ register_node (graph,reg_1);
+}
+#endif
+
#if defined (I486) || defined (G_POWER)
-static void linearize_div_mod_operator (int i_instruction_code,INSTRUCTION_GRAPH graph,ADDRESS *ad_p)
+static void linearize_div_rem_operator (int i_instruction_code,INSTRUCTION_GRAPH graph,ADDRESS *ad_p)
{
INSTRUCTION_GRAPH graph_1,graph_2;
ADDRESS ad_1,ad_2;
@@ -3387,23 +3436,28 @@ static void linearize_div_mod_operator (int i_instruction_code,INSTRUCTION_GRAPH
# ifdef I486
if (ad_1.ad_mode==P_IMMEDIATE){
- int i;
-
- i=ad_1.ad_offset;
- if (i_instruction_code==IMOD && i<0 && i!=0x80000000)
- i=-i;
-
- if ((i & (i-1))==0 && (i_instruction_code==IMOD ? i>1 : i>0))
- instruction_ad_r (i_instruction_code,&ad_1,ad_2.ad_register);
- else if (i>1 || (i<-1 && i!=0x80000000)){
- int tmp_reg;
-
- tmp_reg=get_dregister();
- instruction_ad_r_r (i_instruction_code==IDIV ? IDIVI : IREMI,&ad_1,ad_2.ad_register,tmp_reg);
- free_dregister (tmp_reg);
- } else {
+ if (i_instruction_code==IDIVU || i_instruction_code==IREMU){
in_data_register (&ad_1);
- instruction_ad_r (i_instruction_code,&ad_1,ad_2.ad_register);
+ instruction_ad_r (i_instruction_code,&ad_1,ad_2.ad_register);
+ } else {
+ int i;
+
+ i=ad_1.ad_offset;
+ if (i_instruction_code==IMOD && i<0 && i!=0x80000000)
+ i=-i;
+
+ if ((i & (i-1))==0 && (i_instruction_code==IMOD ? i>1 : i>0))
+ instruction_ad_r (i_instruction_code,&ad_1,ad_2.ad_register);
+ else if (i>1 || (i<-1 && i!=0x80000000)){
+ int tmp_reg;
+
+ tmp_reg=get_dregister();
+ instruction_ad_r_r (i_instruction_code==IDIV ? IDIVI : IREMI,&ad_1,ad_2.ad_register,tmp_reg);
+ free_dregister (tmp_reg);
+ } else {
+ in_data_register (&ad_1);
+ instruction_ad_r (i_instruction_code,&ad_1,ad_2.ad_register);
+ }
}
} else {
if (ad_1.ad_mode==P_INDEXED)
@@ -6053,6 +6107,11 @@ static void linearize_float_graph (register INSTRUCTION_GRAPH graph,register ADD
case GFNEG:
linearize_monadic_float_operator (graph,ad_p,IFNEG);
break;
+#ifdef I486
+ case GFABS:
+ linearize_monadic_float_operator (graph,ad_p,IFABS);
+ break;
+#endif
case GFSIN:
linearize_monadic_float_operator (graph,ad_p,IFSIN);
break;
@@ -7512,11 +7571,19 @@ static void linearize_graph (INSTRUCTION_GRAPH graph,ADDRESS *ad_p)
return;
#if defined (I486) || defined (G_POWER)
case GDIV:
- linearize_div_mod_operator (IDIV,graph,ad_p);
+ linearize_div_rem_operator (IDIV,graph,ad_p);
return;
case GMOD:
- linearize_div_mod_operator (IMOD,graph,ad_p);
+ linearize_div_rem_operator (IMOD,graph,ad_p);
+ return;
+# ifdef I486
+ case GDIVU:
+ linearize_div_rem_operator (IDIVU,graph,ad_p);
+ return;
+ case GREMU:
+ linearize_div_rem_operator (IREMU,graph,ad_p);
return;
+# endif
#else
case GDIV:
linearize_dyadic_non_commutative_data_operator (IDIV,graph,ad_p);
@@ -7531,9 +7598,15 @@ static void linearize_graph (INSTRUCTION_GRAPH graph,ADDRESS *ad_p)
case GCMP_LT:
linearize_compare_operator (CLT,CGT,graph,ad_p);
return;
+ case GCMP_LTU:
+ linearize_compare_operator (CLTU,CGTU,graph,ad_p);
+ return;
case GCMP_GT:
linearize_compare_operator (CGT,CLT,graph,ad_p);
return;
+ case GCMP_GTU:
+ linearize_compare_operator (CGTU,CLTU,graph,ad_p);
+ return;
case GCNOT:
linearize_conditional_not_operator (graph,ad_p);
return;
@@ -7564,6 +7637,14 @@ static void linearize_graph (INSTRUCTION_GRAPH graph,ADDRESS *ad_p)
case GFILL_R:
linearize_fill_r_operator (graph,ad_p);
return;
+#ifdef I486
+ case GNEG:
+ linearize_monadic_data_operator (INEG,graph,ad_p);
+ return;
+ case GNOT:
+ linearize_monadic_data_operator (INOT,graph,ad_p);
+ return;
+#endif
case GMOVEMI:
linearize_movemi_operator (graph,ad_p);
return;