diff options
-rw-r--r-- | cgias.c | 46 | ||||
-rw-r--r-- | cgiconst.h | 4 | ||||
-rw-r--r-- | cgiwas.c | 77 | ||||
-rw-r--r-- | cglin.c | 37 | ||||
-rw-r--r-- | cgopt.c | 40 |
5 files changed, 173 insertions, 31 deletions
@@ -3260,15 +3260,17 @@ static void as_3move_registers (int reg1,int reg2,int reg3,int reg4) as_move_r_r (reg1,reg2); } -#ifndef THREAD32 static void as_mulud_instruction (struct instruction *instruction) { int reg_1,reg_2; - +#ifdef THREAD32 + int reg_3; +#endif + reg_1=instruction->instruction_parameters[0].parameter_data.reg.r; reg_2=instruction->instruction_parameters[1].parameter_data.reg.r; -#if 0 +#ifdef THREAD32 reg_3=instruction->instruction_parameters[2].parameter_data.reg.r; if (reg_3==REGISTER_D0){ @@ -3303,12 +3305,44 @@ static void as_mulud_instruction (struct instruction *instruction) } return; } -#endif if (reg_2==REGISTER_D0){ if (reg_1==REGISTER_A1) as_r (0367,040,reg_1); /* mul */ else { + as_move_r_r (REGISTER_A1,reg_3); + as_r (0367,040,reg_1); /* mul */ + as_2move_registers (reg_3,REGISTER_A1,reg_1); + } + } else if (reg_1==REGISTER_A1){ + as_2move_registers (reg_2,REGISTER_D0,reg_3); + as_r (0367,040,reg_1); /* mul */ + as_2move_registers (reg_3,REGISTER_D0,reg_2); + } else if (reg_1==REGISTER_D0){ + if (reg_2==REGISTER_A1){ + as_r (0367,040,REGISTER_A1); /* mul */ + store_c (0x90+reg_num (REGISTER_A1)); /* xchg A1,D0 */ + } else { + as_move_r_r (REGISTER_A1,reg_3); + as_r (0367,040,reg_2); /* mul */ + as_3move_registers (reg_3,REGISTER_A1,REGISTER_D0,reg_2); + } + } else if (reg_2==REGISTER_A1){ + as_2move_registers (reg_2,REGISTER_D0,reg_3); + as_r (0367,040,reg_1); /* mul */ + as_3move_registers (reg_3,REGISTER_D0,REGISTER_A1,reg_1); + } else { + store_c (0x90+reg_num (reg_2)); /* xchg reg_2,D0 */ + as_move_r_r (REGISTER_A1,reg_3); + as_r (0367,040,reg_1); /* mul */ + store_c (0x90+reg_num (reg_2)); /* xchg reg_2,D0 */ + as_2move_registers (reg_3,REGISTER_A1,reg_1); + } +#else + if (reg_2==REGISTER_D0){ + if (reg_1==REGISTER_A1) + as_r (0367,040,reg_1); /* mul */ + else { as_move_r_r (REGISTER_A1,REGISTER_O0); as_r (0367,040,reg_1); /* mul */ as_2move_registers (REGISTER_O0,REGISTER_A1,reg_1); @@ -3337,8 +3371,8 @@ static void as_mulud_instruction (struct instruction *instruction) store_c (0x90+reg_num (reg_2)); /* xchg reg_2,D0 */ as_2move_registers (REGISTER_O0,REGISTER_A1,reg_1); } -} #endif +} static void as_xchg_eax_r (int reg_1) { @@ -5559,10 +5593,10 @@ static void as_instructions (struct instruction *instruction) case ISBB: as_sbb_instruction (instruction); break; -#ifndef THREAD32 case IMULUD: as_mulud_instruction (instruction); break; +#ifndef THREAD32 case IDIVDU: as_divdu_instruction (instruction); break; @@ -68,9 +68,9 @@ enum { #endif #if defined (I486) ,IADC ,ISBB, IRTSI - ,IDIVI, IREMI, IREMU, IFLOORDIV, IMOD + ,IDIVI, IREMI, IREMU, IFLOORDIV, IMOD, IMULUD # ifndef THREAD32 - ,IMULUD, IDIVDU + ,IDIVDU # endif ,IFLOADS, IFMOVES #endif @@ -2901,14 +2901,85 @@ static void w_as_3movl_registers (int reg1,int reg2,int reg3,int reg4) w_as_movl_register_register_newline (reg1,reg2); } -#ifndef THREAD32 static void w_as_mulud_instruction (struct instruction *instruction) { int reg_1,reg_2; +#ifdef THREAD32 + int reg_3; +#endif reg_1=instruction->instruction_parameters[0].parameter_data.reg.r; reg_2=instruction->instruction_parameters[1].parameter_data.reg.r; +#ifdef THREAD32 + reg_3=instruction->instruction_parameters[2].parameter_data.reg.r; + + if (reg_3==REGISTER_D0){ + if (reg_1==REGISTER_A1){ + w_as_movl_register_register_newline (reg_2,REGISTER_D0); + w_as_opcode_register_newline ("mul",reg_1); + w_as_movl_register_register_newline (REGISTER_D0,reg_2); + } else if (reg_2==REGISTER_A1){ + w_as_movl_register_register_newline (reg_2,REGISTER_D0); + w_as_opcode_register_newline ("mul",reg_1); + w_as_2movl_registers (REGISTER_D0,REGISTER_A1,reg_1); + } else { + w_as_2movl_registers (REGISTER_A1,reg_2,REGISTER_D0); + w_as_opcode_register_newline ("mul",reg_1); + w_as_3movl_registers (REGISTER_D0,reg_2,REGISTER_A1,reg_1); + } + return; + } + + if (reg_3==REGISTER_A1){ + if (reg_2==REGISTER_D0){ + w_as_opcode_register_newline ("mul",reg_1); + w_as_movl_register_register_newline (REGISTER_A1,reg_1); + } else if (reg_1==REGISTER_D0){ + w_as_opcode_register_newline ("mul",reg_2); + w_as_2movl_registers (REGISTER_A1,REGISTER_D0,reg_2); + } else { + w_as_opcode_register_register_newline ("xchg",reg_2,REGISTER_D0); + w_as_opcode_register_newline ("mul",reg_1); + w_as_opcode_register_register_newline ("xchg",reg_2,REGISTER_D0); + w_as_movl_register_register_newline (REGISTER_A1,reg_1); + } + return; + } + + if (reg_2==REGISTER_D0){ + if (reg_1==REGISTER_A1){ + w_as_opcode_register_newline ("mul",reg_1); + } else { + w_as_movl_register_register_newline (REGISTER_A1,reg_3); + w_as_opcode_register_newline ("mul",reg_1); + w_as_2movl_registers (reg_3,REGISTER_A1,reg_1); + } + } else if (reg_1==REGISTER_A1){ + w_as_2movl_registers (reg_2,REGISTER_D0,reg_3); + w_as_opcode_register_newline ("mul",reg_1); + w_as_2movl_registers (reg_3,REGISTER_D0,reg_2); + } else if (reg_1==REGISTER_D0){ + if (reg_2==REGISTER_A1){ + w_as_opcode_register_newline ("mul",REGISTER_A1); + w_as_opcode_register_register_newline ("xchg",REGISTER_A1,REGISTER_D0); + } else { + w_as_movl_register_register_newline (REGISTER_A1,reg_3); + w_as_opcode_register_newline ("mul",reg_2); + w_as_3movl_registers (reg_3,REGISTER_A1,REGISTER_D0,reg_2); + } + } else if (reg_2==REGISTER_A1){ + w_as_2movl_registers (reg_2,REGISTER_D0,reg_3); + w_as_opcode_register_newline ("mul",reg_1); + w_as_3movl_registers (reg_3,REGISTER_D0,REGISTER_A1,reg_1); + } else { + w_as_opcode_register_register_newline ("xchg",reg_2,REGISTER_D0); + w_as_movl_register_register_newline (REGISTER_A1,reg_3); + w_as_opcode_register_newline ("mul",reg_1); + w_as_opcode_register_register_newline ("xchg",reg_2,REGISTER_D0); + w_as_2movl_registers (reg_3,REGISTER_A1,reg_1); + } +#else if (reg_2==REGISTER_D0){ if (reg_1==REGISTER_A1){ w_as_opcode_register_newline ("mul",reg_1); @@ -2941,8 +3012,10 @@ static void w_as_mulud_instruction (struct instruction *instruction) w_as_opcode_register_register_newline ("xchg",reg_2,REGISTER_D0); w_as_2movl_registers (REGISTER_O0,REGISTER_A1,reg_1); } +#endif } +#ifndef THREAD32 static void w_as_divdu_instruction (struct instruction *instruction) { int reg_1,reg_2,reg_3; @@ -4762,10 +4835,10 @@ static void w_as_instructions (register struct instruction *instruction) case ISBB: w_as_dyadic_instruction (instruction,intel_asm ? "sbb" : "sbbl"); break; -#ifndef THREAD32 case IMULUD: w_as_mulud_instruction (instruction); break; +#ifndef THREAD32 case IDIVDU: w_as_divdu_instruction (instruction); break; @@ -1807,18 +1807,31 @@ void i_movew_r_pd (int register_1,int register_2) } #endif -#if defined (I486) && !defined (THREAD32) +#ifdef I486 +# ifdef THREAD32 +void i_mulud_r_r_r (int register_1,int register_2,int register_3) +# else void i_mulud_r_r (int register_1,int register_2) +#endif { struct instruction *instruction; +# ifdef THREAD32 + instruction=i_new_instruction3 (IMULUD); +# else instruction=i_new_instruction2 (IMULUD); +# endif S2 (instruction->instruction_parameters[0], parameter_type=P_REGISTER, parameter_data.i=register_1); - + S2 (instruction->instruction_parameters[1], parameter_type=P_REGISTER, parameter_data.i=register_2); + +# ifdef THREAD32 + S2 (instruction->instruction_parameters[2], parameter_type=P_REGISTER, + parameter_data.i=register_3); +# endif } #endif @@ -4381,7 +4394,6 @@ static void linearize_two_results_operator (INSTRUCTION_GRAPH result_graph,ADDRE graph=result_graph->instruction_parameters[0].p; -#ifndef THREAD32 if (graph->instruction_code==GMULUD){ INSTRUCTION_GRAPH graph_1,graph_2; @@ -4401,8 +4413,25 @@ static void linearize_two_results_operator (INSTRUCTION_GRAPH result_graph,ADDRE reg_1=ad_1.ad_register; reg_2=ad_2.ad_register; +# ifdef THREAD32 + { + int tmp_reg; + + if (try_allocate_register_number (REGISTER_D0)) + tmp_reg=REGISTER_D0; + else if (try_allocate_register_number (REGISTER_A1)) + tmp_reg=REGISTER_A1; + else + tmp_reg=get_dregister(); + i_mulud_r_r_r (reg_1,reg_2,tmp_reg); + free_register (tmp_reg); + } +# else i_mulud_r_r (reg_1,reg_2); - } else if (graph->instruction_code==GDIVDU){ +# endif + } else +#ifndef THREAD32 + if (graph->instruction_code==GDIVDU){ ADDRESS ad_3; linearize_3_graphs (graph->instruction_parameters[0].p,&ad_1, @@ -421,9 +421,9 @@ 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 IDIVI: case IREMI: case IREMU: case IMULUD: # ifndef THREAD32 - case IMULUD: case IDIVDU: + case IDIVDU: # endif case IFLOORDIV: case IMOD: #endif @@ -497,18 +497,18 @@ static void insert_decrement_b_stack_pointer (struct instruction *next_instructi instruction=(struct instruction*)fast_memory_allocate (sizeof (struct instruction)+2*sizeof (struct parameter)); instruction->instruction_arity=2; -#ifdef M68000 +# ifdef M68000 instruction->instruction_icode=ISUB; instruction->instruction_parameters[0].parameter_type=P_IMMEDIATE; instruction->instruction_parameters[0].parameter_data.i=offset; -#else +# else instruction->instruction_icode=ILEA; instruction->instruction_parameters[0].parameter_type=P_INDIRECT; instruction->instruction_parameters[0].parameter_offset=-offset; instruction->instruction_parameters[0].parameter_data.reg.r=B_STACK_POINTER; -#endif +# endif instruction->instruction_parameters[1].parameter_type=P_REGISTER; instruction->instruction_parameters[1].parameter_data.i=B_STACK_POINTER; @@ -680,6 +680,7 @@ static void compute_maximum_b_stack_offsets (register int b_offset) # ifdef THREAD32 instruction->instruction_icode!=IDIV && instruction->instruction_icode!=IDIVU && + instruction->instruction_icode!=IMULUD && # endif instruction->instruction_icode!=IDIVI && instruction->instruction_icode!=IREMI && @@ -929,6 +930,7 @@ void optimize_stack_access (struct basic_block *block,int *a_offset_p,int *b_off # ifdef THREAD32 instruction->instruction_icode!=IDIV && instruction->instruction_icode!=IDIVU && + instruction->instruction_icode!=IMULUD && # endif instruction->instruction_icode!=IDIVI && instruction->instruction_icode!=IREMI && @@ -1561,7 +1563,7 @@ static void store_next_uses (struct instruction *instruction) case IROTL: case IROTR: # endif #endif -#if defined (I486) && !defined (I486_USE_SCRATCH_REGISTER) +#if defined (I486) && !defined (I486_USE_SCRATCH_REGISTER) && !defined (THREAD32) case IMULUD: #endif #if (defined (I486) && !defined (I486_USE_SCRATCH_REGISTER)) || defined (G_POWER) @@ -1593,20 +1595,17 @@ IF_G_POWER ( case IUMULH: ) use_parameter (&instruction->instruction_parameters[1]); use_parameter (&instruction->instruction_parameters[0]); break; - case IDIV: case IREM: case IDIVU: case IREMU: -# ifdef THREAD32 + case IDIV: case IREM: case IDIVU: case IREMU: case IMULUD: +# ifdef THREAD32 use_parameter (&instruction->instruction_parameters[1]); use_parameter (&instruction->instruction_parameters[0]); define_parameter (&instruction->instruction_parameters[2]); - break; -# endif -# ifndef THREAD32 - case IMULUD: +# else define_scratch_register(); use_parameter (&instruction->instruction_parameters[1]); use_parameter (&instruction->instruction_parameters[0]); - break; # endif + break; case IMOVE: if ((instruction->instruction_parameters[0].parameter_type==P_INDIRECT || instruction->instruction_parameters[0].parameter_type==P_INDEXED) && @@ -4041,14 +4040,21 @@ IF_G_RISC (case IADDI: case ILSLI:) case IEXG: instruction_usedef_usedef (instruction); break; -#if defined (I486) && !defined (THREAD32) +#if defined (I486) case IMULUD: -# ifdef I486_USE_SCRATCH_REGISTER +# ifdef THREAD32 + use_3_same_type_registers + (&instruction->instruction_parameters[0].parameter_data.reg,USE_DEF, + &instruction->instruction_parameters[1].parameter_data.reg,USE_DEF, + &instruction->instruction_parameters[2].parameter_data.reg,DEF,D_REGISTER); +# else +# ifdef I486_USE_SCRATCH_REGISTER use_scratch_register(); -# endif +# endif instruction_usedef_usedef (instruction); -# ifdef I486_USE_SCRATCH_REGISTER +# ifdef I486_USE_SCRATCH_REGISTER allocate_scratch_register=1; +# endif # endif break; #endif |