diff options
author | John van Groningen | 2003-05-12 12:44:22 +0000 |
---|---|---|
committer | John van Groningen | 2003-05-12 12:44:22 +0000 |
commit | f3c5802036f372cd3b35b35050b2f90d9eee0dc0 (patch) | |
tree | 608beaad6fa6eae818ad1ce51645f4a21542e19c /cgcode.c | |
parent | extra code for intel_asm (diff) |
cgcode.c
Diffstat (limited to 'cgcode.c')
-rw-r--r-- | cgcode.c | 8213 |
1 files changed, 8213 insertions, 0 deletions
diff --git a/cgcode.c b/cgcode.c new file mode 100644 index 0000000..c0632e1 --- /dev/null +++ b/cgcode.c @@ -0,0 +1,8213 @@ +/* + File: cgcode.c + Author: John van Groningen + At: University of Nijmegen +*/ + +#include <stdio.h> +#include <string.h> + +#define NO_STRING_ADDRES_IN_DESCRIPTOR +#undef NO_FUNCTION_NAMES +#undef NO_CONSTRUCTOR_NAMES + +#undef ARRAY_OPTIMIZATIONS +#define INDEX_CSE +#define REPLACE_MUL_BY_SHIFT + +#define TIME_PROFILE_WITH_MODULE_NAMES 1 + +#include "cgport.h" + +#if defined (G_POWER) || defined (I486) +# define PROFILE +# if defined (G_POWER) +# if defined (MACH_O) +# define PROFILE_OFFSET 16 +# else +# define PROFILE_OFFSET 12 +# endif +# else +# define PROFILE_OFFSET 10 +# endif +#endif + +#include "cg.h" +#include "cgconst.h" +#include "cgrconst.h" +#include "cgtypes.h" +#include "cgcodep.h" +#include "cgcode.h" +#include "cglin.h" +#include "cgcalc.h" +#include "cgstack.h" +#include "cginstructions.h" +#ifdef G_POWER +# include "cgpas.h" +# include "cgpwas.h" +#else +# ifdef I486 +# include "cgias.h" +# include "cgiwas.h" +# else +# ifdef SOLARIS +# include "cgswas.h" +# else +# include "cgas.h" +# include "cgwas.h" +# endif +# endif +#endif + +#define for_l(v,l,n) for(v=(l);v!=NULL;v=v->n) + +#if defined (M68000) && !defined (SUN) +# define GEN_MAC_OBJ +#endif +#ifndef sparc +# define GEN_OBJ +#endif + +#if defined (M68000) || (defined (NO_STRING_ADDRES_IN_DESCRIPTOR) && (defined (G_POWER) || defined (I486))) +# define ARITY_0_DESCRIPTOR_OFFSET (-8) +#else +# define ARITY_0_DESCRIPTOR_OFFSET (-12) +#endif +#ifdef GEN_MAC_OBJ +# define DESCRIPTOR_ARITY_OFFSET (-4) +#else +# if defined (NO_STRING_ADDRES_IN_DESCRIPTOR) && (defined (G_POWER) || defined (I486)) +# define DESCRIPTOR_ARITY_OFFSET (-2) +# else +# define DESCRIPTOR_ARITY_OFFSET (-6) +# endif +#endif + +#ifdef THINK_C +# define SMALL_LAZY_DESCRIPTORS 1 +#else +# define SMALL_LAZY_DESCRIPTORS 0 +#endif + +#ifdef __MWERKS__ +int mystrcmp (char *p1,char *p2) +{ + unsigned char *s1,*s2; + int c1,c2; + + s1=(unsigned char*)p1-1; + s2=(unsigned char*)p2-1; + + do { + c1=*++s1; + c2=*++s2; + } while (c1!=0 && c1==c2); + + return *s1-*s2; +} +#endif + +#ifdef PROFILE +static int profile_offset,profile_table_offset; +#endif +LABEL *profile_table_label; + +int next_label_id; + +struct label_node *labels; + +struct basic_block *first_block,*last_block; +struct block_label *last_block_label; + +struct instruction *last_instruction; + +INSTRUCTION_GRAPH load_indexed_list; + +ULONG e_vector[] = { 0 }; +ULONG i_vector[] = { 0 }; +ULONG r_vector[] = { 3 }; +ULONG i_i_vector[] = { 0 }; +ULONG i_i_i_vector[]= { 0 }; +ULONG i_i_i_i_i_vector[]= { 0 }; +static ULONG i_r_vector[] = { 6 }; +static ULONG r_r_vector[]= { 15 }; + +static ULONG *demanded_vector; +int demanded_a_stack_size=0; +int demanded_b_stack_size=0; +int demand_flag; + +ULONG *offered_vector; +int offered_a_stack_size=0; +int offered_b_stack_size=0; + +static int offered_after_jsr; +static int offered_before_label; + +int reachable; + +int no_memory_profiling; + +#ifdef PROFILE +int no_time_profiling; +#endif + +#pragma segment Code2 + +#define g_add(g1,g2) g_instruction_2(GADD,(g1),(g2)) +#define g_and(g1,g2) g_instruction_2(GAND,(g1),(g2)) +#define g_asr(g1,g2) g_instruction_2(GASR,(g1),(g2)) +#define g_bounds(g1,g2) g_instruction_2(GBOUNDS,(g1),(g2)) +#define g_cmp_eq(g1,g2) g_instruction_2(GCMP_EQ,(g1),(g2)) +#define g_cmp_gt(g1,g2) g_instruction_2(GCMP_GT,(g1),(g2)) +#define g_cmp_lt(g1,g2) g_instruction_2(GCMP_LT,(g1),(g2)) +#define g_cnot(g1) g_instruction_1(GCNOT,(g1)) +#define g_div(g1,g2) g_instruction_2(GDIV,(g1),(g2)) +#define g_eor(g1,g2) g_instruction_2(GEOR,(g1),(g2)) +#define g_fadd(g1,g2) g_instruction_2(GFADD,(g1),(g2)) +#define g_fcmp_eq(g1,g2) g_instruction_2(GFCMP_EQ,(g1),(g2)) +#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_fexp(g1) g_instruction_1(GFEXP,(g1)) + +#define g_fitor(g1) g_instruction_1(GFITOR,(g1)) +#define g_fln(g1) g_instruction_1(GFLN,(g1)) + +#define g_fmul(g1,g2) g_instruction_2(GFMUL,(g1),(g2)) +#define g_frem(g1,g2) g_instruction_2(GFREM,(g1),(g2)) +#define g_frtoi(g1) g_instruction_1(GFRTOI,(g1)) +#define g_fsub(g1,g2) g_instruction_2(GFSUB,(g1),(g2)) +#define g_lsl(g1,g2) g_instruction_2(GLSL,(g1),(g2)) +#define g_lsr(g1,g2) g_instruction_2(GLSR,(g1),(g2)) +#define g_mod(g1,g2) g_instruction_2(GMOD,(g1),(g2)) +#define g_mul(g1,g2) g_instruction_2(GMUL,(g1),(g2)) +#define g_or(g1,g2) g_instruction_2(GOR,(g1),(g2)) +#define g_keep(g1,g2) g_instruction_2(GKEEP,(g1),(g2)) +#define g_fkeep(g1,g2) g_instruction_2(GFKEEP,(g1),(g2)) +#define g_sub(g1,g2) g_instruction_2(GSUB,(g1),(g2)) + +#define MAX_YET_ARGS_NEEDED_ARITY 4 + +LABEL *INT_label,*BOOL_label,*CHAR_label,*REAL_label; +LABEL *_STRING__label; + +static LABEL *FILE_label; + +static struct basic_block + *last_INT_descriptor_block,*last_BOOL_descriptor_block,*last_CHAR_descriptor_block, + *last_REAL_descriptor_block,*last_FILE_descriptor_block,*last__STRING__descriptor_block; + +static INSTRUCTION_GRAPH + last_INT_descriptor_graph,last_BOOL_descriptor_graph,last_CHAR_descriptor_graph, + last_REAL_descriptor_graph,last_FILE_descriptor_graph,last__STRING__descriptor_graph; + +LABEL *cycle_in_spine_label,*reserve_label; + +static LABEL *halt_label,*cmp_string_label,*eqD_label, + *slice_string_label,*print_label,*print_sc_label, + *print_symbol_label,*print_symbol_sc_label,*D_to_S_label, + *div_label,*mod_label,*mul_label,*update_string_label,*equal_string_label, + *yet_args_needed_label, + *repl_args_b_label,*push_arg_b_label,*del_args_label,*printD_label, + *yet_args_needed_labels[MAX_YET_ARGS_NEEDED_ARITY+1], + *new_ext_reducer_label,*ItoP_label,*create_array_label, + *create_arrayB_label,*create_arrayC_label,*create_arrayI_label,*create_arrayR_label,*create_r_array_label, + *create_arrayB__label,*create_arrayC__label,*create_arrayI__label,*create_arrayR__label,*create_r_array__label, + *print_char_label,*print_int_label,*print_real_label; + +LABEL *new_int_reducer_label,*channelP_label,*stop_reducer_label,*send_request_label, + *send_graph_label,*string_to_string_node_label,*cat_string_label; + +static LABEL *add_real,*sub_real,*mul_real,*div_real,*eq_real,*gt_real,*lt_real, + *i_to_r_real,*r_to_i_real,*sqrt_real,*exp_real,*ln_real,*log10_real, + *cos_real,*sin_real,*tan_real,*acos_real,*asin_real,*atan_real, + *pow_real,*entier_real_label; + +LABEL *copy_graph_label,*CHANNEL_label,*create_channel_label,*currentP_label,*newP_label, + *randomP_label,*suspend_label; + +#ifdef M68000 +static LABEL *neg_real; +#endif + +static LABEL *small_integers_label,*static_characters_label; + +LABEL *eval_fill_label,*eval_upd_labels[33]; + +static LABEL *print_r_arg_label,*push_t_r_args_label,*push_a_r_args_label; +LABEL *index_error_label; + +#ifdef G_POWER +LABEL *r_to_i_buffer_label; +#endif + +LABEL *collect_0_label,*collect_1_label,*collect_2_label, +#ifndef I486 + *collect_3_label, +#endif +#ifdef G_POWER + *collect_00_label,*collect_01_label,*collect_02_label,*collect_03_label, + *eval_01_label,*eval_11_label,*eval_02_label,*eval_12_label,*eval_22_label, +#endif +#if defined (I486) && defined (GEN_OBJ) + *collect_0l_label,*collect_1l_label,*collect_2l_label,*end_heap_label, +#endif + *system_sp_label,*EMPTY_label; + +#ifdef PROFILE +LABEL *profile_l_label,*profile_l2_label,*profile_n_label,*profile_n2_label, + *profile_s_label,*profile_s2_label,*profile_r_label,*profile_t_label; +# ifdef G_POWER +LABEL *profile_ti_label; +# endif +#endif + +LABEL *enter_label (char *label_name,int label_flags) +{ + struct label_node **label_p,*new_label; + + label_p=&labels; + while (*label_p!=NULL){ + struct label_node *label; + int r; + + label=*label_p; + r=strcmp (label_name,label->label_node_label.label_name); + if (r==0){ + label->label_node_label.label_flags |= label_flags; + return &label->label_node_label; + } + if (r<0) + label_p=&label->label_node_left; + else + label_p=&label->label_node_right; + } + + new_label=fast_memory_allocate_type (struct label_node); + new_label->label_node_left=NULL; + new_label->label_node_right=NULL; + new_label->label_node_label.label_flags=label_flags; + new_label->label_node_label.label_number=0; + new_label->label_node_label.label_id=-1; + new_label->label_node_label.label_name=(char*)fast_memory_allocate (strlen (label_name)+1); + strcpy (new_label->label_node_label.label_name,label_name); + + new_label->label_node_label.label_last_lea_block=NULL; + + *label_p=new_label; + return &new_label->label_node_label; +} + +static int next_label; + +#define LTEXT 0 +#define LDATA 1 + +struct local_label *local_labels; + +LABEL *new_local_label (int label_flags) +{ + struct local_label *local_label; + LABEL *label; + int id; + + id=next_label_id++; + + local_label=fast_memory_allocate_type (struct local_label); + + local_label->local_label_next=local_labels; + local_labels=local_label; + + label=&local_label->local_label_label; + label->label_number=next_label++; + label->label_name=NULL; + label->label_id=id; + label->label_flags=label_flags; + + return label; +} + +#define DESCRIPTOR_OFFSET 2 +#define ARGUMENTS_OFFSET 4 + +static void code_monadic_real_operator (int g_code) +{ + INSTRUCTION_GRAPH graph_1,graph_2,graph_3,graph_4,graph_5,graph_6; + + graph_2=s_get_b (1); + graph_1=s_get_b (0); + graph_3=g_fjoin (graph_1,graph_2); + + graph_4=g_instruction_1 (g_code,graph_3); + + g_fhighlow (graph_5,graph_6,graph_4); + + s_put_b (1,graph_6); + s_put_b (0,graph_5); +} + +static int eval_label_number; +char eval_label_s [64]; + +static void code_monadic_sane_operator (LABEL *label) +{ +#ifdef M68000 + LABEL *label2; + INSTRUCTION_GRAPH graph; + struct block_label *new_label; + + sprintf (eval_label_s,"e_%d",eval_label_number++); + label2=enter_label (eval_label_s,LOCAL_LABEL); + graph=g_lea (label2); +#endif + + s_push_b (s_get_b (0)); + s_put_b (1,s_get_b (2)); +#ifdef M68000 + s_put_b (2,graph); +#else + s_put_b (2,NULL); +#endif + insert_basic_block (JSR_BLOCK,0,2+1,r_vector,label); + +#ifdef M68000 + new_label=fast_memory_allocate_type (struct block_label); + new_label->block_label_label=label2; + new_label->block_label_next=NULL; + + if (last_block->block_labels==NULL) + last_block->block_labels=new_label; + else + last_block_label->block_label_next=new_label; + last_block_label=new_label; +#endif +} + +static void code_dyadic_sane_operator (LABEL *label) +{ +#ifdef M68000 + LABEL *label2; + INSTRUCTION_GRAPH graph; + struct block_label *new_label; + + if (!mc68881_flag){ + sprintf (eval_label_s,"e_%d",eval_label_number++); + label2=enter_label (eval_label_s,LOCAL_LABEL); + graph=g_lea (label2); + } +#endif + + s_push_b (s_get_b (0)); + s_put_b (1,s_get_b (2)); + s_put_b (2,s_get_b (3)); + s_put_b (3,s_get_b (4)); + +#ifdef M68000 + if (!mc68881_flag) + s_put_b (4,graph); + else +#endif + s_put_b (4,NULL); + + insert_basic_block (JSR_BLOCK,0,4+1,r_r_vector,label); + +#ifdef M68000 + if (!mc68881_flag){ + new_label=fast_memory_allocate_type (struct block_label); + new_label->block_label_label=label2; + new_label->block_label_next=NULL; + + if (last_block->block_labels==NULL) + last_block->block_labels=new_label; + else + last_block_label->block_label_next=new_label; + last_block_label=new_label; + } +#endif +} + +void code_acosR (VOID) +{ +#ifdef M68000 + if (!mc68881_flag){ +#endif + if (acos_real==NULL) + acos_real=enter_label ("acos_real",IMPORT_LABEL); + code_monadic_sane_operator (acos_real); + init_b_stack (2,r_vector); +#ifdef M68000 + } else + code_monadic_real_operator (GFACOS); +#endif +} + +void code_addI (VOID) +{ + INSTRUCTION_GRAPH graph_1,graph_2,graph_3; + + graph_1=s_pop_b(); + graph_2=s_get_b (0); + graph_3=g_add (graph_1,graph_2); + + s_put_b (0,graph_3); +} + +#ifndef M68000 +static void code_operatorIo (int instruction_code) +{ + INSTRUCTION_GRAPH graph_1,graph_2,graph_3,graph_4; + + graph_1=s_get_b (1); + graph_2=s_get_b (0); + graph_3=g_instruction_2_0 (instruction_code,graph_1,graph_2); + graph_4=g_test_o (graph_3); + +#ifdef sparc + if (instruction_code==GMUL_O) + graph_4->inode_arity=0; +#endif + + s_put_b (1,graph_3); + s_put_b (0,graph_4); +} + +void code_addIo (VOID) +{ + code_operatorIo (GADD_O); +} +#endif + +void code_addR (VOID) +{ + INSTRUCTION_GRAPH graph_1,graph_2,graph_3,graph_4,graph_5,graph_6,graph_7,graph_8,graph_9; + +#ifdef M68000 + if (!mc68881_flag){ + if (add_real==NULL) + add_real=enter_label ("add_real",IMPORT_LABEL); + code_dyadic_sane_operator (add_real); + init_b_stack (2,r_vector); + } else { +#endif + graph_1=s_pop_b(); + graph_2=s_pop_b(); + graph_3=g_fjoin (graph_1,graph_2); + + graph_5=s_get_b (1); + graph_4=s_get_b (0); + graph_6=g_fjoin (graph_4,graph_5); + + graph_7=g_fadd (graph_6,graph_3); + + g_fhighlow (graph_8,graph_9,graph_7); + + s_put_b (1,graph_9); + s_put_b (0,graph_8); +#ifdef M68000 + } +#endif +} + +void code_andB (VOID) +{ + INSTRUCTION_GRAPH graph_1,graph_2,graph_3; + + graph_1=s_pop_b(); + graph_2=s_get_b (0); + graph_3=g_and (graph_1,graph_2); + + s_put_b (0,graph_3); +} + +void code_and (VOID) +{ + INSTRUCTION_GRAPH graph_1,graph_2,graph_3; + + graph_1=s_pop_b(); + graph_2=s_get_b (0); + graph_3=g_and (graph_1,graph_2); + + s_put_b (0,graph_3); +} + +void code_asinR (VOID) +{ +#ifdef M68000 + if (!mc68881_flag){ +#endif + if (asin_real==NULL) + asin_real=enter_label ("asin_real",IMPORT_LABEL); + code_monadic_sane_operator (asin_real); + init_b_stack (2,r_vector); +#ifdef M68000 + } else + code_monadic_real_operator (GFASIN); +#endif +} + +void code_atanR (VOID) +{ +#ifdef M68000 + if (!mc68881_flag){ +#endif + if (atan_real==NULL) + atan_real=enter_label ("atan_real",IMPORT_LABEL); + code_monadic_sane_operator (atan_real); + init_b_stack (2,r_vector); +#ifdef M68000 + } else + code_monadic_real_operator (GFATAN); +#endif +} + +void code_build (char descriptor_name[],int arity,char *code_name) +{ + INSTRUCTION_GRAPH graph_2,graph_3,graph_4; + LABEL *descriptor_label,*code_label; + + if (strcmp (code_name,"__hnf")==0){ + code_buildh (descriptor_name,arity); + } else { + int n_arguments; + union instruction_parameter *parameter; + + code_label=enter_label (code_name,NODE_ENTRY_LABEL); + code_label->label_arity=arity; + + if (descriptor_name[0]=='_' && descriptor_name[1]=='_' && descriptor_name[2]=='\0') + descriptor_label=NULL; + else +#if SMALL_LAZY_DESCRIPTORS + if (parallel_flag){ + char curried_descriptor_name[257]; + + strcpy (curried_descriptor_name,descriptor_name); + strcat (curried_descriptor_name,"#"); + + descriptor_label=enter_label (curried_descriptor_name,DATA_LABEL); + } else +#endif + descriptor_label=enter_label (descriptor_name,DATA_LABEL); + + if (arity<-2) + arity=1; + + if (code_label->label_flags & EA_LABEL + && code_label->label_ea_label!=eval_fill_label + && arity>=0 && eval_upd_labels[arity]==NULL) + { + char eval_upd_label_name[32]; + + sprintf (eval_upd_label_name,"eval_upd_%d",arity); + eval_upd_labels[arity]=enter_label (eval_upd_label_name,IMPORT_LABEL); + } + + if (arity<0) + arity=1; + + code_label->label_descriptor=descriptor_label; + + if (arity<2){ + graph_2=g_create_m (3); + graph_2->instruction_parameters[1].p=NULL; + graph_2->instruction_parameters[2].p=NULL; + } else + graph_2=g_create_m (arity+1); + parameter=&graph_2->instruction_parameters[0]; + + graph_3=g_lea (code_label); + parameter->p=graph_3; + ++parameter; + + for (n_arguments=arity; n_arguments>0; --n_arguments){ + graph_4=s_pop_a(); + parameter->p=graph_4; + ++parameter; + } + + s_push_a (graph_2); + } +} + +void code_buildh (char descriptor_name[],int arity) +{ + INSTRUCTION_GRAPH graph_2,graph_3,graph_4,graph_5,graph_6; + LABEL *descriptor_label; + + descriptor_label=enter_label (descriptor_name,DATA_LABEL); + + if (!parallel_flag && arity==0){ + graph_4=g_lea_i (descriptor_label,ARITY_0_DESCRIPTOR_OFFSET+NODE_POINTER_OFFSET); + s_push_a (graph_4); + return; + } + + if (!parallel_flag && + descriptor_label->label_last_lea_block==last_block && + descriptor_label->label_last_lea_arity==arity) + { + graph_2=descriptor_label->label_last_lea; + } else { + graph_2=g_load_des_i (descriptor_label,arity); + + if (!parallel_flag ){ + descriptor_label->label_last_lea=graph_2; + descriptor_label->label_last_lea_block=last_block; + descriptor_label->label_last_lea_arity=arity; + } + } + + switch (arity){ + case 0: + graph_4=g_create_1 (graph_2); + break; + case 1: + graph_5=s_pop_a(); + graph_4=g_create_2 (graph_2,graph_5); + break; + case 2: + graph_5=s_pop_a(); + graph_6=s_pop_a(); + graph_4=g_create_3 (graph_2,graph_5,graph_6); + break; + default: + { + int n_arguments; + union instruction_parameter *parameter; + + graph_5=s_pop_a(); + + graph_3=g_create_m (arity-1); + parameter=graph_3->instruction_parameters; + for (n_arguments=arity-1; n_arguments>0; --n_arguments){ + graph_6=s_pop_a(); + parameter->p=graph_6; + ++parameter; + } + + graph_4=g_create_3 (graph_2,graph_5,graph_3); + } + } + + s_push_a (graph_4); +} + +void code_build_r (char descriptor_name[],int a_size,int b_size,int a_offset,int b_offset) +{ + INSTRUCTION_GRAPH graph_2,graph_3,graph_4,graph_5,graph_6; + LABEL *descriptor_label; + + descriptor_label=enter_label (descriptor_name,DATA_LABEL); + + if (!parallel_flag && descriptor_label->label_last_lea_block==last_block) + graph_2=descriptor_label->label_last_lea; + else { + graph_2=g_load_des_i (descriptor_label,0); + + if (!parallel_flag ){ + descriptor_label->label_last_lea=graph_2; + descriptor_label->label_last_lea_block=last_block; + } + } + + switch (a_size+b_size){ + case 0: + graph_4=g_create_1 (graph_2); + break; + case 1: + if (a_size!=0) + graph_5=s_get_a (a_offset); + else + graph_5=s_get_b (b_offset); + graph_4=g_create_2 (graph_2,graph_5); + break; + case 2: + switch (b_size){ + case 0: + graph_5=s_get_a (a_offset); + graph_6=s_get_a (a_offset+1); + break; + case 1: + graph_5=s_get_a (a_offset); + graph_6=s_get_b (b_offset); + break; + default: + graph_5=s_get_b (b_offset); + graph_6=s_get_b (b_offset+1); + } + graph_4=g_create_3 (graph_2,graph_5,graph_6); + break; + default: + { + union instruction_parameter *parameter; + + if (a_size>0){ + graph_5=s_get_a (a_offset); + ++a_offset; + --a_size; + } else { + graph_5=s_get_b (b_offset); + ++b_offset; + --b_size; + } + + graph_3=g_create_m (a_size+b_size); + + parameter=graph_3->instruction_parameters; + + while (a_size>0){ + parameter->p=s_get_a (a_offset); + ++parameter; + ++a_offset; + --a_size; + } + + while (b_size>0){ + parameter->p=s_get_b (b_offset); + ++parameter; + ++b_offset; + --b_size; + } + + graph_4=g_create_3 (graph_2,graph_5,graph_3); + } + } + + s_push_a (graph_4); +} + +void code_build_u (char descriptor_name[],int a_size,int b_size,char *code_name) +{ + INSTRUCTION_GRAPH graph_2,graph_3,graph_4; + LABEL *descriptor_label,*code_label; + int n_arguments; + union instruction_parameter *parameter; + + code_label=enter_label (code_name,NODE_ENTRY_LABEL); + code_label->label_arity=a_size+b_size+(b_size<<8); + + if (descriptor_name[0]=='_' && descriptor_name[1]=='_' && descriptor_name[2]=='\0') + descriptor_label=NULL; + else + descriptor_label=enter_label (descriptor_name,DATA_LABEL); + + code_label->label_descriptor=descriptor_label; + + if (a_size+b_size<2){ + graph_2=g_create_m (3); + graph_2->instruction_parameters[1].p=NULL; + graph_2->instruction_parameters[2].p=NULL; + } else + graph_2=g_create_m (a_size+b_size+1); + parameter=&graph_2->instruction_parameters[0]; + + graph_3=g_lea (code_label); + parameter->p=graph_3; + ++parameter; + + for (n_arguments=a_size; n_arguments>0; --n_arguments){ + graph_4=s_pop_a(); + parameter->p=graph_4; + ++parameter; + } + + for (n_arguments=b_size; n_arguments>0; --n_arguments){ + graph_4=s_pop_b(); + parameter->p=graph_4; + ++parameter; + } + + s_push_a (graph_2); +} + +void code_buildB (int value) +{ + INSTRUCTION_GRAPH graph_2,graph_3,graph_4; + +#ifdef G_POWER + graph_2=g_g_register (BOOL_REGISTER); +#else + if (!parallel_flag && last_BOOL_descriptor_block==last_block) + graph_2=last_BOOL_descriptor_graph; + else { + if (BOOL_label==NULL) + BOOL_label=enter_label ("BOOL",IMPORT_LABEL | DATA_LABEL); + graph_2=g_load_des_i (BOOL_label,0); + + if (!parallel_flag){ + last_BOOL_descriptor_graph=graph_2; + last_BOOL_descriptor_block=last_block; + } + } +#endif + +#ifdef I486 + graph_3=g_load_i (value); +#else + graph_3=g_load_i (-value); +#endif + graph_4=g_create_2 (graph_2,graph_3); + + s_push_a (graph_4); +} + +void code_buildB_b (int b_offset) +{ + INSTRUCTION_GRAPH graph_2,graph_3,graph_4; + +#ifdef G_POWER + graph_2=g_g_register (BOOL_REGISTER); +#else + if (!parallel_flag && last_BOOL_descriptor_block==last_block) + graph_2=last_BOOL_descriptor_graph; + else { + if (BOOL_label==NULL) + BOOL_label=enter_label ("BOOL",IMPORT_LABEL | DATA_LABEL); + + graph_2=g_load_des_i (BOOL_label,0); + + if (!parallel_flag){ + last_BOOL_descriptor_graph=graph_2; + last_BOOL_descriptor_block=last_block; + } + } +#endif + + graph_3=s_get_b (b_offset); + graph_4=g_create_2 (graph_2,graph_3); + + s_push_a (graph_4); +} + +static INSTRUCTION_GRAPH char_descriptor_graph (void) +{ + INSTRUCTION_GRAPH graph; + +#ifdef G_POWER + graph=g_g_register (CHAR_REGISTER); +#else + if (!parallel_flag && last_CHAR_descriptor_block==last_block) + graph=last_CHAR_descriptor_graph; + else { + if (CHAR_label==NULL) + CHAR_label=enter_label ("CHAR",IMPORT_LABEL | DATA_LABEL); + graph=g_load_des_i (CHAR_label,0); + + if (!parallel_flag){ + last_CHAR_descriptor_graph=graph; + last_CHAR_descriptor_block=last_block; + } + } +#endif + return graph; +} + +void code_buildC (int value) +{ + INSTRUCTION_GRAPH graph_2,graph_3,graph_4; + + if (!parallel_flag){ + if (static_characters_label==NULL) + static_characters_label=enter_label ("static_characters",IMPORT_LABEL | DATA_LABEL); + + graph_4=g_lea_i (static_characters_label,(value<<3)+NODE_POINTER_OFFSET); + s_push_a (graph_4); + return; + } + + graph_2=char_descriptor_graph(); + graph_3=g_load_i (value); + graph_4=g_create_2 (graph_2,graph_3); + + s_push_a (graph_4); +} + +void code_buildC_b (int b_offset) +{ + INSTRUCTION_GRAPH graph_2,graph_3,graph_4; + + graph_2=char_descriptor_graph(); + graph_3=s_get_b (b_offset); + graph_4=g_create_2 (graph_2,graph_3); + + s_push_a (graph_4); +} + +void code_buildF_b (int b_offset) +{ + INSTRUCTION_GRAPH graph_2,graph_3,graph_4,graph_5; + + if (!parallel_flag && last_FILE_descriptor_block==last_block) + graph_2=last_FILE_descriptor_graph; + else { + if (FILE_label==NULL) + FILE_label=enter_label ("FILE",IMPORT_LABEL | DATA_LABEL); + + graph_2=g_load_des_i (FILE_label,0); + + if (!parallel_flag){ + last_FILE_descriptor_graph=graph_2; + last_FILE_descriptor_block=last_block; + } + } + + graph_3=s_get_b (b_offset+1); + graph_4=s_get_b (b_offset); + + graph_5=g_create_3 (graph_2,graph_3,graph_4); + + s_push_a (graph_5); +} + +static INSTRUCTION_GRAPH int_descriptor_graph (void) +{ + INSTRUCTION_GRAPH graph; + +#ifdef G_POWER + graph=g_g_register (INT_REGISTER); +#else + if (!parallel_flag && last_INT_descriptor_block==last_block) + graph=last_INT_descriptor_graph; + else { + if (INT_label==NULL) + INT_label=enter_label ("INT",IMPORT_LABEL | DATA_LABEL); + + graph=g_load_des_i (INT_label,0); + + if (!parallel_flag){ + last_INT_descriptor_graph=graph; + last_INT_descriptor_block=last_block; + } + } +#endif + return graph; +} + +void code_buildI (LONG value) +{ + INSTRUCTION_GRAPH graph_3,graph_4,graph_5; + + if (!parallel_flag && (unsigned long)value<(unsigned long)33){ + if (small_integers_label==NULL) + small_integers_label=enter_label ("small_integers",IMPORT_LABEL | DATA_LABEL); + + graph_5=g_lea_i (small_integers_label,(value<<3)+NODE_POINTER_OFFSET); + s_push_a (graph_5); + return; + } + + graph_3=int_descriptor_graph(); + graph_4=g_load_i (value); + graph_5=g_create_2 (graph_3,graph_4); + + s_push_a (graph_5); +} + +void code_buildI_b (int b_offset) +{ + INSTRUCTION_GRAPH graph_3,graph_4,graph_5; + + graph_3=int_descriptor_graph(); + graph_4=s_get_b (b_offset); + graph_5=g_create_2 (graph_3,graph_4); + + s_push_a (graph_5); +} + +static INSTRUCTION_GRAPH real_descriptor_graph (void) +{ + INSTRUCTION_GRAPH graph; + +#ifdef G_POWER + graph=g_g_register (REAL_REGISTER); +#else + if (!parallel_flag && last_REAL_descriptor_block==last_block) + graph=last_REAL_descriptor_graph; + else { + if (REAL_label==NULL) + REAL_label=enter_label ("REAL",IMPORT_LABEL | DATA_LABEL); + + graph=g_load_des_i (REAL_label,0); + + if (!parallel_flag){ + last_REAL_descriptor_graph=graph; + last_REAL_descriptor_block=last_block; + } + } +#endif + + return graph; +} + +void code_buildR (double value) +{ + INSTRUCTION_GRAPH graph_2,graph_3,graph_4,graph_5; + + graph_2=real_descriptor_graph(); + + if (!mc68881_flag){ + DOUBLE r=value; + + graph_3=g_load_i (((long*)&r)[0]); + graph_4=g_load_i (((long*)&r)[1]); + graph_5=g_create_3 (graph_2,graph_3,graph_4); + } else { + graph_3=g_fload_i (value); + graph_5=g_create_r (graph_2,graph_3); + } + + s_push_a (graph_5); +} + +void code_buildR_b (int b_offset) +{ + INSTRUCTION_GRAPH graph_2,graph_3,graph_4,graph_5; + + graph_2=real_descriptor_graph(); + + graph_3=s_get_b (b_offset); + graph_4=s_get_b (b_offset+1); + + if (!mc68881_flag) + graph_5=g_create_3 (graph_2,graph_3,graph_4); + else + graph_5=g_create_r (graph_2,g_fjoin (graph_3,graph_4)); + + s_push_a (graph_5); +} + +void code_buildAC (char *string,int string_length) +{ + INSTRUCTION_GRAPH graph_0; + LABEL *str_label; + + str_label=w_code_descriptor_length_and_string (string,string_length); +#if NODE_POINTER_OFFSET + graph_0=g_lea_i (str_label,NODE_POINTER_OFFSET); +#else + graph_0=g_lea (str_label); +#endif + + s_push_a (graph_0); +} + +void code_CtoI (VOID) +{ +} + +void code_cmpS (int a_offset_1,int a_offset_2) +{ + INSTRUCTION_GRAPH graph_1,graph_2; + + if (cmp_string_label==NULL) + cmp_string_label=enter_label ("cmp_string",IMPORT_LABEL); + + graph_1=s_get_a (a_offset_1); + graph_2=s_get_a (a_offset_2); + + s_push_a (graph_2); + s_push_a (graph_1); + + s_push_b (NULL); + insert_basic_block (JSR_BLOCK,2,0+1,e_vector,cmp_string_label); + + init_b_stack (1,i_vector); +} + +void code_CtoAC (VOID) +{ + INSTRUCTION_GRAPH graph_1,graph_2,graph_3,graph_4; + + if (!parallel_flag && last__STRING__descriptor_block==last_block) + graph_1=last__STRING__descriptor_graph; + else { + if (_STRING__label==NULL) + _STRING__label=enter_label ("__STRING__",IMPORT_LABEL | DATA_LABEL); + + graph_1=g_load_des_i (_STRING__label,0); + + if (!parallel_flag){ + last__STRING__descriptor_graph=graph_1; + last__STRING__descriptor_block=last_block; + } + } + + graph_2=g_load_i (1); + graph_3=s_pop_b(); +#ifndef I486 + graph_3=g_lsl (g_load_i (24),graph_3); +#endif + + graph_4=g_create_3 (graph_1,graph_2,graph_3); + + s_push_a (graph_4); +} + +static void code_create_lazy_array (VOID) +{ + if (create_array_label==NULL) + create_array_label=enter_label ("create_array",IMPORT_LABEL); + + s_push_b (s_get_b (0)); + s_put_b (1,NULL); + insert_basic_block (JSR_BLOCK,1,1+1,i_vector,create_array_label); + + init_a_stack (1); +} + +static void code_create_arrayB (VOID) +{ + if (create_arrayB_label==NULL) + create_arrayB_label=enter_label ("create_arrayB",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_arrayB_label); + + init_a_stack (1); +} + +static void code_create_arrayC (VOID) +{ + if (create_arrayC_label==NULL) + create_arrayC_label=enter_label ("create_arrayC",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_arrayC_label); + + init_a_stack (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); +} + +static void code_create_arrayR (VOID) +{ + if (create_arrayR_label==NULL) + create_arrayR_label=enter_label ("create_arrayR",IMPORT_LABEL); + +#ifdef M68000 + if (!mc68881_flag){ + LABEL *label2; + INSTRUCTION_GRAPH graph; + struct block_label *new_label; + + sprintf (eval_label_s,"e_%d",eval_label_number++); + label2=enter_label (eval_label_s,LOCAL_LABEL); + graph=g_lea (label2); + + s_push_b (s_get_b (0)); + s_put_b (1,s_get_b (2)); + s_put_b (2,s_get_b (3)); + s_put_b (3,graph); + insert_basic_block (JSR_BLOCK,0,3+1,i_r_vector,create_arrayR_label); + + new_label=fast_memory_allocate_type (struct block_label); + new_label->block_label_label=label2; + new_label->block_label_next=NULL; + + if (last_block->block_labels==NULL) + last_block->block_labels=new_label; + else + last_block_label->block_label_next=new_label; + last_block_label=new_label; + } else { +#endif + s_push_b (s_get_b (0)); + s_put_b (1,s_get_b (2)); + s_put_b (2,s_get_b (3)); + s_put_b (3,NULL); + insert_basic_block (JSR_BLOCK,0,3+1,i_r_vector,create_arrayR_label); +#ifdef M68000 + } +#endif + + init_a_stack (1); +} + +static void code_create_r_array (char element_descriptor[],int a_size,int b_size) +{ + INSTRUCTION_GRAPH graph_1,graph_2,graph_3,graph_4; + LABEL *descriptor; + + descriptor=enter_label (element_descriptor,DATA_LABEL); + + if (create_r_array_label==NULL) + create_r_array_label=enter_label ("create_R_array",IMPORT_LABEL); + + graph_1=s_pop_b(); + graph_2=g_load_des_i (descriptor,0); + graph_3=g_load_i (a_size+b_size); + graph_4=g_load_i (a_size); + +#if defined (I486) + { + INSTRUCTION_GRAPH graph; + struct block_label *new_label; + LABEL *label; + + sprintf (eval_label_s,"e_%d",eval_label_number++); + label=enter_label (eval_label_s,LOCAL_LABEL); + graph=g_lea (label); + + s_push_b (graph); + s_push_b (graph_1); + s_push_b (graph_2); + s_push_b (graph_3); + s_push_b (graph_4); + insert_basic_block_with_extra_parameters_on_stack (JSR_BLOCK,0,4+1,i_i_i_i_i_vector,a_size,b_size,create_r_array_label); + + new_label=fast_memory_allocate (sizeof (struct block_label)); + new_label->block_label_label=label; + new_label->block_label_next=NULL; + + if (last_block->block_labels==NULL) + last_block->block_labels=new_label; + else + last_block_label->block_label_next=new_label; + last_block_label=new_label; + } +#else + s_push_b (NULL); + s_push_b (graph_1); + s_push_b (graph_2); + s_push_b (graph_3); + s_push_b (graph_4); + insert_basic_block_with_extra_parameters_on_stack (JSR_BLOCK,0,4+1,i_i_i_i_i_vector,a_size,b_size,create_r_array_label); +#endif + + if (a_size!=0){ + s_put_a (a_size,s_get_a (0)); + code_pop_a (a_size); + } + + code_pop_b (b_size); + + init_a_stack (1); +} + +static int is__rocid (char *element_descriptor) +{ + return (element_descriptor[1]=='R' && element_descriptor[2]=='O' && element_descriptor[3]=='C' && + element_descriptor[4]=='I' && element_descriptor[5]=='D' && element_descriptor[6]=='\0'); +} + +static int is__orld (char *element_descriptor) +{ + return (element_descriptor[1]=='O' && element_descriptor[2]=='R' && element_descriptor[3]=='L' && + element_descriptor[4]=='D' && element_descriptor[5]=='\0'); +} + +void code_create_array (char element_descriptor[],int a_size,int b_size) +{ + switch (element_descriptor[0]){ + case 'B': + if (element_descriptor[1]=='O' && element_descriptor[2]=='O' && element_descriptor[3]=='L' && + element_descriptor[4]=='\0') + { + code_create_arrayB(); + return; + } + break; + case 'C': + if (element_descriptor[1]=='H' && element_descriptor[2]=='A' && element_descriptor[3]=='R' && + element_descriptor[4]=='\0') + { + code_create_arrayC(); + return; + } + break; + case 'I': + if (element_descriptor[1]=='N' && element_descriptor[2]=='T' && element_descriptor[3]=='\0'){ + code_create_arrayI(); + return; + } + break; + case 'P': + if (is__rocid (element_descriptor)){ + code_create_arrayI(); + return; + } + break; + case 'R': + if (element_descriptor[1]=='E' && element_descriptor[2]=='A' && element_descriptor[3]=='L' && + element_descriptor[4]=='\0') + { + code_create_arrayR(); + return; + } + break; + case 'A': + if (element_descriptor[1]=='R' && element_descriptor[2]=='R' && element_descriptor[3]=='A' && + element_descriptor[4]=='Y' && element_descriptor[5]=='\0') + { + code_create_lazy_array(); + return; + } + break; + case 'S': + if (element_descriptor[1]=='T' && element_descriptor[2]=='R' && element_descriptor[3]=='I' && + element_descriptor[4]=='N' && element_descriptor[5]=='G' && element_descriptor[6]=='\0') + { + code_create_lazy_array(); + return; + } + break; + case 'W': + if (is__orld (element_descriptor)){ + code_create_lazy_array(); + return; + } + break; + case '_': + if (element_descriptor[1]=='_' && element_descriptor[2]=='\0'){ + code_create_lazy_array(); + return; + } + break; + } + + code_create_r_array (element_descriptor,a_size,b_size); +} + +static void code_create_lazy_array_ (VOID) +{ + INSTRUCTION_GRAPH graph_1; + LABEL *nil_label; + + nil_label=enter_label ("__Nil",DATA_LABEL); + if (!parallel_flag) + graph_1=g_lea_i (nil_label,ARITY_0_DESCRIPTOR_OFFSET+NODE_POINTER_OFFSET); + else + graph_1=g_create_1 (g_load_des_i (nil_label,0)); + + s_push_a (graph_1); + code_create_lazy_array(); +} + +void code_create_array_ (char element_descriptor[],int a_size,int b_size) +{ + switch (element_descriptor[0]){ + case 'B': + if (element_descriptor[1]=='O' && element_descriptor[2]=='O' && element_descriptor[3]=='L' && + element_descriptor[4]=='\0') + { + if (create_arrayB__label==NULL) + create_arrayB__label=enter_label ("_create_arrayB",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_arrayB__label); + + init_a_stack (1); + return; + } + break; + case 'C': + if (element_descriptor[1]=='H' && element_descriptor[2]=='A' && element_descriptor[3]=='R' && + element_descriptor[4]=='\0') + { + if (create_arrayC__label==NULL) + create_arrayC__label=enter_label ("_create_arrayC",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_arrayC__label); + + init_a_stack (1); + return; + } + 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)){ + 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; n<size; ++n) + graph_2->instruction_parameters[3+n].p=NULL; + + s_push_a (graph_2); + return; + } +#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; + } + break; + case 'P': + if (is__rocid (element_descriptor)){ + 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; + } + break; + case 'R': + if (element_descriptor[1]=='E' && element_descriptor[2]=='A' && element_descriptor[3]=='L' && + element_descriptor[4]=='\0') + { + if (create_arrayR__label==NULL) + create_arrayR__label=enter_label ("_create_arrayR",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_arrayR__label); + + init_a_stack (1); + return; + } + break; + case 'A': + if (element_descriptor[1]=='R' && element_descriptor[2]=='R' && element_descriptor[3]=='A' && + element_descriptor[4]=='Y' && element_descriptor[5]=='\0') + { + code_create_lazy_array_(); + return; + } + break; + case 'S': + if (element_descriptor[1]=='T' && element_descriptor[2]=='R' && element_descriptor[3]=='I' && + element_descriptor[4]=='N' && element_descriptor[5]=='G' && element_descriptor[6]=='\0') + { + code_create_lazy_array_(); + return; + } + break; + case 'W': + if (is__orld (element_descriptor)){ + code_create_lazy_array_(); + return; + } + break; + case '_': + if (element_descriptor[1]=='_' && element_descriptor[2]=='\0'){ + code_create_lazy_array_(); + return; + } + break; + } + + { + INSTRUCTION_GRAPH graph_1,graph_2,graph_3,graph_4; + LABEL *descriptor; + + { + INSTRUCTION_GRAPH graph_1; + LABEL *nil_label; + + nil_label=enter_label ("__Nil",DATA_LABEL); + if (!parallel_flag) + graph_1=g_lea_i (nil_label,ARITY_0_DESCRIPTOR_OFFSET+NODE_POINTER_OFFSET); + else + graph_1=g_create_1 (g_load_des_i (nil_label,0)); + + s_push_a (graph_1); + } + + descriptor=enter_label (element_descriptor,DATA_LABEL); + + if (create_r_array__label==NULL) + create_r_array__label=enter_label ("_create_r_array",IMPORT_LABEL); + + graph_1=s_pop_b(); + graph_2=g_load_des_i (descriptor,0); + graph_3=g_load_i (a_size+b_size); + graph_4=g_load_i (a_size); + +#if defined (I486) + { + INSTRUCTION_GRAPH graph; + struct block_label *new_label; + LABEL *label; + + sprintf (eval_label_s,"e_%d",eval_label_number++); + label=enter_label (eval_label_s,LOCAL_LABEL); + graph=g_lea (label); + + s_push_b (graph); + s_push_b (graph_1); + s_push_b (graph_2); + s_push_b (graph_3); + s_push_b (graph_4); + insert_basic_block (JSR_BLOCK,1,4+1,i_i_i_i_i_vector,create_r_array__label); + + new_label=fast_memory_allocate (sizeof (struct block_label)); + new_label->block_label_label=label; + new_label->block_label_next=NULL; + + if (last_block->block_labels==NULL) + last_block->block_labels=new_label; + else + last_block_label->block_label_next=new_label; + last_block_label=new_label; + } +#else + s_push_b (NULL); + s_push_b (graph_1); + s_push_b (graph_2); + s_push_b (graph_3); + s_push_b (graph_4); + insert_basic_block (JSR_BLOCK,1,4+1,i_i_i_i_i_vector,create_r_array__label); +#endif + + init_a_stack (1); + } +} + +void code_cosR (VOID) +{ +#ifdef I486 + code_monadic_real_operator (GFCOS); +#else +# ifdef M68000 + if (!mc68881_flag){ +# endif + if (cos_real==NULL) + cos_real=enter_label ("cos_real",IMPORT_LABEL); + code_monadic_sane_operator (cos_real); + init_b_stack (2,r_vector); +# ifdef M68000 + } else + code_monadic_real_operator (GFCOS); +# endif +#endif +} + +void code_create (int n_arguments) +{ + INSTRUCTION_GRAPH graph_1,graph_2; + + if (EMPTY_label==NULL) + EMPTY_label=enter_label ("EMPTY",IMPORT_LABEL | DATA_LABEL); + + if (n_arguments<=2){ +#if !(defined (sparc) || defined (G_POWER)) + if (!parallel_flag){ + if (cycle_in_spine_label==NULL){ + cycle_in_spine_label=enter_label ("__cycle__in__spine",IMPORT_LABEL | NODE_ENTRY_LABEL); + cycle_in_spine_label->label_arity=0; + cycle_in_spine_label->label_descriptor=EMPTY_label; + } + graph_1=g_lea (cycle_in_spine_label); + } else { + if (reserve_label==NULL){ + reserve_label=enter_label ("__reserve",IMPORT_LABEL | NODE_ENTRY_LABEL); + reserve_label->label_arity=0; + reserve_label->label_descriptor=EMPTY_label; + } + graph_1=g_lea (reserve_label); + } +#else + graph_1=g_g_register (RESERVE_CODE_REGISTER); +#endif + graph_2=g_create_3 (graph_1,NULL,NULL); + } else { + char cycle_in_spine_label_n [64]; + LABEL *cycle_label_n; + int n; + + sprintf (cycle_in_spine_label_n,"_c%d",n_arguments); + cycle_label_n=enter_label (cycle_in_spine_label_n,NODE_ENTRY_LABEL | IMPORT_LABEL); + cycle_label_n->label_arity=n_arguments; + cycle_label_n->label_descriptor=EMPTY_label; + + graph_1=g_lea (cycle_label_n); + + graph_2=g_create_m (n_arguments+1); + graph_2->instruction_parameters[0].p=graph_1; + + for (n=0; n<n_arguments; ++n) + graph_2->instruction_parameters[n+1].p=NULL; + } + + s_push_a (graph_2); +} + +void code_decI (VOID) +{ + INSTRUCTION_GRAPH graph_1,graph_2,graph_3; + + graph_1=s_get_b (0); + graph_2=g_load_i (1); + graph_3=g_sub (graph_2,graph_1); + s_put_b (0,graph_3); +} + +void code_del_args (int source_offset,int n_arguments,int destination_offset) +{ + INSTRUCTION_GRAPH graph_1,graph_2,graph_3; + + if (del_args_label==NULL) + del_args_label=enter_label ("del_args",IMPORT_LABEL); + + graph_1=s_get_a (source_offset); + graph_2=s_get_a (destination_offset); + graph_3=g_load_i (n_arguments<<2); + + s_push_a (graph_1); + s_push_a (graph_2); + + s_push_b (NULL); + + s_push_b (graph_3); + + insert_basic_block (JSR_BLOCK,2,1+1,i_vector,del_args_label); +} + +void code_divI (VOID) +{ +#ifdef M68000 + if (!mc68000_flag){ +#endif + INSTRUCTION_GRAPH graph_1,graph_2,graph_3; + + graph_1=s_pop_b(); + graph_2=s_get_b (0); + graph_3=g_div (graph_2,graph_1); + s_put_b (0,graph_3); +#ifdef M68000 + } else { + if (div_label==NULL) + div_label=enter_label ("divide",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,div_label); + + init_b_stack (1,i_vector); + } +#endif +} + +void code_divR (VOID) +{ + INSTRUCTION_GRAPH graph_1,graph_2,graph_3,graph_4,graph_5,graph_6,graph_7,graph_8,graph_9; + +#ifdef M68000 + if (!mc68881_flag){ + if (div_real==NULL) + div_real=enter_label ("div_real",IMPORT_LABEL); + code_dyadic_sane_operator (div_real); + init_b_stack (2,r_vector); + } else { +#endif + graph_1=s_pop_b(); + graph_2=s_pop_b(); + graph_3=g_fjoin (graph_1,graph_2); + + graph_4=s_get_b (0); + graph_5=s_get_b (1); + graph_6=g_fjoin (graph_4,graph_5); + + graph_7=g_fdiv (graph_6,graph_3); + + g_fhighlow (graph_8,graph_9,graph_7); + + s_put_b (0,graph_8); + s_put_b (1,graph_9); +#ifdef M68000 + } +#endif +} + +void code_entierR (VOID) +{ + if (entier_real_label==NULL) + entier_real_label=enter_label ("entier_real",IMPORT_LABEL); + +#ifdef M68000 + if (!mc68881_flag) + code_monadic_sane_operator (entier_real_label); + else { +#endif + 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,r_vector,entier_real_label); +#ifdef M68000 + } +#endif + init_b_stack (1,i_vector); +} + +void code_eqB (VOID) +{ + INSTRUCTION_GRAPH graph_1,graph_2,graph_3; + + graph_1=s_pop_b(); + graph_2=s_get_b (0); + graph_3=g_cmp_eq (graph_2,graph_1); + + s_put_b (0,graph_3); +} + +void code_eqB_a (int value,int a_offset) +{ + INSTRUCTION_GRAPH graph_1,graph_2,graph_3,graph_4; + + graph_1=s_get_a (a_offset); + graph_2=g_load_id (ARGUMENTS_OFFSET-NODE_POINTER_OFFSET,graph_1); +#ifdef I486 + graph_3=g_load_i (value); +#else + graph_3=g_load_i (-value); +#endif + graph_4=g_cmp_eq (graph_3,graph_2); + + s_push_b (graph_4); +} + +void code_eqB_b (int value,int b_offset) +{ + INSTRUCTION_GRAPH graph_1,graph_2,graph_3; + + graph_1=s_get_b (b_offset); +#ifdef I486 + graph_2=g_load_i (value); +#else + graph_2=g_load_i (-value); +#endif + graph_3=g_cmp_eq (graph_2,graph_1); + + s_push_b (graph_3); +} + +void code_eqC (VOID) +{ + INSTRUCTION_GRAPH graph_1,graph_2,graph_3; + + graph_1=s_pop_b(); + graph_2=s_get_b (0); + graph_3=g_cmp_eq (graph_2,graph_1); + + s_put_b (0,graph_3); +} + +void code_eqC_a (int value,int a_offset) +{ + INSTRUCTION_GRAPH graph_1,graph_2,graph_3,graph_4; + + graph_1=s_get_a (a_offset); + graph_2=g_load_id (ARGUMENTS_OFFSET-NODE_POINTER_OFFSET,graph_1); + graph_3=g_load_i (value); + graph_4=g_cmp_eq (graph_3,graph_2); + + s_push_b (graph_4); +} + +void code_eqC_b (int value,int b_offset) +{ + INSTRUCTION_GRAPH graph_1,graph_2,graph_3; + + graph_1=s_get_b (b_offset); + graph_2=g_load_i (value); + graph_3=g_cmp_eq (graph_2,graph_1); + + s_push_b (graph_3); +} + +void code_eqD_b (char descriptor_name[],int arity) +{ + INSTRUCTION_GRAPH graph_1,graph_2,graph_3; + LABEL *descriptor; + + descriptor=enter_label (descriptor_name,DATA_LABEL); + + graph_1=s_get_b (0); + + graph_2=g_load_des_i (descriptor,arity); + graph_3=g_cmp_eq (graph_2,graph_1); + + s_push_b (graph_3); +} + +void code_eqI (VOID) +{ + INSTRUCTION_GRAPH graph_1,graph_2,graph_3; + + graph_1=s_pop_b(); + graph_2=s_get_b (0); + graph_3=g_cmp_eq (graph_2,graph_1); + + s_put_b (0,graph_3); +} + +void code_eqI_a (LONG value,int a_offset) +{ + INSTRUCTION_GRAPH graph_1,graph_2,graph_3,graph_4; + + graph_1=s_get_a (a_offset); + graph_2=g_load_id (ARGUMENTS_OFFSET-NODE_POINTER_OFFSET,graph_1); + graph_3=g_load_i (value); + graph_4=g_cmp_eq (graph_3,graph_2); + + s_push_b (graph_4); +} + +void code_eqI_b (LONG value,int b_offset) +{ + INSTRUCTION_GRAPH graph_1,graph_2,graph_3; + + graph_1=s_get_b (b_offset); + graph_2=g_load_i (value); + graph_3=g_cmp_eq (graph_2,graph_1); + + s_push_b (graph_3); +} + +void code_eqR (VOID) +{ + INSTRUCTION_GRAPH graph_1,graph_2,graph_3,graph_4,graph_5,graph_6,graph_7; + +#ifdef M68000 + if (!mc68881_flag){ + if (eq_real==NULL) + eq_real=enter_label ("eq_real",IMPORT_LABEL); + + code_dyadic_sane_operator (eq_real); + init_b_stack (1,i_vector); + } else { +#endif + graph_1=s_pop_b(); + graph_2=s_pop_b(); + graph_3=g_fjoin (graph_1,graph_2); + + graph_4=s_pop_b(); + graph_5=s_pop_b(); + graph_6=g_fjoin (graph_4,graph_5); + + graph_7=g_fcmp_eq (graph_6,graph_3); + + s_push_b (graph_7); +#ifdef M68000 + } +#endif +} + +void code_eqR_a (double value,int a_offset) +{ + INSTRUCTION_GRAPH graph_1,graph_3,graph_4,graph_5; + +#ifdef M68000 + if (!mc68881_flag){ + INSTRUCTION_GRAPH graph_6,graph_7; + + DOUBLE r=value; + + if (eq_real==NULL) + eq_real=enter_label ("eq_real",IMPORT_LABEL); + + graph_1=s_get_a (a_offset); + /* + graph_3=g_movem (ARGUMENTS_OFFSET,graph_1,2); + graph_4=g_movemi (0,graph_3); + graph_5=g_movemi (1,graph_3); + */ + graph_4=g_load_id (ARGUMENTS_OFFSET-NODE_POINTER_OFFSET,graph_1); + graph_5=g_load_id (ARGUMENTS_OFFSET-NODE_POINTER_OFFSET+4,graph_1); + + graph_6=g_load_i (((long*)&r)[0]); + graph_7=g_load_i (((long*)&r)[1]); + + s_push_b (graph_4); + s_push_b (graph_5); + s_push_b (graph_6); + s_push_b (graph_7); + + code_dyadic_sane_operator (eq_real); + init_b_stack (1,i_vector); + } else { +#endif + graph_1=s_get_a (a_offset); + graph_3=g_fload_id (ARGUMENTS_OFFSET-NODE_POINTER_OFFSET,graph_1); + + graph_4=g_fload_i (value); + + graph_5=g_fcmp_eq (graph_4,graph_3); + + s_push_b (graph_5); +#ifdef M68000 + } +#endif +} + +void code_eqR_b (double value,int b_offset) +{ + INSTRUCTION_GRAPH graph_1,graph_2,graph_3,graph_4,graph_5; + +#ifdef M68000 + if (!mc68881_flag){ + DOUBLE r=value; + + if (eq_real==NULL) + eq_real=enter_label ("eq_real",IMPORT_LABEL); + + graph_1=s_get_b (b_offset+1); + graph_2=s_get_b (b_offset); + graph_3=g_load_i (((long*)&r)[0]); + graph_4=g_load_i (((long*)&r)[1]); + + s_push_b (graph_1); + s_push_b (graph_2); + s_push_b (graph_3); + s_push_b (graph_4); + + code_dyadic_sane_operator (eq_real); + init_b_stack (1,i_vector); + } else { +#endif + graph_1=s_get_b (b_offset); + graph_2=s_get_b (b_offset+1); + graph_3=g_fjoin (graph_1,graph_2); + + graph_4=g_fload_i (value); + + graph_5=g_fcmp_eq (graph_4,graph_3); + + s_push_b (graph_5); +#ifdef M68000 + } +#endif +} + +void code_eqAC_a (char *string,int string_length) +{ + INSTRUCTION_GRAPH graph_1,graph_2; + LABEL *string_label; + + if (equal_string_label==NULL) + equal_string_label=enter_label ("eqAC",IMPORT_LABEL); + + string_label=w_code_length_and_string (string,string_length); + + graph_1=s_pop_a(); + graph_2=g_lea_i (string_label,-4); + + s_push_a (graph_2); + s_push_a (graph_1); + + s_push_b (NULL); + + insert_basic_block (JSR_BLOCK,2,0+1,e_vector,equal_string_label); + + init_b_stack (1,i_vector); +} + +void code_eq_desc (char descriptor_name[],int arity,int a_offset) +{ + INSTRUCTION_GRAPH graph_1,graph_2,graph_3,graph_4; + LABEL *descriptor; + + descriptor=enter_label (descriptor_name,DATA_LABEL); + + graph_1=s_get_a (a_offset); + +#ifndef M68000 + graph_2=g_load_id (0,graph_1); +#else + graph_2=g_load_des_id (DESCRIPTOR_OFFSET,graph_1); +#endif + + graph_3=g_load_des_i (descriptor,arity); + graph_4=g_cmp_eq (graph_3,graph_2); + + s_push_b (graph_4); +} + +void code_eq_desc_b (char descriptor_name[],int arity) +{ + INSTRUCTION_GRAPH graph_1,graph_2,graph_3; + LABEL *descriptor; + + descriptor=enter_label (descriptor_name,DATA_LABEL); + + graph_1=s_pop_b(); + + graph_2=g_load_des_i (descriptor,arity); + graph_3=g_cmp_eq (graph_2,graph_1); + + s_push_b (graph_3); +} + +void code_eq_nulldesc (char descriptor_name[],int a_offset) +{ + INSTRUCTION_GRAPH graph_1,graph_2,graph_3,graph_4,graph_5,graph_6,graph_7,graph_8; + LABEL *descriptor; + + descriptor=enter_label (descriptor_name,DATA_LABEL); + + graph_1=s_get_a (a_offset); + +#ifdef GEN_MAC_OBJ + graph_2=g_load_des_id (DESCRIPTOR_OFFSET,graph_1); + graph_3=g_g_register (GLOBAL_DATA_REGISTER); +#else + graph_2=g_load_id (0,graph_1); + graph_3=g_load_i (-2); +#endif + graph_4=g_add (graph_3,graph_2); +#ifdef GEN_MAC_OBJ + graph_5=g_load_des_id (0,graph_4); +#else + graph_5=g_load_des_id (2,graph_4); +#endif + graph_6=g_sub (graph_5,graph_2); + graph_7=g_load_des_i (descriptor,0); + graph_8=g_cmp_eq (graph_7,graph_6); + + s_push_b (graph_8); +} + +void code_eq_symbol (int a_offset_1,int a_offset_2) +{ + INSTRUCTION_GRAPH graph_1,graph_2; + + if (eqD_label==NULL) + eqD_label=enter_label ("eqD",IMPORT_LABEL); + + graph_1=s_get_a (a_offset_1); + graph_2=s_get_a (a_offset_2); + + s_push_a (graph_2); + s_push_a (graph_1); + + s_push_b (NULL); + insert_basic_block (JSR_BLOCK,2,0+1,e_vector,eqD_label); + + init_b_stack (1,i_vector); +} + +void code_exit_false (char label_name[]) +{ +#ifndef M68000 + INSTRUCTION_GRAPH condition_graph,result_graph; + LABEL *label; + + condition_graph=s_pop_b(); + result_graph=s_get_a (0); + + label=enter_label (label_name, +# ifdef G_POWER + FAR_CONDITIONAL_JUMP_LABEL +# else + 0 +# endif + ); + + result_graph=g_exit_if (label,condition_graph,result_graph); + + s_put_a (0,result_graph); +#else + sprintf (eval_label_s,"e_%d",eval_label_number++); + code_jmp_true (eval_label_s); + code_jmp (label_name); + code_label (eval_label_s); +#endif +} + +void code_expR (VOID) +{ +#ifdef M68000 + if (!mc68881_flag){ +#endif + if (exp_real==NULL) + exp_real=enter_label ("exp_real",IMPORT_LABEL); + code_monadic_sane_operator (exp_real); + init_b_stack (2,r_vector); +#ifdef M68000 + } else + code_monadic_real_operator (GFEXP); +#endif +} + +void code_fill_r (char descriptor_name[],int a_size,int b_size,int root_offset,int a_offset,int b_offset) +{ + INSTRUCTION_GRAPH graph_1,graph_2,graph_3,graph_4,graph_5,graph_6; + LABEL *descriptor_label; + + graph_1=s_get_a (root_offset); + + descriptor_label=enter_label (descriptor_name,DATA_LABEL); + + if (!parallel_flag && descriptor_label->label_last_lea_block==last_block) + graph_2=descriptor_label->label_last_lea; + else { + graph_2=g_load_des_i (descriptor_label,0); + + if (!parallel_flag ){ + descriptor_label->label_last_lea=graph_2; + descriptor_label->label_last_lea_block=last_block; + } + } + + switch (a_size+b_size){ + case 0: + graph_4=g_fill_2 (graph_1,graph_2); + break; + case 1: + if (a_size!=0) + graph_5=s_get_a (a_offset); + else + graph_5=s_get_b (b_offset); + graph_4=g_fill_3 (graph_1,graph_2,graph_5); + break; + case 2: + switch (b_size){ + case 0: + graph_5=s_get_a (a_offset); + graph_6=s_get_a (a_offset+1); + break; + case 1: + graph_5=s_get_a (a_offset); + graph_6=s_get_b (b_offset); + break; + default: + graph_5=s_get_b (b_offset); + graph_6=s_get_b (b_offset+1); + } + graph_4=g_fill_4 (graph_1,graph_2,graph_5,graph_6); + break; + default: + { + union instruction_parameter *parameter; + + if (a_size>0){ + graph_5=s_get_a (a_offset); + ++a_offset; + --a_size; + } else { + graph_5=s_get_b (b_offset); + ++b_offset; + --b_size; + } + + graph_3=g_create_m (a_size+b_size); + + parameter=graph_3->instruction_parameters; + + while (a_size>0){ + parameter->p=s_get_a (a_offset); + ++parameter; + ++a_offset; + --a_size; + } + + while (b_size>0){ + parameter->p=s_get_b (b_offset); + ++parameter; + ++b_offset; + --b_size; + } + + graph_4=g_fill_4 (graph_1,graph_2,graph_5,graph_3); + } + } + + s_put_a (root_offset,graph_4); +} + +void code_fill (char descriptor_name[],int arity,char *code_name,int a_offset) +{ + INSTRUCTION_GRAPH graph_1,graph_2,graph_3,graph_4; + LABEL *descriptor_label,*code_label; + + if (strcmp (code_name,"__hnf")==0){ + code_fillh (descriptor_name,arity,a_offset); + } else { + int n_arguments; + union instruction_parameter *parameter; + + graph_1=s_get_a (a_offset); + + code_label=enter_label (code_name,NODE_ENTRY_LABEL); + code_label->label_arity=arity; + + if (descriptor_name[0]=='_' && descriptor_name[1]=='_' && descriptor_name[2]=='\0') + descriptor_label=NULL; + else +#if SMALL_LAZY_DESCRIPTORS + if (parallel_flag){ + char curried_descriptor_name[257]; + + strcpy (curried_descriptor_name,descriptor_name); + strcat (curried_descriptor_name,"#"); + + descriptor_label=enter_label (curried_descriptor_name,DATA_LABEL); + } else +#endif + descriptor_label=enter_label (descriptor_name,DATA_LABEL); + + if (arity<-2) + arity=1; + + if (code_label->label_flags & EA_LABEL + && code_label->label_ea_label!=eval_fill_label + && arity>=0 && eval_upd_labels[arity]==NULL) + { + char eval_upd_label_name[32]; + + sprintf (eval_upd_label_name,"eval_upd_%d",arity); + eval_upd_labels[arity]=enter_label (eval_upd_label_name,IMPORT_LABEL); + } + + if (arity<0) + arity=1; + + code_label->label_descriptor=descriptor_label; + + if (arity<2){ + graph_2=g_fill_m (graph_1,3); + graph_2->instruction_parameters[2].p=NULL; + graph_2->instruction_parameters[3].p=NULL; + } else + graph_2=g_fill_m (graph_1,arity+1); + parameter=&graph_2->instruction_parameters[1]; + + graph_3=g_lea (code_label); + parameter->p=graph_3; + ++parameter; + + for (n_arguments=arity; n_arguments>0; --n_arguments){ + graph_4=s_pop_a(); + parameter->p=graph_4; + ++parameter; + } + + s_put_a (a_offset-arity,graph_2); + } +} + +void code_fillcp (char descriptor_name[],int arity,char *code_name,int a_offset,char bits[]) +{ + INSTRUCTION_GRAPH graph_1,graph_2,graph_3,graph_4; + LABEL *descriptor_label,*code_label; + int argument_n; + union instruction_parameter *parameter; + + graph_1=s_get_a (a_offset); + + if (bits[0]!='0'){ + code_label=enter_label (code_name,NODE_ENTRY_LABEL); + code_label->label_arity=arity; + + if (descriptor_name[0]=='_' && descriptor_name[1]=='_' && descriptor_name[2]=='\0') + descriptor_label=NULL; + else +#if SMALL_LAZY_DESCRIPTORS + if (parallel_flag){ + char curried_descriptor_name[257]; + + strcpy (curried_descriptor_name,descriptor_name); + strcat (curried_descriptor_name,"#"); + + descriptor_label=enter_label (curried_descriptor_name,DATA_LABEL); + } else +#endif + descriptor_label=enter_label (descriptor_name,DATA_LABEL); + + if (arity<-2) + arity=1; + + if (code_label->label_flags & EA_LABEL + && code_label->label_ea_label!=eval_fill_label + && arity>=0 && eval_upd_labels[arity]==NULL) + { + char eval_upd_label_name[32]; + + sprintf (eval_upd_label_name,"eval_upd_%d",arity); + eval_upd_labels[arity]=enter_label (eval_upd_label_name,IMPORT_LABEL); + } + + if (arity<0) + arity=1; + + code_label->label_descriptor=descriptor_label; + + graph_3=g_lea (code_label); + } else { + if (arity<0) + arity=1; + graph_3=NULL; + } + + if (arity<2){ + graph_2=g_fill_m (graph_1,3); + graph_2->instruction_parameters[2].p=NULL; + graph_2->instruction_parameters[3].p=NULL; + } else + graph_2=g_fill_m (graph_1,arity+1); + parameter=&graph_2->instruction_parameters[1]; + + parameter->p=graph_3; + ++parameter; + + for (argument_n=0; argument_n<arity; ++argument_n){ + if (bits[argument_n+1]!='0'){ + graph_4=s_pop_a(); + --a_offset; + } else + graph_4=NULL; + parameter->p=graph_4; + ++parameter; + } + + s_put_a (a_offset,graph_2); +} + +void code_fillcp_u (char descriptor_name[],int a_size,int b_size,char *code_name,int a_offset,char bits[]) +{ + INSTRUCTION_GRAPH graph_1,graph_2,graph_3,graph_4; + LABEL *descriptor_label,*code_label; + int argument_n; + union instruction_parameter *parameter; + + graph_1=s_get_a (a_offset); + + if (bits[0]!='0'){ + code_label=enter_label (code_name,NODE_ENTRY_LABEL); + code_label->label_arity=a_size+b_size+(b_size<<8); + + if (descriptor_name[0]=='_' && descriptor_name[1]=='_' && descriptor_name[2]=='\0') + descriptor_label=NULL; + else + descriptor_label=enter_label (descriptor_name,DATA_LABEL); + + code_label->label_descriptor=descriptor_label; + + graph_3=g_lea (code_label); + } else { + graph_3=NULL; + } + + if (a_size+b_size<2){ + graph_2=g_fill_m (graph_1,3); + graph_2->instruction_parameters[2].p=NULL; + graph_2->instruction_parameters[3].p=NULL; + } else + graph_2=g_fill_m (graph_1,a_size+b_size+1); + parameter=&graph_2->instruction_parameters[1]; + + parameter->p=graph_3; + ++parameter; + + argument_n=0; + for (; argument_n<a_size; ++argument_n){ + if (bits[argument_n+1]!='0'){ + graph_4=s_pop_a(); + --a_offset; + } else + graph_4=NULL; + parameter->p=graph_4; + ++parameter; + } + + for (; argument_n<a_size+b_size; ++argument_n){ + if (bits[argument_n+1]!='0'){ + graph_4=s_pop_b(); + } else + graph_4=NULL; + parameter->p=graph_4; + ++parameter; + } + + s_put_a (a_offset,graph_2); +} + +void code_fill_u (char descriptor_name[],int a_size,int b_size,char *code_name,int a_offset) +{ + INSTRUCTION_GRAPH graph_1,graph_2,graph_3,graph_4; + LABEL *descriptor_label,*code_label; + int argument_n; + union instruction_parameter *parameter; + + graph_1=s_get_a (a_offset); + + code_label=enter_label (code_name,NODE_ENTRY_LABEL); + code_label->label_arity=a_size+b_size+(b_size<<8); + + if (descriptor_name[0]=='_' && descriptor_name[1]=='_' && descriptor_name[2]=='\0') + descriptor_label=NULL; + else + descriptor_label=enter_label (descriptor_name,DATA_LABEL); + + code_label->label_descriptor=descriptor_label; + + graph_3=g_lea (code_label); + + if (a_size+b_size<2){ + graph_2=g_fill_m (graph_1,3); + graph_2->instruction_parameters[2].p=NULL; + graph_2->instruction_parameters[3].p=NULL; + } else + graph_2=g_fill_m (graph_1,a_size+b_size+1); + parameter=&graph_2->instruction_parameters[1]; + + parameter->p=graph_3; + ++parameter; + + argument_n=0; + for (; argument_n<a_size; ++argument_n){ + graph_4=s_pop_a(); + --a_offset; + parameter->p=graph_4; + ++parameter; + } + + for (; argument_n<a_size+b_size; ++argument_n){ + graph_4=s_pop_b(); + parameter->p=graph_4; + ++parameter; + } + + s_put_a (a_offset,graph_2); +} + +void code_fillh (char descriptor_name[],int arity,int a_offset) +{ + INSTRUCTION_GRAPH graph_1,graph_2,graph_3,graph_4,graph_5,graph_6; + LABEL *descriptor_label; + + graph_1=s_get_a (a_offset); + + descriptor_label=enter_label (descriptor_name,DATA_LABEL); + + if (!parallel_flag && + arity==0 && graph_1->instruction_code==GCREATE && graph_1->inode_arity>0) + { + graph_1->instruction_code=GLEA; + graph_1->inode_arity=1; + graph_1->instruction_parameters[0].l=descriptor_label; + graph_1->instruction_parameters[1].i=ARITY_0_DESCRIPTOR_OFFSET+NODE_POINTER_OFFSET; + return; + } + + if (!parallel_flag && + descriptor_label->label_last_lea_block==last_block && + descriptor_label->label_last_lea_arity==arity) + { + graph_2=descriptor_label->label_last_lea; + } else { + graph_2=g_load_des_i (descriptor_label,arity); + + if (!parallel_flag ){ + descriptor_label->label_last_lea=graph_2; + descriptor_label->label_last_lea_block=last_block; + descriptor_label->label_last_lea_arity=arity; + } + } + + switch (arity){ + case 0: + graph_4=g_fill_2 (graph_1,graph_2); + break; + case 1: + graph_5=s_pop_a(); + graph_4=g_fill_3 (graph_1,graph_2,graph_5); + break; + case 2: + graph_5=s_pop_a(); + graph_6=s_pop_a(); + graph_4=g_fill_4 (graph_1,graph_2,graph_5,graph_6); + break; + default: + { + int n_arguments; + union instruction_parameter *parameter; + + graph_5=s_pop_a(); + + graph_3=g_create_m (arity-1); + parameter=graph_3->instruction_parameters; + for (n_arguments=arity-1; n_arguments>0; --n_arguments){ + graph_6=s_pop_a(); + parameter->p=graph_6; + ++parameter; + } + + graph_4=g_fill_4 (graph_1,graph_2,graph_5,graph_3); + } + } + + s_put_a (a_offset-arity,graph_4); +} + +void code_fill1 (char descriptor_name[],int arity,int a_offset,char bits[]) +{ + INSTRUCTION_GRAPH graph_1,graph_2,graph_3,graph_4,graph_5,graph_6; + LABEL *descriptor_label; + + graph_1=s_get_a (a_offset); + + if (!parallel_flag && arity==0 && graph_1->instruction_code==GCREATE && graph_1->inode_arity>0){ + descriptor_label=enter_label (descriptor_name,DATA_LABEL); + + graph_1->instruction_code=GLEA; + graph_1->inode_arity=1; + graph_1->instruction_parameters[0].l=descriptor_label; + graph_1->instruction_parameters[1].i=ARITY_0_DESCRIPTOR_OFFSET+NODE_POINTER_OFFSET; + return; + } + + if (bits[0]=='1'){ + descriptor_label=enter_label (descriptor_name,DATA_LABEL); + + if (!parallel_flag && + descriptor_label->label_last_lea_block==last_block && + descriptor_label->label_last_lea_arity==arity) + { + graph_2=descriptor_label->label_last_lea; + } else { + graph_2=g_load_des_i (descriptor_label,arity); + + if (!parallel_flag ){ + descriptor_label->label_last_lea=graph_2; + descriptor_label->label_last_lea_block=last_block; + descriptor_label->label_last_lea_arity=arity; + } + } + } else + graph_2=NULL; + + switch (arity){ + case 0: + graph_4=g_fill_2 (graph_1,graph_2); + break; + case 1: + if (bits[1]=='0') + graph_5=NULL; + else { + --a_offset; + graph_5=s_pop_a(); + } + graph_4=g_fill_3 (graph_1,graph_2,graph_5); + break; + case 2: + if (bits[1]=='0') + graph_5=NULL; + else { + --a_offset; + graph_5=s_pop_a(); + } + if (bits[2]=='0') + graph_6=NULL; + else { + --a_offset; + graph_6=s_pop_a(); + } + graph_4=g_fill_4 (graph_1,graph_2,graph_5,graph_6); + break; + default: + { + int argument_n; + union instruction_parameter *parameter; + + if (bits[1]=='0') + graph_5=NULL; + else { + --a_offset; + graph_5=s_pop_a(); + } + + graph_3=g_create_m (arity-1); + parameter=graph_3->instruction_parameters; + + for (argument_n=1; argument_n<arity; ++argument_n){ + if (bits[argument_n+1]=='0') + graph_6=NULL; + else + graph_6=s_pop_a(); + parameter->p=graph_6; + ++parameter; + } + + graph_4=g_fill_4 (graph_1,graph_2,graph_5,graph_3); + } + } + + s_put_a (a_offset,graph_4); +} + +void code_fill2 (char descriptor_name[],int arity,int a_offset,char bits[]) +{ + INSTRUCTION_GRAPH graph_1,graph_2,graph_3,graph_4,graph_5,graph_6; + LABEL *descriptor_label; + int argument_n; + union instruction_parameter *parameter; + + graph_1=s_get_a (a_offset); + if (graph_1->instruction_code==GBEFORE0) + graph_1->instruction_code=GBEFORE; + + if (bits[0]=='1'){ + descriptor_label=enter_label (descriptor_name,DATA_LABEL); + + if (!parallel_flag && + descriptor_label->label_last_lea_block==last_block && + descriptor_label->label_last_lea_arity==arity) + { + graph_2=descriptor_label->label_last_lea; + } else { + graph_2=g_load_des_i (descriptor_label,arity); + + if (!parallel_flag ){ + descriptor_label->label_last_lea=graph_2; + descriptor_label->label_last_lea_block=last_block; + descriptor_label->label_last_lea_arity=arity; + } + } + } else + graph_2=NULL; + + if (bits[1]=='0') + graph_5=NULL; + else { + graph_5=s_pop_a(); + --a_offset; + } + + graph_3=g_fill_m (g_load_id (8-NODE_POINTER_OFFSET,graph_1),arity-1); + + parameter=&graph_3->instruction_parameters[1]; + for (argument_n=1; argument_n<arity; ++argument_n){ + if (bits[argument_n+1]=='0') + graph_6=NULL; + else { + graph_6=s_pop_a(); + --a_offset; + } + + parameter->p=graph_6; + ++parameter; + } + + graph_4=g_fill_3 (g_keep (graph_3,graph_1),graph_2,graph_5); + + s_put_a (a_offset,graph_4); +} + +void code_fill3 (char descriptor_name[],int arity,int a_offset,char bits[]) +{ + INSTRUCTION_GRAPH graph_0,graph_1,graph_2,graph_3,graph_4,graph_5,graph_6; + LABEL *descriptor_label; + union instruction_parameter *parameter; + int a_n; + + graph_0=s_pop_a(); + if (graph_0->instruction_code==GBEFORE0) + graph_0->instruction_code=GBEFORE; + --a_offset; + +#if !(defined (sparc) || defined (G_POWER)) + if (!parallel_flag){ + if (cycle_in_spine_label==NULL){ + cycle_in_spine_label=enter_label ("__cycle__in__spine",IMPORT_LABEL | NODE_ENTRY_LABEL); + cycle_in_spine_label->label_arity=0; + cycle_in_spine_label->label_descriptor=EMPTY_label; + } + graph_6=g_lea (cycle_in_spine_label); + } else { + if (reserve_label==NULL){ + reserve_label=enter_label ("__reserve",IMPORT_LABEL | NODE_ENTRY_LABEL); + reserve_label->label_arity=0; + reserve_label->label_descriptor=EMPTY_label; + } + graph_6=g_lea (reserve_label); + } +#else + graph_6=g_g_register (RESERVE_CODE_REGISTER); +#endif + graph_0=g_fill_2 (graph_0,graph_6); + + graph_1=s_get_a (a_offset); + if (graph_1->instruction_code==GBEFORE0) + graph_1->instruction_code=GBEFORE; + + descriptor_label=enter_label (descriptor_name,DATA_LABEL); + + if (!parallel_flag && descriptor_label->label_last_lea_block==last_block && descriptor_label->label_last_lea_arity==arity) + graph_2=descriptor_label->label_last_lea; + else { + graph_2=g_load_des_i (descriptor_label,arity); + + if (!parallel_flag ){ + descriptor_label->label_last_lea=graph_2; + descriptor_label->label_last_lea_block=last_block; + descriptor_label->label_last_lea_arity=arity; + } + } + + if (bits[0]=='0') + graph_5=g_load_id (4,graph_0); + else { + graph_5=s_pop_a(); + --a_offset; + } + + graph_0=g_load_id (8,graph_0); + + a_n=1; + + graph_3=g_fill_m (graph_0,arity-1); + + parameter=&graph_3->instruction_parameters[1]; + + while (a_n<arity){ + if (bits[a_n]=='0') + parameter->p=NULL; + else { + parameter->p=s_pop_a(); + --a_offset; + } + ++parameter; + ++a_n; + } + + graph_4=g_fill_4 (graph_1,graph_2,graph_5,graph_3); + + s_put_a (a_offset,graph_4); +} + +void code_fillB (int value,int a_offset) +{ + INSTRUCTION_GRAPH graph_1,graph_2,graph_3,graph_4; + +#ifdef G_POWER + graph_2=g_g_register (BOOL_REGISTER); +#else + if (!parallel_flag && last_BOOL_descriptor_block==last_block) + graph_2=last_BOOL_descriptor_graph; + else { + if (BOOL_label==NULL) + BOOL_label=enter_label ("BOOL",IMPORT_LABEL | DATA_LABEL); + + graph_2=g_load_des_i (BOOL_label,0); + + if (!parallel_flag){ + last_BOOL_descriptor_graph=graph_2; + last_BOOL_descriptor_block=last_block; + } + } +#endif + + graph_1=s_get_a (a_offset); +#ifdef I486 + graph_3=g_load_i (value); +#else + graph_3=g_load_i (-value); +#endif + graph_4=g_fill_3 (graph_1,graph_2,graph_3); + + s_put_a (a_offset,graph_4); +} + +void code_fillB_b (int b_offset,int a_offset) +{ + INSTRUCTION_GRAPH graph_1,graph_2,graph_3,graph_4; + +#ifdef G_POWER + graph_2=g_g_register (BOOL_REGISTER); +#else + if (!parallel_flag && last_BOOL_descriptor_block==last_block) + graph_2=last_BOOL_descriptor_graph; + else { + if (BOOL_label==NULL) + BOOL_label=enter_label ("BOOL",IMPORT_LABEL | DATA_LABEL); + + graph_2=g_load_des_i (BOOL_label,0); + + if (!parallel_flag){ + last_BOOL_descriptor_graph=graph_2; + last_BOOL_descriptor_block=last_block; + } + } +#endif + + graph_1=s_get_a (a_offset); + graph_3=s_get_b (b_offset); + graph_4=g_fill_3 (graph_1,graph_2,graph_3); + + s_put_a (a_offset,graph_4); +} + +void code_fillC (int value,int a_offset) +{ + INSTRUCTION_GRAPH graph_1,graph_2,graph_3,graph_4; + + graph_1=s_get_a (a_offset); + + if (!parallel_flag && graph_1->instruction_code==GCREATE){ + if (static_characters_label==NULL) + static_characters_label=enter_label ("static_characters",IMPORT_LABEL | DATA_LABEL); + + graph_1->instruction_code=GLEA; + graph_1->inode_arity=1; + + graph_1->instruction_parameters[0].l=static_characters_label; + graph_1->instruction_parameters[1].i=(value<<3)+NODE_POINTER_OFFSET; + + return; + } + + graph_2=char_descriptor_graph(); + graph_3=g_load_i (value); + graph_4=g_fill_3 (graph_1,graph_2,graph_3); + + s_put_a (a_offset,graph_4); +} + +void code_fillC_b (int b_offset,int a_offset) +{ + INSTRUCTION_GRAPH graph_1,graph_2,graph_3,graph_4; + + graph_2=char_descriptor_graph(); + graph_1=s_get_a (a_offset); + graph_3=s_get_b (b_offset); + graph_4=g_fill_3 (graph_1,graph_2,graph_3); + + s_put_a (a_offset,graph_4); +} + +void code_fillF_b (int b_offset,int a_offset) +{ + INSTRUCTION_GRAPH graph_1,graph_2,graph_3,graph_4,graph_5; + + if (!parallel_flag && last_FILE_descriptor_block==last_block) + graph_2=last_FILE_descriptor_graph; + else { + if (FILE_label==NULL) + FILE_label=enter_label ("FILE",IMPORT_LABEL | DATA_LABEL); + + graph_2=g_load_des_i (FILE_label,0); + + if (!parallel_flag){ + last_FILE_descriptor_graph=graph_2; + last_FILE_descriptor_block=last_block; + } + } + + graph_1=s_get_a (a_offset); + graph_3=s_get_b (b_offset+1); + graph_4=s_get_b (b_offset); + + graph_5=g_fill_4 (graph_1,graph_2,graph_3,graph_4); + + s_put_a (a_offset,graph_5); +} + +void code_fillI (LONG value,int a_offset) +{ + INSTRUCTION_GRAPH graph_1,graph_3,graph_4,graph_5; + + graph_1=s_get_a (a_offset); + + if (!parallel_flag && + (unsigned long)value<(unsigned long)33 && graph_1->instruction_code==GCREATE) + { + if (small_integers_label==NULL) + small_integers_label=enter_label ("small_integers",IMPORT_LABEL | DATA_LABEL); + + graph_1->instruction_code=GLEA; + graph_1->inode_arity=1; + + graph_1->instruction_parameters[0].l=small_integers_label; + graph_1->instruction_parameters[1].i=(value<<3)+NODE_POINTER_OFFSET; + + return; + } + + graph_3=int_descriptor_graph(); + graph_4=g_load_i (value); + graph_5=g_fill_3 (graph_1,graph_3,graph_4); + + s_put_a (a_offset,graph_5); +} + +void code_fillI_b (int b_offset,int a_offset) +{ + INSTRUCTION_GRAPH graph_1,graph_3,graph_4,graph_5; + + graph_3=int_descriptor_graph(); + graph_1=s_get_a (a_offset); + graph_4=s_get_b (b_offset); + graph_5=g_fill_3 (graph_1,graph_3,graph_4); + + s_put_a (a_offset,graph_5); +} + +void code_fillR (double value,int a_offset) +{ + INSTRUCTION_GRAPH graph_1,graph_2,graph_3,graph_4,graph_5; + + graph_2=real_descriptor_graph(); + graph_1=s_get_a (a_offset); + + if (!mc68881_flag){ + DOUBLE r=value; + + graph_3=g_load_i (((long*)&r)[0]); + graph_4=g_load_i (((long*)&r)[1]); + graph_5=g_fill_4 (graph_1,graph_2,graph_3,graph_4); + } else { + graph_3=g_fload_i (value); + graph_5=g_fill_r (graph_1,graph_2,graph_3); + } + + s_put_a (a_offset,graph_5); +} + +void code_fillR_b (int b_offset,int a_offset) +{ + INSTRUCTION_GRAPH graph_1,graph_2,graph_3,graph_4,graph_5,graph_6; + + graph_4=real_descriptor_graph(); + graph_1=s_get_b (b_offset); + graph_2=s_get_b (b_offset+1); + + graph_5=s_get_a (a_offset); + + if (!mc68881_flag) + graph_6=g_fill_4 (graph_5,graph_4,graph_1,graph_2); + else { + graph_3=g_fjoin (graph_1,graph_2); + graph_6=g_fill_r (graph_5,graph_4,graph_3); + } + + s_put_a (a_offset,graph_6); +} + +void code_fill_a (int from_offset,int to_offset) +{ + INSTRUCTION_GRAPH graph_1,graph_2,graph_3 +#if defined (sparc) || defined (G_POWER) + ,graph_4,graph_5,graph_6,graph_7 +#endif + ; + + if (from_offset==to_offset) + return; + +#if defined (sparc) || defined (G_POWER) + graph_1=s_get_a (from_offset); + graph_2=s_get_a (to_offset); + graph_3=g_movem (0-NODE_POINTER_OFFSET,graph_1,3); + graph_4=g_movemi (0,graph_3); + graph_5=g_movemi (1,graph_3); + graph_6=g_movemi (2,graph_3); + graph_7=g_fill_4 (graph_2,graph_4,graph_5,graph_6); + + s_put_a (to_offset,graph_7); +#else + graph_1=s_get_a (from_offset); + graph_2=s_get_a (to_offset); + graph_3=g_copy (graph_1,graph_2); + + s_put_a (to_offset,graph_3); +#endif +} + +void code_fillcaf (char *label_name,int a_stack_size,int b_stack_size) +{ + union instruction_parameter *parameter; + INSTRUCTION_GRAPH graph_1,graph_2,graph_3,graph_4; + int n_arguments,a_offset,b_offset; + LABEL *label; + + label=enter_label (label_name,0); + + graph_1=g_lea (label); + + n_arguments=a_stack_size+b_stack_size; + + graph_2=g_fill_m (graph_1,n_arguments+1); + parameter=&graph_2->instruction_parameters[1]; + + parameter->p=g_load_i (a_stack_size>0 ? a_stack_size : 1); + ++parameter; + + for (a_offset=0; a_offset<a_stack_size; ++a_offset){ + parameter->p=s_get_a (a_offset); + ++parameter; + } + + for (b_offset=0; b_offset<b_stack_size; ++b_offset){ + parameter->p=s_get_b (b_offset); + ++parameter; + } + + if (a_stack_size>0){ + INSTRUCTION_GRAPH graph_5,graph_6,graph_7,graph_8; + LABEL *caf_listp_label; + + caf_listp_label=enter_label ("caf_listp",DATA_LABEL | IMPORT_LABEL); + + graph_5=g_lea (caf_listp_label); + graph_6=g_sub (g_load_i (4),g_load_id (0,graph_5)); + graph_7=g_fill_2 (graph_6,graph_2); + graph_8=g_fill_2 (graph_5,g_keep (graph_7,graph_2)); + + graph_3=s_get_a (0); + graph_4=g_keep (graph_8,graph_3); + s_put_a (0,graph_4); + } else { + graph_3=s_get_b (0); + + if (b_stack_size>=2 && graph_3->instruction_code==GFHIGH){ + graph_4=s_get_b (1); + if (graph_4->instruction_code==GFLOW && + graph_3->instruction_parameters[0].p==graph_4->instruction_parameters[0].p) + { + INSTRUCTION_GRAPH graph_5,graph_6; + + graph_4=g_fkeep (graph_2,g_fjoin (graph_3,graph_4)); + + g_fhighlow (graph_5,graph_6,graph_4); + + s_put_b (0,graph_5); + s_put_b (1,graph_6); + + return; + } + } + + graph_4=g_keep (graph_2,graph_3); + s_put_b (0,graph_4); + } +} + +void code_get_desc_arity (int a_offset) +{ + INSTRUCTION_GRAPH graph_1,graph_2,graph_3,graph_4,graph_5,graph_6,graph_7; + + graph_1=s_get_a (a_offset); +#ifndef M68000 + graph_2=g_load_id (0,graph_1); + graph_3=g_load_i (-2); +#else + graph_2=g_load_des_id (DESCRIPTOR_OFFSET,graph_1); + graph_3=g_g_register (GLOBAL_DATA_REGISTER); +#endif + graph_4=g_add (graph_3,graph_2); +#ifdef GEN_MAC_OBJ + graph_5=g_load_des_id (0,graph_4); +#else + graph_5=g_load_des_id (2,graph_4); +#endif + graph_6=g_sub (graph_5,graph_4); + graph_7=g_load_des_id (DESCRIPTOR_ARITY_OFFSET,graph_6); + s_push_b (graph_7); +} + +void code_get_node_arity (int a_offset) +{ + INSTRUCTION_GRAPH graph_1,graph_2,graph_3,graph_4,graph_5,graph_7; +#ifdef GEN_MAC_OBJ + INSTRUCTION_GRAPH graph_6; +#endif + + graph_1=s_get_a (a_offset); +#ifdef GEN_MAC_OBJ + graph_2=g_load_des_id (DESCRIPTOR_OFFSET,graph_1); + graph_3=g_g_register (GLOBAL_DATA_REGISTER); +#else + graph_2=g_load_id (0,graph_1); + graph_3=g_load_i (-2); +#endif + graph_4=g_add (graph_3,graph_2); + graph_5=g_load_des_id (0,graph_4); + +#ifdef GEN_MAC_OBJ + graph_6=g_load_i (2); + graph_7=g_lsr (graph_6,graph_5); +#else + graph_7=graph_5; +#endif + + s_push_b (graph_7); +} + +void code_gtC (VOID) +{ + INSTRUCTION_GRAPH graph_1,graph_2,graph_3; + + graph_1=s_pop_b(); + graph_2=s_get_b (0); + graph_3=g_cmp_gt (graph_2,graph_1); + + s_put_b (0,graph_3); +} + +void code_gtI (VOID) +{ + INSTRUCTION_GRAPH graph_1,graph_2,graph_3; + + graph_1=s_pop_b(); + graph_2=s_get_b (0); + graph_3=g_cmp_gt (graph_2,graph_1); + + s_put_b (0,graph_3); +} + +void code_gtR (VOID) +{ + INSTRUCTION_GRAPH graph_1,graph_2,graph_3,graph_4,graph_5,graph_6,graph_7; + +#ifdef M68000 + if (!mc68881_flag){ + if (gt_real==NULL) + gt_real=enter_label ("gt_real",IMPORT_LABEL); + + code_dyadic_sane_operator (gt_real); + init_b_stack (1,i_vector); + } else { +#endif + graph_1=s_pop_b(); + graph_2=s_pop_b(); + graph_3=g_fjoin (graph_1,graph_2); + + graph_4=s_pop_b(); + graph_5=s_pop_b(); + graph_6=g_fjoin (graph_4,graph_5); + + graph_7=g_fcmp_gt (graph_6,graph_3); + + s_push_b (graph_7); +#ifdef M68000 + } +#endif +} + +void code_halt (VOID) +{ + if (halt_label==NULL) + halt_label=enter_label ("halt",IMPORT_LABEL); + + end_basic_block_with_registers (0,0,e_vector); + + i_jmp_l (halt_label,0); + + reachable=0; + + begin_new_basic_block(); +} + +void code_incI (VOID) +{ + INSTRUCTION_GRAPH graph_1,graph_2,graph_3; + + graph_1=s_get_b (0); + graph_2=g_load_i (1); + graph_3=g_add (graph_2,graph_1); + + s_put_b (0,graph_3); +} + +void code_instruction (int i) +{ + i_word_i (i); +} + +void code_is_record (int a_offset) +{ + INSTRUCTION_GRAPH graph_1,graph_2,graph_3,graph_4,graph_5,graph_6,graph_7; + + graph_1=s_get_a (a_offset); +#if defined (sparc) || defined (I486) || defined (G_POWER) + graph_2=g_load_id (0,graph_1); + graph_3=g_load_i (-2); +#else + graph_2=g_load_des_id (DESCRIPTOR_OFFSET,graph_1); + graph_3=g_g_register (GLOBAL_DATA_REGISTER); +#endif + graph_4=g_add (graph_3,graph_2); + graph_5=g_load_des_id (0,graph_4); + + graph_6=g_load_i (127); + graph_7=g_cmp_gt (graph_6,graph_5); + + s_push_b (graph_7); +} + +void code_ItoC (VOID) +{ + INSTRUCTION_GRAPH graph_1,graph_2,graph_3; + + graph_1=s_get_b (0); + + graph_2=g_load_i (255); + graph_3=g_and (graph_2,graph_1); + + s_put_b (0,graph_3); +} + +void code_ItoP (void) +{ + if (ItoP_label==NULL) + ItoP_label=enter_label ("ItoP",IMPORT_LABEL); + + s_push_b (s_get_b (0)); + s_put_b (1,NULL); + insert_basic_block (JSR_BLOCK,0,1+1,i_i_vector,ItoP_label); + + init_b_stack (1,i_vector); +} + +void code_ItoR (VOID) +{ + INSTRUCTION_GRAPH graph_1,graph_2,graph_3,graph_4; + +#ifdef M68000 + if (!mc68881_flag){ + if (i_to_r_real==NULL) + i_to_r_real=enter_label ("i_to_r_real",IMPORT_LABEL); + + s_push_b (s_get_b (0)); + s_put_b (1,NULL); + insert_basic_block (JSR_BLOCK,0,1+1,i_vector,i_to_r_real); + init_b_stack (2,r_vector); + } else { +#endif + graph_1=s_pop_b(); + graph_2=g_fitor (graph_1); + + g_fhighlow (graph_3,graph_4,graph_2); + + s_push_b (graph_4); + s_push_b (graph_3); +#ifdef M68000 + } +#endif +} + +LABEL *profile_function_label; +static struct basic_block *profile_function_block; + +int profile_flag=PROFILE_NORMAL; + +void code_jmp (char label_name[]) +{ + if (!strcmp (label_name,"e__system__sAP")){ +#if defined (I486) + end_basic_block_with_registers (2,0,e_vector); + i_move_id_r (0,REGISTER_A1,REGISTER_A2); +# ifdef PROFILE + if (profile_function_label!=NULL) + i_jmp_id_profile (4-2,REGISTER_A2,0); + else +# endif + i_jmp_id (4-2,REGISTER_A2,0); +#else + INSTRUCTION_GRAPH graph_1,graph_2,graph_3,graph_4,graph_5; + + graph_1=s_get_a (0); + +# if defined (sparc) || defined (G_POWER) +# pragma unused (graph_3,graph_4) + graph_2=g_load_id (0,graph_1); + graph_5=g_load_id (4-2,graph_2); +# else + graph_2=g_load_des_id (DESCRIPTOR_OFFSET,graph_1); + graph_3=g_g_register (GLOBAL_DATA_REGISTER); + + graph_4=g_add (graph_3,graph_2); + +# if defined (M68000) && !defined (SUN) + graph_5=g_load_des_id (2,graph_4); +# else + graph_5=g_load_id (4,graph_4); +# endif +# endif + + s_push_a (graph_5); + + end_basic_block_with_registers (3,0,e_vector); +# if defined (M68000) && !defined (SUN) + i_add_r_r (GLOBAL_DATA_REGISTER,REGISTER_A2); +# endif +# ifdef PROFILE + if (profile_function_label!=NULL) + i_jmp_id_profile (0,REGISTER_A2,2<<4); + else +# endif + i_jmp_id (0,REGISTER_A2,2<<4); +#endif + demand_flag=0; + + reachable=0; + + begin_new_basic_block(); + } else { + LABEL *label; + int a_stack_size,b_stack_size,n_a_and_f_registers; + ULONG *vector; + + label=enter_label (label_name,0); + + if (demand_flag){ + a_stack_size=demanded_a_stack_size; + b_stack_size=demanded_b_stack_size; + vector=demanded_vector; + + end_basic_block_with_registers (a_stack_size,b_stack_size,vector); + } else { + generate_code_for_previous_blocks (1); + if (!(label->label_flags & REGISTERS_ALLOCATED)){ + label->label_a_stack_size=get_a_stack_size(); + label->label_vector=&label->label_small_vector; + label->label_b_stack_size=get_b_stack_size (&label->label_vector); + label->label_flags |= REGISTERS_ALLOCATED; + } + + a_stack_size=label->label_a_stack_size; + b_stack_size=label->label_b_stack_size; + vector=label->label_vector; + + end_stack_elements (a_stack_size,b_stack_size,vector); + linearize_stack_graphs(); + adjust_stack_pointers(); + } + + n_a_and_f_registers=0; + + if (mc68881_flag){ + int parameter_n; + + for (parameter_n=0; parameter_n<b_stack_size; ++parameter_n) + if (test_bit (vector,parameter_n)) + if (n_a_and_f_registers<N_FLOAT_PARAMETER_REGISTERS){ + ++n_a_and_f_registers; + ++parameter_n; + } else + break; + } + + n_a_and_f_registers+= + (a_stack_size<=N_ADDRESS_PARAMETER_REGISTERS) ? (a_stack_size<<4) : (N_ADDRESS_PARAMETER_REGISTERS<<4); + +#ifdef PROFILE + if (profile_function_label!=NULL && profile_flag!=PROFILE_NOT && demand_flag){ + int tail_call_profile; + + if (profile_flag==PROFILE_TAIL) + tail_call_profile=1; + else { + struct block_label *profile_block_label; + + tail_call_profile=0; + + if (profile_function_block!=NULL){ + for_l (profile_block_label,profile_function_block->block_labels,block_label_next) + if (profile_block_label->block_label_label==label) + tail_call_profile=1; + } + } + + if (! tail_call_profile) + i_jmp_l_profile (label,0); + else + i_jmp_l_profile (label,profile_offset); + } else +#endif + i_jmp_l (label,n_a_and_f_registers); + + profile_flag=PROFILE_NORMAL; + demand_flag=0; + + reachable=0; + + begin_new_basic_block(); + } +} + +void code_label (char *label_name); + +void code_jmp_eval (VOID) +{ + LABEL *label; + + end_basic_block_with_registers (1,0,e_vector); + + i_move_id_r (0,REGISTER_A0,REGISTER_D0); + sprintf (eval_label_s,"e_%d",eval_label_number++); + label=enter_label (eval_label_s,0); + +#ifndef M68000 + i_btst_i_r (2,REGISTER_D0); +# ifdef G_POWER + i_bnep_l (label); +# else + i_bne_l (label); +# endif +# ifdef I486 +# ifdef PROFILE + if (profile_function_label!=NULL) + i_jmp_r_profile (REGISTER_D0); + else +# endif + i_jmp_r (REGISTER_D0); +# else +# ifdef PROFILE + if (profile_function_label!=NULL) + i_jmp_id_profile (0,REGISTER_D0,256); + else +# endif + i_jmp_id (0,REGISTER_D0,256); +# endif +#else + i_bmi_l (label); + i_move_r_r (REGISTER_D0,REGISTER_A1); + i_jmp_id (0,REGISTER_A1,256); +#endif + + reachable=0; + + begin_new_basic_block(); + + code_label (eval_label_s); +#if ! (defined (sparc) || defined (G_POWER)) +# ifdef PROFILE + if (profile_function_label!=NULL) + i_rts_profile (); + else +# endif + i_rts (); +#else +# ifdef PROFILE + if (profile_function_label!=NULL) + i_rts_profile (0,4); + else +# endif + i_rts (0,4); +#endif + + demand_flag=0; + + reachable=0; + + begin_new_basic_block(); +} + +void code_jmp_eval_upd (VOID) +{ + LABEL *label; + + end_basic_block_with_registers (2,0,e_vector); + + i_move_id_r (0,REGISTER_A1,REGISTER_D0); + sprintf (eval_label_s,"e_%d",eval_label_number++); + label=enter_label (eval_label_s,0); + +#ifndef M68000 + i_btst_i_r (2,REGISTER_D0); +# ifdef G_POWER + i_bnep_l (label); +# else + i_bne_l (label); +# endif +# ifdef I486 + i_sub_i_r (20,REGISTER_D0); +# ifdef PROFILE + if (profile_function_label!=NULL) + i_jmp_r_profile (REGISTER_D0); + else +# endif + i_jmp_r (REGISTER_D0); +# else +# ifdef PROFILE + if (profile_function_label!=NULL) +# if defined (G_POWER) && (defined (MACH_O) || defined (LINUX_ELF)) + i_jmp_id_profile (-28,REGISTER_D0,128); +# else + i_jmp_id_profile (-20,REGISTER_D0,128); +# endif + else +# endif +# if defined (G_POWER) && (defined (MACH_O) || defined (LINUX_ELF)) + i_jmp_id (-28,REGISTER_D0,128); +# else + i_jmp_id (-20,REGISTER_D0,128); +# endif +# endif +#else + i_bmi_l (label); + i_move_r_r (REGISTER_D0,REGISTER_A2); + i_jmp_id (-12,REGISTER_A2,128); +#endif + + reachable=0; + + begin_new_basic_block(); + + code_label (eval_label_s); +# ifdef M68000 + i_move_pi_id (REGISTER_A1,0,REGISTER_A0); + i_move_pi_id (REGISTER_A1,4,REGISTER_A0); + i_move_id_id (0,REGISTER_A1,8,REGISTER_A0); +# else + i_move_r_id (REGISTER_D0,0,REGISTER_A0); +# ifdef I486 + i_move_id_id (4,REGISTER_A1,4,REGISTER_A0); + i_move_id_id (8,REGISTER_A1,8,REGISTER_A0); +# else + i_move_id_r (4,REGISTER_A1,REGISTER_D1); + i_move_id_r (8,REGISTER_A1,REGISTER_D2); + i_move_r_id (REGISTER_D1,4,REGISTER_A0); + i_move_r_id (REGISTER_D2,8,REGISTER_A0); +# endif +# endif + +# if ! (defined (sparc) || defined (G_POWER)) +# ifdef PROFILE + if (profile_function_label!=NULL) + i_rts_profile(); + else +# endif + i_rts (); +# else +# ifdef PROFILE + if (profile_function_label!=NULL) + i_rts_profile (0,4); + else +# endif + i_rts (0,4); +# endif + + demand_flag=0; + + reachable=0; + + begin_new_basic_block(); +} + +void code_jmp_false (char label_name[]) +{ + INSTRUCTION_GRAPH graph_1,store_calculate_with_overflow_graph; + LABEL *label; + + label=enter_label (label_name,0); + + graph_1=s_pop_b(); + mark_and_count_graph (graph_1); + + generate_code_for_previous_blocks (0); + + if (!(label->label_flags & REGISTERS_ALLOCATED)){ + label->label_a_stack_size=get_a_stack_size(); + label->label_vector=&label->label_small_vector; + label->label_b_stack_size=get_b_stack_size (&label->label_vector); + label->label_flags |= REGISTERS_ALLOCATED; + } + + end_stack_elements (label->label_a_stack_size,label->label_b_stack_size,label->label_vector); + + if (graph_1->instruction_code==GTEST_O && + (store_calculate_with_overflow_graph=search_and_remove_graph_from_b_stack (graph_1->instruction_parameters[0].p))!=NULL) + { + linearize_stack_graphs_with_overflow_test (graph_1,store_calculate_with_overflow_graph); + } else + linearize_stack_graphs(); + + calculate_and_linearize_branch_false (label,graph_1); + + begin_new_basic_block(); +#ifdef MORE_PARAMETER_REGISTERS + init_ab_stack (label->label_a_stack_size,label->label_b_stack_size,label->label_vector); +#else + init_a_stack (label->label_a_stack_size); + init_b_stack (label->label_b_stack_size,label->label_vector); +#endif +} + +void code_jmp_true (char label_name[]) +{ + INSTRUCTION_GRAPH graph_1,store_calculate_with_overflow_graph; + LABEL *label; + + label=enter_label (label_name,0); + + graph_1=s_pop_b(); + mark_and_count_graph (graph_1); + + generate_code_for_previous_blocks (0); + + if (!(label->label_flags & REGISTERS_ALLOCATED)){ + label->label_a_stack_size=get_a_stack_size(); + label->label_vector=&label->label_small_vector; + label->label_b_stack_size=get_b_stack_size (&label->label_vector); + label->label_flags |= REGISTERS_ALLOCATED; + } + + end_stack_elements (label->label_a_stack_size,label->label_b_stack_size,label->label_vector); + + if (graph_1->instruction_code==GTEST_O && + (store_calculate_with_overflow_graph=search_and_remove_graph_from_b_stack (graph_1->instruction_parameters[0].p))!=NULL) + { + linearize_stack_graphs_with_overflow_test (graph_1,store_calculate_with_overflow_graph); + } else + linearize_stack_graphs(); + + calculate_and_linearize_branch_true (label,graph_1); + + begin_new_basic_block(); +#ifdef MORE_PARAMETER_REGISTERS + init_ab_stack (label->label_a_stack_size,label->label_b_stack_size,label->label_vector); +#else + init_a_stack (label->label_a_stack_size); + init_b_stack (label->label_b_stack_size,label->label_vector); +#endif +} + +#if defined (M68000) || defined (I486) +static void define_label_in_block (LABEL *label_2) +{ + struct block_label *new_label; + + new_label=fast_memory_allocate_type (struct block_label); + new_label->block_label_label=label_2; + new_label->block_label_next=NULL; + + if (last_block->block_labels==NULL) + last_block->block_labels=new_label; + else + last_block_label->block_label_next=new_label; + last_block_label=new_label; +} + +static int too_many_b_stack_parameters_for_registers (int b_stack_size,int n_data_parameter_registers) +{ + int offset,n_data_registers,n_float_registers; + int n_float_parameter_registers; + + n_float_parameter_registers= mc68881_flag ? N_FLOAT_PARAMETER_REGISTERS : 0; + + n_data_registers=0; + n_float_registers=0; + + for (offset=0; offset<b_stack_size; ++offset) + if (demanded_vector[offset>>LOG_VECTOR_ELEMENT_SIZE] & (((ULONG)1)<<(offset & VECTOR_ELEMENT_MASK))){ + if (++n_float_registers>n_float_parameter_registers) + break; + ++offset; + } else + if (++n_data_registers>n_data_parameter_registers) + break; + + return n_data_registers>n_data_parameter_registers || n_float_registers>n_float_parameter_registers; +} +#endif + +void code_jsr (char label_name[]) +{ + if (!strcmp (label_name,"e__system__sAP")){ + INSTRUCTION_GRAPH graph_1,graph_2,graph_3,graph_4,graph_5; + +#if !defined (I486) + graph_1=s_get_a (0); +# if defined (sparc) || defined (G_POWER) +# pragma unused (graph_3,graph_4) + graph_2=g_load_id (0,graph_1); + graph_5=g_load_id (4-2,graph_2); +# else + graph_2=g_load_des_id (DESCRIPTOR_OFFSET,graph_1); + graph_3=g_g_register (GLOBAL_DATA_REGISTER); + graph_4=g_add (graph_3,graph_2); + +# if defined (M68000) && !defined (SUN) + graph_5=g_load_des_id (2,graph_4); +# else + graph_5=g_load_id (4,graph_4); +# endif +# endif + s_push_a (graph_5); +#endif + + if (demand_flag) + offered_after_jsr=1; + demand_flag=0; + +#if defined (I486) + insert_basic_block (APPLY_BLOCK,2,0,e_vector,NULL); +#else + insert_basic_block (APPLY_BLOCK,3,0,e_vector,NULL); +#endif + init_a_stack (1); + } else { + LABEL *label; + INSTRUCTION_GRAPH graph; + int b_stack_size,n_data_parameter_registers; +#if defined (M68000) || defined (I486) + LABEL *label_2; +#endif + + if (!demand_flag) + error ("Directive .d missing before jsr instruction"); + + label=enter_label (label_name,0); + + offered_after_jsr=1; + demand_flag=0; + + n_data_parameter_registers=parallel_flag ? N_DATA_PARAMETER_REGISTERS-1 : N_DATA_PARAMETER_REGISTERS; +#ifdef MORE_PARAMETER_REGISTERS + if (demanded_a_stack_size<N_ADDRESS_PARAMETER_REGISTERS) + n_data_parameter_registers += N_ADDRESS_PARAMETER_REGISTERS-demanded_a_stack_size; +#endif + graph=NULL; + + b_stack_size=demanded_b_stack_size; + +#if defined (M68000) || defined (I486) + if (b_stack_size>n_data_parameter_registers || !mc68881_flag){ + if (too_many_b_stack_parameters_for_registers (b_stack_size,n_data_parameter_registers)){ + sprintf (eval_label_s,"e_%d",eval_label_number++); + label_2=enter_label (eval_label_s,LOCAL_LABEL); + graph=g_lea (label_2); + } + } +#endif + + insert_graph_in_b_stack (graph,b_stack_size,demanded_vector); + + clear_bit (demanded_vector,b_stack_size); + ++b_stack_size; + + insert_basic_block (JSR_BLOCK,demanded_a_stack_size,b_stack_size,demanded_vector,label); + +#if defined (M68000) || defined (I486) + if (graph!=NULL) + define_label_in_block (label_2); +#endif + } +} + +#ifdef G_POWER +void code_jsr_from_c_to_clean (char *label_name) +{ + LABEL *label; + INSTRUCTION_GRAPH graph; + int b_stack_size,n_data_parameter_registers; +#if defined (M68000) || defined (I486) + LABEL *label_2; +#endif + + n_data_parameter_registers=parallel_flag ? N_DATA_PARAMETER_REGISTERS-1 : N_DATA_PARAMETER_REGISTERS; + + if (!demand_flag) + error ("Directive .d missing before jsr instruction"); + + label=enter_label (label_name,0); + + offered_after_jsr=1; + demand_flag=0; + + graph=NULL; + + b_stack_size=demanded_b_stack_size; + +#if defined (M68000) || defined (I486) + if (b_stack_size>n_data_parameter_registers || !mc68881_flag){ + if (too_many_b_stack_parameters_for_registers (b_stack_size,n_data_parameter_registers)){ + sprintf (eval_label_s,"e_%d",eval_label_number++); + label_2=enter_label (eval_label_s,LOCAL_LABEL); + graph=g_lea (label_2); + } + } +#endif + + insert_graph_in_b_stack (graph,b_stack_size,demanded_vector); + + clear_bit (demanded_vector,b_stack_size); + ++b_stack_size; + + insert_basic_block (JSR_BLOCK_WITH_INSTRUCTIONS,demanded_a_stack_size,b_stack_size,demanded_vector,label); + +#if defined (M68000) || defined (I486) + if (graph!=NULL) + define_label_in_block (label_2); +#endif +} +#endif + +void code_jsr_eval (int a_offset) +{ + INSTRUCTION_GRAPH graph_1; + + if (a_offset!=0){ + graph_1=s_get_a (a_offset); + s_push_a (graph_1); + } else + graph_1=s_get_a (0); + +#ifdef M68000 + if (check_stack) +#endif + { + LABEL *label; + struct block_label *new_label; + + sprintf (eval_label_s,"e_%d",eval_label_number++); + label=enter_label (eval_label_s,LOCAL_LABEL); + + insert_basic_block (JSR_EVAL_BLOCK,0,0,e_vector,label); + + new_label=fast_memory_allocate_type (struct block_label); + new_label->block_label_label=label; + new_label->block_label_next=NULL; + + if (last_block->block_labels==NULL) + last_block->block_labels=new_label; + else + last_block_label->block_label_next=new_label; + last_block_label=new_label; + } +#ifdef M68000 + else + insert_basic_block (JSR_EVAL_BLOCK,0,0,e_vector,NULL); +#endif + + if (a_offset!=0) + s_remove_a(); +} + +void code_keep (int a_offset_1,int a_offset_2) +{ + INSTRUCTION_GRAPH graph_1,graph_2,graph_3; + + graph_1=s_get_a (a_offset_1); + graph_2=s_get_a (a_offset_2); + + graph_3=g_keep (graph_1,graph_2); + + s_put_a (a_offset_2,graph_3); +} + +void code_lnR (VOID) +{ +#ifdef M68000 + if (!mc68881_flag){ +#endif + if (ln_real==NULL) + ln_real=enter_label ("ln_real",IMPORT_LABEL); + code_monadic_sane_operator (ln_real); + init_b_stack (2,r_vector); +#ifdef M68000 + } else + code_monadic_real_operator (GFLN); +#endif +} + +void code_log10R (VOID) +{ +#ifdef M68000 + if (!mc68881_flag){ +#endif + if (log10_real==NULL) + log10_real=enter_label ("log10_real",IMPORT_LABEL); + code_monadic_sane_operator (log10_real); + init_b_stack (2,r_vector); +#ifdef M68000 + } else + code_monadic_real_operator (GFLOG10); +#endif +} + +void code_ltC (VOID) +{ + INSTRUCTION_GRAPH graph_1,graph_2,graph_3; + + graph_1=s_pop_b(); + graph_2=s_get_b (0); + graph_3=g_cmp_lt (graph_2,graph_1); + + s_put_b (0,graph_3); +} + +void code_ltI (VOID) +{ + INSTRUCTION_GRAPH graph_1,graph_2,graph_3; + + graph_1=s_pop_b(); + graph_2=s_get_b (0); + graph_3=g_cmp_lt (graph_2,graph_1); + + s_put_b (0,graph_3); +} + +void code_ltR (VOID) +{ + INSTRUCTION_GRAPH graph_1,graph_2,graph_3,graph_4,graph_5,graph_6,graph_7; + +#ifdef M68000 + if (!mc68881_flag){ + if (lt_real==NULL) + lt_real=enter_label ("lt_real",IMPORT_LABEL); + code_dyadic_sane_operator (lt_real); + init_b_stack (1,i_vector); + } else { +#endif + graph_1=s_pop_b(); + graph_2=s_pop_b(); + graph_3=g_fjoin (graph_1,graph_2); + + graph_4=s_pop_b(); + graph_5=s_pop_b(); + graph_6=g_fjoin (graph_4,graph_5); + + graph_7=g_fcmp_lt (graph_6,graph_3); + + s_push_b (graph_7); +#ifdef M68000 + } +#endif +} + +void code_remI (VOID) +{ +#ifdef M68000 + if (!mc68000_flag){ +#endif + INSTRUCTION_GRAPH graph_1,graph_2,graph_3; + + graph_1=s_pop_b(); + graph_2=s_get_b (0); + graph_3=g_mod (graph_2,graph_1); + s_put_b (0,graph_3); +#ifdef M68000 + } else { + if (mod_label==NULL) + mod_label=enter_label ("modulo",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,mod_label); + + init_b_stack (1,i_vector); + } +#endif +} + +static INSTRUCTION_GRAPH multiply_by_constant (unsigned int n,INSTRUCTION_GRAPH graph_1) +{ + INSTRUCTION_GRAPH graph_2; + int n_shifts; + + if (n==0) + return g_load_i (0); + + n_shifts=0; + while ((n & 1)==0){ + n>>=1; + ++n_shifts; + } + + graph_2=graph_1; + + while (n>1){ + int n_shifts2; + + n>>=1; + + n_shifts2=1; + while ((n & 1)==0){ + n>>=1; + ++n_shifts2; + } + + graph_2=g_lsl (g_load_i (n_shifts2),graph_2); + graph_1=g_add (graph_2,graph_1); + } + + if (n_shifts>0) + graph_1=g_lsl (g_load_i (n_shifts),graph_1); + + return graph_1; +} + +void code_mulI (VOID) +{ +#ifdef M68000 + if (!mc68000_flag){ +#endif + INSTRUCTION_GRAPH graph_1,graph_2,graph_3; + + graph_1=s_pop_b(); + graph_2=s_get_b (0); + +# ifdef REPLACE_MUL_BY_SHIFT + if (graph_1->instruction_code==GLOAD_I){ + unsigned int n,n2; + + n=graph_1->instruction_parameters[0].i; + n2=n & (n-1); + if (n2==0 || (n2 & (n2-1))==0){ + graph_3=multiply_by_constant (n,graph_2); + s_put_b (0,graph_3); + return; + } + } + if (graph_2->instruction_code==GLOAD_I){ + unsigned int n,n2; + + n=graph_2->instruction_parameters[0].i; + n2=n & (n-1); + if (n2==0 || (n2 & (n2-1))==0){ + graph_3=multiply_by_constant (n,graph_1); + s_put_b (0,graph_3); + return; + } + } +# endif + + graph_3=g_mul (graph_1,graph_2); + s_put_b (0,graph_3); +#ifdef M68000 + } else { + if (mul_label==NULL) + mul_label=enter_label ("multiply",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,mul_label); + + init_b_stack (1,i_vector); + } +#endif +} + +#ifndef M68000 +void code_mulIo (VOID) +{ + code_operatorIo (GMUL_O); +} +#endif + +void code_mulR (VOID) +{ + INSTRUCTION_GRAPH graph_1,graph_2,graph_3,graph_4,graph_5,graph_6,graph_7,graph_8,graph_9; + +#ifdef M68000 + if (!mc68881_flag){ + if (mul_real==NULL) + mul_real=enter_label ("mul_real",IMPORT_LABEL); + code_dyadic_sane_operator (mul_real); + init_b_stack (2,r_vector); + } else { +#endif + graph_1=s_pop_b(); + graph_2=s_pop_b(); + graph_3=g_fjoin (graph_1,graph_2); + + graph_4=s_get_b (0); + graph_5=s_get_b (1); + graph_6=g_fjoin (graph_4,graph_5); + + graph_7=g_fmul (graph_6,graph_3); + + g_fhighlow (graph_8,graph_9,graph_7); + + s_put_b (0,graph_8); + s_put_b (1,graph_9); +#ifdef M68000 + } +#endif +} + +void code_n (int number_of_arguments,char *descriptor_name,char *ea_label_name) +{ + LABEL *label; + + if (descriptor_name[0]=='_' && descriptor_name[1]=='_' && descriptor_name[2]=='\0') + label=NULL; + else +#if SMALL_LAZY_DESCRIPTORS + if (parallel_flag){ + char curried_descriptor_name[257]; + + strcpy (curried_descriptor_name,descriptor_name); + strcat (curried_descriptor_name,"#"); + + label=enter_label (curried_descriptor_name,DATA_LABEL); + } else +#endif + label=enter_label (descriptor_name,DATA_LABEL); + + last_block->block_n_node_arguments=number_of_arguments; + last_block->block_descriptor=label; + + if (ea_label_name!=NULL){ + char eval_upd_label_name[32]; + + if (ea_label_name[0]=='_' && ea_label_name[1]=='_' && ea_label_name[2]=='\0'){ + if (eval_fill_label==NULL) + eval_fill_label=enter_label ("eval_fill",IMPORT_LABEL); + last_block->block_ea_label=eval_fill_label; + } else { + if (number_of_arguments<-2) + number_of_arguments=1; + + if (number_of_arguments>=0 && eval_upd_labels[number_of_arguments]==NULL){ + sprintf (eval_upd_label_name,"eval_upd_%d",number_of_arguments); + eval_upd_labels[number_of_arguments]=enter_label (eval_upd_label_name,IMPORT_LABEL); + } + last_block->block_ea_label=enter_label (ea_label_name,0); + } + } else + last_block->block_ea_label=NULL; +} + +void code_nu (int a_size,int b_size,char *descriptor_name,char *ea_label_name) +{ + LABEL *label; + + if (descriptor_name[0]=='_' && descriptor_name[1]=='_' && descriptor_name[2]=='\0') + label=NULL; + else + label=enter_label (descriptor_name,DATA_LABEL); + + last_block->block_n_node_arguments=a_size+b_size+(b_size<<8); + last_block->block_descriptor=label; + + if (ea_label_name!=NULL){ + /* eval_upd not yet implemented */ + if (eval_fill_label==NULL) + eval_fill_label=enter_label ("eval_fill",IMPORT_LABEL); + last_block->block_ea_label=eval_fill_label; + } else + last_block->block_ea_label=NULL; +} + +void code_negR (void) +{ +#ifdef M68000 + if (!mc68881_flag){ + if (neg_real==NULL) + neg_real=enter_label ("neg_real",IMPORT_LABEL); + code_monadic_sane_operator (neg_real); + init_b_stack (2,r_vector); + } else +#endif + code_monadic_real_operator (GFNEG); +} + +void code_no_op (VOID) +{ +} + +void code_notB (VOID) +{ + INSTRUCTION_GRAPH graph_1,graph_2; + + graph_1=s_get_b (0); + graph_2=g_cnot (graph_1); + + s_put_b (0,graph_2); +} + +void code_not (VOID) +{ + INSTRUCTION_GRAPH graph_1,graph_2,graph_3; + + graph_1=s_get_b (0); + graph_2=g_load_i (-1); + graph_3=g_eor (graph_2,graph_1); + + s_put_b (0,graph_3); +} + +void code_orB (VOID) +{ + INSTRUCTION_GRAPH graph_1,graph_2,graph_3; + + graph_1=s_pop_b(); + graph_2=s_get_b (0); + graph_3=g_or (graph_1,graph_2); + + s_put_b (0,graph_3); +} + +void code_or (VOID) +{ + INSTRUCTION_GRAPH graph_1,graph_2,graph_3; + + graph_1=s_pop_b(); + graph_2=s_get_b (0); + graph_3=g_or (graph_1,graph_2); + + s_put_b (0,graph_3); +} + +void code_pop_a (int n) +{ + while (n>0){ + s_remove_a(); + --n; + } +} + +void code_pop_b (int n) +{ + while (n>0){ + s_remove_b(); + --n; + } +} + +void code_powR (VOID) +{ + if (pow_real==NULL) + pow_real=enter_label ("pow_real",IMPORT_LABEL); + + code_dyadic_sane_operator (pow_real); + init_b_stack (2,r_vector); +} + +void code_print (char *string,int length) +{ + LABEL *string_label; + INSTRUCTION_GRAPH graph_1; + + if (print_label==NULL) +#ifdef G_POWER + print_label=enter_label ("print_",IMPORT_LABEL); +#else + print_label=enter_label ("print",IMPORT_LABEL); +#endif + + string_label=w_code_string (string,length); + + graph_1=g_lea (string_label); + + s_push_b (NULL); + s_push_b (graph_1); + + insert_basic_block (JSR_BLOCK,0,1+1,i_i_vector,print_label); +} + +void code_print_char (VOID) +{ + INSTRUCTION_GRAPH graph_1; + + if (print_char_label==NULL) + print_char_label=enter_label ("print_char",IMPORT_LABEL); + + graph_1=s_pop_b(); + + s_push_b (NULL); + s_push_b (graph_1); + + insert_basic_block (JSR_BLOCK,0,1+1,i_i_vector,print_char_label); +} + +void code_print_int (VOID) +{ + INSTRUCTION_GRAPH graph_1; + + if (print_int_label==NULL) + print_int_label=enter_label ("print_int",IMPORT_LABEL); + + graph_1=s_pop_b(); + + s_push_b (NULL); + s_push_b (graph_1); + + insert_basic_block (JSR_BLOCK,0,1+1,i_i_vector,print_int_label); +} + +void code_print_real (VOID) +{ + INSTRUCTION_GRAPH graph_1,graph_2; + + if (print_real_label==NULL) + print_real_label=enter_label ("print_real",IMPORT_LABEL); + + graph_1=s_pop_b(); + graph_2=s_pop_b(); + + s_push_b (NULL); + s_push_b (graph_2); + s_push_b (graph_1); + + insert_basic_block (JSR_BLOCK,0,2+1,r_vector,print_real_label); +} + +void code_print_sc (char *string,int length) +{ + LABEL *string_label; + INSTRUCTION_GRAPH graph_1; + + if (print_sc_label==NULL) + print_sc_label=enter_label ("print_sc",IMPORT_LABEL); + + string_label=w_code_string (string,length); + + graph_1=g_lea (string_label); + + s_push_b (NULL); + s_push_b (graph_1); + + insert_basic_block (JSR_BLOCK,0,1+1,i_i_vector,print_sc_label); +} + +void code_print_symbol (int a_offset) +{ + INSTRUCTION_GRAPH graph_1; + + if (print_symbol_label==NULL) + print_symbol_label=enter_label ("print_symbol",IMPORT_LABEL); + + graph_1=s_get_a (a_offset); + + s_push_a (graph_1); + + s_push_b (NULL); + insert_basic_block (JSR_BLOCK,1,0+1,e_vector,print_symbol_label); +} + +void code_print_symbol_sc (int a_offset) +{ + INSTRUCTION_GRAPH graph_1; + + if (print_symbol_sc_label==NULL) + print_symbol_sc_label=enter_label ("print_symbol_sc",IMPORT_LABEL); + + graph_1=s_get_a (a_offset); + + s_push_a (graph_1); + + s_push_b (NULL); + insert_basic_block (JSR_BLOCK,1,0+1,e_vector,print_symbol_sc_label); +} + +void code_printD (VOID) +{ + if (printD_label==NULL) + printD_label=enter_label ("printD",IMPORT_LABEL); + + s_push_b (s_get_b (0)); + s_put_b (1,NULL); + + insert_basic_block (JSR_BLOCK,0,1+1,i_i_vector,printD_label); +} + +#if 0 +void code_print_r_arg (int a_offset) +{ + if (print_r_arg_label==NULL) + print_r_arg_label=enter_label ("print_r_arg",IMPORT_LABEL); + + s_push_b (s_get_b (0)); + s_put_b (1,NULL); + + if (a_offset!=0) + s_push_a (s_get_a (a_offset)); + + insert_basic_block (JSR_BLOCK,1,1+1,i_i_vector,print_r_arg_label); + + init_a_stack (1); + init_b_stack (2,i_i_vector); + + if (a_offset!=0) + s_put_a (a_offset,s_pop_a()); +} +#endif + +void code_pushcaf (char *label_name,int a_stack_size,int b_stack_size) +{ + INSTRUCTION_GRAPH graph_1,graph_2; + LABEL *label; + int n_arguments; + + label=enter_label (label_name,0); + + graph_1=g_lea (label); + + n_arguments=a_stack_size+b_stack_size; + +#ifndef I486 + if (n_arguments>2 && n_arguments<8){ + INSTRUCTION_GRAPH graph_2; + + graph_2=g_movem (4,graph_1,n_arguments); + + while (b_stack_size>0){ + --n_arguments; + s_push_b (g_movemi (n_arguments,graph_2)); + --b_stack_size; + } + + while (a_stack_size>0){ + --n_arguments; + s_push_a (g_movemi (n_arguments,graph_2)); + --a_stack_size; + } + } else +#endif + { + int offset; + + offset=n_arguments<<2; + + while (b_stack_size>0){ + s_push_b (g_load_id (offset,graph_1)); + offset-=4; + --b_stack_size; + } + + while (a_stack_size>0){ + s_push_a (g_load_id (offset,graph_1)); + offset-=4; + --a_stack_size; + } + } +} + +void code_pushA_a (int a_offset) +{ + INSTRUCTION_GRAPH graph_1,graph_2; + + graph_1=s_get_a (a_offset); + graph_2=g_load_id (4,graph_1); + + s_push_a (graph_2); +} + +void code_pushB (int b) +{ + INSTRUCTION_GRAPH graph_1; + +#ifdef I486 + graph_1=g_load_i (b); +#else + graph_1=g_load_i (-b); +#endif + s_push_b (graph_1); +} + +void code_pushB_a (int a_offset) +{ + INSTRUCTION_GRAPH graph_1,graph_2; + + graph_1=s_get_a (a_offset); + graph_2=g_load_id (ARGUMENTS_OFFSET-NODE_POINTER_OFFSET,graph_1); + + s_push_b (graph_2); +} + +void code_pushC (int c) +{ + INSTRUCTION_GRAPH graph_1; + + graph_1=g_load_i (c); + s_push_b (graph_1); +} + +void code_pushC_a (int a_offset) +{ + INSTRUCTION_GRAPH graph_1,graph_2; + + graph_1=s_get_a (a_offset); + graph_2=g_load_id (ARGUMENTS_OFFSET-NODE_POINTER_OFFSET,graph_1); + + s_push_b (graph_2); +} + +void code_pushD (char *descriptor) +{ + INSTRUCTION_GRAPH graph_1; + LABEL *descriptor_label; + + descriptor_label=enter_label (descriptor,0); + +#ifdef G_POWER + if ((descriptor_label->label_flags & (STRING_LABEL | DATA_LABEL))==DATA_LABEL){ +#else + if (descriptor_label->label_flags & DATA_LABEL){ +#endif + + /* graph_1=g_load_des_i (descriptor_label,0); */ + graph_1=g_lea (descriptor_label->label_descriptor); + } else + graph_1=g_lea (descriptor_label); + +#ifndef M68000 + --graph_1->instruction_d_min_a_cost; +#endif + + s_push_b (graph_1); +} + +void code_pushD_a (int a_offset) +{ + INSTRUCTION_GRAPH graph_1,graph_2; + + graph_1=s_get_a (a_offset); + graph_2=g_load_id (0,graph_1); + + s_push_b (graph_2); +} + +void code_pushF_a (int a_offset) +{ + INSTRUCTION_GRAPH graph_1,graph_2,graph_3,graph_4; + + graph_1=s_get_a (a_offset); + + graph_2=g_movem (ARGUMENTS_OFFSET-NODE_POINTER_OFFSET,graph_1,2); + graph_3=g_movemi (0,graph_2); + graph_4=g_movemi (1,graph_2); + + s_push_b (graph_3); + s_push_b (graph_4); +} + +void code_pushI (LONG i) +{ + INSTRUCTION_GRAPH graph_1; + + graph_1=g_load_i (i); + s_push_b (graph_1); +} + +void code_pushI_a (int a_offset) +{ + INSTRUCTION_GRAPH graph_1,graph_2; + + graph_1=s_get_a (a_offset); + graph_2=g_load_id (ARGUMENTS_OFFSET-NODE_POINTER_OFFSET,graph_1); + + s_push_b (graph_2); +} + +void code_pushL (char *label_name) +{ + INSTRUCTION_GRAPH graph_1; + LABEL *label; + + label=enter_label (label_name,0); + + graph_1=g_lea (label); + +#ifndef M68000 + --graph_1->instruction_d_min_a_cost; +#endif + + s_push_b (graph_1); +} + +void code_pushR (double v) +{ + INSTRUCTION_GRAPH graph_1,graph_2,graph_3; + + if (!mc68881_flag){ + DOUBLE r=v; + + graph_2=g_load_i (((long*)&r)[0]); + graph_3=g_load_i (((long*)&r)[1]); + } else { + graph_1=g_fload_i (v); + + g_fhighlow (graph_2,graph_3,graph_1); + } + + s_push_b (graph_3); + s_push_b (graph_2); +} + +void code_pushR_a (int a_offset) +{ + INSTRUCTION_GRAPH graph_1,graph_2,graph_3,graph_4; + + graph_1=s_get_a (a_offset); + + if (!mc68881_flag){ + /* + graph_2=g_movem (ARGUMENTS_OFFSET,graph_1,2); + graph_3=g_movemi (0,graph_2); + graph_4=g_movemi (1,graph_2); + */ + graph_3=g_load_id (ARGUMENTS_OFFSET-NODE_POINTER_OFFSET,graph_1); + graph_4=g_load_id (ARGUMENTS_OFFSET-NODE_POINTER_OFFSET+4,graph_1); + } else { + graph_2=g_fload_id (ARGUMENTS_OFFSET-NODE_POINTER_OFFSET,graph_1); + + g_fhighlow (graph_3,graph_4,graph_2); + } + + s_push_b (graph_4); + s_push_b (graph_3); +} + +void code_pushzs (char *string,int length) +{ + INSTRUCTION_GRAPH graph_1; + LABEL *string_label; + + string_label=w_code_string (string,length); + + graph_1=g_lea (string_label); + + s_push_b (graph_1); +} + +void code_push_a (int a_offset) +{ + INSTRUCTION_GRAPH graph_1; + + graph_1=s_get_a (a_offset); + s_push_a (graph_1); +} + +void code_push_b (int b_offset) +{ + INSTRUCTION_GRAPH graph_1; + + graph_1=s_get_b (b_offset); + s_push_b (graph_1); +} + +void code_push_a_b (int a_offset) +{ + INSTRUCTION_GRAPH graph_1; + + graph_1=s_get_a (a_offset); + s_push_b (graph_1); +} + +void code_push_a_r_args (VOID) +{ + if (push_a_r_args_label==NULL) + push_a_r_args_label=enter_label ("push_a_r_args",IMPORT_LABEL); + + s_push_b (s_get_b (0)); + s_put_b (1,NULL); + insert_basic_block (JSR_BLOCK,1,1+1,i_vector,push_a_r_args_label); + + init_b_stack (1,i_vector); +} + +void code_push_t_r_a (int a_offset) +{ + INSTRUCTION_GRAPH graph_1,graph_2,graph_3; + + graph_1=s_get_a (a_offset); +#if defined (sparc) || defined (I486) || defined (G_POWER) + graph_2=g_load_id (0,graph_1); + graph_3=g_add (g_load_i (2),graph_2); +#else + graph_2=g_load_des_id (DESCRIPTOR_OFFSET,graph_1); + graph_3=g_add (g_load_i (4),g_add (g_g_register (GLOBAL_DATA_REGISTER),graph_2)); +#endif + + s_push_b (graph_3); +} + +void code_push_t_r_args (VOID) +{ + if (push_t_r_args_label==NULL) + push_t_r_args_label=enter_label ("push_t_r_args",IMPORT_LABEL); + + s_push_b (NULL); + insert_basic_block (JSR_BLOCK,1,0+1,e_vector,push_t_r_args_label); + + init_b_stack (1,i_vector); +} + +void code_push_arg (int a_offset,int arity,int argument_number) +{ + INSTRUCTION_GRAPH graph_1,graph_2; + + graph_1=s_get_a (a_offset); + if (argument_number<2 || (argument_number==2 && arity==2)) + graph_2=g_load_id (argument_number<<2,graph_1); + else { + INSTRUCTION_GRAPH graph_3; + + graph_3=g_load_id (8,graph_1); + graph_2=g_load_id ((argument_number-2)<<2,graph_3); + } + + s_push_a (graph_2); +} + +void code_push_arg_b (int a_offset) +{ + INSTRUCTION_GRAPH graph_1,graph_2; + + graph_2=s_get_b (0); + + if (graph_2->instruction_code==GLOAD_I && graph_2->instruction_parameters[0].i!=2){ + int argument_number; + + argument_number=graph_2->instruction_parameters[0].i; + s_remove_b(); + s_remove_b(); + code_push_arg (a_offset,argument_number,argument_number); + } else { + if (push_arg_b_label==NULL) + push_arg_b_label=enter_label ("push_arg_b",IMPORT_LABEL); + + graph_1=s_get_a (a_offset); + s_push_a (graph_1); + + 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,1,2+1,i_i_vector,push_arg_b_label); + + init_a_stack (1); + } +} + +void code_push_args (int a_offset,int arity,int n_arguments) +{ + INSTRUCTION_GRAPH graph_1,graph_2,graph_3; + + if (n_arguments==0) + return; + + graph_1=s_get_a (a_offset); + graph_2=g_load_id (ARGUMENTS_OFFSET-NODE_POINTER_OFFSET,graph_1); + + if (n_arguments!=1) + if (n_arguments==2 && arity==2){ + graph_3=g_load_id (8-NODE_POINTER_OFFSET,graph_1); + s_push_a (graph_3); + } else { + INSTRUCTION_GRAPH graph_4; + + graph_3=g_load_id (8-NODE_POINTER_OFFSET,graph_1); + --n_arguments; + + if (n_arguments==1){ + graph_4=g_load_id (0-NODE_POINTER_OFFSET,graph_3); + s_push_a (graph_4); + } else { +#ifndef I486 + if (n_arguments>=8){ +#endif + while (n_arguments!=0){ + INSTRUCTION_GRAPH graph_5; + + --n_arguments; + + graph_5=g_load_id ((n_arguments<<2)-NODE_POINTER_OFFSET,graph_3); + + s_push_a (graph_5); + } +#ifndef I486 + } else { + graph_4=g_movem (0-NODE_POINTER_OFFSET,graph_3,n_arguments); + while (n_arguments!=0){ + INSTRUCTION_GRAPH graph_5; + + --n_arguments; + + graph_5=g_movemi (n_arguments,graph_4); + s_push_a (graph_5); + } + } +#endif + } + } + + s_push_a (graph_2); +} + +void code_push_arraysize (char element_descriptor[],int a_size,int b_size) +{ + INSTRUCTION_GRAPH graph_1,graph_2; + + graph_1=s_pop_a(); + graph_2=g_load_id (4,graph_1); + s_push_b (graph_2); +} + +void code_push_b_a (int a_offset) +{ + INSTRUCTION_GRAPH graph_1; + + graph_1=s_get_b (a_offset); + s_push_a (graph_1); +} + +#ifdef FINALIZERS +void code_push_finalizers (VOID) +{ + INSTRUCTION_GRAPH graph_1,graph_2; + LABEL *finalizer_list_label; + + finalizer_list_label=enter_label ("finalizer_list",DATA_LABEL | IMPORT_LABEL); + + graph_1=g_lea (finalizer_list_label); + graph_2=g_load_id (0,graph_1); + + s_push_a (graph_2); +} +#endif + +static void push_record_arguments (INSTRUCTION_GRAPH graph_1,int a_size,int b_size) +{ + INSTRUCTION_GRAPH graph_2,graph_3,graph_4,graph_5; + + switch (a_size+b_size){ + case 0: + return; + case 1: + graph_2=g_load_id (ARGUMENTS_OFFSET-NODE_POINTER_OFFSET,graph_1); + if (a_size!=0) + s_push_a (graph_2); + else + s_push_b (graph_2); + return; + case 2: + graph_2=g_load_id (ARGUMENTS_OFFSET-NODE_POINTER_OFFSET,graph_1); + graph_3=g_load_id (8-NODE_POINTER_OFFSET,graph_1); + switch (b_size){ + case 0: + s_push_a (graph_3); + s_push_a (graph_2); + break; + case 1: + s_push_a (graph_2); + s_push_b (graph_3); + break; + default: + s_push_b (graph_3); + s_push_b (graph_2); + } + return; + default: + graph_2=g_load_id (ARGUMENTS_OFFSET-NODE_POINTER_OFFSET,graph_1); + graph_3=g_load_id (8-NODE_POINTER_OFFSET,graph_1); + +#ifdef M68000 + if (a_size+b_size-1>=8){ +#endif + b_size+=a_size; + + while (b_size>a_size && b_size>1){ + --b_size; + graph_5=g_load_id (((b_size-1)<<2)-NODE_POINTER_OFFSET,graph_3); + s_push_b (graph_5); + } + + while (a_size>1){ + --a_size; + graph_5=g_load_id (((a_size-1)<<2)-NODE_POINTER_OFFSET,graph_3); + s_push_a (graph_5); + } +#ifdef M68000 + } else { + graph_4=g_movem (0-NODE_POINTER_OFFSET,graph_3,a_size+b_size-1); + + b_size+=a_size; + + while (b_size>a_size && b_size>1){ + --b_size; + graph_5=g_movemi (b_size-1,graph_4); + s_push_b (graph_5); + } + + while (a_size>1){ + --a_size; + graph_5=g_movemi (a_size-1,graph_4); + s_push_a (graph_5); + } + } +#endif + if (a_size>0) + s_push_a (graph_2); + else + s_push_b (graph_2); + return; + } +} + +void code_push_r_args (int a_offset,int a_size,int b_size) +{ + INSTRUCTION_GRAPH graph_1; + + graph_1=s_get_a (a_offset); + + push_record_arguments (graph_1,a_size,b_size); +} + +void code_push_r_arg_t (VOID) +{ + INSTRUCTION_GRAPH graph_1,graph_2; + + graph_1=s_get_b (0); + graph_2=g_load_b_id (0,graph_1); + s_put_b (0,graph_2); +} + +void code_push_r_args_a (int a_offset,int a_size,int b_size,int argument_number,int n_arguments) +{ + INSTRUCTION_GRAPH graph_1,graph_2,graph_3; + + graph_1=s_get_a (a_offset); + graph_3=NULL; + + argument_number+=n_arguments; + for (; n_arguments>0; --n_arguments){ + --argument_number; + if (argument_number<2 || (argument_number==2 && a_size+b_size==2)) + graph_2=g_load_id (argument_number<<2,graph_1); + else { + if (graph_3==NULL) + graph_3=g_load_id (8,graph_1); + graph_2=g_load_id ((argument_number-2)<<2,graph_3); + } + s_push_a (graph_2); + } +} + +void code_push_r_args_b (int a_offset,int a_size,int b_size,int argument_number,int n_arguments) +{ + INSTRUCTION_GRAPH graph_1,graph_2,graph_3; + + graph_1=s_get_a (a_offset); + graph_3=NULL; + + argument_number+=a_size+n_arguments; + for (; n_arguments>0; --n_arguments){ + --argument_number; + if (argument_number<2 || (argument_number==2 && a_size+b_size==2)) + graph_2=g_load_id (argument_number<<2,graph_1); + else { + if (graph_3==NULL) + graph_3=g_load_id (8,graph_1); + graph_2=g_load_id ((argument_number-2)<<2,graph_3); + } + s_push_b (graph_2); + } +} + +void code_push_node (char *label_name,int n_arguments) +{ + INSTRUCTION_GRAPH graph_1,graph_2,graph_3,graph_4,graph_5; + + if (EMPTY_label==NULL) + EMPTY_label=enter_label ("EMPTY",IMPORT_LABEL | DATA_LABEL); + + if (!strcmp (label_name,"__cycle__in__spine")){ +#if !(defined (sparc) || defined (G_POWER)) + if (cycle_in_spine_label==NULL){ + cycle_in_spine_label=enter_label ("__cycle__in__spine",IMPORT_LABEL | NODE_ENTRY_LABEL); + cycle_in_spine_label->label_arity=0; + cycle_in_spine_label->label_descriptor=EMPTY_label; + } + graph_2=g_lea (cycle_in_spine_label); +#else + graph_2=g_g_register (RESERVE_CODE_REGISTER); +#endif + } else if (!strcmp (label_name,"__reserve")){ +#ifndef sparc + if (reserve_label==NULL){ + reserve_label=enter_label ("__reserve",IMPORT_LABEL | NODE_ENTRY_LABEL); + reserve_label->label_arity=0; + reserve_label->label_descriptor=EMPTY_label; + } + graph_2=g_lea (reserve_label); +#else + graph_2=g_g_register (RESERVE_CODE_REGISTER); +#endif + } else if (label_name[0]=='_' && label_name[1]=='_' && label_name[2]=='\0') + graph_2=NULL; + else { + LABEL *label; + + label=enter_label (label_name,NODE_ENTRY_LABEL); + label->label_arity=0; + label->label_descriptor=EMPTY_label; + graph_2=g_lea (label); + } + + graph_1=s_get_a (0); + + if (n_arguments!=0){ + if (n_arguments!=1){ + int argument_n; +#ifdef I486 + argument_n=n_arguments; + while (argument_n!=0){ + graph_5=g_load_id ((argument_n<<2)-NODE_POINTER_OFFSET,graph_1); + --argument_n; + s_push_a (graph_5); + } +#else + graph_4=g_movem (4-NODE_POINTER_OFFSET,graph_1,n_arguments); + + argument_n=n_arguments; + while (argument_n!=0){ + --argument_n; + graph_5=g_movemi (argument_n,graph_4); + s_push_a (graph_5); + } +#endif + } else { + graph_4=g_load_id (4-NODE_POINTER_OFFSET,graph_1); + s_push_a (graph_4); + } + } + + if (graph_2==NULL) + graph_3=graph_1; + else + graph_3=g_fill_2 (graph_1,graph_2); + + s_put_a (n_arguments,graph_3); +} + +void code_push_node_u (char *label_name,int a_size,int b_size) +{ + INSTRUCTION_GRAPH graph_1,graph_2,graph_3,graph_4,graph_5; + + if (EMPTY_label==NULL) + EMPTY_label=enter_label ("EMPTY",IMPORT_LABEL | DATA_LABEL); + + if (!strcmp (label_name,"__cycle__in__spine")){ +#if !(defined (sparc) || defined (G_POWER)) + if (cycle_in_spine_label==NULL){ + cycle_in_spine_label=enter_label ("__cycle__in__spine",IMPORT_LABEL | NODE_ENTRY_LABEL); + cycle_in_spine_label->label_arity=0; + cycle_in_spine_label->label_descriptor=EMPTY_label; + } + graph_2=g_lea (cycle_in_spine_label); +#else + graph_2=g_g_register (RESERVE_CODE_REGISTER); +#endif + } else if (!strcmp (label_name,"__reserve")){ +#ifndef sparc + if (reserve_label==NULL){ + reserve_label=enter_label ("__reserve",IMPORT_LABEL | NODE_ENTRY_LABEL); + reserve_label->label_arity=0; + reserve_label->label_descriptor=EMPTY_label; + } + graph_2=g_lea (reserve_label); +#else + graph_2=g_g_register (RESERVE_CODE_REGISTER); +#endif + } else if (label_name[0]=='_' && label_name[1]=='_' && label_name[2]=='\0') + graph_2=NULL; + else { + LABEL *label; + + label=enter_label (label_name,NODE_ENTRY_LABEL); + label->label_arity=0; + label->label_descriptor=EMPTY_label; + graph_2=g_lea (label); + } + + graph_1=s_get_a (0); + + if (a_size+b_size!=0){ + if (a_size+b_size!=1){ + int argument_n; +#ifdef I486 + argument_n=a_size+b_size; + while (argument_n!=0){ + graph_5=g_load_id ((argument_n<<2)-NODE_POINTER_OFFSET,graph_1); + --argument_n; + if (argument_n<a_size) + s_push_a (graph_5); + else + s_push_b (graph_5); + } +#else + graph_4=g_movem (4-NODE_POINTER_OFFSET,graph_1,a_size+b_size); + + argument_n=a_size+b_size; + while (argument_n!=0){ + --argument_n; + graph_5=g_movemi (argument_n,graph_4); + if (argument_n<a_size) + s_push_a (graph_5); + else + s_push_b (graph_5); + } +#endif + } else { + graph_4=g_load_id (4-NODE_POINTER_OFFSET,graph_1); + if (a_size>0) + s_push_a (graph_4); + else + s_push_b (graph_4); + } + } + + if (graph_2==NULL) + graph_3=graph_1; + else + graph_3=g_fill_2 (graph_1,graph_2); + + s_put_a (a_size,graph_3); +} + +# if defined(sparc) +# define MAX_INDIRECT_OFFSET 4095 +# else +# define MAX_INDIRECT_OFFSET 8191 +# endif + +#ifdef INDEX_CSE +#define INDEX_CSE_CACHE_SIZE 16 /* power of 2 */ + +static INSTRUCTION_GRAPH lsl_2_add_12_cache_index[INDEX_CSE_CACHE_SIZE]; +static INSTRUCTION_GRAPH lsl_2_add_12_cache_offset[INDEX_CSE_CACHE_SIZE]; +static int n_lsl_2_add_12_cache; +static struct basic_block *block_in_lsl_2_add_12_cache; + +static INSTRUCTION_GRAPH lsl_3_add_12_cache_index[INDEX_CSE_CACHE_SIZE]; +static INSTRUCTION_GRAPH lsl_3_add_12_cache_offset[INDEX_CSE_CACHE_SIZE]; +static int n_lsl_3_add_12_cache; +static struct basic_block *block_in_lsl_3_add_12_cache; +#endif + +static INSTRUCTION_GRAPH g_lsl_2_add_12 (INSTRUCTION_GRAPH graph_1) +{ + INSTRUCTION_GRAPH graph_2; + int i; + +#ifdef INDEX_CSE + if (block_in_lsl_2_add_12_cache!=last_block){ + n_lsl_2_add_12_cache=0; + block_in_lsl_2_add_12_cache=last_block; + } else { + int n; + + n=n_lsl_2_add_12_cache; + if (n<=INDEX_CSE_CACHE_SIZE){ + while (--n>=0) + if (lsl_2_add_12_cache_index[n]==graph_1) + return lsl_2_add_12_cache_offset[n]; + } else { + int e; + + e = n & (INDEX_CSE_CACHE_SIZE-1); + + n = e; + while (--n>=0) + if (lsl_2_add_12_cache_index[n]==graph_1) + return lsl_2_add_12_cache_offset[n]; + + n = INDEX_CSE_CACHE_SIZE; + while (--n>=e) + if (lsl_2_add_12_cache_index[n]==graph_1) + return lsl_2_add_12_cache_offset[n]; + } + } +#endif + + graph_2=g_add (g_load_i (12),g_lsl (g_load_i (2),graph_1)); + +#ifdef INDEX_CSE + i=n_lsl_2_add_12_cache & (INDEX_CSE_CACHE_SIZE-1); + lsl_2_add_12_cache_index[i]=graph_1; + lsl_2_add_12_cache_offset[i]=graph_2; + ++n_lsl_2_add_12_cache; +#endif + + return graph_2; +} + +/* just add_12 for sparc */ +static INSTRUCTION_GRAPH g_lsl_3_add_12 (INSTRUCTION_GRAPH graph_1) +{ + INSTRUCTION_GRAPH graph_2; + int i; + +#ifdef INDEX_CSE + if (block_in_lsl_3_add_12_cache!=last_block){ + n_lsl_3_add_12_cache=0; + block_in_lsl_3_add_12_cache=last_block; + } else { + int n; + + n=n_lsl_3_add_12_cache; + if (n<=INDEX_CSE_CACHE_SIZE){ + while (--n>=0) + if (lsl_3_add_12_cache_index[n]==graph_1) + return lsl_3_add_12_cache_offset[n]; + } else { + int e; + + e = n & (INDEX_CSE_CACHE_SIZE-1); + + n = e; + while (--n>=0) + if (lsl_3_add_12_cache_index[n]==graph_1) + return lsl_3_add_12_cache_offset[n]; + + n = INDEX_CSE_CACHE_SIZE; + while (--n>=e) + if (lsl_3_add_12_cache_index[n]==graph_1) + return lsl_3_add_12_cache_offset[n]; + } + } +#endif + +#ifdef sparc + graph_2=g_lsl (g_load_i (3),graph_1); +#else + graph_2=g_add (g_load_i (12),g_lsl (g_load_i (3),graph_1)); +#endif + +#ifdef INDEX_CSE + i=n_lsl_3_add_12_cache & (INDEX_CSE_CACHE_SIZE-1); + lsl_3_add_12_cache_index[i]=graph_1; + lsl_3_add_12_cache_offset[i]=graph_2; + ++n_lsl_3_add_12_cache; +#endif + + return graph_2; +} + +static void code_replaceI (VOID) +{ + INSTRUCTION_GRAPH graph_1,graph_2,graph_3,graph_4,graph_5; + + graph_1=s_get_a (0); + graph_2=s_pop_b(); + graph_3=s_get_b (0); + + if (!check_index_flag && graph_2->instruction_code==GLOAD_I && + LESS_UNSIGNED (graph_2->instruction_parameters[0].i,(MAX_INDIRECT_OFFSET-12)>>2)) + { + int offset; + offset=12+(graph_2->instruction_parameters[0].i<<2); + + graph_5=g_load_x (graph_1,offset,0,NULL); + graph_4=g_store_x (graph_3,graph_1,offset,0,NULL); + } else { + if (check_index_flag) + graph_2=g_bounds (graph_1,graph_2); + +#if defined (M68000) || defined (I486) +# ifdef M68000 + if (mc68000_flag){ + graph_2=g_lsl (g_load_i (2),graph_2); + graph_5=g_load_x (graph_1,12,0,graph_2); + graph_4=g_store_x (graph_3,graph_1,12,0,graph_2); + } else +# endif + { + graph_5=g_load_x (graph_1,12,2,graph_2); + graph_4=g_store_x (graph_3,graph_1,12,2,graph_2); + } +#else + graph_2=g_lsl_2_add_12 (graph_2); + graph_5=g_load_x (graph_1,0,0,graph_2); + graph_4=g_store_x (graph_3,graph_1,0,0,graph_2); +#endif + } + + s_put_b (0,graph_5); + s_put_a (0,graph_4); +} + +static void code_replaceBC (int offset,int ext_signed) +{ + INSTRUCTION_GRAPH graph_1,graph_2,graph_3,graph_4,graph_5; + + graph_1=s_get_a (0); + graph_2=s_pop_b(); + graph_3=s_get_b (0); + + if (!check_index_flag && graph_2->instruction_code==GLOAD_I && + LESS_UNSIGNED (graph_2->instruction_parameters[0].i,MAX_INDIRECT_OFFSET-offset)) + { + offset+=graph_2->instruction_parameters[0].i; + + graph_5=g_load_b_x (graph_1,offset,ext_signed,NULL); + graph_4=g_store_b_x (graph_3,graph_1,offset,NULL); + } else { + if (check_index_flag) + graph_2=g_bounds (graph_1,graph_2); + +#if defined (M68000) || defined (I486) + graph_5=g_load_b_x (graph_1,offset,ext_signed,graph_2); + graph_4=g_store_b_x (graph_3,graph_1,offset,graph_2); +#else + graph_2=g_add (g_load_i (offset),graph_2); + graph_5=g_load_b_x (graph_1,0,ext_signed,graph_2); + graph_4=g_store_b_x (graph_3,graph_1,0,graph_2); +#endif + } + + s_put_b (0,graph_5); + s_put_a (0,graph_4); +} + +static void code_lazy_replace (VOID) +{ + INSTRUCTION_GRAPH graph_1,graph_2,graph_3,graph_4,graph_5; + + graph_1=s_pop_a(); + graph_2=s_get_a (0); + graph_3=s_pop_b(); + + if (!check_index_flag && graph_3->instruction_code==GLOAD_I && + LESS_UNSIGNED (graph_3->instruction_parameters[0].i,(MAX_INDIRECT_OFFSET-12)>>2)) + { + int offset; + + offset=12+(graph_3->instruction_parameters[0].i<<2); + graph_5=g_load_x (graph_1,offset,0,NULL); + graph_4=g_store_x (graph_2,graph_1,offset,0,NULL); + } else { + if (check_index_flag) + graph_3=g_bounds (graph_1,graph_3); + +#if defined (M68000) || defined (I486) +# ifdef M68000 + if (mc68000_flag){ + graph_3=g_lsl (g_load_i (2),graph_3); + graph_5=g_load_x (graph_1,12,0,graph_3); + graph_4=g_store_x (graph_2,graph_1,12,0,graph_3); + } else +# endif + { + graph_5=g_load_x (graph_1,12,2,graph_3); + graph_4=g_store_x (graph_2,graph_1,12,2,graph_3); + } +#else + graph_3=g_lsl_2_add_12 (graph_3); + graph_5=g_load_x (graph_1,0,0,graph_3); + graph_4=g_store_x (graph_2,graph_1,0,0,graph_3); +#endif + } + + s_put_a (0,graph_4); + s_push_a (graph_5); +} + +static void code_replaceR (VOID) +{ + INSTRUCTION_GRAPH graph_1,graph_2,graph_3,graph_4,graph_5,graph_6,graph_7,graph_8,graph_9,graph_10; + + graph_1=s_get_a (0); + graph_2=s_pop_b(); + + graph_3=s_pop_b(); + graph_4=s_pop_b(); + + if (check_index_flag) + graph_2=g_bounds (graph_1,graph_2); + +#ifdef M68000 + if (!mc68881_flag){ + if (!check_index_flag && graph_2->instruction_code==GLOAD_I && + LESS_UNSIGNED (graph_2->instruction_parameters[0].i,(MAX_INDIRECT_OFFSET-16)>>3)) + { + int offset; + + offset=12+(graph_2->instruction_parameters[0].i<<3); + graph_9=g_load_x (graph_1,offset,0,NULL); + graph_10=g_load_x (graph_1,offset+4,0,NULL); + graph_7=g_store_x (graph_3,graph_1,offset,0,NULL); + graph_8=g_store_x (graph_4,graph_7,offset+4,0,NULL); + } else { + if (mc68000_flag){ + graph_5=g_load_i (3); + graph_6=g_lsl (graph_5,graph_2); + graph_9=g_load_x (graph_1,12,0,graph_6); + graph_10=g_load_x (graph_1,16,0,graph_6); + graph_7=g_store_x (graph_3,graph_1,12,0,graph_6); + graph_8=g_store_x (graph_4,graph_7,16,0,graph_6); + } else { + graph_9=g_load_x (graph_1,12,3,graph_2); + graph_10=g_load_x (graph_1,16,3,graph_2); + graph_7=g_store_x (graph_3,graph_1,12,3,graph_2); + graph_8=g_store_x (graph_4,graph_7,16,3,graph_2); + } + } + } else +#endif + { + graph_7=g_fjoin (graph_3,graph_4); + + if (!check_index_flag && graph_2->instruction_code==GLOAD_I && + LESS_UNSIGNED (graph_2->instruction_parameters[0].i,(MAX_INDIRECT_OFFSET-12)>>3)) + { + int offset; + + offset=12+(graph_2->instruction_parameters[0].i<<3); + graph_4=g_fload_x (graph_1,offset,0,NULL); + graph_8=g_fstore_x (graph_7,graph_1,offset,0,NULL); + } else { +#if defined (M68000) || defined (I486) + graph_4=g_fload_x (graph_1,12,3,graph_2); + graph_8=g_fstore_x (graph_7,graph_1,12,3,graph_2); +#else + graph_2=g_lsl_3_add_12 (graph_2); +# ifdef sparc + graph_4=g_fload_x (graph_1,12,0,graph_2); + graph_8=g_fstore_x (graph_7,graph_1,12,0,graph_2); +# else + graph_4=g_fload_x (graph_1,0,0,graph_2); + graph_8=g_fstore_x (graph_7,graph_1,0,0,graph_2); +# endif +#endif + } + + g_fhighlow (graph_9,graph_10,graph_4); + } + + s_put_a (0,graph_8); + + s_push_b (graph_10); + s_push_b (graph_9); +} + +static void code_r_replace (int a_size,int b_size) +{ + INSTRUCTION_GRAPH graph_1,graph_2,graph_3; + int i,element_size,offset; + + graph_1=s_get_a (0); + graph_2=s_pop_b(); + + element_size=(a_size+b_size)<<2; + + if (!check_index_flag && graph_2->instruction_code==GLOAD_I && + LESS_UNSIGNED (graph_2->instruction_parameters[0].i,(MAX_INDIRECT_OFFSET-12-(element_size-4))/element_size)) + { + offset=12+graph_2->instruction_parameters[0].i*element_size; + graph_3=NULL; + } else { + if (check_index_flag) + graph_2=g_bounds (graph_1,graph_2); + + offset=12; + graph_3=multiply_by_constant ((a_size+b_size)<<2,graph_2); + } + + for (i=0; i<a_size; ++i){ + INSTRUCTION_GRAPH graph_4,graph_5; + + graph_4=s_get_a (i+1); +#if defined (sparc) || defined (G_POWER) + if (offset+(i<<2)!=0 && graph_3!=NULL){ + INSTRUCTION_GRAPH graph_6; + + graph_6=g_add (g_load_i (offset+(i<<2)),graph_3); + graph_5=g_load_x (graph_1,0,0,graph_6); + graph_1=g_store_x (graph_4,graph_1,0,0,graph_6); + } else +#endif + { + graph_5=g_load_x (graph_1,offset+(i<<2),0,graph_3); + graph_1=g_store_x (graph_4,graph_1,offset+(i<<2),0,graph_3); + } + + s_put_a (i,graph_5); + } + + for (i=0; i<b_size; ++i){ + INSTRUCTION_GRAPH graph_4,graph_5; + + graph_4=s_get_b (i); +#if defined (sparc) || defined (G_POWER) + if (offset+((a_size+i)<<2)!=0 && graph_3!=NULL){ + INSTRUCTION_GRAPH graph_6; + + graph_6=g_add (g_load_i (offset+((a_size+i)<<2)),graph_3); + graph_5=g_load_x (graph_1,0,0,graph_6); + graph_1=g_store_x (graph_4,graph_1,0,0,graph_6); + } else +#endif + { + graph_5=g_load_x (graph_1,offset+((a_size+i)<<2),0,graph_3); + graph_1=g_store_x (graph_4,graph_1,offset+((a_size+i)<<2),0,graph_3); + } + + s_put_b (i,graph_5); + } + + s_put_a (a_size,graph_1); +} + +void code_replace (char element_descriptor[],int a_size,int b_size) +{ + if (check_index_flag && index_error_label==NULL){ + index_error_label=enter_label ("index__error",0); + if (!(index_error_label->label_flags & EXPORT_LABEL)) + index_error_label->label_flags |= IMPORT_LABEL; + } + + switch (element_descriptor[0]){ + case 'B': + if (element_descriptor[1]=='O' && element_descriptor[2]=='O' && element_descriptor[3]=='L' && + element_descriptor[4]=='\0') + { + code_replaceBC (12,1); + return; + } + break; + case 'C': + if (element_descriptor[1]=='H' && element_descriptor[2]=='A' && element_descriptor[3]=='R' && + element_descriptor[4]=='\0') + { + code_replaceBC (8,0); + return; + } + break; + case 'I': + if (element_descriptor[1]=='N' && element_descriptor[2]=='T' && element_descriptor[3]=='\0'){ + code_replaceI(); + return; + } + break; + case 'P': + if (is__rocid (element_descriptor)){ + code_replaceI(); + return; + } + break; + case 'R': + if (element_descriptor[1]=='E' && element_descriptor[2]=='A' && element_descriptor[3]=='L' && + element_descriptor[4]=='\0') + { + code_replaceR(); + return; + } + break; + case 'A': + if (element_descriptor[1]=='R' && element_descriptor[2]=='R' && element_descriptor[3]=='A' && + element_descriptor[4]=='Y' && element_descriptor[5]=='\0') + { + code_lazy_replace(); + return; + } + break; + case 'S': + if (element_descriptor[1]=='T' && element_descriptor[2]=='R' && element_descriptor[3]=='I' && + element_descriptor[4]=='N' && element_descriptor[5]=='G' && element_descriptor[6]=='\0') + { + code_lazy_replace(); + return; + } + break; + case 'W': + if (is__orld (element_descriptor)){ + code_lazy_replace(); + return; + } + break; + case '_': + if (element_descriptor[1]=='_' && element_descriptor[2]=='\0'){ + code_lazy_replace(); + return; + } + break; + } + + code_r_replace (a_size,b_size); +} + +void code_repl_arg (int arity,int argument_n) +{ + INSTRUCTION_GRAPH graph_1,graph_2; + + graph_1=s_pop_a(); + + if (argument_n<2 || (argument_n==2 && arity==2)) + graph_2=g_load_id (argument_n<<2,graph_1); + else { + INSTRUCTION_GRAPH graph_3; + + graph_3=g_load_id (8,graph_1); + graph_2=g_load_id ((argument_n-2)<<2,graph_3); + } + + s_push_a (graph_2); +} + +void code_repl_args (int arity,int n_arguments) +{ + INSTRUCTION_GRAPH graph_1,graph_2,graph_3; + + if (n_arguments==0) + return; + + graph_1=s_pop_a(); + graph_2=g_load_id (ARGUMENTS_OFFSET-NODE_POINTER_OFFSET,graph_1); + + if (n_arguments!=1) + if (n_arguments==2 && arity==2){ + graph_3=g_load_id (8-NODE_POINTER_OFFSET,graph_1); + s_push_a (graph_3); + } else { + INSTRUCTION_GRAPH graph_4; + + graph_3=g_load_id (8-NODE_POINTER_OFFSET,graph_1); + --n_arguments; + + if (n_arguments==1){ + graph_4=g_load_id (0-NODE_POINTER_OFFSET,graph_3); + s_push_a (graph_4); + } else { +#ifndef I486 + if (n_arguments>=8){ +#endif + while (n_arguments!=0){ + INSTRUCTION_GRAPH graph_5; + + --n_arguments; + + graph_5=g_load_id ((n_arguments<<2)-NODE_POINTER_OFFSET,graph_3); + s_push_a (graph_5); + } +#ifndef I486 + } else { + graph_4=g_movem (0-NODE_POINTER_OFFSET,graph_3,n_arguments); + + while (n_arguments!=0){ + INSTRUCTION_GRAPH graph_5; + + --n_arguments; + + graph_5=g_movemi (n_arguments,graph_4); + s_push_a (graph_5); + } + } +#endif + } + } + + s_push_a (graph_2); +} + +void code_repl_args_b (VOID) +{ + if (repl_args_b_label==NULL) + repl_args_b_label=enter_label ("repl_args_b",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,1,2+1,i_i_vector,repl_args_b_label); +} + +void code_repl_r_args (int a_size,int b_size) +{ + INSTRUCTION_GRAPH graph_1; + + graph_1=s_pop_a(); + + push_record_arguments (graph_1,a_size,b_size); +} + +void code_repl_r_args_a (int a_size,int b_size,int argument_number,int n_arguments) +{ + INSTRUCTION_GRAPH graph_1,graph_2,graph_3; + + graph_1=s_pop_a(); + graph_3=NULL; + + argument_number+=n_arguments; + for (; n_arguments>0; --n_arguments){ + --argument_number; + if (argument_number<2 || (argument_number==2 && a_size+b_size==2)) + graph_2=g_load_id (argument_number<<2,graph_1); + else { + if (graph_3==NULL) + graph_3=g_load_id (8,graph_1); + graph_2=g_load_id ((argument_number-2)<<2,graph_3); + } + s_push_a (graph_2); + } +} + +void code_release (void) +{ +} + +void code_rtn (void) +{ + int b_offset,a_stack_size,b_stack_size,return_with_rts,n_data_parameter_registers; + ULONG *local_demanded_vector; + + if (!demand_flag) + error ("Directive .d missing before rtn instruction"); + + a_stack_size=demanded_a_stack_size; + b_stack_size=demanded_b_stack_size; + local_demanded_vector=demanded_vector; + + n_data_parameter_registers= + parallel_flag ? N_DATA_PARAMETER_REGISTERS-1 : N_DATA_PARAMETER_REGISTERS; + +#if ! (defined (sparc) || defined (G_POWER)) + b_offset=0; +#else + b_offset=4; +#endif + return_with_rts=1; + + if (b_stack_size>n_data_parameter_registers || !mc68881_flag){ + int offset,n_data_registers,n_float_registers,n_float_parameter_registers; + + n_float_parameter_registers= mc68881_flag ? N_FLOAT_PARAMETER_REGISTERS : 0; + + n_data_registers=0; + n_float_registers=0; + + for (offset=0; offset<b_stack_size; ++offset) + if (local_demanded_vector[offset>>LOG_VECTOR_ELEMENT_SIZE] & (((ULONG)1)<<(offset & VECTOR_ELEMENT_MASK))){ + if (++n_float_registers>n_float_parameter_registers) + break; + ++offset; + } else + if (++n_data_registers>n_data_parameter_registers) + break; + + if (n_data_registers>n_data_parameter_registers || n_float_registers>n_float_parameter_registers){ + INSTRUCTION_GRAPH graph; + +#ifndef I486 + graph=s_get_b (b_stack_size); + for (offset=b_stack_size-1; offset>=0; --offset) + s_put_b (offset+1,s_get_b (offset)); + s_pop_b(); + s_push_a (graph); + + ++a_stack_size; + b_offset=0; + + return_with_rts=0; +#else + { + int return_address_offset; + ULONG mask,new_vector_0; + + if (n_data_registers>n_data_parameter_registers) + n_data_registers=n_data_parameter_registers; + if (n_float_registers>n_float_parameter_registers) + n_float_registers=n_float_parameter_registers; + return_address_offset=n_data_registers+(n_float_registers<<1); + + graph=s_get_b (b_stack_size); + for (offset=b_stack_size-1; offset>=return_address_offset; --offset) + s_put_b (offset+1,s_get_b (offset)); + s_put_b (return_address_offset,graph); + + ++b_stack_size; + mask=(1<<return_address_offset)-1; + new_vector_0=(local_demanded_vector[0] & mask) | ((local_demanded_vector[0] & ~mask)<<1); + if (b_stack_size < 32){ + static ULONG small_local_demanded_vector; + + small_local_demanded_vector=new_vector_0; + local_demanded_vector=&small_local_demanded_vector; + } else { + ULONG *new_vector_p; + int i,n_longs_in_vector; + + n_longs_in_vector=(b_stack_size+(1+32-1))>>5; + new_vector_p=(ULONG*)fast_memory_allocate (n_longs_in_vector * sizeof (ULONG)); + + new_vector_p[0]=new_vector_0; + if (b_stack_size+(1+32-1)==n_longs_in_vector<<5){ + --n_longs_in_vector; + new_vector_p[n_longs_in_vector]=(local_demanded_vector[n_longs_in_vector-1]>>31) & 1; + } + for (i=1; i<n_longs_in_vector; ++i) + new_vector_p[i]=(local_demanded_vector[i]<<1) | ((local_demanded_vector[i-1]>>31) & 1); + + local_demanded_vector=new_vector_p; + } + } +#endif + } + } + +#ifndef I486 + if (return_with_rts){ +#endif + b_offset+= + end_basic_block_with_registers_and_return_b_stack_offset + (a_stack_size,b_stack_size,local_demanded_vector,N_ADDRESS_PARAMETER_REGISTERS); + +#if ! (defined (sparc) || defined (G_POWER)) + if (b_offset!=0) + if (b_offset>0) + i_add_i_r (b_offset,B_STACK_POINTER); + else + i_sub_i_r (-b_offset,B_STACK_POINTER); + +# ifdef PROFILE + if (profile_function_label!=NULL) + i_rts_profile (); + else +# endif + i_rts(); +#else +# ifdef PROFILE + if (profile_function_label!=NULL) + i_rts_profile (b_offset-4,b_offset); + else +# endif + i_rts (b_offset-4,b_offset); +#endif +#ifndef I486 + } else { + b_offset+= + end_basic_block_with_registers_and_return_b_stack_offset + (a_stack_size,b_stack_size,local_demanded_vector,N_ADDRESS_PARAMETER_REGISTERS+1); + + if (a_stack_size>N_ADDRESS_PARAMETER_REGISTERS+1) + a_stack_size=N_ADDRESS_PARAMETER_REGISTERS+1; + +# ifdef sparc + if (b_offset!=0) + if (b_offset>0) + i_add_i_r (b_offset,B_STACK_POINTER); + else + i_sub_i_r (-b_offset,B_STACK_POINTER); + + i_jmp_id (8,num_to_a_reg (a_stack_size-1),(a_stack_size-1)<<4); +# else +# ifdef G_POWER + if (profile_function_label!=NULL) + i_rts_r_profile (num_to_a_reg (a_stack_size-1),b_offset); + else + i_rts_r (num_to_a_reg (a_stack_size-1),b_offset); +# else + if (b_offset!=0) + if (b_offset>0) + i_add_i_r (b_offset,B_STACK_POINTER); + else + i_sub_i_r (-b_offset,B_STACK_POINTER); + + i_jmp_id (0,num_to_a_reg (a_stack_size-1),(a_stack_size-1)<<4); +# endif +# endif + } +#endif + demand_flag=0; + + reachable=0; + + begin_new_basic_block(); +} + +void code_RtoI (VOID) +{ + INSTRUCTION_GRAPH graph_1,graph_2,graph_3,graph_4; + +#ifdef G_POWER + if (r_to_i_buffer_label==NULL) + r_to_i_buffer_label=enter_label ("r_to_i_buffer",IMPORT_LABEL); + + graph_1=s_pop_b(); + graph_2=s_pop_b(); + graph_3=g_fjoin (graph_1,graph_2); + + graph_4=g_frtoi (graph_3); + + s_push_b (graph_4); +#else +# ifdef M68000 + if (!mc68881_flag){ +# endif + if (r_to_i_real==NULL) + r_to_i_real=enter_label ("r_to_i_real",IMPORT_LABEL); + + code_monadic_sane_operator (r_to_i_real); + init_b_stack (1,i_vector); +# ifdef M68000 + } else { + graph_1=s_pop_b(); + graph_2=s_pop_b(); + graph_3=g_fjoin (graph_1,graph_2); + + graph_4=g_frtoi (graph_3); + + s_push_b (graph_4); + } +# endif +#endif +} + +static void code_lazy_select (VOID) +{ + INSTRUCTION_GRAPH graph_1,graph_2,graph_3; + + graph_1=s_pop_a(); + graph_2=s_pop_b(); + + if (!check_index_flag && graph_2->instruction_code==GLOAD_I && + (unsigned long) graph_2->instruction_parameters[0].i < (unsigned long) ((MAX_INDIRECT_OFFSET-12)>>2)) + { + graph_3=g_load_x (graph_1,12+(graph_2->instruction_parameters[0].i<<2),0,NULL); + } else { + if (check_index_flag) + graph_2=g_bounds (graph_1,graph_2); + +#if defined (M68000) || defined (I486) +# ifdef M68000 + if (mc68000_flag){ + graph_2=g_lsl (g_load_i (2),graph_2); + graph_3=g_load_x (graph_1,12,0,graph_2); + } else +# endif + graph_3=g_load_x (graph_1,12,2,graph_2); +#else + graph_2=g_lsl_2_add_12 (graph_2); + graph_3=g_load_x (graph_1,0,0,graph_2); +#endif + } + + s_push_a (graph_3); +} + +static void code_selectBC (int offset,int ext_signed) +{ + INSTRUCTION_GRAPH graph_1,graph_2,graph_3; + + graph_1=s_pop_a(); + graph_2=s_get_b (0); + + if (!check_index_flag && graph_2->instruction_code==GLOAD_I && + LESS_UNSIGNED (graph_2->instruction_parameters[0].i,MAX_INDIRECT_OFFSET-offset)) + { + graph_3=g_load_b_x (graph_1,offset+graph_2->instruction_parameters[0].i,ext_signed,NULL); + } else { + if (check_index_flag) + graph_2=g_bounds (graph_1,graph_2); + +#if defined (M68000) || defined (I486) + graph_3=g_load_b_x (graph_1,offset,ext_signed,graph_2); +#else + graph_1=g_add (g_load_i (offset),graph_1); + graph_3=g_load_b_x (graph_1,0,ext_signed,graph_2); +#endif + } + + s_put_b (0,graph_3); +} + +static void code_selectI (VOID) +{ + INSTRUCTION_GRAPH graph_1,graph_2,graph_3; + + graph_1=s_pop_a(); + graph_2=s_get_b (0); + +#ifdef ARRAY_OPTIMIZATIONS + if (graph_1->instruction_code==GCREATE && graph_2->instruction_code==GLOAD_I){ + int i; + + i=graph_2->instruction_parameters[0].i; + if (LESS_UNSIGNED (i,4) && 3+i < graph_1->inode_arity){ + INSTRUCTION_GRAPH graph_3; + + graph_3=graph_1->instruction_parameters[3+i].p; + s_put_b (0,graph_3); + return; + } + } +#endif + + if (!check_index_flag && graph_2->instruction_code==GLOAD_I && + LESS_UNSIGNED (graph_2->instruction_parameters[0].i,(MAX_INDIRECT_OFFSET-12)>>2)) + { + graph_3=g_load_x (graph_1,12+(graph_2->instruction_parameters[0].i<<2),0,NULL); + } else { + if (check_index_flag) + graph_2=g_bounds (graph_1,graph_2); + +#if defined (M68000) || defined (I486) +# ifdef M68000 + if (mc68000_flag){ + graph_2=g_lsl (g_load_i (2),graph_2); + graph_3=g_load_x (graph_1,12,0,graph_2); + } else +# endif + graph_3=g_load_x (graph_1,12,2,graph_2); +#else + graph_2=g_lsl_2_add_12 (graph_2); + graph_3=g_load_x (graph_1,0,0,graph_2); +#endif + } + + s_put_b (0,graph_3); +} + +static void code_selectR (VOID) +{ + INSTRUCTION_GRAPH graph_1,graph_2,graph_3,graph_4,graph_5,graph_6; + + graph_1=s_pop_a(); + graph_2=s_pop_b(); + + if (check_index_flag) + graph_2=g_bounds (graph_1,graph_2); + +#ifdef M68000 + if (!mc68881_flag){ + if (!check_index_flag && graph_2->instruction_code==GLOAD_I && + LESS_UNSIGNED (graph_2->instruction_parameters[0].i,(MAX_INDIRECT_OFFSET-16)>>3)) + { + int offset; + + offset=12+(graph_2->instruction_parameters[0].i<<3); + + graph_5=g_load_x (graph_1,offset,0,NULL); + graph_6=g_load_x (graph_1,offset+4,0,NULL); + } else { + if (mc68000_flag){ + graph_3=g_load_i (3); + graph_4=g_lsl (graph_3,graph_2); + graph_5=g_load_x (graph_1,12,0,graph_4); + graph_6=g_load_x (graph_1,16,0,graph_4); + } else { + graph_5=g_load_x (graph_1,12,3,graph_2); + graph_6=g_load_x (graph_1,16,3,graph_2); + } + } + } else +#endif + + { + if (!check_index_flag && graph_2->instruction_code==GLOAD_I && + LESS_UNSIGNED (graph_2->instruction_parameters[0].i,(MAX_INDIRECT_OFFSET-12)>>3)) + { + graph_4=g_fload_x (graph_1,12+(graph_2->instruction_parameters[0].i<<3),0,NULL); + } else { +#if defined (M68000) || defined (I486) + graph_4=g_fload_x (graph_1,12,3,graph_2); +#else + graph_2=g_lsl_3_add_12 (graph_2); +# ifdef sparc + graph_4=g_fload_x (graph_1,12,0,graph_2); +# else + graph_4=g_fload_x (graph_1,0,0,graph_2); +# endif +#endif + } + + g_fhighlow (graph_5,graph_6,graph_4); + } + + s_push_b (graph_6); + s_push_b (graph_5); +} + +static void code_r_select (int a_size,int b_size) +{ + INSTRUCTION_GRAPH graph_1,graph_2,graph_3; + long offset; + int i,element_size; + + graph_1=s_pop_a(); + graph_2=s_pop_b(); + + element_size=(a_size+b_size)<<2; + + if (!check_index_flag && graph_2->instruction_code==GLOAD_I && + LESS_UNSIGNED (graph_2->instruction_parameters[0].i,(MAX_INDIRECT_OFFSET-12-(element_size-4))/element_size)) + { + offset=12+graph_2->instruction_parameters[0].i*element_size; + graph_3=NULL; + } else { + if (check_index_flag) + graph_2=g_bounds (graph_1,graph_2); + + offset=12; + graph_3=multiply_by_constant ((a_size+b_size)<<2,graph_2); + } + + for (i=a_size-1; i>=0; --i){ + INSTRUCTION_GRAPH graph_4; + +#if defined (sparc) || defined (G_POWER) + if (offset+(i<<2)!=0 && graph_3!=NULL) + graph_4=g_load_x (graph_1,0,0,g_add (g_load_i (offset+(i<<2)),graph_3)); + else +#endif + graph_4=g_load_x (graph_1,offset+(i<<2),0,graph_3); + s_push_a (graph_4); + } + + for (i=b_size-1; i>=0; --i){ + INSTRUCTION_GRAPH graph_4; + +#if defined (sparc) || defined (G_POWER) + if (offset+((a_size+i)<<2)!=0 && graph_3!=NULL) + graph_4=g_load_x (graph_1,0,0,g_add (g_load_i (offset+((a_size+i)<<2)),graph_3)); + else +#endif + graph_4=g_load_x (graph_1,offset+((a_size+i)<<2),0,graph_3); + s_push_b (graph_4); + } +} + +void code_select (char element_descriptor[],int a_size,int b_size) +{ + if (check_index_flag) + if (index_error_label==NULL){ + index_error_label=enter_label ("index__error",0); + if (!(index_error_label->label_flags & EXPORT_LABEL)) + index_error_label->label_flags |= IMPORT_LABEL; + } + + switch (element_descriptor[0]){ + case 'B': + if (element_descriptor[1]=='O' && element_descriptor[2]=='O' && element_descriptor[3]=='L' && + element_descriptor[4]=='\0') + { + code_selectBC (12,1); + return; + } + break; + case 'C': + if (element_descriptor[1]=='H' && element_descriptor[2]=='A' && element_descriptor[3]=='R' && + element_descriptor[4]=='\0') + { + code_selectBC (8,0); + return; + } + break; + case 'I': + if (element_descriptor[1]=='N' && element_descriptor[2]=='T' && element_descriptor[3]=='\0'){ + code_selectI(); + return; + } + break; + case 'P': + if (is__rocid (element_descriptor)){ + code_selectI(); + return; + } + break; + case 'R': + if (element_descriptor[1]=='E' && element_descriptor[2]=='A' && element_descriptor[3]=='L' && + element_descriptor[4]=='\0') + { + code_selectR(); + return; + } + break; + case 'A': + if (element_descriptor[1]=='R' && element_descriptor[2]=='R' && element_descriptor[3]=='A' && + element_descriptor[4]=='Y' && element_descriptor[5]=='\0') + { + code_lazy_select(); + return; + } + break; + case 'S': + if (element_descriptor[1]=='T' && element_descriptor[2]=='R' && element_descriptor[3]=='I' && + element_descriptor[4]=='N' && element_descriptor[5]=='G' && element_descriptor[6]=='\0') + { + code_lazy_select(); + return; + } + break; + case 'W': + if (is__orld (element_descriptor)){ + code_lazy_select(); + return; + } + break; + case '_': + if (element_descriptor[1]=='_' && element_descriptor[2]=='\0'){ + code_lazy_select(); + return; + } + break; + } + + code_r_select (a_size,b_size); +} + +void code_set_entry (char *label_name,int a_offset) +{ + INSTRUCTION_GRAPH graph_1,graph_2,graph_3; + + if (EMPTY_label==NULL) + EMPTY_label=enter_label ("EMPTY",IMPORT_LABEL | DATA_LABEL); + + if (!strcmp (label_name,"__cycle__in__spine")){ +#if !(defined (sparc) || defined (G_POWER)) + if (cycle_in_spine_label==NULL){ + cycle_in_spine_label=enter_label ("__cycle__in__spine",IMPORT_LABEL | NODE_ENTRY_LABEL); + cycle_in_spine_label->label_arity=0; + cycle_in_spine_label->label_descriptor=EMPTY_label; + } + graph_2=g_lea (cycle_in_spine_label); +#else + graph_2=g_g_register (RESERVE_CODE_REGISTER); +#endif + } else if (!strcmp (label_name,"__reserve")){ +#ifndef sparc + if (reserve_label==NULL){ + reserve_label=enter_label ("__reserve",IMPORT_LABEL | NODE_ENTRY_LABEL); + reserve_label->label_arity=0; + reserve_label->label_descriptor=EMPTY_label; + } + graph_2=g_lea (reserve_label); +#else + graph_2=g_g_register (RESERVE_CODE_REGISTER); +#endif + } else { + LABEL *label; + + label=enter_label (label_name,NODE_ENTRY_LABEL); + label->label_arity=0; + label->label_descriptor=EMPTY_label; + graph_2=g_lea (label); + } + + graph_1=s_get_a (a_offset); + graph_3=g_fill_2 (graph_1,graph_2); + s_put_a (a_offset,graph_3); +} + +#ifdef FINALIZERS +void code_set_finalizers (VOID) +{ + INSTRUCTION_GRAPH graph_1,graph_2,graph_3,graph_4; + LABEL *finalizer_list_label; + + finalizer_list_label=enter_label ("finalizer_list",DATA_LABEL | IMPORT_LABEL); + + graph_1=g_lea (finalizer_list_label); + graph_2=s_get_a (0); + + graph_3=g_fill_2 (graph_1,graph_2); + + graph_4=g_keep (graph_3,graph_2); + + s_put_a (0,graph_4); +} +#endif + +void code_shiftl (VOID) +{ + INSTRUCTION_GRAPH graph_1,graph_2,graph_3; + + graph_1=s_pop_b(); + graph_2=s_get_b (0); + graph_3=g_lsl (graph_2,graph_1); + + s_put_b (0,graph_3); +} + +void code_shiftr (VOID) +{ + INSTRUCTION_GRAPH graph_1,graph_2,graph_3; + + graph_1=s_pop_b(); + graph_2=s_get_b (0); + graph_3=g_asr (graph_2,graph_1); + + s_put_b (0,graph_3); +} + +void code_shiftrU (VOID) +{ + INSTRUCTION_GRAPH graph_1,graph_2,graph_3; + + graph_1=s_pop_b(); + graph_2=s_get_b (0); + graph_3=g_lsr (graph_2,graph_1); + + s_put_b (0,graph_3); +} + +void code_sliceS (int source_offset,int destination_offset) +{ + INSTRUCTION_GRAPH graph_1,graph_2; + + if (slice_string_label==NULL) + slice_string_label=enter_label ("slice_string",IMPORT_LABEL); + + graph_1=s_get_a (source_offset); + graph_2=s_get_a (destination_offset); + + s_push_a (graph_2); + s_push_a (graph_1); + + 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,2,2+1,i_i_vector,slice_string_label); +} + +void code_sinR (VOID) +{ +#ifdef I486 + code_monadic_real_operator (GFSIN); +#else +# ifdef M68000 + if (!mc68881_flag){ +# endif + if (sin_real==NULL) + sin_real=enter_label ("sin_real",IMPORT_LABEL); + code_monadic_sane_operator (sin_real); + init_b_stack (2,r_vector); +# ifdef M68000 + } else + code_monadic_real_operator (GFSIN); +# endif +#endif +} + +void code_sqrtR (VOID) +{ +#ifdef M68000 + if (!mc68881_flag){ + if (sqrt_real==NULL) + sqrt_real=enter_label ("sqrt_real",IMPORT_LABEL); + code_monadic_sane_operator (sqrt_real); + init_b_stack (2,r_vector); + } else + code_monadic_real_operator (GFSQRT); +#else +# ifdef G_POWER + if (sqrt_real==NULL) + sqrt_real=enter_label ("sqrt_real",IMPORT_LABEL); + code_monadic_sane_operator (sqrt_real); + init_b_stack (2,r_vector); +# else + code_monadic_real_operator (GFSQRT); +# endif +#endif +} + +void code_subI (VOID) +{ + INSTRUCTION_GRAPH graph_1,graph_2,graph_3; + + graph_1=s_pop_b(); + graph_2=s_get_b (0); + graph_3=g_sub (graph_2,graph_1); + + s_put_b (0,graph_3); +} + +#ifndef M68000 +void code_subIo (VOID) +{ + code_operatorIo (GSUB_O); +} +#endif + +void code_subR (VOID) +{ + INSTRUCTION_GRAPH graph_1,graph_2,graph_3,graph_4,graph_5,graph_6,graph_7,graph_8,graph_9; + +#ifdef M68000 + if (!mc68881_flag){ + if (sub_real==NULL) + sub_real=enter_label ("sub_real",IMPORT_LABEL); + code_dyadic_sane_operator (sub_real); + init_b_stack (2,r_vector); + } else { +#endif + graph_1=s_pop_b(); + graph_2=s_pop_b(); + graph_3=g_fjoin (graph_1,graph_2); + + graph_4=s_get_b (0); + graph_5=s_get_b (1); + graph_6=g_fjoin (graph_4,graph_5); + + graph_7=g_fsub (graph_6,graph_3); + + g_fhighlow (graph_8,graph_9,graph_7); + + s_put_b (1,graph_9); + s_put_b (0,graph_8); +#ifdef M68000 + } +#endif +} + +void code_tanR (VOID) +{ +#ifdef M68000 + if (!mc68881_flag){ +#endif + if (tan_real==NULL) + tan_real=enter_label ("tan_real",IMPORT_LABEL); + code_monadic_sane_operator (tan_real); + init_b_stack (2,r_vector); +#ifdef M68000 + } else + code_monadic_real_operator (GFTAN); +#endif +} + +void code_testcaf (char *label_name) +{ + LABEL *label; + INSTRUCTION_GRAPH graph_1,graph_2; + + label=enter_label (label_name,0); + + graph_1=g_lea (label); + graph_2=g_load_id (0,graph_1); + + s_push_b (graph_2); +} + +void code_update_a (int a_offset_1,int a_offset_2) +{ + if (a_offset_1!=a_offset_2){ + INSTRUCTION_GRAPH graph_1; + + graph_1=s_get_a (a_offset_1); + s_put_a (a_offset_2,graph_1); + } +} + +void code_updatepop_a (int a_offset_1,int a_offset_2) +{ + code_update_a (a_offset_1,a_offset_2); + code_pop_a (a_offset_2); +} + +void code_update_b (int b_offset_1,int b_offset_2) +{ + if (b_offset_1!=b_offset_2){ + INSTRUCTION_GRAPH graph_1; + + graph_1=s_get_b (b_offset_1); + s_put_b (b_offset_2,graph_1); + } +} + +void code_updatepop_b (int b_offset_1,int b_offset_2) +{ + code_update_b (b_offset_1,b_offset_2); + code_pop_b (b_offset_2); +} + +static void code_lazy_update (VOID) +{ + INSTRUCTION_GRAPH graph_1,graph_2,graph_3,graph_4; + + graph_1=s_pop_a(); + graph_2=s_get_a (0); + graph_3=s_pop_b(); + + if (!check_index_flag && graph_3->instruction_code==GLOAD_I && + LESS_UNSIGNED (graph_3->instruction_parameters[0].i,(MAX_INDIRECT_OFFSET-12)>>2)) + { + graph_4=g_store_x (graph_2,graph_1,12+(graph_3->instruction_parameters[0].i<<2),0,NULL); + } else { + if (check_index_flag) + graph_3=g_bounds (graph_1,graph_3); + +#if defined (M68000) || defined (I486) +# ifdef M68000 + if (mc68000_flag){ + graph_3=g_lsl (g_load_i (2),graph_3); + graph_4=g_store_x (graph_2,graph_1,12,0,graph_3); + } else +# endif + graph_4=g_store_x (graph_2,graph_1,12,2,graph_3); +#else + graph_3=g_lsl_2_add_12 (graph_3); + graph_4=g_store_x (graph_2,graph_1,0,0,graph_3); +#endif + } + + s_put_a (0,graph_4); +} + +static void code_updateBC (int offset) +{ + INSTRUCTION_GRAPH graph_1,graph_2,graph_3,graph_4; + + graph_1=s_get_a (0); + graph_2=s_pop_b(); + graph_3=s_pop_b(); + + if (!check_index_flag && graph_2->instruction_code==GLOAD_I && + LESS_UNSIGNED (graph_2->instruction_parameters[0].i,MAX_INDIRECT_OFFSET-offset)) + { + graph_4=g_store_b_x (graph_3,graph_1,offset+graph_2->instruction_parameters[0].i,NULL); + } else { + if (check_index_flag) + graph_2=g_bounds (graph_1,graph_2); + +#if defined (M68000) || defined (I486) + graph_4=g_store_b_x (graph_3,graph_1,offset,graph_2); +#else + graph_2=g_add (g_load_i (offset),graph_2); + graph_4=g_store_b_x (graph_3,graph_1,0,graph_2); +#endif + } + + s_put_a (0,graph_4); +} + +static void code_updateI (VOID) +{ + INSTRUCTION_GRAPH graph_1,graph_2,graph_3,graph_4; + + graph_1=s_get_a (0); + graph_2=s_pop_b(); + graph_3=s_pop_b(); + +#ifdef ARRAY_OPTIMIZATIONS + if (graph_1->instruction_code==GCREATE && graph_2->instruction_code==GLOAD_I){ + int i; + + i=graph_2->instruction_parameters[0].i; + if (LESS_UNSIGNED (i,4) && 3+i < graph_1->inode_arity){ + graph_1->instruction_parameters[3+i].p = graph_3; + return; + } + } +#endif + + if (!check_index_flag && graph_2->instruction_code==GLOAD_I && + LESS_UNSIGNED (graph_2->instruction_parameters[0].i,(MAX_INDIRECT_OFFSET-12)>>2)) + { + graph_4=g_store_x (graph_3,graph_1,12+(graph_2->instruction_parameters[0].i<<2),0,NULL); + } else { + if (check_index_flag) + graph_2=g_bounds (graph_1,graph_2); + +#if defined (M68000) || defined (I486) +# ifdef M68000 + if (mc68000_flag){ + graph_2=g_lsl (g_load_i (2),graph_2); + graph_4=g_store_x (graph_3,graph_1,12,0,graph_2); + } else +# endif + graph_4=g_store_x (graph_3,graph_1,12,2,graph_2); +#else + graph_2=g_lsl_2_add_12 (graph_2); + graph_4=g_store_x (graph_3,graph_1,0,0,graph_2); +#endif + } + + s_put_a (0,graph_4); +} + +static void code_updateR (VOID) +{ + INSTRUCTION_GRAPH graph_1,graph_2,graph_3,graph_4,graph_5,graph_6,graph_7,graph_8; + + graph_1=s_get_a (0); + graph_2=s_pop_b(); + + graph_3=s_pop_b(); + graph_4=s_pop_b(); + + if (check_index_flag) + graph_2=g_bounds (graph_1,graph_2); + +#ifdef M68000 + if (!mc68881_flag){ + if (!check_index_flag && graph_2->instruction_code==GLOAD_I && + LESS_UNSIGNED (graph_2->instruction_parameters[0].i,(MAX_INDIRECT_OFFSET-16)>>3)) + { + int offset; + + offset=12+(graph_2->instruction_parameters[0].i<<3); + graph_7=g_store_x (graph_3,graph_1,offset,0,NULL); + graph_8=g_store_x (graph_4,graph_7,offset+4,0,NULL); + } else { + if (mc68000_flag){ + graph_5=g_load_i (3); + graph_6=g_lsl (graph_5,graph_2); + graph_7=g_store_x (graph_3,graph_1,12,0,graph_6); + graph_8=g_store_x (graph_4,graph_7,16,0,graph_6); + } else { + graph_7=g_store_x (graph_3,graph_1,12,3,graph_2); + graph_8=g_store_x (graph_4,graph_7,16,3,graph_2); + } + } + } else +#endif + { + graph_7=g_fjoin (graph_3,graph_4); + + if (!check_index_flag && graph_2->instruction_code==GLOAD_I && + LESS_UNSIGNED (graph_2->instruction_parameters[0].i,(MAX_INDIRECT_OFFSET-12)>>3)) + { + graph_8=g_fstore_x (graph_7,graph_1,12+(graph_2->instruction_parameters[0].i<<3),0,NULL); + } else { +#if defined (M68000) || defined (I486) + graph_8=g_fstore_x (graph_7,graph_1,12,3,graph_2); +#else + graph_2=g_lsl_3_add_12 (graph_2); +# ifdef sparc + graph_8=g_fstore_x (graph_7,graph_1,12,0,graph_2); +# else + graph_8=g_fstore_x (graph_7,graph_1,0,0,graph_2); +# endif +#endif + } + } + + s_put_a (0,graph_8); +} + +static void code_r_update (int a_size,int b_size) +{ + INSTRUCTION_GRAPH graph_1,graph_2,graph_3; + int i,element_size,offset; + + graph_1=s_pop_a(); + graph_2=s_pop_b(); + + element_size=(a_size+b_size)<<2; + + if (!check_index_flag && graph_2->instruction_code==GLOAD_I && + LESS_UNSIGNED (graph_2->instruction_parameters[0].i,(MAX_INDIRECT_OFFSET-12-(element_size-4))/element_size)) + { + offset=12+graph_2->instruction_parameters[0].i*element_size; + graph_3=NULL; + } else { + if (check_index_flag) + graph_2=g_bounds (graph_1,graph_2); + + offset=12; + graph_3=multiply_by_constant (element_size,graph_2); + } + + for (i=0; i<a_size; ++i){ + INSTRUCTION_GRAPH graph_4; + + graph_4=s_pop_a(); +#if defined (sparc) || defined (G_POWER) + if (offset+(i<<2)!=0 && graph_3!=NULL) + graph_1=g_store_x (graph_4,graph_1,0,0,g_add (g_load_i (offset+(i<<2)),graph_3)); + else +#endif + graph_1=g_store_x (graph_4,graph_1,offset+(i<<2),0,graph_3); + } + + for (i=0; i<b_size; ++i){ + INSTRUCTION_GRAPH graph_4; + + graph_4=s_pop_b(); + + /* added 16-10-2001 */ + if (graph_4->instruction_code==GFHIGH && i+1<b_size){ + INSTRUCTION_GRAPH graph_5,graph_6; + + graph_5=s_get_b (0); + if (graph_5->instruction_code==GFLOW && graph_4->instruction_parameters[0].p==graph_5->instruction_parameters[0].p){ + + s_pop_b(); + + graph_6=g_fjoin (graph_4,graph_5); +#if defined (sparc) || defined (G_POWER) + if (offset+((a_size+i)<<2)!=0 && graph_3!=NULL) + graph_1=g_fstore_x (graph_6,graph_1,0,0,g_add (g_load_i (offset+((a_size+i)<<2)),graph_3)); + else +#endif + graph_1=g_fstore_x (graph_6,graph_1,offset+((a_size+i)<<2),0,graph_3); + + ++i; + + continue; + } + } + /* */ + +#if defined (sparc) || defined (G_POWER) + if (offset+((a_size+i)<<2)!=0 && graph_3!=NULL) + graph_1=g_store_x (graph_4,graph_1,0,0,g_add (g_load_i (offset+((a_size+i)<<2)),graph_3)); + else +#endif + graph_1=g_store_x (graph_4,graph_1,offset+((a_size+i)<<2),0,graph_3); + } + + s_push_a (graph_1); +} + +void code_update (char element_descriptor[],int a_size,int b_size) +{ + if (check_index_flag) + if (index_error_label==NULL){ + index_error_label=enter_label ("index__error",0); + if (!(index_error_label->label_flags & EXPORT_LABEL)) + index_error_label->label_flags |= IMPORT_LABEL; + } + + switch (element_descriptor[0]){ + case 'B': + if (element_descriptor[1]=='O' && element_descriptor[2]=='O' && element_descriptor[3]=='L' && + element_descriptor[4]=='\0') + { + code_updateBC (12); + return; + } + break; + case 'C': + if (element_descriptor[1]=='H' && element_descriptor[2]=='A' && element_descriptor[3]=='R' && + element_descriptor[4]=='\0') + { + code_updateBC (8); + return; + } + break; + case 'I': + if (element_descriptor[1]=='N' && element_descriptor[2]=='T' && element_descriptor[3]=='\0'){ + code_updateI(); + return; + } + break; + case 'P': + if (is__rocid (element_descriptor)){ + code_updateI(); + return; + } + break; + case 'R': + if (element_descriptor[1]=='E' && element_descriptor[2]=='A' && element_descriptor[3]=='L' && + element_descriptor[4]=='\0') + { + code_updateR(); + return; + } + break; + case 'A': + if (element_descriptor[1]=='R' && element_descriptor[2]=='R' && element_descriptor[3]=='A' && + element_descriptor[4]=='Y' && element_descriptor[5]=='\0') + { + code_lazy_update(); + return; + } + break; + case 'S': + if (element_descriptor[1]=='T' && element_descriptor[2]=='R' && element_descriptor[3]=='I' && + element_descriptor[4]=='N' && element_descriptor[5]=='G' && element_descriptor[6]=='\0') + { + code_lazy_update(); + return; + } + break; + case 'W': + if (is__orld (element_descriptor)){ + code_lazy_update(); + return; + } + break; + case '_': + if (element_descriptor[1]=='_' && element_descriptor[2]=='\0'){ + code_lazy_update(); + return; + } + break; + } + + code_r_update (a_size,b_size); +} + +void code_updateS (int source_offset,int destination_offset) +{ + INSTRUCTION_GRAPH graph_1,graph_2; + + if (update_string_label==NULL) + update_string_label=enter_label ("update_string",IMPORT_LABEL); + + graph_1=s_get_a (source_offset); + graph_2=s_get_a (destination_offset); + + s_push_a (graph_2); + s_push_a (graph_1); + + 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,2,2+1,i_i_vector,update_string_label); +} + +void code_xor (VOID) +{ + INSTRUCTION_GRAPH graph_1,graph_2,graph_3; + + graph_1=s_pop_b(); + graph_2=s_get_b (0); + graph_3=g_eor (graph_1,graph_2); + + s_put_b (0,graph_3); +} + +int system_file; + +void code_caf (char *label_name,int a_stack_size,int b_stack_size) +{ + LABEL *label; + int n_arguments,n; + + label=enter_label (label_name,LOCAL_LABEL | DATA_LABEL); + if (label->label_id>=0) + error_s ("Label %d defined twice\n",label_name); + label->label_id=next_label_id++; + +#ifdef GEN_MAC_OBJ + start_new_module (2); + if (assembly_flag) + w_as_new_module (2); +#endif +#if defined (G_POWER) || defined (_WINDOWS_) + as_new_data_module(); + if (assembly_flag) + w_as_new_data_module(); +#endif + + if (a_stack_size>0){ +#if defined (GEN_MAC_OBJ) || defined (GEN_OBJ) + store_long_word_in_data_section (0); +#endif + if (assembly_flag) + w_as_long_in_data_section (0); + } + +#ifdef GEN_MAC_OBJ + if (label->label_flags & EXPORT_LABEL) + define_external_label (label->label_id,LDATA,label->label_name); + else + define_local_label (label->label_id,LDATA); +#else +# ifdef GEN_OBJ + define_data_label (label); +# endif +#endif + + if (assembly_flag){ + w_as_to_data_section(); + w_as_define_label (label); + } + + n_arguments=a_stack_size+b_stack_size; + + for (n=0; n<=n_arguments; ++n){ +#if defined (GEN_MAC_OBJ) || defined (GEN_OBJ) + store_long_word_in_data_section (0); +#endif + if (assembly_flag) + w_as_long_in_data_section (0); + } +} + +void code_comp (int version,char *options) +{ +#ifdef GEN_MAC_OBJ + int option_vector,n,l; + + l=strlen (options); + + if (l>8 && options[8]=='1') + system_file=1; + + option_vector=0; + for (n=0; n<l; ++n) + if (options[n]=='1') + option_vector |= (1<<n); + + option_vector |= (check_index_flag<<10); + option_vector |= (check_stack<<11); + option_vector |= (parallel_flag<<12); + + write_version_and_options (version,option_vector); + + no_memory_profiling = system_file && l>3 && options[3]=='0'; +#elif defined (G_POWER) || defined (I486) + int l; + + l=strlen (options); + + system_file = l>8 && options[8]=='1'; + no_memory_profiling = system_file && l>3 && options[3]=='1'; +# ifdef PROFILE + no_time_profiling = system_file && l>5 && options[5]=='1'; +# endif +#endif +} + +struct dependency_list *first_dependency; +static struct dependency_list *last_dependency; + +void code_depend (char *module_name,int module_name_length) +{ +# pragma unused (module_name_length) + struct dependency_list *new_dependency; + char *m_name; + + m_name=(char*)fast_memory_allocate (strlen (module_name)+1); + strcpy (m_name,module_name); + + new_dependency=fast_memory_allocate_type (struct dependency_list); + new_dependency->dependency_next=NULL; + new_dependency->dependency_module_name=m_name; + + if (last_dependency==NULL) + first_dependency=new_dependency; + else + last_dependency->dependency_next=new_dependency; + last_dependency=new_dependency; + +#ifdef M68000 + write_depend (module_name); +#endif +} + +LABEL *module_label; + +static LABEL *enter_descriptor_code_label (char code_label_name[],int arity) +{ + LABEL *code_label; + + if (!strcmp (code_label_name,"__add__arg")){ + if (arity-1>MAX_YET_ARGS_NEEDED_ARITY){ + if (yet_args_needed_label==NULL) + yet_args_needed_label=enter_label ("yet_args_needed",IMPORT_LABEL); + code_label=yet_args_needed_label; + } else { + LABEL **yet_args_needed_label_p; + + yet_args_needed_label_p=&yet_args_needed_labels[arity-1]; + if (*yet_args_needed_label_p==NULL){ + char label_name[64]; + + sprintf (label_name,"yet_args_needed_%d",arity-1); + *yet_args_needed_label_p=enter_label (label_name,IMPORT_LABEL); + } + code_label=*yet_args_needed_label_p; + } + code_label_name=code_label->label_name; + } else + code_label=enter_label (code_label_name,0); + + if (code_label->label_id<0) + code_label->label_id=next_label_id++; + + return code_label; +} + +static void write_descriptor_curry_table (int arity,LABEL *code_label) +{ + int n; + + for (n=0; n<=arity; ++n){ +#ifdef GEN_MAC_OBJ + store_word_in_data_section (n<<2); +#else +# ifdef GEN_OBJ + store_2_words_in_data_section (n,n<<3); +# endif +#endif + if (assembly_flag){ +#ifdef GEN_MAC_OBJ + w_as_word_in_data_section (n<<2); +#else + w_as_word_in_data_section (n); + w_as_word_in_data_section (n<<3); +#endif + } + + if (n<arity-1){ + LABEL *add_arg_label; + + if (n>MAX_YET_ARGS_NEEDED_ARITY){ + if (yet_args_needed_label==NULL) + yet_args_needed_label=enter_label ("yet_args_needed",IMPORT_LABEL); + add_arg_label=yet_args_needed_label; + } else { + LABEL **yet_args_needed_label_p; + + yet_args_needed_label_p=&yet_args_needed_labels[n]; + add_arg_label=*yet_args_needed_label_p; + + if (add_arg_label==NULL){ + char label_name[64]; + + sprintf (label_name,"yet_args_needed_%d",n); + add_arg_label=enter_label (label_name,IMPORT_LABEL); + *yet_args_needed_label_p=add_arg_label; + } + } + + if (add_arg_label->label_id<0) + add_arg_label->label_id=next_label_id++; + +#ifdef GEN_MAC_OBJ + store_label_offset_in_data_section (add_arg_label->label_id); +#else +# ifdef GEN_OBJ + store_label_in_data_section (add_arg_label); +# endif +#endif + if (assembly_flag) + w_as_label_in_data_section (add_arg_label->label_name); + + } else + if (n==arity-1){ +#ifdef GEN_MAC_OBJ + store_label_offset_in_data_section (code_label->label_id); +#else +# ifdef GEN_OBJ + store_label_in_data_section (code_label); +# endif +#endif + if (assembly_flag) + w_as_label_in_data_section (code_label->label_name); + } +#ifdef GEN_MAC_OBJ + else { + /* for long word alignment */ + store_word_in_data_section (0); + if (assembly_flag) + w_as_word_in_data_section (0); + } +#endif + } +} + +static void code_descriptor (char label_name[],char node_entry_label_name[],char code_label_name[],LABEL *code_label, + int arity,int export_flag,int lazy_record_flag,LABEL *string_label,int string_code_label_id) +{ + LABEL *label; + int n; +#if SMALL_LAZY_DESCRIPTORS + char curried_label_name[257]; + + if (parallel_flag){ + strcpy (curried_label_name,label_name); + strcat (curried_label_name,"#"); + + label=enter_label (curried_label_name,LOCAL_LABEL | DATA_LABEL); + } else +#endif + label=enter_label (label_name,LOCAL_LABEL | DATA_LABEL | export_flag); + + if (label->label_id>=0) + error_s ("Label %d defined twice\n",label_name); + label->label_id=next_label_id++; + + label->label_descriptor=string_label; + +#ifdef GEN_MAC_OBJ + start_new_module (2); + if (assembly_flag) + w_as_new_module (0); +#endif +#if defined (G_POWER) || defined (_WINDOWS_) + as_new_data_module(); + if (assembly_flag) + w_as_new_data_module(); +#endif + +#ifndef M68000 + /* not for 68k to maintain long word alignment */ + if (module_info_flag && module_label){ +# ifdef GEN_MAC_OBJ + store_label_offset_in_data_section (module_label->label_id); +# else +# ifdef GEN_OBJ + store_label_in_data_section (module_label); +# endif +# endif + if (assembly_flag) + w_as_label_in_data_section (module_label->label_name); + } +#endif + + if (!parallel_flag){ +#if defined (M68000) && !defined (SUN) + store_descriptor_in_data_section (label->label_id); +#else +# ifdef GEN_OBJ + store_descriptor_in_data_section (label); +# endif +#endif + if (assembly_flag) + w_as_descriptor_in_data_section (label->label_name); + } + + if (export_flag!=0) + enter_label (node_entry_label_name,export_flag); + +#ifdef GEN_MAC_OBJ + if (parallel_flag){ + LABEL *node_entry_label; + + store_label_offset_in_data_section (label->label_id); + store_word_in_data_section (arity); + + node_entry_label=enter_label (node_entry_label_name,export_flag); + if (node_entry_label->label_id<0) + node_entry_label->label_id=next_label_id++; + + store_word_in_data_section (0x4eed); /* JMP x(A5) */ + store_label_offset_in_data_section (node_entry_label->label_id); + +# if SMALL_LAZY_DESCRIPTORS + { + LABEL *new_label; + int flags; + + new_label=enter_label (label_name,LOCAL_LABEL | DATA_LABEL); + if (new_label->label_id>=0) + error_s ("label %d defined twice\n",curried_label_name); + new_label->label_id=next_label_id++; + new_label->label_descriptor=string_label; + + if (new_label->label_flags & EXPORT_LABEL) + label->label_flags |= EXPORT_LABEL; + + if (label->label_flags & EXPORT_LABEL) + define_external_label (label->label_id,LDATA,label->label_name); + else + define_local_label (label->label_id,LDATA); + + if (assembly_flag) + w_as_define_label (label); + + store_word_in_data_section (-4); + if (assembly_flag) + w_as_word_in_data_section (-4); + + if (code_label_name!=NULL && arity==1){ +# ifdef GEN_MAC_OBJ + store_label_offset_in_data_section (code_label->label_id); +# else +# ifdef GEN_OBJ + store_label_in_data_section (code_label); +# endif +# endif + if (assembly_flag) + w_as_label_in_data_section (code_label_name); + } else { + store_word_in_data_section (0); + if (assembly_flag) + w_as_word_in_data_section (0); + + /* + store_label_offset_in_data_section (string_code_label_id); + if (assembly_flag) + w_as_internal_label_value (string_code_label_id); + */ + } + + start_new_module (2); + if (assembly_flag) + w_as_new_module (0); + + label=new_label; + } +# endif + } +#endif + +#ifdef GEN_MAC_OBJ + store_word_in_data_section (arity); +#else +# ifdef GEN_OBJ +# ifdef I486 + store_long_word_in_data_section ((arity<<16) | lazy_record_flag); +# else + store_2_words_in_data_section (lazy_record_flag,arity); +# endif +# endif +#endif + if (assembly_flag){ +#if defined (sparc) || defined (I486) || defined (G_POWER) + w_as_word_in_data_section (lazy_record_flag); +#endif + w_as_word_in_data_section (arity); + } + +#if ! (defined (NO_STRING_ADDRES_IN_DESCRIPTOR) && (defined (G_POWER) || defined (I486))) +# ifdef GEN_MAC_OBJ + store_label_offset_in_data_section (string_code_label_id); +# else +# ifdef GEN_OBJ + store_label_in_data_section (string_label); +# endif +# endif + if (assembly_flag) + w_as_internal_label_value (string_code_label_id); +#endif + +#ifdef GEN_MAC_OBJ + if (label->label_flags & EXPORT_LABEL) + define_external_label (label->label_id,LDATA,label->label_name); + else + define_local_label (label->label_id,LDATA); +#else +# ifdef GEN_OBJ + define_data_label (label); +# endif +#endif + if (assembly_flag) + w_as_define_label (label); +} + +void code_desc (char label_name[],char node_entry_label_name[],char *code_label_name, + int arity,int lazy_record_flag,char descriptor_name[],int descriptor_name_length) +{ + LABEL *string_label,*code_label; + int string_code_label_id; + +#if defined (NO_FUNCTION_NAMES) && defined (NO_CONSTRUCTOR_NAMES) + descriptor_name_length=0; +#elif defined (NO_FUNCTION_NAMES) && defined (NO_CONSTRUCTOR_NAMES) + if (strcmp (code_label_name,"__add__arg")!=0) + descriptor_name_length=0; +#endif + + string_code_label_id=next_label_id++; + string_label=new_local_label (0 +#ifdef G_POWER + | DATA_LABEL +#endif + ); + + if (arity>0){ + code_label = enter_descriptor_code_label (code_label_name,arity); + code_label_name=code_label->label_name; + } + + code_descriptor (label_name,node_entry_label_name,code_label_name,code_label,arity,0,lazy_record_flag,string_label,string_code_label_id); + + write_descriptor_curry_table (arity,code_label); + + w_descriptor_string (descriptor_name,descriptor_name_length,string_code_label_id,string_label); +} + +void code_descn (char label_name[],char node_entry_label_name[],int arity,int lazy_record_flag,char descriptor_name[], + int descriptor_name_length) +{ + LABEL *string_label; + int string_code_label_id; + +#if defined (NO_FUNCTION_NAMES) || defined (NO_CONSTRUCTOR_NAMES) + descriptor_name_length=0; +#endif + + string_code_label_id=next_label_id++; + string_label=new_local_label (0 +#ifdef G_POWER + | DATA_LABEL +#endif + ); + + code_descriptor (label_name,node_entry_label_name,NULL,NULL,0/*arity*/,0,lazy_record_flag,string_label,string_code_label_id); + +#ifdef GEN_MAC_OBJ + store_word_in_data_section (0<<2); + if (assembly_flag) + w_as_word_in_data_section (0<<2); +#else +# ifdef GEN_OBJ + store_2_words_in_data_section (arity,0<<3); +# endif + if (assembly_flag){ + w_as_word_in_data_section (arity); + w_as_word_in_data_section (0<<3); + } +#endif + + w_descriptor_string (descriptor_name,descriptor_name_length,string_code_label_id,string_label); +} + +void code_descexp (char label_name[],char node_entry_label_name[],char *code_label_name, + int arity,int lazy_record_flag,char descriptor_name[],int descriptor_name_length) +{ + LABEL *string_label,*code_label; + int string_code_label_id; + +#if defined (NO_FUNCTION_NAMES) && defined (NO_CONSTRUCTOR_NAMES) + descriptor_name_length=0; +#elif defined (NO_FUNCTION_NAMES) && defined (NO_CONSTRUCTOR_NAMES) + if (strcmp (code_label_name,"__add__arg")!=0) + descriptor_name_length=0; +#endif + + string_code_label_id=next_label_id++; + string_label=new_local_label (0 +#ifdef G_POWER + | DATA_LABEL +#endif + ); + + if (arity>0){ + code_label = enter_descriptor_code_label (code_label_name,arity); + code_label_name=code_label->label_name; + } + + code_descriptor (label_name,node_entry_label_name,code_label_name,code_label,arity,EXPORT_LABEL,lazy_record_flag,string_label,string_code_label_id); + + write_descriptor_curry_table (arity,code_label); + + w_descriptor_string (descriptor_name,descriptor_name_length,string_code_label_id,string_label); +} + +void code_record (char record_label_name[],char type[],int a_size,int b_size,char record_name[],int record_name_length) +{ + LABEL *label; + int string_code_label_id; + LABEL *string_label; + + label=enter_label (record_label_name,LOCAL_LABEL | DATA_LABEL); + if (label->label_id>=0) + error_s ("Label %d defined twice\n",record_label_name); + label->label_id=next_label_id++; + +#ifdef GEN_MAC_OBJ + start_new_module (0); + if (assembly_flag) + w_as_new_module (0); +#endif +#if defined (G_POWER) || defined (_WINDOWS_) + as_new_data_module(); + if (assembly_flag) + w_as_new_data_module(); +#endif + + string_code_label_id=next_label_id++; + string_label=new_local_label (0 +#ifdef G_POWER + | DATA_LABEL +#endif + ); + label->label_descriptor=string_label; + +#ifndef M68000 + /* not for 68k to maintain long word alignment */ + if (module_info_flag && module_label){ +# ifdef GEN_MAC_OBJ + store_label_offset_in_data_section (module_label->label_id); +# else +# ifdef GEN_OBJ + store_label_in_data_section (module_label); +# endif +# endif + if (assembly_flag) + w_as_label_in_data_section (module_label->label_name); + } +#endif + +#ifdef GEN_MAC_OBJ + store_label_offset_in_data_section (string_code_label_id); +#else +# ifdef GEN_OBJ + store_label_in_data_section (string_label); +# endif +#endif + if (assembly_flag) + w_as_internal_label_value (string_code_label_id); + +#ifdef GEN_MAC_OBJ + if (label->label_flags & EXPORT_LABEL) + define_external_label (label->label_id,LDATA,label->label_name); + else + define_local_label (label->label_id,LDATA); +#else +# ifdef GEN_OBJ + define_data_label (label); +# endif +#endif + if (assembly_flag) + w_as_define_label (label); + +#ifdef GEN_MAC_OBJ + store_word_in_data_section (a_size+b_size+256); + store_word_in_data_section (a_size); +#else +# ifdef GEN_OBJ + store_2_words_in_data_section (a_size+b_size+256,a_size); +# endif +#endif + + if (assembly_flag){ + w_as_word_in_data_section (a_size+b_size+256); + w_as_word_in_data_section (a_size); + } + + { + char *t_p; + int length; + + for (t_p=type; *t_p!='\0'; ++t_p) + switch (*t_p){ + case 'p': + *t_p='i'; + break; + case 'w': + *t_p='a'; + break; + default: + break; + } + + length=t_p-type; + +#if defined (GEN_MAC_OBJ) || defined (GEN_OBJ) + store_c_string_in_data_section (type,length); +#endif + + if (assembly_flag) + w_as_c_string_in_data_section (type,length); + } + +#ifdef NO_CONSTRUCTOR_NAMES + record_name_length=0; +#endif + + w_descriptor_string (record_name,record_name_length,string_code_label_id,string_label); +} + +/* +static void show_vector (int n,unsigned int vector[]) +{ + int i; + for (i=0; i<n; ){ + if (vector[i>>LOG_VECTOR_ELEMENT_SIZE] & (((ULONG)1) << (i & VECTOR_ELEMENT_MASK))){ + printf ("R"); + i+=2; + } else { + printf ("I"); + i+=1; + } + } + printf ("\n"); +} +*/ + +void code_d (int da,int db,ULONG vector[]) +{ + demanded_a_stack_size=da; + demanded_b_stack_size=db; + demanded_vector=vector; + + demand_flag=1; + /* show_vector (db,vector); */ +} + +void code_export (char *label_name) +{ + enter_label (label_name,EXPORT_LABEL); +} + +void code_impdesc (char *label_name) +{ + enter_label (label_name,IMPORT_LABEL | DATA_LABEL); +} + +void code_implab_node_entry (char *label_name,char *ea_label_name) +{ + if (ea_label_name!=NULL){ + LABEL *ea_label,*node_label; + + node_label=enter_label (label_name,IMPORT_LABEL | EA_LABEL); + + if (ea_label_name[0]=='_' && ea_label_name[1]=='_' && ea_label_name[2]=='\0'){ + if (eval_fill_label==NULL) + eval_fill_label=enter_label ("eval_fill",IMPORT_LABEL); + node_label->label_ea_label=eval_fill_label; + } else { + ea_label=enter_label (ea_label_name,0); + node_label->label_ea_label=ea_label; + } + } +} + +void code_implab (char *label_name) +{ +/* enter_label (label_name,IMPORT_LABEL); */ +} + +void code_o (int oa,int ob,ULONG vector[]) +{ + offered_a_stack_size=oa; + offered_b_stack_size=ob; + offered_vector=vector; + + /* show_vector (ob,vector); */ + + if (!offered_after_jsr) + offered_before_label=1; + else { + offered_after_jsr=0; + + release_a_stack(); + release_b_stack(); + +#ifdef MORE_PARAMETER_REGISTERS + init_ab_stack (offered_a_stack_size,offered_b_stack_size,offered_vector); +#else + init_a_stack (offered_a_stack_size); + init_b_stack (offered_b_stack_size,offered_vector); +#endif + } +} + +struct profile_table { + LABEL *label; + int string_length; + struct profile_table *next; + char string[4]; +}; + +static struct profile_table *profile_table,**profile_table_next_p; + +void code_pb (char string[],int string_length) +{ +#ifdef PROFILE + if (no_time_profiling) + return; + + if (profile_s_label==NULL){ + profile_l_label =enter_label ("profile_l",IMPORT_LABEL); + profile_l2_label=enter_label ("profile_l2",IMPORT_LABEL); + profile_n_label =enter_label ("profile_n",IMPORT_LABEL); + profile_n2_label=enter_label ("profile_n2",IMPORT_LABEL); + profile_s_label =enter_label ("profile_s",IMPORT_LABEL); + profile_s2_label=enter_label ("profile_s2",IMPORT_LABEL); + profile_r_label =enter_label ("profile_r",IMPORT_LABEL); + profile_t_label =enter_label ("profile_t",IMPORT_LABEL); +# ifdef G_POWER + profile_ti_label=enter_label ("profile_ti",IMPORT_LABEL); +# endif + } + + profile_function_label=new_local_label (LOCAL_LABEL | DATA_LABEL); + profile_function_block=NULL; + +#ifdef G_POWER + if (profile_table_flag){ + struct profile_table *profile_table_entry; + int string_length_4; + + if (profile_table_label==NULL) + profile_table_label=profile_function_label; + + string_length_4=(string_length+1+3) & -4; + profile_function_label->label_arity=profile_table_offset; + + profile_table_entry=(struct profile_table *)fast_memory_allocate (sizeof (struct profile_table)-4+string_length_4); + + profile_table_entry->label=profile_function_label; + profile_table_entry->string_length=string_length; + strcpy (profile_table_entry->string,string); + + profile_table_entry->next=NULL; + *profile_table_next_p=profile_table_entry; + profile_table_next_p=&profile_table_entry->next; + +# if TIME_PROFILE_WITH_MODULE_NAMES + if (module_label!=NULL) + profile_table_offset+=4; +# endif + profile_table_offset+=4+string_length_4; + + if (profile_table_offset>=65536) + error ("Profile table too big\n"); + + return; + } +#endif + +# if defined (G_POWER) || defined (_WINDOWS_) + as_new_data_module(); + if (assembly_flag) + w_as_new_data_module(); +# endif + +#if TIME_PROFILE_WITH_MODULE_NAMES + if (module_label!=NULL){ +# ifdef GEN_MAC_OBJ + store_label_offset_in_data_section (module_label->label_id); +# else +# ifdef GEN_OBJ + store_label_in_data_section (module_label); +# endif +# endif + } +#endif + +# ifdef GEN_OBJ + define_data_label (profile_function_label); + store_long_word_in_data_section (0); + store_c_string_in_data_section (string,string_length); +# endif + + if (assembly_flag){ +# ifdef M68000 + w_as_to_data_section(); +# if TIME_PROFILE_WITH_MODULE_NAMES + if (module_label!=NULL) + w_as_label_in_data_section (module_label->label_name); +# endif + w_as_define_label (profile_function_label); +# else +# if TIME_PROFILE_WITH_MODULE_NAMES + if (module_label!=NULL) + w_as_label_in_data_section (module_label->label_name); +# endif + w_as_define_data_label (profile_function_label->label_number); +# endif + w_as_long_in_data_section (0); + w_as_c_string_in_data_section (string,string_length); + } +#endif +} + +void write_profile_table (void) +{ + struct profile_table *profile_table_entry; + int string_length_4; + +# if defined (G_POWER) || defined (_WINDOWS_) + as_new_data_module(); + if (assembly_flag) + w_as_new_data_module(); +# endif + + for_l (profile_table_entry,profile_table,next){ + char *string; + int string_length; + LABEL *profile_function_label; + + profile_function_label=profile_table_entry->label; + string_length=profile_table_entry->string_length; + string=profile_table_entry->string; + +#if TIME_PROFILE_WITH_MODULE_NAMES + if (module_label!=NULL){ +# ifdef GEN_MAC_OBJ + store_label_offset_in_data_section (module_label->label_id); +# else +# ifdef GEN_OBJ + store_label_in_data_section (module_label); +# endif +# endif + } +#endif + +#ifdef GEN_OBJ + define_data_label (profile_function_label); + store_long_word_in_data_section (0); + store_c_string_in_data_section (string,string_length); +#endif + + if (assembly_flag){ +#ifdef M68000 + w_as_to_data_section(); +# if TIME_PROFILE_WITH_MODULE_NAMES + if (module_label!=NULL) + w_as_label_in_data_section (module_label->label_name); +# endif + w_as_define_label (profile_function_label); +#else +# if TIME_PROFILE_WITH_MODULE_NAMES + if (module_label!=NULL) + w_as_label_in_data_section (module_label->label_name); +# endif + w_as_define_data_label (profile_function_label->label_number); +#endif + w_as_long_in_data_section (0); + w_as_c_string_in_data_section (string,string_length); + } + } + + profile_table=NULL; +} + +void code_start (char *label_name) +{ + if (strcmp ("__nostart__",label_name)==0) + return; + + code_o (0,0,e_vector); +#if defined (SOLARIS) || defined (LINUX_ELF) + code_label ("__start"); + code_export ("__start"); +#else + code_label ("_start"); + code_export ("_start"); +#endif + +#if defined (M68000) && defined (SUN) + { + char reloc_label_name[128]; + LABEL *label; + + strcpy (reloc_label_name,"re_"); + strcat (reloc_label_name,this_module_name); + + label=enter_label (reloc_label_name,LOCAL_LABEL); + end_basic_block_with_registers (0,0,e_vector); + +#if defined (sparc) + i_sub_i_r (4,B_STACK_POINTER); +#endif + i_jsr_l (label,0); + + begin_new_basic_block(); + } +#endif + code_jmp (label_name); +} + +static LABEL *code_string_or_module (char label_name[],char string[],int string_length) +{ + LABEL *label; + + label=enter_label (label_name,LOCAL_LABEL +#ifdef G_POWER + | DATA_LABEL | STRING_LABEL +#endif + ); + + if (label->label_id>=0) + error_s ("Label %d defined twice\n",label_name); + label->label_id=next_label_id++; + +#ifdef GEN_MAC_OBJ + start_new_module (0); + if (assembly_flag) + w_as_new_module (0); +#endif +#if defined (G_POWER) || defined (_WINDOWS_) + as_new_data_module(); + if (assembly_flag) + w_as_new_data_module(); +#endif + +#ifdef GEN_MAC_OBJ + if (label->label_flags & EXPORT_LABEL) + define_external_label (label->label_id,LTEXT,label->label_name); + else + define_local_label (label->label_id,LTEXT); + store_abc_string_in_code_section (string,string_length); + + if (assembly_flag) + w_as_abc_string_and_label_in_code_section (string,string_length,label_name); +#else +# ifdef GEN_OBJ + define_data_label (label); + store_abc_string_in_data_section (string,string_length); +# endif + + if (assembly_flag) + w_as_abc_string_and_label_in_data_section (string,string_length,label_name); +#endif + + return label; +} + +void code_string (char label_name[],char string[],int string_length) +{ + code_string_or_module (label_name,string,string_length); +} + +void code_module (char label_name[],char string[],int string_length) +{ + module_label=code_string_or_module (label_name,string,string_length); +} + +void code_label (char *label_name) +{ + struct block_label *new_label; + LABEL *label; + int begin_module; + + label=enter_label (label_name,LOCAL_LABEL); + + new_label=fast_memory_allocate_type (struct block_label); + new_label->block_label_label=label; + new_label->block_label_next=NULL; + + if (!offered_before_label){ + begin_module=0; + + if (!(label->label_flags & REGISTERS_ALLOCATED)){ + if (reachable){ + label->label_a_stack_size=get_a_stack_size(); + label->label_vector=&label->label_small_vector; + label->label_b_stack_size=get_b_stack_size (&label->label_vector); + } else { + label->label_a_stack_size=0; + label->label_b_stack_size=0; + label->label_vector=e_vector; + } + label->label_flags |= REGISTERS_ALLOCATED; + } + } else { + begin_module=1; + + offered_before_label=0; + + label->label_a_stack_size=offered_a_stack_size; + label->label_b_stack_size=offered_b_stack_size; + +#ifdef G_POWER + label->label_flags |= REGISTERS_ALLOCATED | DOT_O_BEFORE_LABEL; +#else + label->label_flags |= REGISTERS_ALLOCATED; +#endif + if (offered_b_stack_size<=VECTOR_ELEMENT_SIZE){ + label->label_vector=&label->label_small_vector; + label->label_small_vector=*offered_vector; + } else { + int vector_size; + ULONG *vector,*old_vector; + + vector_size=(offered_b_stack_size+VECTOR_ELEMENT_SIZE-1)>>LOG_VECTOR_ELEMENT_SIZE; + vector=(ULONG*)fast_memory_allocate (vector_size * sizeof (ULONG)); + label->label_vector=vector; + old_vector=offered_vector; + while (vector_size>0){ + *vector++=*old_vector++; + --vector_size; + } + } + } + + if (reachable) + end_basic_block_with_registers (label->label_a_stack_size,label->label_b_stack_size,label->label_vector); + else + generate_code_for_previous_blocks (0); + +#ifdef PROFILE + if (begin_module && reachable && profile_function_label!=NULL && profile_flag!=PROFILE_NOT) + + if (! (last_block->block_instructions==NULL && + last_block->block_profile==profile_flag && last_block->block_profile_function_label==profile_function_label)) + + i_jmp_l_profile (label,profile_offset); +#endif + + if (last_block->block_instructions!=NULL){ + begin_new_basic_block(); + + if (begin_module){ + last_block->block_begin_module=1; + last_block->block_link_module=reachable; + + if (profile_function_label!=NULL && profile_flag!=PROFILE_NOT){ + last_block->block_profile=profile_flag; + last_block->block_profile_function_label=profile_function_label; + profile_function_block=last_block; + } + } + } else { + release_a_stack(); + release_b_stack(); + + if (begin_module){ + if (!last_block->block_begin_module){ + last_block->block_begin_module=1; + last_block->block_link_module=reachable; + } + + if (profile_function_label!=NULL && profile_flag!=PROFILE_NOT){ + last_block->block_profile=profile_flag; + last_block->block_profile_function_label=profile_function_label; + profile_function_block=last_block; + } + } + } + + profile_flag=PROFILE_NORMAL; + + reachable=1; + +#ifdef MORE_PARAMETER_REGISTERS + init_ab_stack (label->label_a_stack_size,label->label_b_stack_size,label->label_vector); +#else + init_a_stack (label->label_a_stack_size); + init_b_stack (label->label_b_stack_size,label->label_vector); +#endif + + if (last_block->block_labels==NULL) + last_block->block_labels=new_label; + else + last_block_label->block_label_next=new_label; + last_block_label=new_label; +} + +void code_newlocallabel (char *label_name) +{ + struct label_node **label_p,*new_label; + + new_label=fast_memory_allocate_type (struct label_node); + new_label->label_node_label.label_flags=0; + new_label->label_node_label.label_number=next_label++; + new_label->label_node_label.label_id=next_label++; + new_label->label_node_label.label_last_lea_block=NULL; + + label_p=&labels; + while (*label_p!=NULL){ + struct label_node *label; + int r; + + label=*label_p; + r=strcmp (label_name,label->label_node_label.label_name); + if (r==0){ + new_label->label_node_left=label->label_node_left; + new_label->label_node_right=label->label_node_right; + new_label->label_node_label.label_name=label->label_node_label.label_name; + + *label_p=new_label; + return; + } + if (r<0) + label_p=&label->label_node_left; + else + label_p=&label->label_node_right; + } + + new_label->label_node_left=NULL; + new_label->label_node_right=NULL; + + new_label->label_node_label.label_name=(char*)fast_memory_allocate (strlen (label_name)+1); + strcpy (new_label->label_node_label.label_name,label_name); + + *label_p=new_label; +} + +#if 0 +static void show_labels (struct block_label *labels) +{ + for (; labels!=NULL; labels=labels->block_label_next) + if (labels->block_label_label->label_number!=0) + printf ("L%d\n",labels->block_label_label->label_number); + else + printf ("%s:\n",labels->block_label_label->label_name); +} + +void show_code (VOID) +{ + struct basic_block *block; + + for (block=first_block; block!=NULL; block=block->block_next){ + printf ("%d %d %d\n",block->block_n_new_heap_cells,block->block_n_begin_a_parameter_registers, + block->block_n_begin_d_parameter_registers); + show_labels (block->block_labels); + show_instructions (block->block_instructions); + + printf ("\n"); + } +} + +static void show_import_and_export_labels (struct label_node *label_node) +{ + LABEL *label; + + if (label_node==NULL) + return; + + label=&label_node->label_node_label; + if (!(label->label_flags & LOCAL_LABEL) && label->label_number==0) + printf ("IMPORT %s\n",label->label_name); + if (label->label_flags & EXPORT_LABEL && label->label_number==0) + printf ("EXPORT %s\n",label->label_name); + + show_import_and_export_labels (label_node->label_node_left); + show_import_and_export_labels (label_node->label_node_right); +} + +void show_imports_and_exports (VOID) +{ + show_import_and_export_labels (labels); +} +#endif + +void initialize_coding (VOID) +{ + register int n; + + last_INT_descriptor_block=NULL; + last_BOOL_descriptor_block=NULL; + last_CHAR_descriptor_block=NULL; + last_REAL_descriptor_block=NULL; + last_FILE_descriptor_block=NULL; + last__STRING__descriptor_block=NULL; + + last_instruction=NULL; + first_block=allocate_empty_basic_block(); + last_block=first_block; + + demand_flag=0; + offered_after_jsr=0; + offered_before_label=0; + reachable=0; + + next_label=1; + next_label_id=0; + eval_label_number=0; + + labels=NULL; + local_labels=NULL; + last_instruction=NULL; + + INT_label=BOOL_label=CHAR_label=REAL_label=FILE_label=_STRING__label=NULL; + + halt_label=cat_string_label=NULL; + cmp_string_label=eqD_label=NULL; + slice_string_label=D_to_S_label=NULL; + print_label=print_sc_label=print_symbol_label=print_symbol_sc_label=NULL; + update_string_label=equal_string_label=entier_real_label=cycle_in_spine_label=NULL; + yet_args_needed_label=string_to_string_node_label=NULL; + repl_args_b_label=push_arg_b_label=del_args_label=printD_label=reserve_label=NULL; + suspend_label=stop_reducer_label=new_int_reducer_label=new_ext_reducer_label=NULL; + send_graph_label=send_request_label=copy_graph_label=create_channel_label=NULL; + newP_label=ItoP_label=channelP_label=currentP_label=randomP_label=NULL; + CHANNEL_label=EMPTY_label=system_sp_label=NULL; + + print_char_label=print_int_label=print_real_label=NULL; + + print_r_arg_label=NULL; + push_t_r_args_label=NULL; + + create_array_label=NULL; + create_arrayB_label=create_arrayC_label=create_arrayI_label=create_arrayR_label=create_r_array_label=NULL; + create_arrayB__label=create_arrayC__label=create_arrayI__label=create_arrayR__label=create_r_array__label=NULL; + push_a_r_args_label=index_error_label=NULL; + + small_integers_label=static_characters_label=NULL; + + eval_fill_label=NULL; + for (n=0; n<=32; ++n) + eval_upd_labels[n]=NULL; + + for (n=0; n<=MAX_YET_ARGS_NEEDED_ARITY; ++n) + yet_args_needed_labels[n]=NULL; + +#ifdef M68000 + if (!mc68881_flag){ + add_real=sub_real=mul_real=div_real=eq_real=gt_real=lt_real=NULL; + i_to_r_real=r_to_i_real=NULL; + exp_real=ln_real=log10_real=NULL; + cos_real=neg_real=sin_real=tan_real=acos_real=asin_real=atan_real=NULL; + } +#else + exp_real=ln_real=log10_real=r_to_i_real=NULL; + cos_real=sin_real=tan_real=acos_real=asin_real=atan_real=NULL; +#endif + pow_real=NULL; + +#if defined (M68000) || defined (G_POWER) + sqrt_real=NULL; +#endif + +#ifdef G_POWER + r_to_i_buffer_label=NULL; +#endif + + collect_0_label=enter_label ("collect_0",IMPORT_LABEL); + collect_1_label=enter_label ("collect_1",IMPORT_LABEL); + collect_2_label=enter_label ("collect_2",IMPORT_LABEL); +#ifndef I486 + collect_3_label=enter_label ("collect_3",IMPORT_LABEL); +#endif +#if defined (I486) && defined (GEN_OBJ) + collect_0l_label=enter_label ("collect_0l",IMPORT_LABEL); + collect_1l_label=enter_label ("collect_1l",IMPORT_LABEL); + collect_2l_label=enter_label ("collect_2l",IMPORT_LABEL); + end_heap_label=enter_label ("end_heap",IMPORT_LABEL); +#endif +#ifdef G_POWER + collect_00_label=enter_label ("collect_00",IMPORT_LABEL); + collect_01_label=enter_label ("collect_01",IMPORT_LABEL); + collect_02_label=enter_label ("collect_02",IMPORT_LABEL); + collect_03_label=enter_label ("collect_03",IMPORT_LABEL); + + eval_01_label=enter_label ("eval_01",IMPORT_LABEL); + eval_11_label=enter_label ("eval_11",IMPORT_LABEL); + eval_02_label=enter_label ("eval_02",IMPORT_LABEL); + eval_12_label=enter_label ("eval_12",IMPORT_LABEL); + eval_22_label=enter_label ("eval_22",IMPORT_LABEL); +#endif + + div_label=mod_label=mul_label=NULL; + + first_dependency=NULL; + last_dependency=NULL; + +#ifdef INDEX_CSE + n_lsl_2_add_12_cache=0; + n_lsl_3_add_12_cache=0; + block_in_lsl_2_add_12_cache=NULL; + block_in_lsl_3_add_12_cache=NULL; +#endif + + module_label=NULL; + profile_table_label=NULL; +#ifdef PROFILE + profile_table_offset=0; + profile_offset=PROFILE_OFFSET; +#endif +#ifdef G_POWER + if (profile_table_flag){ + profile_table=NULL; + profile_table_next_p=&profile_table; +# ifdef PROFILE + profile_offset+=4; +# endif + } +#endif + + init_cginstructions(); +} |