diff options
-rw-r--r-- | cgcalc.c | 12 | ||||
-rw-r--r-- | cgcode.c | 20 | ||||
-rw-r--r-- | cgcodep.h | 3 | ||||
-rw-r--r-- | cgconst.h | 2 | ||||
-rw-r--r-- | cgiconst.h | 5 | ||||
-rw-r--r-- | cginput.c | 3 | ||||
-rw-r--r-- | cglin.c | 5 | ||||
-rw-r--r-- | cgopt.c | 3 | ||||
-rw-r--r-- | cgpas.c | 15 | ||||
-rw-r--r-- | cgpwas.c | 18 |
10 files changed, 84 insertions, 2 deletions
@@ -2258,6 +2258,9 @@ void calculate_graph_register_uses (INSTRUCTION_GRAPH graph) case GOR: case GMUL: case GMUL_O: +#ifdef G_POWER + case GUMULH: +#endif calculate_dyadic_commutative_data_operator (graph); return; case GCMP_EQ: @@ -2488,6 +2491,9 @@ void count_graph (INSTRUCTION_GRAPH graph) case GASR: case GCOPY: case GBOUNDS: +#ifdef G_POWER + case GUMULH: +#endif if (++graph->node_count==1){ count_graph (graph->instruction_parameters[0].p); count_graph (graph->instruction_parameters[1].p); @@ -2637,6 +2643,9 @@ void mark_graph_2 (register INSTRUCTION_GRAPH graph) case GASR: case GCOPY: case GBOUNDS: +#ifdef G_POWER + case GUMULH: +#endif if (graph->node_mark<2){ graph->node_mark=2; mark_graph_2 (graph->instruction_parameters[0].p); @@ -2801,6 +2810,9 @@ void mark_graph_1 (register INSTRUCTION_GRAPH graph) case GASR: case GCOPY: case GBOUNDS: +#ifdef G_POWER + case GUMULH: +#endif if (!graph->node_mark){ graph->node_mark=1; mark_graph_2 (graph->instruction_parameters[0].p); @@ -185,6 +185,10 @@ int no_time_profiling; #define g_fkeep(g1,g2) g_instruction_2(GFKEEP,(g1),(g2)) #define g_sub(g1,g2) g_instruction_2(GSUB,(g1),(g2)) +#ifdef G_POWER +# define g_umulh(g1,g2) g_instruction_2(GUMULH,(g1),(g2)) +#endif + #define MAX_YET_ARGS_NEEDED_ARITY 4 LABEL *INT_label,*BOOL_label,*CHAR_label,*REAL_label; @@ -4142,6 +4146,22 @@ void code_mulI (VOID) #endif } +#ifdef G_POWER +void code_umulIIL (VOID) +{ + INSTRUCTION_GRAPH graph_1,graph_2,graph_3,graph_4; + + graph_1=s_get_b (1); + graph_2=s_get_b (0); + + graph_3=g_mul (graph_1,graph_2); + graph_4=g_umulh (graph_1,graph_2); + + s_put_b (1,graph_3); + s_put_b (0,graph_4); +} +#endif + #ifndef M68000 void code_mulIo (VOID) { @@ -243,6 +243,9 @@ void code_updatepop_a (int a_offset_1,int a_offset_2); void code_update_b (int b_offset_1,int b_offset_2); void code_updatepop_b (int b_offset_1,int b_offset_2); void code_updateS (int source_offset,int destination_offset); +#ifdef G_POWER +void code_umulIIL (VOID); +#endif void code_xor (VOID); void code_caf (char *label_name,int a_size,int b_size); @@ -15,7 +15,7 @@ enum { 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 + ,GCREATE_S, GUMULH #endif }; @@ -52,7 +52,10 @@ enum { ,IFEXG #endif #if defined (I486) - ,IRTSI, IDIVI, IREMI + ,IRTSI, IDIVI, IREMI +#endif +#ifdef G_POWER + ,IUMULH #endif }; @@ -1952,6 +1952,9 @@ static void put_instructions_in_table2 (void) put_instruction_name ("updatepop_b", parse_instruction_n_n, code_updatepop_b ); put_instruction_name ("updateS", parse_instruction_n_n, code_updateS ); put_instruction_name ("update", parse_instruction_a_n_n, code_update ); +#ifdef G_POWER + put_instruction_name ("umulIIL", parse_instruction, code_umulIIL ); +#endif put_instruction_name ("xor%", parse_instruction, code_xor ); put_instruction_name (".caf", parse_instruction_a_n_n, code_caf ); put_instruction_name (".code", parse_directive_n_n_n, code_dummy ); @@ -7600,6 +7600,11 @@ static void linearize_graph (INSTRUCTION_GRAPH graph,ADDRESS *ad_p) case GTEST_O: linearize_test_o_operator (graph,ad_p); return; +#ifdef G_POWER + case GUMULH: + linearize_dyadic_commutative_data_operator (IUMULH,graph,ad_p); + return; +#endif default: /* printf ("%d %d\n",(int)graph,graph->instruction_code); */ internal_error_in_function ("linearize_graph"); @@ -211,6 +211,7 @@ IF_G_SPARC (case IADDO: case ISUBO: ) #ifdef I486 case IDIVI: case REMI: #endif +IF_G_POWER ( case IUMULH: ) return 4; case IFADD: case IFCMP: case IFDIV: case IFMUL: case IFREM: case IFSUB: case IFTST: case IFMOVE: @@ -1312,6 +1313,7 @@ IF_G_SPARC (case IADDO: case ISUBO:) #if defined (I486) && defined (FP_STACK_OPTIMIZATIONS) case IFEXG: #endif +IF_G_POWER ( case IUMULH: ) use_parameter (&instruction->instruction_parameters[1]); use_parameter (&instruction->instruction_parameters[0]); break; @@ -3581,6 +3583,7 @@ static void allocate_registers (struct basic_block *basic_block) case IFADD: case IFCMP: case IFDIV: case IFMUL: case IFREM: case IFSUB: case IMUL: case IOR: case ISUB: IF_G_SPARC (case IADDO: case ISUBO:) +IF_G_POWER ( case IUMULH: ) instruction_use_2 (instruction,USE_DEF); break; #ifdef I486_USE_SCRATCH_REGISTER @@ -547,6 +547,7 @@ static unsigned char real_reg_num [32] = #define as_mtctr(rs) as_mtspr (9,rs) #define as_mtspr(spr,rs) store_instruction ((31<<26)|(reg_num(rs)<<21)|(spr<<16)|(467<<1)); #define as_mulhw(rd,ra,rb) as_i_dab (rd,ra,rb,75) +#define as_mulhwu(rd,ra,rb) as_i_dab (rd,ra,rb,11) #define as_mulli(rd,ra,si) as_i_dai (7,rd,ra,si) #define as_mullw(rd,ra,rb) as_i_dab (rd,ra,rb,235) #define as_mullwo_(rd,ra,rb)as_i_dabo_ (rd,ra,rb,235) @@ -1278,6 +1279,17 @@ static void as_mul_instruction (struct instruction *instruction) as_mullw (r,r,reg); } +static void as_umulh_instruction (struct instruction *instruction) +{ + int r,reg; + + r=instruction->instruction_parameters[1].parameter_data.reg.r; + + reg=as_register_parameter (instruction->instruction_parameters[0],SIZE_LONG); + + as_mulhwu (r,r,reg); +} + static void as_mulo_instruction (struct instruction *instruction) { int r,reg; @@ -2836,6 +2848,9 @@ static void write_instructions (struct instruction *instructions) case IMULO: as_mulo_instruction (instruction); break; + case IUMULH: + as_umulh_instruction (instruction); + break; default: internal_error_in_function ("write_instructions"); } @@ -2259,6 +2259,21 @@ static void w_as_mul_instruction (struct instruction *instruction) w_as_newline(); } +static void w_as_umulh_instruction (struct instruction *instruction) +{ + int r,reg; + + r=instruction->instruction_parameters[1].parameter_data.reg.r; + + reg=w_as_register_parameter (instruction->instruction_parameters[0],SIZE_LONG); + + w_as_opcode ("mulhwu"); + w_as_register_comma (r); + w_as_register_comma (r); + w_as_register (reg); + w_as_newline(); +} + static void w_as_mulo_instruction (struct instruction *instruction) { int r,reg; @@ -3183,6 +3198,9 @@ static void w_as_instructions (register struct instruction *instruction) case IMULO: w_as_mulo_instruction (instruction); break; + case IUMULH: + w_as_umulh_instruction (instruction); + break; case IFTST: default: internal_error_in_function ("w_as_instructions"); |