From 6d143de55938f32f1f53df4526e3ce869a3039ef Mon Sep 17 00:00:00 2001 From: John van Groningen Date: Thu, 18 Dec 2008 16:12:51 +0000 Subject: add pushZ, pushZR and jmp_not_eqZ --- cgcode.c | 98 +++--- cgcode.h | 1 + cgcodep.h | 3 + cginput.c | 238 +++++++++++++-- cginstructions.c | 901 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 1179 insertions(+), 62 deletions(-) diff --git a/cgcode.c b/cgcode.c index c66e98d..a13e233 100644 --- a/cgcode.c +++ b/cgcode.c @@ -252,7 +252,6 @@ int no_time_profiling; #define g_fcmp_gt(g1,g2) g_instruction_2(GFCMP_GT,(g1),(g2)) #define g_fcmp_lt(g1,g2) g_instruction_2(GFCMP_LT,(g1),(g2)) #define g_fdiv(g1,g2) g_instruction_2(GFDIV,(g1),(g2)) - #define g_fitor(g1) g_instruction_1(GFITOR,(g1)) #ifdef I486 # define g_floordiv(g1,g2) g_instruction_2(GFLOORDIV,(g1),(g2)) @@ -289,7 +288,7 @@ int no_time_profiling; #endif LABEL *INT_label,*BOOL_label,*CHAR_label,*REAL_label; -LABEL *_STRING__label; +LABEL *_STRING__label,*_ARRAY__label; static LABEL *FILE_label; @@ -1401,19 +1400,54 @@ static void code_create_arrayC (VOID) init_a_stack (1); } +INSTRUCTION_GRAPH g_create_unboxed_int_array (int n_elements) +{ + INSTRUCTION_GRAPH graph_1; + int n; + + graph_1=g_create_m (n_elements+3); + + if (_ARRAY__label==NULL) + _ARRAY__label=enter_label ("__ARRAY__",IMPORT_LABEL | DATA_LABEL); + + graph_1->instruction_parameters[0].p=g_load_des_i (_ARRAY__label,0);; + graph_1->instruction_parameters[1].p=g_load_i (n_elements); + graph_1->instruction_parameters[2].p=int_descriptor_graph(); + + for (n=0; ninstruction_parameters[3+n].p=NULL; + + return graph_1; +} + #define LESS_UNSIGNED(a,b) ((unsigned long)(a)<(unsigned long)(b)) static void code_create_arrayI (VOID) { - if (create_arrayI_label==NULL) - create_arrayI_label=enter_label ("create_arrayI",IMPORT_LABEL); - - s_push_b (s_get_b (0)); - s_put_b (1,s_get_b (2)); - s_put_b (2,NULL); - insert_basic_block (JSR_BLOCK,0,2+1,i_i_vector,create_arrayI_label); - - init_a_stack (1); + INSTRUCTION_GRAPH graph_1; + + graph_1=s_get_b (0); + + if (graph_1->instruction_code==GLOAD_I && graph_1->instruction_parameters[0].i==0){ + INSTRUCTION_GRAPH graph_2; + + s_pop_b(); + s_pop_b(); + + graph_2 = g_create_unboxed_int_array (0); + + s_push_a (graph_2); + } else { + if (create_arrayI_label==NULL) + create_arrayI_label=enter_label ("create_arrayI",IMPORT_LABEL); + + s_push_b (graph_1); + s_put_b (1,s_get_b (2)); + s_put_b (2,NULL); + insert_basic_block (JSR_BLOCK,0,2+1,i_i_vector,create_arrayI_label); + + init_a_stack (1); + } } #ifdef G_AI64 @@ -1704,43 +1738,29 @@ void code_create_array_ (char element_descriptor[],int a_size,int b_size) break; case 'I': if (element_descriptor[1]=='N' && element_descriptor[2]=='T' && element_descriptor[3]=='\0'){ -#ifdef ARRAY_OPTIMIZATIONS INSTRUCTION_GRAPH graph_1; graph_1=s_get_b (0); - if (graph_1->instruction_code==GLOAD_I && LESS_UNSIGNED (graph_1->instruction_parameters[0].i,4)){ + + if (graph_1->instruction_code==GLOAD_I && LESS_UNSIGNED (graph_1->instruction_parameters[0].i,33)){ INSTRUCTION_GRAPH graph_2; - int size,n; - LABEL *__ARRAY___label; s_pop_b(); - size=graph_1->instruction_parameters[0].i; - - graph_2=g_create_m (size+3); - - __ARRAY___label=enter_label ("__ARRAY__",IMPORT_LABEL | DATA_LABEL); - graph_2->instruction_parameters[0].p=g_load_des_i (__ARRAY___label,0);; - graph_2->instruction_parameters[1].p=g_load_i (size); - graph_2->instruction_parameters[2].p=int_descriptor_graph(); - - for (n=0; ninstruction_parameters[3+n].p=NULL; + graph_2 = g_create_unboxed_int_array (graph_1->instruction_parameters[0].i); s_push_a (graph_2); - return; + } else { + if (create_arrayI__label==NULL) + create_arrayI__label=enter_label ("_create_arrayI",IMPORT_LABEL); + + s_push_b (graph_1); + s_put_b (1,NULL); + insert_basic_block (JSR_BLOCK,0,1+1,i_vector,create_arrayI__label); + + init_a_stack (1); } -#endif - - if (create_arrayI__label==NULL) - create_arrayI__label=enter_label ("_create_arrayI",IMPORT_LABEL); - - s_push_b (s_get_b (0)); - s_put_b (1,NULL); - insert_basic_block (JSR_BLOCK,0,1+1,i_vector,create_arrayI__label); - - init_a_stack (1); - return; + return; } break; case 'P': @@ -10103,7 +10123,7 @@ void initialize_coding (VOID) local_labels=NULL; last_instruction=NULL; - INT_label=BOOL_label=CHAR_label=REAL_label=FILE_label=_STRING__label=NULL; + INT_label=BOOL_label=CHAR_label=REAL_label=FILE_label=_STRING__label=_ARRAY__label=NULL; halt_label=cat_string_label=NULL; cmp_string_label=eqD_label=NULL; diff --git a/cgcode.h b/cgcode.h index 8b778ca..164668a 100644 --- a/cgcode.h +++ b/cgcode.h @@ -31,6 +31,7 @@ extern INSTRUCTION_GRAPH g_fload (int offset,int stack); extern INSTRUCTION_GRAPH g_instruction_1 (int instruction_code,INSTRUCTION_GRAPH graph_1); extern INSTRUCTION_GRAPH g_instruction_2 (int instruction_code,INSTRUCTION_GRAPH graph_1,INSTRUCTION_GRAPH graph_2); extern INSTRUCTION_GRAPH g_new_node (int,int,int); +extern INSTRUCTION_GRAPH g_create_unboxed_int_array (int n_elements); #ifdef G_A64 # define g_fromf(g1) g_instruction_1(GFROMF,(g1)) diff --git a/cgcodep.h b/cgcodep.h index 407001d..ac343fe 100644 --- a/cgcodep.h +++ b/cgcodep.h @@ -142,6 +142,7 @@ void code_ItoR (VOID); void code_jmp (char label_name[]); void code_jmp_ap (int n_args); void code_jmp_ap_upd (int n_args); +void code_jmp_not_eqZ (char *integer_string,int integer_string_length,char label_name[]); void code_jmp_upd (char label_name[]); void code_jmp_eval (VOID); void code_jmp_eval_upd (VOID); @@ -243,6 +244,8 @@ void code_push_node (char *label_name,int n_arguments); void code_push_node_u (char *label_name,int a_size,int b_size); void code_push_r_arg_t (VOID); void code_push_r_arg_u (int a_offset,int a_size,int b_size,int a_arg_offset,int a_arg_size,int b_arg_offset,int b_arg_size); +void code_pushZ (char *integer_string,int length); +void code_pushZR (int sign,char *integer_string,int integer_string_length,int exponent); void code_release (VOID); void code_randomP (VOID); void code_replace (char element_descriptor[],int a_size,int b_size); diff --git a/cginput.c b/cginput.c index 7457d22..052ed9f 100644 --- a/cginput.c +++ b/cginput.c @@ -307,6 +307,169 @@ static int parse_hexadecimal_number (int *n_p) } } +static char *resize_string (char *string,int length,int max_length) +{ + if (length==MAX_STRING_LENGTH){ + char *new_string; + int i; + + new_string=malloc (max_length); + if (new_string==NULL) + error ("Out of memory"); + + for (i=0; i=max_length){ + ++max_length; + string=resize_string (string,length,max_length); + } + + string[length]='\0'; + *string_length_p=length; + + skip_spaces_and_tabs(); + + return string; +} + +static char *parse_rational (int *sign_p,char *string,int *string_length_p,int *exponent_p) +{ + int n_chars_after_dot,length,max_length,exponent; + + length=0; + max_length=MAX_STRING_LENGTH; + + if (last_char=='-'){ + *sign_p = -1; + last_char=getc (abc_file); + } else { + *sign_p = 0; + if (last_char=='+') + last_char=getc (abc_file); + } + + if (!is_digit_character (last_char)) + abc_parser_error_i ("Rational expected at line %d\n",line_number); + + do { + if (length=max_length){ + ++max_length; + string=resize_string (string,length,max_length); + } + + string[length]='\0'; + *string_length_p=length; + + if (last_char=='e' || last_char=='E'){ + int exponent_sign; + + last_char=getc (abc_file); + if (last_char=='-'){ + exponent_sign = -1; + last_char=getc (abc_file); + } else { + exponent_sign = 0; + if (last_char=='+') + last_char=getc (abc_file); + } + + if (!is_digit_character (last_char)) + abc_parser_error_i ("Digit expected in rational at line %d\n",line_number); + + exponent=0; + do { + exponent=exponent*10+(last_char-'0'); + last_char=getc (abc_file); + } while (is_digit_character (last_char)); + + exponent = (exponent ^ exponent_sign) - exponent_sign; + } else + exponent = 0; + + *exponent_p = exponent - n_chars_after_dot; + + skip_spaces_and_tabs(); + + return string; +} + static int parse_0_or_1 (int *integer_p) { #if COMPATIBLE_DESC @@ -712,29 +875,6 @@ static int parse_string (char *string,int *string_length_p) return 1; } -static char *resize_string (char *string,int length,int max_length) -{ - if (length==MAX_STRING_LENGTH){ - char *new_string; - int i; - - new_string=malloc (max_length); - if (new_string==NULL) - error ("Out of memory"); - - for (i=0; iinstruction_code_function (integer_string,length); + + if (integer_string!=s) + free (integer_string); + + return 1; +} + +static int parse_instruction_zr (InstructionP instruction) +{ + STRING s; + int length,sign,exponent; + char *integer_string; + + integer_string=parse_rational (&sign,s,&length,&exponent); + + instruction->instruction_code_function (sign,integer_string,length,exponent); + + if (integer_string!=s) + free (integer_string); + + return 1; +} + +static int parse_instruction_z_a (InstructionP instruction) +{ + STRING s,a; + int length; + char *integer_string; + + integer_string=parse_big_integer (s,&length); + parse_label (a); + + instruction->instruction_code_function (integer_string,length,a); + + if (integer_string!=s) + free (integer_string); + + return 1; +} + static int parse_instruction_l_s (InstructionP instruction) { STRING l1,s1; @@ -2024,6 +2213,7 @@ static void put_instructions_in_table (void) put_instruction_name ("jmp_eval", parse_instruction, code_jmp_eval ); put_instruction_name ("jmp_eval_upd", parse_instruction, code_jmp_eval_upd ); put_instruction_name ("jmp_false", parse_instruction_a, code_jmp_false ); + put_instruction_name ("jmp_not_eqZ", parse_instruction_z_a, code_jmp_not_eqZ ); put_instruction_name ("jmp_true", parse_instruction_a, code_jmp_true ); put_instruction_name ("jsr", parse_instruction_a, code_jsr ); put_instruction_name ("jsr_ap", parse_instruction_n, code_jsr_ap ); @@ -2117,6 +2307,8 @@ static void put_instructions_in_table2 (void) put_instruction_name ("push_r_arg_t", parse_instruction, code_push_r_arg_t ); put_instruction_name ("push_r_arg_u", parse_instruction_n_n_n_n_n_n_n, code_push_r_arg_u ); put_instruction_name ("push_wl_args", parse_instruction_n_n_n, code_push_args ); + put_instruction_name ("pushZ", parse_instruction_z, code_pushZ ); + put_instruction_name ("pushZR", parse_instruction_zr, code_pushZR ); put_instruction_name ("putWL", parse_instruction_n, code_dummy ); put_instruction_name ("randomP", parse_instruction, code_randomP ); put_instruction_name ("release", parse_instruction, code_release ); diff --git a/cginstructions.c b/cginstructions.c index d9d365e..495f506 100644 --- a/cginstructions.c +++ b/cginstructions.c @@ -9,6 +9,7 @@ #if defined (LINUX) && defined (G_AI64) # include #endif +#include #include "cgport.h" @@ -1816,6 +1817,906 @@ void code_push_r_arg_u (int a_offset,int a_size,int b_size,int a_arg_offset,int } } +/* convert string to integer */ + +#ifdef _WIN64 +# define A64 +#endif +#if defined (__GNUC__) && defined (__SIZEOF_POINTER__) +# if __SIZEOF_POINTER__==8 +# define A64 +# endif +#endif + +#ifdef _MSC_VER +# define U_LONG_LONG unsigned __int64 +#else +# define U_LONG_LONG unsigned long long +#endif + +#ifdef A64 +# define IF_INT_64_OR_32(if64,if32) if64 +# define N_bits_in_int 64 +# define Max_bit_n_in_int 63 +# define N_digits_in_part 27 +# define N_digits_in_part_m1 26 +# define I5PD 7450580596923828125 +# define I2T5PD 14901161193847656250 +# define I1E18 1000000000000000000 +# define IM1E18 (-1000000000000000000) +#else +# define IF_INT_64_OR_32(if64,if32) if32 +# define N_bits_in_int 32 +# define Max_bit_n_in_int 31 +# define N_digits_in_part 13 +# define N_digits_in_part_m1 12 +# define I5PD 1220703125 +# define I2T5PD 2441406250 +#endif +#define I1E9 1000000000 + +#ifdef A64 +# ifdef __GNUC__ +# define UW unsigned long long +# define W long long +# else +# define UW unsigned __int64 +# define W __int64 +# endif +#else +# define UW unsigned int +# define W int +#endif + +#ifdef _WIN64 +UW _umul128 (UW multiplier, UW multiplicand, UW* highproduct); +# pragma intrinsic (_umul128) +#endif + +#ifdef A64 +# ifdef __GNUC__ +# define umul_hl(h,l,a,b) \ + __asm__ ("mulq %3" \ + : "=a" ((UW)(l)), \ + "=d" ((UW)(h)) \ + : "%0" ((UW)(a)), \ + "rm" ((UW)(b))) +# else +# define umul_hl(h,l,a,b) l=_umul128 (a,b,&h) +# endif +#endif + +struct integer { + W s; + UW *a; +}; + +static UW convertchars (int i,int end_i,char s[]) +{ + UW n; + + n=0; + while (i>32) * I1E9 + (n & 0xffffffff); +} + +static UW convert19to27c_64 (int n_chars,char *s,UW *h_p) +{ + int i; + UW nh,nl,h,l; + + i = n_chars-18; + nl = convert18c_64 (i,s); + nh = convertchars (0,i,s); + + umul_hl (h,l,nh,I1E18); + l = l+nl; + *h_p = h+(l>N_bits_in_int); + l=(UW)hl; +#endif + a[i_a_f]=l; + if (h==0) + return i_a_f+1; + else { + a[i_a_f+1]=h; + return i_a_f+2; + } + } +} + +static int mul_5pd_add (int i,int i_a,UW a[]) +{ + UW n; + + n=0; + + while (i!=i_a){ + UW ai; +#ifdef A64 + UW h,l; +#else + U_LONG_LONG hl; +#endif + ai=a[i]; +#ifdef A64 + umul_hl (h,l,ai,I5PD); + l=l+n; + h=h+(l>32); +#endif + ++i; + } + + if (n!=0){ + a[i]=n; + return i+1; + } else + return i; +} + +static int addi (UW n,int i_a_f,int i_a_e,UW a[]) +{ + UW s; + + if (i_a_f==i_a_e){ + a[i_a_f]=n; + return i_a_f+1; + } + s=a[i_a_f]+n; + a[i_a_f]=s; + if (s>(N_bits_in_int-shift); + ai = (ai<>N_digits_in_part)+(h<<37); + + rl = yl+l; + rh = yh+(rl>shift)+(rh<<(N_bits_in_int-shift)); +#else + UW l; + U_LONG_LONG rhl; + + x = (UW)hl & 0x1fff; + l = (UW)(hl>>N_digits_in_part); + rhl = yhl+l; + new_r = x | ((((UW)rhl) & ((((UW)1)<>shift); +#endif + + i_a_e = mul_5pd_add (i_a_f,i_a_e,a); + i_a_e = addi (n,i_a_f,i_a_e,a); + shift += N_digits_in_part; + r = new_r; + } else if (shift==IF_INT_64_OR_32 (37,19)){ +#ifdef A64 + yh =(yh<>IF_INT_64_OR_32 (37,19)); + yl = yl<>32)),i_a_f,i_a_e,a); + + if (i_a_f<=0) + printf ("error in stoi_next_parts\n"); + + i_a_f = i_a_f-1; + a[i_a_f]=IF_INT_64_OR_32 (l,(UW)hl); + + shift = 0; + r = 0; + } else { + UW new_r; + int n,ys; + + n = shift-IF_INT_64_OR_32 (37,19); + new_r = (IF_INT_64_OR_32 (l,(UW)hl)) & ((((UW)1)<>n) + (h<<(N_bits_in_int-n)); + h = h>>n; +#else + hl = hl>>n; +#endif + ys = N_digits_in_part-n; +#ifdef A64 + yh =(yh<>(N_bits_in_int-ys)); + yl = yl<>32)),i_a_f,i_a_e,a); + + if (i_a_f<=0) + printf ("error in stoi_next_parts\n"); + i_a_f = i_a_f-1; + a[i_a_f]=IF_INT_64_OR_32 (l,(UW)hl); + + shift = n; + r = new_r; + } + i_s += N_digits_in_part; + } + + if (i_s==size_s && i_a_f==0 && i_a_e<=size_a){ + if (shift!=0) + i_a_e=shift_left (0,r,shift,i_a_e,a); + return; + } else + printf ("error in stoi_next_parts\n"); +} + +static struct integer string_to_integer (W sign,char *s,int size_s) +{ + if (s[0]=='-'){ + sign=-1; + --size_s; + ++s; + } + + if (size_s<=N_digits_in_part){ + if (size_s>N_bits_in_int); + l=(UW)hl; +#endif + + if (h==0){ + struct integer i; + + if ((UW)l < (UW)(((UW)1<<(UW)Max_bit_n_in_int)-sign)){ + i.s=(l ^ sign)-sign; + i.a=NULL; + + return i; + } else { + UW *a; + + a=calloc (2,sizeof (UW)); + if (a==NULL) + error ("Out of memory\n"); + + a[0]=1; + a[1]=l; + + i.s=sign; + i.a=a+1; + + return i; + } + } else { + struct integer i; + UW *a; + + a=calloc (3,sizeof (UW)); + if (a==NULL) + error ("Out of memory\n"); + + a[0]=2; + a[1]=l; + a[2]=h; + + i.s=sign; + i.a=a+1; + + return i; + } + } + } else { + int n_chars,n_parts,n_chars_in_parts,n_chars_in_first_part,n_shifts,size_a,i_a_f,i_a_e,i; + UW *a; + + n_chars = size_s; + n_parts = n_chars/N_digits_in_part; + n_chars_in_parts = n_parts * N_digits_in_part; + n_chars_in_first_part = n_chars-n_chars_in_parts; + n_shifts = n_chars_in_parts>>IF_INT_64_OR_32(6,5); + size_a = n_parts + 3 + n_shifts; + + a = calloc (size_a+1,sizeof(UW)); + if (a==NULL) + printf ("Out of memory\n"); + ++a; + + i_a_f = n_shifts; + i_a_e = convert_first_chars (n_chars_in_first_part,s,i_a_f,a); + + stoi_next_parts (n_chars_in_first_part,s,size_s,i_a_f,i_a_e,0,0,a,size_a); + + i=size_a-1; + while (i!=0 && a[i]==0) + --i; + + if (i==0 && (UW)a[0] < (UW)(((UW)1<<(UW)Max_bit_n_in_int)-sign)){ + struct integer si; + + si.a=NULL; + si.s=(a[0] ^ sign)-sign; + + free (a-1); + + return si; + } else if (i+1==size_a){ + struct integer si; + + si.a=a; + si.s=sign; + a[-1]=i+1; + + return si; + } else { + struct integer si; + + a=1+(UW*)realloc (a-1,sizeof (UW)*(i+1+1)); + if (a==0) + printf ("realloc failed\n"); + + a[-1]=i+1; + + si.a=a; + si.s=sign; + + return si; + } + } +} + +#define g_cmp_eq(g1,g2) g_instruction_2(GCMP_EQ,(g1),(g2)) + +void code_jmp_not_eqZ (char *integer_string,int integer_string_length,char label_name[]) +{ + struct integer integer; + INSTRUCTION_GRAPH graph_1,graph_2,graph_3,graph_4; + + integer=string_to_integer (0,integer_string,integer_string_length); + + if (integer.a==NULL){ + graph_1=s_get_b (0); + graph_2=g_load_i (integer.s); + graph_3=g_cmp_eq (graph_2,graph_1); + s_push_b (graph_3); + code_jmp_false (label_name); + + graph_1=s_get_a (0); + graph_2=g_load_id (STACK_ELEMENT_SIZE,graph_1); + graph_3=g_load_i (0); + graph_4=g_cmp_eq (graph_3,graph_2); + s_push_b (graph_4); + code_jmp_false (label_name); + } else { + int i,integer_size; + + integer_size=integer.a[-1]; + + graph_1=s_get_a (0); + graph_2=g_load_id (STACK_ELEMENT_SIZE,graph_1); + graph_3=g_load_i (integer_size); + graph_4=g_cmp_eq (graph_3,graph_2); + s_push_b (graph_4); + code_jmp_false (label_name); + + for (i=0; iinstruction_parameters[3+i].p=g_load_i (integer.a[i]); + } + + s_push_b (graph_1); + s_push_a (graph_2); +} + +static struct integer shift_right (struct integer n,unsigned int n_bits) +{ + UW *a; + + a=n.a; + if (a==NULL) + n.s = n.s>>n_bits; + else { + UW previous_e; + int i,n_n_elements; + + n_n_elements=a[-1]; + + previous_e=0; + for (i=n_n_elements-1; i>=0; --i){ + UW e; + + e = a[i]; + a[i] = (e>>n_bits) + (previous_e<<(N_bits_in_int-n_bits)); + previous_e = e; + } + + if (a[n_n_elements-1]==0){ + --n_n_elements; + a[-1]=n_n_elements; + } + + if (n_n_elements==1 && (W)a[0]>=0){ + n.s=a[0]; + n.a=NULL; + } + } + + return n; +} + +static int divisible_by_5 (struct integer n) +{ + UW s; + + if (n.a==NULL) + s=n.s; + else { + UW *a; + int i,n_elements; + + a=n.a; + n_elements=a[-1]; + + s=0; + for (i=0; ; ){ + int end_i; + + end_i=i+10000; + if (end_i>n_elements) + end_i=n_elements; + + while (i>32u),(e & 0xffffu)+(e>>16u)); + ++i; + } + + if (i>=n_elements) + break; + + s = s % 5; + } + } + + return s % 5==0; +} + +static struct integer exact_div_5 (struct integer n) +{ + if (n.a==NULL) + n.s=n.s / 5; + else { + int i,n_elements; + UW borrow,*a; + + a=n.a; + n_elements=a[-1]; + + borrow=0; + for (i=0; iai; + + ed5=e * IF_INT_64_OR_32 (0xcccccccccccccccd,0xcccccccd); + + h = (ed5 + (ed5<<2u)) < ed5; + borrow += h; + borrow += ed5>>IF_INT_64_OR_32 (62u,30u); + + a[i]=ed5; + } + + if (a[n_elements-1]==0){ + --n_elements; + a[-1]=n_elements; + } + + if (n_elements==1 && (W)a[0]>=0){ + n.s=a[0]; + n.a=NULL; + } + } + + return n; +} + +void code_pushZR (int sign,char *integer_string,int integer_string_length,int exponent) +{ + struct integer numerator,denominator; + INSTRUCTION_GRAPH graph_1,graph_2,graph_3,graph_4; + char *numerator_string; + int denominator_string_length; + + while (integer_string[0]=='0' && integer_string_length>1){ + ++integer_string; + --integer_string_length; + } + + while (exponent<0 && integer_string_length>1 && integer_string[integer_string_length-1]=='0'){ + --integer_string_length; + ++exponent; + } + + if (integer_string_length==1 && integer_string[0]=='0') + exponent=0; + + if (exponent>0){ + int i,new_string_length; + + new_string_length=integer_string_length+exponent; + numerator_string=memory_allocate (new_string_length+1); + + for (i=0; i=N_bits_in_int && numerator.a!=NULL){ + int n_n_elements,n_d_elements; + UW *n_a,*d_a; + + n_a=numerator.a; + n_n_elements=n_a[-1]; + + d_a=denominator.a; + n_d_elements=d_a[-1]; + + while (exponent2>=N_bits_in_int && n_a[0]==0){ + --n_n_elements; + ++n_a; + + --n_d_elements; + ++d_a; + + exponent2-=N_bits_in_int; + } + + if (n_n_elements==1 && (W)n_a[0]>=0){ + numerator.s=n_a[0]; + numerator.a=NULL; + } else { + numerator.a=n_a; + n_a[-1]=n_n_elements; + } + + /* >= 32 bits, because >= 5^32 */ + denominator.a=d_a; + d_a[-1]=n_d_elements; + } + + if (exponent2>0){ + UW n0; + + if (numerator.a==NULL) + n0=numerator.s; + else + n0=numerator.a[0]; + + if ((n0 & 1)==0){ + unsigned int n_0_bits,max_bits; + + n0=n0>>1; + n_0_bits=1; + while (n_0_bits>1; + ++n_0_bits; + } + + exponent2-=n_0_bits; + + numerator = shift_right (numerator,n_0_bits); + denominator = shift_right (denominator,n_0_bits); + } + } + + while (exponent5>0 && divisible_by_5 (numerator)){ + numerator = exact_div_5 (numerator); + denominator = exact_div_5 (denominator); + --exponent5; + } + } else { + denominator.s=1; + denominator.a=NULL; + } + + graph_1=g_load_i (numerator.s); + if (numerator.a==NULL) + graph_2=g_create_unboxed_int_array (0); + else { + int i,n_elements; + + n_elements=numerator.a[-1]; + graph_2=g_create_unboxed_int_array (n_elements); + for (i=0; iinstruction_parameters[3+i].p=g_load_i (numerator.a[i]); + } + + graph_3=g_load_i (denominator.s); + if (denominator.a==NULL) + graph_4=g_create_unboxed_int_array (0); + else { + int i,n_elements; + + n_elements=denominator.a[-1]; + graph_4=g_create_unboxed_int_array (n_elements); + for (i=0; iinstruction_parameters[3+i].p=g_load_i (denominator.a[i]); + } + + s_push_b (graph_3); + s_push_a (graph_4); + s_push_b (graph_1); + s_push_a (graph_2); +} + extern int profile_flag; extern LABEL *profile_function_label; -- cgit v1.2.3