diff options
-rw-r--r-- | cg.tgt | 260 | ||||
-rw-r--r-- | cg.wpj | 10 | ||||
-rw-r--r-- | cgcalc.c | 60 | ||||
-rw-r--r-- | cgcode.c | 96 | ||||
-rw-r--r-- | cgcodep.h | 18 | ||||
-rw-r--r-- | cgconst.h | 30 | ||||
-rw-r--r-- | cgias.c | 177 | ||||
-rw-r--r-- | cgiconst.h | 23 | ||||
-rw-r--r-- | cginput.c | 18 | ||||
-rw-r--r-- | cgiwas.c | 174 | ||||
-rw-r--r-- | cglin.c | 127 | ||||
-rw-r--r-- | cgopt.c | 287 | ||||
-rw-r--r-- | cgstack.c | 34 | ||||
-rw-r--r-- | cgtypes.h | 5 |
14 files changed, 982 insertions, 337 deletions
@@ -12,7 +12,7 @@ NEXE 3 WString 5 -nc2e9 +nc2en 1 0 0 @@ -32,7 +32,7 @@ WString NEXE 8 WVList -11 +9 9 MVState 10 @@ -70,9 +70,9 @@ WINLINK 18 WString 24 -?????Case sensitive link -1 +?????Produce symbol file 1 +0 19 MCState 20 @@ -82,9 +82,9 @@ WINLINK 21 WString 24 -?????Produce symbol file +?????Eliminate dead code +1 1 -0 22 MCState 23 @@ -94,9 +94,9 @@ WINLINK 24 WString 24 -?????Eliminate dead code -1 -1 +?????Incremental Linking +0 +0 25 MVState 26 @@ -134,9 +134,9 @@ WINLINK 34 WString 24 -?????Case sensitive link +?????Produce symbol file +0 0 -1 35 MCState 36 @@ -146,433 +146,409 @@ WINLINK 37 WString 24 -?????Produce symbol file -0 -0 -38 -MRState -39 -WString -7 -WINLINK -40 -WString -19 -nc???Character mode -0 -1 -41 -MCState -42 -WString -7 -WINLINK -43 -WString -24 ?????Eliminate dead code 0 1 -44 +38 WVList 3 -45 +39 ActionStates -46 +40 WString 6 &Debug -47 +41 WVList 0 -48 +42 ActionStates -49 +43 WString 7 Sam&ple -50 +44 WVList 0 -51 +45 ActionStates -52 +46 WString 4 &Run -53 +47 WVList 0 -1 1 1 0 -54 +48 WPickList 11 -55 +49 MItem 3 *.c -56 +50 WString 4 COBJ -57 +51 WVList 13 -58 +52 MVState -59 +53 WString 3 WCC -60 +54 WString 23 ?????Macro definitions: 1 -61 +55 WString 14 _WINDOWS_ I486 0 -62 +56 MCState -63 +57 WString 3 WCC -64 +58 WString 33 ?????Disable stack depth checking 0 1 -65 +59 MVState -66 +60 WString 3 WCC -67 +61 WString 23 ?????Macro definitions: 0 -68 +62 WString 14 _WINDOWS_ I486 0 -69 +63 MRState -70 +64 WString 3 WCC -71 +65 WString 20 ?????Pack structures 0 0 -72 +66 MRState -73 +67 WString 3 WCC -74 +68 WString 21 ?????4 byte alignment 0 1 -75 +69 MRState -76 +70 WString 3 WCC -77 +71 WString 23 ?????Time optimizations 0 1 -78 +72 MRState -79 +73 WString 3 WCC -80 +74 WString 26 ?????Fastest possible code 0 0 -81 +75 MCState -82 +76 WString 3 WCC -83 +77 WString 23 ?????Loop optimizations 0 1 -84 +78 MCState -85 +79 WString 3 WCC -86 +80 WString 30 ?????Call/return optimizations 0 1 -87 +81 MCState -88 +82 WString 3 WCC -89 +83 WString 32 ?????In-line intrinsic functions 0 1 -90 +84 MCState -91 +85 WString 3 WCC -92 +86 WString 27 ?????Instruction scheduling 0 1 -93 +87 MVState -94 +88 WString 3 WCC -95 +89 WString 29 ?????Expand function in-line: 0 -96 +90 WString 2 20 1 -97 +91 MCState -98 +92 WString 3 WCC -99 +93 WString 35 ?????Put functions in separate segs 0 1 -100 +94 WVList 0 -1 1 1 0 -101 +95 MItem 4 cg.c -102 +96 WString 4 COBJ -103 +97 WVList 0 -104 +98 WVList 0 -55 +49 1 1 0 -105 +99 MItem 8 cgcalc.c -106 +100 WString 4 COBJ -107 +101 WVList 0 -108 +102 WVList 0 -55 +49 1 1 0 -109 +103 MItem 8 cgcode.c -110 +104 WString 4 COBJ -111 +105 WVList 0 -112 +106 WVList 0 -55 +49 1 1 0 -113 +107 MItem 7 cgias.c -114 +108 WString 4 COBJ -115 +109 WVList 0 -116 +110 WVList 0 -55 +49 1 1 0 -117 +111 MItem 9 cginput.c -118 +112 WString 4 COBJ -119 +113 WVList 0 -120 +114 WVList 0 -55 +49 1 1 0 -121 +115 MItem 16 cginstructions.c -122 +116 WString 4 COBJ -123 +117 WVList 0 -124 +118 WVList 0 -55 +49 1 1 0 -125 +119 MItem 8 cgiwas.c -126 +120 WString 4 COBJ -127 +121 WVList 0 -128 +122 WVList 0 -55 +49 1 1 0 -129 +123 MItem 7 cglin.c -130 +124 WString 4 COBJ -131 +125 WVList 0 -132 +126 WVList 0 -55 +49 1 1 0 -133 +127 MItem 7 cgopt.c -134 +128 WString 4 COBJ -135 +129 WVList 0 -136 +130 WVList 0 -55 +49 1 1 0 -137 +131 MItem 9 cgstack.c -138 +132 WString 4 COBJ -139 +133 WVList 0 -140 +134 WVList 0 -55 +49 1 1 0 @@ -4,10 +4,10 @@ projectIdent VpeMain 1 WRect -560 -1054 +1475 +1410 7680 -6411 +6400 2 MProject 3 @@ -38,6 +38,6 @@ WRect WFileName 6 cg.tgt -1 -1 +0 +9 7 @@ -571,7 +571,7 @@ static void calculate_dyadic_non_commutative_data_operator (INSTRUCTION_GRAPH gr return; } -static void calculate_mod_operator (INSTRUCTION_GRAPH graph) +static void calculate_rem_operator (INSTRUCTION_GRAPH graph) { register INSTRUCTION_GRAPH graph_1,graph_2; int i_aregs,i_dregs; @@ -2264,8 +2264,10 @@ void calculate_graph_register_uses (INSTRUCTION_GRAPH graph) calculate_dyadic_commutative_data_operator (graph); return; case GCMP_EQ: - case GCMP_LT: case GCMP_GT: + case GCMP_GTU: + case GCMP_LT: + case GCMP_LTU: calculate_compare_operator (graph); return; case GSUB: @@ -2273,10 +2275,16 @@ void calculate_graph_register_uses (INSTRUCTION_GRAPH graph) calculate_dyadic_non_commutative_operator (graph); return; case GDIV: +#ifdef I486 + case GDIVU: +#endif calculate_dyadic_non_commutative_data_operator (graph); return; case GMOD: - calculate_mod_operator (graph); +#ifdef I486 + case GREMU: +#endif + calculate_rem_operator (graph); return; case GLSL: case GLSR: @@ -2299,6 +2307,10 @@ void calculate_graph_register_uses (INSTRUCTION_GRAPH graph) calculate_eor_operator (graph); return; case GCNOT: +#ifdef I486 + case GNEG: + case GNOT: +#endif calculate_cnot_operator (graph); return; case GMOVEMI: @@ -2330,6 +2342,9 @@ void calculate_graph_register_uses (INSTRUCTION_GRAPH graph) case GFEXP: case GFSQRT: case GFNEG: +#ifdef I486 + case GFABS: +#endif calculate_monadic_float_operator (graph); return; case GFLOAD_ID: @@ -2468,8 +2483,13 @@ void count_graph (INSTRUCTION_GRAPH graph) case GAND: case GCMP_EQ: case GCMP_GT: + case GCMP_GTU: case GCMP_LT: + case GCMP_LTU: case GDIV: +#ifdef I486 + case GDIVU: +#endif case GFADD: case GFCMP_EQ: case GFCMP_GT: @@ -2482,6 +2502,9 @@ void count_graph (INSTRUCTION_GRAPH graph) case GLSL: case GLSR: case GMOD: +#ifdef I486 + case GREMU: +#endif case GMUL: case GMUL_O: case GOR: @@ -2515,6 +2538,11 @@ void count_graph (INSTRUCTION_GRAPH graph) case GFEXP: case GFSQRT: case GFNEG: +#ifdef I486 + case GFABS: + case GNEG: + case GNOT: +#endif case GBEFORE0: case GTEST_O: if (++graph->node_count==1) @@ -2620,8 +2648,13 @@ void mark_graph_2 (register INSTRUCTION_GRAPH graph) case GAND: case GCMP_EQ: case GCMP_GT: + case GCMP_GTU: case GCMP_LT: + case GCMP_LTU: case GDIV: +#ifdef I486 + case GDIVU: +#endif case GFADD: case GFCMP_EQ: case GFCMP_GT: @@ -2634,6 +2667,9 @@ void mark_graph_2 (register INSTRUCTION_GRAPH graph) case GLSL: case GLSR: case GMOD: +#ifdef I486 + case GREMU: +#endif case GMUL: case GMUL_O: case GOR: @@ -2668,6 +2704,11 @@ void mark_graph_2 (register INSTRUCTION_GRAPH graph) case GFEXP: case GFSQRT: case GFNEG: +#ifdef I486 + case GFABS: + case GNEG: + case GNOT: +#endif case GBEFORE0: case GTEST_O: if (graph->node_mark<2){ @@ -2787,8 +2828,13 @@ void mark_graph_1 (register INSTRUCTION_GRAPH graph) case GAND: case GCMP_EQ: case GCMP_GT: + case GCMP_GTU: case GCMP_LT: + case GCMP_LTU: case GDIV: +#ifdef I486 + case GDIVU: +#endif case GFADD: case GFCMP_EQ: case GFCMP_GT: @@ -2801,6 +2847,9 @@ void mark_graph_1 (register INSTRUCTION_GRAPH graph) case GLSL: case GLSR: case GMOD: +#ifdef I486 + case GREMU: +#endif case GMUL: case GMUL_O: case GOR: @@ -2833,6 +2882,11 @@ void mark_graph_1 (register INSTRUCTION_GRAPH graph) case GFEXP: case GFSQRT: case GFNEG: +#ifdef I486 + case GFABS: + case GNEG: + case GNOT: +#endif case GBEFORE0: case GTEST_O: if (!graph->node_mark){ @@ -158,9 +158,18 @@ int no_time_profiling; #define g_bounds(g1,g2) g_instruction_2(GBOUNDS,(g1),(g2)) #define g_cmp_eq(g1,g2) g_instruction_2(GCMP_EQ,(g1),(g2)) #define g_cmp_gt(g1,g2) g_instruction_2(GCMP_GT,(g1),(g2)) +#ifdef I486 +# define g_cmp_gtu(g1,g2) g_instruction_2(GCMP_GTU,(g1),(g2)) +#endif #define g_cmp_lt(g1,g2) g_instruction_2(GCMP_LT,(g1),(g2)) +#ifdef I486 +# define g_cmp_ltu(g1,g2) g_instruction_2(GCMP_LTU,(g1),(g2)) +#endif #define g_cnot(g1) g_instruction_1(GCNOT,(g1)) #define g_div(g1,g2) g_instruction_2(GDIV,(g1),(g2)) +#ifdef I486 +# define g_divu(g1,g2) g_instruction_2(GDIVU,(g1),(g2)) +#endif #define g_eor(g1,g2) g_instruction_2(GEOR,(g1),(g2)) #define g_fadd(g1,g2) g_instruction_2(GFADD,(g1),(g2)) #define g_fcmp_eq(g1,g2) g_instruction_2(GFCMP_EQ,(g1),(g2)) @@ -179,7 +188,14 @@ int no_time_profiling; #define g_lsl(g1,g2) g_instruction_2(GLSL,(g1),(g2)) #define g_lsr(g1,g2) g_instruction_2(GLSR,(g1),(g2)) #define g_mod(g1,g2) g_instruction_2(GMOD,(g1),(g2)) +#ifdef I486 +# define g_remu(g1,g2) g_instruction_2(GREMU,(g1),(g2)) +#endif #define g_mul(g1,g2) g_instruction_2(GMUL,(g1),(g2)) +#ifdef I486 +# define g_neg(g1) g_instruction_1(GNEG,(g1)) +# define g_not(g1) g_instruction_1(GNOT,(g1)) +#endif #define g_or(g1,g2) g_instruction_2(GOR,(g1),(g2)) #define g_keep(g1,g2) g_instruction_2(GKEEP,(g1),(g2)) #define g_fkeep(g1,g2) g_instruction_2(GFKEEP,(g1),(g2)) @@ -243,7 +259,7 @@ LABEL *eval_fill_label,*eval_upd_labels[33]; static LABEL *print_r_arg_label,*push_t_r_args_label,*push_a_r_args_label; LABEL *index_error_label; -#ifdef G_POWER +#if defined (G_POWER) || defined (I486) LABEL *r_to_i_buffer_label; #endif @@ -435,6 +451,13 @@ static void code_dyadic_sane_operator (LABEL *label) #endif } +#ifdef I486 +void code_absR (void) +{ + code_monadic_real_operator (GFABS); +} +#endif + void code_acosR (VOID) { #ifdef M68000 @@ -1770,6 +1793,18 @@ void code_divR (VOID) #endif } +#ifdef I486 +void code_divU (VOID) +{ + INSTRUCTION_GRAPH graph_1,graph_2,graph_3; + + graph_1=s_pop_b(); + graph_2=s_get_b (0); + graph_3=g_divu (graph_2,graph_1); + s_put_b (0,graph_3); +} +#endif + void code_entierR (VOID) { if (entier_real_label==NULL) @@ -3237,6 +3272,19 @@ void code_gtR (VOID) #endif } +#ifdef I486 +void code_gtU (VOID) +{ + INSTRUCTION_GRAPH graph_1,graph_2,graph_3; + + graph_1=s_pop_b(); + graph_2=s_get_b (0); + graph_3=g_cmp_gtu (graph_2,graph_1); + + s_put_b (0,graph_3); +} +#endif + void code_halt (VOID) { if (halt_label==NULL) @@ -4021,6 +4069,19 @@ void code_ltR (VOID) #endif } +#ifdef I486 +void code_ltU (VOID) +{ + INSTRUCTION_GRAPH graph_1,graph_2,graph_3; + + graph_1=s_pop_b(); + graph_2=s_get_b (0); + graph_3=g_cmp_ltu (graph_2,graph_1); + + s_put_b (0,graph_3); +} +#endif + void code_remI (VOID) { #ifdef M68000 @@ -4052,6 +4113,18 @@ void code_remI (VOID) #endif } +#ifdef I486 +void code_remU (VOID) +{ + INSTRUCTION_GRAPH graph_1,graph_2,graph_3; + + graph_1=s_pop_b(); + graph_2=s_get_b (0); + graph_3=g_remu (graph_2,graph_1); + s_put_b (0,graph_3); +} +#endif + static INSTRUCTION_GRAPH multiply_by_constant (unsigned int n,INSTRUCTION_GRAPH graph_1) { INSTRUCTION_GRAPH graph_2; @@ -4264,6 +4337,18 @@ void code_nu (int a_size,int b_size,char *descriptor_name,char *ea_label_name) last_block->block_ea_label=NULL; } +#ifdef I486 +void code_negI (void) +{ + INSTRUCTION_GRAPH graph_1,graph_2; + + graph_1=s_get_b (0); + graph_2=g_neg (graph_1); + + s_put_b (0,graph_2); +} +#endif + void code_negR (void) { #ifdef M68000 @@ -4296,9 +4381,12 @@ void code_not (VOID) INSTRUCTION_GRAPH graph_1,graph_2,graph_3; graph_1=s_get_b (0); +#ifdef I486 + graph_3=g_not (graph_1); +#else graph_2=g_load_i (-1); graph_3=g_eor (graph_2,graph_1); - +#endif s_put_b (0,graph_3); } @@ -6200,7 +6288,7 @@ void code_RtoI (VOID) { INSTRUCTION_GRAPH graph_1,graph_2,graph_3,graph_4; -#ifdef G_POWER +#if defined (G_POWER) || defined (I486) if (r_to_i_buffer_label==NULL) r_to_i_buffer_label=enter_label ("r_to_i_buffer",IMPORT_LABEL); @@ -8435,7 +8523,7 @@ void initialize_coding (VOID) sqrt_real=NULL; #endif -#ifdef G_POWER +#if defined (G_POWER) || defined (I486) r_to_i_buffer_label=NULL; #endif @@ -15,6 +15,9 @@ # define ULONG unsigned long #endif +#ifdef I486 +void code_absR (void); +#endif void code_acosR (VOID); void code_add_args (int source_offset,int n_arguments,int destination_offset); void code_addI (VOID); @@ -62,6 +65,9 @@ void code_decI (VOID); void code_del_args (int source_offset,int n_arguments,int destination_offset); void code_divI (VOID); void code_divR (VOID); +#ifdef I486 + void code_divU (VOID); +#endif void code_entierR (VOID); void code_eqB (VOID); void code_eqB_a (int value,int a_offset); @@ -112,6 +118,9 @@ void code_get_node_arity (int a_offset); void code_gtC (VOID); void code_gtI (VOID); void code_gtR (VOID); +#ifdef I486 +void code_gtU (VOID); +#endif void code_halt (VOID); void code_in (char parameters[]); void code_incI (VOID); @@ -132,12 +141,21 @@ void code_log10R (VOID); void code_ltC (VOID); void code_ltI (VOID); void code_ltR (VOID); +#ifdef I486 +void code_ltU (VOID); +#endif void code_remI (VOID); +#ifdef I486 + void code_remU (VOID); +#endif void code_mulI (VOID); #ifndef M68000 void code_mulIo (VOID); #endif void code_mulR (VOID); +#ifdef I486 +void code_negI (void); +#endif void code_negR (VOID); void code_new_ext_reducer (char descriptor_name[],int a_offset); void code_new_int_reducer (char label_name[],int a_offset); @@ -1,22 +1,26 @@ enum { GADD, GADD_O, GAND, GALLOCATE, GASR, GBEFORE, - GBEFORE0, GBOUNDS, GCMP_EQ, GCMP_GT, GCMP_LT, GCNOT, - GCOPY, GCREATE, GCREATE_R, GDIV, GEOR, - GFACOS, GFADD, GFASIN, GFCMP_EQ, GFCMP_GT, GFATAN, - GFCMP_LT, GFCOS, GFDIV, GFEXP, GFHIGH, GFITOR, - GFJOIN, GFKEEP, GFLN, GFLOAD, GFLOAD_I, GFLOAD_ID, - GFLOAD_X, GFLOG10, GFLOW, GFMOVEMI, GFMUL, GFNEG, - GFREM, GFRTOI, GFSIN, GFSUB, GFILL, GFILL_R, - GFREGISTER, GFSQRT, GFSTORE, GFSTORE_R, GFSTORE_X, GFTAN, - GGFREGISTER, GGREGISTER, GKEEP, GINDIRECTION, GLEA, GLOAD, - GLOAD_I, GLOAD_ID, GLOAD_X, GLOAD_B_ID, GLOAD_B_X, GLOAD_DES_ID, - GLOAD_DES_I, GLSL, GLSR, GMOD, GMOVEM, GMOVEMI, - GMUL, GMUL_O, GOR, GREGISTER, GSTORE, GSTORE_R, - GSTORE_B_X, GSTORE_X, GSUB, GSUB_O, GTEST_O, GEXIT_IF + GBEFORE0, GBOUNDS, GCMP_EQ, GCMP_GT, GCMP_GTU, GCMP_LT, + GCMP_LTU, GCNOT, GCOPY, GCREATE, GCREATE_R, GDIV, + GEOR, GFACOS, GFADD, GFASIN, GFCMP_EQ, GFCMP_GT, + GFATAN, GFCMP_LT, GFCOS, GFDIV, GFEXP, GFHIGH, + GFITOR, GFJOIN, GFKEEP, GFLN, GFLOAD, GFLOAD_I, + GFLOAD_ID, GFLOAD_X, GFLOG10, GFLOW, GFMOVEMI, GFMUL, + GFNEG, GFREM, GFRTOI, GFSIN, GFSUB, GFILL, + GFILL_R, GFREGISTER, GFSQRT, GFSTORE, GFSTORE_R, GFSTORE_X, + GFTAN, GGFREGISTER, GGREGISTER, GKEEP, GINDIRECTION, GLEA, + GLOAD, GLOAD_I, GLOAD_ID, GLOAD_X, GLOAD_B_ID, GLOAD_B_X, + GLOAD_DES_ID, GLOAD_DES_I, GLSL, GLSR, GMOD, GMOVEM, + GMOVEMI, GMUL, GMUL_O, GOR, GREGISTER, GSTORE, + GSTORE_R, GSTORE_B_X, GSTORE_X, GSUB, GSUB_O, GTEST_O, + GEXIT_IF #ifdef G_POWER ,GCREATE_S, GUMULH #endif +#ifdef I486 + ,GDIVU, GREMU, GFABS, GNEG, GNOT +#endif }; enum { @@ -2149,13 +2149,13 @@ static void as_div_rem_i_instruction (struct instruction *instruction,int comput } } -static void as_div_instruction (struct instruction *instruction) +static void as_div_instruction (struct instruction *instruction,int unsigned_div) { - int d_reg; + int d_reg,opcode2; d_reg=instruction->instruction_parameters[1].parameter_data.reg.r; - if (instruction->instruction_parameters[0].parameter_type==P_IMMEDIATE){ + if (instruction->instruction_parameters[0].parameter_type==P_IMMEDIATE && unsigned_div==0){ int i,log2i; i=instruction->instruction_parameters[0].parameter_data.i; @@ -2198,24 +2198,28 @@ static void as_div_instruction (struct instruction *instruction) return; } + opcode2=unsigned_div ? 0060 : 0070; + switch (d_reg){ case REGISTER_D0: as_move_r_r (REGISTER_A1,REGISTER_O0); - /*cdq*/ - store_c (0231); + if (unsigned_div) + as_r_r (0063,REGISTER_A1,REGISTER_A1); /* xor */ + else + store_c (0231); /* cdq */ /* idivl */ if (instruction->instruction_parameters[0].parameter_type==P_REGISTER && instruction->instruction_parameters[0].parameter_data.reg.r==REGISTER_A1) { - as_r (0367,0070,REGISTER_O0); + as_r (0367,opcode2,REGISTER_O0); } else if (instruction->instruction_parameters[0].parameter_type==P_INDIRECT && instruction->instruction_parameters[0].parameter_data.reg.r==REGISTER_A1) { - as_id (0367,0070,instruction->instruction_parameters[0].parameter_offset,REGISTER_O0); + as_id (0367,opcode2,instruction->instruction_parameters[0].parameter_offset,REGISTER_O0); } else - as_parameter (0367,0070,&instruction->instruction_parameters[0]); + as_parameter (0367,opcode2,&instruction->instruction_parameters[0]); as_move_r_r (REGISTER_O0,REGISTER_A1); break; @@ -2223,8 +2227,10 @@ static void as_div_instruction (struct instruction *instruction) as_move_r_r (REGISTER_D0,REGISTER_O0); as_move_r_r (REGISTER_A1,REGISTER_D0); - /*cdq*/ - store_c (0231); + if (unsigned_div) + as_r_r (0063,REGISTER_A1,REGISTER_A1); /* xor */ + else + store_c (0231); /* cdq */ /* idivl */ if (instruction->instruction_parameters[0].parameter_type==P_REGISTER){ @@ -2236,7 +2242,7 @@ static void as_div_instruction (struct instruction *instruction) else if (r==REGISTER_A1) r=REGISTER_D0; - as_r (0367,0070,r); + as_r (0367,opcode2,r); } else if (instruction->instruction_parameters[0].parameter_type==P_INDIRECT){ int r; @@ -2246,9 +2252,9 @@ static void as_div_instruction (struct instruction *instruction) else if (r==REGISTER_A1) r=REGISTER_D0; - as_id (0367,0070,instruction->instruction_parameters[0].parameter_offset,r); + as_id (0367,opcode2,instruction->instruction_parameters[0].parameter_offset,r); } else - as_parameter (00367,0070,&instruction->instruction_parameters[0]); + as_parameter (00367,opcode2,&instruction->instruction_parameters[0]); as_move_r_r (REGISTER_D0,REGISTER_A1); as_move_r_r (REGISTER_O0,REGISTER_D0); @@ -2257,8 +2263,10 @@ static void as_div_instruction (struct instruction *instruction) as_move_r_r (REGISTER_A1,REGISTER_O0); store_c (0x90+reg_num (d_reg)); /* xchg d_reg,D0 */ - /*cdq*/ - store_c (0231); + if (unsigned_div) + as_r_r (0063,REGISTER_A1,REGISTER_A1); /* xor */ + else + store_c (0231); /* cdq */ /* idivl */ if (instruction->instruction_parameters[0].parameter_type==P_REGISTER){ @@ -2272,7 +2280,7 @@ static void as_div_instruction (struct instruction *instruction) else if (r==d_reg) r=REGISTER_D0; - as_r (0367,0070,r); + as_r (0367,opcode2,r); } else if (instruction->instruction_parameters[0].parameter_type==P_INDIRECT){ int r; @@ -2284,7 +2292,7 @@ static void as_div_instruction (struct instruction *instruction) else if (r==d_reg) r=REGISTER_D0; - as_id (0367,0070,instruction->instruction_parameters[0].parameter_offset,r); + as_id (0367,opcode2,instruction->instruction_parameters[0].parameter_offset,r); } else as_parameter (0367,0070,&instruction->instruction_parameters[0]); @@ -2293,13 +2301,13 @@ static void as_div_instruction (struct instruction *instruction) } } -static void as_rem_instruction (struct instruction *instruction) +static void as_rem_instruction (struct instruction *instruction,int unsigned_rem) { - int d_reg; + int d_reg,opcode2; d_reg=instruction->instruction_parameters[1].parameter_data.reg.r; - if (instruction->instruction_parameters[0].parameter_type==P_IMMEDIATE){ + if (instruction->instruction_parameters[0].parameter_type==P_IMMEDIATE && unsigned_rem==0){ int i,log2i; i=instruction->instruction_parameters[0].parameter_data.i; @@ -2356,24 +2364,28 @@ static void as_rem_instruction (struct instruction *instruction) return; } + opcode2=unsigned_rem ? 0060 : 0070; + switch (d_reg){ case REGISTER_D0: as_move_r_r (REGISTER_A1,REGISTER_O0); - /*cdq*/ - store_c (0231); + if (unsigned_rem) + as_r_r (0063,REGISTER_A1,REGISTER_A1); /* xor */ + else + store_c (0231); /* cdq */ /* idivl */ if (instruction->instruction_parameters[0].parameter_type==P_REGISTER && instruction->instruction_parameters[0].parameter_data.reg.r==REGISTER_A1) { - as_r (0367,0070,REGISTER_O0); + as_r (0367,opcode2,REGISTER_O0); } else if (instruction->instruction_parameters[0].parameter_type==P_INDIRECT && instruction->instruction_parameters[0].parameter_data.reg.r==REGISTER_A1) { - as_id (0367,0070,instruction->instruction_parameters[0].parameter_offset,REGISTER_O0); + as_id (0367,opcode2,instruction->instruction_parameters[0].parameter_offset,REGISTER_O0); } else - as_parameter (0367,0070,&instruction->instruction_parameters[0]); + as_parameter (0367,opcode2,&instruction->instruction_parameters[0]); as_move_r_r (REGISTER_A1,REGISTER_D0); as_move_r_r (REGISTER_O0,REGISTER_A1); @@ -2382,8 +2394,11 @@ static void as_rem_instruction (struct instruction *instruction) as_move_r_r (REGISTER_D0,REGISTER_O0); as_move_r_r (REGISTER_A1,REGISTER_D0); - /*cdq*/ - store_c (0231); + if (unsigned_rem) + as_r_r (0063,REGISTER_A1,REGISTER_A1); /* xor */ + else + store_c (0231); /* cdq */ + /* idivl */ if (instruction->instruction_parameters[0].parameter_type==P_REGISTER){ int r; @@ -2394,7 +2409,7 @@ static void as_rem_instruction (struct instruction *instruction) else if (r==REGISTER_A1) r=REGISTER_D0; - as_r (0367,0070,r); + as_r (0367,opcode2,r); } else if (instruction->instruction_parameters[0].parameter_type==P_INDIRECT){ int r; @@ -2404,9 +2419,9 @@ static void as_rem_instruction (struct instruction *instruction) else if (r==REGISTER_A1) r=REGISTER_D0; - as_id (0367,0070,instruction->instruction_parameters[0].parameter_offset,r); + as_id (0367,opcode2,instruction->instruction_parameters[0].parameter_offset,r); } else - as_parameter (0367,0070,&instruction->instruction_parameters[0]); + as_parameter (0367,opcode2,&instruction->instruction_parameters[0]); as_move_r_r (REGISTER_O0,REGISTER_D0); break; @@ -2414,8 +2429,10 @@ static void as_rem_instruction (struct instruction *instruction) as_move_r_r (REGISTER_A1,REGISTER_O0); store_c (0x90+reg_num (d_reg)); /* xchg d_reg,D0 */ - /*cdq*/ - store_c (0231); + if (unsigned_rem) + as_r_r (0063,REGISTER_A1,REGISTER_A1); /* xor */ + else + store_c (0231); /* cdq */ /* idivl */ if (instruction->instruction_parameters[0].parameter_type==P_REGISTER){ int r; @@ -2428,7 +2445,7 @@ static void as_rem_instruction (struct instruction *instruction) else if (r==d_reg) r=REGISTER_D0; - as_r (0367,0070,r); + as_r (0367,opcode2,r); } else if (instruction->instruction_parameters[0].parameter_type==P_INDIRECT){ int r; @@ -2440,9 +2457,9 @@ static void as_rem_instruction (struct instruction *instruction) else if (r==d_reg) r=REGISTER_D0; - as_id (0367,0070,instruction->instruction_parameters[0].parameter_offset,r); + as_id (0367,opcode2,instruction->instruction_parameters[0].parameter_offset,r); } else - as_parameter (0367,0070,&instruction->instruction_parameters[0]); + as_parameter (0367,opcode2,&instruction->instruction_parameters[0]); as_move_r_r (d_reg,REGISTER_D0); as_move_r_r (REGISTER_A1,d_reg); @@ -2600,6 +2617,16 @@ static void as_exg_instruction (struct instruction *instruction) as_r_r (0207,r1,r2); } +static void as_neg_instruction (struct instruction *instruction) +{ + as_r (0367,0030,instruction->instruction_parameters[0].parameter_data.reg.r); +} + +static void as_not_instruction (struct instruction *instruction) +{ + as_r (0367,0020,instruction->instruction_parameters[0].parameter_data.reg.r); +} + static void as_rtsi_instruction (struct instruction *instruction) { store_c (0xc2); @@ -2685,6 +2712,9 @@ static void as_f_i (int code1,int code2,DOUBLE *r_p) new_label->label_flags=DATA_LABEL; + if (data_object_label==NULL) + as_new_data_module(); + data_object_label->object_section_align8=1; if ((data_buffer_p-current_data_buffer->data-data_object_label->object_label_offset) & 4) store_long_word_in_data_section (0); @@ -2706,7 +2736,7 @@ struct instruction *find_next_fp_instruction (struct instruction *instruction) while (instruction!=NULL){ switch (instruction->instruction_icode){ case IFADD: case IFSUB: case IFMUL: case IFDIV: - case IFMOVEL: case IFCMP: case IFNEG: case IFTST: case IFREM: + case IFMOVEL: case IFCMP: case IFNEG: case IFABS: case IFTST: case IFREM: case IFBEQ: case IFBGE: case IFBGT: case IFBLE: case IFBLT: case IFBNE: case IFSEQ: case IFSGE: case IFSGT: case IFSLE: case IFSLT: case IFSNE: case IFCOS: case IFSIN: case IFSQRT: case IFTAN: @@ -2734,7 +2764,7 @@ int next_instruction_is_fld_reg (int reg0,struct instruction *instruction) if (next_fp_instruction!=NULL){ switch (next_fp_instruction->instruction_icode){ case IFADD: case IFSUB: case IFMUL: case IFDIV: - case IFSQRT: case IFNEG: case IFSIN: case IFCOS: + case IFSQRT: case IFNEG: case IFABS: case IFSIN: case IFCOS: if (next_fp_instruction->instruction_parameters[0].parameter_type==P_F_REGISTER && next_fp_instruction->instruction_parameters[0].parameter_data.reg.r==reg0) { @@ -2846,7 +2876,7 @@ static void fstpl_instruction (int reg0,struct instruction *instruction) return; } /* else */ - case IFSQRT: case IFNEG: case IFSIN: case IFCOS: + case IFSQRT: case IFNEG: case IFABS: case IFSIN: case IFCOS: if (next_fp_instruction->instruction_parameters[0].parameter_type==P_F_REGISTER && next_fp_instruction->instruction_parameters[0].parameter_data.reg.r==reg0) { @@ -3651,9 +3681,28 @@ void store_descriptor_string_in_data_section (char *string,int length,LABEL *str static void as_fmovel_instruction (struct instruction *instruction) { - if (instruction->instruction_parameters[0].parameter_type==P_F_REGISTER) - internal_error_in_function ("as_fmovel_instruction"); - else { + if (instruction->instruction_parameters[0].parameter_type==P_F_REGISTER){ + if (instruction->instruction_parameters[1].parameter_type==P_REGISTER){ + LABEL *new_label; + int s_freg; + + new_label=allocate_memory_from_heap (sizeof (struct label)); + + new_label->label_flags=DATA_LABEL; + + define_data_label (new_label); + store_long_word_in_data_section (0); + + s_freg=instruction->instruction_parameters[0].parameter_data.reg.r; + if (s_freg!=0){ + as_f_r (0xd9,0xc0,s_freg); /* fld s_freg */ + as_f_a (0xdb,3,new_label); /* fistp */ + } else + as_f_a (0xdb,2,new_label); /* fist */ + as_r_a (0x8b,instruction->instruction_parameters[1].parameter_data.reg.r,new_label); + } else + internal_error_in_function ("as_fmovel_instruction"); + } else { switch (instruction->instruction_parameters[0].parameter_type){ case P_REGISTER: { @@ -3792,21 +3841,30 @@ static void as_instructions (struct instruction *instruction) case IBGE: as_branch_instruction (instruction,015); break; + case IBGEU: + as_branch_instruction (instruction,003); + break; case IBGT: as_branch_instruction (instruction,017); break; + case IBGTU: + as_branch_instruction (instruction,007); + break; case IBLE: as_branch_instruction (instruction,016); break; + case IBLEU: + as_branch_instruction (instruction,006); + break; case IBLT: as_branch_instruction (instruction,014); break; + case IBLTU: + as_branch_instruction (instruction,002); + break; case IBNE: as_branch_instruction (instruction,005); break; - case IBHS: - as_branch_instruction (instruction,003); - break; case IBO: as_branch_instruction (instruction,0); break; @@ -3826,17 +3884,23 @@ static void as_instructions (struct instruction *instruction) as_mul_instruction (instruction); break; case IDIV: - as_div_instruction (instruction); + as_div_instruction (instruction,0); break; case IDIVI: as_div_rem_i_instruction (instruction,0); break; + case IDIVU: + as_div_instruction (instruction,1); + break; case IMOD: - as_rem_instruction (instruction); + as_rem_instruction (instruction,0); break; case IREMI: as_div_rem_i_instruction (instruction,1); break; + case IREMU: + as_rem_instruction (instruction,1); + break; case IAND: as_logic_instruction (instruction,0043,040,045); break; @@ -3852,15 +3916,27 @@ static void as_instructions (struct instruction *instruction) case ISGE: as_set_condition_instruction (instruction,015); break; + case ISGEU: + as_set_condition_instruction (instruction,003); + break; case ISGT: as_set_condition_instruction (instruction,017); break; + case ISGTU: + as_set_condition_instruction (instruction,007); + break; case ISLE: as_set_condition_instruction (instruction,016); break; + case ISLEU: + as_set_condition_instruction (instruction,006); + break; case ISLT: as_set_condition_instruction (instruction,014); break; + case ISLTU: + as_set_condition_instruction (instruction,002); + break; case ISNE: as_set_condition_instruction (instruction,005); break; @@ -3888,6 +3964,12 @@ static void as_instructions (struct instruction *instruction) case IEXG: as_exg_instruction (instruction); break; + case INEG: + as_neg_instruction (instruction); + break; + case INOT: + as_not_instruction (instruction); + break; case IWORD: store_c (instruction->instruction_parameters[0].parameter_data.i); break; @@ -3946,6 +4028,9 @@ static void as_instructions (struct instruction *instruction) case IFNEG: as_monadic_float_instruction (instruction,0xe0); break; + case IFABS: + as_monadic_float_instruction (instruction,0xe1); + break; case IFSIN: as_monadic_float_instruction (instruction,0xfe); break; @@ -7,16 +7,19 @@ # define FP_STACK_OPTIMIZATIONS #endif +#define IBHS IBGEU + enum { - IADD, IAND, IASR, IBEQ, IBGE, IBGT, IBHS, - IBLE, IBLT, IBNE, IBNO, IBO, ICMP, ICMPW, - IDIV, IEOR, IEXG, IEXT, IFADD, IFBEQ, IFBGE, - IFBGT, IFBLE, IFBLT, IFBNE, IFCMP, IFCOS, IFDIV, - IFMUL, IFNEG, IFREM, IFSEQ, IFSGE, IFSGT, IFSIN, - IFSLE, IFSLT, IFSNE, IFSUB, IFTAN, IFTST, IFMOVE, - IFMOVEL, IJMP, IJSR, ILEA, ILSL, ILSR, IMOD, - IMOVE, IMOVEB, IMOVEW, IMUL, IOR, IRTS, ISCHEDULE, - ISEQ, ISGE, ISGT, ISLE, ISLT, ISNE, ISNO, + IADD, IAND, IASR, IBEQ, IBGE, IBGEU, IBGT, + IBGTU, IBLE, IBLEU, IBLT, IBLTU, IBNE, IBNO, + IBO, ICMP, ICMPW, IDIV, IEOR, IEXG, IEXT, + IFADD, IFBEQ, IFBGE, IFBGT, IFBLE, IFBLT, IFBNE, + IFCMP, IFCOS, IFDIV, IFMUL, IFNEG, IFREM, IFSEQ, + IFSGE, IFSGT, IFSIN, IFSLE, IFSLT, IFSNE, IFSUB, + IFTAN, IFTST, IFMOVE, IFMOVEL, IJMP, IJSR, ILEA, + ILSL, ILSR, IMOD, IMOVE, IMOVEB, IMOVEW, IMUL, + IOR, IRTS, ISCHEDULE, ISEQ, ISGE, ISGEU, ISGT, + ISGTU, ISLE, ISLEU, ISLT, ISLTU, ISNE, ISNO, ISO, ISUB, ITST, IWORD #if !defined (G_POWER) ,IFSQRT @@ -52,7 +55,7 @@ enum { ,IFEXG #endif #if defined (I486) - ,IRTSI, IDIVI, IREMI + ,IRTSI, IDIVI, IREMI, IDIVU, IREMU, IFABS, INEG, INOT #endif #ifdef G_POWER ,IUMULH @@ -1717,6 +1717,9 @@ static void put_instruction_name static void put_instructions_in_table (void) { +#ifdef I486 + put_instruction_name ("absR", parse_instruction, code_absR ); +#endif put_instruction_name ("acosR", parse_instruction, code_acosR ); put_instruction_name ("add_args", parse_instruction_n_n_n, code_add_args ); put_instruction_name ("addI", parse_instruction, code_addI ); @@ -1760,6 +1763,9 @@ static void put_instructions_in_table (void) put_instruction_name ("del_args", parse_instruction_n_n_n, code_del_args ); put_instruction_name ("divI", parse_instruction, code_divI ); put_instruction_name ("divR", parse_instruction, code_divR ); +#ifdef I486 + put_instruction_name ("divU", parse_instruction, code_divU ); +#endif put_instruction_name ("entierR", parse_instruction, code_entierR ); put_instruction_name ("eqB", parse_instruction, code_eqB ); put_instruction_name ("eqB_a", parse_instruction_b_n, code_eqB_a ); @@ -1810,6 +1816,9 @@ static void put_instructions_in_table (void) put_instruction_name ("gtC", parse_instruction, code_gtC ); put_instruction_name ("gtI", parse_instruction, code_gtI ); put_instruction_name ("gtR", parse_instruction, code_gtR ); +#ifdef I486 + put_instruction_name ("gtU", parse_instruction, code_gtU ); +#endif put_instruction_name ("halt", parse_instruction, code_halt ); put_instruction_name ("in", parse_instruction_in_or_out, code_in ); put_instruction_name ("incI", parse_instruction, code_incI ); @@ -1834,9 +1843,15 @@ static void put_instructions_in_table (void) put_instruction_name ("ltC", parse_instruction, code_ltC ); put_instruction_name ("ltI", parse_instruction, code_ltI ); put_instruction_name ("ltR", parse_instruction, code_ltR ); +#ifdef I486 + put_instruction_name ("ltU", parse_instruction, code_ltU ); +#endif put_instruction_name ("modI", parse_instruction, code_remI ); put_instruction_name ("mulI", parse_instruction, code_mulI ); put_instruction_name ("mulR", parse_instruction, code_mulR ); +#ifdef I486 + put_instruction_name ("negI", parse_instruction, code_negI ); +#endif put_instruction_name ("negR", parse_instruction, code_negR ); put_instruction_name ("new_ext_reducer",parse_instruction_a_n, code_new_ext_reducer ); put_instruction_name ("new_int_reducer",parse_instruction_a_n, code_new_int_reducer ); @@ -1911,6 +1926,9 @@ static void put_instructions_in_table2 (void) put_instruction_name ("randomP", parse_instruction, code_randomP ); put_instruction_name ("release", parse_instruction, code_release ); put_instruction_name ("remI", parse_instruction, code_remI ); +#ifdef I486 + put_instruction_name ("remU", parse_instruction, code_remU ); +#endif put_instruction_name ("replace", parse_instruction_a_n_n, code_replace ); put_instruction_name ("repl_arg", parse_instruction_n_n, code_repl_arg ); put_instruction_name ("repl_args", parse_instruction_n_n, code_repl_args ); @@ -1270,6 +1270,13 @@ static void w_as_tst_instruction (struct instruction *instruction,int size_flag) } } +static void w_as_monadic_instruction (struct instruction *instruction,char *opcode) +{ + w_as_opcode (opcode); + w_as_register (instruction->instruction_parameters[0].parameter_data.reg.r); + w_as_newline(); +} + static void w_as_btst_instruction (struct instruction *instruction) { if (instruction->instruction_parameters[1].parameter_type==P_REGISTER){ @@ -1378,7 +1385,7 @@ static void as_test_floating_point_condition_code (int n) fprintf (assembly_file,intel_asm ? "\tand\tah,69\n\tdec\tah\n\tcmp\tah,64\n" : "\tandb\t$69,%%ah\n\tdecb\t%%ah\n\tcmpb\t$64,%%ah\n"); break; case 5: - fprintf (assembly_file,intel_asm ? "\tand\tah,5\n" : "\tand\t5,%%ah\n"); + fprintf (assembly_file,intel_asm ? "\tand\tah,5\n" : "\tand\t$5,%%ah\n"); break; } } @@ -1687,7 +1694,7 @@ static void w_as_div_rem_i_instruction (struct instruction *instruction,int comp } } -static void w_as_div_instruction (struct instruction *instruction) +static void w_as_div_instruction (struct instruction *instruction,int unsigned_div) { int d_reg; @@ -1697,8 +1704,8 @@ static void w_as_div_instruction (struct instruction *instruction) int i,log2i; i=instruction->instruction_parameters[0].parameter_data.i; - - if ((i & (i-1))==0 && i>0){ + + if (unsigned_div==0 && (i & (i-1))==0 && i>0){ if (i==1) return; @@ -1729,19 +1736,24 @@ static void w_as_div_instruction (struct instruction *instruction) w_as_immediate_register_newline (log2i,d_reg); return; - } else { - internal_error_in_function ("w_as_div_instruction"); - return; } + + internal_error_in_function ("w_as_div_instruction"); + return; } switch (d_reg){ case REGISTER_D0: w_as_movl_register_register_newline (REGISTER_A1,REGISTER_O0); - - w_as_instruction_without_parameters ("cdq"); - - w_as_opcode (intel_asm ? "idiv" : "idivl"); + + if (unsigned_div){ + w_as_opcode_register_register_newline ("xor",REGISTER_A1,REGISTER_A1); + w_as_opcode (intel_asm ? "div" : "divl"); + } else { + w_as_instruction_without_parameters ("cdq"); + w_as_opcode (intel_asm ? "idiv" : "idivl"); + } + if (instruction->instruction_parameters[0].parameter_type==P_REGISTER && instruction->instruction_parameters[0].parameter_data.reg.r==REGISTER_A1) { @@ -1765,9 +1777,13 @@ static void w_as_div_instruction (struct instruction *instruction) w_as_movl_register_register_newline (REGISTER_A1,REGISTER_D0); - w_as_instruction_without_parameters ("cdq"); - - w_as_opcode (intel_asm ? "idiv" : "idivl"); + if (unsigned_div){ + w_as_opcode_register_register_newline ("xor",REGISTER_A1,REGISTER_A1); + w_as_opcode (intel_asm ? "div" : "divl"); + } else { + w_as_instruction_without_parameters ("cdq"); + w_as_opcode (intel_asm ? "idiv" : "idivl"); + } if (instruction->instruction_parameters[0].parameter_type==P_REGISTER){ int r; @@ -1805,9 +1821,13 @@ static void w_as_div_instruction (struct instruction *instruction) w_as_opcode_register_register_newline ("xchg",REGISTER_D0,d_reg); - w_as_instruction_without_parameters ("cdq"); - - w_as_opcode (intel_asm ? "idiv" : "idivl"); + if (unsigned_div){ + w_as_opcode_register_register_newline ("xor",REGISTER_A1,REGISTER_A1); + w_as_opcode (intel_asm ? "div" : "divl"); + } else { + w_as_instruction_without_parameters ("cdq"); + w_as_opcode (intel_asm ? "idiv" : "idivl"); + } if (instruction->instruction_parameters[0].parameter_type==P_REGISTER){ int r; @@ -1846,13 +1866,13 @@ static void w_as_div_instruction (struct instruction *instruction) } } -static void w_as_rem_instruction (struct instruction *instruction) +static void w_as_rem_instruction (struct instruction *instruction,int unsigned_rem) { int d_reg; d_reg=instruction->instruction_parameters[1].parameter_data.reg.r; - if (instruction->instruction_parameters[0].parameter_type==P_IMMEDIATE){ + if (instruction->instruction_parameters[0].parameter_type==P_IMMEDIATE && unsigned_rem==0){ int i,log2i; i=instruction->instruction_parameters[0].parameter_data.i; @@ -1903,9 +1923,14 @@ static void w_as_rem_instruction (struct instruction *instruction) case REGISTER_D0: w_as_movl_register_register_newline (REGISTER_A1,REGISTER_O0); - w_as_instruction_without_parameters ("cdq"); + if (unsigned_rem){ + w_as_opcode_register_register_newline ("xor",REGISTER_A1,REGISTER_A1); + w_as_opcode (intel_asm ? "div" : "divl"); + } else { + w_as_instruction_without_parameters ("cdq"); + w_as_opcode (intel_asm ? "idiv" : "idivl"); + } - w_as_opcode ("idivl"); if (instruction->instruction_parameters[0].parameter_type==P_REGISTER && instruction->instruction_parameters[0].parameter_data.reg.r==REGISTER_A1) { @@ -1932,9 +1957,13 @@ static void w_as_rem_instruction (struct instruction *instruction) w_as_movl_register_register_newline (REGISTER_A1,REGISTER_D0); - w_as_instruction_without_parameters ("cdq"); - - w_as_opcode ("idivl"); + if (unsigned_rem){ + w_as_opcode_register_register_newline ("xor",REGISTER_A1,REGISTER_A1); + w_as_opcode (intel_asm ? "div" : "divl"); + } else { + w_as_instruction_without_parameters ("cdq"); + w_as_opcode (intel_asm ? "idiv" : "idivl"); + } if (instruction->instruction_parameters[0].parameter_type==P_REGISTER){ int r; @@ -1970,9 +1999,13 @@ static void w_as_rem_instruction (struct instruction *instruction) w_as_opcode_register_register_newline ("xchg",REGISTER_D0,d_reg); - w_as_instruction_without_parameters ("cdq"); - - w_as_opcode (intel_asm ? "idiv" : "idivl"); + if (unsigned_rem){ + w_as_opcode_register_register_newline ("xor",REGISTER_A1,REGISTER_A1); + w_as_opcode (intel_asm ? "div" : "divl"); + } else { + w_as_instruction_without_parameters ("cdq"); + w_as_opcode (intel_asm ? "idiv" : "idivl"); + } if (instruction->instruction_parameters[0].parameter_type==P_REGISTER){ int r; @@ -2174,7 +2207,7 @@ static void fstpl_instruction (int reg0,struct instruction *instruction) return; } /* else */ - case IFSQRT: case IFNEG: case IFSIN: case IFCOS: + case IFSQRT: case IFNEG: case IFABS: case IFSIN: case IFCOS: if (next_fp_instruction->instruction_parameters[0].parameter_type==P_F_REGISTER && next_fp_instruction->instruction_parameters[0].parameter_data.reg.r==reg0) { @@ -2691,9 +2724,42 @@ static int int_to_real_scratch_imported=0; static void w_as_fmovel_instruction (struct instruction *instruction) { - if (instruction->instruction_parameters[0].parameter_type==P_F_REGISTER) - internal_error_in_function ("w_as_fmovel_instruction"); - else { + if (instruction->instruction_parameters[0].parameter_type==P_F_REGISTER){ + if (instruction->instruction_parameters[1].parameter_type==P_REGISTER){ + int s_freg; + + if (intel_asm && !int_to_real_scratch_imported){ + w_as_opcode ("extrn"); + fprintf (assembly_file,"%s:near\n","int_to_real_scratch"); + int_to_real_scratch_imported=1; + } + + s_freg=instruction->instruction_parameters[0].parameter_data.reg.r; + if (s_freg!=0){ + w_as_opcode ("fld"); + w_as_fp_register (s_freg); + w_as_newline(); + + w_as_opcode (!intel_asm ? "fistpl" : "fistp"); + } else + w_as_opcode (!intel_asm ? "fistl" : "fist"); + if (intel_asm) + fprintf (assembly_file,"dword ptr "); + w_as_label ("int_to_real_scratch"); + w_as_newline(); + + w_as_opcode_movl(); + if (intel_asm){ + w_as_register_comma (instruction->instruction_parameters[1].parameter_data.reg.r); + fprintf (assembly_file,"dword ptr "); + } + w_as_label ("int_to_real_scratch"); + if (!intel_asm) + w_as_comma_register (instruction->instruction_parameters[1].parameter_data.reg.r); + w_as_newline(); + } else + internal_error_in_function ("w_as_fmovel_instruction"); + } else { switch (instruction->instruction_parameters[0].parameter_type){ case P_REGISTER: if (intel_asm && !int_to_real_scratch_imported){ @@ -2877,21 +2943,30 @@ static void w_as_instructions (register struct instruction *instruction) case IBGE: w_as_branch_instruction (instruction,"jge"); break; + case IBGEU: + w_as_branch_instruction (instruction,"jae"); + break; case IBGT: w_as_branch_instruction (instruction,"jg"); break; + case IBGTU: + w_as_branch_instruction (instruction,"ja"); + break; case IBLE: w_as_branch_instruction (instruction,"jle"); break; + case IBLEU: + w_as_branch_instruction (instruction,"jbe"); + break; case IBLT: w_as_branch_instruction (instruction,"jl"); break; + case IBLTU: + w_as_branch_instruction (instruction,"jb"); + break; case IBNE: w_as_branch_instruction (instruction,"jne"); break; - case IBHS: - w_as_branch_instruction (instruction,"jae"); - break; case IBO: w_as_branch_instruction (instruction,"jo"); break; @@ -2911,17 +2986,23 @@ static void w_as_instructions (register struct instruction *instruction) w_as_dyadic_instruction (instruction,intel_asm ? "imul" : "imull"); break; case IDIV: - w_as_div_instruction (instruction); + w_as_div_instruction (instruction,0); break; case IDIVI: w_as_div_rem_i_instruction (instruction,0); break; + case IDIVU: + w_as_div_instruction (instruction,1); + break; case IMOD: - w_as_rem_instruction (instruction); + w_as_rem_instruction (instruction,0); break; case IREMI: w_as_div_rem_i_instruction (instruction,1); break; + case IREMU: + w_as_rem_instruction (instruction,1); + break; case IAND: w_as_dyadic_instruction (instruction,intel_asm ? "and" : "andl"); break; @@ -2937,15 +3018,27 @@ static void w_as_instructions (register struct instruction *instruction) case ISGE: w_as_set_condition_instruction (instruction,"setge"); break; + case ISGEU: + w_as_set_condition_instruction (instruction,"setae"); + break; case ISGT: w_as_set_condition_instruction (instruction,"setg"); break; + case ISGTU: + w_as_set_condition_instruction (instruction,"seta"); + break; case ISLE: w_as_set_condition_instruction (instruction,"setle"); break; + case ISLEU: + w_as_set_condition_instruction (instruction,"setbe"); + break; case ISLT: w_as_set_condition_instruction (instruction,"setl"); break; + case ISLTU: + w_as_set_condition_instruction (instruction,"setb"); + break; case ISNE: w_as_set_condition_instruction (instruction,"setne"); break; @@ -2973,6 +3066,12 @@ static void w_as_instructions (register struct instruction *instruction) case IEXG: w_as_dyadic_instruction (instruction,"xchg"); break; + case INEG: + w_as_monadic_instruction (instruction,intel_asm ? "neg" : "negl"); + break; + case INOT: + w_as_monadic_instruction (instruction,intel_asm ? "not" : "notl"); + break; case IFMOVE: instruction=w_as_fmove_instruction (instruction); break; @@ -3028,6 +3127,9 @@ static void w_as_instructions (register struct instruction *instruction) case IFNEG: w_as_monadic_float_instruction (instruction,"fchs"); break; + case IFABS: + w_as_monadic_float_instruction (instruction,"fabs"); + break; case IFSIN: w_as_monadic_float_instruction (instruction,"fsin"); break; @@ -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; @@ -40,9 +40,10 @@ # define IF_G_RISC(a) #endif -#define POWER_PC_A_STACK_OPTIMIZE +#define for_l(v,l,n) for(v=(l);v!=NULL;v=v->n) -#define for_all(v,l,n) for(v=(l);v!=NULL;v=v->n) +#define POWER_PC_A_STACK_OPTIMIZE +#undef OPTIMIZE_LOOPS #pragma segment Code4 @@ -50,12 +51,14 @@ extern struct basic_block *first_block; -static void optimize_branch_jump - (struct instruction *branch,struct instruction *jump,struct basic_block *jump_block) +#ifdef OPTIMIZE_LOOPS +extern LABEL *new_local_label (int label_flags); +#endif + +static void optimize_branch_jump (struct instruction *branch,LABEL *new_branch_label) { - branch->instruction_parameters[0].parameter_data.l= - jump->instruction_parameters[0].parameter_data.l; - + branch->instruction_parameters[0].parameter_data.l=new_branch_label; + switch (branch->instruction_icode){ case IBEQ: branch->instruction_icode=IBNE; break; case IBGE: branch->instruction_icode=IBLT; break; @@ -63,6 +66,10 @@ static void optimize_branch_jump case IBLE: branch->instruction_icode=IBGT; break; case IBLT: branch->instruction_icode=IBGE; break; case IBNE: branch->instruction_icode=IBEQ; break; + case IBGEU: branch->instruction_icode=IBLTU; break; + case IBGTU: branch->instruction_icode=IBLEU; break; + case IBLEU: branch->instruction_icode=IBGTU; break; + case IBLTU: branch->instruction_icode=IBGEU; break; case IFBEQ: branch->instruction_icode=IFBNE; break; case IFBGE: branch->instruction_icode=IFBLT; break; case IFBGT: branch->instruction_icode=IFBLE; break; @@ -70,20 +77,41 @@ static void optimize_branch_jump case IFBLT: branch->instruction_icode=IFBGE; break; case IFBNE: branch->instruction_icode=IFBEQ; } - - jump_block->block_instructions=NULL; } -void optimize_jumps() +#ifdef OPTIMIZE_LOOPS +static LABEL *get_label_of_block (struct basic_block *block) +{ + if (block->block_labels!=NULL) + return block->block_labels->block_label_label; + else { + struct block_label *new_block_label; + LABEL *new_jmp_label; + + new_jmp_label=new_local_label (0); + + new_block_label=fast_memory_allocate_type (struct block_label); + new_block_label->block_label_label=new_jmp_label; + new_block_label->block_label_next=NULL; + + block->block_labels=new_block_label; + + return new_jmp_label; + } +} +#endif + +void optimize_jumps (void) { struct basic_block *block; - for_all (block,first_block,block_next){ + for_l (block,first_block,block_next){ struct instruction *branch; if ((branch=block->block_last_instruction)!=NULL){ switch (branch->instruction_icode){ - case IBEQ: case IBGE: case IBGT: case IBLE: case IBLT: case IBNE: + case IBEQ: case IBGE: case IBGT: case IBLE: case IBLT: + case IBNE: case IBGEU: case IBGTU: case IBLEU: case IBLTU: case IFBEQ: case IFBGE: case IFBGT: case IFBLE: case IFBLT: case IFBNE: { struct basic_block *next_block; @@ -110,25 +138,54 @@ void optimize_jumps() #endif ) { - for ( block_labels=next_next_block->block_labels; - block_labels!=NULL; - block_labels=block_labels->block_label_next - ) + for_l (block_labels,next_next_block->block_labels,block_label_next) if (block_labels->block_label_label==branch_label){ - optimize_branch_jump (branch,jump,next_block); + optimize_branch_jump (branch,jump->instruction_parameters[0].parameter_data.l); + next_block->block_instructions=NULL; +#ifdef OPTIMIZE_LOOPS + next_block->block_last_instruction=NULL; +#endif break; } } } } } + +#ifdef OPTIMIZE_LOOPS + { + struct instruction *cmp_instruction; + + cmp_instruction=block->block_instructions; + if (cmp_instruction->instruction_icode==ICMP && cmp_instruction->instruction_next==branch + && (cmp_instruction->instruction_parameters[0].parameter_type==P_IMMEDIATE || + cmp_instruction->instruction_parameters[0].parameter_type==P_REGISTER || + (cmp_instruction->instruction_parameters[0].parameter_type==P_INDIRECT && + cmp_instruction->instruction_parameters[1].parameter_type==P_REGISTER)) + && (cmp_instruction->instruction_parameters[1].parameter_type==P_REGISTER || + cmp_instruction->instruction_parameters[1].parameter_type==P_INDIRECT) + ){ + struct block_label *block_label; + + for_l (block_label,block->block_labels,block_label_next){ + LABEL *label; + + label=block_label->block_label_label; + label->label_flags |= CMP_BRANCH_BLOCK_LABEL; + label->label_block = block; + } + } + } +#endif break; } case IJMP: { struct basic_block *next_block; - - if ((next_block=block->block_next)!=NULL){ + + if (branch->instruction_parameters[0].parameter_type==P_LABEL + && (next_block=block->block_next)!=NULL) + { struct block_label *labels; LABEL *jmp_label; @@ -144,7 +201,14 @@ void optimize_jumps() if (branch->instruction_prev!=NULL) branch->instruction_prev->instruction_next=NULL; else +#ifdef OPTIMIZE_LOOPS + { + block->block_instructions=NULL; + block->block_last_instruction=NULL; + } +#else block->block_instructions=NULL; +#endif break; } } @@ -187,6 +251,140 @@ void optimize_jumps() } } } + +#ifdef OPTIMIZE_LOOPS + for_l (block,first_block,block_next){ + struct instruction *branch; + + if ((branch=block->block_last_instruction)!=NULL && + branch->instruction_icode==IJMP && branch->instruction_parameters[0].parameter_type==P_LABEL) + { + LABEL *jmp_label; + + jmp_label=branch->instruction_parameters[0].parameter_data.l; + if (jmp_label->label_flags & CMP_BRANCH_BLOCK_LABEL){ + struct basic_block *jmp_block,*jmp_next_block; + struct block_label *branch_block_label,*branch_next_block_label; + struct instruction *old_cmp_instruction,*old_branch_instruction,*new_branch_instruction; + LABEL *branch_label,*new_jmp_label; +# ifdef I486 + struct instruction *previous_instruction; +# endif + + jmp_block=jmp_label->label_block; + old_cmp_instruction=jmp_block->block_instructions; + jmp_next_block=jmp_block->block_next; + old_branch_instruction=old_cmp_instruction->instruction_next; + + branch_label=old_branch_instruction->instruction_parameters[0].parameter_data.l; + + branch_next_block_label=NULL; + if (block->block_next!=NULL) + for_l (branch_next_block_label,block->block_next->block_labels,block_label_next) + if (branch_next_block_label->block_label_label==branch_label) + break; + + branch_block_label=NULL; + if (branch_next_block_label==NULL) + for_l (branch_block_label,block->block_labels,block_label_next) + if (branch_block_label->block_label_label==branch_label) + break; + +# ifdef I486 + if (old_cmp_instruction->instruction_parameters[0].parameter_type==P_IMMEDIATE && + old_cmp_instruction->instruction_parameters[0].parameter_data.i==0 && + old_cmp_instruction->instruction_parameters[1].parameter_type==P_REGISTER && + (previous_instruction=branch->instruction_prev)!=NULL && + (previous_instruction->instruction_icode==ISUB || previous_instruction->instruction_icode==IADD) && + previous_instruction->instruction_parameters[1].parameter_type==P_REGISTER && + old_cmp_instruction->instruction_parameters[1].parameter_data.reg.r==previous_instruction->instruction_parameters[1].parameter_data.reg.r) + { + new_jmp_label = get_label_of_block (jmp_next_block); + + if (branch_next_block_label!=NULL){ + branch->instruction_icode=old_branch_instruction->instruction_icode; + branch->instruction_parameters[0]=old_branch_instruction->instruction_parameters[0]; + + optimize_branch_jump (branch,new_jmp_label); + } else { + new_branch_instruction=(struct instruction*)fast_memory_allocate (sizeof (struct instruction)+sizeof (struct parameter)); + + new_branch_instruction->instruction_icode=old_branch_instruction->instruction_icode; + new_branch_instruction->instruction_arity=1; + new_branch_instruction->instruction_parameters[0]=old_branch_instruction->instruction_parameters[0]; + + if (block->block_instructions==branch){ + block->block_instructions=new_branch_instruction; + new_branch_instruction->instruction_prev=NULL; + } else { + struct instruction *previous_instruction; + + previous_instruction=branch->instruction_prev; + previous_instruction->instruction_next=new_branch_instruction; + new_branch_instruction->instruction_prev=previous_instruction; + } + new_branch_instruction->instruction_next=branch; + + branch->instruction_prev=new_branch_instruction; + + branch->instruction_parameters[0].parameter_data.l=new_jmp_label; + } + } else +# endif + + if (branch_next_block_label!=NULL || branch_block_label!=NULL){ + struct instruction *new_cmp_instruction; + + new_cmp_instruction=(struct instruction*)fast_memory_allocate (sizeof (struct instruction)+2*sizeof (struct parameter)); + + new_cmp_instruction->instruction_icode=ICMP; + new_cmp_instruction->instruction_arity=2; + new_cmp_instruction->instruction_parameters[0]=old_cmp_instruction->instruction_parameters[0]; + new_cmp_instruction->instruction_parameters[1]=old_cmp_instruction->instruction_parameters[1]; + + if (block->block_instructions==branch){ + block->block_instructions=new_cmp_instruction; + new_cmp_instruction->instruction_prev=NULL; + } else { + struct instruction *previous_instruction; + + previous_instruction=branch->instruction_prev; + previous_instruction->instruction_next=new_cmp_instruction; + new_cmp_instruction->instruction_prev=previous_instruction; + } + + new_jmp_label = get_label_of_block (jmp_next_block); + + if (branch_next_block_label!=NULL){ + branch->instruction_icode=old_branch_instruction->instruction_icode; + branch->instruction_parameters[0]=old_branch_instruction->instruction_parameters[0]; + + optimize_branch_jump (branch,new_jmp_label); + + new_cmp_instruction->instruction_next=branch; + + branch->instruction_prev=new_cmp_instruction; + } else { + new_branch_instruction=(struct instruction*)fast_memory_allocate (sizeof (struct instruction)+sizeof (struct parameter)); + + new_branch_instruction->instruction_icode=old_branch_instruction->instruction_icode; + new_branch_instruction->instruction_arity=1; + new_branch_instruction->instruction_parameters[0]=old_branch_instruction->instruction_parameters[0]; + + new_cmp_instruction->instruction_next=new_branch_instruction; + + new_branch_instruction->instruction_prev=new_cmp_instruction; + new_branch_instruction->instruction_next=branch; + + branch->instruction_prev=new_branch_instruction; + + branch->instruction_parameters[0].parameter_data.l=new_jmp_label; + } + } + } + } + } +#endif } #if defined (M68000) || defined (I486) @@ -209,7 +407,7 @@ static int get_argument_size (int instruction_code) IF_G_RISC (case IADDI: case ILSLI:) IF_G_SPARC (case IADDO: case ISUBO: ) #ifdef I486 - case IDIVI: case REMI: + case IDIVI: case IREMI: case IDIVU: case IREMU: #endif IF_G_POWER ( case IUMULH: ) return 4; @@ -221,6 +419,9 @@ IF_G_POWER ( case IUMULH: ) #if !defined (G_POWER) case IFSQRT: #endif +#ifdef I486 + case IFABS: +#endif return 8; default: return 0; @@ -449,7 +650,7 @@ static void compute_maximum_b_stack_offsets (register int b_offset) { struct instruction *instruction; - for_all (instruction,last_instruction,instruction_prev){ + for_l (instruction,last_instruction,instruction_prev){ switch (instruction->instruction_arity){ default: if ( @@ -459,6 +660,7 @@ static void compute_maximum_b_stack_offsets (register int b_offset) #ifdef I486 instruction->instruction_icode!=IDIVI && instruction->instruction_icode!=IREMI && + instruction->instruction_icode!=IREMU && #endif instruction->instruction_icode!=IMOD) #ifdef M68000 @@ -511,7 +713,7 @@ void optimize_stack_access (struct basic_block *block,int *a_offset_p,int *b_off compute_maximum_b_stack_offsets (*b_offset_p); # ifdef M68000 - for_all (instruction,block->block_instructions,instruction_next){ + for_l (instruction,block->block_instructions,instruction_next){ switch (instruction->instruction_arity){ default: if ( @@ -594,7 +796,7 @@ void optimize_stack_access (struct basic_block *block,int *a_offset_p,int *b_off # endif # ifdef I486 - for_all (instruction,block->block_instructions,instruction_next){ + for_l (instruction,block->block_instructions,instruction_next){ if (instruction->instruction_icode==IMOVE){ if (instruction->instruction_parameters[0].parameter_type==P_INDIRECT && instruction->instruction_parameters[0].parameter_data.reg.r==B_STACK_POINTER) @@ -692,6 +894,7 @@ void optimize_stack_access (struct basic_block *block,int *a_offset_p,int *b_off default: if (instruction->instruction_icode!=IDIVI && instruction->instruction_icode!=IREMI && + instruction->instruction_icode!=IREMU && instruction->instruction_icode!=IMOD) internal_error_in_function ("optimize_stack_access"); /* only first argument of mod might be register indirect */ @@ -722,7 +925,7 @@ void optimize_stack_access (struct basic_block *block,int *a_offset_p,int *b_off # endif # ifdef OLDI486 - for_all (instruction,block->block_instructions,instruction_next){ + for_l (instruction,block->block_instructions,instruction_next){ if (instruction->instruction_icode==IMOVE){ if (instruction->instruction_parameters[0].parameter_type==P_INDIRECT && instruction->instruction_parameters[0].parameter_data.reg.r==B_STACK_POINTER && @@ -799,8 +1002,8 @@ void optimize_stack_access (struct basic_block *block,int *a_offset_p,int *b_off if (a_offset==0) return; - - for_all (instruction,block->block_instructions,instruction_next){ + + for_l (instruction,block->block_instructions,instruction_next){ if (instruction->instruction_icode==IMOVE){ if (instruction->instruction_parameters[0].parameter_type==P_INDIRECT && instruction->instruction_parameters[0].parameter_data.reg.r==A_STACK_POINTER && @@ -1302,6 +1505,9 @@ static void store_next_uses (struct instruction *instruction) #ifndef I486_USE_SCRATCH_REGISTER case IASR: case ILSL: case ILSR: case IDIV: +# ifdef I486 + case IDIVU: +# endif case ICMPW: #endif case IEOR: case IFADD: @@ -1331,7 +1537,7 @@ IF_G_POWER ( case IUMULH: ) use_parameter (&instruction->instruction_parameters[1]); use_parameter (&instruction->instruction_parameters[0]); break; - case IDIV: case IMOD: + case IDIV: case IMOD: case IDIVU: case IREMU: define_scratch_register(); use_parameter (&instruction->instruction_parameters[1]); use_parameter (&instruction->instruction_parameters[0]); @@ -1368,6 +1574,9 @@ IF_G_POWER ( case IUMULH: ) #if !defined (G_POWER) case IFSQRT: #endif +#ifdef I486 + case IFABS: +#endif IF_G_SPARC (case IFMOVEHI: case IFMOVELO:) IF_G_RISC (case IADDI: case ILSLI:) define_parameter (&instruction->instruction_parameters[1]); @@ -1382,7 +1591,7 @@ IF_G_RISC (case IADDI: case ILSLI:) break; case IFSEQ: case IFSGE: case IFSGT: case IFSLE: case IFSLT: case IFSNE: case ISEQ: case ISGE: case ISGT: case ISLE: case ISLT: case ISNE: - case ISO: case ISNO: + case ISO: case ISGEU: case ISGTU: case ISLEU: case ISLTU: case ISNO: #ifdef I486_USE_SCRATCH_REGISTER define_scratch_register(); #endif @@ -1392,6 +1601,9 @@ IF_G_RISC (case IADDI: case ILSLI:) case IMOD: # if defined (I486) || defined (G_POWER) use_parameter (&instruction->instruction_parameters[1]); +# ifdef I486 + case IREMU: +# endif use_parameter (&instruction->instruction_parameters[0]); break; # else @@ -1429,8 +1641,7 @@ IF_G_RISC (case IADDI: case ILSLI:) break; */ case IBEQ: case IBGE: case IBGT: case IBLE: case IBLT: case IBNE: - case IBHS: - case IBO: case IBNO: + case IBO: case IBGEU: case IBGTU: case IBLEU: case IBLTU: case IBNO: break; default: internal_error_in_function ("store_next_uses"); @@ -3578,6 +3789,9 @@ static void allocate_registers (struct basic_block *basic_block) #ifndef I486_USE_SCRATCH_REGISTER case IASR: case ILSL: case ILSR: case IDIV: +# ifdef I486 + case IDIVU: +# endif #endif case IEOR: case IFADD: case IFCMP: case IFDIV: case IFMUL: case IFREM: case IFSUB: @@ -3593,7 +3807,7 @@ IF_G_POWER ( case IUMULH: ) instruction_use_2 (instruction,USE_DEF); allocate_scratch_register=1; break; - case IDIV: case IMOD: + case IDIV: case IMOD: case IDIVU: case IREMU: use_scratch_register(); instruction_use_2 (instruction,USE_DEF); allocate_scratch_register=1; @@ -3643,6 +3857,9 @@ IF_G_POWER (case ICMPLW:) #if !defined (G_POWER) case IFSQRT: #endif +#ifdef I486 + case IFABS: +#endif IF_G_SPARC (case IFMOVEHI: case IFMOVELO:) IF_G_RISC (case IADDI: case ILSLI:) @@ -3675,7 +3892,7 @@ IF_G_RISC (case IADDI: case ILSLI:) break; } case ISEQ: case ISGE: case ISGT: case ISLE: case ISLT: case ISNE: - case ISO: case ISNO: + case ISO: case ISGEU: case ISGTU: case ISLEU: case ISLTU: case ISNO: #ifdef I486_USE_SCRATCH_REGISTER use_scratch_register(); #endif @@ -3697,6 +3914,9 @@ IF_G_RISC (case IADDI: case ILSLI:) #ifndef I486_USE_SCRATCH_REGISTER case IMOD: # if defined (I486) || defined (G_POWER) +# ifdef I486 + case IREMU: +# endif instruction_use_2 (instruction,USE_DEF); # else instruction_mod_use_def_use (instruction); @@ -3736,8 +3956,7 @@ IF_G_RISC (case IADDI: case ILSLI:) break; */ case IBEQ: case IBGE: case IBGT: case IBLE: case IBLT: case IBNE: - case IBO: case IBNO: - case IBHS: + case IBO: case IBGEU: case IBGTU: case IBLEU: case IBLTU: case IBNO: break; default: internal_error_in_function ("allocate_registers"); @@ -3194,7 +3194,7 @@ int block_stack_displacement; static WORD *check_size_p; #endif -static int stack_access_and_adjust_a_stack_pointer (int extra_b_offset) +static int stack_access_and_adjust_a_stack_pointer (int extra_b_offset,int do_not_alter_condition_codes) { int a_offset,b_offset,minimum_b_offset; @@ -3270,32 +3270,34 @@ static int stack_access_and_adjust_a_stack_pointer (int extra_b_offset) if (a_offset!=0) #ifdef I486 - i_lea_id_r (a_offset,A_STACK_POINTER,A_STACK_POINTER); -#else + if (do_not_alter_condition_codes) + i_lea_id_r (a_offset,A_STACK_POINTER,A_STACK_POINTER); + else +#endif if (a_offset>0) i_add_i_r (a_offset,A_STACK_POINTER); else i_sub_i_r (-a_offset,A_STACK_POINTER); -#endif return b_offset; } -static void stack_access (void) +static void stack_access (int do_not_alter_condition_codes) { register int b_offset; - b_offset=stack_access_and_adjust_a_stack_pointer (0); + b_offset=stack_access_and_adjust_a_stack_pointer (0,do_not_alter_condition_codes); if (b_offset!=0) #ifdef I486 - i_lea_id_r (b_offset,B_STACK_POINTER,B_STACK_POINTER); -#else + if (do_not_alter_condition_codes) + i_lea_id_r (b_offset,B_STACK_POINTER,B_STACK_POINTER); + else +#endif if (b_offset>0) i_add_i_r (b_offset,B_STACK_POINTER); else i_sub_i_r (-b_offset,B_STACK_POINTER); -#endif } static int local_register_allocation_and_adjust_a_stack_pointer (int extra_b_offset) @@ -3304,7 +3306,7 @@ static int local_register_allocation_and_adjust_a_stack_pointer (int extra_b_off get_n_virtual_registers (&n_virtual_a_regs,&n_virtual_d_regs,&n_virtual_f_regs); do_register_allocation (last_instruction,last_block,n_virtual_a_regs,n_virtual_d_regs,n_virtual_f_regs,0,0); - return stack_access_and_adjust_a_stack_pointer (extra_b_offset); + return stack_access_and_adjust_a_stack_pointer (extra_b_offset,0); } void adjust_stack_pointers (void) @@ -3313,7 +3315,7 @@ void adjust_stack_pointers (void) get_n_virtual_registers (&n_virtual_a_regs,&n_virtual_d_regs,&n_virtual_f_regs); do_register_allocation (last_instruction,last_block,n_virtual_a_regs,n_virtual_d_regs,n_virtual_f_regs,0,0); - stack_access(); + stack_access (0); } int adjust_stack_pointers_without_altering_condition_codes (int float_condition,int condition) @@ -3322,7 +3324,7 @@ int adjust_stack_pointers_without_altering_condition_codes (int float_condition, get_n_virtual_registers (&n_virtual_a_regs,&n_virtual_d_regs,&n_virtual_f_regs); condition_on_stack=do_register_allocation (last_instruction,last_block,n_virtual_a_regs,n_virtual_d_regs,n_virtual_f_regs,1+float_condition,condition); - stack_access(); + stack_access (1); return condition_on_stack; } @@ -3755,14 +3757,10 @@ static void generate_code_for_basic_block (struct block_graph *next_block_graph) } #else if (b_offset!=0) -# ifdef I486 - i_lea_id_r (b_offset,B_STACK_POINTER,B_STACK_POINTER); -# else if (b_offset<0) i_sub_i_r (-b_offset,B_STACK_POINTER); else i_add_i_r (b_offset,B_STACK_POINTER); -# endif # if ! defined (sparc) { @@ -4187,14 +4185,10 @@ void end_basic_block_with_registers (int n_a_parameters,int n_b_parameters,ULONG b_offset=end_basic_block_with_registers_and_return_b_stack_offset (n_a_parameters,n_b_parameters,vector,N_ADDRESS_PARAMETER_REGISTERS); if (b_offset!=0) -#ifdef I486 - i_lea_id_r (b_offset,B_STACK_POINTER,B_STACK_POINTER); -#else if (b_offset>0) i_add_i_r (b_offset,B_STACK_POINTER); else i_sub_i_r (-b_offset,B_STACK_POINTER); -#endif } void end_stack_elements (int n_a_parameters,int n_b_parameters,ULONG vector[]) @@ -36,6 +36,7 @@ typedef struct label { } label_u1; union { struct basic_block * u_last_lea_block; /* cgcode.c */ + struct basic_block * u_block; /* cgopt.c */ #ifdef G_POWER struct toc_label * u_toc_labels; /* cgpwas.c */ #endif @@ -43,7 +44,8 @@ typedef struct label { WORD label_last_lea_arity; } LABEL; -#define label_last_lea_block label_u2.u_last_lea_block +#define label_last_lea_block label_u2.u_last_lea_block +#define label_block label_u2.u_block #ifdef G_POWER # define label_toc_labels label_u2.u_toc_labels #endif @@ -66,6 +68,7 @@ typedef struct label { # define DOT_O_BEFORE_LABEL 2048 # define STUB_GENERATED 4096 #endif +#define CMP_BRANCH_BLOCK_LABEL 8192 struct label_node { struct label_node * label_node_left; |