diff options
author | John van Groningen | 2004-07-12 14:26:40 +0000 |
---|---|---|
committer | John van Groningen | 2004-07-12 14:26:40 +0000 |
commit | 5fd3638b200ddd7c901449347ae3b003bb31683b (patch) | |
tree | f7ea535d8601c15d5e3ba52290226f4bab849200 /cglin.c | |
parent | use 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.c | 127 |
1 files changed, 104 insertions, 23 deletions
@@ -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; |