summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cginstructions.c27
-rw-r--r--cglin.c13
-rw-r--r--cglin.h3
3 files changed, 42 insertions, 1 deletions
diff --git a/cginstructions.c b/cginstructions.c
index 495f506..f924ff2 100644
--- a/cginstructions.c
+++ b/cginstructions.c
@@ -3486,7 +3486,7 @@ void code_ccall (char *c_function_name,char *s,int length)
if (!float_parameters)
++n_clean_b_register_parameters;
continue;
-# if (defined (I486) && !defined (G_AI64)) || defined (G_POWER)
+# if defined (I486) || defined (G_POWER)
case 'r':
# endif
case 'R':
@@ -4483,6 +4483,19 @@ void code_ccall (char *c_function_name,char *s,int length)
c_offset+=STACK_ELEMENT_SIZE;
}
break;
+ case 'r':
+ b_o-=8;
+ if (c_fp_parameter_n<8){
+ i_fcvt2s_id_fr (b_o+c_offset_before_pushing_arguments,REGISTER_RBP,c_fp_parameter_n);
+ ++c_fp_parameter_n;
+ } else {
+ /* xmm8 is a 64 bit linux ABI scratch register */
+ i_fcvt2s_id_fr (b_o+c_offset_before_pushing_arguments,REGISTER_RBP,8);
+ i_fmoves_fr_id (8,-8,B_STACK_POINTER);
+ i_sub_i_r (8,B_STACK_POINTER);
+ c_offset+=8;
+ }
+ break;
case 'R':
b_o-=8;
if (c_fp_parameter_n<8){
@@ -4730,6 +4743,18 @@ void code_ccall (char *c_function_name,char *s,int length)
c_offset+=STACK_ELEMENT_SIZE;
}
break;
+ case 'r':
+ b_o-=8;
+ if (--c_parameter_n<4)
+ i_fcvt2s_id_fr (b_o+c_offset_before_pushing_arguments,REGISTER_RBP,c_parameter_n);
+ else {
+ /* xmm4 is a 64 bit windows ABI scratch register */
+ i_fcvt2s_id_fr (b_o+c_offset_before_pushing_arguments,REGISTER_RBP,4);
+ i_fmoves_fr_id (4,-8,B_STACK_POINTER);
+ i_sub_i_r (8,B_STACK_POINTER);
+ c_offset+=8;
+ }
+ break;
case 'R':
b_o-=8;
if (--c_parameter_n<4)
diff --git a/cglin.c b/cglin.c
index 4a85ea5..2bc784a 100644
--- a/cglin.c
+++ b/cglin.c
@@ -417,6 +417,19 @@ void i_fcvt2s_fr_fr (int register_1,int register_2)
set_float_register_parameter (instruction->instruction_parameters[0],register_1);
set_float_register_parameter (instruction->instruction_parameters[1],register_2);
}
+
+void i_fcvt2s_id_fr (int offset,int register_1,int register_2)
+{
+ struct instruction *instruction;
+
+ instruction=i_new_instruction2 (IFCVT2S);
+
+ instruction->instruction_parameters[0].parameter_type=P_INDIRECT;
+ instruction->instruction_parameters[0].parameter_offset=offset;
+ instruction->instruction_parameters[0].parameter_data.i=register_1;
+
+ set_float_register_parameter (instruction->instruction_parameters[1],register_2);
+}
#endif
#ifdef FP_STACK_OPTIMIZATIONS
diff --git a/cglin.h b/cglin.h
index b694706..1b234cb 100644
--- a/cglin.h
+++ b/cglin.h
@@ -68,6 +68,9 @@ void i_beq_l (LABEL *label);
void i_btst_i_r (LONG i,int register_1);
#endif
void i_ext_r (int register_1);
+#ifdef G_AI64
+void i_fcvt2s_id_fr (int offset,int register_1,int register_2);
+#endif
void i_fmove_fr_fr (int register_1,int register_2);
void i_fmove_fr_id (int register_1,int offset,int register_2);
#ifdef M68000