diff options
-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; |