summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn van Groningen2005-01-19 10:52:58 +0000
committerJohn van Groningen2005-01-19 10:52:58 +0000
commit35929d022753195e9461fca5ff9d1b4aa82f7868 (patch)
treec8c66e7466637e2b0c59f47e1b4bf104119b42fe
parentadd divU for the PowerPC (diff)
implement mulUUL and divLU instructions for IA32,
define acos, asin, exp, ln and log10 instructons only for M68000 platform, add code for jsr_ap and jmp_ap instructions (not yet enabled)
-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