summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cgcalc.c12
-rw-r--r--cgcode.c20
-rw-r--r--cgcodep.h3
-rw-r--r--cgconst.h2
-rw-r--r--cgiconst.h5
-rw-r--r--cginput.c3
-rw-r--r--cglin.c5
-rw-r--r--cgopt.c3
-rw-r--r--cgpas.c15
-rw-r--r--cgpwas.c18
10 files changed, 84 insertions, 2 deletions
diff --git a/cgcalc.c b/cgcalc.c
index d3f06e7..771457b 100644
--- a/cgcalc.c
+++ b/cgcalc.c
@@ -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);
diff --git a/cgcode.c b/cgcode.c
index f770450..d2dcd98 100644
--- a/cgcode.c
+++ b/cgcode.c
@@ -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)
{
diff --git a/cgcodep.h b/cgcodep.h
index 597a3a8..ad18364 100644
--- a/cgcodep.h
+++ b/cgcodep.h
@@ -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);
diff --git a/cgconst.h b/cgconst.h
index 29d64e6..2553b8c 100644
--- a/cgconst.h
+++ b/cgconst.h
@@ -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
};
diff --git a/cgiconst.h b/cgiconst.h
index 3fcd728..0c06775 100644
--- a/cgiconst.h
+++ b/cgiconst.h
@@ -52,7 +52,10 @@ enum {
,IFEXG
#endif
#if defined (I486)
- ,IRTSI, IDIVI, IREMI
+ ,IRTSI, IDIVI, IREMI
+#endif
+#ifdef G_POWER
+ ,IUMULH
#endif
};
diff --git a/cginput.c b/cginput.c
index ded9c69..ee6bab6 100644
--- a/cginput.c
+++ b/cginput.c
@@ -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 );
diff --git a/cglin.c b/cglin.c
index 5a6cdf1..605951e 100644
--- a/cglin.c
+++ b/cglin.c
@@ -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");
diff --git a/cgopt.c b/cgopt.c
index 9c7241b..bd9a5df 100644
--- a/cgopt.c
+++ b/cgopt.c
@@ -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
diff --git a/cgpas.c b/cgpas.c
index 64d55af..a537926 100644
--- a/cgpas.c
+++ b/cgpas.c
@@ -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");
}
diff --git a/cgpwas.c b/cgpwas.c
index 776cadd..16ce013 100644
--- a/cgpwas.c
+++ b/cgpwas.c
@@ -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");