From 28bc807ebe373fec0991ef0219ac1413f8375ac2 Mon Sep 17 00:00:00 2001 From: John van Groningen Date: Fri, 11 Mar 2016 10:45:12 +0000 Subject: move code_ccall for the ARM to new file cgarmc.c --- Makefile.linux_arm | 2 + cgarmc.c | 543 +++++++++++++++++++++++++++++++++++++++++++++++++++++ cginstructions.c | 368 ++---------------------------------- 3 files changed, 558 insertions(+), 355 deletions(-) create mode 100644 cgarmc.c diff --git a/Makefile.linux_arm b/Makefile.linux_arm index 5b32afb..bec90c8 100644 --- a/Makefile.linux_arm +++ b/Makefile.linux_arm @@ -8,6 +8,8 @@ OBJECTS = cg.o cgcalc.o cgcode.o cginput.o cginstructions.o \ cg: $(OBJECTS) gcc -s $(OBJECTS) -o $@ +cginstructions.o : cgarmc.c + clean: rm $(OBJECTS) diff --git a/cgarmc.c b/cgarmc.c new file mode 100644 index 0000000..24936c2 --- /dev/null +++ b/cgarmc.c @@ -0,0 +1,543 @@ + +void code_ccall (char *c_function_name,char *s,int length) +{ + LABEL *label; + int l,min_index; + int a_offset,b_offset,a_result_offset,b_result_offset; + int result,a_o,b_o,float_parameters; + int n_clean_b_register_parameters,clean_b_register_parameter_n; + int n_extra_clean_b_register_parameters; + int first_pointer_result_index,callee_pops_arguments,save_state_in_global_variables; + int function_address_parameter; + int c_offset; + int c_parameter_n; + + function_address_parameter=0; + + if (*s=='G'){ + ++s; + --length; + save_state_in_global_variables=1; + if (saved_heap_p_label==NULL) + saved_heap_p_label=enter_label ("saved_heap_p",IMPORT_LABEL); + if (saved_a_stack_p_label==NULL) + saved_a_stack_p_label=enter_label ("saved_a_stack_p",IMPORT_LABEL); + } else + save_state_in_global_variables=0; + + if (*s=='P'){ + ++s; + --length; + callee_pops_arguments=1; + } else + callee_pops_arguments=0; + + float_parameters=0; + + a_offset=0; + b_offset=0; + n_clean_b_register_parameters=0; + + for (l=0; l=length) + error_s (ccall_error_string,c_function_name); + + a_result_offset=0; + b_result_offset=0; + + n_extra_clean_b_register_parameters=0; + + for (++l; lN_DATA_PARAMETER_REGISTERS){ + n_clean_b_register_parameters=N_DATA_PARAMETER_REGISTERS; + n_extra_clean_b_register_parameters=0; + } else if (n_clean_b_register_parameters+n_extra_clean_b_register_parameters>N_DATA_PARAMETER_REGISTERS) + n_extra_clean_b_register_parameters=N_DATA_PARAMETER_REGISTERS-n_clean_b_register_parameters; + + end_basic_block_with_registers (0,n_clean_b_register_parameters+n_extra_clean_b_register_parameters,e_vector); + + b_offset-=n_clean_b_register_parameters<b_offset){ + i_sub_i_r (a_result_offset+b_result_offset-b_offset,B_STACK_POINTER); + c_offset=a_result_offset+b_result_offset; + } + + c_offset_before_pushing_arguments=c_offset; + + c_parameter_n=((a_offset+b_offset+a_result_offset+b_result_offset)>>STACK_ELEMENT_LOG_SIZE)+n_clean_b_register_parameters; + + i_move_r_r (B_STACK_POINTER,REGISTER_A2); + + if (c_parameter_n>=4 && (c_parameter_n & 1)!=0){ + i_sub_i_r (4,B_STACK_POINTER); + i_or_i_r (4,B_STACK_POINTER); + } else { + i_and_i_r (-8,B_STACK_POINTER); + } + + for (l=length-1; l>=first_pointer_result_index; --l){ + switch (s[l]){ + case 'I': + case 'p': + b_o-=STACK_ELEMENT_SIZE; + if (--c_parameter_n<4) + i_lea_id_r (b_o+c_offset_before_pushing_arguments,REGISTER_A2,REGISTER_D4-c_parameter_n); + else { + i_lea_id_r (b_o+c_offset_before_pushing_arguments,REGISTER_A2,REGISTER_A3); + i_move_r_pd (REGISTER_A3,B_STACK_POINTER); + c_offset+=STACK_ELEMENT_SIZE; + } + break; + case 'i': + case 'r': + --l; + case 'S': + if (--c_parameter_n<4) + i_lea_id_r (a_o+c_offset_before_pushing_arguments,REGISTER_A2,REGISTER_D4-c_parameter_n); + else { + i_lea_id_r (a_o+c_offset_before_pushing_arguments,REGISTER_A2,REGISTER_A3); + i_move_r_pd (REGISTER_A3,B_STACK_POINTER); + c_offset+=STACK_ELEMENT_SIZE; + } + a_o+=STACK_ELEMENT_SIZE; + break; + case 'V': + break; + default: + error_s (ccall_error_string,c_function_name); + } + } + + { + int last_register_parameter_index,reg_n,c_offset_1; + + last_register_parameter_index=-1; + + reg_n=0; + l=0; + while (reg_n=0; --l){ + switch (s[l]){ + case 'I': + case 'p': + case 'S': + case 's': + if (--c_parameter_n_1>=4) + c_offset_1+=STACK_ELEMENT_SIZE; + break; + case 'O': + case 'F': + case '*': + case ']': + while (l>=0 && (s[l]!='F' && s[l]!='O')) + --l; + if (--c_parameter_n_1>=4) + c_offset_1+=STACK_ELEMENT_SIZE; + break; + } + } + + if (c_offset_1!=0){ + i_sub_i_r (c_offset_1,B_STACK_POINTER); + c_offset += c_offset_1; + } + } + + { + int c_parameter_n_2,l,c_offset_2,not_finished,new_reg[5]; + + new_reg[0]=new_reg[1]=new_reg[2]=new_reg[3]=new_reg[4]=-1; /* [0] not used */ + + c_offset_2 = c_offset_1; + c_parameter_n_2 = c_parameter_n; + reg_n=0; + for (l=min_index-1; l>=0; --l){ + switch (s[l]){ + case 'I': + case 'p': + if (--c_parameter_n_2<4){ + if (l<=last_register_parameter_index){ + new_reg [4-c_parameter_n_2] = n_extra_clean_b_register_parameters+reg_n; + ++reg_n; + } + } else { + c_offset_2-=STACK_ELEMENT_SIZE; + if (l<=last_register_parameter_index){ + i_move_r_id (REGISTER_D0+n_extra_clean_b_register_parameters+reg_n,c_offset_2,B_STACK_POINTER); + ++reg_n; + } + } + break; + case 'S': + case 's': + if (--c_parameter_n_2>=4) + c_offset_2-=STACK_ELEMENT_SIZE; + break; + case 'O': + case 'F': + case '*': + case ']': + while (l>=0 && (s[l]!='F' && s[l]!='O')) + --l; + if (--c_parameter_n_2<4){ + if (l<=last_register_parameter_index){ + new_reg [4-c_parameter_n_2] = n_extra_clean_b_register_parameters+reg_n; + ++reg_n; + } + } + break; + } + } + + do { + not_finished=0; + for (reg_n=1; reg_n<=4; ++reg_n){ + int n; + + n=new_reg[reg_n]; + if (n>=0 && n!=reg_n){ + if (new_reg[1]!=reg_n && new_reg[2]!=reg_n && new_reg[3]!=reg_n && new_reg[4]!=reg_n){ + i_move_r_r (REGISTER_D0+n,REGISTER_D0+reg_n); + new_reg[reg_n]=-1; + } else + not_finished=1; + } + } + } while (not_finished); /* infinite loop in case of cycle */ + } + + reg_n=0; + a_o=-a_offset; + b_o=0; + for (l=min_index-1; l>=0; --l){ + switch (s[l]){ + case 'I': + case 'p': + if (--c_parameter_n<4){ + if (l<=last_register_parameter_index){ + /* i_move_r_r (REGISTER_D0+n_extra_clean_b_register_parameters+reg_n,REGISTER_D4-c_parameter_n); */ + ++reg_n; + } else { + b_o-=STACK_ELEMENT_SIZE; + i_move_id_r (b_o+c_offset_before_pushing_arguments,REGISTER_A2,REGISTER_D4-c_parameter_n); + } + } else { + c_offset_1-=STACK_ELEMENT_SIZE; + if (l<=last_register_parameter_index){ + /* i_move_r_id (REGISTER_D0+n_extra_clean_b_register_parameters+reg_n,c_offset_1,B_STACK_POINTER); */ + ++reg_n; + } else { + b_o-=STACK_ELEMENT_SIZE; + i_move_id_r (b_o+c_offset_before_pushing_arguments,REGISTER_A2,6/*r12*/); + i_move_r_id (6/*r12*/,c_offset_1,B_STACK_POINTER); + } + } + break; + case 'S': + if (--c_parameter_n<4){ + i_move_id_r (a_o,A_STACK_POINTER,REGISTER_D4-c_parameter_n); + i_add_i_r (STACK_ELEMENT_SIZE,REGISTER_D4-c_parameter_n); + } else { + c_offset_1-=STACK_ELEMENT_SIZE; + i_move_id_r (a_o,A_STACK_POINTER,REGISTER_A0); + i_add_i_r (STACK_ELEMENT_SIZE,REGISTER_A0); + i_move_r_id (REGISTER_A0,c_offset_1,B_STACK_POINTER); + } + a_o+=STACK_ELEMENT_SIZE; + break; + case 's': + if (--c_parameter_n<4){ + i_move_id_r (a_o,A_STACK_POINTER,REGISTER_D4-c_parameter_n); + i_add_i_r (2*STACK_ELEMENT_SIZE,REGISTER_D4-c_parameter_n); + } else { + c_offset_1-=STACK_ELEMENT_SIZE; + i_move_id_r (a_o,A_STACK_POINTER,REGISTER_A0); + i_add_i_r (2*STACK_ELEMENT_SIZE,REGISTER_A0); + i_move_r_id (REGISTER_A0,c_offset_1,B_STACK_POINTER); + } + a_o+=STACK_ELEMENT_SIZE; + break; + case 'O': + case 'F': + case '*': + case ']': + while (l>=0 && (s[l]!='F' && s[l]!='O')) + --l; + if (--c_parameter_n<4){ + if (l<=last_register_parameter_index){ + /* i_move_r_r (REGISTER_D0+n_extra_clean_b_register_parameters+reg_n,REGISTER_D4-c_parameter_n); */ + ++reg_n; + } else { + b_o-=STACK_ELEMENT_SIZE; + i_move_id_r (b_o+c_offset_before_pushing_arguments,REGISTER_A2,REGISTER_D4-c_parameter_n); + } + + function_address_reg = REGISTER_D4-c_parameter_n; + function_address_s_index = l+1; + break; + } + default: + error_s (ccall_error_string,c_function_name); + } + } + } + + if (save_state_in_global_variables){ + i_lea_l_i_r (saved_a_stack_p_label,0,REGISTER_D6); + i_move_r_id (A_STACK_POINTER,0,REGISTER_D6); + i_lea_l_i_r (saved_heap_p_label,0,REGISTER_D6); + i_move_r_id (HEAP_POINTER,0,REGISTER_D6); + i_move_r_id (REGISTER_D5,4,REGISTER_D6); + } + + if (!function_address_parameter) + i_call_l (label); + else { + int l; + + for (l=function_address_s_index; l=first_pointer_result_index; --l){ + switch (s[l]){ + case 'I': + case 'p': + case 'R': + case 'V': + break; + case 'S': + if (string_to_string_node_label==NULL) + string_to_string_node_label=enter_label ("string_to_string_node",IMPORT_LABEL); + i_move_pi_r (B_STACK_POINTER,REGISTER_A0); + i_jsr_l_idu (string_to_string_node_label,-4); + i_move_r_id (REGISTER_A0,0,A_STACK_POINTER); + i_add_i_r (STACK_ELEMENT_SIZE,A_STACK_POINTER); + break; + default: + error_s (ccall_error_string,c_function_name); + } + } + + b_o=0; + for (l=first_pointer_result_index; l'){ ++l; n_b_c_in_clean_out_parameters_size+=STACK_ELEMENT_SIZE; } # endif continue; -# if defined (I486) || defined (ARM) || defined (G_POWER) +# if defined (I486) || defined (G_POWER) case 'r': # endif case 'R': @@ -3819,7 +3823,7 @@ void code_ccall (char *c_function_name,char *s,int length) case 's': case 'A': a_offset+=STACK_ELEMENT_SIZE; -# if (defined (I486) || defined (ARM)) && !defined (G_AI64) +# if defined (I486) && !defined (G_AI64) if (s[l+1]=='>'){ ++l; n_a_c_in_clean_out_parameters_size+=STACK_ELEMENT_SIZE; @@ -5467,357 +5471,11 @@ void code_ccall (char *c_function_name,char *s,int length) } # endif -#elif defined (ARM) - - { - int c_offset_before_pushing_arguments,function_address_reg,function_address_s_index,c_parameter_n; - - a_o=-b_result_offset-a_result_offset; - b_o=0; - - if (a_result_offset+b_result_offset>b_offset){ - i_sub_i_r (a_result_offset+b_result_offset-b_offset,B_STACK_POINTER); - c_offset=a_result_offset+b_result_offset; - } - - c_offset_before_pushing_arguments=c_offset; - - c_parameter_n=((a_offset+b_offset+a_result_offset+b_result_offset)>>STACK_ELEMENT_LOG_SIZE)+n_clean_b_register_parameters; - - i_move_r_r (B_STACK_POINTER,REGISTER_A2); - - if (c_parameter_n>=4 && (c_parameter_n & 1)!=0){ - i_sub_i_r (4,B_STACK_POINTER); - i_or_i_r (4,B_STACK_POINTER); - } else { - i_and_i_r (-8,B_STACK_POINTER); - } - - for (l=length-1; l>=first_pointer_result_index; --l){ - switch (s[l]){ - case 'I': - case 'p': - b_o-=STACK_ELEMENT_SIZE; - if (--c_parameter_n<4) - i_lea_id_r (b_o+c_offset_before_pushing_arguments,REGISTER_A2,REGISTER_D4-c_parameter_n); - else { - i_lea_id_r (b_o+c_offset_before_pushing_arguments,REGISTER_A2,REGISTER_A3); - i_move_r_pd (REGISTER_A3,B_STACK_POINTER); - c_offset+=STACK_ELEMENT_SIZE; - } - break; - case 'i': - case 'r': - --l; - case 'S': - if (--c_parameter_n<4) - i_lea_id_r (a_o+c_offset_before_pushing_arguments,REGISTER_A2,REGISTER_D4-c_parameter_n); - else { - i_lea_id_r (a_o+c_offset_before_pushing_arguments,REGISTER_A2,REGISTER_A3); - i_move_r_pd (REGISTER_A3,B_STACK_POINTER); - c_offset+=STACK_ELEMENT_SIZE; - } - a_o+=STACK_ELEMENT_SIZE; - break; - case 'V': - break; - default: - error_s (ccall_error_string,c_function_name); - } - } - - { - int last_register_parameter_index,reg_n,c_offset_1; - - last_register_parameter_index=-1; - - reg_n=0; - l=0; - while (reg_n=0; --l){ - switch (s[l]){ - case 'I': - case 'p': - case 'S': - case 's': - if (--c_parameter_n_1>=4) - c_offset_1+=STACK_ELEMENT_SIZE; - break; - case 'O': - case 'F': - case '*': - case ']': - while (l>=0 && (s[l]!='F' && s[l]!='O')) - --l; - if (--c_parameter_n_1>=4) - c_offset_1+=STACK_ELEMENT_SIZE; - break; - } - } - - if (c_offset_1!=0){ - i_sub_i_r (c_offset_1,B_STACK_POINTER); - c_offset += c_offset_1; - } - } - - { - int c_parameter_n_2,l,c_offset_2,not_finished,new_reg[5]; - - new_reg[0]=new_reg[1]=new_reg[2]=new_reg[3]=new_reg[4]=-1; /* [0] not used */ - - c_offset_2 = c_offset_1; - c_parameter_n_2 = c_parameter_n; - reg_n=0; - for (l=min_index-1; l>=0; --l){ - switch (s[l]){ - case 'I': - case 'p': - if (--c_parameter_n_2<4){ - if (l<=last_register_parameter_index){ - new_reg [4-c_parameter_n_2] = n_extra_clean_b_register_parameters+reg_n; - ++reg_n; - } - } else { - c_offset_2-=STACK_ELEMENT_SIZE; - if (l<=last_register_parameter_index){ - i_move_r_id (REGISTER_D0+n_extra_clean_b_register_parameters+reg_n,c_offset_2,B_STACK_POINTER); - ++reg_n; - } - } - break; - case 'S': - case 's': - if (--c_parameter_n_2>=4) - c_offset_2-=STACK_ELEMENT_SIZE; - break; - case 'O': - case 'F': - case '*': - case ']': - while (l>=0 && (s[l]!='F' && s[l]!='O')) - --l; - if (--c_parameter_n_2<4){ - if (l<=last_register_parameter_index){ - new_reg [4-c_parameter_n_2] = n_extra_clean_b_register_parameters+reg_n; - ++reg_n; - } - } - break; - } - } - - do { - not_finished=0; - for (reg_n=1; reg_n<=4; ++reg_n){ - int n; - - n=new_reg[reg_n]; - if (n>=0 && n!=reg_n){ - if (new_reg[1]!=reg_n && new_reg[2]!=reg_n && new_reg[3]!=reg_n && new_reg[4]!=reg_n){ - i_move_r_r (REGISTER_D0+n,REGISTER_D0+reg_n); - new_reg[reg_n]=-1; - } else - not_finished=1; - } - } - } while (not_finished); /* infinite loop in case of cycle */ - } - - reg_n=0; - a_o=-a_offset; - b_o=0; - for (l=min_index-1; l>=0; --l){ - switch (s[l]){ - case 'I': - case 'p': - if (--c_parameter_n<4){ - if (l<=last_register_parameter_index){ - /* i_move_r_r (REGISTER_D0+n_extra_clean_b_register_parameters+reg_n,REGISTER_D4-c_parameter_n); */ - ++reg_n; - } else { - b_o-=STACK_ELEMENT_SIZE; - i_move_id_r (b_o+c_offset_before_pushing_arguments,REGISTER_A2,REGISTER_D4-c_parameter_n); - } - } else { - c_offset_1-=STACK_ELEMENT_SIZE; - if (l<=last_register_parameter_index){ - /* i_move_r_id (REGISTER_D0+n_extra_clean_b_register_parameters+reg_n,c_offset_1,B_STACK_POINTER); */ - ++reg_n; - } else { - b_o-=STACK_ELEMENT_SIZE; - i_move_id_r (b_o+c_offset_before_pushing_arguments,REGISTER_A2,6/*r12*/); - i_move_r_id (6/*r12*/,c_offset_1,B_STACK_POINTER); - } - } - break; - case 'S': - if (--c_parameter_n<4){ - i_move_id_r (a_o,A_STACK_POINTER,REGISTER_D4-c_parameter_n); - i_add_i_r (STACK_ELEMENT_SIZE,REGISTER_D4-c_parameter_n); - } else { - c_offset_1-=STACK_ELEMENT_SIZE; - i_move_id_r (a_o,A_STACK_POINTER,REGISTER_A0); - i_add_i_r (STACK_ELEMENT_SIZE,REGISTER_A0); - i_move_r_id (REGISTER_A0,c_offset_1,B_STACK_POINTER); - } - a_o+=STACK_ELEMENT_SIZE; - break; - case 's': - if (--c_parameter_n<4){ - i_move_id_r (a_o,A_STACK_POINTER,REGISTER_D4-c_parameter_n); - i_add_i_r (2*STACK_ELEMENT_SIZE,REGISTER_D4-c_parameter_n); - } else { - c_offset_1-=STACK_ELEMENT_SIZE; - i_move_id_r (a_o,A_STACK_POINTER,REGISTER_A0); - i_add_i_r (2*STACK_ELEMENT_SIZE,REGISTER_A0); - i_move_r_id (REGISTER_A0,c_offset_1,B_STACK_POINTER); - } - a_o+=STACK_ELEMENT_SIZE; - break; - case 'O': - case 'F': - case '*': - case ']': - while (l>=0 && (s[l]!='F' && s[l]!='O')) - --l; - if (--c_parameter_n<4){ - if (l<=last_register_parameter_index){ - /* i_move_r_r (REGISTER_D0+n_extra_clean_b_register_parameters+reg_n,REGISTER_D4-c_parameter_n); */ - ++reg_n; - } else { - b_o-=STACK_ELEMENT_SIZE; - i_move_id_r (b_o+c_offset_before_pushing_arguments,REGISTER_A2,REGISTER_D4-c_parameter_n); - } - - function_address_reg = REGISTER_D4-c_parameter_n; - function_address_s_index = l+1; - break; - } - default: - error_s (ccall_error_string,c_function_name); - } - } - } - - if (save_state_in_global_variables){ - i_lea_l_i_r (saved_a_stack_p_label,0,REGISTER_D6); - i_move_r_id (A_STACK_POINTER,0,REGISTER_D6); - i_lea_l_i_r (saved_heap_p_label,0,REGISTER_D6); - i_move_r_id (HEAP_POINTER,0,REGISTER_D6); - i_move_r_id (REGISTER_D5,4,REGISTER_D6); - } - - if (!function_address_parameter) - i_call_l (label); - else { - int l; - - for (l=function_address_s_index; l=first_pointer_result_index; --l){ - switch (s[l]){ - case 'I': - case 'p': - case 'R': - case 'V': - break; - case 'S': - if (string_to_string_node_label==NULL) - string_to_string_node_label=enter_label ("string_to_string_node",IMPORT_LABEL); - i_move_pi_r (B_STACK_POINTER,REGISTER_A0); - i_jsr_l_idu (string_to_string_node_label,-4); - i_move_r_id (REGISTER_A0,0,A_STACK_POINTER); - i_add_i_r (STACK_ELEMENT_SIZE,A_STACK_POINTER); - break; - default: - error_s (ccall_error_string,c_function_name); - } - } - - b_o=0; - for (l=first_pointer_result_index; l