summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn van Groningen2011-11-14 11:47:49 +0000
committerJohn van Groningen2011-11-14 11:47:49 +0000
commitadccda3571c16a957f3df960d90bf593f34a4984 (patch)
tree82ad783aef217951be91f67c48337c5d2a5cdb67
parentfix pushLc label name on AMD64 (no extra _) (diff)
fix adding large immediate values (>32 bit) on 64 bit processors
-rw-r--r--cglin.c36
1 files 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;