summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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;