summaryrefslogtreecommitdiff
path: root/cginstructions.c
diff options
context:
space:
mode:
authorJohn van Groningen2012-02-23 11:52:58 +0000
committerJohn van Groningen2012-02-23 11:52:58 +0000
commit0f45876d1b3f9cd78ac00b006df1c10ba6049c2f (patch)
tree263d4a9cb0e7a5df27892850d0295de22b310674 /cginstructions.c
parentsave/restore r9 in c call code (without G) on Mac OS X with THREAD64 defined (diff)
in foreign export of 64 bit thread safe code, load global registers for clean before copying strings or arrays
Diffstat (limited to 'cginstructions.c')
-rw-r--r--cginstructions.c235
1 files changed, 127 insertions, 108 deletions
diff --git a/cginstructions.c b/cginstructions.c
index a04cebb..a3960ef 100644
--- a/cginstructions.c
+++ b/cginstructions.c
@@ -5375,6 +5375,49 @@ extern struct instruction *last_instruction;
extern LABEL *INT_label,*BOOL_label,*CHAR_label,*REAL_label;
extern LABEL *cycle_in_spine_label,*reserve_label;
void code_jsr_from_c_to_clean (char *label_name);
+
+static void load_constant_registers (void)
+{
+ /*
+ lea a5,__cycle__in__spine
+ lea int_reg,INT2
+ lea char_reg,CHAR2
+ lea real_reg,REAL2
+ lea bool_reg,BOOL2
+ */
+
+ if (INT_label==NULL)
+ INT_label=enter_label ("INT",IMPORT_LABEL | DATA_LABEL);
+ i_lea_l_i_r (INT_label,2,INT_REGISTER);
+
+ if (CHAR_label==NULL)
+ CHAR_label=enter_label ("CHAR",IMPORT_LABEL | DATA_LABEL);
+ i_lea_l_i_r (CHAR_label,2,CHAR_REGISTER);
+
+ if (REAL_label==NULL)
+ REAL_label=enter_label ("REAL",IMPORT_LABEL | DATA_LABEL);
+ i_lea_l_i_r (REAL_label,2,REAL_REGISTER);
+
+ if (BOOL_label==NULL)
+ BOOL_label=enter_label ("BOOL",IMPORT_LABEL | DATA_LABEL);
+ i_lea_l_i_r (BOOL_label,2,BOOL_REGISTER);
+
+ if (!parallel_flag){
+ if (cycle_in_spine_label==NULL){
+ cycle_in_spine_label=enter_label ("__cycle__in__spine",IMPORT_LABEL | NODE_ENTRY_LABEL);
+ cycle_in_spine_label->label_arity=0;
+ cycle_in_spine_label->label_descriptor=EMPTY_label;
+ }
+ i_lea_l_i_r (cycle_in_spine_label,0,REGISTER_A5);
+ } else {
+ if (reserve_label==NULL){
+ reserve_label=enter_label ("__reserve",IMPORT_LABEL | NODE_ENTRY_LABEL);
+ reserve_label->label_arity=0;
+ reserve_label->label_descriptor=EMPTY_label;
+ }
+ i_lea_l_i_r (reserve_label,0,REGISTER_A5);
+ }
+}
#endif
static void save_registers_before_clean_call (void)
@@ -5546,6 +5589,79 @@ static void restore_registers_after_clean_call (void)
#endif
}
+#ifdef THREAD64
+static void insert_loads_of_r9_rsi_rdi_and_r15_before_call (struct basic_block *block_with_call)
+{
+ /* hack to load r9, rsi, rdi and r15 before jmp or call */
+ struct instruction *instruction1,*instruction2,*instruction3,*instruction4,*jmp_or_call_instruction,*old_second_last_instruction;
+
+ /* LDTLSP tlsp_tls_index_label,r9 */
+
+ instruction1=(struct instruction*)fast_memory_allocate (sizeof (struct instruction)+2*sizeof (struct parameter));
+ instruction1->instruction_icode=ILDTLSP;
+ instruction1->instruction_arity=2;
+ instruction1->instruction_parameters[0].parameter_type=P_LABEL;
+ instruction1->instruction_parameters[0].parameter_data.l=tlsp_tls_index_label;
+ instruction1->instruction_parameters[1].parameter_type=P_REGISTER;
+ instruction1->instruction_parameters[1].parameter_data.i=-4/*R9*/;
+
+ jmp_or_call_instruction=block_with_call->block_last_instruction;
+ old_second_last_instruction=jmp_or_call_instruction->instruction_prev;
+
+ if (old_second_last_instruction==NULL)
+ block_with_call->block_instructions=instruction1;
+ else
+ old_second_last_instruction->instruction_next=instruction1;
+ instruction1->instruction_prev=old_second_last_instruction;
+
+ /* i_move_id_r (SAVED_A_STACK_P_OFFSET,R9,-6 */ /*RSI*/ /*); */
+
+ instruction2=(struct instruction*)fast_memory_allocate (sizeof (struct instruction)+2*sizeof (struct parameter));
+ instruction2->instruction_icode=IMOVE;
+ instruction2->instruction_arity=2;
+ instruction2->instruction_parameters[0].parameter_type=P_INDIRECT;
+ instruction2->instruction_parameters[0].parameter_offset=SAVED_A_STACK_P_OFFSET;
+ instruction2->instruction_parameters[0].parameter_data.i=-4/*R9*/;
+ instruction2->instruction_parameters[1].parameter_type=P_REGISTER;
+ instruction2->instruction_parameters[1].parameter_data.i=-6/*RSI*/;
+
+ instruction1->instruction_next=instruction2;
+ instruction2->instruction_prev=instruction1;
+
+ /* i_move_id_r (SAVED_R15_OFFSET,R9,REGISTER_D7); */
+
+ instruction3=(struct instruction*)fast_memory_allocate (sizeof (struct instruction)+2*sizeof (struct parameter));
+ instruction3->instruction_icode=IMOVE;
+ instruction3->instruction_arity=2;
+ instruction3->instruction_parameters[0].parameter_type=P_INDIRECT;
+ instruction3->instruction_parameters[0].parameter_offset=SAVED_R15_OFFSET;
+ instruction3->instruction_parameters[0].parameter_data.i=-4/*R9*/;
+ instruction3->instruction_parameters[1].parameter_type=P_REGISTER;
+ instruction3->instruction_parameters[1].parameter_data.i=REGISTER_D7;
+
+ instruction2->instruction_next=instruction3;
+ instruction3->instruction_prev=instruction2;
+
+ /* i_move_id_r (SAVED_HEAP_P_OFFSET,R9,-7 */ /*RDI*/ /*); */
+
+ instruction4=(struct instruction*)fast_memory_allocate (sizeof (struct instruction)+2*sizeof (struct parameter));
+ instruction4->instruction_icode=IMOVE;
+ instruction4->instruction_arity=2;
+ instruction4->instruction_parameters[0].parameter_type=P_INDIRECT;
+ instruction4->instruction_parameters[0].parameter_offset=SAVED_HEAP_P_OFFSET;
+ instruction4->instruction_parameters[0].parameter_data.i=-4/*R9*/;
+ instruction4->instruction_parameters[1].parameter_type=P_REGISTER;
+ instruction4->instruction_parameters[1].parameter_data.i=-7 /*RDI*/;
+
+ instruction3->instruction_next=instruction4;
+ instruction4->instruction_prev=instruction3;
+
+ instruction4->instruction_next=jmp_or_call_instruction;
+ jmp_or_call_instruction->instruction_prev=instruction4;
+}
+#endif
+
+
#ifdef I486
# ifdef G_AI64
# define REGISTER_EBP_OR_RBP (-5)
@@ -5793,6 +5909,14 @@ void code_centry (char *c_function_name,char *clean_function_label,char *s,int l
if (n_string_or_array_parameters!=0){
int i,offset;
+# ifdef THREAD64
+ instruction_l_r (ILDTLSP,tlsp_tls_index_label,-4/*R9*/);
+
+ i_move_id_r (SAVED_A_STACK_P_OFFSET,-4/*R9*/,A_STACK_POINTER);
+ i_move_id_r (SAVED_R15_OFFSET,-4/*R9*/,REGISTER_D7);
+ i_move_id_r (SAVED_HEAP_P_OFFSET,-4/*R9*/,-7/*RDI*/);
+# endif
+
# if defined (G_A64)
offset=((18+1+n_integer_parameters+n_string_or_array_parameters)<<STACK_ELEMENT_LOG_SIZE)+(n_float_parameters<<3);
# else
@@ -5974,46 +6098,7 @@ void code_centry (char *c_function_name,char *clean_function_label,char *s,int l
code_d (n_string_or_array_parameters,n_integer_and_float_parameters,vector_p);
#ifdef G_POWER
- /*
- lea a5,__cycle__in__spine
- lea int_reg,INT2
- lea char_reg,CHAR2
- lea real_reg,REAL2
- lea bool_reg,BOOL2
- */
-
- if (INT_label==NULL)
- INT_label=enter_label ("INT",IMPORT_LABEL | DATA_LABEL);
- i_lea_l_i_r (INT_label,2,INT_REGISTER);
-
- if (CHAR_label==NULL)
- CHAR_label=enter_label ("CHAR",IMPORT_LABEL | DATA_LABEL);
- i_lea_l_i_r (CHAR_label,2,CHAR_REGISTER);
-
- if (REAL_label==NULL)
- REAL_label=enter_label ("REAL",IMPORT_LABEL | DATA_LABEL);
- i_lea_l_i_r (REAL_label,2,REAL_REGISTER);
-
- if (BOOL_label==NULL)
- BOOL_label=enter_label ("BOOL",IMPORT_LABEL | DATA_LABEL);
- i_lea_l_i_r (BOOL_label,2,BOOL_REGISTER);
-
- if (!parallel_flag){
- if (cycle_in_spine_label==NULL){
- cycle_in_spine_label=enter_label ("__cycle__in__spine",IMPORT_LABEL | NODE_ENTRY_LABEL);
- cycle_in_spine_label->label_arity=0;
- cycle_in_spine_label->label_descriptor=EMPTY_label;
- }
- i_lea_l_i_r (cycle_in_spine_label,0,REGISTER_A5);
- } else {
- if (reserve_label==NULL){
- reserve_label=enter_label ("__reserve",IMPORT_LABEL | NODE_ENTRY_LABEL);
- reserve_label->label_arity=0;
- reserve_label->label_descriptor=EMPTY_label;
- }
- i_lea_l_i_r (reserve_label,0,REGISTER_A5);
- }
-
+ load_constant_registers();
code_jsr_from_c_to_clean (clean_function_label);
#else
code_jsr (clean_function_label);
@@ -6175,74 +6260,8 @@ void code_centry (char *c_function_name,char *clean_function_label,char *s,int l
float_c_function_result ? r_vector : i_vector,N_ADDRESS_PARAMETER_REGISTERS);
# ifdef THREAD64
- {
- /* hack to load r9, rsi, rdi and r15 before jmp or call */
- struct instruction *instruction1,*instruction2,*instruction3,*instruction4,*jmp_or_call_instruction,*old_second_last_instruction;
-
- /* LDTLSP tlsp_tls_index_label,r9 */
-
- instruction1=(struct instruction*)fast_memory_allocate (sizeof (struct instruction)+2*sizeof (struct parameter));
- instruction1->instruction_icode=ILDTLSP;
- instruction1->instruction_arity=2;
- instruction1->instruction_parameters[0].parameter_type=P_LABEL;
- instruction1->instruction_parameters[0].parameter_data.l=tlsp_tls_index_label;
- instruction1->instruction_parameters[1].parameter_type=P_REGISTER;
- instruction1->instruction_parameters[1].parameter_data.i=-4/*R9*/;
-
- jmp_or_call_instruction=block_with_call->block_last_instruction;
- old_second_last_instruction=jmp_or_call_instruction->instruction_prev;
-
- if (old_second_last_instruction==NULL)
- block_with_call->block_instructions=instruction1;
- else
- old_second_last_instruction->instruction_next=instruction1;
- instruction1->instruction_prev=old_second_last_instruction;
-
- /* i_move_id_r (SAVED_A_STACK_P_OFFSET,R9,-6 */ /*RSI*/ /*); */
-
- instruction2=(struct instruction*)fast_memory_allocate (sizeof (struct instruction)+2*sizeof (struct parameter));
- instruction2->instruction_icode=IMOVE;
- instruction2->instruction_arity=2;
- instruction2->instruction_parameters[0].parameter_type=P_INDIRECT;
- instruction2->instruction_parameters[0].parameter_offset=SAVED_A_STACK_P_OFFSET;
- instruction2->instruction_parameters[0].parameter_data.i=-4/*R9*/;
- instruction2->instruction_parameters[1].parameter_type=P_REGISTER;
- instruction2->instruction_parameters[1].parameter_data.i=-6/*RSI*/;
-
- instruction1->instruction_next=instruction2;
- instruction2->instruction_prev=instruction1;
-
- /* i_move_id_r (SAVED_R15_OFFSET,R9,REGISTER_D7); */
-
- instruction3=(struct instruction*)fast_memory_allocate (sizeof (struct instruction)+2*sizeof (struct parameter));
- instruction3->instruction_icode=IMOVE;
- instruction3->instruction_arity=2;
- instruction3->instruction_parameters[0].parameter_type=P_INDIRECT;
- instruction3->instruction_parameters[0].parameter_offset=SAVED_R15_OFFSET;
- instruction3->instruction_parameters[0].parameter_data.i=-4/*R9*/;
- instruction3->instruction_parameters[1].parameter_type=P_REGISTER;
- instruction3->instruction_parameters[1].parameter_data.i=REGISTER_D7;
-
- instruction2->instruction_next=instruction3;
- instruction3->instruction_prev=instruction2;
-
- /* i_move_id_r (SAVED_HEAP_P_OFFSET,R9,-7 */ /*RDI*/ /*); */
-
- instruction4=(struct instruction*)fast_memory_allocate (sizeof (struct instruction)+2*sizeof (struct parameter));
- instruction4->instruction_icode=IMOVE;
- instruction4->instruction_arity=2;
- instruction4->instruction_parameters[0].parameter_type=P_INDIRECT;
- instruction4->instruction_parameters[0].parameter_offset=SAVED_HEAP_P_OFFSET;
- instruction4->instruction_parameters[0].parameter_data.i=-4/*R9*/;
- instruction4->instruction_parameters[1].parameter_type=P_REGISTER;
- instruction4->instruction_parameters[1].parameter_data.i=-7 /*RDI*/;
-
- instruction3->instruction_next=instruction4;
- instruction4->instruction_prev=instruction3;
-
- instruction4->instruction_next=jmp_or_call_instruction;
- jmp_or_call_instruction->instruction_prev=instruction4;
- }
+ if (n_string_or_array_parameters==0)
+ insert_loads_of_r9_rsi_rdi_and_r15_before_call (block_with_call);
# endif
#if ! (defined (sparc) || defined (G_POWER))