summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cgcalc.c13
-rw-r--r--cgcode.c164
-rw-r--r--cgcodep.h6
-rw-r--r--cgconst.h2
-rw-r--r--cgias.c60
-rw-r--r--cgiconst.h2
-rw-r--r--cginput.c6
-rw-r--r--cgiwas.c6
-rw-r--r--cglin.c110
-rw-r--r--cgopt.c6
-rw-r--r--cgport.h2
11 files changed, 331 insertions, 46 deletions
diff --git a/cgcalc.c b/cgcalc.c
index d45d35a..7c88f00 100644
--- a/cgcalc.c
+++ b/cgcalc.c
@@ -2552,9 +2552,14 @@ void calculate_graph_register_uses (INSTRUCTION_GRAPH graph)
if (graph_0->order_mode==R_NOMODE)
if (graph_0->instruction_code==GMULUD)
calculate_mulud_operator (graph_0);
- else
+ else if ( graph_0->instruction_code==GDIVDU ||
+ graph_0->instruction_code==GADDDU ||
+ graph_0->instruction_code==GSUBDU)
+ {
calculate_divdu_operator (graph_0);
-
+ } else
+ internal_error_in_function ("calculate_graph_register_uses");
+
graph->order_mode=R_DREGISTER;
graph->u_aregs=graph_0->u_aregs;
graph->u_dregs=graph_0->u_dregs;
@@ -2775,6 +2780,8 @@ void count_graph (INSTRUCTION_GRAPH graph)
++graph->node_count;
break;
#ifdef I486
+ case GADDDU:
+ case GSUBDU:
case GDIVDU:
if (++graph->node_count==1){
count_graph (graph->instruction_parameters[0].p);
@@ -2973,6 +2980,8 @@ void mark_graph_2 (register INSTRUCTION_GRAPH graph)
graph->node_mark=2;
break;
#ifdef I486
+ case GADDDU:
+ case GSUBDU:
case GDIVDU:
if (graph->node_mark<2){
graph->node_mark=2;
diff --git a/cgcode.c b/cgcode.c
index 12475f4..1377d7f 100644
--- a/cgcode.c
+++ b/cgcode.c
@@ -19,6 +19,10 @@
#include "cgport.h"
+#ifdef I486
+# define NEW_DESCRIPTORS
+#endif
+
#if defined (G_POWER) || defined (I486)
# define PROFILE
# if defined (G_POWER)
@@ -66,10 +70,14 @@
#endif
#define GEN_OBJ
-#if defined (M68000) || (defined (NO_STRING_ADDRES_IN_DESCRIPTOR) && (defined (G_POWER) || defined (I486)))
-# define ARITY_0_DESCRIPTOR_OFFSET (-8)
+#ifdef NEW_DESCRIPTORS
+# define ARITY_0_DESCRIPTOR_OFFSET (-4)
#else
-# define ARITY_0_DESCRIPTOR_OFFSET (-12)
+# if defined (M68000) || (defined (NO_STRING_ADDRES_IN_DESCRIPTOR) && (defined (G_POWER) || defined (I486)))
+# define ARITY_0_DESCRIPTOR_OFFSET (-8)
+# else
+# define ARITY_0_DESCRIPTOR_OFFSET (-12)
+# endif
#endif
#ifdef GEN_MAC_OBJ
# define DESCRIPTOR_ARITY_OFFSET (-4)
@@ -518,6 +526,30 @@ void code_addI (VOID)
s_put_b (0,graph_3);
}
+#ifdef I486
+void code_addLU (VOID)
+{
+ INSTRUCTION_GRAPH graph_1,graph_2,graph_3,graph_4,graph_5,graph_6;
+
+ graph_3=s_get_b (2);
+ graph_2=s_get_b (1);
+ graph_1=s_pop_b();
+
+ graph_4=g_new_node (GADDDU,3,3*sizeof (union instruction_parameter));
+ graph_4->instruction_parameters[0].p=graph_1;
+ graph_4->instruction_parameters[1].p=graph_2;
+ graph_4->instruction_parameters[2].p=graph_3;
+
+ graph_5=g_instruction_2 (GRESULT1,graph_4,NULL);
+ graph_6=g_instruction_2 (GRESULT0,graph_4,NULL);
+ graph_5->instruction_parameters[1].p=graph_6;
+ graph_6->instruction_parameters[1].p=graph_5;
+
+ s_put_b (1,graph_5);
+ s_put_b (0,graph_6);
+}
+#endif
+
#ifndef M68000
static void code_operatorIo (int instruction_code)
{
@@ -2200,15 +2232,19 @@ void code_eq_nulldesc (char descriptor_name[],int a_offset)
graph_2=g_load_des_id (DESCRIPTOR_OFFSET,graph_1);
graph_3=g_g_register (GLOBAL_DATA_REGISTER);
graph_4=g_add (graph_3,graph_2);
-#else
- graph_2=g_load_id (0,graph_1);
-#endif
-#ifdef GEN_MAC_OBJ
graph_5=g_load_des_id (0,graph_4);
+ graph_6=g_sub (graph_5,graph_2);
#else
+ graph_2=g_load_id (0,graph_1);
+# ifdef NEW_DESCRIPTORS
+ graph_5=g_load_des_id (-2,graph_2);
+ graph_5=g_lsl (g_load_i (3),graph_5);
+ graph_6=g_sub (graph_5,graph_2);
+# else
graph_5=g_load_des_id (2-2,graph_2);
-#endif
graph_6=g_sub (graph_5,graph_2);
+# endif
+#endif
graph_7=g_load_des_i (descriptor,0);
graph_8=g_cmp_eq (graph_7,graph_6);
@@ -3255,30 +3291,21 @@ void code_get_desc_arity (int a_offset)
void code_get_node_arity (int a_offset)
{
- INSTRUCTION_GRAPH graph_1,graph_2,graph_3,graph_4,graph_5,graph_7;
-#ifdef GEN_MAC_OBJ
- INSTRUCTION_GRAPH graph_6;
-#endif
-
+ INSTRUCTION_GRAPH graph_1,graph_2,graph_3,graph_4,graph_5,graph_6;
+
graph_1=s_get_a (a_offset);
#ifdef GEN_MAC_OBJ
graph_2=g_load_des_id (DESCRIPTOR_OFFSET,graph_1);
graph_3=g_g_register (GLOBAL_DATA_REGISTER);
graph_4=g_add (graph_3,graph_2);
graph_5=g_load_des_id (0,graph_4);
+ graph_6=g_lsr (g_load_i (2),graph_5);
#else
graph_2=g_load_id (0,graph_1);
- graph_5=g_load_des_id (-2,graph_2);
-#endif
-
-#ifdef GEN_MAC_OBJ
- graph_6=g_load_i (2);
- graph_7=g_lsr (graph_6,graph_5);
-#else
- graph_7=graph_5;
+ graph_6=g_load_des_id (-2,graph_2);
#endif
- s_push_b (graph_7);
+ s_push_b (graph_6);
}
void code_get_desc_flags_b (void)
@@ -6950,6 +6977,30 @@ void code_subI (VOID)
s_put_b (0,graph_3);
}
+#ifdef I486
+void code_subLU (VOID)
+{
+ INSTRUCTION_GRAPH graph_1,graph_2,graph_3,graph_4,graph_5,graph_6;
+
+ graph_3=s_get_b (2);
+ graph_2=s_get_b (1);
+ graph_1=s_pop_b();
+
+ graph_4=g_new_node (GSUBDU,3,3*sizeof (union instruction_parameter));
+ graph_4->instruction_parameters[0].p=graph_1;
+ graph_4->instruction_parameters[1].p=graph_2;
+ graph_4->instruction_parameters[2].p=graph_3;
+
+ graph_5=g_instruction_2 (GRESULT1,graph_4,NULL);
+ graph_6=g_instruction_2 (GRESULT0,graph_4,NULL);
+ graph_5->instruction_parameters[1].p=graph_6;
+ graph_6->instruction_parameters[1].p=graph_5;
+
+ s_put_b (1,graph_5);
+ s_put_b (0,graph_6);
+}
+#endif
+
#ifndef M68000
void code_subIo (VOID)
{
@@ -7622,7 +7673,11 @@ static void write_descriptor_curry_table (int arity,LABEL *code_label)
store_word_in_data_section (n<<2);
#else
# ifdef GEN_OBJ
+# ifdef NEW_DESCRIPTORS
+ store_2_words_in_data_section (n,(arity-n)<<3);
+# else
store_2_words_in_data_section (n,n<<3);
+# endif
# endif
#endif
if (assembly_flag){
@@ -7630,7 +7685,11 @@ static void write_descriptor_curry_table (int arity,LABEL *code_label)
w_as_word_in_data_section (n<<2);
#else
w_as_word_in_data_section (n);
+# ifdef NEW_DESCRIPTORS
+ w_as_word_in_data_section ((arity-n)<<3);
+# else
w_as_word_in_data_section (n<<3);
+# endif
#endif
}
@@ -7693,7 +7752,11 @@ static void write_descriptor_curry_table (int arity,LABEL *code_label)
}
static void code_descriptor (char label_name[],char node_entry_label_name[],char code_label_name[],LABEL *code_label,
+#ifdef NEW_DESCRIPTORS
+ int arity,int export_flag,LABEL *string_label,int string_code_label_id)
+#else
int arity,int export_flag,int lazy_record_flag,LABEL *string_label,int string_code_label_id)
+#endif
{
LABEL *label;
int n;
@@ -7726,7 +7789,7 @@ static void code_descriptor (char label_name[],char node_entry_label_name[],char
w_as_new_data_module();
#endif
-#ifndef M68000
+#if !defined (NEW_DESCRIPTORS) && !defined (M68000)
/* not for 68k to maintain long word alignment */
if (module_info_flag && module_label){
# ifdef GEN_MAC_OBJ
@@ -7828,19 +7891,21 @@ static void code_descriptor (char label_name[],char node_entry_label_name[],char
}
#endif
-#ifdef GEN_MAC_OBJ
+#ifndef NEW_DESCRIPTORS
+# ifdef GEN_MAC_OBJ
store_word_in_data_section (arity);
-#else
-# ifdef GEN_OBJ
+# else
+# ifdef GEN_OBJ
store_2_words_in_data_section (lazy_record_flag,arity);
+# endif
# endif
-#endif
if (assembly_flag){
-#if defined (sparc) || defined (I486) || defined (G_POWER)
+# if defined (sparc) || defined (I486) || defined (G_POWER)
w_as_word_in_data_section (lazy_record_flag);
-#endif
+# endif
w_as_word_in_data_section (arity);
}
+#endif
#if ! (defined (NO_STRING_ADDRES_IN_DESCRIPTOR) && (defined (G_POWER) || defined (I486)))
# ifdef GEN_MAC_OBJ
@@ -7868,6 +7933,23 @@ static void code_descriptor (char label_name[],char node_entry_label_name[],char
w_as_define_label (label);
}
+#ifdef NEW_DESCRIPTORS
+static void code_new_descriptor (int arity,int lazy_record_flag)
+{
+ store_2_words_in_data_section (lazy_record_flag,arity);
+ if (assembly_flag){
+ w_as_word_in_data_section (lazy_record_flag);
+ w_as_word_in_data_section (arity);
+ }
+
+ if (module_info_flag && module_label){
+ store_label_in_data_section (module_label);
+ if (assembly_flag)
+ w_as_label_in_data_section (module_label->label_name);
+ }
+}
+#endif
+
void code_desc (char label_name[],char node_entry_label_name[],char *code_label_name,
int arity,int lazy_record_flag,char descriptor_name[],int descriptor_name_length)
{
@@ -7893,10 +7975,18 @@ void code_desc (char label_name[],char node_entry_label_name[],char *code_label_
code_label_name=code_label->label_name;
}
+#ifdef NEW_DESCRIPTORS
+ code_descriptor (label_name,node_entry_label_name,code_label_name,code_label,arity,0,string_label,string_code_label_id);
+#else
code_descriptor (label_name,node_entry_label_name,code_label_name,code_label,arity,0,lazy_record_flag,string_label,string_code_label_id);
+#endif
write_descriptor_curry_table (arity,code_label);
+#ifdef NEW_DESCRIPTORS
+ code_new_descriptor (arity,lazy_record_flag);
+#endif
+
w_descriptor_string (descriptor_name,descriptor_name_length,string_code_label_id,string_label);
}
@@ -7917,7 +8007,11 @@ void code_descn (char label_name[],char node_entry_label_name[],int arity,int la
#endif
);
+#ifdef NEW_DESCRIPTORS
+ code_descriptor (label_name,node_entry_label_name,NULL,NULL,0/*arity*/,0,string_label,string_code_label_id);
+#else
code_descriptor (label_name,node_entry_label_name,NULL,NULL,0/*arity*/,0,lazy_record_flag,string_label,string_code_label_id);
+#endif
#ifdef GEN_MAC_OBJ
store_word_in_data_section (0<<2);
@@ -7933,6 +8027,10 @@ void code_descn (char label_name[],char node_entry_label_name[],int arity,int la
}
#endif
+#ifdef NEW_DESCRIPTORS
+ code_new_descriptor (0/*arity*/,lazy_record_flag);
+#endif
+
w_descriptor_string (descriptor_name,descriptor_name_length,string_code_label_id,string_label);
}
@@ -7961,10 +8059,18 @@ void code_descexp (char label_name[],char node_entry_label_name[],char *code_lab
code_label_name=code_label->label_name;
}
+#ifdef NEW_DESCRIPTORS
+ code_descriptor (label_name,node_entry_label_name,code_label_name,code_label,arity,EXPORT_LABEL,string_label,string_code_label_id);
+#else
code_descriptor (label_name,node_entry_label_name,code_label_name,code_label,arity,EXPORT_LABEL,lazy_record_flag,string_label,string_code_label_id);
+#endif
write_descriptor_curry_table (arity,code_label);
+#ifdef NEW_DESCRIPTORS
+ code_new_descriptor (arity,lazy_record_flag);
+#endif
+
w_descriptor_string (descriptor_name,descriptor_name_length,string_code_label_id,string_label);
}
diff --git a/cgcodep.h b/cgcodep.h
index ca6f612..edc3a78 100644
--- a/cgcodep.h
+++ b/cgcodep.h
@@ -19,6 +19,9 @@ void code_absR (void);
void code_acosR (VOID);
void code_add_args (int source_offset,int n_arguments,int destination_offset);
void code_addI (VOID);
+#ifdef I486
+void code_addLU (VOID);
+#endif
#ifndef M68000
void code_addIo (VOID);
#endif
@@ -253,6 +256,9 @@ void code_sliceS (int source_offset,int destination_offset);
void code_sqrtR (VOID);
void code_stop_reducer (VOID);
void code_subI (VOID);
+#ifdef I486
+void code_subLU (VOID);
+#endif
#ifndef M68000
void code_subIo (VOID);
#endif
diff --git a/cgconst.h b/cgconst.h
index e94eb66..287f29c 100644
--- a/cgconst.h
+++ b/cgconst.h
@@ -24,7 +24,7 @@ enum {
,GDIVU
#endif
#ifdef I486
- ,GREMU, GMULUD, GDIVDU, GRESULT0, GRESULT1
+ ,GADDDU, GDIVDU, GMULUD, GREMU, GRESULT0, GRESULT1, GSUBDU
#endif
#ifdef M68000
,GFACOS, GFASIN, GFEXP, GFLN, GFLOG10
diff --git a/cgias.c b/cgias.c
index dd9059d..835559a 100644
--- a/cgias.c
+++ b/cgias.c
@@ -1593,6 +1593,60 @@ static void as_sub_instruction (struct instruction *instruction)
}
}
+static void as_adc_instruction (struct instruction *instruction)
+{
+ switch (instruction->instruction_parameters[0].parameter_type){
+ case P_REGISTER:
+ as_r_r (0023,instruction->instruction_parameters[0].parameter_data.reg.r,
+ instruction->instruction_parameters[1].parameter_data.reg.r);
+ return;
+ case P_IMMEDIATE:
+ as_i_r2 (0201,0020,0025,instruction->instruction_parameters[0].parameter_data.i,
+ instruction->instruction_parameters[1].parameter_data.reg.r);
+ return;
+ case P_INDIRECT:
+ as_id_r (0023,instruction->instruction_parameters[0].parameter_offset,
+ instruction->instruction_parameters[0].parameter_data.reg.r,
+ instruction->instruction_parameters[1].parameter_data.reg.r);
+ return;
+ case P_INDEXED:
+ as_x_r (0023,instruction->instruction_parameters[0].parameter_offset,
+ instruction->instruction_parameters[0].parameter_data.ir,
+ instruction->instruction_parameters[1].parameter_data.reg.r);
+ return;
+ default:
+ internal_error_in_function ("as_adc_instruction");
+ return;
+ }
+}
+
+static void as_sbb_instruction (struct instruction *instruction)
+{
+ switch (instruction->instruction_parameters[0].parameter_type){
+ case P_REGISTER:
+ as_r_r (0033,instruction->instruction_parameters[0].parameter_data.reg.r,
+ instruction->instruction_parameters[1].parameter_data.reg.r);
+ return;
+ case P_IMMEDIATE:
+ as_i_r2 (0201,0030,0035,instruction->instruction_parameters[0].parameter_data.i,
+ instruction->instruction_parameters[1].parameter_data.reg.r);
+ return;
+ case P_INDIRECT:
+ as_id_r (0033,instruction->instruction_parameters[0].parameter_offset,
+ instruction->instruction_parameters[0].parameter_data.reg.r,
+ instruction->instruction_parameters[1].parameter_data.reg.r);
+ return;
+ case P_INDEXED:
+ as_x_r (0033,instruction->instruction_parameters[0].parameter_offset,
+ instruction->instruction_parameters[0].parameter_data.ir,
+ instruction->instruction_parameters[1].parameter_data.reg.r);
+ return;
+ default:
+ internal_error_in_function ("as_sbb_instruction");
+ return;
+ }
+}
+
enum { SIZE_LONG, SIZE_WORD, SIZE_BYTE };
static void as_cmp_i_parameter (int i,struct parameter *parameter)
@@ -4141,6 +4195,12 @@ static void as_instructions (struct instruction *instruction)
case INOT:
as_not_instruction (instruction);
break;
+ case IADC:
+ as_adc_instruction (instruction);
+ break;
+ case ISBB:
+ as_sbb_instruction (instruction);
+ break;
case IMULUD:
as_mulud_instruction (instruction);
break;
diff --git a/cgiconst.h b/cgiconst.h
index 37ff784..b4d79bb 100644
--- a/cgiconst.h
+++ b/cgiconst.h
@@ -55,7 +55,7 @@ enum {
,IFEXG
#endif
#if defined (I486)
- ,IRTSI, IDIVI, IREMI, IREMU, IMULUD, IDIVDU
+ ,IADC ,IRTSI, IDIVI, IREMI, IREMU, IMULUD, IDIVDU, ISBB
#endif
#if defined (I486) || defined (G_POWER)
,IDIVU
diff --git a/cginput.c b/cginput.c
index 1cda6b5..39b2851 100644
--- a/cginput.c
+++ b/cginput.c
@@ -1738,6 +1738,9 @@ static void put_instructions_in_table (void)
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 );
+#ifdef I486
+ put_instruction_name ("addLU", parse_instruction, code_addLU );
+#endif
put_instruction_name ("addR", parse_instruction, code_addR );
put_instruction_name ("andB", parse_instruction, code_andB );
put_instruction_name ("and%", parse_instruction, code_and );
@@ -1977,6 +1980,9 @@ static void put_instructions_in_table2 (void)
put_instruction_name ("sqrtR", parse_instruction, code_sqrtR );
put_instruction_name ("stop_reducer", parse_instruction, code_stop_reducer );
put_instruction_name ("subI", parse_instruction, code_subI );
+#ifdef I486
+ put_instruction_name ("subLU", parse_instruction, code_subLU );
+#endif
#ifndef M68000
put_instruction_name ("addIo", parse_instruction, code_addIo );
put_instruction_name ("mulIo", parse_instruction, code_mulIo );
diff --git a/cgiwas.c b/cgiwas.c
index 680a798..cd84ff0 100644
--- a/cgiwas.c
+++ b/cgiwas.c
@@ -3249,6 +3249,12 @@ static void w_as_instructions (register struct instruction *instruction)
case INOT:
w_as_monadic_instruction (instruction,intel_asm ? "not" : "notl");
break;
+ case IADC:
+ w_as_dyadic_instruction (instruction,intel_asm ? "adc" : "adcl");
+ break;
+ case ISBB:
+ w_as_dyadic_instruction (instruction,intel_asm ? "sbb" : "sbbl");
+ break;
case IMULUD:
w_as_mulud_instruction (instruction);
break;
diff --git a/cglin.c b/cglin.c
index 11c9e6c..ede33dc 100644
--- a/cglin.c
+++ b/cglin.c
@@ -3767,7 +3767,63 @@ static void linearize_mod_operator (int i_instruction_code,INSTRUCTION_GRAPH gra
#endif
#ifdef I486
-static void linearize_mulud_or_divdu_operator (INSTRUCTION_GRAPH result_graph,ADDRESS *ad_p)
+static int linearize_first_graph_first (INSTRUCTION_GRAPH a_graph_1,INSTRUCTION_GRAPH a_graph_2)
+{
+ int i1,i2,u1,u2;
+ int a,d;
+
+ a=a_graph_1->i_aregs; d=a_graph_1->i_dregs; i1=AD_REG_WEIGHT (a,d);
+ a=a_graph_2->i_aregs; d=a_graph_2->i_dregs; i2=AD_REG_WEIGHT (a,d);
+
+ a=a_graph_1->u_aregs; d=a_graph_1->u_dregs; u1=AD_REG_WEIGHT (a,d);
+ a=a_graph_2->u_aregs; d=a_graph_2->u_dregs; u2=AD_REG_WEIGHT (a,d);
+
+ if (i1<0)
+ return ! (i2<0 && (u2<u1 || (u1==u2 && i2<i1)));
+ else if (i1==0)
+ return ! (i2<0 || (i2==0 && u2<u1));
+ else
+ return ! (i2<=0 || (u2-i2>u1-i1 || (u2-i2==u1-i1 && i2<i1)));
+}
+
+static void linearize_3_graphs (INSTRUCTION_GRAPH graph_1,ADDRESS *ad_1_p,
+ INSTRUCTION_GRAPH graph_2,ADDRESS *ad_2_p,
+ INSTRUCTION_GRAPH graph_3,ADDRESS *ad_3_p)
+{
+ if (linearize_first_graph_first (graph_1,graph_2)){
+ if (linearize_first_graph_first (graph_1,graph_3)){
+ linearize_graph (graph_1,ad_1_p);
+ if (linearize_first_graph_first (graph_2,graph_3)){
+ linearize_graph (graph_2,ad_2_p);
+ linearize_graph (graph_3,ad_3_p);
+ } else {
+ linearize_graph (graph_3,ad_3_p);
+ linearize_graph (graph_2,ad_2_p);
+ }
+ } else {
+ linearize_graph (graph_3,ad_3_p);
+ linearize_graph (graph_1,ad_1_p);
+ linearize_graph (graph_2,ad_2_p);
+ }
+ } else {
+ if (linearize_first_graph_first (graph_2,graph_3)){
+ linearize_graph (graph_2,ad_2_p);
+ if (linearize_first_graph_first (graph_1,graph_3)){
+ linearize_graph (graph_1,ad_1_p);
+ linearize_graph (graph_3,ad_3_p);
+ } else {
+ linearize_graph (graph_3,ad_3_p);
+ linearize_graph (graph_1,ad_1_p);
+ }
+ } else {
+ linearize_graph (graph_3,ad_3_p);
+ linearize_graph (graph_2,ad_2_p);
+ linearize_graph (graph_1,ad_1_p);
+ }
+ }
+}
+
+static void linearize_two_results_operator (INSTRUCTION_GRAPH result_graph,ADDRESS *ad_p)
{
INSTRUCTION_GRAPH graph,result_graph2;
ADDRESS ad_1,ad_2;
@@ -3795,17 +3851,12 @@ static void linearize_mulud_or_divdu_operator (INSTRUCTION_GRAPH result_graph,AD
reg_1=ad_1.ad_register;
reg_2=ad_2.ad_register;
i_mulud_r_r (reg_1,reg_2);
- } else {
- INSTRUCTION_GRAPH graph_1,graph_2,graph_3;
+ } else if (graph->instruction_code==GDIVDU){
ADDRESS ad_3;
- graph_1=graph->instruction_parameters[0].p;
- graph_2=graph->instruction_parameters[1].p;
- graph_3=graph->instruction_parameters[2].p;
-
- linearize_graph (graph_1,&ad_1);
- linearize_graph (graph_2,&ad_2);
- linearize_graph (graph_3,&ad_3);
+ linearize_3_graphs (graph->instruction_parameters[0].p,&ad_1,
+ graph->instruction_parameters[1].p,&ad_2,
+ graph->instruction_parameters[2].p,&ad_3);
in_preferred_alterable_register (&ad_2,REGISTER_D0);
in_preferred_alterable_register (&ad_1,REGISTER_A1);
@@ -3816,7 +3867,42 @@ static void linearize_mulud_or_divdu_operator (INSTRUCTION_GRAPH result_graph,AD
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 if (graph->instruction_code==GADDDU){
+ ADDRESS ad_3,ad_4;
+
+ linearize_3_graphs (graph->instruction_parameters[0].p,&ad_1,
+ graph->instruction_parameters[1].p,&ad_2,
+ graph->instruction_parameters[2].p,&ad_3);
+
+ in_alterable_data_register (&ad_2);
+ instruction_ad_r (IADD,&ad_3,ad_2.ad_register);
+
+ in_alterable_data_register (&ad_1);
+ ad_4.ad_mode=P_IMMEDIATE;
+ ad_4.ad_offset=0;
+ instruction_ad_r (IADC,&ad_4,ad_1.ad_register);
+
+ reg_1=ad_1.ad_register;
+ reg_2=ad_2.ad_register;
+ } else if (graph->instruction_code==GSUBDU){
+ ADDRESS ad_3,ad_4;
+
+ linearize_3_graphs (graph->instruction_parameters[0].p,&ad_1,
+ graph->instruction_parameters[1].p,&ad_2,
+ graph->instruction_parameters[2].p,&ad_3);
+
+ in_alterable_data_register (&ad_2);
+ instruction_ad_r (ISUB,&ad_3,ad_2.ad_register);
+
+ in_alterable_data_register (&ad_1);
+ ad_4.ad_mode=P_IMMEDIATE;
+ ad_4.ad_offset=0;
+ instruction_ad_r (ISBB,&ad_4,ad_1.ad_register);
+
+ reg_1=ad_1.ad_register;
+ reg_2=ad_2.ad_register;
+ } else
+ internal_error_in_function ("linearize_two_results_operator");
result_graph2=result_graph->instruction_parameters[1].p;
@@ -8056,7 +8142,7 @@ static void linearize_graph (INSTRUCTION_GRAPH graph,ADDRESS *ad_p)
#ifdef I486
case GRESULT0:
case GRESULT1:
- linearize_mulud_or_divdu_operator (graph,ad_p);
+ linearize_two_results_operator (graph,ad_p);
return;
#endif
default:
diff --git a/cgopt.c b/cgopt.c
index 888e976..1bd87be 100644
--- a/cgopt.c
+++ b/cgopt.c
@@ -1534,6 +1534,9 @@ IF_G_SPARC (case IADDO: case ISUBO:)
case IFEXG:
#endif
IF_G_POWER ( case IUMULH: )
+#ifdef I486
+ case IADC: case ISBB:
+#endif
use_parameter (&instruction->instruction_parameters[1]);
use_parameter (&instruction->instruction_parameters[0]);
break;
@@ -3824,6 +3827,9 @@ static void allocate_registers (struct basic_block *basic_block)
case IMUL: case IOR: case ISUB:
IF_G_SPARC (case IADDO: case ISUBO:)
IF_G_POWER ( case IUMULH: )
+#ifdef I486
+ case IADC: case ISBB:
+#endif
instruction_use_2 (instruction,USE_DEF);
break;
#ifdef I486_USE_SCRATCH_REGISTER
diff --git a/cgport.h b/cgport.h
index 4cf03e7..952cc34 100644
--- a/cgport.h
+++ b/cgport.h
@@ -1,6 +1,6 @@
#define FINALIZERS
-#undef NEW_APPLY
+#define NEW_APPLY
#if defined (__MWERKS__) || defined (__MRC__)
# define POWER