summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cgcalc.c20
-rw-r--r--cgcode.c43
-rw-r--r--cgconst.h3
-rw-r--r--cgias.c184
-rw-r--r--cgiconst.h3
-rw-r--r--cginstructions.c4
-rw-r--r--cginstructions.h6
-rw-r--r--cgiwas.c167
-rw-r--r--cglin.c39
-rw-r--r--cgopt.c10
10 files changed, 444 insertions, 35 deletions
diff --git a/cgcalc.c b/cgcalc.c
index 7a8de67..a6a30eb 100644
--- a/cgcalc.c
+++ b/cgcalc.c
@@ -1438,7 +1438,7 @@ static void calculate_store_x_operator (INSTRUCTION_GRAPH graph)
select_graph=select_graph->instruction_parameters[3].p;
break;
case GFLOAD_X:
-#ifdef G_AI64
+#ifdef I486
case GFLOAD_S_X:
#endif
case GREGISTER:
@@ -1757,7 +1757,7 @@ static void calculate_fstore_x_operator (INSTRUCTION_GRAPH graph)
while (select_graph!=NULL){
switch (select_graph->instruction_code){
case GFLOAD_X:
-#ifdef G_AI64
+#ifdef I486
case GFLOAD_S_X:
#endif
if (graph_2==select_graph->instruction_parameters[0].p){
@@ -2487,13 +2487,13 @@ void calculate_graph_register_uses (INSTRUCTION_GRAPH graph)
calculate_fstore_operator (graph);
return;
case GFLOAD_X:
-#ifdef G_AI64
+#ifdef I486
case GFLOAD_S_X:
#endif
calculate_fload_x_operator (graph);
return;
case GFSTORE_X:
-#ifdef G_AI64
+#ifdef I486
case GFSTORE_S_X:
#endif
calculate_fstore_x_operator (graph);
@@ -2859,6 +2859,8 @@ void count_graph (INSTRUCTION_GRAPH graph)
case GFLOAD_X:
#ifdef G_AI64
case GLOAD_S_X:
+#endif
+#ifdef I486
case GFLOAD_S_X:
#endif
if (++graph->node_count==1){
@@ -2875,7 +2877,7 @@ void count_graph (INSTRUCTION_GRAPH graph)
count_gstore_x_node (graph);
break;
case GFSTORE_X:
-#ifdef G_AI64
+#ifdef I486
case GFSTORE_S_X:
#endif
if (++graph->node_count==1){
@@ -3082,6 +3084,8 @@ void mark_graph_2 (register INSTRUCTION_GRAPH graph)
case GFLOAD_X:
#ifdef G_AI64
case GLOAD_S_X:
+#endif
+#ifdef I486
case GFLOAD_S_X:
#endif
if (graph->node_mark<2){
@@ -3097,7 +3101,7 @@ void mark_graph_2 (register INSTRUCTION_GRAPH graph)
case GSTORE_S_X:
#endif
case GFSTORE_X:
-#ifdef G_AI64
+#ifdef I486
case GFSTORE_S_X:
#endif
if (graph->node_mark<2){
@@ -3296,6 +3300,8 @@ void mark_graph_1 (register INSTRUCTION_GRAPH graph)
case GFLOAD_X:
#ifdef G_AI64
case GLOAD_S_X:
+#endif
+#ifdef I486
case GFLOAD_S_X:
#endif
if (!graph->node_mark){
@@ -3311,7 +3317,7 @@ void mark_graph_1 (register INSTRUCTION_GRAPH graph)
case GSTORE_S_X:
#endif
case GFSTORE_X:
-#ifdef G_AI64
+#ifdef I486
case GFSTORE_S_X:
#endif
if (!graph->node_mark){
diff --git a/cgcode.c b/cgcode.c
index c8abdeb..99d8e26 100644
--- a/cgcode.c
+++ b/cgcode.c
@@ -6365,19 +6365,26 @@ static void code_replaceR (VOID)
s_push_b (graph_9);
}
-#ifdef G_AI64
+#ifdef I486
static void code_replaceR32 (VOID)
{
- INSTRUCTION_GRAPH graph_1,graph_2,graph_3,graph_4,graph_7,graph_8,graph_9;
+ INSTRUCTION_GRAPH graph_1,graph_2,graph_3,graph_4,graph_7,graph_8,graph_9,graph_10;
graph_1=s_get_a (0);
graph_2=s_pop_b();
graph_3=s_pop_b();
+# ifndef G_A64
+ graph_4=s_pop_b();
+# endif
if (check_index_flag)
graph_2=g_bounds (graph_1,graph_2);
+# ifdef G_A64
graph_7=g_fp_arg (graph_3);
+# else
+ graph_7=g_fjoin (graph_3,graph_4);
+# endif
if (!check_index_flag && graph_2->instruction_code==GLOAD_I &&
LESS_UNSIGNED (graph_2->instruction_parameters[0].i,(MAX_INDIRECT_OFFSET-ARRAY_ELEMENTS_OFFSET)>>2))
@@ -6395,9 +6402,16 @@ static void code_replaceR32 (VOID)
graph_8=g_fstore_s_x (graph_7,graph_1,offset,2,graph_2);
}
+# ifdef G_A64
graph_9=g_fromf (graph_4);
+# else
+ g_fhighlow (graph_9,graph_10,graph_4);
+# endif
s_put_a (0,graph_8);
+# ifndef G_A64
+ s_push_b (graph_10);
+# endif
s_push_b (graph_9);
}
#endif
@@ -6544,7 +6558,7 @@ void code_replace (char element_descriptor[],int a_size,int b_size)
code_replaceR();
return;
}
-#ifdef G_AI64
+#ifdef I486
if (element_descriptor[4]=='3' && element_descriptor[5]=='2' && element_descriptor[6]=='\0'){
code_replaceR32();
return;
@@ -7147,7 +7161,7 @@ static void code_selectR (VOID)
s_push_b (graph_5);
}
-#ifdef G_AI64
+#ifdef I486
static void code_selectR32 (VOID)
{
INSTRUCTION_GRAPH graph_1,graph_2,graph_3,graph_4,graph_5,graph_6;
@@ -7169,8 +7183,12 @@ static void code_selectR32 (VOID)
graph_4=g_fload_s_x (graph_1,offset,2,graph_2);
}
+# ifdef G_A64
graph_5=g_fromf (graph_4);
-
+# else
+ g_fhighlow (graph_5,graph_6,graph_4);
+ s_push_b (graph_6);
+# endif
s_push_b (graph_5);
}
#endif
@@ -7274,7 +7292,7 @@ void code_select (char element_descriptor[],int a_size,int b_size)
code_selectR();
return;
}
-#ifdef G_AI64
+#ifdef I486
if (element_descriptor[4]=='3' && element_descriptor[5]=='2' && element_descriptor[6]=='\0'){
code_selectR32();
return;
@@ -7901,19 +7919,26 @@ static void code_updateR (VOID)
s_put_a (0,graph_8);
}
-#ifdef G_AI64
+#ifdef I486
static void code_updateR32 (VOID)
{
- INSTRUCTION_GRAPH graph_1,graph_2,graph_3,graph_7,graph_8;
+ INSTRUCTION_GRAPH graph_1,graph_2,graph_3,graph_4,graph_7,graph_8;
graph_1=s_get_a (0);
graph_2=s_pop_b();
graph_3=s_pop_b();
+# ifndef G_A64
+ graph_4=s_pop_b();
+# endif
if (check_index_flag)
graph_2=g_bounds (graph_1,graph_2);
+# ifdef G_A64
graph_7=g_fp_arg (graph_3);
+# else
+ graph_7=g_fjoin (graph_3,graph_4);
+# endif
if (!check_index_flag && graph_2->instruction_code==GLOAD_I &&
LESS_UNSIGNED (graph_2->instruction_parameters[0].i,(MAX_INDIRECT_OFFSET-REAL_ARRAY_ELEMENTS_OFFSET)>>2))
@@ -8115,7 +8140,7 @@ void code_update (char element_descriptor[],int a_size,int b_size)
code_updateR();
return;
}
-#ifdef G_AI64
+#ifdef I486
if (element_descriptor[4]=='3' && element_descriptor[5]=='2' && element_descriptor[6]=='\0'){
code_updateR32();
return;
diff --git a/cgconst.h b/cgconst.h
index 5f9f24d..d9cc686 100644
--- a/cgconst.h
+++ b/cgconst.h
@@ -30,12 +30,13 @@ enum {
#endif
#ifdef I486
,GADDDU, GDIVDU, GMULUD, GREMU, GRESULT0, GRESULT1, GSUBDU
+ ,GFLOAD_S_X,GFSTORE_S_X
#endif
#if defined (I486) && !defined (G_A64)
,GFSINCOS, GFRESULT0, GFRESULT1
#endif
#ifdef G_AI64
- ,GLOAD_S_X, GSTORE_S_X, GFLOAD_S_X, GFSTORE_S_X
+ ,GLOAD_S_X, GSTORE_S_X
#endif
#ifdef M68000
,GFACOS, GFASIN, GFEXP, GFLN, GFLOG10
diff --git a/cgias.c b/cgias.c
index 8803735..8260661 100644
--- a/cgias.c
+++ b/cgias.c
@@ -3068,6 +3068,7 @@ struct instruction *find_next_fp_instruction (struct instruction *instruction)
case IFCOS: case IFSIN: case IFSQRT: case IFTAN: case IFSINCOS:
case IFEXG:
case IWORD:
+ case IFLOADS: case IFMOVES:
return instruction;
case IFMOVE:
if (! (instruction->instruction_parameters[0].parameter_type==P_F_REGISTER
@@ -3554,6 +3555,183 @@ static struct instruction *as_fmove_instruction (struct instruction *instruction
return instruction;
}
+static struct instruction *as_floads_instruction (struct instruction *instruction)
+{
+ switch (instruction->instruction_parameters[1].parameter_type){
+ case P_F_REGISTER:
+ {
+ int reg0;
+
+ reg0=-1;
+
+ switch (instruction->instruction_parameters[0].parameter_type){
+ case P_INDIRECT:
+ as_f_id (0xd9,instruction->instruction_parameters[0].parameter_offset,
+ instruction->instruction_parameters[0].parameter_data.reg.r,0); /* flds */
+ break;
+ case P_INDEXED:
+ as_f_x (0xd9,instruction->instruction_parameters[0].parameter_offset,
+ instruction->instruction_parameters[0].parameter_data.ir,0); /* flds */
+ break;
+ default:
+ internal_error_in_function ("as_floads_instruction");
+ return instruction;
+ }
+#ifdef FP_STACK_OPTIMIZATIONS
+ fstpl_instruction (instruction->instruction_parameters[1].parameter_data.reg.r,instruction);
+ return instruction;
+ }
+#else
+ {
+ struct instruction *next_instruction;
+ int reg1;
+
+ reg1=instruction->instruction_parameters[1].parameter_data.reg.r;
+ next_instruction=instruction->instruction_next;
+
+ if (next_instruction)
+ switch (next_instruction->instruction_icode){
+ case IFADD: case IFSUB: case IFMUL: case IFDIV:
+ if (next_instruction->instruction_parameters[1].parameter_data.reg.r==reg1){
+ if (next_instruction->instruction_parameters[0].parameter_type==P_F_REGISTER){
+ int reg_s,code2;
+
+ reg_s=next_instruction->instruction_parameters[0].parameter_data.reg.r;
+ if (reg_s==reg1)
+ reg_s=reg0;
+
+ switch (next_instruction->instruction_icode){
+ case IFADD:
+ code2=0xc0;
+ break;
+ case IFSUB:
+# ifdef FSUB_FDIV_REVERSED
+ if (next_instruction->instruction_parameters[1].parameter_flags & FP_REVERSE_SUB_DIV_OPERANDS)
+ code2=0xe8;
+ else
+# endif
+ code2=0xe0;
+ break;
+ case IFMUL:
+ code2=0xc8;
+ break;
+ case IFDIV:
+# ifdef FSUB_FDIV_REVERSED
+ if (next_instruction->instruction_parameters[1].parameter_flags & FP_REVERSE_SUB_DIV_OPERANDS)
+ code2=0xf8;
+ else
+# endif
+ code2=0xf0;
+ break;
+ }
+
+ as_f_r (0xd8,code2,reg_s+1);
+ } else {
+ int code2;
+
+ switch (next_instruction->instruction_icode){
+ case IFADD:
+ code2=0;
+ break;
+ case IFSUB:
+# ifdef FSUB_FDIV_REVERSED
+ if (next_instruction->instruction_parameters[1].parameter_flags & FP_REVERSE_SUB_DIV_OPERANDS)
+ code2=5;
+ else
+# endif
+ code2=4;
+ break;
+ case IFMUL:
+ code2=1;
+ break;
+ case IFDIV:
+# ifdef FSUB_FDIV_REVERSED
+ if (next_instruction->instruction_parameters[1].parameter_flags & FP_REVERSE_SUB_DIV_OPERANDS)
+ code2=7;
+ else
+# endif
+ code2=6;
+ break;
+ }
+
+ switch (next_instruction->instruction_parameters[0].parameter_type){
+ case P_F_IMMEDIATE:
+ as_f_i (0xdc,code2,next_instruction->instruction_parameters[0].parameter_data.r);
+ break;
+ case P_INDIRECT:
+ as_f_id (0xdc,next_instruction->instruction_parameters[0].parameter_offset,
+ next_instruction->instruction_parameters[0].parameter_data.reg.r,code2);
+ break;
+ case P_INDEXED:
+ as_f_x (0xdc,next_instruction->instruction_parameters[0].parameter_offset,
+ next_instruction->instruction_parameters[0].parameter_data.ir,code2);
+ break;
+ default:
+ internal_error_in_function ("as_floads_instruction");
+ return instruction;
+ }
+ }
+
+ as_f_r (0xdd,0xd8,reg1+1); /* fstp reg1+1 */
+
+ return next_instruction;
+ }
+ }
+
+ as_f_r (0xdd,0xd8,reg1+1); /* fstp reg */
+ return instruction;
+ }
+ }
+#endif
+ }
+ internal_error_in_function ("as_floads_instruction");
+ return instruction;
+}
+
+static struct instruction *as_fmoves_instruction (struct instruction *instruction)
+{
+ switch (instruction->instruction_parameters[1].parameter_type){
+ case P_INDIRECT:
+ case P_INDEXED:
+ if (instruction->instruction_parameters[0].parameter_type==P_F_REGISTER){
+ int s_freg,code2;
+
+ s_freg=instruction->instruction_parameters[0].parameter_data.reg.r;
+
+#ifdef FP_STACK_OPTIMIZATIONS
+ if (instruction->instruction_parameters[0].parameter_flags & FP_REG_ON_TOP){
+ if (next_instruction_is_fld_reg (s_freg,instruction))
+ code2=2; /* fsts */
+ else
+ code2=3; /* fstps */
+ } else
+#endif
+ if (s_freg!=0){
+ as_f_r (0xd9,0xc0,s_freg); /* fld s_freg */
+
+#ifdef FP_STACK_OPTIMIZATIONS
+ if (next_instruction_is_fld_reg (s_freg,instruction))
+ code2=2; /* fsts */
+ else
+#endif
+ code2=3; /* fstps */
+ } else
+ code2=2; /* fsts */
+
+ if (instruction->instruction_parameters[1].parameter_type==P_INDIRECT)
+ as_f_id (0xd9,instruction->instruction_parameters[1].parameter_offset,
+ instruction->instruction_parameters[1].parameter_data.reg.r,code2);
+ else
+ as_f_x (0xd9,instruction->instruction_parameters[1].parameter_offset,
+ instruction->instruction_parameters[1].parameter_data.ir,code2);
+
+ return instruction;
+ }
+ }
+ internal_error_in_function ("as_fmoves_instruction");
+ return instruction;
+}
+
static void as_dyadic_float_instruction (struct instruction *instruction,int code,int code1,int code2)
{
int d_freg;
@@ -4401,6 +4579,12 @@ static void as_instructions (struct instruction *instruction)
case IFMOVEL:
as_fmovel_instruction (instruction);
break;
+ case IFLOADS:
+ instruction=as_floads_instruction (instruction);
+ break;
+ case IFMOVES:
+ instruction=as_fmoves_instruction (instruction);
+ break;
case IFSQRT:
as_monadic_float_instruction (instruction,0xfa);
break;
diff --git a/cgiconst.h b/cgiconst.h
index 7b93eb4..053ba95 100644
--- a/cgiconst.h
+++ b/cgiconst.h
@@ -67,6 +67,7 @@ enum {
#endif
#if defined (I486)
,IADC ,IRTSI, IDIVI, IREMI, IREMU, IMULUD, IDIVDU, ISBB
+ ,IFLOADS, IFMOVES
#endif
#if defined (I486) || defined (G_POWER)
,IDIVU
@@ -75,7 +76,7 @@ enum {
,IUMULH
#endif
#ifdef G_AI64
- ,ILOADSQB, IMOVEQB, IFLOADS, IFCVT2S, IFMOVES
+ ,ILOADSQB, IMOVEQB, IFCVT2S
#endif
};
diff --git a/cginstructions.c b/cginstructions.c
index 25c11a8..4f1d8a7 100644
--- a/cginstructions.c
+++ b/cginstructions.c
@@ -673,7 +673,7 @@ INSTRUCTION_GRAPH g_fload_x (INSTRUCTION_GRAPH graph_1,int offset,int shift,INST
return instruction;
}
-#ifdef G_AI64
+#ifdef I486
INSTRUCTION_GRAPH g_fload_s_x (INSTRUCTION_GRAPH graph_1,int offset,int shift,INSTRUCTION_GRAPH graph_2)
{
INSTRUCTION_GRAPH instruction;
@@ -973,7 +973,7 @@ INSTRUCTION_GRAPH g_fstore_x (INSTRUCTION_GRAPH graph_1,INSTRUCTION_GRAPH graph_
return instruction;
}
-#ifdef G_AI64
+#ifdef I486
INSTRUCTION_GRAPH g_fstore_s_x (INSTRUCTION_GRAPH graph_1,INSTRUCTION_GRAPH graph_2,int offset,int shift,INSTRUCTION_GRAPH graph_3)
{
INSTRUCTION_GRAPH instruction;
diff --git a/cginstructions.h b/cginstructions.h
index d587abe..e75f23b 100644
--- a/cginstructions.h
+++ b/cginstructions.h
@@ -22,7 +22,7 @@ extern INSTRUCTION_GRAPH g_fload (int offset,int stack);
extern INSTRUCTION_GRAPH g_fload_i (DOUBLE v);
extern INSTRUCTION_GRAPH g_fload_id (int offset,INSTRUCTION_GRAPH graph_1);
extern INSTRUCTION_GRAPH g_fload_x (INSTRUCTION_GRAPH graph_1,int offset,int shift,INSTRUCTION_GRAPH graph_2);
-#ifdef G_AI64
+#ifdef I486
extern INSTRUCTION_GRAPH g_fload_s_x (INSTRUCTION_GRAPH graph_1,int offset,int shift,INSTRUCTION_GRAPH graph_2);
#endif
extern INSTRUCTION_GRAPH g_lea (LABEL *label);
@@ -35,14 +35,14 @@ extern INSTRUCTION_GRAPH g_load_x (INSTRUCTION_GRAPH graph_1,int offset,int shif
extern INSTRUCTION_GRAPH g_load_b_id (int offset,INSTRUCTION_GRAPH graph_1);
extern INSTRUCTION_GRAPH g_load_des_i (LABEL *descriptor_label,int arity);
extern INSTRUCTION_GRAPH g_load_des_id (int offset,INSTRUCTION_GRAPH graph_1);
-#ifdef G_AI64
+#ifdef g_load_s_x
extern INSTRUCTION_GRAPH g_load_s_x (INSTRUCTION_GRAPH graph_1,int offset,int shift,INSTRUCTION_GRAPH graph_2);
#endif
extern INSTRUCTION_GRAPH g_movem (int offset,INSTRUCTION_GRAPH graph_1,int n);
extern INSTRUCTION_GRAPH g_movemi (int number,INSTRUCTION_GRAPH movem_graph);
extern INSTRUCTION_GRAPH g_fregister (int float_reg);
extern INSTRUCTION_GRAPH g_fstore_x (INSTRUCTION_GRAPH graph_1,INSTRUCTION_GRAPH graph_2,int offset,int shift,INSTRUCTION_GRAPH graph_3);
-#ifdef G_AI64
+#ifdef I486
extern INSTRUCTION_GRAPH g_fstore_s_x (INSTRUCTION_GRAPH graph_1,INSTRUCTION_GRAPH graph_2,int offset,int shift,INSTRUCTION_GRAPH graph_3);
#endif
extern INSTRUCTION_GRAPH g_g_register (int reg);
diff --git a/cgiwas.c b/cgiwas.c
index 2fa7cfd..eb7d9cd 100644
--- a/cgiwas.c
+++ b/cgiwas.c
@@ -3069,6 +3069,167 @@ static struct instruction *w_as_fmove_instruction (struct instruction *instructi
return instruction;
}
+static struct instruction *w_as_floads_instruction (struct instruction *instruction)
+{
+ switch (instruction->instruction_parameters[1].parameter_type){
+ case P_F_REGISTER:
+ {
+ int reg0;
+
+ reg0=-1;
+
+ switch (instruction->instruction_parameters[0].parameter_type){
+ case P_INDIRECT:
+ if (!intel_asm)
+ w_as_opcode ("flds");
+ else {
+ w_as_opcode ("fld");
+ fprintf (assembly_file,"dword ptr ");
+ }
+ w_as_indirect (instruction->instruction_parameters[0].parameter_offset,
+ instruction->instruction_parameters[0].parameter_data.reg.r);
+ w_as_newline();
+ break;
+ case P_INDEXED:
+ if (!intel_asm)
+ w_as_opcode ("flds");
+ else {
+ w_as_opcode ("fld");
+ fprintf (assembly_file,"dword ptr ");
+ }
+ w_as_indexed (instruction->instruction_parameters[0].parameter_offset,
+ instruction->instruction_parameters[0].parameter_data.ir);
+ w_as_newline();
+ break;
+ default:
+ internal_error_in_function ("w_as_floads_instruction");
+ return instruction;
+ }
+#ifdef FP_STACK_OPTIMIZATIONS
+ fstpl_instruction (instruction->instruction_parameters[1].parameter_data.reg.r,instruction);
+ return instruction;
+ }
+#else
+ {
+ struct instruction *next_instruction;
+ int reg1;
+
+ reg1=instruction->instruction_parameters[1].parameter_data.reg.r;
+
+ next_instruction=instruction->instruction_next;
+ if (next_instruction)
+ switch (next_instruction->instruction_icode){
+ case IFADD: case IFSUB: case IFMUL: case IFDIV:
+ if (next_instruction->instruction_parameters[1].parameter_data.reg.r==reg1){
+ char *opcode;
+
+ switch (next_instruction->instruction_icode){
+ case IFADD:
+ opcode="fadd";
+ break;
+ case IFSUB:
+# ifdef FSUB_FDIV_REVERSED
+ if (next_instruction->instruction_parameters[1].parameter_flags & FP_REVERSE_SUB_DIV_OPERANDS)
+ opcode="fsubr";
+ else
+# endif
+ opcode="fsub";
+ break;
+ case IFMUL:
+ opcode="fmul";
+ break;
+ case IFDIV:
+# ifdef FSUB_FDIV_REVERSED
+ if (next_instruction->instruction_parameters[1].parameter_flags & FP_REVERSE_SUB_DIV_OPERANDS)
+ opcode="fdivr";
+ else
+# endif
+ opcode="fdiv";
+ break;
+ }
+
+ if (next_instruction->instruction_parameters[0].parameter_type==P_F_REGISTER){
+ int reg_s;
+
+ reg_s=next_instruction->instruction_parameters[0].parameter_data.reg.r;
+ if (reg_s==reg1)
+ reg_s=reg0;
+
+ w_as_opcode (opcode);
+ if (intel_asm)
+ fprintf (assembly_file,"st,");
+ w_as_fp_register_newline (reg_s+1);
+ } else
+ w_as_opcode_parameter_newline (opcode,&next_instruction->instruction_parameters[0]);
+
+ w_as_opcode ("fstp");
+ w_as_fp_register_newline (reg1+1);
+
+ return next_instruction;
+ }
+ }
+ }
+ }
+
+ w_as_opcode ("fstp");
+ w_as_fp_register_newline (instruction->instruction_parameters[1].parameter_data.reg.r+1);
+ return instruction;
+#endif
+ }
+ internal_error_in_function ("w_as_floads_instruction");
+ return instruction;
+}
+
+static struct instruction *w_as_fmoves_instruction (struct instruction *instruction)
+{
+ switch (instruction->instruction_parameters[1].parameter_type){
+ case P_INDIRECT:
+ case P_INDEXED:
+ if (instruction->instruction_parameters[0].parameter_type==P_F_REGISTER){
+ int s_freg;
+
+ s_freg=instruction->instruction_parameters[0].parameter_data.reg.r;
+
+#ifdef FP_STACK_OPTIMIZATIONS
+ if (instruction->instruction_parameters[0].parameter_flags & FP_REG_ON_TOP){
+ if (next_instruction_is_fld_reg (s_freg,instruction))
+ w_as_opcode (intel_asm ? "fst" : "fsts");
+ else {
+ w_as_opcode (intel_asm ? "fstp" : "fstps");
+ }
+ } else
+#endif
+ if (s_freg!=0){
+ w_as_opcode ("fld");
+ w_as_fp_register_newline (s_freg);
+
+#ifdef FP_STACK_OPTIMIZATIONS
+ if (next_instruction_is_fld_reg (s_freg,instruction))
+ w_as_opcode (intel_asm ? "fst" : "fsts");
+ else
+#endif
+ w_as_opcode (intel_asm ? "fstp" : "fstps");
+ } else
+ w_as_opcode (intel_asm ? "fst" : "fsts");
+
+ if (intel_asm)
+ fprintf (assembly_file,"dword ptr ");
+
+ if (instruction->instruction_parameters[1].parameter_type==P_INDIRECT)
+ w_as_indirect (instruction->instruction_parameters[1].parameter_offset,
+ instruction->instruction_parameters[1].parameter_data.reg.r);
+ else
+ w_as_indexed (instruction->instruction_parameters[1].parameter_offset,
+ instruction->instruction_parameters[1].parameter_data.ir);
+
+ w_as_newline();
+ return instruction;
+ }
+ }
+ internal_error_in_function ("w_as_fmoves_instruction");
+ return instruction;
+}
+
static int int_to_real_scratch_imported=0;
static void w_as_fmovel_instruction (struct instruction *instruction)
@@ -3495,6 +3656,12 @@ static void w_as_instructions (register struct instruction *instruction)
case IFMOVEL:
w_as_fmovel_instruction (instruction);
break;
+ case IFLOADS:
+ instruction=w_as_floads_instruction (instruction);
+ break;
+ case IFMOVES:
+ instruction=w_as_fmoves_instruction (instruction);
+ break;
case IFSQRT:
w_as_monadic_float_instruction (instruction,"fsqrt");
break;
diff --git a/cglin.c b/cglin.c
index ef79333..194ed0a 100644
--- a/cglin.c
+++ b/cglin.c
@@ -431,7 +431,7 @@ static void i_fexg_fr_fr (int register_1,int register_2)
}
#endif
-#ifdef G_AI64
+#ifdef I486
static void i_floads_id_fr (int offset,int register_2,int register_1)
{
struct instruction *instruction;
@@ -622,7 +622,7 @@ static void i_fmovel_fr_r (int register_1,int register_2)
parameter_data.i=register_2);
}
-#ifdef G_AI64
+#ifdef I486
static void i_fmoves_fr_id (int register_1,int offset,int register_2)
{
struct instruction *instruction;
@@ -689,7 +689,7 @@ static void i_fmove_x_fr (int offset,int register_1,int register_2,int register_
set_float_register_parameter (instruction->instruction_parameters[1],register_3);
}
-#ifdef G_AI64
+#ifdef I486
static void i_floads_x_fr (int offset,int register_1,int register_2,int register_3)
{
struct instruction *instruction;
@@ -6882,7 +6882,7 @@ static void linearize_fload_x_operator (INSTRUCTION_GRAPH graph,ADDRESS *ad_p)
}
}
-#ifdef G_AI64
+#ifdef I486
static void linearize_fload_s_x_operator (INSTRUCTION_GRAPH graph,ADDRESS *ad_p)
{
INSTRUCTION_GRAPH graph_1,graph_2;
@@ -7080,7 +7080,7 @@ static void linearize_float_graph (register INSTRUCTION_GRAPH graph,register ADD
case GFLOAD_X:
linearize_fload_x_operator (graph,ad_p);
return;
-#ifdef G_AI64
+#ifdef I486
case GFLOAD_S_X:
linearize_fload_s_x_operator (graph,ad_p);
return;
@@ -7190,7 +7190,7 @@ static void linearize_fstore_operator (INSTRUCTION_GRAPH graph)
}
static void linearize_fstore_x_operator (INSTRUCTION_GRAPH graph,ADDRESS *ad_p);
-#ifdef G_AI64
+#ifdef I486
static void linearize_fstore_s_x_operator (INSTRUCTION_GRAPH graph,ADDRESS *ad_p);
#endif
@@ -8092,7 +8092,7 @@ static void do_array_selects_before_update (INSTRUCTION_GRAPH select_graph,INSTR
}
}
break;
-#ifdef G_AI64
+#ifdef I486
case GFLOAD_S_X:
if (graph_2==select_graph->instruction_parameters[0].p){
if (select_graph->node_count>0 && !(select_graph->inode_arity & LOAD_X_TO_REGISTER)){
@@ -8743,7 +8743,7 @@ static void linearize_graph (INSTRUCTION_GRAPH graph,ADDRESS *ad_p)
case GFSTORE_X:
linearize_fstore_x_operator (graph,ad_p);
return;
-#ifdef G_AI64
+#ifdef I486
case GFSTORE_S_X:
linearize_fstore_s_x_operator (graph,ad_p);
return;
@@ -9043,7 +9043,7 @@ static void linearize_fstore_x_operator (INSTRUCTION_GRAPH graph,ADDRESS *ad_p)
}
}
-#ifdef G_AI64
+#ifdef I486
static void linearize_fstore_s_x_operator (INSTRUCTION_GRAPH graph,ADDRESS *ad_p)
{
INSTRUCTION_GRAPH graph_1,graph_2,graph_3;
@@ -9110,6 +9110,7 @@ static void linearize_fstore_s_x_operator (INSTRUCTION_GRAPH graph,ADDRESS *ad_p
if (ad_1.ad_mode!=P_F_REGISTER)
in_float_register (&ad_1);
+#ifdef G_AI64
if (--*ad_1.ad_count_p==0)
reg_1=ad_1.ad_register;
else
@@ -9119,6 +9120,15 @@ static void linearize_fstore_s_x_operator (INSTRUCTION_GRAPH graph,ADDRESS *ad_p
i_fmoves_fr_id (reg_1,offset>>2,ad_p->ad_register);
free_fregister (reg_1);
+#else
+ i_fmoves_fr_id (ad_1.ad_register,offset>>2,ad_p->ad_register);
+ if (--*ad_1.ad_count_p==0){
+# ifdef FP_STACK_OPTIMIZATIONS
+ last_instruction->instruction_parameters[0].parameter_flags |= FP_REG_LAST_USE;
+# endif
+ free_fregister (ad_1.ad_register);
+ }
+#endif
} else {
int reg_1;
@@ -9129,7 +9139,7 @@ static void linearize_fstore_s_x_operator (INSTRUCTION_GRAPH graph,ADDRESS *ad_p
if (ad_1.ad_mode!=P_F_REGISTER)
in_float_register (&ad_1);
-
+#ifdef G_AI64
if (--*ad_1.ad_count_p==0)
reg_1=ad_1.ad_register;
else
@@ -9139,6 +9149,15 @@ static void linearize_fstore_s_x_operator (INSTRUCTION_GRAPH graph,ADDRESS *ad_p
i_fmoves_fr_x (reg_1,offset,ad_p->ad_register,ad_3.ad_register);
free_fregister (reg_1);
+#else
+ i_fmoves_fr_x (ad_1.ad_register,offset,ad_p->ad_register,ad_3.ad_register);
+ if (--*ad_1.ad_count_p==0){
+# ifdef FP_STACK_OPTIMIZATIONS
+ last_instruction->instruction_parameters[0].parameter_flags |= FP_REG_LAST_USE;
+# endif
+ free_fregister (ad_1.ad_register);
+ }
+#endif
}
if (graph->node_count>1){
diff --git a/cgopt.c b/cgopt.c
index a248660..7b99bbf 100644
--- a/cgopt.c
+++ b/cgopt.c
@@ -1609,7 +1609,10 @@ IF_G_POWER ( case IUMULH: )
IF_G_SPARC (case IFMOVEHI: case IFMOVELO:)
IF_G_RISC (case IADDI: case ILSLI:)
#ifdef G_AI64
- case ILOADSQB: case IFLOADS: case IFCVT2S: case IFMOVES:
+ case ILOADSQB: case IFCVT2S:
+#endif
+#ifdef I486
+ case IFLOADS: case IFMOVES:
#endif
#if defined (I486) && !defined (G_A64)
case IFSINCOS:
@@ -3917,7 +3920,10 @@ IF_G_POWER (case ICMPLW:)
IF_G_SPARC (case IFMOVEHI: case IFMOVELO:)
IF_G_RISC (case IADDI: case ILSLI:)
#ifdef G_AI64
- case ILOADSQB: case IFLOADS: case IFCVT2S: case IFMOVES:
+ case ILOADSQB: case IFCVT2S:
+#endif
+#ifdef I486
+ case IFLOADS: case IFMOVES:
#endif
#if 1
if (instruction->instruction_parameters[1].parameter_type==P_REGISTER ||