summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn van Groningen2006-03-24 11:26:30 +0000
committerJohn van Groningen2006-03-24 11:26:30 +0000
commit9dac5f646c025a82c2dfb841db019fc8e1e77945 (patch)
treec98a328e09befbe34b8d338333fc9b678860c71e
parentoptimize 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.c73
-rw-r--r--cgawas.c82
-rw-r--r--cgias.c289
-rw-r--r--cgiconst.h28
-rw-r--r--cgiwas.c250
-rw-r--r--cglin.c313
-rw-r--r--cgopt.c81
-rw-r--r--cgpas.c106
-rw-r--r--cgpwas.c118
-rw-r--r--cgsas.c85
-rw-r--r--cgswas.c96
11 files changed, 1089 insertions, 432 deletions
diff --git a/cgaas.c b/cgaas.c
index bd0e5c4..39a0b5a 100644
--- a/cgaas.c
+++ b/cgaas.c
@@ -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,&parameter_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,&parameter_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;
diff --git a/cgawas.c b/cgawas.c
index ba2d403..f1db070 100644
--- a/cgawas.c
+++ b/cgawas.c
@@ -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 (&parameter_1);
+ w_as_scratch_register();
+ if (!intel_asm)
+ w_as_comma_parameter (&parameter_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 (&parameter_1);
+ }
+ w_as_parameter (&parameter_0);
+ if (!intel_asm)
+ w_as_comma_parameter (&parameter_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 (&parameter_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 (&parameter_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 (&parameter_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;
diff --git a/cgias.c b/cgias.c
index 725595a..38d6c83 100644
--- a/cgias.c
+++ b/cgias.c
@@ -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,&parameter_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,&parameter_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;
diff --git a/cgiconst.h b/cgiconst.h
index 74d8d9f..fe4d373 100644
--- a/cgiconst.h
+++ b/cgiconst.h
@@ -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
diff --git a/cgiwas.c b/cgiwas.c
index eef34df..d59dc6e 100644
--- a/cgiwas.c
+++ b/cgiwas.c
@@ -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 (&parameter_1);
+ w_as_descriptor (parameter_0.parameter_data.l,parameter_0.parameter_offset);
+ if (!intel_asm)
+ w_as_comma_parameter (&parameter_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 (&parameter_1);
+ }
+ w_as_parameter (&parameter_0);
+ if (!intel_asm)
+ w_as_comma_parameter (&parameter_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 (&parameter_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 (&parameter_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 (&parameter_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);
diff --git a/cglin.c b/cglin.c
index 56e7ed8..233b923 100644
--- a/cglin.c
+++ b/cglin.c
@@ -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,&parameter1);
+ free_f_register=fad_to_parameter_without_freeing_fregister (&ad_1,&parameter1);
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,&parameter1);
+ free_f_register=fad_to_parameter_without_freeing_fregister (&ad_1,&parameter1);
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
diff --git a/cgopt.c b/cgopt.c
index ccd4e39..beff6ff 100644
--- a/cgopt.c
+++ b/cgopt.c
@@ -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;
*/
diff --git a/cgpas.c b/cgpas.c
index 6dd81cd..d2e536d 100644
--- a/cgpas.c
+++ b/cgpas.c
@@ -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 (&parameter_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;
diff --git a/cgpwas.c b/cgpwas.c
index 896c1f3..d2bd19b 100644
--- a/cgpwas.c
+++ b/cgpwas.c
@@ -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 (&parameter_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 (&parameter_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 (&parameter_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 (&parameter_1);
+ w_as_comma();
+ w_as_parameter (&parameter_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 (&parameter_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 (&parameter_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 (&parameter_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 (&parameter_0);
w_as_newline();
@@ -1316,6 +1383,7 @@ static void w_as_cmp_instruction (struct instruction *instruction,int size_flag)
w_as_parameter (&parameter_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;
diff --git a/cgsas.c b/cgsas.c
index d18d618..5a7bba5 100644
--- a/cgsas.c
+++ b/cgsas.c
@@ -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 (&parameter_0,REGISTER_O0);
- break;
- case SIZE_LONG:
- as_ld_parameter (&parameter_0,REGISTER_O0);
- break;
- default:
- internal_error_in_function ("as_cmp_instruction");
+ as_ld_parameter (&parameter_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 (&parameter_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;
diff --git a/cgswas.c b/cgswas.c
index 452a0e1..4ad8992 100644
--- a/cgswas.c
+++ b/cgswas.c
@@ -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",&parameter_1);
+ w_as_opcode_parameter ("ld",&parameter_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 (&parameter_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",&parameter_0);
- break;
- case SIZE_LONG:
- w_as_opcode_parameter ("ld",&parameter_0);
- break;
- default:
- internal_error_in_function ("w_as_cmp_instruction");
+ w_as_opcode_parameter ("ld",&parameter_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 (&parameter_1);
+ w_as_comma();
+ w_as_parameter (&parameter_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",&parameter_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 (&parameter_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 (&parameter_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",&parameter_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 (&parameter_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;