summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cginstructions.c227
1 files changed, 177 insertions, 50 deletions
diff --git a/cginstructions.c b/cginstructions.c
index 942d1d0..b2c2b20 100644
--- a/cginstructions.c
+++ b/cginstructions.c
@@ -58,8 +58,9 @@ extern int offered_b_stack_size;
extern LABEL *enter_label (char *label_name,int label_flags);
extern LABEL *new_local_label (int label_flags);
-extern LABEL * system_sp_label,*new_int_reducer_label,*channelP_label,*stop_reducer_label,
- *send_request_label,*send_graph_label,*string_to_string_node_label;
+extern LABEL * system_sp_label,
+ *string_to_string_node_label,*int_array_to_node_label,*real_array_to_node_label,
+ *new_int_reducer_label,*channelP_label,*stop_reducer_label,*send_request_label,*send_graph_label;
#if defined (I486) || defined (G_POWER)
LABEL *saved_heap_p_label,*saved_a_stack_p_label;
@@ -2566,6 +2567,15 @@ void code_ccall (char *c_function_name,char *s,int length)
case 'S':
a_result_offset+=STACK_ELEMENT_SIZE;
continue;
+ case 'A':
+ ++l;
+ if (l<length && (s[l]=='i' || s[l]=='r')){
+ a_result_offset+=STACK_ELEMENT_SIZE;
+ continue;
+ } else {
+ error_s (ccall_error_string,c_function_name);
+ break;
+ }
case ':':
if (l==min_index+1 || l==length-1)
error_s (ccall_error_string,c_function_name);
@@ -2645,6 +2655,8 @@ void code_ccall (char *c_function_name,char *s,int length)
first_pointer_result_index=min_index+1;
} else {
result=s[min_index+1];
+ first_pointer_result_index=min_index+2;
+
switch (result){
case 'I':
case 'p':
@@ -2654,11 +2666,12 @@ void code_ccall (char *c_function_name,char *s,int length)
b_result_offset-=8;
break;
case 'S':
+ a_result_offset-=STACK_ELEMENT_SIZE;
+ break;
case 'A':
a_result_offset-=STACK_ELEMENT_SIZE;
-
+ ++first_pointer_result_index;
}
- first_pointer_result_index=min_index+2;
}
#endif
@@ -2974,7 +2987,7 @@ void code_ccall (char *c_function_name,char *s,int length)
error_s (ccall_error_string,c_function_name);
}
#elif defined (I486)
-# ifndef G_AI64
+# ifndef G_AI64 /* for I486 && ! G_AI64 */
{
int c_offset_before_pushing_arguments,function_address_reg;
@@ -3003,6 +3016,9 @@ void code_ccall (char *c_function_name,char *s,int length)
i_move_r_pd (REGISTER_A0,B_STACK_POINTER);
c_offset+=STACK_ELEMENT_SIZE;
break;
+ case 'i':
+ case 'r':
+ --l;
case 'S':
i_lea_id_r (a_o+c_offset,B_STACK_POINTER,REGISTER_A0);
i_move_r_pd (REGISTER_A0,B_STACK_POINTER);
@@ -3047,7 +3063,6 @@ void code_ccall (char *c_function_name,char *s,int length)
}
c_offset+=STACK_ELEMENT_SIZE;
break;
-#ifdef I486
case 'r':
{
int offset;
@@ -3079,7 +3094,6 @@ void code_ccall (char *c_function_name,char *s,int length)
c_offset+=4;
break;
}
-#endif
case 'R':
b_o-=8;
i_move_id_pd (b_o+c_offset+4,B_STACK_POINTER,B_STACK_POINTER);
@@ -3206,6 +3220,24 @@ void code_ccall (char *c_function_name,char *s,int length)
i_move_r_id (REGISTER_A0,0,A_STACK_POINTER);
i_add_i_r (STACK_ELEMENT_SIZE,A_STACK_POINTER);
break;
+ case 'i':
+ --l;
+ if (int_array_to_node_label==NULL)
+ int_array_to_node_label=enter_label ("int_array_to_node",IMPORT_LABEL);
+ i_move_pi_r (B_STACK_POINTER,REGISTER_A0);
+ i_jsr_l (int_array_to_node_label,0);
+ i_move_r_id (REGISTER_A0,0,A_STACK_POINTER);
+ i_add_i_r (STACK_ELEMENT_SIZE,A_STACK_POINTER);
+ break;
+ case 'r':
+ --l;
+ if (real_array_to_node_label==NULL)
+ real_array_to_node_label=enter_label ("real_array_to_node",IMPORT_LABEL);
+ i_move_pi_r (B_STACK_POINTER,REGISTER_A0);
+ i_jsr_l (real_array_to_node_label,0);
+ i_move_r_id (REGISTER_A0,0,A_STACK_POINTER);
+ i_add_i_r (STACK_ELEMENT_SIZE,A_STACK_POINTER);
+ break;
case 'V':
break;
default:
@@ -3233,13 +3265,27 @@ void code_ccall (char *c_function_name,char *s,int length)
begin_new_basic_block();
init_a_stack (1);
break;
+ case 'A':
+ i_move_r_r (REGISTER_D0,REGISTER_A0);
+ if (s[min_index+2]=='i'){
+ if (int_array_to_node_label==NULL)
+ int_array_to_node_label=enter_label ("int_array_to_node",IMPORT_LABEL);
+ i_jsr_l (int_array_to_node_label,0);
+ } else if (s[min_index+2]=='r'){
+ if (real_array_to_node_label==NULL)
+ real_array_to_node_label=enter_label ("real_array_to_node",IMPORT_LABEL);
+ i_jsr_l (real_array_to_node_label,0);
+ }
+ begin_new_basic_block();
+ init_a_stack (1);
+ break;
case 'V':
begin_new_basic_block();
break;
default:
error_s (ccall_error_string,c_function_name);
}
-# else /* G_AI64 */
+# else /* for I486 && G_AI64 */
a_o=-b_result_offset-a_result_offset;
b_o=0;
c_fp_parameter_n=0;
@@ -3249,7 +3295,7 @@ void code_ccall (char *c_function_name,char *s,int length)
c_offset=a_result_offset+b_result_offset;
}
-# ifdef LINUX_ELF
+# ifdef LINUX_ELF /* for I486 && G_AI64 && LINUX_ELF */
{
int c_offset_before_pushing_arguments,function_address_reg,c_parameter_n,n_c_parameters,a_stack_pointer,heap_pointer;
unsigned int used_clean_b_parameter_registers;
@@ -3610,7 +3656,7 @@ void code_ccall (char *c_function_name,char *s,int length)
i_move_r_r (a_stack_pointer,A_STACK_POINTER);
i_move_r_r (heap_pointer,HEAP_POINTER);
-# else
+# else /* for I486 && G_AI64 && ! LINUX_ELF */
{
int c_offset_before_pushing_arguments,function_address_reg,c_parameter_n;
@@ -3822,6 +3868,7 @@ void code_ccall (char *c_function_name,char *s,int length)
else
i_lea_id_r (c_offset_before_pushing_arguments-(b_result_offset+a_result_offset),REGISTER_RBP,B_STACK_POINTER);
# endif
+ /* for I486 && G_AI64 */
if (save_state_in_global_variables){
i_lea_l_i_r (saved_heap_p_label,0,-7/*RDI*/);
@@ -3936,7 +3983,9 @@ void code_centry (char *c_function_name,char *clean_function_label,char *s,int l
int first_parameter_index,colon_index,first_result_index;
int n_integer_parameters,n_integer_results,integer_c_function_result;
int n_float_parameters,n_float_results,float_c_function_result;
- int n_string_parameters,n_string_results,string_c_function_result;
+ int n_string_or_array_parameters,n_string_or_array_results;
+ int string_c_function_result,array_c_function_result,string_or_array_c_function_result;
+ int float_parameter_or_result;
if (saved_heap_p_label==NULL)
saved_heap_p_label=enter_label ("saved_heap_p",IMPORT_LABEL);
@@ -3945,10 +3994,11 @@ void code_centry (char *c_function_name,char *clean_function_label,char *s,int l
n_integer_parameters=0;
n_float_parameters=0;
- n_string_parameters=0;
+ n_string_or_array_parameters=0;
n_integer_results=0;
n_float_results=0;
- n_string_results=0;
+ float_parameter_or_result=0;
+ n_string_or_array_results=0;
i=0;
callee_pops_arguments=0;
@@ -3960,6 +4010,7 @@ void code_centry (char *c_function_name,char *clean_function_label,char *s,int l
integer_c_function_result=0;
float_c_function_result=0;
string_c_function_result=0;
+ array_c_function_result=0;
first_parameter_index=i;
@@ -3970,10 +4021,21 @@ void code_centry (char *c_function_name,char *clean_function_label,char *s,int l
if (c=='I')
++n_integer_parameters;
#if defined (I486) && !defined (G_A64)
- else if (c=='R')
+ else if (c=='R'){
++n_float_parameters;
- else if (c=='S')
- ++n_string_parameters;
+ float_parameter_or_result=1;
+ } else if (c=='S')
+ ++n_string_or_array_parameters;
+ else if (c=='A' && i+1<length){
+ c=s[++i];
+ if (c=='i')
+ ++n_string_or_array_parameters;
+ else if (c=='r'){
+ ++n_string_or_array_parameters;
+ float_parameter_or_result=1;
+ } else
+ error_s (centry_error_string,c_function_name);
+ }
#endif
else if (c==':'){
colon_index=i;
@@ -3990,9 +4052,20 @@ void code_centry (char *c_function_name,char *clean_function_label,char *s,int l
} else if (c=='R'){
float_c_function_result=1;
++n_float_results;
+ float_parameter_or_result=1;
} else if (c=='S'){
string_c_function_result=1;
- ++n_string_results;
+ ++n_string_or_array_results;
+ } else if (c=='A' && i+1<length){
+ c=s[++i];
+ ++n_string_or_array_results;
+ if (c=='i'){
+ array_c_function_result=1;
+ } else if (c=='r'){
+ array_c_function_result=1;
+ float_parameter_or_result=1;
+ } else
+ error_s (centry_error_string,c_function_name);
#endif
} else
error_s (centry_error_string,c_function_name);
@@ -4005,10 +4078,21 @@ void code_centry (char *c_function_name,char *clean_function_label,char *s,int l
if (c=='I')
++n_integer_results;
#if defined (I486) && !defined (G_A64)
- else if (c=='R')
+ else if (c=='R'){
++n_float_results;
- else if (c=='S')
- ++n_string_results;
+ float_parameter_or_result=1;
+ } else if (c=='S')
+ ++n_string_or_array_results;
+ else if (c=='A' && i+1<length){
+ c=s[++i];
+ if (c=='i'){
+ ++n_string_or_array_results;
+ } else if (c=='r'){
+ ++n_string_or_array_results;
+ float_parameter_or_result=1;
+ } else
+ error_s (centry_error_string,c_function_name);
+ }
#endif
else
error_s (centry_error_string,c_function_name);
@@ -4021,8 +4105,10 @@ void code_centry (char *c_function_name,char *clean_function_label,char *s,int l
++i;
}
+ string_or_array_c_function_result=string_c_function_result+array_c_function_result;
+
#ifdef I486
- if (n_integer_results==0 && n_float_results==0 && n_string_results==0)
+ if (n_integer_results==0 && n_float_results==0 && n_string_or_array_results==0)
#else
if (n_integer_results!=1)
#endif
@@ -4145,13 +4231,10 @@ void code_centry (char *c_function_name,char *clean_function_label,char *s,int l
# endif
#if defined (I486) && !defined (G_A64)
- if (n_string_parameters!=0){
+ if (n_string_or_array_parameters!=0){
int i,offset;
- if (string_to_string_node_label==NULL)
- string_to_string_node_label=enter_label ("string_to_string_node",IMPORT_LABEL);
-
- offset=24+((n_integer_parameters+n_string_parameters)<<STACK_ELEMENT_LOG_SIZE)+(n_float_parameters<<3);
+ offset=24+((n_integer_parameters+n_string_or_array_parameters)<<STACK_ELEMENT_LOG_SIZE)+(n_float_parameters<<3);
for (i=colon_index-1; i>=first_parameter_index; --i){
char c;
@@ -4162,11 +4245,31 @@ void code_centry (char *c_function_name,char *clean_function_label,char *s,int l
else if (c=='R')
offset-=8;
else if (c=='S'){
+ if (string_to_string_node_label==NULL)
+ string_to_string_node_label=enter_label ("string_to_string_node",IMPORT_LABEL);
offset-=STACK_ELEMENT_SIZE;
i_move_id_r (offset,B_STACK_POINTER,REGISTER_A0);
i_jsr_l (string_to_string_node_label,0);
i_move_r_id (REGISTER_A0,0,A_STACK_POINTER);
i_add_i_r (STACK_ELEMENT_SIZE,A_STACK_POINTER);
+ } else if (c=='i'){
+ --i;
+ if (int_array_to_node_label==NULL)
+ int_array_to_node_label=enter_label ("int_array_to_node",IMPORT_LABEL);
+ offset-=STACK_ELEMENT_SIZE;
+ i_move_id_r (offset,B_STACK_POINTER,REGISTER_A0);
+ i_jsr_l (int_array_to_node_label,0);
+ i_move_r_id (REGISTER_A0,0,A_STACK_POINTER);
+ i_add_i_r (STACK_ELEMENT_SIZE,A_STACK_POINTER);
+ } else if (c=='r'){
+ --i;
+ if (real_array_to_node_label==NULL)
+ real_array_to_node_label=enter_label ("real_array_to_node",IMPORT_LABEL);
+ offset-=STACK_ELEMENT_SIZE;
+ i_move_id_r (offset,B_STACK_POINTER,REGISTER_A0);
+ i_jsr_l (real_array_to_node_label,0);
+ i_move_r_id (REGISTER_A0,0,A_STACK_POINTER);
+ i_add_i_r (STACK_ELEMENT_SIZE,A_STACK_POINTER);
} else
break;
}
@@ -4190,12 +4293,12 @@ void code_centry (char *c_function_name,char *clean_function_label,char *s,int l
init_b_stack (0,e_vector);
#if defined (I486) && !defined (G_A64)
- if (n_string_parameters!=0){
+ if (n_string_or_array_parameters!=0){
int i,offset;
- offset=5+1+(n_integer_and_float_parameters+n_string_parameters-1);
+ offset=5+1+(n_integer_and_float_parameters+n_string_or_array_parameters-1);
- for (i=first_parameter_index; i<colon_index; ++i){
+ for (i=colon_index-1; i>=first_parameter_index; --i){
char c;
c=s[i];
@@ -4206,6 +4309,9 @@ void code_centry (char *c_function_name,char *clean_function_label,char *s,int l
s_push_b (s_get_b (offset));
} else if (c=='S'){
--offset;
+ } else if (c=='i' || c=='r'){
+ --i;
+ --offset;
} else
error ("error in centry");
}
@@ -4242,7 +4348,7 @@ void code_centry (char *c_function_name,char *clean_function_label,char *s,int l
vector_p[i]=0;
}
- if (n_float_parameters>0){
+ if (n_float_parameters!=0){
int i,offset;
i=first_parameter_index;
@@ -4261,12 +4367,17 @@ void code_centry (char *c_function_name,char *clean_function_label,char *s,int l
vector_p[offset>>LOG_SMALL_VECTOR_SIZE] |= (1<< (offset & MASK_SMALL_VECTOR_SIZE));
++offset;
#endif
- } else break;
+ } else if (c=='S')
+ ;
+ else if (c=='A')
+ ++i;
+ else
+ break;
++i;
}
}
- code_d (n_string_parameters,n_integer_and_float_parameters,vector_p);
+ code_d (n_string_or_array_parameters,n_integer_and_float_parameters,vector_p);
#ifdef G_POWER
/*
@@ -4315,12 +4426,12 @@ void code_centry (char *c_function_name,char *clean_function_label,char *s,int l
#endif
{
- int result_pointer_parameter_offset,n_data_results_registers,n_float_results_registers,n_string_results_registers;
+ int result_pointer_parameter_offset,n_data_results_registers,n_float_results_registers,n_string_or_array_results_registers;
#ifdef G_AI64
- result_pointer_parameter_offset=((18+1+4+n_integer_and_float_parameters+n_string_parameters-4)<<STACK_ELEMENT_LOG_SIZE);
+ result_pointer_parameter_offset=((18+1+4+n_integer_and_float_parameters+n_string_or_array_parameters-4)<<STACK_ELEMENT_LOG_SIZE);
#else
- result_pointer_parameter_offset=20+4+((n_integer_and_float_parameters+n_string_parameters)<<STACK_ELEMENT_LOG_SIZE);
+ result_pointer_parameter_offset=20+4+((n_integer_and_float_parameters+n_string_or_array_parameters)<<STACK_ELEMENT_LOG_SIZE);
#endif
if (n_integer_results-integer_c_function_result>N_DATA_PARAMETER_REGISTERS)
result_pointer_parameter_offset+=(n_integer_results-integer_c_function_result-N_DATA_PARAMETER_REGISTERS)<<STACK_ELEMENT_LOG_SIZE;
@@ -4335,16 +4446,16 @@ void code_centry (char *c_function_name,char *clean_function_label,char *s,int l
if (n_float_results_registers>N_FLOAT_PARAMETER_REGISTERS)
n_float_results_registers=N_FLOAT_PARAMETER_REGISTERS;
- n_string_results_registers=n_string_results;
- if (n_string_results_registers>N_ADDRESS_PARAMETER_REGISTERS)
- n_string_results_registers=N_ADDRESS_PARAMETER_REGISTERS;
+ n_string_or_array_results_registers=n_string_or_array_results;
+ if (n_string_or_array_results_registers>N_ADDRESS_PARAMETER_REGISTERS)
+ n_string_or_array_results_registers=N_ADDRESS_PARAMETER_REGISTERS;
{
- int i,data_result_n,float_result_n,result_offset,string_result_n;
+ int i,data_result_n,float_result_n,result_offset,string_or_array_result_n;
float_result_n=float_c_function_result;
data_result_n=integer_c_function_result;
- string_result_n=string_c_function_result;
+ string_or_array_result_n=string_or_array_c_function_result;
i=first_result_index;
result_offset=0;
@@ -4377,16 +4488,30 @@ void code_centry (char *c_function_name,char *clean_function_label,char *s,int l
} else if (c=='S'){
int reg_n;
- if (string_result_n<n_string_results_registers)
- reg_n=REGISTER_A0-(n_string_results_registers-1-string_result_n);
+ if (string_or_array_result_n<n_string_or_array_results_registers)
+ reg_n=REGISTER_A0-(n_string_or_array_results_registers-1-string_or_array_result_n);
else {
- reg_n=REGISTER_A0-string_c_function_result;
+ reg_n=REGISTER_A0-string_or_array_c_function_result;
i_sub_i_r (4,A_STACK_POINTER);
i_move_id_r (0,A_STACK_POINTER,reg_n);
}
i_add_i_r (STACK_ELEMENT_SIZE,reg_n);
i_move_r_id (reg_n,0,-3/*EBP*/);
- ++string_result_n;
+ ++string_or_array_result_n;
+ } else if (c=='A'){
+ int reg_n;
+
+ ++i;
+ if (string_or_array_result_n<n_string_or_array_results_registers)
+ reg_n=REGISTER_A0-(n_string_or_array_results_registers-1-string_or_array_result_n);
+ else {
+ reg_n=REGISTER_A0-string_or_array_c_function_result;
+ i_sub_i_r (4,A_STACK_POINTER);
+ i_move_id_r (0,A_STACK_POINTER,reg_n);
+ }
+ i_add_i_r (STACK_ELEMENT_SIZE*3,reg_n);
+ i_move_r_id (reg_n,0,-3/*EBP*/);
+ ++string_or_array_result_n;
} else
error ("error in centry");
++i;
@@ -4394,7 +4519,7 @@ void code_centry (char *c_function_name,char *clean_function_label,char *s,int l
}
# ifdef I486
- if (n_float_results!=0 || n_float_parameters!=0){
+ if (float_parameter_or_result){
int freg_n;
for (freg_n=float_c_function_result; freg_n<8; ++freg_n){
@@ -4420,11 +4545,13 @@ void code_centry (char *c_function_name,char *clean_function_label,char *s,int l
if (n_data_results_registers>1)
i_move_r_r (n_data_results_registers-1,0);
} else if (string_c_function_result)
- i_lea_id_r (4,REGISTER_A0,REGISTER_D0);
+ i_lea_id_r (STACK_ELEMENT_SIZE,REGISTER_A0,REGISTER_D0);
+ else if (array_c_function_result)
+ i_lea_id_r (STACK_ELEMENT_SIZE*3,REGISTER_A0,REGISTER_D0);
}
if (!float_c_function_result)
- code_o (0,integer_c_function_result+string_c_function_result,i_vector);
+ code_o (0,integer_c_function_result+string_or_array_c_function_result,i_vector);
else
#ifdef G_A64
code_o (0,float_c_function_result,r_vector);
@@ -4498,7 +4625,7 @@ void code_centry (char *c_function_name,char *clean_function_label,char *s,int l
int b_offset,a_stack_size,b_stack_size;
a_stack_size=0;
- b_stack_size=string_c_function_result+integer_c_function_result;
+ b_stack_size=string_or_array_c_function_result+integer_c_function_result;
#ifdef G_A64
b_stack_size+=float_c_function_result;
#else
@@ -4520,8 +4647,8 @@ void code_centry (char *c_function_name,char *clean_function_label,char *s,int l
else
i_sub_i_r (-b_offset,B_STACK_POINTER);
# ifdef I486
- if (callee_pops_arguments && n_integer_and_float_parameters+n_string_parameters>0)
- i_rts_i ((n_integer_and_float_parameters+n_string_parameters)<<2);
+ if (callee_pops_arguments && n_integer_and_float_parameters+n_string_or_array_parameters>0)
+ i_rts_i ((n_integer_and_float_parameters+n_string_or_array_parameters)<<2);
else
# endif
i_rts();