summaryrefslogtreecommitdiff
path: root/cglin.c
diff options
context:
space:
mode:
authorJohn van Groningen2003-05-16 12:36:51 +0000
committerJohn van Groningen2003-05-16 12:36:51 +0000
commit9f32504f724e79511b9a00e2c4871e5ffab0a9a0 (patch)
tree83d43f45dd2d4717cbe90825a8bacd485dbdba13 /cglin.c
parentoptimize remainder of non power of 2 constant (diff)
optimize remainder of non power of 2 constant for IA32
Diffstat (limited to 'cglin.c')
-rw-r--r--cglin.c29
1 files changed, 26 insertions, 3 deletions
diff --git a/cglin.c b/cglin.c
index 5f7092e..5a6cdf1 100644
--- a/cglin.c
+++ b/cglin.c
@@ -3384,11 +3384,34 @@ static void linearize_div_mod_operator (int i_instruction_code,INSTRUCTION_GRAPH
to_data_addressing_mode (&ad_1);
# ifdef I486
- if ((ad_1.ad_mode==P_IMMEDIATE && !((ad_1.ad_offset & (ad_1.ad_offset-1))==0 && (i_instruction_code==IMOD ? ad_1.ad_offset>1 : ad_1.ad_offset>0))) || ad_1.ad_mode==P_INDEXED)
- in_data_register (&ad_1);
+ if (ad_1.ad_mode==P_IMMEDIATE){
+ int i;
+
+ i=ad_1.ad_offset;
+ if (i_instruction_code==IMOD && i<0 && i!=0x80000000)
+ i=-i;
+
+ if ((i & (i-1))==0 && (i_instruction_code==IMOD ? i>1 : i>0))
+ instruction_ad_r (i_instruction_code,&ad_1,ad_2.ad_register);
+ else if (i>1 || (i<-1 && i!=0x80000000)){
+ int tmp_reg;
+
+ tmp_reg=get_dregister();
+ instruction_ad_r_r (i_instruction_code==IDIV ? IDIVI : IREMI,&ad_1,ad_2.ad_register,tmp_reg);
+ free_dregister (tmp_reg);
+ } else {
+ in_data_register (&ad_1);
+ instruction_ad_r (i_instruction_code,&ad_1,ad_2.ad_register);
+ }
+ } else {
+ if (ad_1.ad_mode==P_INDEXED)
+ in_data_register (&ad_1);
+ instruction_ad_r (i_instruction_code,&ad_1,ad_2.ad_register);
+ }
+# else
+ instruction_ad_r (i_instruction_code,&ad_1,ad_2.ad_register);
# endif
- instruction_ad_r (i_instruction_code,&ad_1,ad_2.ad_register);
--*ad_2.ad_count_p;
reg_1=ad_2.ad_register;