summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn van Groningen2016-03-14 16:09:04 +0000
committerJohn van Groningen2016-03-14 16:09:04 +0000
commitd9104e2918ecec417d7c56aa26c4f2e946902ab0 (patch)
tree728ed88b05e956ce073b446e69aafa882774c89a
parentwaste more time because of the stupid version management system, fix incorrec... (diff)
waste more time because of the stupid version management system, fix incorrect newlines again
-rw-r--r--cgarmc.c1472
1 files changed, 736 insertions, 736 deletions
diff --git a/cgarmc.c b/cgarmc.c
index ad44663..b2537ba 100644
--- a/cgarmc.c
+++ b/cgarmc.c
@@ -1,736 +1,736 @@
-
-#ifdef ANDROID
-# define SOFT_FP_CC
-#endif
-
-#define NO_REG_OR_PAD 128
-#define PAD_4_AFTER 129
-
-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,c_register_parameter_n,c_register_pair_parameter_n,c_parameter_offset;
-#ifndef SOFT_FP_CC
- int c_fp_register_parameter_n;
-#endif
- int c_parameter_padding;
- int previous_word_l;
- unsigned char reg_or_pad[100]; /* 128 = no_reg_or_pad, <128 = reg number, 129 = pad 4 bytes after */
-
- function_address_parameter=0;
-
- if (length>100)
- error_s (ccall_error_string,c_function_name);
-
- for (l=0; l<length; ++l)
- reg_or_pad[l] = NO_REG_OR_PAD;
-
- 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;
- c_register_parameter_n=0;
- c_register_pair_parameter_n=0;
- c_parameter_offset = 0;
- c_parameter_padding = 0;
-#ifndef SOFT_FP_CC
- c_fp_register_parameter_n=0;
-#endif
-
- previous_word_l = -1;
- for (l=0; l<length; ++l){
- switch (s[l]){
- case '-':
- case ':':
- min_index=l;
- break;
- case 'I':
- case 'p':
- if (c_register_parameter_n<4){
- reg_or_pad[l] = c_register_parameter_n;
- if (c_register_parameter_n>=c_register_pair_parameter_n)
- ++c_register_parameter_n;
- else
- c_register_parameter_n=c_register_pair_parameter_n+2;
- } else {
- previous_word_l = l;
- c_parameter_offset+=STACK_ELEMENT_SIZE;
- }
- b_offset+=STACK_ELEMENT_SIZE;
- if (!float_parameters)
- ++n_clean_b_register_parameters;
- continue;
- case 'r':
- if (c_register_parameter_n<4){
- reg_or_pad[l] = c_register_parameter_n;
- if (c_register_parameter_n>=c_register_pair_parameter_n)
- ++c_register_parameter_n;
- else
- c_register_parameter_n=c_register_pair_parameter_n;
- } else {
- previous_word_l = l;
- c_parameter_offset+=STACK_ELEMENT_SIZE;
- }
- float_parameters=1;
- b_offset+=8;
- continue;
- case 'R':
- float_parameters=1;
- b_offset+=8;
-#ifdef SOFT_FP_CC
- if (c_register_parameter_n<4){
- if ((c_register_parameter_n & 1)==0){
- reg_or_pad[l] = c_register_parameter_n;
- c_register_parameter_n+=2;
- c_register_pair_parameter_n = c_register_parameter_n;
- previous_word_l = -1;
- continue;
- } else {
- if (c_register_pair_parameter_n<=c_register_parameter_n)
- c_register_pair_parameter_n = c_register_parameter_n+1;
- if (c_register_pair_parameter_n<4){
- reg_or_pad[l] = c_register_pair_parameter_n;
- c_register_pair_parameter_n+=2;
- previous_word_l = -1;
- continue;
- } else
- c_register_parameter_n=4;
- }
- }
-#else
- if (c_fp_register_parameter_n<8){
- reg_or_pad[l] = c_fp_register_parameter_n++;
- continue;
- }
-#endif
- if (c_parameter_offset & 4){
- if (previous_word_l<0 || reg_or_pad[previous_word_l]!=NO_REG_OR_PAD)
- internal_error_in_function ("code_ccall");
- reg_or_pad[previous_word_l]=PAD_4_AFTER;
- c_parameter_padding+=4;
- c_parameter_offset+=4;
- }
- c_parameter_offset+=8;
- previous_word_l = -1;
- continue;
- case 'S':
- case 's':
- case 'A':
- if (c_register_parameter_n<4){
- reg_or_pad[l] = c_register_parameter_n;
- if (c_register_parameter_n>=c_register_pair_parameter_n)
- ++c_register_parameter_n;
- else
- c_register_parameter_n=c_register_pair_parameter_n+2;
- } else {
- previous_word_l = l;
- c_parameter_offset+=STACK_ELEMENT_SIZE;
- }
- a_offset+=STACK_ELEMENT_SIZE;
- continue;
- case 'O':
- case 'F':
- if (function_address_parameter)
- error_s (ccall_error_string,c_function_name);
- function_address_parameter=s[l];
-
- while (l+1<length && (s[l+1]=='*' || s[l+1]=='[')){
- ++l;
- if (s[l]=='['){
- ++l;
- while (l<length && (unsigned)(s[l]-'0')<(unsigned)10)
- ++l;
- if (!(l<length && s[l]==']'))
- error_s (ccall_error_string,c_function_name);
- }
- }
- b_offset+=STACK_ELEMENT_SIZE;
- if (!float_parameters)
- ++n_clean_b_register_parameters;
- continue;
- default:
- error_s (ccall_error_string,c_function_name);
- }
- break;
- }
- if (l>=length)
- error_s (ccall_error_string,c_function_name);
-
- n_extra_clean_b_register_parameters=0;
-
- for (++l; l<length; ++l){
- switch (s[l]){
- case 'I':
- case 'p':
- continue;
- case 'R':
- float_parameters=1;
- continue;
- case 'S':
- continue;
- case 'A':
- ++l;
- if (l<length && (s[l]=='i' || s[l]=='r')){
- 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);
- else {
- int new_length;
-
- new_length=l;
-
- for (++l; l<length; ++l){
- switch (s[l]){
- case 'I':
- case 'p':
- if (!float_parameters)
- ++n_extra_clean_b_register_parameters;
- break;
- case 'R':
- float_parameters=1;
- break;
- case 'S':
- case 'A':
- continue;
- default:
- error_s (ccall_error_string,c_function_name);
- }
- }
-
- length=new_length;
- }
- break;
- case 'V':
- if (l==min_index+1 && l!=length-1)
- continue;
- default:
- error_s (ccall_error_string,c_function_name);
- }
- }
-
- if (n_clean_b_register_parameters>N_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<<STACK_ELEMENT_LOG_SIZE;
-
- if (n_extra_clean_b_register_parameters!=0)
- push_extra_clean_b_register_parameters (n_extra_clean_b_register_parameters);
-
- c_offset=b_offset;
-
- if (s[min_index]=='-' && length-1!=min_index+1){
- result='V';
- 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':
- case 'R':
- case 'S':
- break;
- case 'A':
- ++first_pointer_result_index;
- }
- }
-
- a_result_offset=0;
- b_result_offset=0;
-
- for (l=first_pointer_result_index; l<length; ++l){
- switch (s[l]){
- case 'I':
- case 'p':
- if (c_register_parameter_n<4){
- reg_or_pad[l] = c_register_parameter_n;
- if (c_register_parameter_n>=c_register_pair_parameter_n)
- ++c_register_parameter_n;
- else
- c_register_parameter_n=c_register_pair_parameter_n+2;
- } else
- c_parameter_offset+=STACK_ELEMENT_SIZE;
- b_result_offset+=STACK_ELEMENT_SIZE;
- continue;
- case 'R':
- if (c_register_parameter_n<4){
- reg_or_pad[l] = c_register_parameter_n;
- if (c_register_parameter_n>=c_register_pair_parameter_n)
- ++c_register_parameter_n;
- else
- c_register_parameter_n=c_register_pair_parameter_n+2;
- } else
- c_parameter_offset+=STACK_ELEMENT_SIZE;
- b_result_offset+=8;
- continue;
- case 'S':
- if (c_register_parameter_n<4){
- reg_or_pad[l] = c_register_parameter_n;
- if (c_register_parameter_n>=c_register_pair_parameter_n)
- ++c_register_parameter_n;
- else
- c_register_parameter_n=c_register_pair_parameter_n+2;
- } else
- c_parameter_offset+=STACK_ELEMENT_SIZE;
- a_result_offset+=STACK_ELEMENT_SIZE;
- continue;
- case 'A':
- if (c_register_parameter_n<4){
- reg_or_pad[l] = c_register_parameter_n;
- if (c_register_parameter_n>=c_register_pair_parameter_n)
- ++c_register_parameter_n;
- else
- c_register_parameter_n=c_register_pair_parameter_n+2;
- } else
- c_parameter_offset+=STACK_ELEMENT_SIZE;
- ++l;
- a_result_offset+=STACK_ELEMENT_SIZE;
- continue;
- }
- }
-
- if (!function_address_parameter)
- label = enter_c_function_name_label (c_function_name);
-
- {
- int c_offset_before_pushing_arguments,function_address_reg,function_address_s_index;
-
- 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;
-
- i_move_r_r (B_STACK_POINTER,REGISTER_A2);
-
- if (c_parameter_offset & 4){
- 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 (reg_or_pad[l]<NO_REG_OR_PAD)
- i_lea_id_r (b_o+c_offset_before_pushing_arguments,REGISTER_A2,REGISTER_D4-reg_or_pad[l]);
- 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 (reg_or_pad[l]<NO_REG_OR_PAD)
- i_lea_id_r (a_o+c_offset_before_pushing_arguments,REGISTER_A2,REGISTER_D4-reg_or_pad[l]);
- 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 'R':
- b_o-=8;
- if (reg_or_pad[l]<NO_REG_OR_PAD)
- i_lea_id_r (b_o+c_offset_before_pushing_arguments,REGISTER_A2,REGISTER_D4-reg_or_pad[l]);
- 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 '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<n_clean_b_register_parameters && l<min_index){
- if (s[l]=='I' || s[l]=='p' || s[l]=='F' || s[l]=='O'){
- ++reg_n;
- last_register_parameter_index=l;
- }
- ++l;
- }
-
- c_offset_1=0;
-
- for (l=min_index-1; l>=0; --l){
- switch (s[l]){
- case 'I':
- case 'p':
- case 'S':
- case 's':
- if (reg_or_pad[l]>=NO_REG_OR_PAD){
- if (reg_or_pad[l]==PAD_4_AFTER)
- c_offset_1+=4;
- c_offset_1+=STACK_ELEMENT_SIZE;
- }
- break;
- case 'R':
- if (reg_or_pad[l]>=NO_REG_OR_PAD)
- c_offset_1+=8;
- break;
- case 'O':
- case 'F':
- case '*':
- case ']':
- while (l>=0 && (s[l]!='F' && s[l]!='O'))
- --l;
- if (reg_or_pad[l]>=NO_REG_OR_PAD)
- 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 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;
- reg_n=0;
- for (l=min_index-1; l>=0; --l){
- switch (s[l]){
- case 'I':
- case 'p':
- if (reg_or_pad[l]<NO_REG_OR_PAD){
- if (l<=last_register_parameter_index){
- new_reg [4-reg_or_pad[l]] = n_extra_clean_b_register_parameters+reg_n;
- ++reg_n;
- }
- } else {
- if (reg_or_pad[l]==PAD_4_AFTER)
- c_offset_2-=4;
- 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 (reg_or_pad[l]>=NO_REG_OR_PAD){
- if (reg_or_pad[l]==PAD_4_AFTER)
- c_offset_2-=4;
- c_offset_2-=STACK_ELEMENT_SIZE;
- }
- break;
- case 'R':
- if (reg_or_pad[l]>=NO_REG_OR_PAD)
- c_offset_2-=8;
- break;
- case 'O':
- case 'F':
- case '*':
- case ']':
- while (l>=0 && (s[l]!='F' && s[l]!='O'))
- --l;
- if (reg_or_pad[l]<NO_REG_OR_PAD){
- if (l<=last_register_parameter_index){
- new_reg [4-reg_or_pad[l]] = 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 (reg_or_pad[l]<NO_REG_OR_PAD){
- if (l<=last_register_parameter_index){
- /* i_move_r_r (REGISTER_D0+n_extra_clean_b_register_parameters+reg_n,REGISTER_D4-reg_or_pad[l]); */
- ++reg_n;
- } else {
- b_o-=STACK_ELEMENT_SIZE;
- i_move_id_r (b_o+c_offset_before_pushing_arguments,REGISTER_A2,REGISTER_D4-reg_or_pad[l]);
- }
- } else {
- if (reg_or_pad[l]==PAD_4_AFTER)
- c_offset_1-=4;
- 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 (reg_or_pad[l]<NO_REG_OR_PAD){
- i_move_id_r (a_o,A_STACK_POINTER,REGISTER_D4-reg_or_pad[l]);
- i_add_i_r (STACK_ELEMENT_SIZE,REGISTER_D4-reg_or_pad[l]);
- } else {
- if (reg_or_pad[l]==PAD_4_AFTER)
- c_offset_1-=4;
- 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 'R':
- if (reg_or_pad[l]<NO_REG_OR_PAD){
- b_o-=8;
-#ifdef SOFT_FP_CC
- i_move_id_r (b_o+c_offset_before_pushing_arguments,REGISTER_A2,REGISTER_D4-reg_or_pad[l]);
- i_move_id_r (b_o+c_offset_before_pushing_arguments+4,REGISTER_A2,REGISTER_D4-(reg_or_pad[l]+1));
-#else
- i_fmove_id_fr (b_o+c_offset_before_pushing_arguments,REGISTER_A2,reg_or_pad[l]);
-#endif
- } else {
- c_offset_1-=8;
- b_o-=8;
- 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);
- i_move_id_r (b_o+c_offset_before_pushing_arguments+4,REGISTER_A2,6/*r12*/);
- i_move_r_id (6/*r12*/,c_offset_1+4,B_STACK_POINTER);
- }
- break;
- case 's':
- if (reg_or_pad[l]<NO_REG_OR_PAD){
- i_move_id_r (a_o,A_STACK_POINTER,REGISTER_D4-reg_or_pad[l]);
- i_add_i_r (2*STACK_ELEMENT_SIZE,REGISTER_D4-reg_or_pad[l]);
- } else {
- if (reg_or_pad[l]==PAD_4_AFTER)
- c_offset_1-=4;
- 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 (reg_or_pad[l]<NO_REG_OR_PAD){
- if (l<=last_register_parameter_index){
- /* i_move_r_r (REGISTER_D0+n_extra_clean_b_register_parameters+reg_n,REGISTER_D4-reg_or_pad[l]); */
- ++reg_n;
- } else {
- b_o-=STACK_ELEMENT_SIZE;
- i_move_id_r (b_o+c_offset_before_pushing_arguments,REGISTER_A2,REGISTER_D4-reg_or_pad[l]);
- }
-
- function_address_reg = REGISTER_D4-reg_or_pad[l];
- 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<length && (s[l]=='*' || s[l]=='['); ++l){
- int n;
-
- n=0;
-
- if (s[l]=='['){
- ++l;
- while (l<length && (unsigned)(s[l]-'0')<(unsigned)10){
- n=n*10+(s[l]-'0');
- ++l;
- }
- }
-
- i_move_id_r (n,function_address_reg,REGISTER_D6);
- function_address_reg = REGISTER_D6;
- }
-
- i_call_r (function_address_reg);
- }
-
- if (save_state_in_global_variables){
- i_lea_l_i_r (saved_a_stack_p_label,0,REGISTER_D6);
- i_move_id_r (0,REGISTER_D6,A_STACK_POINTER);
- i_lea_l_i_r (saved_heap_p_label,0,REGISTER_D6);
- i_move_id_r (0,REGISTER_D6,HEAP_POINTER);
- i_move_id_r (4,REGISTER_D6,REGISTER_D5);
- }
-
- if (c_offset_before_pushing_arguments-(b_result_offset+a_result_offset)==0)
- i_move_r_r (REGISTER_A2,B_STACK_POINTER);
- else
- i_lea_id_r (c_offset_before_pushing_arguments-(b_result_offset+a_result_offset),REGISTER_A2,B_STACK_POINTER);
- }
-
- if (a_offset!=0)
- i_sub_i_r (a_offset,A_STACK_POINTER);
-
- for (l=length-1; 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<length; ++l){
- switch (s[l]){
- case 'I':
- case 'p':
- b_o+=STACK_ELEMENT_SIZE;
- break;
- case 'S':
- case 'V':
- break;
- case 'R':
- b_o+=8;
- break;
- default:
- error_s (ccall_error_string,c_function_name);
- }
- }
-
- switch (result){
- case 'I':
- case 'p':
- begin_new_basic_block();
- init_b_stack (5,i_i_i_i_i_vector);
- s_put_b (4,s_get_b (0));
- s_remove_b();
- s_remove_b();
- s_remove_b();
- s_remove_b();
- break;
- case 'V':
- begin_new_basic_block();
- break;
- case 'R':
- begin_new_basic_block();
-#ifdef SOFT_FP_CC
- init_b_stack (5,i_i_i_i_i_vector);
- s_put_b (3,s_get_b (0));
- s_put_b (4,s_get_b (1));
- s_remove_b();
- s_remove_b();
- s_remove_b();
-#else
- init_b_stack (2,r_vector);
-#endif
- break;
- default:
- error_s (ccall_error_string,c_function_name);
- }
-}
+
+#ifdef ANDROID
+# define SOFT_FP_CC
+#endif
+
+#define NO_REG_OR_PAD 128
+#define PAD_4_AFTER 129
+
+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,c_register_parameter_n,c_register_pair_parameter_n,c_parameter_offset;
+#ifndef SOFT_FP_CC
+ int c_fp_register_parameter_n;
+#endif
+ int c_parameter_padding;
+ int previous_word_l;
+ unsigned char reg_or_pad[100]; /* 128 = no_reg_or_pad, <128 = reg number, 129 = pad 4 bytes after */
+
+ function_address_parameter=0;
+
+ if (length>100)
+ error_s (ccall_error_string,c_function_name);
+
+ for (l=0; l<length; ++l)
+ reg_or_pad[l] = NO_REG_OR_PAD;
+
+ 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;
+ c_register_parameter_n=0;
+ c_register_pair_parameter_n=0;
+ c_parameter_offset = 0;
+ c_parameter_padding = 0;
+#ifndef SOFT_FP_CC
+ c_fp_register_parameter_n=0;
+#endif
+
+ previous_word_l = -1;
+ for (l=0; l<length; ++l){
+ switch (s[l]){
+ case '-':
+ case ':':
+ min_index=l;
+ break;
+ case 'I':
+ case 'p':
+ if (c_register_parameter_n<4){
+ reg_or_pad[l] = c_register_parameter_n;
+ if (c_register_parameter_n>=c_register_pair_parameter_n)
+ ++c_register_parameter_n;
+ else
+ c_register_parameter_n=c_register_pair_parameter_n+2;
+ } else {
+ previous_word_l = l;
+ c_parameter_offset+=STACK_ELEMENT_SIZE;
+ }
+ b_offset+=STACK_ELEMENT_SIZE;
+ if (!float_parameters)
+ ++n_clean_b_register_parameters;
+ continue;
+ case 'r':
+ if (c_register_parameter_n<4){
+ reg_or_pad[l] = c_register_parameter_n;
+ if (c_register_parameter_n>=c_register_pair_parameter_n)
+ ++c_register_parameter_n;
+ else
+ c_register_parameter_n=c_register_pair_parameter_n;
+ } else {
+ previous_word_l = l;
+ c_parameter_offset+=STACK_ELEMENT_SIZE;
+ }
+ float_parameters=1;
+ b_offset+=8;
+ continue;
+ case 'R':
+ float_parameters=1;
+ b_offset+=8;
+#ifdef SOFT_FP_CC
+ if (c_register_parameter_n<4){
+ if ((c_register_parameter_n & 1)==0){
+ reg_or_pad[l] = c_register_parameter_n;
+ c_register_parameter_n+=2;
+ c_register_pair_parameter_n = c_register_parameter_n;
+ previous_word_l = -1;
+ continue;
+ } else {
+ if (c_register_pair_parameter_n<=c_register_parameter_n)
+ c_register_pair_parameter_n = c_register_parameter_n+1;
+ if (c_register_pair_parameter_n<4){
+ reg_or_pad[l] = c_register_pair_parameter_n;
+ c_register_pair_parameter_n+=2;
+ previous_word_l = -1;
+ continue;
+ } else
+ c_register_parameter_n=4;
+ }
+ }
+#else
+ if (c_fp_register_parameter_n<8){
+ reg_or_pad[l] = c_fp_register_parameter_n++;
+ continue;
+ }
+#endif
+ if (c_parameter_offset & 4){
+ if (previous_word_l<0 || reg_or_pad[previous_word_l]!=NO_REG_OR_PAD)
+ internal_error_in_function ("code_ccall");
+ reg_or_pad[previous_word_l]=PAD_4_AFTER;
+ c_parameter_padding+=4;
+ c_parameter_offset+=4;
+ }
+ c_parameter_offset+=8;
+ previous_word_l = -1;
+ continue;
+ case 'S':
+ case 's':
+ case 'A':
+ if (c_register_parameter_n<4){
+ reg_or_pad[l] = c_register_parameter_n;
+ if (c_register_parameter_n>=c_register_pair_parameter_n)
+ ++c_register_parameter_n;
+ else
+ c_register_parameter_n=c_register_pair_parameter_n+2;
+ } else {
+ previous_word_l = l;
+ c_parameter_offset+=STACK_ELEMENT_SIZE;
+ }
+ a_offset+=STACK_ELEMENT_SIZE;
+ continue;
+ case 'O':
+ case 'F':
+ if (function_address_parameter)
+ error_s (ccall_error_string,c_function_name);
+ function_address_parameter=s[l];
+
+ while (l+1<length && (s[l+1]=='*' || s[l+1]=='[')){
+ ++l;
+ if (s[l]=='['){
+ ++l;
+ while (l<length && (unsigned)(s[l]-'0')<(unsigned)10)
+ ++l;
+ if (!(l<length && s[l]==']'))
+ error_s (ccall_error_string,c_function_name);
+ }
+ }
+ b_offset+=STACK_ELEMENT_SIZE;
+ if (!float_parameters)
+ ++n_clean_b_register_parameters;
+ continue;
+ default:
+ error_s (ccall_error_string,c_function_name);
+ }
+ break;
+ }
+ if (l>=length)
+ error_s (ccall_error_string,c_function_name);
+
+ n_extra_clean_b_register_parameters=0;
+
+ for (++l; l<length; ++l){
+ switch (s[l]){
+ case 'I':
+ case 'p':
+ continue;
+ case 'R':
+ float_parameters=1;
+ continue;
+ case 'S':
+ continue;
+ case 'A':
+ ++l;
+ if (l<length && (s[l]=='i' || s[l]=='r')){
+ 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);
+ else {
+ int new_length;
+
+ new_length=l;
+
+ for (++l; l<length; ++l){
+ switch (s[l]){
+ case 'I':
+ case 'p':
+ if (!float_parameters)
+ ++n_extra_clean_b_register_parameters;
+ break;
+ case 'R':
+ float_parameters=1;
+ break;
+ case 'S':
+ case 'A':
+ continue;
+ default:
+ error_s (ccall_error_string,c_function_name);
+ }
+ }
+
+ length=new_length;
+ }
+ break;
+ case 'V':
+ if (l==min_index+1 && l!=length-1)
+ continue;
+ default:
+ error_s (ccall_error_string,c_function_name);
+ }
+ }
+
+ if (n_clean_b_register_parameters>N_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<<STACK_ELEMENT_LOG_SIZE;
+
+ if (n_extra_clean_b_register_parameters!=0)
+ push_extra_clean_b_register_parameters (n_extra_clean_b_register_parameters);
+
+ c_offset=b_offset;
+
+ if (s[min_index]=='-' && length-1!=min_index+1){
+ result='V';
+ 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':
+ case 'R':
+ case 'S':
+ break;
+ case 'A':
+ ++first_pointer_result_index;
+ }
+ }
+
+ a_result_offset=0;
+ b_result_offset=0;
+
+ for (l=first_pointer_result_index; l<length; ++l){
+ switch (s[l]){
+ case 'I':
+ case 'p':
+ if (c_register_parameter_n<4){
+ reg_or_pad[l] = c_register_parameter_n;
+ if (c_register_parameter_n>=c_register_pair_parameter_n)
+ ++c_register_parameter_n;
+ else
+ c_register_parameter_n=c_register_pair_parameter_n+2;
+ } else
+ c_parameter_offset+=STACK_ELEMENT_SIZE;
+ b_result_offset+=STACK_ELEMENT_SIZE;
+ continue;
+ case 'R':
+ if (c_register_parameter_n<4){
+ reg_or_pad[l] = c_register_parameter_n;
+ if (c_register_parameter_n>=c_register_pair_parameter_n)
+ ++c_register_parameter_n;
+ else
+ c_register_parameter_n=c_register_pair_parameter_n+2;
+ } else
+ c_parameter_offset+=STACK_ELEMENT_SIZE;
+ b_result_offset+=8;
+ continue;
+ case 'S':
+ if (c_register_parameter_n<4){
+ reg_or_pad[l] = c_register_parameter_n;
+ if (c_register_parameter_n>=c_register_pair_parameter_n)
+ ++c_register_parameter_n;
+ else
+ c_register_parameter_n=c_register_pair_parameter_n+2;
+ } else
+ c_parameter_offset+=STACK_ELEMENT_SIZE;
+ a_result_offset+=STACK_ELEMENT_SIZE;
+ continue;
+ case 'A':
+ if (c_register_parameter_n<4){
+ reg_or_pad[l] = c_register_parameter_n;
+ if (c_register_parameter_n>=c_register_pair_parameter_n)
+ ++c_register_parameter_n;
+ else
+ c_register_parameter_n=c_register_pair_parameter_n+2;
+ } else
+ c_parameter_offset+=STACK_ELEMENT_SIZE;
+ ++l;
+ a_result_offset+=STACK_ELEMENT_SIZE;
+ continue;
+ }
+ }
+
+ if (!function_address_parameter)
+ label = enter_c_function_name_label (c_function_name);
+
+ {
+ int c_offset_before_pushing_arguments,function_address_reg,function_address_s_index;
+
+ 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;
+
+ i_move_r_r (B_STACK_POINTER,REGISTER_A2);
+
+ if (c_parameter_offset & 4){
+ 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 (reg_or_pad[l]<NO_REG_OR_PAD)
+ i_lea_id_r (b_o+c_offset_before_pushing_arguments,REGISTER_A2,REGISTER_D4-reg_or_pad[l]);
+ 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 (reg_or_pad[l]<NO_REG_OR_PAD)
+ i_lea_id_r (a_o+c_offset_before_pushing_arguments,REGISTER_A2,REGISTER_D4-reg_or_pad[l]);
+ 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 'R':
+ b_o-=8;
+ if (reg_or_pad[l]<NO_REG_OR_PAD)
+ i_lea_id_r (b_o+c_offset_before_pushing_arguments,REGISTER_A2,REGISTER_D4-reg_or_pad[l]);
+ 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 '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<n_clean_b_register_parameters && l<min_index){
+ if (s[l]=='I' || s[l]=='p' || s[l]=='F' || s[l]=='O'){
+ ++reg_n;
+ last_register_parameter_index=l;
+ }
+ ++l;
+ }
+
+ c_offset_1=0;
+
+ for (l=min_index-1; l>=0; --l){
+ switch (s[l]){
+ case 'I':
+ case 'p':
+ case 'S':
+ case 's':
+ if (reg_or_pad[l]>=NO_REG_OR_PAD){
+ if (reg_or_pad[l]==PAD_4_AFTER)
+ c_offset_1+=4;
+ c_offset_1+=STACK_ELEMENT_SIZE;
+ }
+ break;
+ case 'R':
+ if (reg_or_pad[l]>=NO_REG_OR_PAD)
+ c_offset_1+=8;
+ break;
+ case 'O':
+ case 'F':
+ case '*':
+ case ']':
+ while (l>=0 && (s[l]!='F' && s[l]!='O'))
+ --l;
+ if (reg_or_pad[l]>=NO_REG_OR_PAD)
+ 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 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;
+ reg_n=0;
+ for (l=min_index-1; l>=0; --l){
+ switch (s[l]){
+ case 'I':
+ case 'p':
+ if (reg_or_pad[l]<NO_REG_OR_PAD){
+ if (l<=last_register_parameter_index){
+ new_reg [4-reg_or_pad[l]] = n_extra_clean_b_register_parameters+reg_n;
+ ++reg_n;
+ }
+ } else {
+ if (reg_or_pad[l]==PAD_4_AFTER)
+ c_offset_2-=4;
+ 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 (reg_or_pad[l]>=NO_REG_OR_PAD){
+ if (reg_or_pad[l]==PAD_4_AFTER)
+ c_offset_2-=4;
+ c_offset_2-=STACK_ELEMENT_SIZE;
+ }
+ break;
+ case 'R':
+ if (reg_or_pad[l]>=NO_REG_OR_PAD)
+ c_offset_2-=8;
+ break;
+ case 'O':
+ case 'F':
+ case '*':
+ case ']':
+ while (l>=0 && (s[l]!='F' && s[l]!='O'))
+ --l;
+ if (reg_or_pad[l]<NO_REG_OR_PAD){
+ if (l<=last_register_parameter_index){
+ new_reg [4-reg_or_pad[l]] = 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 (reg_or_pad[l]<NO_REG_OR_PAD){
+ if (l<=last_register_parameter_index){
+ /* i_move_r_r (REGISTER_D0+n_extra_clean_b_register_parameters+reg_n,REGISTER_D4-reg_or_pad[l]); */
+ ++reg_n;
+ } else {
+ b_o-=STACK_ELEMENT_SIZE;
+ i_move_id_r (b_o+c_offset_before_pushing_arguments,REGISTER_A2,REGISTER_D4-reg_or_pad[l]);
+ }
+ } else {
+ if (reg_or_pad[l]==PAD_4_AFTER)
+ c_offset_1-=4;
+ 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 (reg_or_pad[l]<NO_REG_OR_PAD){
+ i_move_id_r (a_o,A_STACK_POINTER,REGISTER_D4-reg_or_pad[l]);
+ i_add_i_r (STACK_ELEMENT_SIZE,REGISTER_D4-reg_or_pad[l]);
+ } else {
+ if (reg_or_pad[l]==PAD_4_AFTER)
+ c_offset_1-=4;
+ 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 'R':
+ if (reg_or_pad[l]<NO_REG_OR_PAD){
+ b_o-=8;
+#ifdef SOFT_FP_CC
+ i_move_id_r (b_o+c_offset_before_pushing_arguments,REGISTER_A2,REGISTER_D4-reg_or_pad[l]);
+ i_move_id_r (b_o+c_offset_before_pushing_arguments+4,REGISTER_A2,REGISTER_D4-(reg_or_pad[l]+1));
+#else
+ i_fmove_id_fr (b_o+c_offset_before_pushing_arguments,REGISTER_A2,reg_or_pad[l]);
+#endif
+ } else {
+ c_offset_1-=8;
+ b_o-=8;
+ 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);
+ i_move_id_r (b_o+c_offset_before_pushing_arguments+4,REGISTER_A2,6/*r12*/);
+ i_move_r_id (6/*r12*/,c_offset_1+4,B_STACK_POINTER);
+ }
+ break;
+ case 's':
+ if (reg_or_pad[l]<NO_REG_OR_PAD){
+ i_move_id_r (a_o,A_STACK_POINTER,REGISTER_D4-reg_or_pad[l]);
+ i_add_i_r (2*STACK_ELEMENT_SIZE,REGISTER_D4-reg_or_pad[l]);
+ } else {
+ if (reg_or_pad[l]==PAD_4_AFTER)
+ c_offset_1-=4;
+ 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 (reg_or_pad[l]<NO_REG_OR_PAD){
+ if (l<=last_register_parameter_index){
+ /* i_move_r_r (REGISTER_D0+n_extra_clean_b_register_parameters+reg_n,REGISTER_D4-reg_or_pad[l]); */
+ ++reg_n;
+ } else {
+ b_o-=STACK_ELEMENT_SIZE;
+ i_move_id_r (b_o+c_offset_before_pushing_arguments,REGISTER_A2,REGISTER_D4-reg_or_pad[l]);
+ }
+
+ function_address_reg = REGISTER_D4-reg_or_pad[l];
+ 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<length && (s[l]=='*' || s[l]=='['); ++l){
+ int n;
+
+ n=0;
+
+ if (s[l]=='['){
+ ++l;
+ while (l<length && (unsigned)(s[l]-'0')<(unsigned)10){
+ n=n*10+(s[l]-'0');
+ ++l;
+ }
+ }
+
+ i_move_id_r (n,function_address_reg,REGISTER_D6);
+ function_address_reg = REGISTER_D6;
+ }
+
+ i_call_r (function_address_reg);
+ }
+
+ if (save_state_in_global_variables){
+ i_lea_l_i_r (saved_a_stack_p_label,0,REGISTER_D6);
+ i_move_id_r (0,REGISTER_D6,A_STACK_POINTER);
+ i_lea_l_i_r (saved_heap_p_label,0,REGISTER_D6);
+ i_move_id_r (0,REGISTER_D6,HEAP_POINTER);
+ i_move_id_r (4,REGISTER_D6,REGISTER_D5);
+ }
+
+ if (c_offset_before_pushing_arguments-(b_result_offset+a_result_offset)==0)
+ i_move_r_r (REGISTER_A2,B_STACK_POINTER);
+ else
+ i_lea_id_r (c_offset_before_pushing_arguments-(b_result_offset+a_result_offset),REGISTER_A2,B_STACK_POINTER);
+ }
+
+ if (a_offset!=0)
+ i_sub_i_r (a_offset,A_STACK_POINTER);
+
+ for (l=length-1; 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<length; ++l){
+ switch (s[l]){
+ case 'I':
+ case 'p':
+ b_o+=STACK_ELEMENT_SIZE;
+ break;
+ case 'S':
+ case 'V':
+ break;
+ case 'R':
+ b_o+=8;
+ break;
+ default:
+ error_s (ccall_error_string,c_function_name);
+ }
+ }
+
+ switch (result){
+ case 'I':
+ case 'p':
+ begin_new_basic_block();
+ init_b_stack (5,i_i_i_i_i_vector);
+ s_put_b (4,s_get_b (0));
+ s_remove_b();
+ s_remove_b();
+ s_remove_b();
+ s_remove_b();
+ break;
+ case 'V':
+ begin_new_basic_block();
+ break;
+ case 'R':
+ begin_new_basic_block();
+#ifdef SOFT_FP_CC
+ init_b_stack (5,i_i_i_i_i_vector);
+ s_put_b (3,s_get_b (0));
+ s_put_b (4,s_get_b (1));
+ s_remove_b();
+ s_remove_b();
+ s_remove_b();
+#else
+ init_b_stack (2,r_vector);
+#endif
+ break;
+ default:
+ error_s (ccall_error_string,c_function_name);
+ }
+}