From adccda3571c16a957f3df960d90bf593f34a4984 Mon Sep 17 00:00:00 2001 From: John van Groningen Date: Mon, 14 Nov 2011 11:47:49 +0000 Subject: fix adding large immediate values (>32 bit) on 64 bit processors --- cglin.c | 36 ++++++++++++++++++++++++++++++++---- 1 file changed, 32 insertions(+), 4 deletions(-) diff --git a/cglin.c b/cglin.c index 40c902e..5f04c28 100644 --- a/cglin.c +++ b/cglin.c @@ -2648,7 +2648,21 @@ static void to_data_addressing_mode (ADDRESS *ad_p) #endif } -static void in_register (register ADDRESS *ad_p) +#ifdef G_A64 +static void load_large_immediate (ADDRESS *ad_p) +{ + int dreg; + + dreg=get_dregister(); + i_move_i_r (ad_p->ad_offset,dreg); + 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_register (ADDRESS *ad_p) { int dreg; @@ -3211,11 +3225,15 @@ static void linearize_dyadic_commutative_operator (int i_instruction_code,INSTRU linearize_graph (graph_2,&ad_2); linearize_graph (graph_1,&ad_1); } - + if (graph->instruction_d_min_a_cost<=0){ if (ad_1.ad_mode==P_REGISTER && is_d_register (ad_1.ad_register) && *ad_1.ad_count_p<=1 && !(ad_2.ad_mode==P_REGISTER && is_d_register (ad_2.ad_register) && *ad_2.ad_count_p<=1)) { +#ifdef G_A64 + if (ad_2.ad_mode==P_IMMEDIATE && ((int)ad_2.ad_offset)!=ad_2.ad_offset) + load_large_immediate (&ad_2); +#endif instruction_ad_r (i_instruction_code,&ad_2,ad_1.ad_register); --*ad_1.ad_count_p; reg_1=ad_1.ad_register; @@ -3232,6 +3250,10 @@ static void linearize_dyadic_commutative_operator (int i_instruction_code,INSTRU # endif { in_alterable_data_register (&ad_1); +# ifdef G_A64 + if (((int)ad_2.ad_offset)!=ad_2.ad_offset) + load_large_immediate (&ad_2); +# endif instruction_ad_r (i_instruction_code,&ad_2,ad_1.ad_register); --*ad_1.ad_count_p; reg_1=ad_1.ad_register; @@ -3248,10 +3270,8 @@ static void linearize_dyadic_commutative_operator (int i_instruction_code,INSTRU #endif { -#if 1 /* optimization added 9-1-2000 */ if (! (ad_1.ad_mode==P_REGISTER && ad_2.ad_mode==P_REGISTER && ad_1.ad_register==ad_2.ad_register && is_d_register (ad_1.ad_register) && *ad_1.ad_count_p==2 && ad_1.ad_count_p==ad_2.ad_count_p)) -#endif in_alterable_data_register (&ad_2); instruction_ad_r (i_instruction_code,&ad_1,ad_2.ad_register); --*ad_2.ad_count_p; @@ -3280,11 +3300,19 @@ static void linearize_dyadic_commutative_operator (int i_instruction_code,INSTRU && is_a_register (ad_1.ad_register) && *ad_1.ad_count_p<=1) { in_alterable_address_register (&ad_1); +#ifdef G_A64 + if (ad_2.ad_mode==P_IMMEDIATE && ((int)ad_2.ad_offset)!=ad_2.ad_offset) + load_large_immediate (&ad_2); +#endif instruction_ad_r (i_instruction_code,&ad_2,ad_1.ad_register); --*ad_1.ad_count_p; reg_1=ad_1.ad_register; } else { in_alterable_address_register (&ad_2); +#ifdef G_A64 + if (ad_1.ad_mode==P_IMMEDIATE && ((int)ad_1.ad_offset)!=ad_1.ad_offset) + load_large_immediate (&ad_1); +#endif instruction_ad_r (i_instruction_code,&ad_1,ad_2.ad_register); --*ad_2.ad_count_p; reg_1=ad_2.ad_register; -- cgit v1.2.3