diff options
author | John van Groningen | 2006-03-24 11:26:30 +0000 |
---|---|---|
committer | John van Groningen | 2006-03-24 11:26:30 +0000 |
commit | 9dac5f646c025a82c2dfb841db019fc8e1e77945 (patch) | |
tree | c98a328e09befbe34b8d338333fc9b678860c71e | |
parent | optimize shift n bitand 31 or 64 for IA32 and AMD64 (diff) |
remove use of scratch register on IA32 for shift instructions (by adding
instruction with extra register), IScc, IFScc, IFBcc (by adding IFCcc
instructions with extra register), ICMPW (not used anymore)
prevent generating FLD and FSTP instructions between FCOMP and
FNSTSW instruction
-rw-r--r-- | cgaas.c | 73 | ||||
-rw-r--r-- | cgawas.c | 82 | ||||
-rw-r--r-- | cgias.c | 289 | ||||
-rw-r--r-- | cgiconst.h | 28 | ||||
-rw-r--r-- | cgiwas.c | 250 | ||||
-rw-r--r-- | cglin.c | 313 | ||||
-rw-r--r-- | cgopt.c | 81 | ||||
-rw-r--r-- | cgpas.c | 106 | ||||
-rw-r--r-- | cgpwas.c | 118 | ||||
-rw-r--r-- | cgsas.c | 85 | ||||
-rw-r--r-- | cgswas.c | 96 |
11 files changed, 1089 insertions, 432 deletions
@@ -1857,14 +1857,60 @@ static void as_cmp_i_parameter (int i,struct parameter *parameter) } } -static void as_cmp_instruction (struct instruction *instruction,int size_flag) +static void as_cmp_instruction (struct instruction *instruction) { struct parameter parameter_0,parameter_1; parameter_0=instruction->instruction_parameters[0]; parameter_1=instruction->instruction_parameters[1]; - if (parameter_1.parameter_type==P_INDIRECT && size_flag!=SIZE_LONG){ + switch (parameter_0.parameter_type){ + case P_DESCRIPTOR_NUMBER: + switch (parameter_1.parameter_type){ + case P_REGISTER: + as_d_r2 (0201,0070,0075,parameter_0.parameter_data.l,parameter_0.parameter_offset, + parameter_1.parameter_data.reg.r); + return; + case P_INDIRECT: + as_d_id (0201,0070,parameter_0.parameter_data.l,parameter_0.parameter_offset, + parameter_1.parameter_offset,parameter_1.parameter_data.reg.r); + return; + case P_INDEXED: + as_d_x (0201,0070,parameter_0.parameter_data.l,parameter_0.parameter_offset, + parameter_1.parameter_offset,parameter_1.parameter_data.ir); + return; + } + break; + case P_IMMEDIATE: + as_cmp_i_parameter (parameter_0.parameter_data.i,¶meter_1); + return; + } + + if (parameter_1.parameter_type==P_REGISTER) + switch (parameter_0.parameter_type){ + case P_REGISTER: + as_r_r (0073,parameter_0.parameter_data.reg.r,parameter_1.parameter_data.reg.r); + return; + case P_INDIRECT: + as_id_r (0073,parameter_0.parameter_offset,parameter_0.parameter_data.reg.r,parameter_1.parameter_data.reg.r); + return; + case P_INDEXED: + as_x_r (0073,parameter_0.parameter_offset,parameter_0.parameter_data.ir,parameter_1.parameter_data.reg.r); + return; + } + + internal_error_in_function ("as_cmp_instruction"); +} + +#if 0 +static void as_cmpw_instruction (struct instruction *instruction) +{ + struct parameter parameter_0,parameter_1; + + parameter_0=instruction->instruction_parameters[0]; + parameter_1=instruction->instruction_parameters[1]; + + if (parameter_1.parameter_type==P_INDIRECT){ /* movswl */ as_017_id_r (0277,instruction->instruction_parameters[1].parameter_offset, instruction->instruction_parameters[1].parameter_data.reg.r,REGISTER_O0); @@ -1894,14 +1940,12 @@ static void as_cmp_instruction (struct instruction *instruction,int size_flag) as_cmp_i_parameter (parameter_0.parameter_data.i,¶meter_1); return; case P_INDIRECT: - if (size_flag==SIZE_WORD){ - /* movswl */ - as_017_id_r (0277,instruction->instruction_parameters[0].parameter_offset, - instruction->instruction_parameters[0].parameter_data.reg.r,REGISTER_O0); - - parameter_0.parameter_type=P_REGISTER; - parameter_0.parameter_data.reg.r=REGISTER_O0; - } + /* movswl */ + as_017_id_r (0277,instruction->instruction_parameters[0].parameter_offset, + instruction->instruction_parameters[0].parameter_data.reg.r,REGISTER_O0); + + parameter_0.parameter_type=P_REGISTER; + parameter_0.parameter_data.reg.r=REGISTER_O0; } if (parameter_1.parameter_type==P_REGISTER) @@ -1917,8 +1961,9 @@ static void as_cmp_instruction (struct instruction *instruction,int size_flag) return; } - internal_error_in_function ("as_cmp_instruction"); + internal_error_in_function ("as_cmpw_instruction"); } +#endif void store_label_in_data_section (LABEL *label) { @@ -3695,7 +3740,7 @@ static void as_instructions (struct instruction *instruction) as_sub_instruction (instruction); break; case ICMP: - as_cmp_instruction (instruction,SIZE_LONG); + as_cmp_instruction (instruction); break; case IJMP: as_jmp_instruction (instruction); @@ -3819,9 +3864,11 @@ static void as_instructions (struct instruction *instruction) case ISNO: as_set_condition_instruction (instruction,1); break; +#if 0 case ICMPW: - as_cmp_instruction (instruction,SIZE_WORD); + as_cmpw_instruction (instruction); break; +#endif case ITST: as_tst_instruction (instruction); break; @@ -1405,14 +1405,56 @@ static void w_as_shift_instruction (struct instruction *instruction,char *opcode } } -static void w_as_cmp_instruction (struct instruction *instruction,int size_flag) +static void w_as_cmp_instruction (struct instruction *instruction) { struct parameter parameter_0,parameter_1; parameter_0=instruction->instruction_parameters[0]; parameter_1=instruction->instruction_parameters[1]; - if (parameter_1.parameter_type==P_INDIRECT && size_flag!=SIZE_LONG){ + switch (parameter_0.parameter_type){ + case P_DESCRIPTOR_NUMBER: + w_as_lea_descriptor (parameter_0.parameter_data.l,parameter_0.parameter_offset,REGISTER_O0); + + w_as_opcode (intel_asm ? "cmp" : "cmpl"); + if (intel_asm) + w_as_parameter_comma (¶meter_1); + w_as_scratch_register(); + if (!intel_asm) + w_as_comma_parameter (¶meter_1); + w_as_newline(); + return; + case P_IMMEDIATE: + if (parameter_0.parameter_data.i==0 && parameter_1.parameter_type==P_REGISTER){ + w_as_opcode (intel_asm ? "test" : "testl"); + w_as_register (parameter_1.parameter_data.reg.r); + w_as_comma_register (parameter_1.parameter_data.reg.r); + w_as_newline(); + return; + } + } + + w_as_opcode (intel_asm ? "cmp" : "cmpl"); + if (intel_asm){ + if (parameter_0.parameter_type==P_IMMEDIATE && parameter_1.parameter_type!=P_REGISTER) + fprintf (assembly_file,"qword ptr "); + w_as_parameter_comma (¶meter_1); + } + w_as_parameter (¶meter_0); + if (!intel_asm) + w_as_comma_parameter (¶meter_1); + w_as_newline(); +} + +#if 0 +static void w_as_cmpw_instruction (struct instruction *instruction) +{ + struct parameter parameter_0,parameter_1; + + parameter_0=instruction->instruction_parameters[0]; + parameter_1=instruction->instruction_parameters[1]; + + if (parameter_1.parameter_type==P_INDIRECT){ w_as_opcode (intel_asm ? "movsx" : "movswl"); if (intel_asm) @@ -1439,26 +1481,17 @@ static void w_as_cmp_instruction (struct instruction *instruction,int size_flag) w_as_newline(); return; case P_INDIRECT: - if (size_flag==SIZE_WORD){ - w_as_opcode (intel_asm ? "movsx" : "movswl"); - if (intel_asm) - w_as_scratch_register_comma(); - w_as_parameter (¶meter_0); - if (!intel_asm) - w_as_comma_scratch_register(); - w_as_newline(); + w_as_opcode (intel_asm ? "movsx" : "movswl"); + if (intel_asm) + w_as_scratch_register_comma(); + w_as_parameter (¶meter_0); + if (!intel_asm) + w_as_comma_scratch_register(); + w_as_newline(); - parameter_0.parameter_type=P_REGISTER; - parameter_0.parameter_data.reg.r=REGISTER_O0; - } - case P_IMMEDIATE: - if (parameter_0.parameter_data.i==0 && parameter_1.parameter_type==P_REGISTER && size_flag==SIZE_LONG){ - w_as_opcode (intel_asm ? "test" : "testl"); - w_as_register (parameter_1.parameter_data.reg.r); - w_as_comma_register (parameter_1.parameter_data.reg.r); - w_as_newline(); - return; - } + parameter_0.parameter_type=P_REGISTER; + parameter_0.parameter_data.reg.r=REGISTER_O0; + break; } w_as_opcode (intel_asm ? "cmp" : "cmpl"); @@ -1472,6 +1505,7 @@ static void w_as_cmp_instruction (struct instruction *instruction,int size_flag) w_as_comma_parameter (¶meter_1); w_as_newline(); } +#endif static void w_as_tst_instruction (struct instruction *instruction,int size_flag) { @@ -2774,7 +2808,7 @@ static void w_as_instructions (register struct instruction *instruction) w_as_dyadic_instruction (instruction,intel_asm ? "sub" : "subl"); break; case ICMP: - w_as_cmp_instruction (instruction,SIZE_LONG); + w_as_cmp_instruction (instruction); break; case IJMP: w_as_jmp_instruction (instruction); @@ -2896,9 +2930,11 @@ static void w_as_instructions (register struct instruction *instruction) case ISNO: w_as_set_condition_instruction (instruction,"setno"); break; +#if 0 case ICMPW: - w_as_cmp_instruction (instruction,SIZE_WORD); + w_as_cmpw_instruction (instruction); break; +#endif case ITST: w_as_tst_instruction (instruction,SIZE_LONG); break; @@ -1676,14 +1676,60 @@ static void as_cmp_i_parameter (int i,struct parameter *parameter) } } -static void as_cmp_instruction (struct instruction *instruction,int size_flag) +static void as_cmp_instruction (struct instruction *instruction) { struct parameter parameter_0,parameter_1; parameter_0=instruction->instruction_parameters[0]; parameter_1=instruction->instruction_parameters[1]; - if (parameter_1.parameter_type==P_INDIRECT && size_flag!=SIZE_LONG){ + switch (parameter_0.parameter_type){ + case P_DESCRIPTOR_NUMBER: + switch (parameter_1.parameter_type){ + case P_REGISTER: + as_d_r2 (0201,0070,0075,parameter_0.parameter_data.l,parameter_0.parameter_offset, + parameter_1.parameter_data.reg.r); + return; + case P_INDIRECT: + as_d_id (0201,0070,parameter_0.parameter_data.l,parameter_0.parameter_offset, + parameter_1.parameter_offset,parameter_1.parameter_data.reg.r); + return; + case P_INDEXED: + as_d_x (0201,0070,parameter_0.parameter_data.l,parameter_0.parameter_offset, + parameter_1.parameter_offset,parameter_1.parameter_data.ir); + return; + } + break; + case P_IMMEDIATE: + as_cmp_i_parameter (parameter_0.parameter_data.i,¶meter_1); + return; + } + + if (parameter_1.parameter_type==P_REGISTER) + switch (parameter_0.parameter_type){ + case P_REGISTER: + as_r_r (0073,parameter_0.parameter_data.reg.r,parameter_1.parameter_data.reg.r); + return; + case P_INDIRECT: + as_id_r (0073,parameter_0.parameter_offset,parameter_0.parameter_data.reg.r,parameter_1.parameter_data.reg.r); + return; + case P_INDEXED: + as_x_r (0073,parameter_0.parameter_offset,parameter_0.parameter_data.ir,parameter_1.parameter_data.reg.r); + return; + } + + internal_error_in_function ("as_cmp_instruction"); +} + +#if 0 +static void as_cmpw_instruction (struct instruction *instruction) +{ + struct parameter parameter_0,parameter_1; + + parameter_0=instruction->instruction_parameters[0]; + parameter_1=instruction->instruction_parameters[1]; + + if (parameter_1.parameter_type==P_INDIRECT){ /* movswl */ store_c (0017); as_id_r (0277,instruction->instruction_parameters[1].parameter_offset, @@ -1714,15 +1760,13 @@ static void as_cmp_instruction (struct instruction *instruction,int size_flag) as_cmp_i_parameter (parameter_0.parameter_data.i,¶meter_1); return; case P_INDIRECT: - if (size_flag==SIZE_WORD){ - /* movswl */ - store_c (0017); - as_id_r (0277,instruction->instruction_parameters[0].parameter_offset, - instruction->instruction_parameters[0].parameter_data.reg.r,REGISTER_O0); - - parameter_0.parameter_type=P_REGISTER; - parameter_0.parameter_data.reg.r=REGISTER_O0; - } + /* movswl */ + store_c (0017); + as_id_r (0277,instruction->instruction_parameters[0].parameter_offset, + instruction->instruction_parameters[0].parameter_data.reg.r,REGISTER_O0); + + parameter_0.parameter_type=P_REGISTER; + parameter_0.parameter_data.reg.r=REGISTER_O0; } if (parameter_1.parameter_type==P_REGISTER) @@ -1738,8 +1782,9 @@ static void as_cmp_instruction (struct instruction *instruction,int size_flag) return; } - internal_error_in_function ("as_cmp_instruction"); + internal_error_in_function ("as_cmpw_instruction"); } +#endif void store_label_in_data_section (LABEL *label) { @@ -1894,6 +1939,47 @@ static void as_shift_instruction (struct instruction *instruction,int shift_code } } +static void as_shift_s_instruction (struct instruction *instruction,int shift_code) +{ + if (instruction->instruction_parameters[0].parameter_type!=P_REGISTER){ + if (instruction->instruction_parameters[0].parameter_type==P_IMMEDIATE){ + store_c (0301); + store_c (0300 | (shift_code<<3) | reg_num (instruction->instruction_parameters[1].parameter_data.reg.r)); + store_c (instruction->instruction_parameters[0].parameter_data.i & 31); + } else + internal_error_in_function ("as_shift_s_instruction"); + } else { + int r0,r1; + + r0=instruction->instruction_parameters[0].parameter_data.reg.r; + r1=instruction->instruction_parameters[1].parameter_data.reg.r; + if (r0==REGISTER_A0){ + store_c (0323); + store_c (0300 | (shift_code<<3) | reg_num (r1)); + } else { + int scratch_register; + + scratch_register=instruction->instruction_parameters[2].parameter_data.reg.r; + if (scratch_register==REGISTER_A0){ + as_move_r_r (r0,REGISTER_A0); + + store_c (0323); + store_c (0300 | (shift_code<<3) | reg_num (r1)); + } else { + as_move_r_r (REGISTER_A0,scratch_register); + as_move_r_r (r0,REGISTER_A0); + + if (r1==REGISTER_A0) + r1=scratch_register; + store_c (0323); + store_c (0300 | (shift_code<<3) | reg_num (r1)); + + as_move_r_r (scratch_register,REGISTER_A0); + } + } + } +} + static void as_logic_instruction (struct instruction *instruction,int code1,int code2,int code3) { switch (instruction->instruction_parameters[0].parameter_type){ @@ -2705,68 +2791,33 @@ static void as_divdu_instruction (struct instruction *instruction) static void as_set_condition_instruction (struct instruction *instruction,int condition_code) { int r; + unsigned int rn; r=instruction->instruction_parameters[0].parameter_data.reg.r; - - if (r==REGISTER_A3 || r==REGISTER_A4){ -#if 1 - as_move_r_r (REGISTER_D0,REGISTER_O0); -#else - as_move_r_r (REGISTER_D0,r); -#endif + rn=reg_num (r); + + if (rn<4u){ store_c (0017); store_c (0220 | condition_code); - store_c (0300 | 0); /* %al */ + store_c (0300 | rn); -#if 1 /* movzbl */ store_c (017); store_c (0266); - store_c (0300 | (reg_num (r)<<3) | 0 /* %al */); - - as_move_r_r (REGISTER_O0,REGISTER_D0); -#else - /* and $1,D0 */ - store_c (0203); - store_c (0340); - store_c (1); - - store_c (0x90+reg_num (r)); /* xchg r,D0 */ -#endif + store_c (0300 | (rn<<3) | rn); } else { - int rn; - - switch (r){ - case REGISTER_D0: - rn=0; - break; - case REGISTER_D1: - rn=3; - break; - case REGISTER_A0: - rn=1; - break; - case REGISTER_A1: - rn=2; - break; - } + as_move_r_r (REGISTER_D0,r); store_c (0017); store_c (0220 | condition_code); + store_c (0300 | 0); /* %al */ - store_c (0300 | rn); - -#if 1 /* movzbl */ store_c (017); store_c (0266); - store_c (0300 | (reg_num (r)<<3) | rn); -#else - /* and $1,reg */ - store_c (0203); - store_c (0340+rn); - store_c (1); -#endif + store_c (0300 | (reg_num (REGISTER_D0)<<3) | 0 /* %al */); + + store_c (0x90+rn); /* xchg r,D0 */ } } @@ -2972,8 +3023,11 @@ struct instruction *find_next_fp_instruction (struct instruction *instruction) switch (instruction->instruction_icode){ case IFADD: case IFSUB: case IFMUL: case IFDIV: case IFMOVEL: case IFCMP: case IFNEG: case IFABS: case IFTST: case IFREM: +#if 0 case IFBEQ: case IFBGE: case IFBGT: case IFBLE: case IFBLT: case IFBNE: +#endif case IFSEQ: case IFSGE: case IFSGT: case IFSLE: case IFSLT: case IFSNE: + case IFCEQ: case IFCGE: case IFCGT: case IFCLE: case IFCLT: case IFCNE: case IFCOS: case IFSIN: case IFSQRT: case IFTAN: case IFEXG: case IWORD: @@ -3673,14 +3727,8 @@ static void as_monadic_float_instruction (struct instruction *instruction,int co #endif } -static void as_float_branch_instruction (struct instruction *instruction,int n) +static void as_test_floating_point_condition_code (int n) { - int r; - - r=instruction->instruction_parameters[0].parameter_data.reg.r; - - as_r_r (0213,REGISTER_D0,REGISTER_O0); - store_c (0xdf); store_c (0xe0); /* fnstsw %ax */ @@ -3721,6 +3769,18 @@ static void as_float_branch_instruction (struct instruction *instruction,int n) store_c (5); /* andb $5,%ah */ break; } +} + +#if 0 +static void as_float_branch_instruction (struct instruction *instruction,int n) +{ + int r; + + r=instruction->instruction_parameters[0].parameter_data.reg.r; + + as_r_r (0213,REGISTER_D0,REGISTER_O0); + + as_test_floating_point_condition_code (n); as_r_r (0213,REGISTER_O0,REGISTER_D0); @@ -3739,6 +3799,7 @@ static void as_float_branch_instruction (struct instruction *instruction,int n) break; } } +#endif static void as_set_float_condition_instruction (struct instruction *instruction,int n) { @@ -3749,46 +3810,7 @@ static void as_set_float_condition_instruction (struct instruction *instruction, if (r!=REGISTER_D0) as_r_r (0213,REGISTER_D0,r); - store_c (0xdf); - store_c (0xe0); /* fnstsw %ax */ - - store_c (0x80); - store_c (0xe4); /* andb $i,%ah */ - - switch (n){ - case 0: - store_c (68); /* andb $68,%ah */ - store_c (0x80); - store_c (0xf4); - store_c (64); /* xorb $64,%ah */ - break; - case 1: - store_c (69); /* andb $69,%ah */ - store_c (0x80); - store_c (0xfc); - store_c (1); /* cmpb $1,%ah */ - break; - case 2: - store_c (69); /* andb $69,%ah */ - break; - case 3: - store_c (69); /* andb $69,%ah */ - store_c (0x80); - store_c (0xfc); - store_c (64); /* cmpb $64,%ah */ - break; - case 4: - store_c (69); /* andb $69,%ah */ - store_c (0xfe); - store_c (0xcc); /* decb %ah */ - store_c (0x80); - store_c (0xfc); - store_c (64); /* cmpb $64,%ah */ - break; - case 5: - store_c (5); /* andb $5,%ah */ - break; - } + as_test_floating_point_condition_code (n); store_c (0x0f); switch (n){ @@ -3807,15 +3829,37 @@ static void as_set_float_condition_instruction (struct instruction *instruction, } store_c (0xc0); +#if 1 + /* movzbl */ + store_c (017); + store_c (0266); + store_c (0300 | (reg_num (REGISTER_D0)<<3) | 0 /* %al */); +#else /* and $1,D0 */ store_c (0203); store_c (0340); store_c (1); +#endif if (r!=REGISTER_D0) store_c (0x90+reg_num (r)); /* xchg r,D0 */ } +static void as_convert_float_condition_instruction (struct instruction *instruction,int n) +{ + int r; + + r=instruction->instruction_parameters[0].parameter_data.reg.r; + + if (r!=REGISTER_D0) + as_r_r (0213,REGISTER_D0,r); + + as_test_floating_point_condition_code (n); + + if (r!=REGISTER_D0) + as_r_r (0213,r,REGISTER_D0); +} + #ifdef FP_STACK_OPTIMIZATIONS static void as_fexg (struct instruction *instruction) { @@ -4051,7 +4095,7 @@ static void as_instructions (struct instruction *instruction) as_sub_instruction (instruction); break; case ICMP: - as_cmp_instruction (instruction,SIZE_LONG); + as_cmp_instruction (instruction); break; case IJMP: as_jmp_instruction (instruction); @@ -4115,6 +4159,15 @@ static void as_instructions (struct instruction *instruction) case IASR: as_shift_instruction (instruction,7); break; + case ILSL_S: + as_shift_s_instruction (instruction,4); + break; + case ILSR_S: + as_shift_s_instruction (instruction,5); + break; + case IASR_S: + as_shift_s_instruction (instruction,7); + break; case IMUL: as_mul_instruction (instruction); break; @@ -4181,9 +4234,11 @@ static void as_instructions (struct instruction *instruction) case ISNO: as_set_condition_instruction (instruction,1); break; +#if 0 case ICMPW: - as_cmp_instruction (instruction,SIZE_WORD); + as_cmpw_instruction (instruction); break; +#endif case ITST: as_tst_instruction (instruction); break; @@ -4248,6 +4303,7 @@ static void as_instructions (struct instruction *instruction) case IFMUL: as_dyadic_float_instruction (instruction,1,0xc8,0xc8); /*fmull fmul fmulp*/ break; +#if 0 case IFBEQ: as_float_branch_instruction (instruction,0); break; @@ -4266,6 +4322,7 @@ static void as_instructions (struct instruction *instruction) case IFBNE: as_float_branch_instruction (instruction,3); break; +#endif case IFMOVEL: as_fmovel_instruction (instruction); break; @@ -4302,6 +4359,24 @@ static void as_instructions (struct instruction *instruction) case IFSNE: as_set_float_condition_instruction (instruction,3); break; + case IFCEQ: + as_convert_float_condition_instruction (instruction,0); + break; + case IFCGE: + as_convert_float_condition_instruction (instruction,5); + break; + case IFCGT: + as_convert_float_condition_instruction (instruction,2); + break; + case IFCLE: + as_convert_float_condition_instruction (instruction,4); + break; + case IFCLT: + as_convert_float_condition_instruction (instruction,1); + break; + case IFCNE: + as_convert_float_condition_instruction (instruction,3); + break; case IRTSI: as_rtsi_instruction (instruction); break; @@ -12,19 +12,23 @@ enum { IADD, IAND, IASR, IBEQ, IBGE, IBGEU, IBGT, IBGTU, IBLE, IBLEU, IBLT, IBLTU, IBNE, IBNO, - IBO, ICMP, ICMPW, IDIV, IEOR, IEXG, IEXT, - IFADD, IFBEQ, IFBGE, IFBGT, IFBLE, IFBLT, IFBNE, - IFABS, IFCMP, IFCOS, IFDIV, IFMUL, IFNEG, IFREM, - IFSEQ, IFSGE, IFSGT, IFSIN, IFSLE, IFSLT, IFSNE, - IFSUB, IFTAN, IFTST, IFMOVE, IFMOVEL, IJMP, IJSR, - ILEA, ILSL, ILSR, IMOD, IMOVE, IMOVEB, IMOVEW, - IMUL, INEG, IOR, IRTS, ISCHEDULE, ISEQ, ISGE, - ISGEU, ISGT, ISGTU, ISLE, ISLEU, ISLT, ISLTU, - ISNE, ISNO, ISO, ISUB, ITST, IWORD + IBO, ICMP, IDIV, IEOR, IEXG, IEXT, IFADD, +#if ! (defined (I486) && !defined (G_A64)) + IFBEQ, IFBGE, IFBGT, IFBLE, IFBLT, IFBNE, +#endif + IFABS, + IFCMP, IFCOS, IFDIV, IFMUL, IFNEG, IFREM, IFSEQ, + IFSGE, IFSGT, IFSIN, IFSLE, IFSLT, IFSNE, IFSUB, + IFTAN, IFTST, IFMOVE, IFMOVEL, IJMP, IJSR, ILEA, + ILSL, ILSR, IMOD, IMOVE, IMOVEB, IMOVEW, IMUL, + INEG, IOR, IRTS, ISCHEDULE, ISEQ, ISGE, ISGEU, + ISGT, ISGTU, ISLE, ISLEU, ISLT, ISLTU, ISNE, + ISNO, ISO, ISUB, ITST, IWORD #if !defined (G_POWER) ,IFSQRT #endif #ifdef M68000 + ,ICMPW ,IFACOS, IFASIN, IFATAN, IFEXP, IFLN, IFLOG10, IBMI, IBMOVE, IMOVEM, ITSTB #endif @@ -44,6 +48,12 @@ enum { ,IADDI, ILSLI ,IADDO, ISUBO #endif +#ifdef I486 + ,IASR_S,ILSL_S,ILSR_S +#endif +#if defined (I486) && !defined (G_A64) + ,IFCEQ, IFCGE, IFCGT, IFCLE, IFCLT, IFCNE +#endif #ifdef G_POWER ,ICMPLW ,IMULO @@ -1179,14 +1179,117 @@ static void w_as_shift_instruction (struct instruction *instruction,char *opcode } } -static void w_as_cmp_instruction (struct instruction *instruction,int size_flag) +static void w_as_shift_s_instruction (struct instruction *instruction,char *opcode) +{ + if (instruction->instruction_parameters[0].parameter_type!=P_REGISTER){ + if (instruction->instruction_parameters[0].parameter_type==P_IMMEDIATE){ + w_as_opcode (opcode); + if (intel_asm) + w_as_register_comma (instruction->instruction_parameters[1].parameter_data.reg.r); + w_as_immediate (instruction->instruction_parameters[0].parameter_data.i & 31); + if (!intel_asm) + w_as_comma_register (instruction->instruction_parameters[1].parameter_data.reg.r); + w_as_newline(); + } else + internal_error_in_function ("w_as_shift_s_instruction"); + } else { + int r0; + + r0=instruction->instruction_parameters[0].parameter_data.reg.r; + if (r0==REGISTER_A0){ + w_as_opcode (opcode); + if (intel_asm) + w_as_register_comma (instruction->instruction_parameters[1].parameter_data.reg.r); + fprintf (assembly_file,intel_asm ? "cl" : "%%cl"); + if (!intel_asm) + w_as_comma_register (instruction->instruction_parameters[1].parameter_data.reg.r); + w_as_newline(); + } else { + int scratch_register; + + scratch_register=instruction->instruction_parameters[2].parameter_data.reg.r; + if (scratch_register==REGISTER_A0){ + w_as_movl_register_register_newline (r0,REGISTER_A0); + + w_as_opcode (opcode); + if (!intel_asm) + fprintf (assembly_file,"%%cl,"); + w_as_register (instruction->instruction_parameters[1].parameter_data.reg.r); + if (intel_asm) + fprintf (assembly_file,",cl"); + w_as_newline(); + } else { + int r; + + w_as_movl_register_register_newline (REGISTER_A0,scratch_register); + w_as_movl_register_register_newline (r0,REGISTER_A0); + + w_as_opcode (opcode); + if (!intel_asm) + fprintf (assembly_file,"%%cl,"); + r=instruction->instruction_parameters[1].parameter_data.reg.r; + if (r==REGISTER_A0) + w_as_register (scratch_register); + else + w_as_register (r); + if (intel_asm) + fprintf (assembly_file,",cl"); + w_as_newline(); + + w_as_movl_register_register_newline (scratch_register,REGISTER_A0); + } + } + } +} + +static void w_as_cmp_instruction (struct instruction *instruction) +{ + struct parameter parameter_0,parameter_1; + + parameter_0=instruction->instruction_parameters[0]; + parameter_1=instruction->instruction_parameters[1]; + + switch (parameter_0.parameter_type){ + case P_DESCRIPTOR_NUMBER: + w_as_opcode (intel_asm ? "cmp" : "cmpl"); + if (intel_asm) + w_as_parameter_comma (¶meter_1); + w_as_descriptor (parameter_0.parameter_data.l,parameter_0.parameter_offset); + if (!intel_asm) + w_as_comma_parameter (¶meter_1); + w_as_newline(); + return; + case P_IMMEDIATE: + if (parameter_0.parameter_data.i==0 && parameter_1.parameter_type==P_REGISTER){ + w_as_opcode (intel_asm ? "test" : "testl"); + w_as_register (parameter_1.parameter_data.reg.r); + w_as_comma_register (parameter_1.parameter_data.reg.r); + w_as_newline(); + return; + } + } + + w_as_opcode (intel_asm ? "cmp" : "cmpl"); + if (intel_asm){ + if (parameter_0.parameter_type==P_IMMEDIATE) + fprintf (assembly_file,"dword ptr "); + w_as_parameter_comma (¶meter_1); + } + w_as_parameter (¶meter_0); + if (!intel_asm) + w_as_comma_parameter (¶meter_1); + w_as_newline(); +} + +#if 0 +static void w_as_cmpw_instruction (struct instruction *instruction) { struct parameter parameter_0,parameter_1; parameter_0=instruction->instruction_parameters[0]; parameter_1=instruction->instruction_parameters[1]; - if (parameter_1.parameter_type==P_INDIRECT && size_flag!=SIZE_LONG){ + if (parameter_1.parameter_type==P_INDIRECT){ w_as_opcode (intel_asm ? "movsx" : "movswl"); if (intel_asm) @@ -1211,26 +1314,16 @@ static void w_as_cmp_instruction (struct instruction *instruction,int size_flag) w_as_newline(); return; case P_INDIRECT: - if (size_flag==SIZE_WORD){ - w_as_opcode (intel_asm ? "movsx" : "movswl"); - if (intel_asm) - w_as_scratch_register_comma(); - w_as_parameter (¶meter_0); - if (!intel_asm) - w_as_comma_scratch_register(); - w_as_newline(); + w_as_opcode (intel_asm ? "movsx" : "movswl"); + if (intel_asm) + w_as_scratch_register_comma(); + w_as_parameter (¶meter_0); + if (!intel_asm) + w_as_comma_scratch_register(); + w_as_newline(); - parameter_0.parameter_type=P_REGISTER; - parameter_0.parameter_data.reg.r=REGISTER_O0; - } - case P_IMMEDIATE: - if (parameter_0.parameter_data.i==0 && parameter_1.parameter_type==P_REGISTER && size_flag==SIZE_LONG){ - w_as_opcode (intel_asm ? "test" : "testl"); - w_as_register (parameter_1.parameter_data.reg.r); - w_as_comma_register (parameter_1.parameter_data.reg.r); - w_as_newline(); - return; - } + parameter_0.parameter_type=P_REGISTER; + parameter_0.parameter_data.reg.r=REGISTER_O0; } w_as_opcode (intel_asm ? "cmp" : "cmpl"); @@ -1244,6 +1337,7 @@ static void w_as_cmp_instruction (struct instruction *instruction,int size_flag) w_as_comma_parameter (¶meter_1); w_as_newline(); } +#endif static void w_as_tst_instruction (struct instruction *instruction,int size_flag) { @@ -1446,53 +1540,55 @@ static void w_as_jsr_instruction (struct instruction *instruction) static void w_as_set_condition_instruction (struct instruction *instruction,char *opcode) { int r; + char *reg_s; r=instruction->instruction_parameters[0].parameter_data.reg.r; - - if (r==REGISTER_A3 || r==REGISTER_A4){ - w_as_movl_register_register_newline (REGISTER_D0,REGISTER_O0); + switch (r){ + case REGISTER_D0: + reg_s=intel_asm ? "al" : "%%al"; + break; + case REGISTER_D1: + reg_s=intel_asm ? "bl" : "%%bl"; + break; + case REGISTER_A0: + reg_s=intel_asm ? "cl" : "%%cl"; + break; + case REGISTER_A1: + reg_s=intel_asm ? "dl" : "%%dl"; + break; + default: + reg_s=NULL; + } + + if (reg_s!=NULL){ w_as_opcode (opcode); - fprintf (assembly_file,intel_asm ? "al" : "%%al"); + fprintf (assembly_file,reg_s); w_as_newline(); w_as_opcode (intel_asm ? "movzx" : "movzbl"); if (intel_asm) w_as_register_comma (r); - fprintf (assembly_file,intel_asm ? "al" : "%%al"); + fprintf (assembly_file,reg_s); if (!intel_asm) w_as_comma_register (r); w_as_newline(); - - w_as_movl_register_register_newline (REGISTER_O0,REGISTER_D0); } else { - char *reg_s; + w_as_movl_register_register_newline (REGISTER_D0,r); w_as_opcode (opcode); - switch (r){ - case REGISTER_D0: - reg_s=intel_asm ? "al" : "%%al"; - break; - case REGISTER_D1: - reg_s=intel_asm ? "bl" : "%%bl"; - break; - case REGISTER_A0: - reg_s=intel_asm ? "cl" : "%%cl"; - break; - case REGISTER_A1: - reg_s=intel_asm ? "dl" : "%%dl"; - break; - } - fprintf (assembly_file,reg_s); + fprintf (assembly_file,intel_asm ? "al" : "%%al"); w_as_newline(); w_as_opcode (intel_asm ? "movzx" : "movzbl"); if (intel_asm) - w_as_register_comma (r); - fprintf (assembly_file,reg_s); + w_as_register_comma (REGISTER_D0); + fprintf (assembly_file,intel_asm ? "al" : "%%al"); if (!intel_asm) - w_as_comma_register (r); + w_as_comma_register (REGISTER_D0); w_as_newline(); + + w_as_opcode_register_register_newline ("xchg",r,REGISTER_D0); } } @@ -1524,6 +1620,7 @@ static void w_as_set_float_condition_instruction (struct instruction *instructio fprintf (assembly_file,intel_asm ? "al" : "%%al"); w_as_newline(); +#if 0 w_as_opcode ("and"); if (intel_asm) w_as_register_comma (REGISTER_D0); @@ -1531,11 +1628,35 @@ static void w_as_set_float_condition_instruction (struct instruction *instructio if (!intel_asm) w_as_comma_register (REGISTER_D0); w_as_newline(); +#else + w_as_opcode (intel_asm ? "movzx" : "movzbl"); + if (intel_asm) + w_as_register_comma (REGISTER_D0); + fprintf (assembly_file,intel_asm ? "al" : "%%al"); + if (!intel_asm) + w_as_comma_register (REGISTER_D0); + w_as_newline(); +#endif if (r!=REGISTER_D0) w_as_opcode_register_register_newline ("xchg",r,REGISTER_D0); } +static void w_as_convert_float_condition_instruction (struct instruction *instruction,int n) +{ + int r; + + r=instruction->instruction_parameters[0].parameter_data.reg.r; + + if (r!=REGISTER_D0) + w_as_movl_register_register_newline (REGISTER_D0,r); + + as_test_floating_point_condition_code (n); + + if (r!=REGISTER_D0) + w_as_movl_register_register_newline (r,REGISTER_D0); +} + static void w_as_div_rem_i_instruction (struct instruction *instruction,int compute_remainder) { int s_reg1,s_reg2,s_reg3,i,sd_reg,i_reg,tmp_reg,abs_i; @@ -3107,7 +3228,7 @@ static void w_as_instructions (register struct instruction *instruction) w_as_dyadic_instruction (instruction,intel_asm ? "sub" : "subl"); break; case ICMP: - w_as_cmp_instruction (instruction,SIZE_LONG); + w_as_cmp_instruction (instruction); break; case IJMP: w_as_jmp_instruction (instruction); @@ -3169,6 +3290,15 @@ static void w_as_instructions (register struct instruction *instruction) case IASR: w_as_shift_instruction (instruction,"sar"); break; + case ILSL_S: + w_as_shift_s_instruction (instruction,"shl"); + break; + case ILSR_S: + w_as_shift_s_instruction (instruction,"shr"); + break; + case IASR_S: + w_as_shift_s_instruction (instruction,"sar"); + break; case IMUL: w_as_dyadic_instruction (instruction,intel_asm ? "imul" : "imull"); break; @@ -3235,9 +3365,11 @@ static void w_as_instructions (register struct instruction *instruction) case ISNO: w_as_set_condition_instruction (instruction,"setno"); break; +#if 0 case ICMPW: - w_as_cmp_instruction (instruction,SIZE_WORD); + w_as_cmp_instruction (instruction); break; +#endif case ITST: w_as_tst_instruction (instruction,SIZE_LONG); break; @@ -3299,6 +3431,7 @@ static void w_as_instructions (register struct instruction *instruction) case IFMUL: w_as_dyadic_float_instruction (instruction,"fmul","fmul"); break; +#if 0 case IFBEQ: w_as_float_branch_instruction (instruction,0); break; @@ -3317,6 +3450,7 @@ static void w_as_instructions (register struct instruction *instruction) case IFBNE: w_as_float_branch_instruction (instruction,3); break; +#endif case IFMOVEL: w_as_fmovel_instruction (instruction); break; @@ -3353,6 +3487,24 @@ static void w_as_instructions (register struct instruction *instruction) case IFSNE: w_as_set_float_condition_instruction (instruction,3); break; + case IFCEQ: + w_as_convert_float_condition_instruction (instruction,0); + break; + case IFCGE: + w_as_convert_float_condition_instruction (instruction,5); + break; + case IFCGT: + w_as_convert_float_condition_instruction (instruction,2); + break; + case IFCLE: + w_as_convert_float_condition_instruction (instruction,4); + break; + case IFCLT: + w_as_convert_float_condition_instruction (instruction,1); + break; + case IFCNE: + w_as_convert_float_condition_instruction (instruction,3); + break; #ifdef FP_STACK_OPTIMIZATIONS case IFEXG: w_as_fexg (instruction); @@ -340,9 +340,10 @@ static void i_cmp_id_r (int offset,int register_1,int register_2) parameter_data.i=register_2); } +#ifdef M68000 static void i_cmpw_d_id (LABEL *descriptor,int arity,int offset_1,int register_1) { - register struct instruction *instruction; + struct instruction *instruction; instruction=i_new_instruction2 (ICMPW); @@ -354,6 +355,7 @@ static void i_cmpw_d_id (LABEL *descriptor,int arity,int offset_1,int register_1 parameter_offset=offset_1, parameter_data.i=register_1); } +#endif #if defined (M68000) || defined (I486) static void i_exg_r_r (int register_1,int register_2) @@ -778,7 +780,7 @@ void i_jsr_l_id (LABEL *label,int offset) #ifdef I486 void i_jsr_r (int register_1) { - register struct instruction *instruction; + struct instruction *instruction; instruction=i_new_instruction1 (IJSR); @@ -847,7 +849,7 @@ void i_divdu_r_r_r (int register_1,int register_2,int register_3) void i_lea_id_r (int offset,int register_1,int register_2) { - register struct instruction *instruction; + struct instruction *instruction; instruction=i_new_instruction2 (ILEA); @@ -2203,7 +2205,11 @@ static void ad_to_parameter (ADDRESS *ad_p,struct parameter *parameter_p) } } -static int fad_to_parameter (ADDRESS *ad_p,struct parameter *parameter_p) +#if defined (FP_STACK_OPTIMIZATIONS) || defined (FMADD) +#define FP_REG_LAST_USE 4 +#endif + +static int fad_to_parameter_without_freeing_fregister (ADDRESS *ad_p,struct parameter *parameter_p) { switch (ad_p->ad_mode){ case P_F_REGISTER: @@ -2245,7 +2251,7 @@ static int fad_to_parameter (ADDRESS *ad_p,struct parameter *parameter_p) load_x_graph=ad_p->ad_load_x_graph; i_ad_p=(ADDRESS *)load_x_graph->instruction_parameters[1].p; - + if (load_x_graph->inode_arity & LOAD_X_TO_ADDRESS){ load_x_graph->inode_arity ^= (LOAD_X_TO_ADDRESS | LOAD_X_TO_REGISTER); if (i_ad_p->ad_mode==P_INDEXED){ @@ -2274,15 +2280,16 @@ static int fad_to_parameter (ADDRESS *ad_p,struct parameter *parameter_p) parameter_p->parameter_flags = load_x_graph->inode_arity & LOAD_STORE_ALIGNED_REAL; #endif } else { - U2(parameter_p,parameter_type=P_REGISTER,parameter_data.i=i_ad_p->ad_register); - - if (--*i_ad_p->ad_count_p==0) - free_register (i_ad_p->ad_register); + set_float_register_parameter (*parameter_p,i_ad_p->ad_register); + if (--*i_ad_p->ad_count_p==0){ + /* free_fregister (i_ad_p->ad_register);*/ + return 1; + } } break; } default: - internal_error_in_function ("ad_to_parameter"); + internal_error_in_function ("fad_to_parameter_without_freeing_fregister"); } return 0; } @@ -2400,7 +2407,7 @@ static void instruction_fr_fr (int instruction_code,int register_1,int register_ static void instruction_l (int instruction_code,LABEL *label) { - register struct instruction *instruction; + struct instruction *instruction; instruction=i_new_instruction1 (instruction_code); @@ -3244,7 +3251,8 @@ static int compare_node (INSTRUCTION_GRAPH graph,int i_test_1,int i_test_2) graph_1=graph->instruction_parameters[0].p; graph_2=graph->instruction_parameters[1].p; - + +#ifdef M68000 if (graph_1->instruction_code==GLOAD_DES_ID && graph_1->node_count==1 && graph_2->instruction_code==GLOAD_DES_I && graph_2->node_count==1) { @@ -3255,100 +3263,99 @@ static int compare_node (INSTRUCTION_GRAPH graph,int i_test_1,int i_test_2) i_cmpw_d_id (graph_2->instruction_parameters[0].l,graph_2->instruction_parameters[1].i, graph_1->instruction_parameters[0].i,ad_1.ad_register); return i_test_2; - } else - if (graph_2->instruction_code==GLOAD_DES_ID && graph_2->node_count==1 - && graph_1->instruction_code==GLOAD_DES_I && graph_1->node_count==1) - { - linearize_graph (graph_2->instruction_parameters[1].p,&ad_1); - in_address_register (&ad_1); - if (--*ad_1.ad_count_p==0) - free_aregister (ad_1.ad_register); - i_cmpw_d_id (graph_1->instruction_parameters[0].l, - graph_1->instruction_parameters[1].i, - graph_2->instruction_parameters[0].i,ad_1.ad_register); - return i_test_1; - } else { - if (graph->order_left){ - linearize_graph (graph_1,&ad_1); - linearize_graph (graph_2,&ad_2); - } else { - linearize_graph (graph_2,&ad_2); - linearize_graph (graph_1,&ad_1); - } + } - mode_1=ad_1.ad_mode; - mode_2=ad_2.ad_mode; + if (graph_2->instruction_code==GLOAD_DES_ID && graph_2->node_count==1 + && graph_1->instruction_code==GLOAD_DES_I && graph_1->node_count==1) + { + linearize_graph (graph_2->instruction_parameters[1].p,&ad_1); + in_address_register (&ad_1); + if (--*ad_1.ad_count_p==0) + free_aregister (ad_1.ad_register); + i_cmpw_d_id (graph_1->instruction_parameters[0].l, + graph_1->instruction_parameters[1].i, + graph_2->instruction_parameters[0].i,ad_1.ad_register); + return i_test_1; + } +#endif - if (mode_1==P_IMMEDIATE && ! (mode_2==P_IMMEDIATE || mode_2==P_DESCRIPTOR_NUMBER)){ - LONG i; + if (graph->order_left){ + linearize_graph (graph_1,&ad_1); + linearize_graph (graph_2,&ad_2); + } else { + linearize_graph (graph_2,&ad_2); + linearize_graph (graph_1,&ad_1); + } + + mode_1=ad_1.ad_mode; + mode_2=ad_2.ad_mode; + + if (mode_1==P_IMMEDIATE && ! (mode_2==P_IMMEDIATE || mode_2==P_DESCRIPTOR_NUMBER)){ + LONG i; #ifdef M68000 - int real_dreg_number; + int real_dreg_number; #endif - i=ad_1.ad_offset; + i=ad_1.ad_offset; #ifdef M68000 - if (i<128 && i>=-128 && i!=0 && (real_dreg_number=try_get_real_dregister_number())>=0){ - int dreg; - - dreg=num_to_d_reg (real_dreg_number); - i_move_i_r (i,dreg); - instruction_ad_r (ICMP,&ad_2,dreg); - free_dregister (dreg); - return i_test_2; - } else { + if (i<128 && i>=-128 && i!=0 && (real_dreg_number=try_get_real_dregister_number())>=0){ + int dreg; + + dreg=num_to_d_reg (real_dreg_number); + i_move_i_r (i,dreg); + instruction_ad_r (ICMP,&ad_2,dreg); + free_dregister (dreg); + return i_test_2; + } else { #endif - instruction_i_ad (ICMP,i,&ad_2); - return i_test_1; + instruction_i_ad (ICMP,i,&ad_2); + return i_test_1; #ifdef M68000 - } + } #endif - } else if (mode_1==P_DESCRIPTOR_NUMBER - && ! (mode_2==P_IMMEDIATE || mode_2==P_DESCRIPTOR_NUMBER)){ - instruction_d_ad (ICMP,ad_1.ad_label,ad_1.ad_offset,&ad_2); - return i_test_1; - } else if (mode_2==P_IMMEDIATE - && ! (mode_1==P_IMMEDIATE || mode_1==P_DESCRIPTOR_NUMBER)) - { - LONG i; + } else if (mode_1==P_DESCRIPTOR_NUMBER && ! (mode_2==P_IMMEDIATE || mode_2==P_DESCRIPTOR_NUMBER)){ + instruction_d_ad (ICMP,ad_1.ad_label,ad_1.ad_offset,&ad_2); + return i_test_1; + } else if (mode_2==P_IMMEDIATE && ! (mode_1==P_IMMEDIATE || mode_1==P_DESCRIPTOR_NUMBER)){ + LONG i; #ifdef M68000 - int real_dreg_number; + int real_dreg_number; #endif - - i=ad_2.ad_offset; + + i=ad_2.ad_offset; #ifdef M68000 - if (i<128 && i>=-128 && i!=0 && (real_dreg_number=try_get_real_dregister_number())>=0){ - int dreg; - - dreg=num_to_d_reg (real_dreg_number); - i_move_i_r (i,dreg); - instruction_ad_r (ICMP,&ad_1,dreg); - free_dregister (dreg); - return i_test_1; - } else { + if (i<128 && i>=-128 && i!=0 && (real_dreg_number=try_get_real_dregister_number())>=0){ + int dreg; + + dreg=num_to_d_reg (real_dreg_number); + i_move_i_r (i,dreg); + instruction_ad_r (ICMP,&ad_1,dreg); + free_dregister (dreg); + return i_test_1; + } else { #endif - instruction_i_ad (ICMP,i,&ad_1); - return i_test_2; + instruction_i_ad (ICMP,i,&ad_1); + return i_test_2; #ifdef M68000 - } -#endif - } else if (mode_2==P_DESCRIPTOR_NUMBER - && ! (mode_1==P_IMMEDIATE || mode_1==P_DESCRIPTOR_NUMBER)){ - instruction_d_ad (ICMP,ad_2.ad_label,ad_2.ad_offset,&ad_1); - return i_test_2; - } else if (mode_2==P_REGISTER - || (mode_1!=P_REGISTER && mode_2==P_INDIRECT && *ad_2.ad_count_p==1)){ - in_register (&ad_2); - instruction_ad_r (ICMP,&ad_1,ad_2.ad_register); - if (--*ad_2.ad_count_p==0) - free_register (ad_2.ad_register); - return i_test_1; - } else { - in_register (&ad_1); - instruction_ad_r (ICMP,&ad_2,ad_1.ad_register); - if (--*ad_1.ad_count_p==0) - free_register (ad_1.ad_register); - return i_test_2; - } } +#endif + } else if (mode_2==P_DESCRIPTOR_NUMBER + && ! (mode_1==P_IMMEDIATE || mode_1==P_DESCRIPTOR_NUMBER)){ + instruction_d_ad (ICMP,ad_2.ad_label,ad_2.ad_offset,&ad_1); + return i_test_2; + } else if (mode_2==P_REGISTER + || (mode_1!=P_REGISTER && mode_2==P_INDIRECT && *ad_2.ad_count_p==1)){ + in_register (&ad_2); + instruction_ad_r (ICMP,&ad_1,ad_2.ad_register); + if (--*ad_2.ad_count_p==0) + free_register (ad_2.ad_register); + return i_test_1; + } else { + in_register (&ad_1); + instruction_ad_r (ICMP,&ad_2,ad_1.ad_register); + if (--*ad_1.ad_count_p==0) + free_register (ad_1.ad_register); + return i_test_2; + } } enum { @@ -3370,14 +3377,22 @@ static int condition_to_branch_false_instruction[]= { IBNE, IBEQ, IBLE, IBGE, IBLT, IBGT, IBNO, IBO, IBLEU, IBGEU, IBLTU, IBGTU, +#if defined (I486) && !defined (G_A64) + IFCNE, IFCEQ, IFCLE, IFCGE, IFCLT, IFCGT +#else IFBNE, IFBEQ, IFBLE, IFBGE, IFBLT, IFBGT +#endif }; static int condition_to_branch_true_instruction[]= { IBEQ, IBNE, IBGT, IBLT, IBGE, IBLE, IBO, IBNO, IBGTU, IBLTU, IBGEU, IBLEU, +#if defined (I486) && !defined (G_A64) + IFCEQ, IFCNE, IFCGT, IFCLT, IFCGE, IFCLE +#else IFBEQ, IFBNE, IFBGT, IFBLT, IFBGE, IFBLE +#endif }; static void save_condition (INSTRUCTION_GRAPH graph,int condition) @@ -3988,7 +4003,11 @@ static void linearize_two_results_operator (INSTRUCTION_GRAPH result_graph,ADDRE } #endif +#ifndef I486 static void linearize_shift_operator (int i_instruction_code,INSTRUCTION_GRAPH graph,ADDRESS *ad_p) +#else +static void linearize_shift_operator (int i_instruction_code,int i_instruction_code_s,INSTRUCTION_GRAPH graph,ADDRESS *ad_p) +#endif { INSTRUCTION_GRAPH graph_1,graph_2; ADDRESS ad_1,ad_2; @@ -4025,10 +4044,26 @@ static void linearize_shift_operator (int i_instruction_code,INSTRUCTION_GRAPH g #ifdef M68000 if (ad_1.ad_mode!=P_IMMEDIATE || ad_1.ad_offset<=0 || ad_1.ad_offset>8) #else +# ifndef G_A64 if (ad_1.ad_mode!=P_IMMEDIATE || ad_1.ad_offset<0 || ad_1.ad_offset>=32) +# else + if (ad_1.ad_mode!=P_IMMEDIATE || ad_1.ad_offset<0 || ad_1.ad_offset>=64) +# endif #endif in_data_register (&ad_1); +#ifdef I486 + if (ad_1.ad_mode!=P_IMMEDIATE){ + int tmp_reg; + + if (try_allocate_register_number (REGISTER_A0)) + tmp_reg=REGISTER_A0; + else + tmp_reg=get_dregister(); + instruction_ad_r_r (i_instruction_code_s,&ad_1,ad_2.ad_register,tmp_reg); + free_register (tmp_reg); + } else +#endif instruction_ad_r (i_instruction_code,&ad_1,ad_2.ad_register); --*ad_2.ad_count_p; @@ -4375,10 +4410,6 @@ void evaluate_arguments_and_free_addresses (union instruction_parameter argument memory_free (ad_a); } -#if defined (FP_STACK_OPTIMIZATIONS) || defined (FMADD) -#define FP_REG_LAST_USE 4 -#endif - static void move_float_ad_id (ADDRESS *ad_p,int offset,int areg) { switch (ad_p->ad_mode){ @@ -5671,7 +5702,7 @@ static void instruction_ad_fr (int instruction_code,ADDRESS *ad_p,int register_1 instruction=i_new_instruction2 (instruction_code); parameter_p=&instruction->instruction_parameters[0]; - + switch (ad_p->ad_mode){ case P_F_REGISTER: set_float_register_parameter (*parameter_p,ad_p->ad_register); @@ -6451,7 +6482,7 @@ static void linearize_dyadic_commutative_float_operator (int instruction_code,re #if defined (FMADD) parameter1.parameter_flags=0; #endif - free_f_register=fad_to_parameter (&ad_1,¶meter1); + free_f_register=fad_to_parameter_without_freeing_fregister (&ad_1,¶meter1); in_alterable_float_register (&ad_2); if (free_f_register){ #if defined (FP_STACK_OPTIMIZATIONS) || defined (FMADD) @@ -6492,7 +6523,6 @@ static void linearize_dyadic_non_commutative_float_operator (int instruction_cod #if 1 # if (defined (I486) && !defined (G_AI64)) || defined (G_POWER) - /* added 15-12-1998 */ if (ad_1.ad_mode==P_F_REGISTER && *ad_1.ad_count_p==1 && !(ad_2.ad_mode==P_F_REGISTER && ad_2.ad_register<ad_1.ad_register && *ad_2.ad_count_p==1) ){ @@ -6511,7 +6541,7 @@ static void linearize_dyadic_non_commutative_float_operator (int instruction_cod parameter1.parameter_flags=0; # endif - free_f_register=fad_to_parameter (&ad_1,¶meter1); + free_f_register=fad_to_parameter_without_freeing_fregister (&ad_1,¶meter1); in_alterable_float_register (&ad_2); if (free_f_register){ #if defined (FP_STACK_OPTIMIZATIONS) || defined (FMADD) @@ -7920,9 +7950,28 @@ static void linearize_exit_if_operator (INSTRUCTION_GRAPH graph,ADDRESS *ad_p) graph_2=graph->instruction_parameters[2].p; condition=linearize_condition (graph_1); + +#if defined (I486) && !defined (G_A64) + if (is_float_condition (condition)){ + int convert_instruction_code,branch_instruction_code,tmp_reg; - instruction_l (condition_to_branch_false_instruction[condition],graph->instruction_parameters[0].l); + if (try_allocate_register_number (REGISTER_D0)) + tmp_reg=REGISTER_D0; + else + tmp_reg=get_dregister(); + + convert_instruction_code=condition_to_branch_false_instruction[condition]; + instruction_r (convert_instruction_code,tmp_reg); + + free_register (tmp_reg); + branch_instruction_code=convert_instruction_code==IFCNE ? IBNE : + convert_instruction_code==IFCLE ? IBLT : IBEQ; + instruction_l (branch_instruction_code,graph->instruction_parameters[0].l); + } else +#endif + instruction_l (condition_to_branch_false_instruction[condition],graph->instruction_parameters[0].l); + linearize_graph (graph_2,ad_p); if (graph->node_count>1){ @@ -8394,13 +8443,25 @@ static void linearize_graph (INSTRUCTION_GRAPH graph,ADDRESS *ad_p) linearize_conditional_not_operator (graph,ad_p); return; case GLSR: +#ifndef I486 linearize_shift_operator (ILSR,graph,ad_p); +#else + linearize_shift_operator (ILSR,ILSR_S,graph,ad_p); +#endif return; case GLSL: +#ifndef I486 linearize_shift_operator (ILSL,graph,ad_p); +#else + linearize_shift_operator (ILSL,ILSL_S,graph,ad_p); +#endif return; case GASR: +#ifndef I486 linearize_shift_operator (IASR,graph,ad_p); +#else + linearize_shift_operator (IASR,IASR_S,graph,ad_p); +#endif return; case GCREATE: linearize_create_operator (graph,ad_p,0); @@ -8619,6 +8680,30 @@ void calculate_and_linearize_branch_false (LABEL *label,INSTRUCTION_GRAPH graph) calculate_graph_register_uses (graph); condition=linearize_condition (graph); +#if defined (I486) && !defined (G_A64) + if (is_float_condition (condition)){ + int convert_instruction_code,branch_instruction_code,tmp_reg; + + if (try_allocate_register_number (REGISTER_D0)) + tmp_reg=REGISTER_D0; + else + tmp_reg=get_dregister(); + + convert_instruction_code=condition_to_branch_false_instruction[condition]; + instruction_r (convert_instruction_code,tmp_reg); + + free_register (tmp_reg); + + adjust_stack_pointers_without_altering_condition_codes (1,condition); + + branch_instruction_code=convert_instruction_code==IFCNE ? IBNE : + convert_instruction_code==IFCLE ? IBLT : IBEQ; + instruction_l (branch_instruction_code,label); + + return; + } +#endif + condition_on_stack=adjust_stack_pointers_without_altering_condition_codes (is_float_condition (condition),condition); #ifdef M68000 @@ -8627,7 +8712,7 @@ void calculate_and_linearize_branch_false (LABEL *label,INSTRUCTION_GRAPH graph) instruction_l (IBEQ,label); } else #endif - instruction_l (condition_to_branch_false_instruction[condition],label); + instruction_l (condition_to_branch_false_instruction[condition],label); } void calculate_and_linearize_branch_true (LABEL *label,INSTRUCTION_GRAPH graph) @@ -8637,6 +8722,30 @@ void calculate_and_linearize_branch_true (LABEL *label,INSTRUCTION_GRAPH graph) calculate_graph_register_uses (graph); condition=linearize_condition (graph); +#if defined (I486) && !defined (G_A64) + if (is_float_condition (condition)){ + int convert_instruction_code,branch_instruction_code,tmp_reg; + + if (try_allocate_register_number (REGISTER_D0)) + tmp_reg=REGISTER_D0; + else + tmp_reg=get_dregister(); + + convert_instruction_code=condition_to_branch_true_instruction[condition]; + instruction_r (convert_instruction_code,tmp_reg); + + free_register (tmp_reg); + + adjust_stack_pointers_without_altering_condition_codes (1,condition); + + branch_instruction_code=convert_instruction_code==IFCNE ? IBNE : + convert_instruction_code==IFCLE ? IBLT : IBEQ; + instruction_l (branch_instruction_code,label); + + return; + } +#endif + condition_on_stack=adjust_stack_pointers_without_altering_condition_codes (is_float_condition (condition),condition); #ifdef M68000 @@ -72,12 +72,14 @@ static void optimize_branch_jump (struct instruction *branch,LABEL *new_branch_l case IBGTU: branch->instruction_icode=IBLEU; break; case IBLEU: branch->instruction_icode=IBGTU; break; case IBLTU: branch->instruction_icode=IBGEU; break; +#if !defined (I486_USE_SCRATCH_REGISTER) || defined (G_A64) case IFBEQ: branch->instruction_icode=IFBNE; break; case IFBGE: branch->instruction_icode=IFBLT; break; case IFBGT: branch->instruction_icode=IFBLE; break; case IFBLE: branch->instruction_icode=IFBGT; break; case IFBLT: branch->instruction_icode=IFBGE; break; case IFBNE: branch->instruction_icode=IFBEQ; +#endif } } @@ -114,7 +116,9 @@ void optimize_jumps (void) switch (branch->instruction_icode){ case IBEQ: case IBGE: case IBGT: case IBLE: case IBLT: case IBNE: case IBGEU: case IBGTU: case IBLEU: case IBLTU: +#if !defined (I486_USE_SCRATCH_REGISTER) || defined (G_A64) case IFBEQ: case IFBGE: case IFBGT: case IFBLE: case IFBLT: case IFBNE: +#endif { struct basic_block *next_block; @@ -671,6 +675,9 @@ static void compute_maximum_b_stack_offsets (register int b_offset) instruction->instruction_icode!=IREMI && instruction->instruction_icode!=IREMU && instruction->instruction_icode!=IDIVDU && + instruction->instruction_icode!=IASR_S && + instruction->instruction_icode!=ILSL_S && + instruction->instruction_icode!=ILSR_S && #endif instruction->instruction_icode!=IMOD) #ifdef M68000 @@ -906,6 +913,9 @@ void optimize_stack_access (struct basic_block *block,int *a_offset_p,int *b_off instruction->instruction_icode!=IREMI && instruction->instruction_icode!=IREMU && instruction->instruction_icode!=IDIVDU && + instruction->instruction_icode!=IASR_S && + instruction->instruction_icode!=ILSL_S && + instruction->instruction_icode!=ILSR_S && instruction->instruction_icode!=IMOD) internal_error_in_function ("optimize_stack_access"); /* only first argument of mod might be register indirect */ @@ -1520,7 +1530,6 @@ static void store_next_uses (struct instruction *instruction) #ifndef I486_USE_SCRATCH_REGISTER case IASR: case ILSL: case ILSR: case IDIV: - case ICMPW: #endif #if defined (I486) && !defined (I486_USE_SCRATCH_REGISTER) case IMULUD: @@ -1541,6 +1550,9 @@ IF_G_POWER ( case IUMULH: ) #ifdef I486 case IADC: case ISBB: #endif +#ifdef M68000 + case ICMPW: +#endif use_parameter (&instruction->instruction_parameters[1]); use_parameter (&instruction->instruction_parameters[0]); break; @@ -1551,13 +1563,6 @@ IF_G_POWER ( case IUMULH: ) use_parameter (&instruction->instruction_parameters[1]); use_parameter (&instruction->instruction_parameters[0]); break; - case ICMPW: - if (instruction->instruction_parameters[0].parameter_type==P_INDIRECT || - instruction->instruction_parameters[1].parameter_type==P_INDIRECT) - define_scratch_register(); - use_parameter (&instruction->instruction_parameters[1]); - use_parameter (&instruction->instruction_parameters[0]); - break; case IDIV: case IMOD: case IDIVU: case IREMU: case IMULUD: define_scratch_register(); use_parameter (&instruction->instruction_parameters[1]); @@ -1615,11 +1620,11 @@ IF_G_RISC (case IADDI: case ILSLI:) /* case IJMP: case IJSR: */ use_parameter (&instruction->instruction_parameters[0]); break; - case IFSEQ: case IFSGE: case IFSGT: case IFSLE: case IFSLT: case IFSNE: case ISEQ: case ISGE: case ISGT: case ISLE: case ISLT: case ISNE: case ISO: case ISGEU: case ISGTU: case ISLEU: case ISLTU: case ISNO: -#ifdef I486_USE_SCRATCH_REGISTER - define_scratch_register(); + case IFSEQ: case IFSGE: case IFSGT: case IFSLE: case IFSLT: case IFSNE: +#if defined (I486) && !defined (G_A64) + case IFCEQ: case IFCGE: case IFCGT: case IFCLE: case IFCLT: case IFCNE: #endif define_parameter (&instruction->instruction_parameters[0]); break; @@ -1639,6 +1644,13 @@ IF_G_RISC (case IADDI: case ILSLI:) break; # endif #endif +#ifdef I486 + case IASR_S: case ILSL_S: case ILSR_S: + define_parameter (&instruction->instruction_parameters[2]); + use_parameter (&instruction->instruction_parameters[1]); + use_parameter (&instruction->instruction_parameters[0]); + break; +#endif #ifdef M68000 case IMOVEM: { @@ -1666,13 +1678,12 @@ IF_G_RISC (case IADDI: case ILSLI:) use_parameter (&instruction->instruction_parameters[0]); break; #endif -#ifdef I486_USE_SCRATCH_REGISTER +#if 0 case IFBEQ: case IFBGE: case IFBGT: case IFBLE: case IFBLT: case IFBNE: define_scratch_register(); break; #endif /* - case IFBEQ: case IFBGE: case IFBGT: case IFBLE: case IFBLT: case IFBNE: case IRTS: break; */ @@ -3065,7 +3076,7 @@ static void use_3_same_type_registers int reg_n_1,reg_n_2,reg_n_3,real_reg_n_1,real_reg_n_2,real_reg_n_3,instruction_n; struct register_use *reg_uses; struct register_allocation *reg_alloc; - + reg_n_1=reg_p_1->r; reg_n_2=reg_p_2->r; reg_n_3=reg_p_3->r; @@ -3855,20 +3866,13 @@ IF_G_POWER ( case IUMULH: ) break; #endif case ICMP: -#ifndef I486_USE_SCRATCH_REGISTER +#ifdef M68000 case ICMPW: #endif IF_G_POWER (case ICMPLW:) instruction_use_2 (instruction,USE); break; #ifdef I486_USE_SCRATCH_REGISTER - case ICMPW: - if (instruction->instruction_parameters[0].parameter_type==P_INDIRECT || - instruction->instruction_parameters[1].parameter_type==P_INDIRECT) - use_scratch_register(); - instruction_use_2 (instruction,USE); - allocate_scratch_register=1; - break; case IMOVE: if ((instruction->instruction_parameters[0].parameter_type==P_INDIRECT || instruction->instruction_parameters[0].parameter_type==P_INDEXED) && @@ -3925,28 +3929,17 @@ IF_G_RISC (case IADDI: case ILSLI:) #endif instruction_usedef (instruction); break; - case IFSEQ: case IFSGE: case IFSGT: case IFSLE: case IFSLT: case IFSNE: - { -#ifdef I486_USE_SCRATCH_REGISTER - use_scratch_register(); -#endif - instruction_def (instruction); -#ifdef I486_USE_SCRATCH_REGISTER - allocate_scratch_register=1; -#endif - break; - } case ISEQ: case ISGE: case ISGT: case ISLE: case ISLT: case ISNE: case ISO: case ISGEU: case ISGTU: case ISLEU: case ISLTU: case ISNO: -#ifdef I486_USE_SCRATCH_REGISTER - use_scratch_register(); -#endif do_not_alter_condition_codes=1; instruction_def (instruction); do_not_alter_condition_codes=0; -#ifdef I486_USE_SCRATCH_REGISTER - allocate_scratch_register=1; + break; + case IFSEQ: case IFSGE: case IFSGT: case IFSLE: case IFSLT: case IFSNE: +#if defined (I486) && !defined (G_A64) + case IFCEQ: case IFCGE: case IFCGT: case IFCLE: case IFCLT: case IFCNE: #endif + instruction_def (instruction); break; case IEXG: instruction_usedef_usedef (instruction); @@ -3967,6 +3960,15 @@ IF_G_RISC (case IADDI: case ILSLI:) instruction_fexg_usedef_usedef (instruction); break; #endif + +#ifdef I486 + case IASR_S: case ILSL_S: case ILSR_S: + 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,DEF,D_REGISTER); + break; +#endif #ifndef I486_USE_SCRATCH_REGISTER case IMOD: # if defined (I486) || defined (G_POWER) @@ -4014,14 +4016,13 @@ IF_G_RISC (case IADDI: case ILSLI:) # endif break; #endif -#ifdef I486_USE_SCRATCH_REGISTER +#if 0 case IFBEQ: case IFBGE: case IFBGT: case IFBLE: case IFBLT: case IFBNE: use_scratch_register(); allocate_scratch_register=1; break; #endif /* - case IFBEQ: case IFBGE: case IFBGT: case IFBLE: case IFBLT: case IFBNE: case IRTS: case IJMP: case IJSR: break; */ @@ -1093,7 +1093,7 @@ static void as_subo_instruction (struct instruction *instruction) instruction->instruction_parameters[1].parameter_data.reg.r,reg); } -static void as_cmp_instruction (struct instruction *instruction,int size_flag) +static void as_cmp_instruction (struct instruction *instruction) { struct parameter parameter_0,parameter_1; @@ -1101,18 +1101,12 @@ static void as_cmp_instruction (struct instruction *instruction,int size_flag) parameter_1=instruction->instruction_parameters[1]; if (parameter_1.parameter_type==P_INDIRECT){ - if (size_flag==SIZE_LONG) - as_lwz (REGISTER_O1,parameter_1.parameter_offset,parameter_1.parameter_data.reg.r); - else - as_lha (REGISTER_O1,parameter_1.parameter_offset,parameter_1.parameter_data.reg.r); + as_lwz (REGISTER_O1,parameter_1.parameter_offset,parameter_1.parameter_data.reg.r); parameter_1.parameter_type=P_REGISTER; parameter_1.parameter_data.reg.r=REGISTER_O1; } else if (parameter_1.parameter_type==P_INDEXED){ - if (size_flag==SIZE_LONG) - as_lwzx (REGISTER_O1,parameter_1.parameter_data.ir->a_reg.r,parameter_1.parameter_data.ir->d_reg.r); - else - as_lhax (REGISTER_O1,parameter_1.parameter_data.ir->a_reg.r,parameter_1.parameter_data.ir->d_reg.r); + as_lwzx (REGISTER_O1,parameter_1.parameter_data.ir->a_reg.r,parameter_1.parameter_data.ir->d_reg.r); parameter_1.parameter_type=P_REGISTER; parameter_1.parameter_data.reg.r=REGISTER_O1; @@ -1146,31 +1140,80 @@ static void as_cmp_instruction (struct instruction *instruction,int size_flag) break; } case P_INDIRECT: - switch (size_flag){ - case SIZE_WORD: - as_lha (REGISTER_O0,parameter_0.parameter_offset,parameter_0.parameter_data.reg.r); - break; - case SIZE_LONG: - as_lwz (REGISTER_O0,parameter_0.parameter_offset,parameter_0.parameter_data.reg.r); - break; - default: - internal_error_in_function ("as_cmp_instruction"); - } + as_lwz (REGISTER_O0,parameter_0.parameter_offset,parameter_0.parameter_data.reg.r); parameter_0.parameter_type=P_REGISTER; parameter_0.parameter_data.reg.r=REGISTER_O0; break; case P_INDEXED: - switch (size_flag){ - case SIZE_WORD: - as_lhax (REGISTER_O0,parameter_0.parameter_data.ir->a_reg.r,parameter_0.parameter_data.ir->d_reg.r); - break; - case SIZE_LONG: - as_lwzx (REGISTER_O0,parameter_0.parameter_data.ir->a_reg.r,parameter_0.parameter_data.ir->d_reg.r); - break; - default: - internal_error_in_function ("as_cmp_instruction"); + as_lwzx (REGISTER_O0,parameter_0.parameter_data.ir->a_reg.r,parameter_0.parameter_data.ir->d_reg.r); + + parameter_0.parameter_type=P_REGISTER; + parameter_0.parameter_data.reg.r=REGISTER_O0; + break; + } + + if (parameter_0.parameter_type==P_IMMEDIATE){ + as_cmpi (parameter_1.parameter_data.reg.r,parameter_0.parameter_data.i); + } else + as_cmp (parameter_1.parameter_data.reg.r,parameter_0.parameter_data.reg.r); +} + +#if 0 +static void as_cmpw_instruction (struct instruction *instruction) +{ + struct parameter parameter_0,parameter_1; + + parameter_0=instruction->instruction_parameters[0]; + parameter_1=instruction->instruction_parameters[1]; + + if (parameter_1.parameter_type==P_INDIRECT){ + as_lha (REGISTER_O1,parameter_1.parameter_offset,parameter_1.parameter_data.reg.r); + + parameter_1.parameter_type=P_REGISTER; + parameter_1.parameter_data.reg.r=REGISTER_O1; + } else if (parameter_1.parameter_type==P_INDEXED){ + as_lhax (REGISTER_O1,parameter_1.parameter_data.ir->a_reg.r,parameter_1.parameter_data.ir->d_reg.r); + + parameter_1.parameter_type=P_REGISTER; + parameter_1.parameter_data.reg.r=REGISTER_O1; + } + + switch (parameter_0.parameter_type){ + case P_DESCRIPTOR_NUMBER: + as_load_descriptor (¶meter_0,REGISTER_O0); + + parameter_0.parameter_type=P_REGISTER; + parameter_0.parameter_data.reg.r=REGISTER_O0; + break; + case P_REGISTER: + break; + case P_IMMEDIATE: + { + int i; + + i=parameter_0.parameter_data.i; + + if (i!=(WORD)i){ + as_lis (REGISTER_O0,(i-(WORD)i)>>16); + + i=(WORD)i; + + as_addi (REGISTER_O0,REGISTER_O0,i); + + parameter_0.parameter_type=P_REGISTER; + parameter_0.parameter_data.reg.r=REGISTER_O0; } + break; + } + case P_INDIRECT: + as_lha (REGISTER_O0,parameter_0.parameter_offset,parameter_0.parameter_data.reg.r); + + parameter_0.parameter_type=P_REGISTER; + parameter_0.parameter_data.reg.r=REGISTER_O0; + break; + case P_INDEXED: + as_lhax (REGISTER_O0,parameter_0.parameter_data.ir->a_reg.r,parameter_0.parameter_data.ir->d_reg.r); parameter_0.parameter_type=P_REGISTER; parameter_0.parameter_data.reg.r=REGISTER_O0; @@ -1182,6 +1225,7 @@ static void as_cmp_instruction (struct instruction *instruction,int size_flag) } else as_cmp (parameter_1.parameter_data.reg.r,parameter_0.parameter_data.reg.r); } +#endif static void as_cmplw_instruction (struct instruction *instruction) { @@ -2742,7 +2786,7 @@ static void write_instructions (struct instruction *instructions) as_sub_instruction (instruction); break; case ICMP: - as_cmp_instruction (instruction,SIZE_LONG); + as_cmp_instruction (instruction); break; case IJMP: as_jmp_instruction (instruction); @@ -2855,9 +2899,11 @@ static void write_instructions (struct instruction *instructions) case ISO: as_seto_condition_instruction (instruction); break; +#if 0 case ICMPW: - as_cmp_instruction (instruction,SIZE_WORD); + as_cmpw_instruction (instruction); break; +#endif case ITST: as_tst_instruction (instruction); break; @@ -1215,7 +1215,7 @@ static void w_as_subo_instruction (struct instruction *instruction) w_as_newline(); } -static void w_as_cmp_instruction (struct instruction *instruction,int size_flag) +static void w_as_cmp_instruction (struct instruction *instruction) { struct parameter parameter_0,parameter_1; @@ -1224,9 +1224,9 @@ static void w_as_cmp_instruction (struct instruction *instruction,int size_flag) if (parameter_1.parameter_type==P_INDIRECT || parameter_1.parameter_type==P_INDEXED){ if (parameter_1.parameter_type==P_INDIRECT) - w_as_opcode (size_flag==SIZE_LONG ? "lwz" : "lha"); + w_as_opcode ("lwz"); else - w_as_opcode (size_flag==SIZE_LONG ? "lwzx" : "lhax"); + w_as_opcode ("lwzx"); w_as_register_comma (REGISTER_O1); w_as_parameter (¶meter_1); @@ -1271,16 +1271,7 @@ static void w_as_cmp_instruction (struct instruction *instruction,int size_flag) break; } case P_INDIRECT: - switch (size_flag){ - case SIZE_WORD: - w_as_opcode ("lha"); - break; - case SIZE_LONG: - w_as_opcode ("lwz"); - break; - default: - internal_error_in_function ("w_as_cmp_instruction"); - } + w_as_opcode ("lwz"); w_as_register_comma (REGISTER_O0); w_as_parameter (¶meter_0); w_as_newline(); @@ -1289,16 +1280,92 @@ static void w_as_cmp_instruction (struct instruction *instruction,int size_flag) parameter_0.parameter_data.reg.r=REGISTER_O0; break; case P_INDEXED: - switch (size_flag){ - case SIZE_WORD: - w_as_opcode ("lhax"); - break; - case SIZE_LONG: - w_as_opcode ("lwzx"); - break; - default: - internal_error_in_function ("w_as_cmp_instruction"); + w_as_opcode ("lwzx"); + w_as_register_comma (REGISTER_O0); + w_as_parameter (¶meter_0); + w_as_newline(); + + parameter_0.parameter_type=P_REGISTER; + parameter_0.parameter_data.reg.r=REGISTER_O0; + break; + } + + w_as_opcode (parameter_0.parameter_type==P_IMMEDIATE ? "cmpwi" : "cmpw"); + w_as_immediate (0); + w_as_comma(); + w_as_parameter (¶meter_1); + w_as_comma(); + w_as_parameter (¶meter_0); + w_as_newline(); +} + +#if 0 +static void w_as_cmpw_instruction (struct instruction *instruction) +{ + struct parameter parameter_0,parameter_1; + + parameter_0=instruction->instruction_parameters[0]; + parameter_1=instruction->instruction_parameters[1]; + + if (parameter_1.parameter_type==P_INDIRECT || parameter_1.parameter_type==P_INDEXED){ + if (parameter_1.parameter_type==P_INDIRECT) + w_as_opcode ("lha"); + else + w_as_opcode ("lhax"); + + w_as_register_comma (REGISTER_O1); + w_as_parameter (¶meter_1); + w_as_newline(); + + parameter_1.parameter_type=P_REGISTER; + parameter_1.parameter_data.reg.r=REGISTER_O1; + } + + switch (parameter_0.parameter_type){ + case P_DESCRIPTOR_NUMBER: + w_as_load_descriptor (¶meter_0,REGISTER_O0); + + parameter_0.parameter_type=P_REGISTER; + parameter_0.parameter_data.reg.r=REGISTER_O0; + break; + case P_REGISTER: + break; + case P_IMMEDIATE: + { + int i; + + i=parameter_0.parameter_data.i; + + if (i!=(WORD)i){ + w_as_opcode ("lis"); + w_as_register_comma (REGISTER_O0); + w_as_immediate ((i-(WORD)i)>>16); + w_as_newline(); + + i=(WORD)i; + + w_as_opcode ("addi"); + w_as_register_comma (REGISTER_O0); + w_as_register_comma (REGISTER_O0); + w_as_immediate (i); + w_as_newline(); + + parameter_0.parameter_type=P_REGISTER; + parameter_0.parameter_data.reg.r=REGISTER_O0; } + break; + } + case P_INDIRECT: + w_as_opcode ("lha"); + w_as_register_comma (REGISTER_O0); + w_as_parameter (¶meter_0); + w_as_newline(); + + parameter_0.parameter_type=P_REGISTER; + parameter_0.parameter_data.reg.r=REGISTER_O0; + break; + case P_INDEXED: + w_as_opcode ("lhax"); w_as_register_comma (REGISTER_O0); w_as_parameter (¶meter_0); w_as_newline(); @@ -1316,6 +1383,7 @@ static void w_as_cmp_instruction (struct instruction *instruction,int size_flag) w_as_parameter (¶meter_0); w_as_newline(); } +#endif static void w_as_cmplw_instruction (struct instruction *instruction) { @@ -3092,7 +3160,7 @@ static void w_as_instructions (register struct instruction *instruction) w_as_sub_instruction (instruction); break; case ICMP: - w_as_cmp_instruction (instruction,SIZE_LONG); + w_as_cmp_instruction (instruction); break; case IJMP: w_as_jmp_instruction (instruction); @@ -3193,9 +3261,11 @@ static void w_as_instructions (register struct instruction *instruction) case ISO: w_as_seto_condition_instruction (instruction); break; +#if 0 case ICMPW: - w_as_cmp_instruction (instruction,SIZE_WORD); + w_as_cmpw_instruction (instruction); break; +#endif case ITST: w_as_tst_instruction (instruction); break; @@ -1022,7 +1022,7 @@ static void as_sub_o_instruction (struct instruction *instruction) } } -static void as_cmp_instruction (struct instruction *instruction,int size_flag) +static void as_cmp_instruction (struct instruction *instruction) { struct parameter parameter_0,parameter_1; @@ -1030,10 +1030,7 @@ static void as_cmp_instruction (struct instruction *instruction,int size_flag) parameter_1=instruction->instruction_parameters[1]; if (parameter_1.parameter_type==P_INDIRECT){ - if (size_flag==SIZE_LONG) - as_ld (parameter_1.parameter_offset,parameter_1.parameter_data.reg.r,REGISTER_O1); - else - as_ldsh (parameter_1.parameter_offset,parameter_1.parameter_data.reg.r,REGISTER_O1); + as_ld (parameter_1.parameter_offset,parameter_1.parameter_data.reg.r,REGISTER_O1); parameter_1.parameter_type=P_REGISTER; parameter_1.parameter_data.reg.r=REGISTER_O1; @@ -1041,10 +1038,7 @@ static void as_cmp_instruction (struct instruction *instruction,int size_flag) if (parameter_1.parameter_offset!=0) internal_error_in_function ("as_cmp_instruction"); - if (size_flag==SIZE_LONG) - as_ld_x (parameter_1.parameter_data.ir->a_reg.r,parameter_1.parameter_data.ir->d_reg.r,REGISTER_O1); - else - as_ldsh_x (parameter_1.parameter_data.ir->a_reg.r,parameter_1.parameter_data.ir->d_reg.r,REGISTER_O1); + as_ld_x (parameter_1.parameter_data.ir->a_reg.r,parameter_1.parameter_data.ir->d_reg.r,REGISTER_O1); parameter_1.parameter_type=P_REGISTER; parameter_1.parameter_data.reg.r=REGISTER_O1; @@ -1075,16 +1069,64 @@ static void as_cmp_instruction (struct instruction *instruction,int size_flag) case P_REGISTER: break; default: - switch (size_flag){ - case SIZE_WORD: - as_ldsh_parameter (¶meter_0,REGISTER_O0); - break; - case SIZE_LONG: - as_ld_parameter (¶meter_0,REGISTER_O0); - break; - default: - internal_error_in_function ("as_cmp_instruction"); + as_ld_parameter (¶meter_0,REGISTER_O0); + + parameter_0.parameter_type=P_REGISTER; + parameter_0.parameter_data.reg.r=REGISTER_O0; + } + + as_cmp (parameter_1.parameter_data.reg.r,parameter_0.parameter_data.reg.r); +} + +#if 0 +static void as_cmpw_instruction (struct instruction *instruction) +{ + struct parameter parameter_0,parameter_1; + + parameter_0=instruction->instruction_parameters[0]; + parameter_1=instruction->instruction_parameters[1]; + + if (parameter_1.parameter_type==P_INDIRECT){ + as_ldsh (parameter_1.parameter_offset,parameter_1.parameter_data.reg.r,REGISTER_O1); + + parameter_1.parameter_type=P_REGISTER; + parameter_1.parameter_data.reg.r=REGISTER_O1; + } else if (parameter_1.parameter_type==P_INDEXED){ + if (parameter_1.parameter_offset!=0) + internal_error_in_function ("as_cmpw_instruction"); + + as_ldsh_x (parameter_1.parameter_data.ir->a_reg.r,parameter_1.parameter_data.ir->d_reg.r,REGISTER_O1); + + parameter_1.parameter_type=P_REGISTER; + parameter_1.parameter_data.reg.r=REGISTER_O1; + } + + switch (parameter_0.parameter_type){ + case P_DESCRIPTOR_NUMBER: + as_sethi (0,REGISTER_O0); + as_hi_or_lo_label (parameter_0.parameter_data.l,2+(parameter_0.parameter_offset<<3),HI22_RELOCATION); + + as_ori (REGISTER_O0,0,REGISTER_O0); + as_hi_or_lo_label (parameter_0.parameter_data.l,2+(parameter_0.parameter_offset<<3),LO12_RELOCATION); + + parameter_0.parameter_type=P_REGISTER; + parameter_0.parameter_data.reg.r=REGISTER_O0; + break; + case P_IMMEDIATE: + if ((unsigned)(parameter_0.parameter_data.i+4096)>=(unsigned)8192){ + as_set (parameter_0.parameter_data.i,REGISTER_O0); + + parameter_0.parameter_type=P_REGISTER; + parameter_0.parameter_data.reg.r=REGISTER_O0; + } else { + as_cmpi (parameter_1.parameter_data.reg.r,parameter_0.parameter_data.i); + return; } + break; + case P_REGISTER: + break; + default: + as_ldsh_parameter (¶meter_0,REGISTER_O0); parameter_0.parameter_type=P_REGISTER; parameter_0.parameter_data.reg.r=REGISTER_O0; @@ -1092,6 +1134,7 @@ static void as_cmp_instruction (struct instruction *instruction,int size_flag) as_cmp (parameter_1.parameter_data.reg.r,parameter_0.parameter_data.reg.r); } +#endif static void as_tst_instruction (struct instruction *instruction,int size_flag) { @@ -1722,7 +1765,7 @@ static void as_instructions (register struct instruction *instruction) as_sub_instruction (instruction); break; case ICMP: - as_cmp_instruction (instruction,SIZE_LONG); + as_cmp_instruction (instruction); break; case IJMP: as_jmp_instruction (instruction); @@ -1814,9 +1857,11 @@ static void as_instructions (register struct instruction *instruction) case ISO: as_set_condition_instruction (instruction,VS_COND); break; +#if 0 case ICMPW: - as_cmp_instruction (instruction,SIZE_WORD); + as_cmpw_instruction (instruction); break; +#endif case ITST: as_tst_instruction (instruction,SIZE_LONG); break; @@ -970,7 +970,7 @@ static void w_as_sub_o_instruction (struct instruction *instruction) } } -static void w_as_cmp_instruction (struct instruction *instruction,int size_flag) +static void w_as_cmp_instruction (struct instruction *instruction) { struct parameter parameter_0,parameter_1; @@ -978,7 +978,7 @@ static void w_as_cmp_instruction (struct instruction *instruction,int size_flag) parameter_1=instruction->instruction_parameters[1]; if (parameter_1.parameter_type==P_INDIRECT){ - w_as_opcode_parameter (size_flag==SIZE_LONG ? "ld" : "ldsh",¶meter_1); + w_as_opcode_parameter ("ld",¶meter_1); w_as_comma(); w_as_register (REGISTER_O1); w_as_newline(); @@ -986,7 +986,7 @@ static void w_as_cmp_instruction (struct instruction *instruction,int size_flag) parameter_1.parameter_type=P_REGISTER; parameter_1.parameter_data.reg.r=REGISTER_O1; } else if (parameter_1.parameter_type==P_INDEXED){ - w_as_opcode (size_flag==SIZE_LONG ? "ld" : "ldsh"); + w_as_opcode ("ld"); w_as_parameter (¶meter_1); w_as_comma(); @@ -1025,16 +1025,79 @@ static void w_as_cmp_instruction (struct instruction *instruction,int size_flag) case P_REGISTER: break; default: - switch (size_flag){ - case SIZE_WORD: - w_as_opcode_parameter ("ldsh",¶meter_0); - break; - case SIZE_LONG: - w_as_opcode_parameter ("ld",¶meter_0); - break; - default: - internal_error_in_function ("w_as_cmp_instruction"); + w_as_opcode_parameter ("ld",¶meter_0); + w_as_comma(); + w_as_register (REGISTER_O0); + w_as_newline(); + + parameter_0.parameter_type=P_REGISTER; + parameter_0.parameter_data.reg.r=REGISTER_O0; + } + + w_as_opcode ("cmp"); + w_as_parameter (¶meter_1); + w_as_comma(); + w_as_parameter (¶meter_0); + w_as_newline(); +} + +#if 0 +static void w_as_cmpw_instruction (struct instruction *instruction) +{ + struct parameter parameter_0,parameter_1; + + parameter_0=instruction->instruction_parameters[0]; + parameter_1=instruction->instruction_parameters[1]; + + if (parameter_1.parameter_type==P_INDIRECT){ + w_as_opcode_parameter ("ldsh",¶meter_1); + w_as_comma(); + w_as_register (REGISTER_O1); + w_as_newline(); + + parameter_1.parameter_type=P_REGISTER; + parameter_1.parameter_data.reg.r=REGISTER_O1; + } else if (parameter_1.parameter_type==P_INDEXED){ + w_as_opcode ("ldsh"); + + w_as_parameter (¶meter_1); + w_as_comma(); + w_as_register (REGISTER_O1); + w_as_newline(); + + parameter_1.parameter_type=P_REGISTER; + parameter_1.parameter_data.reg.r=REGISTER_O1; + } + + switch (parameter_0.parameter_type){ + case P_DESCRIPTOR_NUMBER: + w_as_opcode_descriptor ("set", + parameter_0.parameter_data.l->label_name, + parameter_0.parameter_offset + ); + w_as_comma(); + w_as_register (REGISTER_O0); + w_as_newline(); + + parameter_0.parameter_type=P_REGISTER; + parameter_0.parameter_data.reg.r=REGISTER_O0; + break; + case P_IMMEDIATE: + if ((unsigned)(parameter_0.parameter_data.i+4096)>=(unsigned)8192){ + w_as_opcode ("set"); + w_as_parameter (¶meter_0); + w_as_comma(); + w_as_register (REGISTER_O0); + w_as_newline(); + + parameter_0.parameter_type=P_REGISTER; + parameter_0.parameter_data.reg.r=REGISTER_O0; } + break; + case P_REGISTER: + break; + default: + w_as_opcode_parameter ("ldsh",¶meter_0); w_as_comma(); w_as_register (REGISTER_O0); w_as_newline(); @@ -1049,6 +1112,7 @@ static void w_as_cmp_instruction (struct instruction *instruction,int size_flag) w_as_parameter (¶meter_0); w_as_newline(); } +#endif static void w_as_tst_instruction (struct instruction *instruction,int size_flag) { @@ -1993,7 +2057,7 @@ static void w_as_instructions (register struct instruction *instruction) w_as_sub_instruction (instruction); break; case ICMP: - w_as_cmp_instruction (instruction,SIZE_LONG); + w_as_cmp_instruction (instruction); break; case IJMP: w_as_jmp_instruction (instruction); @@ -2084,10 +2148,12 @@ static void w_as_instructions (register struct instruction *instruction) break; case ISO: w_as_set_condition_instruction (instruction,"bvs,a"); - break; + break; +#if 0 case ICMPW: - w_as_cmp_instruction (instruction,SIZE_WORD); + w_as_cmpw_instruction (instruction); break; +#endif case ITST: w_as_tst_instruction (instruction,SIZE_LONG); break; |