diff options
-rw-r--r-- | cgias.c | 103 | ||||
-rw-r--r-- | cgiconst.h | 5 | ||||
-rw-r--r-- | cgiwas.c | 82 | ||||
-rw-r--r-- | cglin.c | 10 | ||||
-rw-r--r-- | cgopt.c | 25 |
5 files changed, 183 insertions, 42 deletions
@@ -3379,15 +3379,103 @@ static void as_xchg_eax_r (int reg_1) store_c (0x90+reg_num (reg_1)); /* xchg reg_1,D0 */ } -#ifndef THREAD32 +static void as_xchg (int r1,int r2) +{ + if (r1==REGISTER_D0) + store_c (0x90+reg_num (r2)); /* xchg r,D0 */ + else if (r2==REGISTER_D0) + store_c (0x90+reg_num (r1)); /* xchg r,D0 */ + else + as_r_r (0207,r1,r2); +} + 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; + /* reg_2:reg_3/reg_1, quotient in reg3, remainder in reg_2 */ + +#ifdef THREAD32 + if (reg_3==REGISTER_D0){ + if (reg_2==REGISTER_A1) + as_r (0367,0060,reg_1); /* div */ + else { + as_xchg (REGISTER_A1,reg_2); + if (reg_1==reg_2) + as_r (0367,0060,REGISTER_A1); /* div */ + else if (reg_1==REGISTER_A1) + as_r (0367,0060,reg_2); /* div */ + else + as_r (0367,0060,reg_1); /* div */ + as_xchg (REGISTER_A1,reg_2); + } + } else if (reg_3==REGISTER_A1){ + as_xchg (REGISTER_D0,REGISTER_A1); + if (reg_2==REGISTER_D0){ + if (reg_1==REGISTER_D0) + as_r (0367,0060,REGISTER_A1); /* div */ + else if (reg_1==REGISTER_A1) + as_r (0367,0060,REGISTER_D0); /* div */ + else + as_r (0367,0060,reg_1); /* div */ + } else { + as_xchg (REGISTER_A1,reg_2); + if (reg_1==reg_2) + as_r (0367,0060,REGISTER_A1); /* div */ + else if (reg_1==REGISTER_D0) + as_r (0367,0060,reg_2); /* div */ + else if (reg_1==REGISTER_A1) + as_r (0367,0060,REGISTER_D0); /* div */ + else + as_r (0367,0060,reg_1); /* div */ + as_xchg (REGISTER_A1,reg_2); + } + as_xchg (REGISTER_D0,REGISTER_A1); + } else { + if (reg_2==REGISTER_A1){ + as_xchg (REGISTER_D0,reg_3); + if (reg_1==reg_3) + as_r (0367,0060,REGISTER_D0); /* div */ + else if (reg_1==REGISTER_D0) + as_r (0367,0060,reg_3); /* div */ + else + as_r (0367,0060,reg_1); /* div */ + as_xchg (REGISTER_D0,reg_3); + } else if (reg_2==REGISTER_D0){ + as_xchg (REGISTER_A1,REGISTER_D0); + as_xchg (REGISTER_D0,reg_3); + if (reg_1==reg_3) + as_r (0367,0060,REGISTER_D0); /* div */ + else if (reg_1==REGISTER_D0) + as_r (0367,0060,REGISTER_A1); /* div */ + else if (reg_1==REGISTER_A1) + as_r (0367,0060,reg_3); /* div */ + else + as_r (0367,0060,reg_1); /* div */ + as_xchg (REGISTER_D0,reg_3); + as_xchg (REGISTER_A1,REGISTER_D0); + } else { + as_xchg (REGISTER_D0,reg_3); + as_xchg (REGISTER_A1,reg_2); + if (reg_1==REGISTER_D0) + as_r (0367,0060,reg_3); /* div */ + else if (reg_1==REGISTER_A1) + as_r (0367,0060,reg_2); /* div */ + else if (reg_1==reg_3) + as_r (0367,0060,REGISTER_D0); /* div */ + else if (reg_1==reg_2) + as_r (0367,0060,REGISTER_A1); /* div */ + else + as_r (0367,0060,reg_1); /* div */ + as_xchg (REGISTER_A1,reg_2); + as_xchg (REGISTER_D0,reg_3); + } + } +#else if (reg_1==REGISTER_D0){ if (reg_3==REGISTER_D0){ if (reg_2==REGISTER_A1) @@ -3495,8 +3583,8 @@ static void as_divdu_instruction (struct instruction *instruction) as_xchg_eax_r (reg_3); /* xchg reg_3,D0 */ } } -} #endif +} static void as_mul_shift_magic (int s) { @@ -3970,12 +4058,7 @@ static void as_exg_instruction (struct instruction *instruction) r1=instruction->instruction_parameters[0].parameter_data.reg.r; r2=instruction->instruction_parameters[1].parameter_data.reg.r; - if (r1==REGISTER_D0) - store_c (0x90+reg_num (r2)); /* xchg r,D0 */ - else if (r2==REGISTER_D0) - store_c (0x90+reg_num (r1)); /* xchg r,D0 */ - else - as_r_r (0207,r1,r2); + as_xchg (r1,r2); } static void as_neg_instruction (struct instruction *instruction) @@ -5596,11 +5679,9 @@ static void as_instructions (struct instruction *instruction) case IMULUD: as_mulud_instruction (instruction); break; -#ifndef THREAD32 case IDIVDU: as_divdu_instruction (instruction); break; -#endif case IFLOORDIV: as_floordiv_mod_instruction (instruction,0); break; @@ -68,10 +68,7 @@ enum { #endif #if defined (I486) ,IADC ,ISBB, IRTSI - ,IDIVI, IREMI, IREMU, IFLOORDIV, IMOD, IMULUD -# ifndef THREAD32 - ,IDIVDU -# endif + ,IDIVI, IREMI, IREMU, IFLOORDIV, IMOD, IMULUD, IDIVDU ,IFLOADS, IFMOVES #endif #if defined (I486) || defined (G_POWER) @@ -3015,7 +3015,6 @@ static void w_as_mulud_instruction (struct instruction *instruction) #endif } -#ifndef THREAD32 static void w_as_divdu_instruction (struct instruction *instruction) { int reg_1,reg_2,reg_3; @@ -3024,6 +3023,83 @@ static void w_as_divdu_instruction (struct instruction *instruction) reg_2=instruction->instruction_parameters[1].parameter_data.reg.r; reg_3=instruction->instruction_parameters[2].parameter_data.reg.r; +#ifdef THREAD32 + if (reg_3==REGISTER_D0){ + if (reg_2==REGISTER_A1) + w_as_opcode_register_newline ("div",reg_1); + else { + w_as_opcode_register_register_newline ("xchg",REGISTER_A1,reg_2); + if (reg_1==reg_2) + w_as_opcode_register_newline ("div",REGISTER_A1); + else if (reg_1==REGISTER_A1) + w_as_opcode_register_newline ("div",reg_2); + else + w_as_opcode_register_newline ("div",reg_1); + w_as_opcode_register_register_newline ("xchg",REGISTER_A1,reg_2); + } + } else if (reg_3==REGISTER_A1){ + w_as_opcode_register_register_newline ("xchg",REGISTER_D0,REGISTER_A1); + if (reg_2==REGISTER_D0){ + if (reg_1==REGISTER_D0) + w_as_opcode_register_newline ("div",REGISTER_A1); + else if (reg_1==REGISTER_A1) + w_as_opcode_register_newline ("div",REGISTER_D0); + else + w_as_opcode_register_newline ("div",reg_1); + } else { + w_as_opcode_register_register_newline ("xchg",REGISTER_A1,reg_2); + if (reg_1==reg_2) + w_as_opcode_register_newline ("div",REGISTER_A1); + else if (reg_1==REGISTER_D0) + w_as_opcode_register_newline ("div",reg_2); + else if (reg_1==REGISTER_A1) + w_as_opcode_register_newline ("div",REGISTER_D0); + else + w_as_opcode_register_newline ("div",reg_1); + w_as_opcode_register_register_newline ("xchg",REGISTER_A1,reg_2); + } + w_as_opcode_register_register_newline ("xchg",REGISTER_D0,REGISTER_A1); + } else { + if (reg_2==REGISTER_A1){ + w_as_opcode_register_register_newline ("xchg",REGISTER_D0,reg_3); + if (reg_1==reg_3) + w_as_opcode_register_newline ("div",REGISTER_D0); + else if (reg_1==REGISTER_D0) + w_as_opcode_register_newline ("div",reg_3); + else + w_as_opcode_register_newline ("div",reg_1); + w_as_opcode_register_register_newline ("xchg",REGISTER_D0,reg_3); + } else if (reg_2==REGISTER_D0){ + w_as_opcode_register_register_newline ("xchg",REGISTER_A1,REGISTER_D0); + w_as_opcode_register_register_newline ("xchg",REGISTER_D0,reg_3); + if (reg_1==reg_3) + w_as_opcode_register_newline ("div",REGISTER_D0); + else if (reg_1==REGISTER_D0) + w_as_opcode_register_newline ("div",REGISTER_A1); + else if (reg_1==REGISTER_A1) + w_as_opcode_register_newline ("div",reg_3); + else + w_as_opcode_register_newline ("div",reg_1); + w_as_opcode_register_register_newline ("xchg",REGISTER_D0,reg_3); + w_as_opcode_register_register_newline ("xchg",REGISTER_A1,REGISTER_D0); + } else { + w_as_opcode_register_register_newline ("xchg",REGISTER_D0,reg_3); + w_as_opcode_register_register_newline ("xchg",REGISTER_A1,reg_2); + if (reg_1==REGISTER_D0) + w_as_opcode_register_newline ("div",reg_3); + else if (reg_1==REGISTER_A1) + w_as_opcode_register_newline ("div",reg_2); + else if (reg_1==reg_3) + w_as_opcode_register_newline ("div",REGISTER_D0); + else if (reg_1==reg_2) + w_as_opcode_register_newline ("div",REGISTER_A1); + else + w_as_opcode_register_newline ("div",reg_1); + w_as_opcode_register_register_newline ("xchg",REGISTER_A1,reg_2); + w_as_opcode_register_register_newline ("xchg",REGISTER_D0,reg_3); + } + } +#else if (reg_1==REGISTER_D0){ if (reg_3==REGISTER_D0){ if (reg_2==REGISTER_A1) @@ -3131,8 +3207,8 @@ static void w_as_divdu_instruction (struct instruction *instruction) w_as_opcode_register_register_newline ("xchg",reg_3,REGISTER_D0); } } -} #endif +} static void w_as_or_r_r (int reg_1,int reg_2) { @@ -4838,11 +4914,9 @@ static void w_as_instructions (register struct instruction *instruction) case IMULUD: w_as_mulud_instruction (instruction); break; -#ifndef THREAD32 case IDIVDU: w_as_divdu_instruction (instruction); break; -#endif case IFLOORDIV: w_as_floordiv_mod_instruction (instruction,0); break; @@ -937,7 +937,7 @@ void i_call_r (int register_1,int frame_size) } #endif -#if defined (I486) && !defined (THREAD32) +#ifdef I486 void i_divdu_r_r_r (int register_1,int register_2,int register_3) { struct instruction *instruction; @@ -4429,9 +4429,7 @@ static void linearize_two_results_operator (INSTRUCTION_GRAPH result_graph,ADDRE # else i_mulud_r_r (reg_1,reg_2); # endif - } else -#ifndef THREAD32 - if (graph->instruction_code==GDIVDU){ + } else if (graph->instruction_code==GDIVDU){ ADDRESS ad_3; linearize_3_graphs (graph->instruction_parameters[0].p,&ad_1, @@ -4447,9 +4445,7 @@ static void linearize_two_results_operator (INSTRUCTION_GRAPH result_graph,ADDRE 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); - } else -#endif - if (graph->instruction_code==GADDDU){ + } else if (graph->instruction_code==GADDDU){ ADDRESS ad_3,ad_4; linearize_3_graphs (graph->instruction_parameters[0].p,&ad_1, @@ -421,10 +421,7 @@ 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 IMULUD: -# ifndef THREAD32 - case IDIVDU: -# endif + case IDIVI: case IREMI: case IREMU: case IMULUD: case IDIVDU: case IFLOORDIV: case IMOD: #endif #if (defined (I486) && !defined (I486_USE_SCRATCH_REGISTER)) || defined (G_POWER) @@ -685,9 +682,7 @@ static void compute_maximum_b_stack_offsets (register int b_offset) instruction->instruction_icode!=IDIVI && instruction->instruction_icode!=IREMI && instruction->instruction_icode!=IREMU && -# ifndef THREAD32 instruction->instruction_icode!=IDIVDU && -# endif instruction->instruction_icode!=IASR_S && instruction->instruction_icode!=ILSL_S && instruction->instruction_icode!=ILSR_S && @@ -935,9 +930,7 @@ void optimize_stack_access (struct basic_block *block,int *a_offset_p,int *b_off instruction->instruction_icode!=IDIVI && instruction->instruction_icode!=IREMI && instruction->instruction_icode!=IREMU && -# ifndef THREAD32 instruction->instruction_icode!=IDIVDU && -# endif instruction->instruction_icode!=IASR_S && instruction->instruction_icode!=ILSL_S && instruction->instruction_icode!=ILSR_S && @@ -1563,7 +1556,7 @@ static void store_next_uses (struct instruction *instruction) case IROTL: case IROTR: # endif #endif -#if defined (I486) && !defined (I486_USE_SCRATCH_REGISTER) && !defined (THREAD32) +#if defined (I486) && !defined (I486_USE_SCRATCH_REGISTER) case IMULUD: #endif #if (defined (I486) && !defined (I486_USE_SCRATCH_REGISTER)) || defined (G_POWER) @@ -1596,7 +1589,7 @@ IF_G_POWER ( case IUMULH: ) use_parameter (&instruction->instruction_parameters[0]); break; case IDIV: case IREM: case IDIVU: case IREMU: case IMULUD: -# ifdef THREAD32 +# ifdef THREAD32 use_parameter (&instruction->instruction_parameters[1]); use_parameter (&instruction->instruction_parameters[0]); define_parameter (&instruction->instruction_parameters[2]); @@ -1718,9 +1711,9 @@ IF_G_RISC (case IADDI: case ILSLI:) use_parameter (&instruction->instruction_parameters[0]); break; #endif -#if defined (I486) && !defined (THREAD32) +#ifdef I486 case IDIVDU: -# ifdef I486_USE_SCRATCH_REGISTER +# if defined (I486_USE_SCRATCH_REGISTER) && !defined (THREAD32) define_scratch_register(); # endif use_parameter (&instruction->instruction_parameters[2]); @@ -4040,7 +4033,7 @@ IF_G_RISC (case IADDI: case ILSLI:) case IEXG: instruction_usedef_usedef (instruction); break; -#if defined (I486) +#ifdef I486 case IMULUD: # ifdef THREAD32 use_3_same_type_registers @@ -4112,16 +4105,16 @@ IF_G_RISC (case IADDI: case ILSLI:) instruction_bmove_use_use_use (instruction); break; #endif -#if defined (I486) && !defined (THREAD32) +#ifdef I486 case IDIVDU: -# ifdef I486_USE_SCRATCH_REGISTER +# if defined (I486_USE_SCRATCH_REGISTER) && !defined (THREAD32) 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 +# if defined (I486_USE_SCRATCH_REGISTER) && !defined (THREAD32) allocate_scratch_register=1; # endif break; |