summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cgcalc.c222
-rw-r--r--cgcode.c271
-rw-r--r--cgcodep.h16
-rw-r--r--cgconst.h28
-rw-r--r--cgias.c403
-rw-r--r--cgiconst.h2
-rw-r--r--cginput.c32
-rw-r--r--cgiwas.c480
-rw-r--r--cglin.c267
-rw-r--r--cgopt.c54
-rw-r--r--cgport.h1
11 files changed, 1406 insertions, 370 deletions
diff --git a/cgcalc.c b/cgcalc.c
index 7c14d0c..8d13697 100644
--- a/cgcalc.c
+++ b/cgcalc.c
@@ -241,9 +241,116 @@ static void calculate_eor_operator (INSTRUCTION_GRAPH graph)
graph->i_dregs=i_dregs;
graph->order_alterable=graph->node_count<=1;
- return;
}
+#ifdef I486
+static void calculate_mulud_operator (INSTRUCTION_GRAPH graph)
+{
+ INSTRUCTION_GRAPH graph_1,graph_2;
+ int i_aregs,i_dregs,l_aregs,r_aregs,l_dregs,r_dregs;
+
+ graph_1=graph->instruction_parameters[0].p;
+ graph_2=graph->instruction_parameters[1].p;
+
+ calculate_graph_register_uses (graph_1);
+ calculate_graph_register_uses (graph_2);
+
+ i_aregs=graph_1->i_aregs+graph_2->i_aregs;
+ i_dregs=graph_1->i_dregs+graph_2->i_dregs;
+
+ l_aregs=MAX (graph_1->u_aregs,graph_1->i_aregs+graph_2->u_aregs);
+ l_dregs=MAX (graph_1->u_dregs,graph_1->i_dregs+graph_2->u_dregs);
+
+ r_aregs=MAX (graph_2->u_aregs,graph_2->i_aregs+graph_1->u_aregs);
+ r_dregs=MAX (graph_2->u_dregs,graph_2->i_dregs+graph_1->u_dregs);
+
+ if (graph_1->order_mode==R_DREGISTER)
+ i_dregs-=graph_1->order_alterable;
+ else
+ i_aregs-=graph_1->order_alterable;
+
+ if (graph_2->order_mode==R_DREGISTER)
+ i_dregs-=graph_2->order_alterable;
+ else
+ i_aregs-=graph_2->order_alterable;
+
+ i_dregs+=2;
+
+ if (l_dregs<i_dregs)
+ l_dregs=i_dregs;
+ if (r_dregs<i_dregs)
+ r_dregs=i_dregs;
+
+ graph->order_mode=R_DREGISTER;
+
+ if (AD_REG_WEIGHT (l_aregs,l_dregs) < AD_REG_WEIGHT (r_aregs,r_dregs)){
+ graph->u_aregs=l_aregs;
+ graph->u_dregs=l_dregs;
+ graph->order_left=1;
+ } else {
+ graph->u_aregs=r_aregs;
+ graph->u_dregs=r_dregs;
+ graph->order_left=0;
+ }
+
+ graph->i_aregs=i_aregs;
+ graph->i_dregs=i_dregs;
+
+ graph->order_alterable=0;
+}
+
+static void calculate_divdu_operator (INSTRUCTION_GRAPH graph)
+{
+ INSTRUCTION_GRAPH graph_1,graph_2,graph_3;
+ int i_aregs,i_dregs,aregs,dregs;
+
+ graph_1=graph->instruction_parameters[0].p;
+ graph_2=graph->instruction_parameters[1].p;
+ graph_3=graph->instruction_parameters[2].p;
+
+ calculate_graph_register_uses (graph_1);
+ calculate_graph_register_uses (graph_2);
+ calculate_graph_register_uses (graph_3);
+
+ i_aregs=graph_1->i_aregs+graph_2->i_aregs+graph_3->i_aregs;
+ i_dregs=graph_1->i_dregs+graph_2->i_dregs+graph_3->i_dregs;
+
+ aregs=MAX ( MAX (graph_1->u_aregs,graph_1->i_aregs+graph_2->u_aregs),
+ graph_1->i_aregs+graph_2->i_aregs+graph_3->u_aregs);
+ dregs=MAX ( MAX (graph_1->u_dregs,graph_1->i_dregs+graph_2->u_dregs),
+ graph_1->i_dregs+graph_2->i_dregs+graph_3->u_dregs);
+
+ if (graph_1->order_mode==R_DREGISTER)
+ i_dregs-=graph_1->order_alterable;
+ else
+ i_aregs-=graph_1->order_alterable;
+
+ if (graph_2->order_mode==R_DREGISTER)
+ i_dregs-=graph_2->order_alterable;
+ else
+ i_aregs-=graph_2->order_alterable;
+
+ if (graph_3->order_mode==R_DREGISTER)
+ i_dregs-=graph_3->order_alterable;
+ else
+ i_aregs-=graph_3->order_alterable;
+
+ i_dregs+=2;
+
+ if (dregs<i_dregs)
+ dregs=i_dregs;
+
+ graph->order_mode=R_DREGISTER;
+
+ graph->u_aregs=aregs;
+ graph->u_dregs=dregs;
+ graph->i_aregs=i_aregs;
+ graph->i_dregs=i_dregs;
+
+ graph->order_alterable=0;
+}
+#endif
+
static void calculate_dyadic_float_operator (INSTRUCTION_GRAPH graph)
{
INSTRUCTION_GRAPH graph_1,graph_2;
@@ -2334,15 +2441,17 @@ void calculate_graph_register_uses (INSTRUCTION_GRAPH graph)
case GFCOS:
case GFSIN:
case GFTAN:
+ case GFATAN:
+ case GFSQRT:
+ case GFNEG:
+ case GFABS:
+#ifdef M68000
case GFASIN:
case GFACOS:
- case GFATAN:
case GFLN:
case GFLOG10:
case GFEXP:
- case GFSQRT:
- case GFNEG:
- case GFABS:
+#endif
calculate_monadic_float_operator (graph);
return;
case GFLOAD_ID:
@@ -2433,6 +2542,29 @@ void calculate_graph_register_uses (INSTRUCTION_GRAPH graph)
graph->order_alterable=graph_2->order_alterable;
return;
}
+#ifdef I486
+ case GRESULT0:
+ case GRESULT1:
+ {
+ INSTRUCTION_GRAPH graph_0;
+
+ graph_0=graph->instruction_parameters[0].p;
+ if (graph_0->order_mode==R_NOMODE)
+ if (graph->instruction_code==GMULUD)
+ calculate_mulud_operator (graph_0);
+ else
+ calculate_divdu_operator (graph_0);
+
+ graph->order_mode=R_DREGISTER;
+ graph->u_aregs=graph_0->u_aregs;
+ graph->u_dregs=graph_0->u_dregs;
+ graph->i_aregs=graph_0->i_aregs;
+ graph->i_dregs=graph_0->i_dregs;
+
+ graph->order_alterable=graph->node_count<=1;
+ return;
+ }
+#endif
default:
/* printf ("%d\n",graph->instruction_code); */
internal_error_in_function ("calculate_graph_register_uses");
@@ -2515,6 +2647,9 @@ void count_graph (INSTRUCTION_GRAPH graph)
#ifdef G_POWER
case GUMULH:
#endif
+#ifdef I486
+ case GMULUD:
+#endif
if (++graph->node_count==1){
count_graph (graph->instruction_parameters[0].p);
count_graph (graph->instruction_parameters[1].p);
@@ -2528,21 +2663,27 @@ void count_graph (INSTRUCTION_GRAPH graph)
case GFCOS:
case GFSIN:
case GFTAN:
+ case GFATAN:
+ case GFSQRT:
+ case GFNEG:
+ case GFABS:
+#ifdef M68000
case GFASIN:
case GFACOS:
- case GFATAN:
case GFLN:
case GFLOG10:
case GFEXP:
- case GFSQRT:
- case GFNEG:
- case GFABS:
+#endif
case GNEG:
#if defined (I486) || defined (G_POWER)
case GNOT:
#endif
case GBEFORE0:
case GTEST_O:
+#ifdef I486
+ case GRESULT0:
+ case GRESULT1:
+#endif
if (++graph->node_count==1)
count_graph (graph->instruction_parameters[0].p);
break;
@@ -2633,6 +2774,15 @@ void count_graph (INSTRUCTION_GRAPH graph)
case GREGISTER:
++graph->node_count;
break;
+#ifdef I486
+ case GDIVDU:
+ if (++graph->node_count==1){
+ count_graph (graph->instruction_parameters[0].p);
+ count_graph (graph->instruction_parameters[1].p);
+ count_graph (graph->instruction_parameters[2].p);
+ }
+ break;
+#endif
default:
internal_error_in_function ("count_graph");
}
@@ -2680,6 +2830,9 @@ void mark_graph_2 (register INSTRUCTION_GRAPH graph)
#ifdef G_POWER
case GUMULH:
#endif
+#ifdef I486
+ case GMULUD:
+#endif
if (graph->node_mark<2){
graph->node_mark=2;
mark_graph_2 (graph->instruction_parameters[0].p);
@@ -2694,21 +2847,27 @@ void mark_graph_2 (register INSTRUCTION_GRAPH graph)
case GFCOS:
case GFSIN:
case GFTAN:
+ case GFATAN:
+ case GFSQRT:
+ case GFNEG:
+ case GFABS:
+#ifdef M68000
case GFASIN:
case GFACOS:
- case GFATAN:
case GFLN:
case GFLOG10:
case GFEXP:
- case GFSQRT:
- case GFNEG:
- case GFABS:
+#endif
case GNEG:
#if defined (I486) || defined (G_POWER)
case GNOT:
#endif
case GBEFORE0:
case GTEST_O:
+#ifdef I486
+ case GRESULT0:
+ case GRESULT1:
+#endif
if (graph->node_mark<2){
graph->node_mark=2;
mark_graph_2 (graph->instruction_parameters[0].p);
@@ -2813,6 +2972,16 @@ void mark_graph_2 (register INSTRUCTION_GRAPH graph)
case GREGISTER:
graph->node_mark=2;
break;
+#ifdef I486
+ case GDIVDU:
+ if (graph->node_mark<2){
+ graph->node_mark=2;
+ mark_graph_2 (graph->instruction_parameters[0].p);
+ mark_graph_2 (graph->instruction_parameters[1].p);
+ mark_graph_2 (graph->instruction_parameters[2].p);
+ }
+ break;
+#endif
default:
internal_error_in_function ("mark_graph_2");
}
@@ -2860,6 +3029,9 @@ void mark_graph_1 (register INSTRUCTION_GRAPH graph)
#ifdef G_POWER
case GUMULH:
#endif
+#ifdef I486
+ case GMULUD:
+#endif
if (!graph->node_mark){
graph->node_mark=1;
mark_graph_2 (graph->instruction_parameters[0].p);
@@ -2872,21 +3044,27 @@ void mark_graph_1 (register INSTRUCTION_GRAPH graph)
case GFCOS:
case GFSIN:
case GFTAN:
+ case GFATAN:
+ case GFSQRT:
+ case GFNEG:
+ case GFABS:
+#ifdef M68000
case GFASIN:
case GFACOS:
- case GFATAN:
case GFLN:
case GFLOG10:
case GFEXP:
- case GFSQRT:
- case GFNEG:
- case GFABS:
+#endif
#if defined (I486) || defined (G_POWER)
case GNEG:
case GNOT:
#endif
case GBEFORE0:
case GTEST_O:
+#ifdef I486
+ case GRESULT0:
+ case GRESULT1:
+#endif
if (!graph->node_mark){
graph->node_mark=1;
mark_graph_2 (graph->instruction_parameters[0].p);
@@ -2999,6 +3177,16 @@ void mark_graph_1 (register INSTRUCTION_GRAPH graph)
mark_graph_1 (graph->instruction_parameters[0].p);
}
break;
+#ifdef I486
+ case GDIVDU:
+ if (!graph->node_mark){
+ graph->node_mark=1;
+ mark_graph_2 (graph->instruction_parameters[0].p);
+ mark_graph_2 (graph->instruction_parameters[1].p);
+ mark_graph_2 (graph->instruction_parameters[2].p);
+ }
+ break;
+#endif
default:
internal_error_in_function ("mark_graph_1");
}
diff --git a/cgcode.c b/cgcode.c
index f7fae7a..b05139d 100644
--- a/cgcode.c
+++ b/cgcode.c
@@ -208,10 +208,8 @@ int no_time_profiling;
#define g_fcmp_gt(g1,g2) g_instruction_2(GFCMP_GT,(g1),(g2))
#define g_fcmp_lt(g1,g2) g_instruction_2(GFCMP_LT,(g1),(g2))
#define g_fdiv(g1,g2) g_instruction_2(GFDIV,(g1),(g2))
-#define g_fexp(g1) g_instruction_1(GFEXP,(g1))
#define g_fitor(g1) g_instruction_1(GFITOR,(g1))
-#define g_fln(g1) g_instruction_1(GFLN,(g1))
#define g_fmul(g1,g2) g_instruction_2(GFMUL,(g1),(g2))
#define g_frem(g1,g2) g_instruction_2(GFREM,(g1),(g2))
@@ -272,10 +270,13 @@ static LABEL *halt_label,*cmp_string_label,*eqD_label,
LABEL *new_int_reducer_label,*channelP_label,*stop_reducer_label,*send_request_label,
*send_graph_label,*string_to_string_node_label,*cat_string_label;
-static LABEL *add_real,*sub_real,*mul_real,*div_real,*eq_real,*gt_real,*lt_real,
- *i_to_r_real,*r_to_i_real,*sqrt_real,*exp_real,*ln_real,*log10_real,
- *cos_real,*sin_real,*tan_real,*acos_real,*asin_real,*atan_real,
- *pow_real,*entier_real_label;
+#ifdef M68000
+static LABEL *add_real,*sub_real,*mul_real,*div_real,*eq_real,*gt_real,*lt_real;
+#endif
+
+static LABEL *i_to_r_real,*r_to_i_real,*sqrt_real,*exp_real,*ln_real,*log10_real,
+ *cos_real,*sin_real,*tan_real,*acos_real,*asin_real,*atan_real,*pow_real,
+ *entier_real_label;
LABEL *copy_graph_label,*CHANNEL_label,*create_channel_label,*currentP_label,*newP_label,
*randomP_label,*suspend_label;
@@ -288,6 +289,10 @@ static LABEL *small_integers_label,*static_characters_label;
LABEL *eval_fill_label,*eval_upd_labels[33];
+#ifdef NEW_APPLY
+LABEL *add_empty_node_labels[33];
+#endif
+
static LABEL *print_r_arg_label,*push_t_r_args_label,*push_a_r_args_label;
LABEL *index_error_label;
@@ -491,16 +496,15 @@ void code_absR (void)
void code_acosR (VOID)
{
#ifdef M68000
- if (!mc68881_flag){
-#endif
- if (acos_real==NULL)
- acos_real=enter_label ("acos_real",IMPORT_LABEL);
- code_monadic_sane_operator (acos_real);
- init_b_stack (2,r_vector);
-#ifdef M68000
- } else
+ if (mc68881_flag){
code_monadic_real_operator (GFACOS);
+ return
+ }
#endif
+ if (acos_real==NULL)
+ acos_real=enter_label ("acos_real",IMPORT_LABEL);
+ code_monadic_sane_operator (acos_real);
+ init_b_stack (2,r_vector);
}
void code_addI (VOID)
@@ -595,16 +599,15 @@ void code_and (VOID)
void code_asinR (VOID)
{
#ifdef M68000
- if (!mc68881_flag){
-#endif
- if (asin_real==NULL)
- asin_real=enter_label ("asin_real",IMPORT_LABEL);
- code_monadic_sane_operator (asin_real);
- init_b_stack (2,r_vector);
-#ifdef M68000
- } else
+ if (mc68881_flag){
code_monadic_real_operator (GFASIN);
+ return;
+ }
#endif
+ if (asin_real==NULL)
+ asin_real=enter_label ("asin_real",IMPORT_LABEL);
+ code_monadic_sane_operator (asin_real);
+ init_b_stack (2,r_vector);
}
void code_atanR (VOID)
@@ -1840,6 +1843,30 @@ void code_divU (VOID)
}
#endif
+#ifdef I486
+void code_divLU (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 (GDIVDU,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
+
void code_entierR (VOID)
{
if (entier_real_label==NULL)
@@ -2238,16 +2265,15 @@ void code_exit_false (char label_name[])
void code_expR (VOID)
{
#ifdef M68000
- if (!mc68881_flag){
-#endif
- if (exp_real==NULL)
- exp_real=enter_label ("exp_real",IMPORT_LABEL);
- code_monadic_sane_operator (exp_real);
- init_b_stack (2,r_vector);
-#ifdef M68000
- } else
+ if (mc68881_flag){
code_monadic_real_operator (GFEXP);
+ return;
+ }
#endif
+ if (exp_real==NULL)
+ exp_real=enter_label ("exp_real",IMPORT_LABEL);
+ code_monadic_sane_operator (exp_real);
+ init_b_stack (2,r_vector);
}
void code_fill_r (char descriptor_name[],int a_size,int b_size,int root_offset,int a_offset,int b_offset)
@@ -3441,63 +3467,70 @@ static struct basic_block *profile_function_block;
int profile_flag=PROFILE_NORMAL;
-static void code_jmp_ap_ (void)
+static void code_jmp_ap_ (int n_apply_args)
{
+ if (n_apply_args==1){
#if defined (I486)
- end_basic_block_with_registers (2,0,e_vector);
- i_move_id_r (0,REGISTER_A1,REGISTER_A2);
+ end_basic_block_with_registers (2,0,e_vector);
+ i_move_id_r (0,REGISTER_A1,REGISTER_A2);
# ifdef PROFILE
- if (profile_function_label!=NULL)
- i_jmp_id_profile (4-2,REGISTER_A2,0);
- else
+ if (profile_function_label!=NULL)
+ i_jmp_id_profile (4-2,REGISTER_A2,0);
+ else
# endif
- i_jmp_id (4-2,REGISTER_A2,0);
+ i_jmp_id (4-2,REGISTER_A2,0);
#else
- INSTRUCTION_GRAPH graph_1,graph_2,graph_3,graph_4,graph_5;
+ INSTRUCTION_GRAPH graph_1,graph_2,graph_3,graph_4,graph_5;
- graph_1=s_get_a (0);
+ graph_1=s_get_a (0);
# if defined (sparc) || defined (G_POWER)
# pragma unused (graph_3,graph_4)
- graph_2=g_load_id (0,graph_1);
- graph_5=g_load_id (4-2,graph_2);
+ graph_2=g_load_id (0,graph_1);
+ graph_5=g_load_id (4-2,graph_2);
# else
- graph_2=g_load_des_id (DESCRIPTOR_OFFSET,graph_1);
- graph_3=g_g_register (GLOBAL_DATA_REGISTER);
+ 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_4=g_add (graph_3,graph_2);
# if defined (M68000) && !defined (SUN)
- graph_5=g_load_des_id (2,graph_4);
+ graph_5=g_load_des_id (2,graph_4);
# else
- graph_5=g_load_id (4,graph_4);
+ graph_5=g_load_id (4,graph_4);
# endif
# endif
- s_push_a (graph_5);
+ s_push_a (graph_5);
- end_basic_block_with_registers (3,0,e_vector);
+ end_basic_block_with_registers (3,0,e_vector);
# if defined (M68000) && !defined (SUN)
- i_add_r_r (GLOBAL_DATA_REGISTER,REGISTER_A2);
+ i_add_r_r (GLOBAL_DATA_REGISTER,REGISTER_A2);
# endif
# ifdef PROFILE
- if (profile_function_label!=NULL)
- i_jmp_id_profile (0,REGISTER_A2,2<<4);
- else
+ if (profile_function_label!=NULL)
+ i_jmp_id_profile (0,REGISTER_A2,2<<4);
+ else
# endif
- i_jmp_id (0,REGISTER_A2,2<<4);
+ i_jmp_id (0,REGISTER_A2,2<<4);
#endif
- demand_flag=0;
+ demand_flag=0;
- reachable=0;
+ reachable=0;
- begin_new_basic_block();
+ begin_new_basic_block();
+ } else {
+ char ap_label_name[32];
+
+ sprintf (ap_label_name,"ap_%d",n_apply_args);
+ code_jmp (ap_label_name);
+ }
}
void code_jmp (char label_name[])
{
if (!strcmp (label_name,"e__system__sAP"))
- code_jmp_ap_();
+ code_jmp_ap_(1);
else {
LABEL *label;
int a_stack_size,b_stack_size,n_a_and_f_registers;
@@ -3581,10 +3614,10 @@ void code_jmp (char label_name[])
}
}
-void code_jmp_ap (void)
+void code_jmp_ap (int n_apply_args)
{
- code_d (2,0,e_vector);
- code_jmp_ap_();
+ code_d (1+n_apply_args,0,e_vector);
+ code_jmp_ap_ (n_apply_args);
}
void code_label (char *label_name);
@@ -3864,46 +3897,53 @@ static int too_many_b_stack_parameters_for_registers (int b_stack_size,int n_dat
}
#endif
-static void code_jsr_ap_ (void)
+static void code_jsr_ap_ (int n_apply_args)
{
INSTRUCTION_GRAPH graph_1,graph_2,graph_3,graph_4,graph_5;
+ if (n_apply_args==1){
#if !defined (I486)
- graph_1=s_get_a (0);
+ graph_1=s_get_a (0);
# if defined (sparc) || defined (G_POWER)
# pragma unused (graph_3,graph_4)
- graph_2=g_load_id (0,graph_1);
- graph_5=g_load_id (4-2,graph_2);
+ graph_2=g_load_id (0,graph_1);
+ graph_5=g_load_id (4-2,graph_2);
# else
- 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_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);
# if defined (M68000) && !defined (SUN)
- graph_5=g_load_des_id (2,graph_4);
+ graph_5=g_load_des_id (2,graph_4);
# else
- graph_5=g_load_id (4,graph_4);
+ graph_5=g_load_id (4,graph_4);
# endif
# endif
- s_push_a (graph_5);
+ s_push_a (graph_5);
#endif
- if (demand_flag)
- offered_after_jsr=1;
- demand_flag=0;
+ if (demand_flag)
+ offered_after_jsr=1;
+ demand_flag=0;
#if defined (I486)
- insert_basic_block (APPLY_BLOCK,2,0,e_vector,NULL);
+ insert_basic_block (APPLY_BLOCK,2,0,e_vector,NULL);
#else
- insert_basic_block (APPLY_BLOCK,3,0,e_vector,NULL);
+ insert_basic_block (APPLY_BLOCK,3,0,e_vector,NULL);
#endif
- init_a_stack (1);
+ init_a_stack (1);
+ } else {
+ char ap_label_name[32];
+
+ sprintf (ap_label_name,"ap_%d",n_apply_args);
+ code_jsr (ap_label_name);
+ }
}
void code_jsr (char label_name[])
{
if (!strcmp (label_name,"e__system__sAP"))
- code_jsr_ap_();
+ code_jsr_ap_ (1);
else {
LABEL *label;
INSTRUCTION_GRAPH graph;
@@ -3953,10 +3993,10 @@ void code_jsr (char label_name[])
}
}
-void code_jsr_ap (void)
+void code_jsr_ap (int n_apply_args)
{
- code_d (2,0,e_vector);
- code_jsr_ap_();
+ code_d (1+n_apply_args,0,e_vector);
+ code_jsr_ap_ (n_apply_args);
code_o (1,0,e_vector);
}
@@ -4064,31 +4104,29 @@ void code_keep (int a_offset_1,int a_offset_2)
void code_lnR (VOID)
{
#ifdef M68000
- if (!mc68881_flag){
-#endif
- if (ln_real==NULL)
- ln_real=enter_label ("ln_real",IMPORT_LABEL);
- code_monadic_sane_operator (ln_real);
- init_b_stack (2,r_vector);
-#ifdef M68000
- } else
+ if (mc68881_flag){
code_monadic_real_operator (GFLN);
+ return;
+ }
#endif
+ if (ln_real==NULL)
+ ln_real=enter_label ("ln_real",IMPORT_LABEL);
+ code_monadic_sane_operator (ln_real);
+ init_b_stack (2,r_vector);
}
void code_log10R (VOID)
{
#ifdef M68000
- if (!mc68881_flag){
-#endif
- if (log10_real==NULL)
- log10_real=enter_label ("log10_real",IMPORT_LABEL);
- code_monadic_sane_operator (log10_real);
- init_b_stack (2,r_vector);
-#ifdef M68000
- } else
+ if (mc68881_flag){
code_monadic_real_operator (GFLOG10);
+ return;
+ }
#endif
+ if (log10_real==NULL)
+ log10_real=enter_label ("log10_real",IMPORT_LABEL);
+ code_monadic_sane_operator (log10_real);
+ init_b_stack (2,r_vector);
}
void code_ltC (VOID)
@@ -4291,17 +4329,27 @@ void code_mulI (VOID)
#endif
}
-#ifdef G_POWER
-void code_umulIIL (VOID)
+#if defined (I486) || defined (G_POWER)
+void code_mulUUL (VOID)
{
INSTRUCTION_GRAPH graph_1,graph_2,graph_3,graph_4;
+# ifdef I486
+ INSTRUCTION_GRAPH graph_5;
+# endif
- graph_1=s_get_b (1);
- graph_2=s_get_b (0);
+ graph_1=s_get_b (0);
+ graph_2=s_get_b (1);
+# ifdef G_POWER
graph_3=g_mul (graph_1,graph_2);
graph_4=g_umulh (graph_1,graph_2);
-
+# else
+ graph_5=g_instruction_2 (GMULUD,graph_1,graph_2);
+ graph_3=g_instruction_2 (GRESULT1,graph_5,NULL);
+ graph_4=g_instruction_2 (GRESULT0,graph_5,NULL);
+ graph_3->instruction_parameters[1].p=graph_4;
+ graph_4->instruction_parameters[1].p=graph_3;
+#endif
s_put_b (1,graph_3);
s_put_b (0,graph_4);
}
@@ -4345,6 +4393,22 @@ void code_mulR (VOID)
#endif
}
+#ifdef NEW_APPLY
+void code_a (int n_apply_args,char *ea_label_name)
+{
+ LABEL *label;
+ char add_empty_node_label_name[32];
+
+ last_block->block_n_node_arguments=-200+n_apply_args;
+ last_block->block_ea_label=enter_label (ea_label_name,0);
+
+ if (n_apply_args>0 && add_empty_node_labels[n_apply_args]==NULL){
+ sprintf (add_empty_node_label_name,"add_empty_node_%d",n_apply_args);
+ add_empty_node_labels[n_apply_args]=enter_label (add_empty_node_label_name,IMPORT_LABEL);
+ }
+}
+#endif
+
void code_n (int number_of_arguments,char *descriptor_name,char *ea_label_name)
{
LABEL *label;
@@ -8599,6 +8663,11 @@ void initialize_coding (VOID)
for (n=0; n<=32; ++n)
eval_upd_labels[n]=NULL;
+#ifdef NEW_APPLY
+ for (n=0; n<=32; ++n)
+ add_empty_node_labels[n]=NULL;
+#endif
+
for (n=0; n<=MAX_YET_ARGS_NEEDED_ARITY; ++n)
yet_args_needed_labels[n]=NULL;
diff --git a/cgcodep.h b/cgcodep.h
index 7ba6489..ca6f612 100644
--- a/cgcodep.h
+++ b/cgcodep.h
@@ -62,6 +62,9 @@ void code_create_channel (char *label_name);
void code_decI (VOID);
void code_del_args (int source_offset,int n_arguments,int destination_offset);
void code_divI (VOID);
+#ifdef I486
+void code_divLU (VOID);
+#endif
void code_divR (VOID);
#if defined (I486) || defined (G_POWER)
void code_divU (VOID);
@@ -129,13 +132,13 @@ void code_ItoC (VOID);
void code_ItoP (VOID);
void code_ItoR (VOID);
void code_jmp (char label_name[]);
-void code_jmp_ap (void);
+void code_jmp_ap (int n_args);
void code_jmp_eval (VOID);
void code_jmp_eval_upd (VOID);
void code_jmp_false (char label_name[]);
void code_jmp_true (char label_name[]);
void code_jsr (char label_name[]);
-void code_jsr_ap (void);
+void code_jsr_ap (int n_args);
void code_jsr_eval (int a_offset);
void code_lnR (VOID);
void code_log10R (VOID);
@@ -154,6 +157,9 @@ void code_mulI (VOID);
void code_mulIo (VOID);
#endif
void code_mulR (VOID);
+#if defined (I486) || defined (G_POWER)
+void code_mulUUL (VOID);
+#endif
void code_negI (void);
void code_negR (VOID);
void code_new_ext_reducer (char descriptor_name[],int a_offset);
@@ -260,11 +266,11 @@ 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);
+#ifdef NEW_APPLY
+void code_a (int number_of_arguments,char *ea_label_name);
+#endif
void code_caf (char *label_name,int a_size,int b_size);
void code_comp (int version,char *options);
void code_d (int da,int db,ULONG vector[]);
diff --git a/cgconst.h b/cgconst.h
index 882fcc7..e94eb66 100644
--- a/cgconst.h
+++ b/cgconst.h
@@ -3,18 +3,17 @@ enum {
GADD, GADD_O, GAND, GALLOCATE, GASR, GBEFORE,
GBEFORE0, GBOUNDS, GCMP_EQ, GCMP_GT, GCMP_GTU, GCMP_LT,
GCMP_LTU, GCNOT, GCOPY, GCREATE, GCREATE_R, GDIV,
- GEOR, GFABS, 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, GNEG, GOR,
- GREGISTER, GSTORE, GSTORE_R, GSTORE_B_X, GSTORE_X, GSUB,
- GSUB_O, GTEST_O, GEXIT_IF
+ GEOR, GFABS, GFADD, GFCMP_EQ, GFCMP_GT, GFATAN,
+ GFCMP_LT, GFCOS, GFDIV, GFHIGH, GFITOR, GFJOIN,
+ GFKEEP, GFLOAD, GFLOAD_I, GFLOAD_ID, GFLOAD_X, 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, GNEG,
+ GOR, GREGISTER, GSTORE, GSTORE_R, GSTORE_B_X, GSTORE_X,
+ GSUB, GSUB_O, GTEST_O, GEXIT_IF
#if defined (I486) || defined (G_POWER)
,GNOT
#endif
@@ -25,7 +24,10 @@ enum {
,GDIVU
#endif
#ifdef I486
- ,GREMU
+ ,GREMU, GMULUD, GDIVDU, GRESULT0, GRESULT1
+#endif
+#ifdef M68000
+ ,GFACOS, GFASIN, GFEXP, GFLN, GFLOG10
#endif
};
diff --git a/cgias.c b/cgias.c
index aa0942c..dd9059d 100644
--- a/cgias.c
+++ b/cgias.c
@@ -2425,7 +2425,7 @@ static void as_rem_instruction (struct instruction *instruction,int unsigned_rem
as_move_r_r (REGISTER_O0,REGISTER_D0);
break;
- default:
+ default:
as_move_r_r (REGISTER_A1,REGISTER_O0);
store_c (0x90+reg_num (d_reg)); /* xchg d_reg,D0 */
@@ -2467,6 +2467,177 @@ static void as_rem_instruction (struct instruction *instruction,int unsigned_rem
}
}
+static void as_2move_registers (int reg1,int reg2,int reg3)
+{
+ as_move_r_r (reg2,reg3);
+ as_move_r_r (reg1,reg2);
+}
+
+static void as_3move_registers (int reg1,int reg2,int reg3,int reg4)
+{
+ as_move_r_r (reg3,reg4);
+ as_move_r_r (reg2,reg3);
+ as_move_r_r (reg1,reg2);
+}
+
+static void as_mulud_instruction (struct instruction *instruction)
+{
+ int reg_1,reg_2;
+
+ reg_1=instruction->instruction_parameters[0].parameter_data.reg.r;
+ reg_2=instruction->instruction_parameters[1].parameter_data.reg.r;
+
+ if (reg_2==REGISTER_D0){
+ if (reg_1==REGISTER_A1)
+ as_r (0367,040,reg_1); /* mul */
+ else {
+ as_move_r_r (REGISTER_A1,REGISTER_O0);
+ as_r (0367,040,reg_1); /* mul */
+ as_2move_registers (REGISTER_O0,REGISTER_A1,reg_1);
+ }
+ } else if (reg_1==REGISTER_A1){
+ as_2move_registers (reg_2,REGISTER_D0,REGISTER_O0);
+ as_r (0367,040,reg_1); /* mul */
+ as_2move_registers (REGISTER_O0,REGISTER_D0,reg_2);
+ } else if (reg_1==REGISTER_D0){
+ if (reg_2==REGISTER_A1){
+ as_r (0367,040,REGISTER_A1); /* mul */
+ store_c (0x90+reg_num (REGISTER_A1)); /* xchg A1,D0 */
+ } else {
+ as_move_r_r (REGISTER_A1,REGISTER_O0);
+ as_r (0367,040,reg_2); /* mul */
+ as_3move_registers (REGISTER_O0,REGISTER_A1,REGISTER_D0,reg_2);
+ }
+ } else if (reg_2==REGISTER_A1){
+ as_2move_registers (reg_2,REGISTER_D0,REGISTER_O0);
+ as_r (0367,040,reg_1); /* mul */
+ as_3move_registers (REGISTER_O0,REGISTER_D0,REGISTER_A1,reg_1);
+ } else {
+ store_c (0x90+reg_num (reg_2)); /* xchg reg_2,D0 */
+ as_move_r_r (REGISTER_A1,REGISTER_O0);
+ as_r (0367,040,reg_1); /* mul */
+ store_c (0x90+reg_num (reg_2)); /* xchg reg_2,D0 */
+ as_2move_registers (REGISTER_O0,REGISTER_A1,reg_1);
+ }
+}
+
+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;
+
+ if (reg_1==REGISTER_D0){
+ if (reg_3==REGISTER_D0){
+ if (reg_2==REGISTER_A1)
+ as_r (0367,0060,reg_1); /* div */
+ else {
+ as_2move_registers (reg_2,REGISTER_A1,REGISTER_O0);
+ as_r (0367,0060,reg_1); /* div */
+ as_2move_registers (REGISTER_O0,REGISTER_A1,reg_2);
+ }
+ } else if (reg_3==REGISTER_A1){
+ if (reg_2==REGISTER_D0){
+ store_c (0x90+reg_num (REGISTER_A1)); /* xchg A1,D0 */
+ as_r (0367,0060,REGISTER_A1); /* div */
+ store_c (0x90+reg_num (REGISTER_A1)); /* xchg A1,D0 */
+ } else {
+ as_3move_registers (reg_2,REGISTER_A1,REGISTER_D0,REGISTER_O0);
+ as_r (0367,0060,REGISTER_O0); /* div */
+ as_3move_registers (REGISTER_O0,REGISTER_D0,REGISTER_A1,reg_2);
+ }
+ } else {
+ if (reg_2==REGISTER_A1){
+ as_2move_registers (reg_3,REGISTER_D0,REGISTER_O0);
+ as_r (0367,0060,REGISTER_O0); /* div */
+ as_2move_registers (REGISTER_O0,REGISTER_D0,reg_3);
+ } else if (reg_2==REGISTER_D0){
+ as_3move_registers (reg_3,REGISTER_D0,REGISTER_A1,REGISTER_O0);
+ as_r (0367,0060,REGISTER_A1); /* div */
+ as_3move_registers (REGISTER_O0,REGISTER_A1,REGISTER_D0,reg_3);
+ } else {
+ store_c (0x90+reg_num (reg_3)); /* xchg reg_3,D0 */
+ as_2move_registers (reg_2,REGISTER_A1,REGISTER_O0);
+ as_r (0367,0060,reg_3); /* div */
+ as_2move_registers (REGISTER_O0,REGISTER_A1,reg_2);
+ store_c (0x90+reg_num (reg_3)); /* xchg reg_3,D0 */
+ }
+ }
+ } else if (reg_1==REGISTER_A1){
+ if (reg_2==REGISTER_A1){
+ if (reg_3==REGISTER_D0)
+ as_r (0367,0060,reg_1); /* div */
+ else {
+ as_2move_registers (reg_3,REGISTER_D0,REGISTER_O0);
+ as_r (0367,0060,reg_1); /* div */
+ as_2move_registers (REGISTER_O0,REGISTER_D0,reg_3);
+ }
+ } else if (reg_2==REGISTER_D0){
+ if (reg_3==REGISTER_A1){
+ store_c (0x90+reg_num (REGISTER_A1)); /* xchg A1,D0 */
+ as_r (0367,0060,REGISTER_D0); /* div */
+ store_c (0x90+reg_num (REGISTER_A1)); /* xchg A1,D0 */
+ } else {
+ as_3move_registers (reg_3,REGISTER_D0,REGISTER_A1,REGISTER_O0);
+ as_r (0367,0060,REGISTER_O0); /* div */
+ as_3move_registers (REGISTER_O0,REGISTER_A1,REGISTER_D0,reg_3);
+ }
+ } else {
+ if (reg_3==REGISTER_D0){
+ as_2move_registers (reg_2,REGISTER_A1,REGISTER_O0);
+ as_r (0367,0060,REGISTER_O0); /* div */
+ as_2move_registers (REGISTER_O0,REGISTER_A1,reg_2);
+ } else if (reg_3==REGISTER_A1){
+ as_3move_registers (reg_2,REGISTER_A1,REGISTER_D0,REGISTER_O0);
+ as_r (0367,0060,REGISTER_D0); /* div */
+ as_3move_registers (REGISTER_O0,REGISTER_D0,REGISTER_A1,reg_2);
+ } else {
+ as_r_r (0207,reg_2,REGISTER_A1); /* xchg */
+ as_2move_registers (reg_3,REGISTER_D0,REGISTER_O0);
+ as_r (0367,0060,reg_2); /* div */
+ as_2move_registers (REGISTER_O0,REGISTER_D0,reg_3);
+ as_r_r (0207,reg_2,REGISTER_A1); /* xchg */
+ }
+ }
+ } else {
+ if (reg_3==REGISTER_D0){
+ if (reg_2==REGISTER_A1){
+ as_r (0367,0060,reg_1); /* div */
+ } else {
+ as_2move_registers (reg_2,REGISTER_A1,REGISTER_O0);
+ as_r (0367,0060,reg_1); /* div */
+ as_2move_registers (REGISTER_O0,REGISTER_A1,reg_2);
+ }
+ } else if (reg_2==REGISTER_A1){
+ as_2move_registers (reg_3,REGISTER_D0,REGISTER_O0);
+ as_r (0367,0060,reg_1); /* div */
+ as_2move_registers (REGISTER_O0,REGISTER_D0,reg_3);
+ } else if (reg_2==REGISTER_D0){
+ if (reg_3==REGISTER_A1){
+ store_c (0x90+reg_num (REGISTER_A1)); /* xchg A1,D0 */
+ as_r (0367,0060,reg_1); /* div */
+ store_c (0x90+reg_num (REGISTER_A1)); /* xchg A1,D0 */
+ } else {
+ as_3move_registers (reg_3,REGISTER_D0,REGISTER_A1,REGISTER_O0);
+ as_r (0367,0060,reg_1); /* div */
+ as_3move_registers (REGISTER_O0,REGISTER_A1,REGISTER_D0,reg_3);
+ }
+ } else if (reg_2==REGISTER_A1){
+ as_3move_registers (reg_3,REGISTER_A1,REGISTER_D0,REGISTER_O0);
+ as_r (0367,0060,reg_1); /* div */
+ as_3move_registers (REGISTER_O0,REGISTER_D0,REGISTER_A1,reg_3);
+ } else {
+ store_c (0x90+reg_num (reg_3)); /* xchg reg_3,D0 */
+ as_2move_registers (reg_2,REGISTER_A1,REGISTER_O0);
+ as_r (0367,0060,reg_1); /* div */
+ as_2move_registers (REGISTER_O0,REGISTER_A1,reg_2);
+ store_c (0x90+reg_num (reg_3)); /* xchg reg_3,D0 */
+ }
+ }
+}
+
static void as_set_condition_instruction (struct instruction *instruction,int condition_code)
{
int r;
@@ -3970,6 +4141,12 @@ static void as_instructions (struct instruction *instruction)
case INOT:
as_not_instruction (instruction);
break;
+ case IMULUD:
+ as_mulud_instruction (instruction);
+ break;
+ case IDIVDU:
+ as_divdu_instruction (instruction);
+ break;
case IWORD:
store_c (instruction->instruction_parameters[0].parameter_data.i);
break;
@@ -4179,6 +4356,135 @@ static void as_check_stack (struct basic_block *block)
}
}
+static void as_profile_call (struct basic_block *block)
+{
+ LABEL *profile_label;
+
+ as_move_d_r (block->block_profile_function_label,0,REGISTER_A2);
+
+ if (block->block_n_node_arguments>-100)
+ profile_label=block->block_profile==2 ? profile_n2_label : profile_n_label;
+ else {
+ switch (block->block_profile){
+ case 2: profile_label=profile_s2_label; break;
+ case 4: profile_label=profile_l_label; break;
+ case 5: profile_label=profile_l2_label; break;
+ default: profile_label=profile_s_label;
+ }
+ }
+ store_c (0350);
+ store_l (0);
+ as_branch_label (profile_label,CALL_RELOCATION);
+}
+
+#ifdef NEW_APPLY
+extern LABEL *add_empty_node_labels[];
+
+static void as_apply_update_entry (struct basic_block *block)
+{
+ if (block->block_profile)
+ as_profile_call (block);
+
+ if (block->block_n_node_arguments==-200){
+ store_c (0351);
+ store_l (0);
+ as_branch_label (block->block_ea_label,JUMP_RELOCATION);
+
+ store_c (0x90);
+ store_c (0x90);
+ store_c (0x90);
+ store_c (0x90);
+ store_c (0x90);
+ } else {
+ store_c (0350); /* call */
+ store_l (0);
+ as_branch_label (add_empty_node_labels[block->block_n_node_arguments+200],CALL_RELOCATION);
+
+ store_c (0351);
+ store_l (0);
+ as_branch_label (block->block_ea_label,JUMP_RELOCATION);
+ }
+
+ if (!block->block_profile){
+ store_c (0x90);
+ store_c (0x90);
+ }
+}
+#endif
+
+static void as_node_entry_info (struct basic_block *block)
+{
+ if (block->block_ea_label!=NULL){
+ extern LABEL *eval_fill_label,*eval_upd_labels[];
+ int n_node_arguments;
+
+ n_node_arguments=block->block_n_node_arguments;
+ if (n_node_arguments<-2)
+ n_node_arguments=1;
+
+ if (n_node_arguments>=0 && block->block_ea_label!=eval_fill_label){
+#if 1
+ if (!block->block_profile){
+ as_move_l_r (block->block_ea_label,REGISTER_A2);
+
+ store_c (0351);
+ store_l (0);
+ as_branch_label (eval_upd_labels[n_node_arguments],JUMP_RELOCATION);
+
+ store_c (0x90);
+ store_c (0x90);
+ } else {
+ store_c (0351);
+ store_l (-7);
+ as_branch_label (eval_upd_labels[n_node_arguments],JUMP_RELOCATION);
+
+ store_c (0x90);
+ store_c (0x90);
+ store_c (0x90);
+
+ as_move_l_r (block->block_ea_label,REGISTER_D0);
+ as_move_l_r (block->block_profile_function_label,REGISTER_A2);
+
+ store_c (0xeb);
+ store_c (-20);
+ }
+#else
+ as_move_l_r (eval_upd_labels[n_node_arguments],REGISTER_D0);
+ as_move_l_r (block->block_ea_label,REGISTER_A2);
+
+ store_c (0377);
+ store_c (0340 | reg_num (REGISTER_D0)); /* jmp d0 */
+#endif
+ } else {
+ as_move_l_r (block->block_ea_label,REGISTER_D0);
+
+ store_c (0377);
+ store_c (0340 | reg_num (REGISTER_D0)); /* jmp d0 */
+
+ store_c (0x90);
+ store_c (0x90);
+ store_c (0x90);
+ store_c (0x90);
+ store_c (0x90);
+ }
+
+ if (block->block_descriptor!=NULL && (block->block_n_node_arguments<0 || parallel_flag || module_info_flag)){
+ store_l (0);
+ store_label_in_code_section (block->block_descriptor);
+ } else
+ store_l (0);
+ } else
+ if (block->block_descriptor!=NULL && (block->block_n_node_arguments<0 || parallel_flag || module_info_flag)){
+ store_l (0);
+ store_label_in_code_section (block->block_descriptor);
+ }
+ /* else
+ store_l (0);
+ */
+
+ store_l (block->block_n_node_arguments);
+}
+
static void write_code (void)
{
struct basic_block *block;
@@ -4294,98 +4600,17 @@ static void write_code (void)
store_c (0x90);
#endif
- if (block->block_ea_label!=NULL){
- extern LABEL *eval_fill_label,*eval_upd_labels[];
- int n_node_arguments;
-
- n_node_arguments=block->block_n_node_arguments;
- if (n_node_arguments<-2)
- n_node_arguments=1;
-
- if (n_node_arguments>=0 && block->block_ea_label!=eval_fill_label){
-#if 1
- if (!block->block_profile){
- as_move_l_r (block->block_ea_label,REGISTER_A2);
-
- store_c (0351);
- store_l (0);
- as_branch_label (eval_upd_labels[n_node_arguments],JUMP_RELOCATION);
-
- store_c (0x90);
- store_c (0x90);
- } else {
- store_c (0351);
- store_l (-7);
- as_branch_label (eval_upd_labels[n_node_arguments],JUMP_RELOCATION);
-
- store_c (0x90);
- store_c (0x90);
- store_c (0x90);
-
- as_move_l_r (block->block_ea_label,REGISTER_D0);
- as_move_l_r (block->block_profile_function_label,REGISTER_A2);
-
- store_c (0xeb);
- store_c (-20);
- }
-#else
- as_move_l_r (eval_upd_labels[n_node_arguments],REGISTER_D0);
- as_move_l_r (block->block_ea_label,REGISTER_A2);
-
- store_c (0377);
- store_c (0340 | reg_num (REGISTER_D0)); /* jmp d0 */
-#endif
- } else {
- as_move_l_r (block->block_ea_label,REGISTER_D0);
-
- store_c (0377);
- store_c (0340 | reg_num (REGISTER_D0)); /* jmp d0 */
-
- store_c (0x90);
- store_c (0x90);
- store_c (0x90);
- store_c (0x90);
- store_c (0x90);
- }
-
- if (block->block_descriptor!=NULL && (block->block_n_node_arguments<0 || parallel_flag || module_info_flag)){
- store_l (0);
- store_label_in_code_section (block->block_descriptor);
- } else
- store_l (0);
- } else
- if (block->block_descriptor!=NULL && (block->block_n_node_arguments<0 || parallel_flag || module_info_flag)){
- store_l (0);
- store_label_in_code_section (block->block_descriptor);
- }
- /* else
- store_l (0);
- */
-
- store_l (block->block_n_node_arguments);
+ as_node_entry_info (block);
}
+#ifdef NEW_APPLY
+ else if (block->block_n_node_arguments<-100)
+ as_apply_update_entry (block);
+#endif
as_labels (block->block_labels);
- if (block->block_profile){
- LABEL *profile_label;
-
- as_move_d_r (block->block_profile_function_label,0,REGISTER_A2);
-
- if (block->block_n_node_arguments>-100)
- profile_label=block->block_profile==2 ? profile_n2_label : profile_n_label;
- else {
- switch (block->block_profile){
- case 2: profile_label=profile_s2_label; break;
- case 4: profile_label=profile_l_label; break;
- case 5: profile_label=profile_l2_label; break;
- default: profile_label=profile_s_label;
- }
- }
- store_c (0350);
- store_l (0);
- as_branch_label (profile_label,CALL_RELOCATION);
- }
+ if (block->block_profile)
+ as_profile_call (block);
if (block->block_n_new_heap_cells>0)
as_garbage_collect_test (block);
diff --git a/cgiconst.h b/cgiconst.h
index 95f9315..37ff784 100644
--- a/cgiconst.h
+++ b/cgiconst.h
@@ -55,7 +55,7 @@ enum {
,IFEXG
#endif
#if defined (I486)
- ,IRTSI, IDIVI, IREMI, IREMU
+ ,IRTSI, IDIVI, IREMI, IREMU, IMULUD, IDIVDU
#endif
#if defined (I486) || defined (G_POWER)
,IDIVU
diff --git a/cginput.c b/cginput.c
index 4e0b77f..1cda6b5 100644
--- a/cginput.c
+++ b/cginput.c
@@ -1168,6 +1168,22 @@ static int parse_directive (InstructionP instruction)
return 1;
}
+#ifdef NEW_APPLY
+static int parse_directive_a (InstructionP instruction)
+{
+ LONG n;
+ STRING s;
+
+ if (!parse_integer (&n))
+ return 0;
+
+ parse_label (s);
+ instruction->instruction_code_function ((int)n,s);
+
+ return 1;
+}
+#endif
+
static int parse_directive_n (InstructionP instruction)
{
LONG n;
@@ -1761,6 +1777,9 @@ static void put_instructions_in_table (void)
put_instruction_name ("decI", parse_instruction, code_decI );
put_instruction_name ("del_args", parse_instruction_n_n_n, code_del_args );
put_instruction_name ("divI", parse_instruction, code_divI );
+#ifdef I486
+ put_instruction_name ("divLU", parse_instruction, code_divLU );
+#endif
put_instruction_name ("divR", parse_instruction, code_divR );
#if defined (I486) || defined (G_POWER)
put_instruction_name ("divU", parse_instruction, code_divU );
@@ -1832,13 +1851,13 @@ static void put_instructions_in_table (void)
put_instruction_name ("ItoP", parse_instruction, code_ItoP );
put_instruction_name ("ItoR", parse_instruction, code_ItoR );
put_instruction_name ("jmp", parse_instruction_a, code_jmp );
- put_instruction_name ("jmp_ap", parse_instruction, code_jmp_ap );
+ put_instruction_name ("jmp_ap", parse_instruction_n, code_jmp_ap );
put_instruction_name ("jmp_eval", parse_instruction, code_jmp_eval );
put_instruction_name ("jmp_eval_upd", parse_instruction, code_jmp_eval_upd );
put_instruction_name ("jmp_false", parse_instruction_a, code_jmp_false );
put_instruction_name ("jmp_true", parse_instruction_a, code_jmp_true );
put_instruction_name ("jsr", parse_instruction_a, code_jsr );
- put_instruction_name ("jsr_ap", parse_instruction, code_jsr_ap );
+ put_instruction_name ("jsr_ap", parse_instruction_n, code_jsr_ap );
put_instruction_name ("jsr_eval", parse_instruction_n, code_jsr_eval );
put_instruction_name ("lnR", parse_instruction, code_lnR );
put_instruction_name ("log10R", parse_instruction, code_log10R );
@@ -1851,6 +1870,9 @@ static void put_instructions_in_table (void)
put_instruction_name ("modI", parse_instruction, code_remI );
put_instruction_name ("mulI", parse_instruction, code_mulI );
put_instruction_name ("mulR", parse_instruction, code_mulR );
+#if defined (I486) || defined (G_POWER)
+ put_instruction_name ("mulUUL", parse_instruction, code_mulUUL );
+#endif
put_instruction_name ("negI", parse_instruction, code_negI );
put_instruction_name ("negR", parse_instruction, code_negR );
put_instruction_name ("new_ext_reducer",parse_instruction_a_n, code_new_ext_reducer );
@@ -1970,13 +1992,13 @@ 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 );
put_instruction_name (".comp", parse_directive_n_l, code_comp );
+#ifdef NEW_APPLY
+ put_instruction_name (".a", parse_directive_a, code_a );
+#endif
put_instruction_name (".d", parse_directive_n_n_t, code_d );
put_instruction_name (".depend", parse_directive_depend, code_depend );
put_instruction_name (".desc", parse_directive_desc, code_desc );
diff --git a/cgiwas.c b/cgiwas.c
index 32b45f3..680a798 100644
--- a/cgiwas.c
+++ b/cgiwas.c
@@ -734,6 +734,13 @@ static void w_as_register_register_newline (int reg1,int reg2)
w_as_newline();
}
+static void w_as_opcode_register_newline (char *opcode,int reg1)
+{
+ w_as_opcode (opcode);
+ w_as_register (reg1);
+ w_as_newline();
+}
+
static void w_as_opcode_register_register_newline (char *opcode,int reg1,int reg2)
{
w_as_opcode (opcode);
@@ -2045,6 +2052,177 @@ static void w_as_rem_instruction (struct instruction *instruction,int unsigned_r
}
}
+static void w_as_2movl_registers (int reg1,int reg2,int reg3)
+{
+ w_as_movl_register_register_newline (reg2,reg3);
+ w_as_movl_register_register_newline (reg1,reg2);
+}
+
+static void w_as_3movl_registers (int reg1,int reg2,int reg3,int reg4)
+{
+ w_as_movl_register_register_newline (reg3,reg4);
+ w_as_movl_register_register_newline (reg2,reg3);
+ w_as_movl_register_register_newline (reg1,reg2);
+}
+
+static void w_as_mulud_instruction (struct instruction *instruction)
+{
+ int reg_1,reg_2;
+
+ reg_1=instruction->instruction_parameters[0].parameter_data.reg.r;
+ reg_2=instruction->instruction_parameters[1].parameter_data.reg.r;
+
+ if (reg_2==REGISTER_D0){
+ if (reg_1==REGISTER_A1){
+ w_as_opcode_register_newline ("mul",reg_1);
+ } else {
+ w_as_movl_register_register_newline (REGISTER_A1,REGISTER_O0);
+ w_as_opcode_register_newline ("mul",reg_1);
+ w_as_2movl_registers (REGISTER_O0,REGISTER_A1,reg_1);
+ }
+ } else if (reg_1==REGISTER_A1){
+ w_as_2movl_registers (reg_2,REGISTER_D0,REGISTER_O0);
+ w_as_opcode_register_newline ("mul",reg_1);
+ w_as_2movl_registers (REGISTER_O0,REGISTER_D0,reg_2);
+ } else if (reg_1==REGISTER_D0){
+ if (reg_2==REGISTER_A1){
+ w_as_opcode_register_newline ("mul",REGISTER_A1);
+ w_as_opcode_register_register_newline ("xchg",REGISTER_A1,REGISTER_D0);
+ } else {
+ w_as_movl_register_register_newline (REGISTER_A1,REGISTER_O0);
+ w_as_opcode_register_newline ("mul",reg_2);
+ w_as_3movl_registers (REGISTER_O0,REGISTER_A1,REGISTER_D0,reg_2);
+ }
+ } else if (reg_2==REGISTER_A1){
+ w_as_2movl_registers (reg_2,REGISTER_D0,REGISTER_O0);
+ w_as_opcode_register_newline ("mul",reg_1);
+ w_as_3movl_registers (REGISTER_O0,REGISTER_D0,REGISTER_A1,reg_1);
+ } else {
+ w_as_opcode_register_register_newline ("xchg",reg_2,REGISTER_D0);
+ w_as_movl_register_register_newline (REGISTER_A1,REGISTER_O0);
+ w_as_opcode_register_newline ("mul",reg_1);
+ w_as_opcode_register_register_newline ("xchg",reg_2,REGISTER_D0);
+ w_as_2movl_registers (REGISTER_O0,REGISTER_A1,reg_1);
+ }
+}
+
+static void w_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;
+
+ if (reg_1==REGISTER_D0){
+ if (reg_3==REGISTER_D0){
+ if (reg_2==REGISTER_A1)
+ w_as_opcode_register_newline ("div",reg_1);
+ else {
+ w_as_2movl_registers (reg_2,REGISTER_A1,REGISTER_O0);
+ w_as_opcode_register_newline ("div",reg_1);
+ w_as_2movl_registers (REGISTER_O0,REGISTER_A1,reg_2);
+ }
+ } else if (reg_3==REGISTER_A1){
+ if (reg_2==REGISTER_D0){
+ w_as_opcode_register_register_newline ("xchg",REGISTER_A1,REGISTER_D0);
+ w_as_opcode_register_newline ("div",REGISTER_A1);
+ w_as_opcode_register_register_newline ("xchg",REGISTER_A1,REGISTER_D0);
+ } else {
+ w_as_3movl_registers (reg_2,REGISTER_A1,REGISTER_D0,REGISTER_O0);
+ w_as_opcode_register_newline ("div",REGISTER_O0);
+ w_as_3movl_registers (REGISTER_O0,REGISTER_D0,REGISTER_A1,reg_2);
+ }
+ } else {
+ if (reg_2==REGISTER_A1){
+ w_as_2movl_registers (reg_3,REGISTER_D0,REGISTER_O0);
+ w_as_opcode_register_newline ("div",REGISTER_O0);
+ w_as_2movl_registers (REGISTER_O0,REGISTER_D0,reg_3);
+ } else if (reg_2==REGISTER_D0){
+ w_as_3movl_registers (reg_3,REGISTER_D0,REGISTER_A1,REGISTER_O0);
+ w_as_opcode_register_newline ("div",REGISTER_A1);
+ w_as_3movl_registers (REGISTER_O0,REGISTER_A1,REGISTER_D0,reg_3);
+ } else {
+ w_as_opcode_register_register_newline ("xchg",reg_3,REGISTER_D0);
+ w_as_2movl_registers (reg_2,REGISTER_A1,REGISTER_O0);
+ w_as_opcode_register_newline ("div",reg_3);
+ w_as_2movl_registers (REGISTER_O0,REGISTER_A1,reg_2);
+ w_as_opcode_register_register_newline ("xchg",reg_3,REGISTER_D0);
+ }
+ }
+ } else if (reg_1==REGISTER_A1){
+ if (reg_2==REGISTER_A1){
+ if (reg_3==REGISTER_D0)
+ w_as_opcode_register_newline ("div",reg_1);
+ else {
+ w_as_2movl_registers (reg_3,REGISTER_D0,REGISTER_O0);
+ w_as_opcode_register_newline ("div",reg_1);
+ w_as_2movl_registers (REGISTER_O0,REGISTER_D0,reg_3);
+ }
+ } else if (reg_2==REGISTER_D0){
+ if (reg_3==REGISTER_A1){
+ w_as_opcode_register_register_newline ("xchg",REGISTER_A1,REGISTER_D0);
+ w_as_opcode_register_newline ("div",REGISTER_D0);
+ w_as_opcode_register_register_newline ("xchg",REGISTER_A1,REGISTER_D0);
+ } else {
+ w_as_3movl_registers (reg_3,REGISTER_D0,REGISTER_A1,REGISTER_O0);
+ w_as_opcode_register_newline ("div",REGISTER_O0);
+ w_as_3movl_registers (REGISTER_O0,REGISTER_A1,REGISTER_D0,reg_3);
+ }
+ } else {
+ if (reg_3==REGISTER_D0){
+ w_as_2movl_registers (reg_2,REGISTER_A1,REGISTER_O0);
+ w_as_opcode_register_newline ("div",REGISTER_O0);
+ w_as_2movl_registers (REGISTER_O0,REGISTER_A1,reg_2);
+ } else if (reg_3==REGISTER_A1){
+ w_as_3movl_registers (reg_2,REGISTER_A1,REGISTER_D0,REGISTER_O0);
+ w_as_opcode_register_newline ("div",REGISTER_D0);
+ w_as_3movl_registers (REGISTER_O0,REGISTER_D0,REGISTER_A1,reg_2);
+ } else {
+ w_as_opcode_register_register_newline ("xchg",reg_2,REGISTER_A1);
+ w_as_2movl_registers (reg_3,REGISTER_D0,REGISTER_O0);
+ w_as_opcode_register_newline ("div",reg_2);
+ w_as_2movl_registers (REGISTER_O0,REGISTER_D0,reg_3);
+ w_as_opcode_register_register_newline ("xchg",reg_2,REGISTER_A1);
+ }
+ }
+ } else {
+ if (reg_3==REGISTER_D0){
+ if (reg_2==REGISTER_A1){
+ w_as_opcode_register_newline ("div",reg_1);
+ } else {
+ w_as_2movl_registers (reg_2,REGISTER_A1,REGISTER_O0);
+ w_as_opcode_register_newline ("div",reg_1);
+ w_as_2movl_registers (REGISTER_O0,REGISTER_A1,reg_2);
+ }
+ } else if (reg_2==REGISTER_A1){
+ w_as_2movl_registers (reg_3,REGISTER_D0,REGISTER_O0);
+ w_as_opcode_register_newline ("div",reg_1);
+ w_as_2movl_registers (REGISTER_O0,REGISTER_D0,reg_3);
+ } else if (reg_2==REGISTER_D0){
+ if (reg_3==REGISTER_A1){
+ w_as_opcode_register_register_newline ("xchg",REGISTER_A1,REGISTER_D0);
+ w_as_opcode_register_newline ("div",reg_1);
+ w_as_opcode_register_register_newline ("xchg",REGISTER_A1,REGISTER_D0);
+ } else {
+ w_as_3movl_registers (reg_3,REGISTER_D0,REGISTER_A1,REGISTER_O0);
+ w_as_opcode_register_newline ("div",reg_1);
+ w_as_3movl_registers (REGISTER_O0,REGISTER_A1,REGISTER_D0,reg_3);
+ }
+ } else if (reg_2==REGISTER_A1){
+ w_as_3movl_registers (reg_3,REGISTER_A1,REGISTER_D0,REGISTER_O0);
+ w_as_opcode_register_newline ("div",reg_1);
+ w_as_3movl_registers (REGISTER_O0,REGISTER_D0,REGISTER_A1,reg_3);
+ } else {
+ w_as_opcode_register_register_newline ("xchg",reg_3,REGISTER_D0);
+ w_as_2movl_registers (reg_2,REGISTER_A1,REGISTER_O0);
+ w_as_opcode_register_newline ("div",reg_1);
+ w_as_2movl_registers (REGISTER_O0,REGISTER_A1,reg_2);
+ w_as_opcode_register_register_newline ("xchg",reg_3,REGISTER_D0);
+ }
+ }
+}
+
static void w_as_word_instruction (struct instruction *instruction)
{
fprintf (assembly_file,"\t.byte\t%d\n",
@@ -3071,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 IMULUD:
+ w_as_mulud_instruction (instruction);
+ break;
+ case IDIVDU:
+ w_as_divdu_instruction (instruction);
+ break;
case IFMOVE:
instruction=w_as_fmove_instruction (instruction);
break;
@@ -3501,6 +3685,170 @@ static void w_as_import_labels (struct label_node *label_node)
w_as_import_labels (label_node->label_node_right);
}
+static void w_as_node_entry_info (struct basic_block *block)
+{
+ if (block->block_ea_label!=NULL){
+ int n_node_arguments;
+
+ n_node_arguments=block->block_n_node_arguments;
+ if (n_node_arguments<-2)
+ n_node_arguments=1;
+
+ if (n_node_arguments>=0 && block->block_ea_label!=eval_fill_label){
+#if 1
+ if (!block->block_profile){
+ w_as_opcode_movl();
+ if (intel_asm)
+ w_as_register_comma (REGISTER_A2);
+ w_as_immediate_label (block->block_ea_label->label_name);
+ if (!intel_asm)
+ w_as_comma_register (REGISTER_A2);
+ w_as_newline();
+
+ w_as_opcode ("jmp");
+ w_as_label (eval_upd_labels[n_node_arguments]->label_name);
+ w_as_newline();
+
+ w_as_instruction_without_parameters ("nop");
+ w_as_instruction_without_parameters ("nop");
+ } else {
+ w_as_opcode ("jmp");
+ w_as_label (eval_upd_labels[n_node_arguments]->label_name);
+ fprintf (assembly_file,"-7");
+ w_as_newline();
+
+ w_as_instruction_without_parameters ("nop");
+ w_as_instruction_without_parameters ("nop");
+ w_as_instruction_without_parameters ("nop");
+
+ w_as_opcode_movl();
+ if (intel_asm)
+ w_as_register_comma (REGISTER_D0);
+ w_as_immediate_label (block->block_ea_label->label_name);
+ if (!intel_asm)
+ w_as_comma_register (REGISTER_D0);
+ w_as_newline();
+
+ w_as_opcode_movl();
+ if (intel_asm)
+ w_as_register_comma (REGISTER_A2);
+ w_as_descriptor (block->block_profile_function_label,0);
+ if (!intel_asm)
+ w_as_comma_register (REGISTER_A2);
+ w_as_newline();
+
+ w_as_opcode ("jmp");
+ fprintf (assembly_file,".-18");
+ w_as_newline();
+ }
+#else
+ w_as_opcode_movl();
+ if (intel_asm)
+ w_as_register_comma (REGISTER_D0);
+ w_as_immediate_label (eval_upd_labels[n_node_arguments]->label_name);
+ if (!intel_asm)
+ w_as_comma_register (REGISTER_D0);
+ w_as_newline();
+
+ w_as_opcode_movl();
+ if (intel_asm)
+ w_as_register_comma (REGISTER_A2);
+ w_as_immediate_label (block->block_ea_label->label_name);
+ if (!intel_asm)
+ w_as_comma_register (REGISTER_A2);
+ w_as_newline();
+
+ w_as_opcode ("jmp");
+ w_as_register (REGISTER_D0);
+ w_as_newline();
+#endif
+ } else {
+ w_as_opcode_movl();
+ if (intel_asm)
+ w_as_register_comma (REGISTER_D0);
+ w_as_immediate_label (block->block_ea_label->label_name);
+ if (!intel_asm)
+ w_as_comma_register (REGISTER_D0);
+ w_as_newline();
+
+ w_as_opcode ("jmp");
+ w_as_register (REGISTER_D0);
+ w_as_newline();
+
+ w_as_space (5);
+ }
+
+ if (block->block_descriptor!=NULL && (block->block_n_node_arguments<0 || parallel_flag || module_info_flag))
+ w_as_label_in_code_section (block->block_descriptor->label_name);
+ else
+ w_as_number_of_arguments (0);
+ } else
+ if (block->block_descriptor!=NULL && (block->block_n_node_arguments<0 || parallel_flag || module_info_flag))
+ w_as_label_in_code_section (block->block_descriptor->label_name);
+
+ w_as_number_of_arguments (block->block_n_node_arguments);
+}
+
+static void w_as_profile_call (struct basic_block *block)
+{
+ w_as_opcode_movl();
+ if (intel_asm)
+ w_as_scratch_register_comma();
+ w_as_descriptor (block->block_profile_function_label,0);
+ if (!intel_asm)
+ w_as_comma_scratch_register();
+ w_as_newline();
+
+ w_as_opcode ("call");
+
+ if (block->block_n_node_arguments>-100)
+ w_as_label (block->block_profile==2 ? "profile_n2" : "profile_n");
+ else {
+ switch (block->block_profile){
+ case 2: w_as_label ("profile_s2"); break;
+ case 4: w_as_label ("profile_l"); break;
+ case 5: w_as_label ("profile_l2"); break;
+ default: w_as_label ("profile_s");
+ }
+ }
+ w_as_newline();
+}
+
+#ifdef NEW_APPLY
+extern LABEL *add_empty_node_labels[];
+
+static void w_as_apply_update_entry (struct basic_block *block)
+{
+ if (block->block_profile)
+ w_as_profile_call (block);
+
+ if (block->block_n_node_arguments==-200){
+ w_as_opcode ("jmp");
+ w_as_label (block->block_ea_label->label_name);
+ w_as_newline();
+
+ w_as_instruction_without_parameters ("nop");
+ w_as_instruction_without_parameters ("nop");
+ w_as_instruction_without_parameters ("nop");
+ w_as_instruction_without_parameters ("nop");
+ w_as_instruction_without_parameters ("nop");
+ } else {
+ w_as_opcode ("call");
+ w_as_label (add_empty_node_labels[block->block_n_node_arguments+200]->label_name);
+ w_as_newline();
+
+ w_as_opcode ("jmp");
+ w_as_label (block->block_ea_label->label_name);
+ w_as_newline();
+ }
+
+ if (!block->block_profile){
+ w_as_instruction_without_parameters ("nop");
+ w_as_instruction_without_parameters ("nop");
+ }
+}
+#endif
+
void write_assembly (VOID)
{
struct basic_block *block;
@@ -3523,135 +3871,17 @@ void write_assembly (VOID)
for_l (block,first_block,block_next){
if (block->block_n_node_arguments>-100){
w_as_align (2);
-
- if (block->block_ea_label!=NULL){
- int n_node_arguments;
-
- n_node_arguments=block->block_n_node_arguments;
- if (n_node_arguments<-2)
- n_node_arguments=1;
-
- if (n_node_arguments>=0 && block->block_ea_label!=eval_fill_label){
-#if 1
- if (!block->block_profile){
- w_as_opcode_movl();
- if (intel_asm)
- w_as_register_comma (REGISTER_A2);
- w_as_immediate_label (block->block_ea_label->label_name);
- if (!intel_asm)
- w_as_comma_register (REGISTER_A2);
- w_as_newline();
-
- w_as_opcode ("jmp");
- w_as_label (eval_upd_labels[n_node_arguments]->label_name);
- w_as_newline();
-
- w_as_instruction_without_parameters ("nop");
- w_as_instruction_without_parameters ("nop");
- } else {
- w_as_opcode ("jmp");
- w_as_label (eval_upd_labels[n_node_arguments]->label_name);
- fprintf (assembly_file,"-7");
- w_as_newline();
-
- w_as_instruction_without_parameters ("nop");
- w_as_instruction_without_parameters ("nop");
- w_as_instruction_without_parameters ("nop");
-
- w_as_opcode_movl();
- if (intel_asm)
- w_as_register_comma (REGISTER_D0);
- w_as_immediate_label (block->block_ea_label->label_name);
- if (!intel_asm)
- w_as_comma_register (REGISTER_D0);
- w_as_newline();
-
- w_as_opcode_movl();
- if (intel_asm)
- w_as_register_comma (REGISTER_A2);
- w_as_descriptor (block->block_profile_function_label,0);
- if (!intel_asm)
- w_as_comma_register (REGISTER_A2);
- w_as_newline();
-
- w_as_opcode ("jmp");
- fprintf (assembly_file,".-18");
- w_as_newline();
- }
-#else
- w_as_opcode_movl();
- if (intel_asm)
- w_as_register_comma (REGISTER_D0);
- w_as_immediate_label (eval_upd_labels[n_node_arguments]->label_name);
- if (!intel_asm)
- w_as_comma_register (REGISTER_D0);
- w_as_newline();
-
- w_as_opcode_movl();
- if (intel_asm)
- w_as_register_comma (REGISTER_A2);
- w_as_immediate_label (block->block_ea_label->label_name);
- if (!intel_asm)
- w_as_comma_register (REGISTER_A2);
- w_as_newline();
-
- w_as_opcode ("jmp");
- w_as_register (REGISTER_D0);
- w_as_newline();
-#endif
- } else {
- w_as_opcode_movl();
- if (intel_asm)
- w_as_register_comma (REGISTER_D0);
- w_as_immediate_label (block->block_ea_label->label_name);
- if (!intel_asm)
- w_as_comma_register (REGISTER_D0);
- w_as_newline();
-
- w_as_opcode ("jmp");
- w_as_register (REGISTER_D0);
- w_as_newline();
-
- w_as_space (5);
- }
-
- if (block->block_descriptor!=NULL && (block->block_n_node_arguments<0 || parallel_flag || module_info_flag))
- w_as_label_in_code_section (block->block_descriptor->label_name);
- else
- w_as_number_of_arguments (0);
- } else
-
- if (block->block_descriptor!=NULL && (block->block_n_node_arguments<0 || parallel_flag || module_info_flag))
- w_as_label_in_code_section (block->block_descriptor->label_name);
-
- w_as_number_of_arguments (block->block_n_node_arguments);
+ w_as_node_entry_info (block);
}
+#ifdef NEW_APPLY
+ else if (block->block_n_node_arguments<-100)
+ w_as_apply_update_entry (block);
+#endif
w_as_labels (block->block_labels);
- if (block->block_profile){
- w_as_opcode_movl();
- if (intel_asm)
- w_as_scratch_register_comma();
- w_as_descriptor (block->block_profile_function_label,0);
- if (!intel_asm)
- w_as_comma_scratch_register();
- w_as_newline();
-
- w_as_opcode ("call");
-
- if (block->block_n_node_arguments>-100)
- w_as_label (block->block_profile==2 ? "profile_n2" : "profile_n");
- else {
- switch (block->block_profile){
- case 2: w_as_label ("profile_s2"); break;
- case 4: w_as_label ("profile_l"); break;
- case 5: w_as_label ("profile_l2"); break;
- default: w_as_label ("profile_s");
- }
- }
- w_as_newline();
- }
+ if (block->block_profile)
+ w_as_profile_call (block);
if (block->block_n_new_heap_cells>0)
w_as_garbage_collect_test (block);
diff --git a/cglin.c b/cglin.c
index 0afc369..55e2bfa 100644
--- a/cglin.c
+++ b/cglin.c
@@ -78,7 +78,7 @@ static struct instruction *i_new_instruction (int instruction_code,int arity,int
static struct instruction *i_new_instruction1 (int instruction_code)
{
- register struct instruction *instruction;
+ struct instruction *instruction;
instruction=(struct instruction*)fast_memory_allocate (sizeof (struct instruction)+sizeof (struct parameter));
@@ -98,7 +98,7 @@ static struct instruction *i_new_instruction1 (int instruction_code)
static struct instruction *i_new_instruction2 (int instruction_code)
{
- register struct instruction *instruction;
+ struct instruction *instruction;
instruction=(struct instruction*)fast_memory_allocate (sizeof (struct instruction)+2*sizeof (struct parameter));
@@ -116,6 +116,26 @@ static struct instruction *i_new_instruction2 (int instruction_code)
return instruction;
}
+static struct instruction *i_new_instruction3 (int instruction_code)
+{
+ struct instruction *instruction;
+
+ instruction=(struct instruction*)fast_memory_allocate (sizeof (struct instruction)+3*sizeof (struct parameter));
+
+ U4(instruction, instruction_next=NULL,
+ instruction_prev=last_instruction,
+ instruction_icode=instruction_code,
+ instruction_arity=3);
+
+ if (last_block->block_instructions==NULL)
+ last_block->block_instructions=instruction;
+ else
+ last_instruction->instruction_next=instruction;
+ last_instruction=instruction;
+
+ return instruction;
+}
+
void i_add_i_r (LONG value,int register_1)
{
struct instruction *instruction;
@@ -807,6 +827,24 @@ void i_call_r (int register_1,int frame_size)
}
#endif
+#ifdef I486
+void i_divdu_r_r_r (int register_1,int register_2,int register_3)
+{
+ struct instruction *instruction;
+
+ instruction=i_new_instruction3 (IDIVDU);
+
+ S2 (instruction->instruction_parameters[0], parameter_type=P_REGISTER,
+ parameter_data.i=register_1);
+
+ S2 (instruction->instruction_parameters[1], parameter_type=P_REGISTER,
+ parameter_data.i=register_2);
+
+ S2 (instruction->instruction_parameters[2], parameter_type=P_REGISTER,
+ parameter_data.i=register_3);
+}
+#endif
+
void i_lea_id_r (int offset,int register_1,int register_2)
{
register struct instruction *instruction;
@@ -1574,6 +1612,21 @@ void i_movew_r_pd (int register_1,int register_2)
}
#endif
+#ifdef I486
+void i_mulud_r_r (int register_1,int register_2)
+{
+ struct instruction *instruction;
+
+ instruction=i_new_instruction2 (IMULUD);
+
+ S2 (instruction->instruction_parameters[0], parameter_type=P_REGISTER,
+ parameter_data.i=register_1);
+
+ S2 (instruction->instruction_parameters[1], parameter_type=P_REGISTER,
+ parameter_data.i=register_2);
+}
+#endif
+
#ifdef G_POWER
void i_or_i_r (LONG value,int register_1)
{
@@ -2256,7 +2309,7 @@ static void instruction_ad_pi (int instruction_code,ADDRESS *ad_p,int register_1
static void instruction_ad_r (int instruction_code,ADDRESS *ad_p,int register_1)
{
- register struct instruction *instruction;
+ struct instruction *instruction;
instruction=i_new_instruction2 (instruction_code);
@@ -2314,7 +2367,7 @@ static void instruction_l (int instruction_code,LABEL *label)
static void instruction_ad_r_r (int instruction_code,ADDRESS *ad_p,int register_1,int register_2)
{
- register struct instruction *instruction;
+ struct instruction *instruction;
instruction=i_new_instruction (instruction_code,3,3*sizeof (struct parameter));
@@ -2329,7 +2382,7 @@ static void instruction_ad_r_r (int instruction_code,ADDRESS *ad_p,int register_
static void instruction_r (int instruction_code,int register_1)
{
- register struct instruction *instruction;
+ struct instruction *instruction;
instruction=i_new_instruction1 (instruction_code);
@@ -2522,7 +2575,7 @@ static void in_data_register (register ADDRESS *ad_p)
ad_p->ad_count=1;
}
-static void in_alterable_data_register (register ADDRESS *ad_p)
+static void in_alterable_data_register (ADDRESS *ad_p)
{
int dreg;
@@ -2615,6 +2668,119 @@ static void in_alterable_data_register (register ADDRESS *ad_p)
ad_p->ad_count=1;
}
+#ifdef I486
+static void in_preferred_alterable_register (ADDRESS *ad_p,int preferred_reg)
+{
+ int dreg;
+
+ switch (ad_p->ad_mode){
+ case P_REGISTER:
+ if (*ad_p->ad_count_p==1)
+ return;
+
+ --*ad_p->ad_count_p;
+ if (try_allocate_register_number (preferred_reg))
+ dreg=preferred_reg;
+ else
+ dreg=get_dregister();
+ i_move_r_r (ad_p->ad_register,dreg);
+ break;
+ case P_IMMEDIATE:
+ if (try_allocate_register_number (preferred_reg))
+ dreg=preferred_reg;
+ else
+ dreg=get_dregister();
+ i_move_i_r (ad_p->ad_offset,dreg);
+ break;
+ case P_INDIRECT:
+ if (--*ad_p->ad_count_p==0)
+ free_aregister (ad_p->ad_register);
+ if (try_allocate_register_number (preferred_reg))
+ dreg=preferred_reg;
+ else
+ dreg=get_dregister();
+ i_move_id_r (ad_p->ad_offset,ad_p->ad_register,dreg);
+ break;
+ case P_DESCRIPTOR_NUMBER:
+ if (try_allocate_register_number (preferred_reg))
+ dreg=preferred_reg;
+ else
+ dreg=get_dregister();
+ i_move_d_r (ad_p->ad_label,ad_p->ad_offset,dreg);
+ break;
+ case P_INDEXED:
+ {
+ INSTRUCTION_GRAPH load_x_graph;
+ ADDRESS *i_ad_p;
+
+ load_x_graph=(INSTRUCTION_GRAPH)ad_p->ad_offset;
+ i_ad_p=(ADDRESS *)load_x_graph->instruction_parameters[1].p;
+
+ if (load_x_graph->inode_arity & LOAD_X_TO_ADDRESS){
+ load_x_graph->inode_arity ^= (LOAD_X_TO_ADDRESS | LOAD_X_TO_REGISTER);
+ if (i_ad_p->ad_mode==P_INDEXED){
+ if (--*i_ad_p->ad_count_p==0)
+ free_aregister (i_ad_p->ad_areg);
+ if (--*i_ad_p->ad_count_p2==0)
+ free_dregister (i_ad_p->ad_dreg);
+
+ if (try_allocate_register_number (preferred_reg))
+ dreg=preferred_reg;
+ else
+ dreg=get_dregister();
+ i_move_x_r (i_ad_p->ad_offset,i_ad_p->ad_areg,i_ad_p->ad_dreg,dreg);
+ } else {
+ if (--*i_ad_p->ad_count_p==0)
+ free_aregister (i_ad_p->ad_register);
+ if (try_allocate_register_number (preferred_reg))
+ dreg=preferred_reg;
+ else
+ dreg=get_dregister();
+ i_move_id_r (i_ad_p->ad_offset,i_ad_p->ad_register,dreg);
+ }
+ i_ad_p->ad_register=dreg;
+ } else {
+ dreg=i_ad_p->ad_register;
+
+ if (is_d_register (dreg)){
+ if (*i_ad_p->ad_count_p>1){
+ int old_dreg;
+
+ old_dreg=dreg;
+ if (try_allocate_register_number (preferred_reg))
+ dreg=preferred_reg;
+ else
+ dreg=get_dregister();
+ i_move_r_r (old_dreg,dreg);
+ --*i_ad_p->ad_count_p;
+ }
+ } else {
+ int areg;
+
+ areg=dreg;
+ if (try_allocate_register_number (preferred_reg))
+ dreg=preferred_reg;
+ else
+ dreg=get_dregister();
+ i_move_r_r (areg,dreg);
+ if (--*i_ad_p->ad_count_p==0)
+ free_aregister (areg);
+ }
+ }
+ break;
+ }
+ default:
+ internal_error_in_function ("in_alterable_data register");
+ return;
+ }
+
+ ad_p->ad_mode=P_REGISTER;
+ ad_p->ad_register=dreg;
+ ad_p->ad_count_p=&ad_p->ad_count;
+ ad_p->ad_count=1;
+}
+#endif
+
static void in_address_register (register ADDRESS *ad_p)
{
int areg;
@@ -2924,7 +3090,7 @@ static void linearize_dyadic_commutative_operator (int i_instruction_code,INSTRU
static void linearize_dyadic_commutative_data_operator (int i_instruction_code,INSTRUCTION_GRAPH graph,ADDRESS *ad_p)
{
- register INSTRUCTION_GRAPH graph_1,graph_2;
+ INSTRUCTION_GRAPH graph_1,graph_2;
ADDRESS ad_1,ad_2;
int reg_1;
@@ -3600,6 +3766,87 @@ 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)
+{
+ INSTRUCTION_GRAPH graph,result_graph2;
+ ADDRESS ad_1,ad_2;
+ int reg_1,reg_2;
+
+ graph=result_graph->instruction_parameters[0].p;
+
+ if (graph->instruction_code==GMULUD){
+ INSTRUCTION_GRAPH graph_1,graph_2;
+
+ graph_1=graph->instruction_parameters[0].p;
+ graph_2=graph->instruction_parameters[1].p;
+
+ if (graph->order_left){
+ linearize_graph (graph_1,&ad_1);
+ linearize_graph (graph_2,&ad_2);
+ } else {
+ linearize_graph (graph_2,&ad_2);
+ linearize_graph (graph_1,&ad_1);
+ }
+
+ in_preferred_alterable_register (&ad_2,REGISTER_D0);
+ in_preferred_alterable_register (&ad_1,REGISTER_A1);
+
+ 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;
+ 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);
+
+ in_preferred_alterable_register (&ad_2,REGISTER_D0);
+ in_preferred_alterable_register (&ad_1,REGISTER_A1);
+ in_register (&ad_3);
+
+ reg_1=ad_1.ad_register;
+ reg_2=ad_2.ad_register;
+ 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);
+ }
+
+ result_graph2=result_graph->instruction_parameters[1].p;
+
+ ad_p->ad_mode=P_REGISTER;
+ ad_p->ad_count_p=&result_graph->node_count;
+
+ if (result_graph->instruction_code==GRESULT0){
+ ad_p->ad_register=reg_1;
+ if (result_graph->node_count>1)
+ register_node (result_graph,reg_1);
+ if (result_graph2->node_count>0)
+ register_node (result_graph2,reg_2);
+ else {
+ --*ad_2.ad_count_p;
+ free_register (reg_2);
+ }
+ } else {
+ ad_p->ad_register=reg_2;
+ if (result_graph->node_count>1)
+ register_node (result_graph,reg_2);
+ if (result_graph2->node_count>0)
+ register_node (result_graph2,reg_1);
+ else {
+ --*ad_1.ad_count_p;
+ free_register (reg_1);
+ }
+ }
+}
+#endif
+
static void linearize_shift_operator (int i_instruction_code,INSTRUCTION_GRAPH graph,ADDRESS *ad_p)
{
INSTRUCTION_GRAPH graph_1,graph_2;
@@ -7795,6 +8042,12 @@ static void linearize_graph (INSTRUCTION_GRAPH graph,ADDRESS *ad_p)
linearize_dyadic_commutative_data_operator (IUMULH,graph,ad_p);
return;
#endif
+#ifdef I486
+ case GRESULT0:
+ case GRESULT1:
+ linearize_mulud_or_divdu_operator (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 1753f65..888e976 100644
--- a/cgopt.c
+++ b/cgopt.c
@@ -415,10 +415,10 @@ 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 IDIVI: case IREMI: case IREMU: case IMULUD: case IDIVDU:
#endif
#if (defined (I486) && !defined (I486_USE_SCRATCH_REGISTER)) || defined (G_POWER)
- case IDIVU:
+ case IDIVU:
#endif
IF_G_POWER ( case IUMULH: )
return 4;
@@ -669,7 +669,8 @@ 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 &&
+ instruction->instruction_icode!=IREMU &&
+ instruction->instruction_icode!=IDIVDU &&
#endif
instruction->instruction_icode!=IMOD)
#ifdef M68000
@@ -904,6 +905,7 @@ void optimize_stack_access (struct basic_block *block,int *a_offset_p,int *b_off
if (instruction->instruction_icode!=IDIVI &&
instruction->instruction_icode!=IREMI &&
instruction->instruction_icode!=IREMU &&
+ instruction->instruction_icode!=IDIVDU &&
instruction->instruction_icode!=IMOD)
internal_error_in_function ("optimize_stack_access");
/* only first argument of mod might be register indirect */
@@ -1516,6 +1518,9 @@ static void store_next_uses (struct instruction *instruction)
case IDIV:
case ICMPW:
#endif
+#if defined (I486) && !defined (I486_USE_SCRATCH_REGISTER)
+ case IMULUD:
+#endif
#if (defined (I486) && !defined (I486_USE_SCRATCH_REGISTER)) || defined (G_POWER)
case IDIVU:
#endif
@@ -1546,7 +1551,7 @@ IF_G_POWER ( case IUMULH: )
use_parameter (&instruction->instruction_parameters[1]);
use_parameter (&instruction->instruction_parameters[0]);
break;
- case IDIV: case IMOD: case IDIVU: case IREMU:
+ case IDIV: case IMOD: case IDIVU: case IREMU: case IMULUD:
define_scratch_register();
use_parameter (&instruction->instruction_parameters[1]);
use_parameter (&instruction->instruction_parameters[0]);
@@ -1641,6 +1646,16 @@ IF_G_RISC (case IADDI: case ILSLI:)
use_parameter (&instruction->instruction_parameters[0]);
break;
#endif
+#ifdef I486
+ case IDIVDU:
+# ifdef I486_USE_SCRATCH_REGISTER
+ define_scratch_register();
+# endif
+ use_parameter (&instruction->instruction_parameters[2]);
+ use_parameter (&instruction->instruction_parameters[1]);
+ use_parameter (&instruction->instruction_parameters[0]);
+ break;
+#endif
#ifdef I486_USE_SCRATCH_REGISTER
case IFBEQ: case IFBGE: case IFBGT: case IFBLE: case IFBLT: case IFBNE:
define_scratch_register();
@@ -3054,7 +3069,7 @@ static void use_3_same_type_registers
reg_alloc=f_reg_alloc;
break;
default:
- internal_error_in_function ("use_2_same_type_registers");
+ internal_error_in_function ("use_3_same_type_registers");
return;
}
@@ -3600,7 +3615,7 @@ static void instruction_def (struct instruction *instruction)
}
}
-static void instruction_exg_usedef_usedef (struct instruction *instruction)
+static void instruction_usedef_usedef (struct instruction *instruction)
{
register_use_2 ( &instruction->instruction_parameters[0].parameter_data.reg,USE_DEF,
&instruction->instruction_parameters[1].parameter_data.reg,USE_DEF);
@@ -3917,8 +3932,19 @@ IF_G_RISC (case IADDI: case ILSLI:)
#endif
break;
case IEXG:
- instruction_exg_usedef_usedef (instruction);
+ instruction_usedef_usedef (instruction);
break;
+#ifdef I486
+ case IMULUD:
+# ifdef I486_USE_SCRATCH_REGISTER
+ use_scratch_register();
+# endif
+ instruction_usedef_usedef (instruction);
+# ifdef I486_USE_SCRATCH_REGISTER
+ allocate_scratch_register=1;
+# endif
+ break;
+#endif
#if defined (I486) && defined (FP_STACK_OPTIMIZATIONS)
case IFEXG:
instruction_fexg_usedef_usedef (instruction);
@@ -3957,6 +3983,20 @@ IF_G_RISC (case IADDI: case ILSLI:)
instruction_bmove_use_use_use (instruction);
break;
#endif
+#ifdef I486
+ case IDIVDU:
+# ifdef I486_USE_SCRATCH_REGISTER
+ 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
+ allocate_scratch_register=1;
+# endif
+ break;
+#endif
#ifdef I486_USE_SCRATCH_REGISTER
case IFBEQ: case IFBGE: case IFBGT: case IFBLE: case IFBLT: case IFBNE:
use_scratch_register();
diff --git a/cgport.h b/cgport.h
index 6840dd5..4cf03e7 100644
--- a/cgport.h
+++ b/cgport.h
@@ -1,5 +1,6 @@
#define FINALIZERS
+#undef NEW_APPLY
#if defined (__MWERKS__) || defined (__MRC__)
# define POWER