summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cgias.c103
-rw-r--r--cgiconst.h5
-rw-r--r--cgiwas.c82
-rw-r--r--cglin.c10
-rw-r--r--cgopt.c25
5 files changed, 183 insertions, 42 deletions
diff --git a/cgias.c b/cgias.c
index 031a372..6fe2c87 100644
--- a/cgias.c
+++ b/cgias.c
@@ -3379,15 +3379,103 @@ static void as_xchg_eax_r (int reg_1)
store_c (0x90+reg_num (reg_1)); /* xchg reg_1,D0 */
}
-#ifndef THREAD32
+static void as_xchg (int r1,int r2)
+{
+ if (r1==REGISTER_D0)
+ store_c (0x90+reg_num (r2)); /* xchg r,D0 */
+ else if (r2==REGISTER_D0)
+ store_c (0x90+reg_num (r1)); /* xchg r,D0 */
+ else
+ as_r_r (0207,r1,r2);
+}
+
static void as_divdu_instruction (struct instruction *instruction)
{
int reg_1,reg_2,reg_3;
-
+
reg_1=instruction->instruction_parameters[0].parameter_data.reg.r;
reg_2=instruction->instruction_parameters[1].parameter_data.reg.r;
reg_3=instruction->instruction_parameters[2].parameter_data.reg.r;
+ /* reg_2:reg_3/reg_1, quotient in reg3, remainder in reg_2 */
+
+#ifdef THREAD32
+ if (reg_3==REGISTER_D0){
+ if (reg_2==REGISTER_A1)
+ as_r (0367,0060,reg_1); /* div */
+ else {
+ as_xchg (REGISTER_A1,reg_2);
+ if (reg_1==reg_2)
+ as_r (0367,0060,REGISTER_A1); /* div */
+ else if (reg_1==REGISTER_A1)
+ as_r (0367,0060,reg_2); /* div */
+ else
+ as_r (0367,0060,reg_1); /* div */
+ as_xchg (REGISTER_A1,reg_2);
+ }
+ } else if (reg_3==REGISTER_A1){
+ as_xchg (REGISTER_D0,REGISTER_A1);
+ if (reg_2==REGISTER_D0){
+ if (reg_1==REGISTER_D0)
+ as_r (0367,0060,REGISTER_A1); /* div */
+ else if (reg_1==REGISTER_A1)
+ as_r (0367,0060,REGISTER_D0); /* div */
+ else
+ as_r (0367,0060,reg_1); /* div */
+ } else {
+ as_xchg (REGISTER_A1,reg_2);
+ if (reg_1==reg_2)
+ as_r (0367,0060,REGISTER_A1); /* div */
+ else if (reg_1==REGISTER_D0)
+ as_r (0367,0060,reg_2); /* div */
+ else if (reg_1==REGISTER_A1)
+ as_r (0367,0060,REGISTER_D0); /* div */
+ else
+ as_r (0367,0060,reg_1); /* div */
+ as_xchg (REGISTER_A1,reg_2);
+ }
+ as_xchg (REGISTER_D0,REGISTER_A1);
+ } else {
+ if (reg_2==REGISTER_A1){
+ as_xchg (REGISTER_D0,reg_3);
+ if (reg_1==reg_3)
+ as_r (0367,0060,REGISTER_D0); /* div */
+ else if (reg_1==REGISTER_D0)
+ as_r (0367,0060,reg_3); /* div */
+ else
+ as_r (0367,0060,reg_1); /* div */
+ as_xchg (REGISTER_D0,reg_3);
+ } else if (reg_2==REGISTER_D0){
+ as_xchg (REGISTER_A1,REGISTER_D0);
+ as_xchg (REGISTER_D0,reg_3);
+ if (reg_1==reg_3)
+ as_r (0367,0060,REGISTER_D0); /* div */
+ else if (reg_1==REGISTER_D0)
+ as_r (0367,0060,REGISTER_A1); /* div */
+ else if (reg_1==REGISTER_A1)
+ as_r (0367,0060,reg_3); /* div */
+ else
+ as_r (0367,0060,reg_1); /* div */
+ as_xchg (REGISTER_D0,reg_3);
+ as_xchg (REGISTER_A1,REGISTER_D0);
+ } else {
+ as_xchg (REGISTER_D0,reg_3);
+ as_xchg (REGISTER_A1,reg_2);
+ if (reg_1==REGISTER_D0)
+ as_r (0367,0060,reg_3); /* div */
+ else if (reg_1==REGISTER_A1)
+ as_r (0367,0060,reg_2); /* div */
+ else if (reg_1==reg_3)
+ as_r (0367,0060,REGISTER_D0); /* div */
+ else if (reg_1==reg_2)
+ as_r (0367,0060,REGISTER_A1); /* div */
+ else
+ as_r (0367,0060,reg_1); /* div */
+ as_xchg (REGISTER_A1,reg_2);
+ as_xchg (REGISTER_D0,reg_3);
+ }
+ }
+#else
if (reg_1==REGISTER_D0){
if (reg_3==REGISTER_D0){
if (reg_2==REGISTER_A1)
@@ -3495,8 +3583,8 @@ static void as_divdu_instruction (struct instruction *instruction)
as_xchg_eax_r (reg_3); /* xchg reg_3,D0 */
}
}
-}
#endif
+}
static void as_mul_shift_magic (int s)
{
@@ -3970,12 +4058,7 @@ static void as_exg_instruction (struct instruction *instruction)
r1=instruction->instruction_parameters[0].parameter_data.reg.r;
r2=instruction->instruction_parameters[1].parameter_data.reg.r;
- if (r1==REGISTER_D0)
- store_c (0x90+reg_num (r2)); /* xchg r,D0 */
- else if (r2==REGISTER_D0)
- store_c (0x90+reg_num (r1)); /* xchg r,D0 */
- else
- as_r_r (0207,r1,r2);
+ as_xchg (r1,r2);
}
static void as_neg_instruction (struct instruction *instruction)
@@ -5596,11 +5679,9 @@ static void as_instructions (struct instruction *instruction)
case IMULUD:
as_mulud_instruction (instruction);
break;
-#ifndef THREAD32
case IDIVDU:
as_divdu_instruction (instruction);
break;
-#endif
case IFLOORDIV:
as_floordiv_mod_instruction (instruction,0);
break;
diff --git a/cgiconst.h b/cgiconst.h
index a4e2ad2..22db79f 100644
--- a/cgiconst.h
+++ b/cgiconst.h
@@ -68,10 +68,7 @@ enum {
#endif
#if defined (I486)
,IADC ,ISBB, IRTSI
- ,IDIVI, IREMI, IREMU, IFLOORDIV, IMOD, IMULUD
-# ifndef THREAD32
- ,IDIVDU
-# endif
+ ,IDIVI, IREMI, IREMU, IFLOORDIV, IMOD, IMULUD, IDIVDU
,IFLOADS, IFMOVES
#endif
#if defined (I486) || defined (G_POWER)
diff --git a/cgiwas.c b/cgiwas.c
index a021ed8..dfebec4 100644
--- a/cgiwas.c
+++ b/cgiwas.c
@@ -3015,7 +3015,6 @@ static void w_as_mulud_instruction (struct instruction *instruction)
#endif
}
-#ifndef THREAD32
static void w_as_divdu_instruction (struct instruction *instruction)
{
int reg_1,reg_2,reg_3;
@@ -3024,6 +3023,83 @@ static void w_as_divdu_instruction (struct instruction *instruction)
reg_2=instruction->instruction_parameters[1].parameter_data.reg.r;
reg_3=instruction->instruction_parameters[2].parameter_data.reg.r;
+#ifdef THREAD32
+ if (reg_3==REGISTER_D0){
+ if (reg_2==REGISTER_A1)
+ w_as_opcode_register_newline ("div",reg_1);
+ else {
+ w_as_opcode_register_register_newline ("xchg",REGISTER_A1,reg_2);
+ if (reg_1==reg_2)
+ w_as_opcode_register_newline ("div",REGISTER_A1);
+ else if (reg_1==REGISTER_A1)
+ w_as_opcode_register_newline ("div",reg_2);
+ else
+ w_as_opcode_register_newline ("div",reg_1);
+ w_as_opcode_register_register_newline ("xchg",REGISTER_A1,reg_2);
+ }
+ } else if (reg_3==REGISTER_A1){
+ w_as_opcode_register_register_newline ("xchg",REGISTER_D0,REGISTER_A1);
+ if (reg_2==REGISTER_D0){
+ if (reg_1==REGISTER_D0)
+ w_as_opcode_register_newline ("div",REGISTER_A1);
+ else if (reg_1==REGISTER_A1)
+ w_as_opcode_register_newline ("div",REGISTER_D0);
+ else
+ w_as_opcode_register_newline ("div",reg_1);
+ } else {
+ w_as_opcode_register_register_newline ("xchg",REGISTER_A1,reg_2);
+ if (reg_1==reg_2)
+ w_as_opcode_register_newline ("div",REGISTER_A1);
+ else if (reg_1==REGISTER_D0)
+ w_as_opcode_register_newline ("div",reg_2);
+ else if (reg_1==REGISTER_A1)
+ w_as_opcode_register_newline ("div",REGISTER_D0);
+ else
+ w_as_opcode_register_newline ("div",reg_1);
+ w_as_opcode_register_register_newline ("xchg",REGISTER_A1,reg_2);
+ }
+ w_as_opcode_register_register_newline ("xchg",REGISTER_D0,REGISTER_A1);
+ } else {
+ if (reg_2==REGISTER_A1){
+ w_as_opcode_register_register_newline ("xchg",REGISTER_D0,reg_3);
+ if (reg_1==reg_3)
+ w_as_opcode_register_newline ("div",REGISTER_D0);
+ else if (reg_1==REGISTER_D0)
+ w_as_opcode_register_newline ("div",reg_3);
+ else
+ w_as_opcode_register_newline ("div",reg_1);
+ w_as_opcode_register_register_newline ("xchg",REGISTER_D0,reg_3);
+ } else if (reg_2==REGISTER_D0){
+ w_as_opcode_register_register_newline ("xchg",REGISTER_A1,REGISTER_D0);
+ w_as_opcode_register_register_newline ("xchg",REGISTER_D0,reg_3);
+ if (reg_1==reg_3)
+ w_as_opcode_register_newline ("div",REGISTER_D0);
+ else if (reg_1==REGISTER_D0)
+ w_as_opcode_register_newline ("div",REGISTER_A1);
+ else if (reg_1==REGISTER_A1)
+ w_as_opcode_register_newline ("div",reg_3);
+ else
+ w_as_opcode_register_newline ("div",reg_1);
+ w_as_opcode_register_register_newline ("xchg",REGISTER_D0,reg_3);
+ w_as_opcode_register_register_newline ("xchg",REGISTER_A1,REGISTER_D0);
+ } else {
+ w_as_opcode_register_register_newline ("xchg",REGISTER_D0,reg_3);
+ w_as_opcode_register_register_newline ("xchg",REGISTER_A1,reg_2);
+ if (reg_1==REGISTER_D0)
+ w_as_opcode_register_newline ("div",reg_3);
+ else if (reg_1==REGISTER_A1)
+ w_as_opcode_register_newline ("div",reg_2);
+ else if (reg_1==reg_3)
+ w_as_opcode_register_newline ("div",REGISTER_D0);
+ else if (reg_1==reg_2)
+ w_as_opcode_register_newline ("div",REGISTER_A1);
+ else
+ w_as_opcode_register_newline ("div",reg_1);
+ w_as_opcode_register_register_newline ("xchg",REGISTER_A1,reg_2);
+ w_as_opcode_register_register_newline ("xchg",REGISTER_D0,reg_3);
+ }
+ }
+#else
if (reg_1==REGISTER_D0){
if (reg_3==REGISTER_D0){
if (reg_2==REGISTER_A1)
@@ -3131,8 +3207,8 @@ static void w_as_divdu_instruction (struct instruction *instruction)
w_as_opcode_register_register_newline ("xchg",reg_3,REGISTER_D0);
}
}
-}
#endif
+}
static void w_as_or_r_r (int reg_1,int reg_2)
{
@@ -4838,11 +4914,9 @@ static void w_as_instructions (register struct instruction *instruction)
case IMULUD:
w_as_mulud_instruction (instruction);
break;
-#ifndef THREAD32
case IDIVDU:
w_as_divdu_instruction (instruction);
break;
-#endif
case IFLOORDIV:
w_as_floordiv_mod_instruction (instruction,0);
break;
diff --git a/cglin.c b/cglin.c
index ab9f7c2..50ddcaf 100644
--- a/cglin.c
+++ b/cglin.c
@@ -937,7 +937,7 @@ void i_call_r (int register_1,int frame_size)
}
#endif
-#if defined (I486) && !defined (THREAD32)
+#ifdef I486
void i_divdu_r_r_r (int register_1,int register_2,int register_3)
{
struct instruction *instruction;
@@ -4429,9 +4429,7 @@ static void linearize_two_results_operator (INSTRUCTION_GRAPH result_graph,ADDRE
# else
i_mulud_r_r (reg_1,reg_2);
# endif
- } else
-#ifndef THREAD32
- if (graph->instruction_code==GDIVDU){
+ } else if (graph->instruction_code==GDIVDU){
ADDRESS ad_3;
linearize_3_graphs (graph->instruction_parameters[0].p,&ad_1,
@@ -4447,9 +4445,7 @@ static void linearize_two_results_operator (INSTRUCTION_GRAPH result_graph,ADDRE
if (--*ad_3.ad_count_p==0)
free_register (ad_3.ad_register);
i_divdu_r_r_r (ad_3.ad_register,reg_1,reg_2);
- } else
-#endif
- if (graph->instruction_code==GADDDU){
+ } else if (graph->instruction_code==GADDDU){
ADDRESS ad_3,ad_4;
linearize_3_graphs (graph->instruction_parameters[0].p,&ad_1,
diff --git a/cgopt.c b/cgopt.c
index fe784ed..ee74478 100644
--- a/cgopt.c
+++ b/cgopt.c
@@ -421,10 +421,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 IREMI: case IREMU: case IMULUD:
-# ifndef THREAD32
- case IDIVDU:
-# endif
+ case IDIVI: case IREMI: case IREMU: case IMULUD: case IDIVDU:
case IFLOORDIV: case IMOD:
#endif
#if (defined (I486) && !defined (I486_USE_SCRATCH_REGISTER)) || defined (G_POWER)
@@ -685,9 +682,7 @@ static void compute_maximum_b_stack_offsets (register int b_offset)
instruction->instruction_icode!=IDIVI &&
instruction->instruction_icode!=IREMI &&
instruction->instruction_icode!=IREMU &&
-# ifndef THREAD32
instruction->instruction_icode!=IDIVDU &&
-# endif
instruction->instruction_icode!=IASR_S &&
instruction->instruction_icode!=ILSL_S &&
instruction->instruction_icode!=ILSR_S &&
@@ -935,9 +930,7 @@ void optimize_stack_access (struct basic_block *block,int *a_offset_p,int *b_off
instruction->instruction_icode!=IDIVI &&
instruction->instruction_icode!=IREMI &&
instruction->instruction_icode!=IREMU &&
-# ifndef THREAD32
instruction->instruction_icode!=IDIVDU &&
-# endif
instruction->instruction_icode!=IASR_S &&
instruction->instruction_icode!=ILSL_S &&
instruction->instruction_icode!=ILSR_S &&
@@ -1563,7 +1556,7 @@ static void store_next_uses (struct instruction *instruction)
case IROTL: case IROTR:
# endif
#endif
-#if defined (I486) && !defined (I486_USE_SCRATCH_REGISTER) && !defined (THREAD32)
+#if defined (I486) && !defined (I486_USE_SCRATCH_REGISTER)
case IMULUD:
#endif
#if (defined (I486) && !defined (I486_USE_SCRATCH_REGISTER)) || defined (G_POWER)
@@ -1596,7 +1589,7 @@ IF_G_POWER ( case IUMULH: )
use_parameter (&instruction->instruction_parameters[0]);
break;
case IDIV: case IREM: case IDIVU: case IREMU: case IMULUD:
-# ifdef THREAD32
+# ifdef THREAD32
use_parameter (&instruction->instruction_parameters[1]);
use_parameter (&instruction->instruction_parameters[0]);
define_parameter (&instruction->instruction_parameters[2]);
@@ -1718,9 +1711,9 @@ IF_G_RISC (case IADDI: case ILSLI:)
use_parameter (&instruction->instruction_parameters[0]);
break;
#endif
-#if defined (I486) && !defined (THREAD32)
+#ifdef I486
case IDIVDU:
-# ifdef I486_USE_SCRATCH_REGISTER
+# if defined (I486_USE_SCRATCH_REGISTER) && !defined (THREAD32)
define_scratch_register();
# endif
use_parameter (&instruction->instruction_parameters[2]);
@@ -4040,7 +4033,7 @@ IF_G_RISC (case IADDI: case ILSLI:)
case IEXG:
instruction_usedef_usedef (instruction);
break;
-#if defined (I486)
+#ifdef I486
case IMULUD:
# ifdef THREAD32
use_3_same_type_registers
@@ -4112,16 +4105,16 @@ IF_G_RISC (case IADDI: case ILSLI:)
instruction_bmove_use_use_use (instruction);
break;
#endif
-#if defined (I486) && !defined (THREAD32)
+#ifdef I486
case IDIVDU:
-# ifdef I486_USE_SCRATCH_REGISTER
+# if defined (I486_USE_SCRATCH_REGISTER) && !defined (THREAD32)
use_scratch_register();
# endif
use_3_same_type_registers
(&instruction->instruction_parameters[0].parameter_data.reg,USE,
&instruction->instruction_parameters[1].parameter_data.reg,USE_DEF,
&instruction->instruction_parameters[2].parameter_data.reg,USE_DEF,D_REGISTER);
-# ifdef I486_USE_SCRATCH_REGISTER
+# if defined (I486_USE_SCRATCH_REGISTER) && !defined (THREAD32)
allocate_scratch_register=1;
# endif
break;