From d17bd94108dcdf97a1caa452c506aae1e2eb0a39 Mon Sep 17 00:00:00 2001 From: John van Groningen Date: Tue, 13 May 2003 13:32:28 +0000 Subject: optimize remainder of power of 2 for ia32 --- cgias.c | 65 +++++++++++++++++++++++++++++++++++++++++++-- cgiwas.c | 92 ++++++++++++++++++++++++++++++++++++++++++++++------------------ cglin.c | 2 +- 3 files changed, 130 insertions(+), 29 deletions(-) diff --git a/cgias.c b/cgias.c index 456c37d..c441505 100644 --- a/cgias.c +++ b/cgias.c @@ -1954,6 +1954,7 @@ static void as_div_instruction (struct instruction *instruction) as_r_r (0003,REGISTER_O0,d_reg); /* add */ } + /* sar */ store_c (0301); store_c (0300 | (7<<3) | reg_num (d_reg)); store_c (log2i); @@ -2056,12 +2057,72 @@ static void as_div_instruction (struct instruction *instruction) } } -static void as_mod_instruction (struct instruction *instruction) +static void as_rem_instruction (struct instruction *instruction) { int d_reg; d_reg=instruction->instruction_parameters[1].parameter_data.reg.r; + if (instruction->instruction_parameters[0].parameter_type==P_IMMEDIATE){ + int i,log2i; + + i=instruction->instruction_parameters[0].parameter_data.i; + + if (! ((i & (i-1))==0 && i>1)){ + internal_error_in_function ("as_rem_instruction"); + return; + } + + log2i=0; + while (i>1){ + i=i>>1; + ++log2i; + } + + as_move_r_r (d_reg,REGISTER_O0); + + if (log2i==1){ + /* and */ + if (d_reg==EAX) + store_c (045); + else + as_r (0201,040,d_reg); + store_l (1); + + /* sar */ + store_c (0301); + store_c (0300 | (7<<3) | reg_num (REGISTER_O0)); + store_c (31); + + as_r_r (0063,REGISTER_O0,d_reg); /* xor */ + } else { + /* sar */ + store_c (0301); + store_c (0300 | (7<<3) | reg_num (REGISTER_O0)); + store_c (31); + + /* and */ + if (REGISTER_O0==EAX) + store_c (045); + else + as_r (0201,040,REGISTER_O0); + store_l ((1<instruction_parameters[1].parameter_type){ @@ -1531,43 +1543,23 @@ static void w_as_div_instruction (struct instruction *instruction) if (log2i==1){ w_as_opcode ("sar"); - if (intel_asm) - w_as_register_comma (REGISTER_O0); - w_as_immediate (31); - if (!intel_asm) - w_as_comma_register (REGISTER_O0); - w_as_newline(); + w_as_immediate_register_newline (31,REGISTER_O0); w_as_opcode ("sub"); w_as_register_register_newline (REGISTER_O0,d_reg); } else { w_as_opcode ("sar"); - if (intel_asm) - w_as_register_comma (d_reg); - w_as_immediate (31); - if (!intel_asm) - w_as_comma_register (d_reg); - w_as_newline(); + w_as_immediate_register_newline (31,d_reg); w_as_opcode ("and"); - if (intel_asm) - w_as_register_comma (d_reg); - w_as_immediate ((1<instruction_parameters[1].parameter_data.reg.r; + if (instruction->instruction_parameters[0].parameter_type==P_IMMEDIATE){ + int i,log2i; + + i=instruction->instruction_parameters[0].parameter_data.i; + + if (! ((i & (i-1))==0 && i>1)){ + internal_error_in_function ("w_as_rem_instruction"); + return; + } + + log2i=0; + while (i>1){ + i=i>>1; + ++log2i; + } + + w_as_opcode_movl(); + w_as_register_register_newline (d_reg,REGISTER_O0); + + if (log2i==1){ + w_as_opcode ("and"); + w_as_immediate_register_newline (1,d_reg); + + w_as_opcode ("sar"); + w_as_immediate_register_newline (31,REGISTER_O0); + + w_as_opcode ("xor"); + w_as_register_register_newline (REGISTER_O0,d_reg); + } else { + w_as_opcode ("sar"); + w_as_immediate_register_newline (31,REGISTER_O0); + + w_as_opcode ("and"); + w_as_immediate_register_newline ((1<0)) || ad_1.ad_mode==P_INDEXED) + 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); # endif -- cgit v1.2.3