/* File: cglin.c Author: John van Groningen At: University of Nijmegen */ #include #if defined (LINUX) && defined (G_AI64) # include #endif #include "cgport.h" #include "cg.h" #include "cgconst.h" #include "cgiconst.h" #include "cgrconst.h" #include "cgtypes.h" #include "cglin.h" #include "cgcalc.h" #include "cgstack.h" #define g_fhighlow #define LOAD_X_PARAMETER_REGISTER #ifdef G_POWER # define IF_G_POWER(a) a #else # define IF_G_POWER(a) #endif #define LOAD_X_TO_ADDRESS 1 #define LOAD_X_TO_REGISTER 2 #ifdef sparc # undef ALIGN_REAL_ARRAYS # undef LOAD_STORE_ALIGNED_REAL 4 #endif /* from cgcode.c : */ extern struct basic_block *first_block,*last_block; extern struct instruction *last_instruction; extern LABEL *index_error_label; int local_data_offset; #pragma segment Code3 #define S2(s,v1,v2) s.v1;s.v2 #define S3(s,v1,v2,v3) s.v1;s.v2;s.v3 #define S4(s,v1,v2,v3,v4) s.v1;s.v2;s.v3;s.v4 #define U2(s,v1,v2) s->v1;s->v2 #define U3(s,v1,v2,v3) s->v1;s->v2;s->v3 #define U4(s,v1,v2,v3,v4) s->v1;s->v2;s->v3;s->v4 IF_G_POWER(struct instruction *last_heap_pointer_update;) static struct instruction *i_new_instruction (int instruction_code,int arity,int arg_size) { register struct instruction *instruction; instruction=(struct instruction*)fast_memory_allocate (sizeof (struct instruction)+arg_size); U4(instruction, instruction_next=NULL, instruction_prev=last_instruction, instruction_icode=instruction_code, instruction_arity=arity); if (last_block->block_instructions==NULL) last_block->block_instructions=instruction; else last_instruction->instruction_next=instruction; last_instruction=instruction; return instruction; } static struct instruction *i_new_instruction1 (int instruction_code) { struct instruction *instruction; instruction=(struct instruction*)fast_memory_allocate (sizeof (struct instruction)+sizeof (struct parameter)); U4(instruction, instruction_next=NULL, instruction_prev=last_instruction, instruction_icode=instruction_code, instruction_arity=1); if (last_block->block_instructions==NULL) last_block->block_instructions=instruction; else last_instruction->instruction_next=instruction; last_instruction=instruction; return instruction; } static struct instruction *i_new_instruction2 (int instruction_code) { struct instruction *instruction; instruction=(struct instruction*)fast_memory_allocate (sizeof (struct instruction)+2*sizeof (struct parameter)); U4(instruction, instruction_next=NULL, instruction_prev=last_instruction, instruction_icode=instruction_code, instruction_arity=2); if (last_block->block_instructions==NULL) last_block->block_instructions=instruction; else last_instruction->instruction_next=instruction; last_instruction=instruction; return instruction; } static struct instruction *i_new_instruction3 (int instruction_code) { struct instruction *instruction; instruction=(struct instruction*)fast_memory_allocate (sizeof (struct instruction)+3*sizeof (struct parameter)); U4(instruction, instruction_next=NULL, instruction_prev=last_instruction, instruction_icode=instruction_code, instruction_arity=3); if (last_block->block_instructions==NULL) last_block->block_instructions=instruction; else last_instruction->instruction_next=instruction; last_instruction=instruction; return instruction; } void i_add_i_r (LONG value,int register_1) { struct instruction *instruction; instruction=i_new_instruction2 (IADD); S2 (instruction->instruction_parameters[0], parameter_type=P_IMMEDIATE, parameter_data.imm=value); S2 (instruction->instruction_parameters[1], parameter_type=P_REGISTER, parameter_data.i=register_1); } void i_add_r_r (int register_1,int register_2) { struct instruction *instruction; instruction=i_new_instruction2 (IADD); S2 (instruction->instruction_parameters[0], parameter_type=P_REGISTER, parameter_data.i=register_1); S2 (instruction->instruction_parameters[1], parameter_type=P_REGISTER, parameter_data.i=register_2); } #if defined (G_POWER) || defined (sparc) static void i_addi_r_r (LONG value,int register_1,int register_2) { struct instruction *instruction; instruction=i_new_instruction (IADDI,3,3*sizeof (struct parameter)); S2 (instruction->instruction_parameters[0], parameter_type=P_REGISTER, parameter_data.i=register_1); S2 (instruction->instruction_parameters[1], parameter_type=P_REGISTER, parameter_data.i=register_2); S2 (instruction->instruction_parameters[2], parameter_type=P_IMMEDIATE, parameter_data.imm=value); } #endif #if defined (M68000) || defined (G_POWER) || defined (G_AI64) # if defined (M68000) static # endif void i_and_i_r (LONG value,int register_1) { struct instruction *instruction; instruction=i_new_instruction2 (IAND); S2 (instruction->instruction_parameters[0], parameter_type=P_IMMEDIATE, parameter_data.imm=value); S2 (instruction->instruction_parameters[1], parameter_type=P_REGISTER, parameter_data.i=register_1); } #endif #ifdef M68000 void i_bmi_l (LABEL *label) { struct instruction *instruction; instruction=i_new_instruction1 (IBMI); S2 (instruction->instruction_parameters[0], parameter_type=P_LABEL, parameter_data.l=label); } LONG *i_bmi_i (VOID) { struct instruction *instruction; instruction=i_new_instruction1 (IBMI); instruction->instruction_parameters[0].parameter_type=P_IMMEDIATE; return &instruction->instruction_parameters[0].parameter_data.imm; } #endif #ifdef G_POWER void i_bnep_l (LABEL *label) { register struct instruction *instruction; instruction=i_new_instruction1 (IBNEP); instruction->instruction_parameters[0].parameter_type=P_LABEL; instruction->instruction_parameters[0].parameter_data.l=label; } #endif #if defined (sparc) || defined (I486) void i_bne_l (LABEL *label) { register struct instruction *instruction; instruction=i_new_instruction1 (IBNE); instruction->instruction_parameters[0].parameter_type=P_LABEL; instruction->instruction_parameters[0].parameter_data.l=label; } #endif #ifdef M68000 static void i_bmove_pd_pd_r (int reg_1,int reg_2,int reg_3) { register struct instruction *instruction; instruction=i_new_instruction (IBMOVE,3,3*sizeof (struct parameter)); instruction->instruction_parameters[0].parameter_type=P_PRE_DECREMENT; instruction->instruction_parameters[0].parameter_data.i=reg_1; instruction->instruction_parameters[1].parameter_type=P_PRE_DECREMENT; instruction->instruction_parameters[1].parameter_data.i=reg_2; instruction->instruction_parameters[2].parameter_type=P_REGISTER; instruction->instruction_parameters[2].parameter_data.i=reg_3; } static void i_bmove_pi_pi_r (int reg_1,int reg_2,int reg_3) { register struct instruction *instruction; instruction=i_new_instruction (IBMOVE,3,3*sizeof (struct parameter)); instruction->instruction_parameters[0].parameter_type=P_POST_INCREMENT; instruction->instruction_parameters[0].parameter_data.i=reg_1; instruction->instruction_parameters[1].parameter_type=P_POST_INCREMENT; instruction->instruction_parameters[1].parameter_data.i=reg_2; instruction->instruction_parameters[2].parameter_type=P_REGISTER; instruction->instruction_parameters[2].parameter_data.i=reg_3; } #endif #ifdef I486 void i_btst_i_id (LONG i,int offset,int register_1) { register struct instruction *instruction; instruction=i_new_instruction2 (IBTST); S2 (instruction->instruction_parameters[0], parameter_type=P_IMMEDIATE, parameter_data.imm=i); instruction->instruction_parameters[1].parameter_type=P_INDIRECT; instruction->instruction_parameters[1].parameter_offset=offset; instruction->instruction_parameters[1].parameter_data.i=register_1; } #endif #if defined (sparc) || defined (I486) || defined (G_POWER) void i_btst_i_r (LONG i,int register_1) { register struct instruction *instruction; instruction=i_new_instruction2 (IBTST); S2 (instruction->instruction_parameters[0], parameter_type=P_IMMEDIATE, parameter_data.imm=i); S2 (instruction->instruction_parameters[1], parameter_type=P_REGISTER, parameter_data.i=register_1); } #endif static void i_cmp_i_r (LONG value,int register_1) { register struct instruction *instruction; instruction=i_new_instruction2 (ICMP); S2 (instruction->instruction_parameters[0], parameter_type=P_IMMEDIATE, parameter_data.imm=value); S2 (instruction->instruction_parameters[1], parameter_type=P_REGISTER, parameter_data.i=register_1); } static void i_cmp_id_r (int offset,int register_1,int register_2) { struct instruction *instruction; #ifdef G_POWER instruction=i_new_instruction2 (ICMPLW); #else instruction=i_new_instruction2 (ICMP); #endif S3(instruction->instruction_parameters[0], parameter_type=P_INDIRECT, parameter_offset=offset, parameter_data.i=register_1); S2(instruction->instruction_parameters[1], parameter_type=P_REGISTER, parameter_data.i=register_2); } #ifdef M68000 static void i_cmpw_d_id (LABEL *descriptor,int arity,int offset_1,int register_1) { struct instruction *instruction; instruction=i_new_instruction2 (ICMPW); S3(instruction->instruction_parameters[0], parameter_type=P_DESCRIPTOR_NUMBER, parameter_offset=arity, parameter_data.l=descriptor); S3(instruction->instruction_parameters[1], parameter_type=P_INDIRECT, parameter_offset=offset_1, parameter_data.i=register_1); } #endif #if defined (M68000) || defined (I486) # ifndef G_AI64 static # endif void i_exg_r_r (int register_1,int register_2) { register struct instruction *instruction; instruction=i_new_instruction2 (IEXG); S2 (instruction->instruction_parameters[0], parameter_type=P_REGISTER, parameter_data.i=register_1); S2 (instruction->instruction_parameters[1], parameter_type=P_REGISTER, parameter_data.i=register_2); } #endif #if defined (I486) && defined (FP_STACK_OPTIMIZATIONS) # define set_float_register_parameter(p,r) (p).parameter_type=P_F_REGISTER; (p).parameter_flags=0; (p).parameter_data.i=(r) #else # define set_float_register_parameter(p,r) (p).parameter_type=P_F_REGISTER; (p).parameter_data.i=(r) #endif #if defined (M68000) || defined (G_POWER) static void i_extb_r (int register_1) { register struct instruction *instruction; instruction=i_new_instruction1 (IEXTB); S2 (instruction->instruction_parameters[0], parameter_type=P_REGISTER, parameter_data.i=register_1); } #endif #ifdef M68000 void i_ext_r (int register_1) { register struct instruction *instruction; instruction=i_new_instruction1 (IEXT); S2 (instruction->instruction_parameters[0], parameter_type=P_REGISTER, parameter_data.i=register_1); } #endif #ifdef FP_STACK_OPTIMIZATIONS static void i_fexg_fr_fr (int register_1,int register_2) { struct instruction *instruction; instruction=i_new_instruction2 (IFEXG); set_float_register_parameter (instruction->instruction_parameters[0],register_1); set_float_register_parameter (instruction->instruction_parameters[1],register_2); } #endif void i_fmove_fr_fr (int register_1,int register_2) { struct instruction *instruction; instruction=i_new_instruction2 (IFMOVE); set_float_register_parameter (instruction->instruction_parameters[0],register_1); set_float_register_parameter (instruction->instruction_parameters[1],register_2); } void i_fmove_fr_id (int register_1,int offset,int register_2) { struct instruction *instruction; instruction=i_new_instruction2 (IFMOVE); set_float_register_parameter (instruction->instruction_parameters[0],register_1); instruction->instruction_parameters[1].parameter_type=P_INDIRECT; instruction->instruction_parameters[1].parameter_offset=offset; instruction->instruction_parameters[1].parameter_data.i=register_2; #ifdef ALIGN_REAL_ARRAYS instruction->instruction_parameters[1].parameter_flags=0; #endif } #ifdef ALIGN_REAL_ARRAYS void i_fmove_fr_id_f (int register_1,int offset,int register_2,int flags) { struct instruction *instruction; instruction=i_new_instruction2 (IFMOVE); set_float_register_parameter (instruction->instruction_parameters[0],register_1); instruction->instruction_parameters[1].parameter_type=P_INDIRECT; instruction->instruction_parameters[1].parameter_offset=offset; instruction->instruction_parameters[1].parameter_data.i=register_2; instruction->instruction_parameters[1].parameter_flags=flags; } #endif #ifdef M68000 void i_fmove_fr_pd (int register_1,int register_2) { register struct instruction *instruction; instruction=i_new_instruction2 (IFMOVE); set_float_register_parameter (instruction->instruction_parameters[0],register_1); instruction->instruction_parameters[1].parameter_type=P_PRE_DECREMENT; instruction->instruction_parameters[1].parameter_data.i=register_2; } void i_fmove_fr_pi (int register_1,int register_2) { register struct instruction *instruction; instruction=i_new_instruction2 (IFMOVE); set_float_register_parameter (instruction->instruction_parameters[0],register_1); instruction->instruction_parameters[1].parameter_type=P_POST_INCREMENT; instruction->instruction_parameters[1].parameter_data.i=register_2; } #endif #ifdef ALIGN_REAL_ARRAYS static void i_fmove_fr_x (int register_1,int offset,int register_2,int register_3,int flags) #else static void i_fmove_fr_x (int register_1,int offset,int register_2,int register_3) #endif { struct instruction *instruction; struct index_registers *index_registers; instruction=i_new_instruction (IFMOVE,2,2*sizeof (struct parameter)+sizeof (struct index_registers)); index_registers=(struct index_registers *)&instruction->instruction_parameters[2]; set_float_register_parameter (instruction->instruction_parameters[0],register_1); S3(instruction->instruction_parameters[1],parameter_type=P_INDEXED,parameter_offset=offset,parameter_data.ir=index_registers); #ifdef ALIGN_REAL_ARRAYS instruction->instruction_parameters[1].parameter_flags=flags; #endif index_registers->a_reg.r=register_2; index_registers->d_reg.r=register_3; } void i_fmove_id_fr (int offset,int register_2,int register_1) { struct instruction *instruction; instruction=i_new_instruction2 (IFMOVE); instruction->instruction_parameters[0].parameter_type=P_INDIRECT; instruction->instruction_parameters[0].parameter_offset=offset; instruction->instruction_parameters[0].parameter_data.i=register_2; #ifdef ALIGN_REAL_ARRAYS instruction->instruction_parameters[0].parameter_flags=0; #endif set_float_register_parameter (instruction->instruction_parameters[1],register_1); } #ifdef ALIGN_REAL_ARRAYS void i_fmove_id_fr_f (int offset,int register_2,int register_1,int flags) { struct instruction *instruction; instruction=i_new_instruction2 (IFMOVE); instruction->instruction_parameters[0].parameter_type=P_INDIRECT; instruction->instruction_parameters[0].parameter_offset=offset; instruction->instruction_parameters[0].parameter_data.i=register_2; instruction->instruction_parameters[0].parameter_flags=flags; set_float_register_parameter (instruction->instruction_parameters[1],register_1); } #endif #ifdef M68000 void i_fmove_pd_fr (int register_1,int register_2) { struct instruction *instruction; instruction=i_new_instruction2 (IFMOVE); instruction->instruction_parameters[0].parameter_type=P_PRE_DECREMENT; instruction->instruction_parameters[0].parameter_data.i=register_1; set_float_register_parameter (instruction->instruction_parameters[1],register_2); } void i_fmove_pi_fr (int register_1,int register_2) { struct instruction *instruction; instruction=i_new_instruction2 (IFMOVE); instruction->instruction_parameters[0].parameter_type=P_POST_INCREMENT; instruction->instruction_parameters[0].parameter_data.i=register_1; set_float_register_parameter (instruction->instruction_parameters[1],register_2); } #endif static void i_fmove_if_fr (DOUBLE r,int register_1) { struct instruction *instruction; DOUBLE *rp; instruction=i_new_instruction2 (IFMOVE); rp=(DOUBLE*)fast_memory_allocate (sizeof (DOUBLE)); instruction->instruction_parameters[0].parameter_type=P_F_IMMEDIATE; instruction->instruction_parameters[0].parameter_data.r=rp; *rp=r; set_float_register_parameter (instruction->instruction_parameters[1],register_1); } static void i_fmovel_fr_r (int register_1,int register_2) { struct instruction *instruction; instruction=i_new_instruction2 (IFMOVEL); set_float_register_parameter (instruction->instruction_parameters[0],register_1); S2 (instruction->instruction_parameters[1], parameter_type=P_REGISTER, parameter_data.i=register_2); } #ifdef ALIGN_REAL_ARRAYS static void i_fmove_x_fr (int offset,int register_1,int register_2,int register_3,int flags) #else static void i_fmove_x_fr (int offset,int register_1,int register_2,int register_3) #endif { struct instruction *instruction; struct index_registers *index_registers; instruction=i_new_instruction (IFMOVE,2,2*sizeof (struct parameter)+sizeof (struct index_registers)); index_registers=(struct index_registers *)&instruction->instruction_parameters[2]; instruction->instruction_parameters[0].parameter_type=P_INDEXED; instruction->instruction_parameters[0].parameter_offset=offset; instruction->instruction_parameters[0].parameter_data.ir=index_registers; #ifdef ALIGN_REAL_ARRAYS instruction->instruction_parameters[0].parameter_flags=flags; #endif index_registers->a_reg.r=register_1; index_registers->d_reg.r=register_2; set_float_register_parameter (instruction->instruction_parameters[1],register_3); } void i_jmp_id (int offset_1,int register_1,int n_a_registers) { struct instruction *instruction; instruction=i_new_instruction1 (IJMP); instruction->instruction_parameters[0].parameter_type=P_INDIRECT; instruction->instruction_parameters[0].parameter_offset=offset_1; instruction->instruction_parameters[0].parameter_data.reg.r=register_1; instruction->instruction_parameters[0].parameter_data.reg.u=n_a_registers; } #if defined (G_POWER) || defined (I486) void i_jmp_id_profile (int offset_1,int register_1,int n_a_registers) { struct instruction *instruction; instruction=i_new_instruction1 (IJMPP); instruction->instruction_parameters[0].parameter_type=P_INDIRECT; instruction->instruction_parameters[0].parameter_offset=offset_1; instruction->instruction_parameters[0].parameter_data.reg.r=register_1; instruction->instruction_parameters[0].parameter_data.reg.u=n_a_registers; } #endif void i_jmp_l (LABEL *label,int n_a_registers) { struct instruction *instruction; instruction=i_new_instruction1 (IJMP); instruction->instruction_parameters[0].parameter_type=P_LABEL; instruction->instruction_parameters[0].parameter_data.l=label; instruction->instruction_parameters[0].parameter_offset=n_a_registers; } #if defined (G_POWER) || defined (I486) void i_jmp_l_profile (LABEL *label,int offset) { struct instruction *instruction; instruction=i_new_instruction1 (IJMPP); instruction->instruction_parameters[0].parameter_type=P_LABEL; instruction->instruction_parameters[0].parameter_data.l=label; instruction->instruction_parameters[0].parameter_offset=offset; } #endif #ifdef I486 void i_jmp_r (int a_reg) { struct instruction *instruction; instruction=i_new_instruction1 (IJMP); instruction->instruction_parameters[0].parameter_type=P_REGISTER; instruction->instruction_parameters[0].parameter_data.i=a_reg; } void i_jmp_r_profile (int a_reg) { struct instruction *instruction; instruction=i_new_instruction1 (IJMPP); instruction->instruction_parameters[0].parameter_type=P_REGISTER; instruction->instruction_parameters[0].parameter_data.i=a_reg; } #endif #if defined (M68000) || defined (I486) void i_jsr_id (int offset,int register_1,int n_a_registers) { register struct instruction *instruction; instruction=i_new_instruction1 (IJSR); instruction->instruction_parameters[0].parameter_type=P_INDIRECT; instruction->instruction_parameters[0].parameter_offset=offset; instruction->instruction_parameters[0].parameter_data.reg.r=register_1; instruction->instruction_parameters[0].parameter_data.reg.u=n_a_registers; } void i_jsr_l (LABEL *label,int n_a_registers) { struct instruction *instruction; instruction=i_new_instruction1 (IJSR); instruction->instruction_parameters[0].parameter_type=P_LABEL; instruction->instruction_parameters[0].parameter_data.l=label; instruction->instruction_parameters[0].parameter_offset=n_a_registers; } #else void i_jsr_id_id (int offset_1,int register_1,int offset_2) { struct instruction *instruction; instruction=i_new_instruction2 (IJSR); instruction->instruction_parameters[0].parameter_type=P_INDIRECT; instruction->instruction_parameters[0].parameter_offset=offset_1; instruction->instruction_parameters[0].parameter_data.i=register_1; instruction->instruction_parameters[1].parameter_type=P_INDIRECT; /* instruction->instruction_parameters[1].parameter_data.reg.r=B_STACK_POINTER; */ instruction->instruction_parameters[1].parameter_data.i=offset_2; } void i_jsr_l_id (LABEL *label,int offset) { register struct instruction *instruction; instruction=i_new_instruction2 (IJSR); instruction->instruction_parameters[0].parameter_type=P_LABEL; instruction->instruction_parameters[0].parameter_data.l=label; instruction->instruction_parameters[1].parameter_type=P_INDIRECT; /* instruction->instruction_parameters[1].parameter_data.reg.r=B_STACK_POINTER; */ instruction->instruction_parameters[1].parameter_data.i=offset; } # ifdef G_POWER void i_jsr_id_idu (int offset_1,int register_1,int offset_2) { struct instruction *instruction; instruction=i_new_instruction2 (IJSR); instruction->instruction_parameters[0].parameter_type=P_INDIRECT; instruction->instruction_parameters[0].parameter_offset=offset_1; instruction->instruction_parameters[0].parameter_data.i=register_1; instruction->instruction_parameters[1].parameter_type=P_INDIRECT_WITH_UPDATE; /* instruction->instruction_parameters[1].parameter_data.reg.r=B_STACK_POINTER; */ instruction->instruction_parameters[1].parameter_data.i=offset_2; } void i_jsr_l_idu (LABEL *label,int offset) { struct instruction *instruction; instruction=i_new_instruction2 (IJSR); instruction->instruction_parameters[0].parameter_type=P_LABEL; instruction->instruction_parameters[0].parameter_data.l=label; instruction->instruction_parameters[1].parameter_type=P_INDIRECT_WITH_UPDATE; /* instruction->instruction_parameters[1].parameter_data.reg.r=B_STACK_POINTER; */ instruction->instruction_parameters[1].parameter_data.i=offset; } # endif #endif #ifdef I486 void i_jsr_r (int register_1) { struct instruction *instruction; instruction=i_new_instruction1 (IJSR); instruction->instruction_parameters[0].parameter_type=P_REGISTER; instruction->instruction_parameters[0].parameter_data.reg.r=register_1; } #endif #if defined (sparc) || defined (G_POWER) # ifdef sparc void i_call_l (LABEL *label) # else void i_call_l (LABEL *label,int frame_size) # endif { struct instruction *instruction; instruction=i_new_instruction2 (IJSR); S2(instruction->instruction_parameters[0], parameter_type=P_LABEL, parameter_data.l=label); instruction->instruction_parameters[1].parameter_type=P_REGISTER; # ifdef G_POWER instruction->instruction_parameters[1].parameter_data.i=frame_size; # endif } # ifdef sparc void i_call_r (int register_1) # else void i_call_r (int register_1,int frame_size) # endif { struct instruction *instruction; instruction=i_new_instruction2 (IJSR); S2(instruction->instruction_parameters[0], parameter_type=P_REGISTER, parameter_data.reg.r=register_1); instruction->instruction_parameters[1].parameter_type=P_REGISTER; # ifdef G_POWER instruction->instruction_parameters[1].parameter_data.i=frame_size; # endif } #endif #ifdef I486 void i_divdu_r_r_r (int register_1,int register_2,int register_3) { struct instruction *instruction; instruction=i_new_instruction3 (IDIVDU); S2 (instruction->instruction_parameters[0], parameter_type=P_REGISTER, parameter_data.i=register_1); S2 (instruction->instruction_parameters[1], parameter_type=P_REGISTER, parameter_data.i=register_2); S2 (instruction->instruction_parameters[2], parameter_type=P_REGISTER, parameter_data.i=register_3); } #endif void i_lea_id_r (int offset,int register_1,int register_2) { struct instruction *instruction; instruction=i_new_instruction2 (ILEA); instruction->instruction_parameters[0].parameter_type=P_INDIRECT; instruction->instruction_parameters[0].parameter_offset=offset; instruction->instruction_parameters[0].parameter_data.reg.r=register_1; instruction->instruction_parameters[1].parameter_type=P_REGISTER; instruction->instruction_parameters[1].parameter_data.reg.r=register_2; } void i_lea_l_i_r (LABEL *label,int offset,int register_1) { struct instruction *instruction; instruction=i_new_instruction2 (ILEA); instruction->instruction_parameters[0].parameter_type=P_LABEL; instruction->instruction_parameters[0].parameter_offset=offset; instruction->instruction_parameters[0].parameter_data.l=label; instruction->instruction_parameters[1].parameter_type=P_REGISTER; instruction->instruction_parameters[1].parameter_data.reg.r=register_1; } #if defined (sparc) || defined (I486) || defined (G_POWER) static void i_lea_x_r (int register_1,int register_2,int register_3) { register struct instruction *instruction; register struct index_registers *index_registers; instruction=i_new_instruction (ILEA,2,2*sizeof (struct parameter)+sizeof (struct index_registers)); index_registers=(struct index_registers *)&instruction->instruction_parameters[2]; instruction->instruction_parameters[0].parameter_type=P_INDEXED; instruction->instruction_parameters[0].parameter_offset=0; instruction->instruction_parameters[0].parameter_data.ir=index_registers; index_registers->a_reg.r=register_1; index_registers->d_reg.r=register_2; instruction->instruction_parameters[1].parameter_type=P_REGISTER; instruction->instruction_parameters[1].parameter_data.i=register_3; } #endif #if defined (G_POWER) || defined (sparc) static void i_lsli_r_r (LONG value,int register_1,int register_2) { struct instruction *instruction; instruction=i_new_instruction (ILSLI,3,3*sizeof (struct parameter)); S2 (instruction->instruction_parameters[0], parameter_type=P_REGISTER, parameter_data.i=register_1); S2 (instruction->instruction_parameters[1], parameter_type=P_REGISTER, parameter_data.i=register_2); S2 (instruction->instruction_parameters[2], parameter_type=P_IMMEDIATE, parameter_data.imm=value); } #endif static void i_moveb_id_r (int offset,int register_1,int register_2) { register struct instruction *instruction; instruction=i_new_instruction2 (IMOVEB); instruction->instruction_parameters[0].parameter_type=P_INDIRECT; instruction->instruction_parameters[0].parameter_offset=offset; instruction->instruction_parameters[0].parameter_data.i=register_1; S2 (instruction->instruction_parameters[1], parameter_type=P_REGISTER, parameter_data.i=register_2); } #if !(defined (M68000) || defined (I486)) static void i_moveb_x_r (int register_1,int register_2,int register_3) { struct instruction *instruction; struct index_registers *index_registers; instruction=i_new_instruction (IMOVEB,2,2*sizeof (struct parameter)+sizeof (struct index_registers)); index_registers=(struct index_registers *)&instruction->instruction_parameters[2]; instruction->instruction_parameters[0].parameter_type=P_INDEXED; instruction->instruction_parameters[0].parameter_offset=0; instruction->instruction_parameters[0].parameter_data.ir=index_registers; index_registers->a_reg.r=register_1; index_registers->d_reg.r=register_2; instruction->instruction_parameters[1].parameter_type=P_REGISTER; instruction->instruction_parameters[1].parameter_data.i=register_3; } #else static void i_moveb_x_r (int offset,int register_1,int register_2,int register_3) { struct instruction *instruction; struct index_registers *index_registers; instruction=i_new_instruction (IMOVEB,2,2*sizeof (struct parameter)+sizeof (struct index_registers)); index_registers=(struct index_registers *)&instruction->instruction_parameters[2]; instruction->instruction_parameters[0].parameter_type=P_INDEXED; instruction->instruction_parameters[0].parameter_offset=offset; instruction->instruction_parameters[0].parameter_data.ir=index_registers; index_registers->a_reg.r=register_1; index_registers->d_reg.r=register_2; instruction->instruction_parameters[1].parameter_type=P_REGISTER; instruction->instruction_parameters[1].parameter_data.i=register_3; } #endif #ifdef M68000 static void i_movem_id (int offset_1,int register_1,int n_arguments,int arguments[]) { register struct instruction *instruction; register struct parameter *parameter; register int argument_number; instruction=i_new_instruction (IMOVEM,n_arguments+1,(n_arguments+1)*sizeof (struct parameter)); instruction->instruction_parameters[0].parameter_type=P_INDIRECT; instruction->instruction_parameters[0].parameter_offset=offset_1; instruction->instruction_parameters[0].parameter_data.i=register_1; parameter=&instruction->instruction_parameters[1]; for (argument_number=0; argument_numberparameter_type=P_REGISTER; parameter->parameter_data.i=arguments[argument_number]; ++parameter; } } void i_movem_pd (int register_1,int n_arguments,int arguments[]) { struct instruction *instruction; struct parameter *parameter; int argument_number; instruction=i_new_instruction (IMOVEM,n_arguments+1,(n_arguments+1)*sizeof (struct parameter)); instruction->instruction_parameters[n_arguments].parameter_type=P_PRE_DECREMENT; instruction->instruction_parameters[n_arguments].parameter_data.i=register_1; parameter=&instruction->instruction_parameters[0]; for (argument_number=0; argument_numberparameter_type=P_REGISTER; parameter->parameter_data.i=arguments[argument_number]; ++parameter; } } void i_movem_pi (int register_1,int n_arguments,int arguments[]) { struct instruction *instruction; struct parameter *parameter; int argument_number; instruction=i_new_instruction (IMOVEM,n_arguments+1,(n_arguments+1)*sizeof (struct parameter)); instruction->instruction_parameters[0].parameter_type=P_POST_INCREMENT; instruction->instruction_parameters[0].parameter_data.i=register_1; parameter=&instruction->instruction_parameters[1]; for (argument_number=0; argument_numberparameter_type=P_REGISTER; parameter->parameter_data.i=arguments[argument_number]; ++parameter; } } void i_movem_id_r (int offset,int register_1,int register_2) { register struct instruction *instruction; instruction=i_new_instruction2 (IMOVEM); instruction->instruction_parameters[0].parameter_type=P_INDIRECT; instruction->instruction_parameters[0].parameter_offset=offset; instruction->instruction_parameters[0].parameter_data.i=register_1; S2 (instruction->instruction_parameters[1], parameter_type=P_REGISTER, parameter_data.i=register_2); } #endif #ifdef G_AI64 void i_movesw_r_r (int register_1,int register_2) { struct instruction *instruction; instruction=i_new_instruction2 (IMOVESW); S2 (instruction->instruction_parameters[0], parameter_type=P_REGISTER, parameter_data.i=register_1); S2 (instruction->instruction_parameters[1], parameter_type=P_REGISTER, parameter_data.i=register_2); } void i_movesw_id_r (int offset,int register_1,int register_2) { struct instruction *instruction; instruction=i_new_instruction2 (IMOVESW); S3 (instruction->instruction_parameters[0], parameter_type=P_INDIRECT, parameter_offset=offset, parameter_data.i=register_1); S2 (instruction->instruction_parameters[1], parameter_type=P_REGISTER, parameter_data.i=register_2); } #endif void i_movew_id_r (int offset,int register_1,int register_2) { register struct instruction *instruction; instruction=i_new_instruction2 (IMOVEW); instruction->instruction_parameters[0].parameter_type=P_INDIRECT; instruction->instruction_parameters[0].parameter_offset=offset; instruction->instruction_parameters[0].parameter_data.i=register_1; S2 (instruction->instruction_parameters[1], parameter_type=P_REGISTER, parameter_data.i=register_2); } #ifdef G_A64 static void i_move_i_id (int_64 i,int offset_1,int register_1) #else static void i_move_i_id (LONG i,int offset_1,int register_1) #endif { struct instruction *instruction; instruction=i_new_instruction2 (IMOVE); S2 (instruction->instruction_parameters[0], parameter_type=P_IMMEDIATE, parameter_data.imm=i); instruction->instruction_parameters[1].parameter_type=P_INDIRECT; instruction->instruction_parameters[1].parameter_offset=offset_1; instruction->instruction_parameters[1].parameter_data.i=register_1; } #ifdef M68000 static void i_move_i_pi (LONG i,int register_1) { register struct instruction *instruction; instruction=i_new_instruction2 (IMOVE); S2 (instruction->instruction_parameters[0], parameter_type=P_IMMEDIATE, parameter_data.imm=i); instruction->instruction_parameters[1].parameter_type=P_POST_INCREMENT; instruction->instruction_parameters[1].parameter_data.i=register_1; } #endif void i_move_i_r (CleanInt i,int register_1) { struct instruction *instruction; instruction=i_new_instruction2 (IMOVE); S2 (instruction->instruction_parameters[0], parameter_type=P_IMMEDIATE, parameter_data.imm=i); S2 (instruction->instruction_parameters[1], parameter_type=P_REGISTER, parameter_data.i=register_1); } #if defined (M68000) || defined (I486) # ifdef G_A64 static void i_move_i_x (int_64 i,int offset,int register_1,int register_2) # else static void i_move_i_x (LONG i,int offset,int register_1,int register_2) # endif { struct instruction *instruction; struct index_registers *index_registers; instruction=i_new_instruction (IMOVE,2,2*sizeof (struct parameter)+sizeof (struct index_registers)); index_registers=(struct index_registers *)&instruction->instruction_parameters[2]; S2 (instruction->instruction_parameters[0], parameter_type=P_IMMEDIATE, parameter_data.imm=i); instruction->instruction_parameters[1].parameter_type=P_INDEXED; instruction->instruction_parameters[1].parameter_offset=offset; instruction->instruction_parameters[1].parameter_data.ir=index_registers; index_registers->a_reg.r=register_1; index_registers->d_reg.r=register_2; } void i_move_id_pd (int offset_1,int register_1,int register_2) { register struct instruction *instruction; instruction=i_new_instruction2 (IMOVE); instruction->instruction_parameters[0].parameter_type=P_INDIRECT; instruction->instruction_parameters[0].parameter_offset=offset_1; instruction->instruction_parameters[0].parameter_data.i=register_1; instruction->instruction_parameters[1].parameter_type=P_PRE_DECREMENT; instruction->instruction_parameters[1].parameter_data.i=register_2; } #endif #ifdef M68000 static void i_move_id_pi (int offset_1,int register_1,int register_2) { register struct instruction *instruction; instruction=i_new_instruction2 (IMOVE); instruction->instruction_parameters[0].parameter_type=P_INDIRECT; instruction->instruction_parameters[0].parameter_offset=offset_1; instruction->instruction_parameters[0].parameter_data.i=register_1; instruction->instruction_parameters[1].parameter_type=P_POST_INCREMENT; instruction->instruction_parameters[1].parameter_data.i=register_2; } #endif static void i_move_d_r (LABEL *descriptor,int arity,int register_1) { register struct instruction *instruction; instruction=i_new_instruction2 (IMOVE); instruction->instruction_parameters[0].parameter_type=P_DESCRIPTOR_NUMBER; instruction->instruction_parameters[0].parameter_offset=arity; instruction->instruction_parameters[0].parameter_data.l=descriptor; S2 (instruction->instruction_parameters[1], parameter_type=P_REGISTER, parameter_data.i=register_1); } void i_move_id_id (int offset_1,int register_1,int offset_2,int register_2) { register struct instruction *instruction; instruction=i_new_instruction2 (IMOVE); instruction->instruction_parameters[0].parameter_type=P_INDIRECT; instruction->instruction_parameters[0].parameter_offset=offset_1; instruction->instruction_parameters[0].parameter_data.i=register_1; instruction->instruction_parameters[1].parameter_type=P_INDIRECT; instruction->instruction_parameters[1].parameter_offset=offset_2; instruction->instruction_parameters[1].parameter_data.i=register_2; } void i_move_id_r (int offset,int register_1,int register_2) { register struct instruction *instruction; instruction=i_new_instruction2 (IMOVE); instruction->instruction_parameters[0].parameter_type=P_INDIRECT; instruction->instruction_parameters[0].parameter_offset=offset; instruction->instruction_parameters[0].parameter_data.i=register_1; S2 (instruction->instruction_parameters[1], parameter_type=P_REGISTER, parameter_data.i=register_2); } #ifdef G_POWER void i_move_idu_r (int offset,int register_1,int register_2) { struct instruction *instruction; instruction=i_new_instruction2 (IMOVE); instruction->instruction_parameters[0].parameter_type=P_INDIRECT_WITH_UPDATE; instruction->instruction_parameters[0].parameter_offset=offset; instruction->instruction_parameters[0].parameter_data.i=register_1; instruction->instruction_parameters[1].parameter_type=P_REGISTER; instruction->instruction_parameters[1].parameter_data.i=register_2; } void i_move_id_idu (int offset1,int register_1,int offset2,int register_2) { struct instruction *instruction; instruction=i_new_instruction2 (IMOVE); instruction->instruction_parameters[0].parameter_type=P_INDIRECT; instruction->instruction_parameters[0].parameter_offset=offset1; instruction->instruction_parameters[0].parameter_data.i=register_1; instruction->instruction_parameters[1].parameter_type=P_INDIRECT_WITH_UPDATE; instruction->instruction_parameters[1].parameter_offset=offset2; instruction->instruction_parameters[1].parameter_data.i=register_2; } void i_move_r_idu (int register_1,int offset,int register_2) { struct instruction *instruction; instruction=i_new_instruction2 (IMOVE); instruction->instruction_parameters[0].parameter_type=P_REGISTER; instruction->instruction_parameters[0].parameter_data.i=register_1; instruction->instruction_parameters[1].parameter_type=P_INDIRECT_WITH_UPDATE; instruction->instruction_parameters[1].parameter_offset=offset; instruction->instruction_parameters[1].parameter_data.i=register_2; } void i_movew_id_idu (int offset1,int register_1,int offset2,int register_2) { struct instruction *instruction; instruction=i_new_instruction2 (IMOVEW); instruction->instruction_parameters[0].parameter_type=P_INDIRECT; instruction->instruction_parameters[0].parameter_offset=offset1; instruction->instruction_parameters[0].parameter_data.i=register_1; instruction->instruction_parameters[1].parameter_type=P_INDIRECT_WITH_UPDATE; instruction->instruction_parameters[1].parameter_offset=offset2; instruction->instruction_parameters[1].parameter_data.i=register_2; } void i_movew_r_idu (int register_1,int offset,int register_2) { struct instruction *instruction; instruction=i_new_instruction2 (IMOVEW); instruction->instruction_parameters[0].parameter_type=P_REGISTER; instruction->instruction_parameters[0].parameter_data.i=register_1; instruction->instruction_parameters[1].parameter_type=P_INDIRECT_WITH_UPDATE; instruction->instruction_parameters[1].parameter_offset=offset; instruction->instruction_parameters[1].parameter_data.i=register_2; } #endif #if defined (M68000) || defined (I486) static void i_move_id_x (int offset_1,int register_1,int offset_2,int register_2,int register_3) { register struct instruction *instruction; register struct index_registers *index_registers; instruction=i_new_instruction (IMOVE,2,2*sizeof (struct parameter)+sizeof (struct index_registers)); index_registers=(struct index_registers *)&instruction->instruction_parameters[2]; instruction->instruction_parameters[0].parameter_type=P_INDIRECT; instruction->instruction_parameters[0].parameter_offset=offset_1; instruction->instruction_parameters[0].parameter_data.i=register_1; instruction->instruction_parameters[1].parameter_type=P_INDEXED; instruction->instruction_parameters[1].parameter_offset=offset_2; instruction->instruction_parameters[1].parameter_data.ir=index_registers; index_registers->a_reg.r=register_2; index_registers->d_reg.r=register_3; } #endif void i_move_l_r (LABEL *label,int register_1) { struct instruction *instruction; instruction=i_new_instruction2 (IMOVE); instruction->instruction_parameters[0].parameter_type=P_LABEL; instruction->instruction_parameters[0].parameter_data.l=label; S2 (instruction->instruction_parameters[1], parameter_type=P_REGISTER, parameter_data.i=register_1); } #ifdef M68000 void i_move_pd_r (int register_1,int register_2) { register struct instruction *instruction; instruction=i_new_instruction2 (IMOVE); instruction->instruction_parameters[0].parameter_type=P_PRE_DECREMENT; instruction->instruction_parameters[0].parameter_data.i=register_1; S2 (instruction->instruction_parameters[1], parameter_type=P_REGISTER, parameter_data.i=register_2); } void i_move_pi_id (int register_1,int offset_2,int register_2) { register struct instruction *instruction; instruction=i_new_instruction2 (IMOVE); instruction->instruction_parameters[0].parameter_type=P_POST_INCREMENT; instruction->instruction_parameters[0].parameter_data.i=register_1; instruction->instruction_parameters[1].parameter_type=P_INDIRECT; instruction->instruction_parameters[1].parameter_offset=offset_2; instruction->instruction_parameters[1].parameter_data.i=register_2; } static void i_move_pi_pi (int register_1,int register_2) { register struct instruction *instruction; instruction=i_new_instruction2 (IMOVE); instruction->instruction_parameters[0].parameter_type=P_POST_INCREMENT; instruction->instruction_parameters[0].parameter_data.i=register_1; instruction->instruction_parameters[1].parameter_type=P_POST_INCREMENT; instruction->instruction_parameters[1].parameter_data.i=register_2; } #endif #if defined (M68000) | defined (I486) void i_move_pi_r (int register_1,int register_2) { register struct instruction *instruction; instruction=i_new_instruction2 (IMOVE); instruction->instruction_parameters[0].parameter_type=P_POST_INCREMENT; instruction->instruction_parameters[0].parameter_data.i=register_1; S2 (instruction->instruction_parameters[1], parameter_type=P_REGISTER, parameter_data.i=register_2); } #endif #ifdef M68000 static void i_move_pi_x (int register_1,int offset,int register_2,int register_3) { register struct instruction *instruction; register struct index_registers *index_registers; instruction=i_new_instruction (IMOVE,2,2*sizeof (struct parameter)+sizeof (struct index_registers)); index_registers=(struct index_registers *)&instruction->instruction_parameters[2]; instruction->instruction_parameters[0].parameter_type=P_POST_INCREMENT; instruction->instruction_parameters[0].parameter_data.i=register_1; instruction->instruction_parameters[1].parameter_type=P_INDEXED; instruction->instruction_parameters[1].parameter_offset=offset; instruction->instruction_parameters[1].parameter_data.ir=index_registers; index_registers->a_reg.r=register_2; index_registers->d_reg.r=register_3; } #endif #ifdef G_POWER static struct instruction *instruction_move_r_idhp (int register_1,LONG offset) { struct instruction *instruction; instruction=i_new_instruction2 (IMOVE); S2 (instruction->instruction_parameters[0], parameter_type=P_REGISTER, parameter_data.i=register_1); instruction->instruction_parameters[1].parameter_type=P_INDIRECT_HP; instruction->instruction_parameters[1].parameter_data.i=offset; return instruction; } #endif #if defined (I486) void i_move_r_l (int register_1,LABEL *label) { struct instruction *instruction; instruction=i_new_instruction2 (IMOVE); S2 (instruction->instruction_parameters[0], parameter_type=P_REGISTER, parameter_data.i=register_1); S2 (instruction->instruction_parameters[1], parameter_type=P_LABEL, parameter_data.l=label); } #endif void i_move_r_id (int register_1,int offset,int register_2) { struct instruction *instruction; instruction=i_new_instruction2 (IMOVE); S2 (instruction->instruction_parameters[0], parameter_type=P_REGISTER, parameter_data.i=register_1); instruction->instruction_parameters[1].parameter_type=P_INDIRECT; instruction->instruction_parameters[1].parameter_offset=offset; instruction->instruction_parameters[1].parameter_data.i=register_2; } #if defined (M68000) | defined (I486) void i_move_r_pd (int register_1,int register_2) { register struct instruction *instruction; instruction=i_new_instruction2 (IMOVE); S2 (instruction->instruction_parameters[0], parameter_type=P_REGISTER, parameter_data.i=register_1); instruction->instruction_parameters[1].parameter_type=P_PRE_DECREMENT; instruction->instruction_parameters[1].parameter_data.i=register_2; } #endif #ifdef M68000 void i_move_r_pi (int register_1,int register_2) { register struct instruction *instruction; instruction=i_new_instruction2 (IMOVE); S2 (instruction->instruction_parameters[0], parameter_type=P_REGISTER, parameter_data.i=register_1); instruction->instruction_parameters[1].parameter_type=P_POST_INCREMENT; instruction->instruction_parameters[1].parameter_data.i=register_2; } #endif void i_move_r_r (int register_1,int register_2) { register struct instruction *instruction; instruction=i_new_instruction2 (IMOVE); S2 (instruction->instruction_parameters[0], parameter_type=P_REGISTER, parameter_data.i=register_1); S2 (instruction->instruction_parameters[1], parameter_type=P_REGISTER, parameter_data.i=register_2); } static void i_move_x_r (int offset,int register_1,int register_2,int register_3) { register struct instruction *instruction; register struct index_registers *index_registers; instruction=i_new_instruction (IMOVE,2,2*sizeof (struct parameter)+sizeof (struct index_registers)); index_registers=(struct index_registers *)&instruction->instruction_parameters[2]; instruction->instruction_parameters[0].parameter_type=P_INDEXED; instruction->instruction_parameters[0].parameter_offset=offset; instruction->instruction_parameters[0].parameter_data.ir=index_registers; index_registers->a_reg.r=register_1; index_registers->d_reg.r=register_2; instruction->instruction_parameters[1].parameter_type=P_REGISTER; instruction->instruction_parameters[1].parameter_data.i=register_3; } static void i_move_x_id (int offset_1,int register_1,int register_2,int offset_2,int register_3) { register struct instruction *instruction; register struct index_registers *index_registers; instruction=i_new_instruction (IMOVE,2,2*sizeof (struct parameter)+sizeof (struct index_registers)); index_registers=(struct index_registers *)&instruction->instruction_parameters[2]; instruction->instruction_parameters[0].parameter_type=P_INDEXED; instruction->instruction_parameters[0].parameter_offset=offset_1; instruction->instruction_parameters[0].parameter_data.ir=index_registers; index_registers->a_reg.r=register_1; index_registers->d_reg.r=register_2; instruction->instruction_parameters[1].parameter_type=P_INDIRECT; instruction->instruction_parameters[1].parameter_offset=offset_2; instruction->instruction_parameters[1].parameter_data.i=register_3; } #if defined (M68000) static void i_move_x_pi (int offset,int register_1,int register_2,int register_3) { register struct instruction *instruction; register struct index_registers *index_registers; instruction=i_new_instruction (IMOVE,2,2*sizeof (struct parameter)+sizeof (struct index_registers)); index_registers=(struct index_registers *)&instruction->instruction_parameters[2]; instruction->instruction_parameters[0].parameter_type=P_INDEXED; instruction->instruction_parameters[0].parameter_offset=offset; instruction->instruction_parameters[0].parameter_data.ir=index_registers; index_registers->a_reg.r=register_1; index_registers->d_reg.r=register_2; instruction->instruction_parameters[1].parameter_type=P_POST_INCREMENT; instruction->instruction_parameters[1].parameter_data.i=register_3; } static void i_move_x_x (int offset_1,int register_1,int register_2,int offset_2,int register_3,int register_4) { register struct instruction *instruction; register struct index_registers *index_registers_1,*index_registers_2; instruction=i_new_instruction (IMOVE,2,2*sizeof (struct parameter)+2*sizeof (struct index_registers)); index_registers_1=(struct index_registers *)&instruction->instruction_parameters[2]; index_registers_2=&index_registers_1[1]; instruction->instruction_parameters[0].parameter_type=P_INDEXED; instruction->instruction_parameters[0].parameter_offset=offset_1; instruction->instruction_parameters[0].parameter_data.ir=index_registers_1; index_registers_1->a_reg.r=register_1; index_registers_1->d_reg.r=register_2; instruction->instruction_parameters[1].parameter_type=P_INDEXED; instruction->instruction_parameters[1].parameter_offset=offset_2; instruction->instruction_parameters[1].parameter_data.ir=index_registers_2; index_registers_2->a_reg.r=register_3; index_registers_2->d_reg.r=register_4; } void i_movew_id_pd (int offset_1,int register_1,int register_2) { register struct instruction *instruction; instruction=i_new_instruction2 (IMOVEW); instruction->instruction_parameters[0].parameter_type=P_INDIRECT; instruction->instruction_parameters[0].parameter_offset=offset_1; instruction->instruction_parameters[0].parameter_data.i=register_1; instruction->instruction_parameters[1].parameter_type=P_PRE_DECREMENT; instruction->instruction_parameters[1].parameter_data.i=register_2; } void i_movew_pi_id (int register_1,int offset_2,int register_2) { struct instruction *instruction; instruction=i_new_instruction2 (IMOVEW); instruction->instruction_parameters[0].parameter_type=P_POST_INCREMENT; instruction->instruction_parameters[0].parameter_data.i=register_1; instruction->instruction_parameters[1].parameter_type=P_INDIRECT; instruction->instruction_parameters[1].parameter_offset=offset_2; instruction->instruction_parameters[1].parameter_data.i=register_2; } void i_movew_pi_r (int register_1,int register_2) { struct instruction *instruction; instruction=i_new_instruction2 (IMOVEW); instruction->instruction_parameters[0].parameter_type=P_POST_INCREMENT; instruction->instruction_parameters[0].parameter_data.i=register_1; S2 (instruction->instruction_parameters[1], parameter_type=P_REGISTER, parameter_data.i=register_2); } void i_movew_r_pd (int register_1,int register_2) { struct instruction *instruction; instruction=i_new_instruction2 (IMOVEW); S2 (instruction->instruction_parameters[0], parameter_type=P_REGISTER, parameter_data.i=register_1); instruction->instruction_parameters[1].parameter_type=P_PRE_DECREMENT; instruction->instruction_parameters[1].parameter_data.i=register_2; } #endif #ifdef I486 void i_mulud_r_r (int register_1,int register_2) { struct instruction *instruction; instruction=i_new_instruction2 (IMULUD); S2 (instruction->instruction_parameters[0], parameter_type=P_REGISTER, parameter_data.i=register_1); S2 (instruction->instruction_parameters[1], parameter_type=P_REGISTER, parameter_data.i=register_2); } #endif #if defined (G_POWER) || defined (G_AI64) void i_or_i_r (LONG value,int register_1) { struct instruction *instruction; instruction=i_new_instruction2 (IOR); S2 (instruction->instruction_parameters[0], parameter_type=P_IMMEDIATE, parameter_data.imm=value); S2 (instruction->instruction_parameters[1], parameter_type=P_REGISTER, parameter_data.i=register_1); } #endif #ifdef G_POWER void i_mtctr (int register_1) { struct instruction *instruction; instruction=i_new_instruction (IMTCTR,1,1*sizeof (struct parameter)); S2 (instruction->instruction_parameters[0], parameter_type=P_REGISTER, parameter_data.i=register_1); } #endif #if ! (defined (sparc) || defined (G_POWER)) void i_rts (void) { i_new_instruction (IRTS,0,0); } # ifdef I486 void i_rts_i (int offset) { struct instruction *instruction; instruction=i_new_instruction (IRTSI,1,1*sizeof (struct parameter)); S2 (instruction->instruction_parameters[0], parameter_type=P_IMMEDIATE, parameter_data.imm=offset); } void i_rts_profile (void) { i_new_instruction (IRTSP,0,0); } # endif #else void i_rts (int offset_1,int offset_2) { struct instruction *instruction; instruction=i_new_instruction2 (IRTS); instruction->instruction_parameters[0].parameter_type=P_INDIRECT; instruction->instruction_parameters[0].parameter_offset=offset_1; instruction->instruction_parameters[0].parameter_data.i=B_STACK_POINTER; instruction->instruction_parameters[1].parameter_type=P_IMMEDIATE; instruction->instruction_parameters[1].parameter_data.imm=offset_2; } #endif #ifdef G_POWER void i_rts_c (void) { i_new_instruction (IRTS,0,0); } void i_rts_profile (int offset_1,int offset_2) { struct instruction *instruction; instruction=i_new_instruction2 (IRTSP); instruction->instruction_parameters[0].parameter_type=P_INDIRECT; instruction->instruction_parameters[0].parameter_offset=offset_1; instruction->instruction_parameters[0].parameter_data.i=B_STACK_POINTER; instruction->instruction_parameters[1].parameter_type=P_IMMEDIATE; instruction->instruction_parameters[1].parameter_data.imm=offset_2; } void i_rts_r (int register1,int offset_1) { struct instruction *instruction; instruction=i_new_instruction2 (IRTS); instruction->instruction_parameters[0].parameter_type=P_REGISTER; instruction->instruction_parameters[0].parameter_data.i=register1; instruction->instruction_parameters[1].parameter_type=P_IMMEDIATE; instruction->instruction_parameters[1].parameter_data.imm=offset_1; } void i_rts_r_profile (int register1,int offset_1) { struct instruction *instruction; instruction=i_new_instruction2 (IRTSP); instruction->instruction_parameters[0].parameter_type=P_REGISTER; instruction->instruction_parameters[0].parameter_data.i=register1; instruction->instruction_parameters[1].parameter_type=P_IMMEDIATE; instruction->instruction_parameters[1].parameter_data.imm=offset_1; } #endif void i_schedule_i (int value) { register struct instruction *instruction; instruction=i_new_instruction1 (ISCHEDULE); S2 (instruction->instruction_parameters[0], parameter_type=P_IMMEDIATE, parameter_data.imm=value); } void i_sub_i_r (LONG value,int register_1) { register struct instruction *instruction; instruction=i_new_instruction2 (ISUB); S2 (instruction->instruction_parameters[0], parameter_type=P_IMMEDIATE, parameter_data.imm=value); S2 (instruction->instruction_parameters[1], parameter_type=P_REGISTER, parameter_data.i=register_1); } #ifdef M68000 static void i_tstb_pi (int register_1) { register struct instruction *instruction; instruction=i_new_instruction1 (ITSTB); instruction->instruction_parameters[0].parameter_type=P_POST_INCREMENT; instruction->instruction_parameters[0].parameter_data.i=register_1; } #endif void i_tst_r (int register_1) { register struct instruction *instruction; instruction=i_new_instruction1 (ITST); S2 (instruction->instruction_parameters[0], parameter_type=P_REGISTER, parameter_data.i=register_1); } void i_word_i (int value) { struct instruction *instruction; instruction=i_new_instruction1 (IWORD); S2 (instruction->instruction_parameters[0], parameter_type=P_IMMEDIATE, parameter_data.imm=value); } #define N_VECTOR_BITS 32 struct register_list { ULONG r_l_vector; struct register_list *r_l_next; }; struct register_set { struct register_list r_s_list; UWORD r_s_first_free; UWORD r_s_highest; }; static struct register_set free_dregisters,free_aregisters,free_fregisters; void get_n_virtual_registers (int *n_virtual_a_regs_p,int *n_virtual_d_regs_p,int *n_virtual_f_regs_p) { *n_virtual_a_regs_p=free_aregisters.r_s_highest; *n_virtual_d_regs_p=free_dregisters.r_s_highest; *n_virtual_f_regs_p=free_fregisters.r_s_highest; } static int get_free_register_number (register struct register_set *r_s_p) { struct register_list *r_list; register unsigned int bit_n,reg_n; ULONG vector; reg_n=r_s_p->r_s_first_free; bit_n=reg_n; r_list=&r_s_p->r_s_list; while (bit_n>=N_VECTOR_BITS){ struct register_list *n_r_list; bit_n-=N_VECTOR_BITS; n_r_list=r_list->r_l_next; if (n_r_list==NULL){ n_r_list=(struct register_list*)fast_memory_allocate (sizeof (struct register_list)); n_r_list->r_l_next=NULL; r_list->r_l_next=n_r_list; } r_list=n_r_list; } vector=r_list->r_l_vector; while (reg_nr_s_highest){ if (bit_n==N_VECTOR_BITS){ bit_n=0; r_list=r_list->r_l_next; vector=r_list->r_l_vector; } if (vector & (1<r_l_vector &= ~(1<r_s_first_free=reg_n+1; return reg_n; } ++reg_n; ++bit_n; } if (bit_n==N_VECTOR_BITS){ r_list=r_list->r_l_next=(struct register_list*)fast_memory_allocate (sizeof (struct register_list)); r_list->r_l_next=NULL; bit_n=0; } r_s_p->r_s_highest=reg_n+1; r_s_p->r_s_first_free=reg_n+1; r_list->r_l_vector &= ~(1<r_s_first_free) r_s_p->r_s_first_free=reg_n; bit_n=reg_n; r_list=&r_s_p->r_s_list; while (bit_n>=N_VECTOR_BITS){ bit_n-=N_VECTOR_BITS; r_list=r_list->r_l_next; } r_list->r_l_vector |= (1<r_s_list; while (bit_n>=N_VECTOR_BITS){ bit_n-=N_VECTOR_BITS; r_list=r_list->r_l_next; } r_list->r_l_vector &= ~(1<=N_VECTOR_BITS){ bit_n-=N_VECTOR_BITS; r_list=r_list->r_l_next; } if (r_list->r_l_vector & (1<r_l_vector &= ~(1<r_l_vector; while (reg_nr_l_vector &= ~(1<=N_DATA_PARAMETER_REGISTERS) return -1; free_dregisters.r_s_highest=reg_n+1; r_list->r_l_vector &= ~(1<ad_mode){ case P_REGISTER: parameter_p->parameter_type=P_REGISTER; parameter_p->parameter_data.i=ad_p->ad_register; if (--*ad_p->ad_count_p==0) free_register (ad_p->ad_register); break; case P_IMMEDIATE: parameter_p->parameter_type=P_IMMEDIATE; parameter_p->parameter_data.imm=ad_p->ad_offset; break; case P_INDIRECT: parameter_p->parameter_type=P_INDIRECT; parameter_p->parameter_offset=ad_p->ad_offset; parameter_p->parameter_data.i=ad_p->ad_register; if (--*ad_p->ad_count_p==0) free_aregister (ad_p->ad_register); break; case P_DESCRIPTOR_NUMBER: parameter_p->parameter_type=P_DESCRIPTOR_NUMBER; parameter_p->parameter_offset=ad_p->ad_offset; parameter_p->parameter_data.l=ad_p->ad_label; break; case P_INDEXED: { struct index_registers *index_registers; INSTRUCTION_GRAPH load_x_graph; ADDRESS *i_ad_p; load_x_graph=ad_p->ad_load_x_graph; i_ad_p=(ADDRESS *)load_x_graph->instruction_parameters[1].p; if (load_x_graph->inode_arity & LOAD_X_TO_ADDRESS){ load_x_graph->inode_arity ^= (LOAD_X_TO_ADDRESS | LOAD_X_TO_REGISTER); if (i_ad_p->ad_mode==P_INDEXED){ index_registers=(struct index_registers*)fast_memory_allocate (sizeof (struct index_registers)); U3(parameter_p, parameter_type=P_INDEXED, parameter_offset=i_ad_p->ad_offset, parameter_data.ir=index_registers); index_registers->a_reg.r=i_ad_p->ad_areg; index_registers->d_reg.r=i_ad_p->ad_dreg; if (--*i_ad_p->ad_count_p==0) free_aregister (i_ad_p->ad_areg); if (--*i_ad_p->ad_count_p2==0) free_dregister (i_ad_p->ad_dreg); } else { U3(parameter_p, parameter_type=P_INDIRECT, parameter_offset=i_ad_p->ad_offset, parameter_data.i=i_ad_p->ad_register); if (--*i_ad_p->ad_count_p==0) free_aregister (i_ad_p->ad_register); } } else { U2(parameter_p,parameter_type=P_REGISTER,parameter_data.i=i_ad_p->ad_register); if (--*i_ad_p->ad_count_p==0) free_register (i_ad_p->ad_register); } break; } default: internal_error_in_function ("ad_to_parameter"); } } #if defined (FP_STACK_OPTIMIZATIONS) || defined (FMADD) #define FP_REG_LAST_USE 4 #endif static int fad_to_parameter_without_freeing_fregister (ADDRESS *ad_p,struct parameter *parameter_p) { switch (ad_p->ad_mode){ case P_F_REGISTER: set_float_register_parameter (*parameter_p,ad_p->ad_register); if (--*ad_p->ad_count_p==0) /* free_fregister (ad_p->ad_register); */ return 1; break; case P_F_IMMEDIATE: { DOUBLE *rp; parameter_p->parameter_type=P_F_IMMEDIATE; rp=(DOUBLE*)fast_memory_allocate (sizeof (DOUBLE)); parameter_p->parameter_data.r=rp; *rp=ad_p->ad_real; break; } case P_INDIRECT: parameter_p->parameter_type=P_INDIRECT; parameter_p->parameter_offset=ad_p->ad_offset; parameter_p->parameter_data.i=ad_p->ad_register; #ifdef ALIGN_REAL_ARRAYS parameter_p->parameter_flags=0; #endif if (--*ad_p->ad_count_p==0) free_aregister (ad_p->ad_register); break; case P_DESCRIPTOR_NUMBER: parameter_p->parameter_type=P_DESCRIPTOR_NUMBER; parameter_p->parameter_offset=ad_p->ad_offset; parameter_p->parameter_data.l=ad_p->ad_label; break; case P_INDEXED: { struct index_registers *index_registers; INSTRUCTION_GRAPH load_x_graph; ADDRESS *i_ad_p; load_x_graph=ad_p->ad_load_x_graph; i_ad_p=(ADDRESS *)load_x_graph->instruction_parameters[1].p; if (load_x_graph->inode_arity & LOAD_X_TO_ADDRESS){ load_x_graph->inode_arity ^= (LOAD_X_TO_ADDRESS | LOAD_X_TO_REGISTER); if (i_ad_p->ad_mode==P_INDEXED){ index_registers=(struct index_registers*)fast_memory_allocate (sizeof (struct index_registers)); U3(parameter_p, parameter_type=P_INDEXED, parameter_offset=i_ad_p->ad_offset, parameter_data.ir=index_registers); index_registers->a_reg.r=i_ad_p->ad_areg; index_registers->d_reg.r=i_ad_p->ad_dreg; if (--*i_ad_p->ad_count_p==0) free_aregister (i_ad_p->ad_areg); if (--*i_ad_p->ad_count_p2==0) free_dregister (i_ad_p->ad_dreg); } else { U3(parameter_p, parameter_type=P_INDIRECT, parameter_offset=i_ad_p->ad_offset, parameter_data.i=i_ad_p->ad_register); if (--*i_ad_p->ad_count_p==0) free_aregister (i_ad_p->ad_register); } #ifdef ALIGN_REAL_ARRAYS parameter_p->parameter_flags = load_x_graph->inode_arity & LOAD_STORE_ALIGNED_REAL; #endif } else { set_float_register_parameter (*parameter_p,i_ad_p->ad_register); if (--*i_ad_p->ad_count_p==0){ /* free_fregister (i_ad_p->ad_register);*/ return 1; } } break; } default: internal_error_in_function ("fad_to_parameter_without_freeing_fregister"); } return 0; } static void instruction_ad (int instruction_code,ADDRESS *ad_p) { struct instruction *instruction; instruction=i_new_instruction1 (instruction_code); ad_to_parameter (ad_p,&instruction->instruction_parameters[0]); } static void instruction_ad_id (int instruction_code,ADDRESS *ad_p,int offset,int register_1) { struct instruction *instruction; instruction=i_new_instruction2 (instruction_code); ad_to_parameter (ad_p,&instruction->instruction_parameters[0]); instruction->instruction_parameters[1].parameter_type=P_INDIRECT; instruction->instruction_parameters[1].parameter_offset=offset; instruction->instruction_parameters[1].parameter_data.i=register_1; } #ifdef G_POWER static void i_move_ad_idu (ADDRESS *ad_p,int offset,int register_1) { struct instruction *instruction; instruction=i_new_instruction2 (IMOVE); ad_to_parameter (ad_p,&instruction->instruction_parameters[0]); instruction->instruction_parameters[1].parameter_type=P_INDIRECT_WITH_UPDATE; instruction->instruction_parameters[1].parameter_offset=offset; instruction->instruction_parameters[1].parameter_data.i=register_1; } #endif #ifdef M68000 static void instruction_ad_pd (int instruction_code,ADDRESS *ad_p,int register_1) { register struct instruction *instruction; instruction=i_new_instruction2 (instruction_code); ad_to_parameter (ad_p,&instruction->instruction_parameters[0]); instruction->instruction_parameters[1].parameter_type=P_PRE_DECREMENT; instruction->instruction_parameters[1].parameter_data.i=register_1; } static void instruction_ad_pi (int instruction_code,ADDRESS *ad_p,int register_1) { register struct instruction *instruction; instruction=i_new_instruction2 (instruction_code); ad_to_parameter (ad_p,&instruction->instruction_parameters[0]); instruction->instruction_parameters[1].parameter_type=P_POST_INCREMENT; instruction->instruction_parameters[1].parameter_data.i=register_1; } #endif static void instruction_ad_r (int instruction_code,ADDRESS *ad_p,int register_1) { struct instruction *instruction; instruction=i_new_instruction2 (instruction_code); ad_to_parameter (ad_p,&instruction->instruction_parameters[0]); S2 (instruction->instruction_parameters[1], parameter_type=P_REGISTER, parameter_data.i=register_1); } static void instruction_i_ad (int instruction_code,LONG value,ADDRESS *ad_p) { struct instruction *instruction; instruction=i_new_instruction2 (instruction_code); S2 (instruction->instruction_parameters[0], parameter_type=P_IMMEDIATE, parameter_data.imm=value); ad_to_parameter (ad_p,&instruction->instruction_parameters[1]); } static void instruction_d_ad (int instruction_code,LABEL *label,int arity,ADDRESS *ad_p) { register struct instruction *instruction; instruction=i_new_instruction2 (instruction_code); instruction->instruction_parameters[0].parameter_type=P_DESCRIPTOR_NUMBER; instruction->instruction_parameters[0].parameter_data.l=label; instruction->instruction_parameters[0].parameter_offset=arity; ad_to_parameter (ad_p,&instruction->instruction_parameters[1]); } static void instruction_fr_fr (int instruction_code,int register_1,int register_2) { register struct instruction *instruction; instruction=i_new_instruction2 (instruction_code); set_float_register_parameter (instruction->instruction_parameters[0],register_1); set_float_register_parameter (instruction->instruction_parameters[1],register_2); } static void instruction_l (int instruction_code,LABEL *label) { struct instruction *instruction; instruction=i_new_instruction1 (instruction_code); instruction->instruction_parameters[0].parameter_type=P_LABEL; instruction->instruction_parameters[0].parameter_data.l=label; } static void instruction_ad_r_r (int instruction_code,ADDRESS *ad_p,int register_1,int register_2) { struct instruction *instruction; instruction=i_new_instruction (instruction_code,3,3*sizeof (struct parameter)); ad_to_parameter (ad_p,&instruction->instruction_parameters[0]); S2 (instruction->instruction_parameters[1], parameter_type=P_REGISTER, parameter_data.i=register_1); S2 (instruction->instruction_parameters[2], parameter_type=P_REGISTER, parameter_data.i=register_2); } static void instruction_r (int instruction_code,int register_1) { struct instruction *instruction; instruction=i_new_instruction1 (instruction_code); S2 (instruction->instruction_parameters[0], parameter_type=P_REGISTER, parameter_data.i=register_1); } #ifdef M68000 void instruction_pd (int instruction_code,int register_1) { register struct instruction *instruction; instruction=i_new_instruction1 (instruction_code); instruction->instruction_parameters[0].parameter_type=P_PRE_DECREMENT; instruction->instruction_parameters[0].parameter_data.i=register_1; } #endif static void instruction_ad_x (int instruction_code,ADDRESS *ad_p,int offset,int register_1,int register_2) { register struct instruction *instruction; register struct index_registers *index_registers; instruction=i_new_instruction (instruction_code,2,2*sizeof (struct parameter)+sizeof (struct index_registers)); index_registers=(struct index_registers *)&instruction->instruction_parameters[2]; ad_to_parameter (ad_p,&instruction->instruction_parameters[0]); instruction->instruction_parameters[1].parameter_type=P_INDEXED; instruction->instruction_parameters[1].parameter_offset=offset; instruction->instruction_parameters[1].parameter_data.ir=index_registers; index_registers->a_reg.r=register_1; index_registers->d_reg.r=register_2; } static void to_data_addressing_mode (ADDRESS *ad_p) { if (ad_p->ad_mode==P_REGISTER && is_a_register (ad_p->ad_register)){ int dreg; dreg=get_dregister(); i_move_r_r (ad_p->ad_register,dreg); if (--*ad_p->ad_count_p==0) free_aregister (ad_p->ad_register); ad_p->ad_mode=P_REGISTER; ad_p->ad_register=dreg; ad_p->ad_count_p=&ad_p->ad_count; ad_p->ad_count=1; } #ifdef G_A64 else if (ad_p->ad_mode==P_IMMEDIATE && ((int)ad_p->ad_offset)!=ad_p->ad_offset){ int dreg; dreg=get_dregister(); i_move_i_r (ad_p->ad_offset,dreg); ad_p->ad_mode=P_REGISTER; ad_p->ad_register=dreg; ad_p->ad_count_p=&ad_p->ad_count; ad_p->ad_count=1; } #endif } static void in_register (register ADDRESS *ad_p) { int dreg; switch (ad_p->ad_mode){ case P_REGISTER: return; case P_IMMEDIATE: dreg=get_dregister(); i_move_i_r (ad_p->ad_offset,dreg); break; case P_INDIRECT: if (--*ad_p->ad_count_p==0) free_aregister (ad_p->ad_register); dreg=get_dregister(); i_move_id_r (ad_p->ad_offset,ad_p->ad_register,dreg); break; case P_DESCRIPTOR_NUMBER: dreg=get_dregister(); i_move_d_r (ad_p->ad_label,ad_p->ad_offset,dreg); break; case P_INDEXED: { INSTRUCTION_GRAPH load_x_graph; ADDRESS *i_ad_p; load_x_graph=ad_p->ad_load_x_graph; i_ad_p=(ADDRESS *)load_x_graph->instruction_parameters[1].p; if (load_x_graph->inode_arity & LOAD_X_TO_ADDRESS){ load_x_graph->inode_arity ^= (LOAD_X_TO_ADDRESS | LOAD_X_TO_REGISTER); if (i_ad_p->ad_mode==P_INDEXED){ if (--*i_ad_p->ad_count_p==0) free_aregister (i_ad_p->ad_areg); if (--*i_ad_p->ad_count_p2==0) free_dregister (i_ad_p->ad_dreg); dreg=get_dregister(); i_move_x_r (i_ad_p->ad_offset,i_ad_p->ad_areg,i_ad_p->ad_dreg,dreg); } else { if (--*i_ad_p->ad_count_p==0) free_aregister (i_ad_p->ad_register); dreg=get_dregister(); i_move_id_r (i_ad_p->ad_offset,i_ad_p->ad_register,dreg); } i_ad_p->ad_register=dreg; } else { dreg=i_ad_p->ad_register; } break; } default: internal_error_in_function ("in_register"); return; } ad_p->ad_mode=P_REGISTER; ad_p->ad_register=dreg; ad_p->ad_count_p=&ad_p->ad_count; ad_p->ad_count=1; } static void in_data_register (register ADDRESS *ad_p) { int dreg; switch (ad_p->ad_mode){ case P_REGISTER: if (is_d_register (ad_p->ad_register)) return; dreg=get_dregister(); i_move_r_r (ad_p->ad_register,dreg); if (--*ad_p->ad_count_p==0) free_aregister (ad_p->ad_register); break; case P_IMMEDIATE: dreg=get_dregister(); i_move_i_r (ad_p->ad_offset,dreg); break; case P_INDIRECT: if (--*ad_p->ad_count_p==0) free_aregister (ad_p->ad_register); dreg=get_dregister(); i_move_id_r (ad_p->ad_offset,ad_p->ad_register,dreg); break; case P_DESCRIPTOR_NUMBER: dreg=get_dregister(); i_move_d_r (ad_p->ad_label,ad_p->ad_offset,dreg); break; case P_INDEXED: { INSTRUCTION_GRAPH load_x_graph; ADDRESS *i_ad_p; load_x_graph=ad_p->ad_load_x_graph; i_ad_p=(ADDRESS *)load_x_graph->instruction_parameters[1].p; if (load_x_graph->inode_arity & LOAD_X_TO_ADDRESS){ load_x_graph->inode_arity ^= (LOAD_X_TO_ADDRESS | LOAD_X_TO_REGISTER); if (i_ad_p->ad_mode==P_INDEXED){ if (--*i_ad_p->ad_count_p==0) free_aregister (i_ad_p->ad_areg); if (--*i_ad_p->ad_count_p2==0) free_dregister (i_ad_p->ad_dreg); dreg=get_dregister(); i_move_x_r (i_ad_p->ad_offset,i_ad_p->ad_areg,i_ad_p->ad_dreg,dreg); } else { if (--*i_ad_p->ad_count_p==0) free_aregister (i_ad_p->ad_register); dreg=get_dregister(); i_move_id_r (i_ad_p->ad_offset,i_ad_p->ad_register,dreg); } i_ad_p->ad_register=dreg; } else { dreg=i_ad_p->ad_register; if (!is_d_register (dreg)){ int areg; areg=dreg; dreg=get_dregister(); i_move_r_r (areg,dreg); if (--*i_ad_p->ad_count_p==0) free_aregister (areg); } } break; } default: internal_error_in_function ("in_data_register"); return; } ad_p->ad_mode=P_REGISTER; ad_p->ad_register=dreg; ad_p->ad_count_p=&ad_p->ad_count; ad_p->ad_count=1; } static void in_alterable_data_register (ADDRESS *ad_p) { int dreg; switch (ad_p->ad_mode){ case P_REGISTER: if (is_d_register (ad_p->ad_register)){ if (*ad_p->ad_count_p==1) return; dreg=get_dregister(); i_move_r_r (ad_p->ad_register,dreg); --*ad_p->ad_count_p; } else { dreg=get_dregister(); i_move_r_r (ad_p->ad_register,dreg); if (--*ad_p->ad_count_p==0) free_aregister (ad_p->ad_register); } break; case P_IMMEDIATE: dreg=get_dregister(); i_move_i_r (ad_p->ad_offset,dreg); break; case P_INDIRECT: if (--*ad_p->ad_count_p==0) free_aregister (ad_p->ad_register); dreg=get_dregister(); i_move_id_r (ad_p->ad_offset,ad_p->ad_register,dreg); break; case P_DESCRIPTOR_NUMBER: dreg=get_dregister(); i_move_d_r (ad_p->ad_label,ad_p->ad_offset,dreg); break; case P_INDEXED: { INSTRUCTION_GRAPH load_x_graph; ADDRESS *i_ad_p; load_x_graph=ad_p->ad_load_x_graph; i_ad_p=(ADDRESS *)load_x_graph->instruction_parameters[1].p; if (load_x_graph->inode_arity & LOAD_X_TO_ADDRESS){ load_x_graph->inode_arity ^= (LOAD_X_TO_ADDRESS | LOAD_X_TO_REGISTER); if (i_ad_p->ad_mode==P_INDEXED){ if (--*i_ad_p->ad_count_p==0) free_aregister (i_ad_p->ad_areg); if (--*i_ad_p->ad_count_p2==0) free_dregister (i_ad_p->ad_dreg); dreg=get_dregister(); i_move_x_r (i_ad_p->ad_offset,i_ad_p->ad_areg,i_ad_p->ad_dreg,dreg); } else { if (--*i_ad_p->ad_count_p==0) free_aregister (i_ad_p->ad_register); dreg=get_dregister(); i_move_id_r (i_ad_p->ad_offset,i_ad_p->ad_register,dreg); } i_ad_p->ad_register=dreg; } else { dreg=i_ad_p->ad_register; if (is_d_register (dreg)){ if (*i_ad_p->ad_count_p>1){ int old_dreg; old_dreg=dreg; dreg=get_dregister(); i_move_r_r (old_dreg,dreg); --*i_ad_p->ad_count_p; } } else { int areg; areg=dreg; dreg=get_dregister(); i_move_r_r (areg,dreg); if (--*i_ad_p->ad_count_p==0) free_aregister (areg); } } break; } default: internal_error_in_function ("in_alterable_data register"); return; } ad_p->ad_mode=P_REGISTER; ad_p->ad_register=dreg; ad_p->ad_count_p=&ad_p->ad_count; ad_p->ad_count=1; } #ifdef I486 static void in_preferred_alterable_register (ADDRESS *ad_p,int preferred_reg) { int dreg; switch (ad_p->ad_mode){ case P_REGISTER: if (*ad_p->ad_count_p==1) return; --*ad_p->ad_count_p; if (try_allocate_register_number (preferred_reg)) dreg=preferred_reg; else dreg=get_dregister(); i_move_r_r (ad_p->ad_register,dreg); break; case P_IMMEDIATE: if (try_allocate_register_number (preferred_reg)) dreg=preferred_reg; else dreg=get_dregister(); i_move_i_r (ad_p->ad_offset,dreg); break; case P_INDIRECT: if (--*ad_p->ad_count_p==0) free_aregister (ad_p->ad_register); if (try_allocate_register_number (preferred_reg)) dreg=preferred_reg; else dreg=get_dregister(); i_move_id_r (ad_p->ad_offset,ad_p->ad_register,dreg); break; case P_DESCRIPTOR_NUMBER: if (try_allocate_register_number (preferred_reg)) dreg=preferred_reg; else dreg=get_dregister(); i_move_d_r (ad_p->ad_label,ad_p->ad_offset,dreg); break; case P_INDEXED: { INSTRUCTION_GRAPH load_x_graph; ADDRESS *i_ad_p; load_x_graph=ad_p->ad_load_x_graph; i_ad_p=(ADDRESS *)load_x_graph->instruction_parameters[1].p; if (load_x_graph->inode_arity & LOAD_X_TO_ADDRESS){ load_x_graph->inode_arity ^= (LOAD_X_TO_ADDRESS | LOAD_X_TO_REGISTER); if (i_ad_p->ad_mode==P_INDEXED){ if (--*i_ad_p->ad_count_p==0) free_aregister (i_ad_p->ad_areg); if (--*i_ad_p->ad_count_p2==0) free_dregister (i_ad_p->ad_dreg); if (try_allocate_register_number (preferred_reg)) dreg=preferred_reg; else dreg=get_dregister(); i_move_x_r (i_ad_p->ad_offset,i_ad_p->ad_areg,i_ad_p->ad_dreg,dreg); } else { if (--*i_ad_p->ad_count_p==0) free_aregister (i_ad_p->ad_register); if (try_allocate_register_number (preferred_reg)) dreg=preferred_reg; else dreg=get_dregister(); i_move_id_r (i_ad_p->ad_offset,i_ad_p->ad_register,dreg); } i_ad_p->ad_register=dreg; } else { dreg=i_ad_p->ad_register; if (is_d_register (dreg)){ if (*i_ad_p->ad_count_p>1){ int old_dreg; old_dreg=dreg; if (try_allocate_register_number (preferred_reg)) dreg=preferred_reg; else dreg=get_dregister(); i_move_r_r (old_dreg,dreg); --*i_ad_p->ad_count_p; } } else { int areg; areg=dreg; if (try_allocate_register_number (preferred_reg)) dreg=preferred_reg; else dreg=get_dregister(); i_move_r_r (areg,dreg); if (--*i_ad_p->ad_count_p==0) free_aregister (areg); } } break; } default: internal_error_in_function ("in_alterable_data register"); return; } ad_p->ad_mode=P_REGISTER; ad_p->ad_register=dreg; ad_p->ad_count_p=&ad_p->ad_count; ad_p->ad_count=1; } #endif static void in_address_register (register ADDRESS *ad_p) { int areg; switch (ad_p->ad_mode){ case P_REGISTER: if (is_a_register (ad_p->ad_register)) return; areg=get_aregister(); i_move_r_r (ad_p->ad_register,areg); if (--*ad_p->ad_count_p==0) free_dregister (ad_p->ad_register); break; case P_IMMEDIATE: areg=get_aregister(); i_move_i_r (ad_p->ad_offset,areg); break; case P_INDIRECT: if (--*ad_p->ad_count_p==0) free_aregister (ad_p->ad_register); areg=get_aregister(); i_move_id_r (ad_p->ad_offset,ad_p->ad_register,areg); break; case P_DESCRIPTOR_NUMBER: areg=get_aregister(); i_move_d_r (ad_p->ad_label,ad_p->ad_offset,areg); break; case P_INDEXED: { INSTRUCTION_GRAPH load_x_graph; ADDRESS *i_ad_p; load_x_graph=ad_p->ad_load_x_graph; i_ad_p=(ADDRESS *)load_x_graph->instruction_parameters[1].p; if (load_x_graph->inode_arity & LOAD_X_TO_ADDRESS){ load_x_graph->inode_arity ^= (LOAD_X_TO_ADDRESS | LOAD_X_TO_REGISTER); if (i_ad_p->ad_mode==P_INDEXED){ if (--*i_ad_p->ad_count_p==0) free_aregister (i_ad_p->ad_areg); if (--*i_ad_p->ad_count_p2==0) free_dregister (i_ad_p->ad_dreg); areg=get_aregister(); i_move_x_r (i_ad_p->ad_offset,i_ad_p->ad_areg,i_ad_p->ad_dreg,areg); } else { if (--*i_ad_p->ad_count_p==0) free_aregister (i_ad_p->ad_register); areg=get_aregister(); i_move_id_r (i_ad_p->ad_offset,i_ad_p->ad_register,areg); } i_ad_p->ad_register=areg; } else { areg=i_ad_p->ad_register; if (!is_a_register (areg)){ int dreg; dreg=areg; areg=get_aregister(); i_move_r_r (dreg,areg); if (--*i_ad_p->ad_count_p==0) free_dregister (dreg); } } break; } default: internal_error_in_function ("in_address_register"); return; } ad_p->ad_mode=P_REGISTER; ad_p->ad_register=areg; ad_p->ad_count_p=&ad_p->ad_count; ad_p->ad_count=1; } static void in_alterable_address_register (register ADDRESS *ad_p) { int areg; switch (ad_p->ad_mode){ case P_REGISTER: if (is_a_register (ad_p->ad_register)){ if (*ad_p->ad_count_p==1) return; areg=get_aregister(); i_move_r_r (ad_p->ad_register,areg); --*ad_p->ad_count_p; } else { areg=get_aregister(); i_move_r_r (ad_p->ad_register,areg); if (--*ad_p->ad_count_p==0) free_dregister (ad_p->ad_register); } break; case P_IMMEDIATE: areg=get_aregister(); i_move_i_r (ad_p->ad_offset,areg); break; case P_INDIRECT: if (--*ad_p->ad_count_p==0) free_aregister (ad_p->ad_register); areg=get_aregister(); i_move_id_r (ad_p->ad_offset,ad_p->ad_register,areg); break; case P_DESCRIPTOR_NUMBER: areg=get_aregister(); i_move_d_r (ad_p->ad_label,ad_p->ad_offset,areg); break; case P_INDEXED: { INSTRUCTION_GRAPH load_x_graph; ADDRESS *i_ad_p; load_x_graph=ad_p->ad_load_x_graph; i_ad_p=(ADDRESS *)load_x_graph->instruction_parameters[1].p; if (load_x_graph->inode_arity & LOAD_X_TO_ADDRESS){ load_x_graph->inode_arity ^= (LOAD_X_TO_ADDRESS | LOAD_X_TO_REGISTER); if (i_ad_p->ad_mode==P_INDEXED){ if (--*i_ad_p->ad_count_p==0) free_aregister (i_ad_p->ad_areg); if (--*i_ad_p->ad_count_p2==0) free_dregister (i_ad_p->ad_dreg); areg=get_aregister(); i_move_x_r (i_ad_p->ad_offset,i_ad_p->ad_areg,i_ad_p->ad_dreg,areg); } else { if (--*i_ad_p->ad_count_p==0) free_aregister (i_ad_p->ad_register); areg=get_aregister(); i_move_id_r (i_ad_p->ad_offset,i_ad_p->ad_register,areg); } i_ad_p->ad_register=areg; } else { areg=i_ad_p->ad_register; if (is_a_register (areg)){ if (*i_ad_p->ad_count_p>1){ int old_areg; old_areg=areg; areg=get_aregister(); i_move_r_r (old_areg,areg); --*i_ad_p->ad_count_p; } } else { int dreg; dreg=areg; areg=get_aregister(); i_move_r_r (dreg,areg); if (--*i_ad_p->ad_count_p==0) free_dregister (dreg); } } break; } default: internal_error_in_function ("in_alterable_address_register"); return; } ad_p->ad_mode=P_REGISTER; ad_p->ad_register=areg; ad_p->ad_count_p=&ad_p->ad_count; ad_p->ad_count=1; } static void register_node (INSTRUCTION_GRAPH graph,int reg) { graph->instruction_code=GREGISTER; graph->instruction_parameters[0].i=reg; if ((unsigned)a_reg_num (reg)<(unsigned)N_ADDRESS_PARAMETER_REGISTERS) global_block.block_graph_a_register_parameter_node[a_reg_num (reg)]=graph; if ((unsigned)d_reg_num (reg)<(unsigned)N_DATA_PARAMETER_REGISTERS #ifdef MORE_PARAMETER_REGISTERS + N_ADDRESS_PARAMETER_REGISTERS #endif ) global_block.block_graph_d_register_parameter_node[d_reg_num (reg)]=graph; } static void float_register_node (register INSTRUCTION_GRAPH graph,int reg) { graph->instruction_code=GFREGISTER; graph->instruction_parameters[0].i=reg; if ((unsigned)reg<(unsigned)N_FLOAT_PARAMETER_REGISTERS) global_block.block_graph_f_register_parameter_node [reg]=graph; } static void linearize_graph (INSTRUCTION_GRAPH,ADDRESS *); #if defined (G_POWER) # define SMALL_IMMEDIATE(i) (((short int)i)==((int)i)) #endif #if defined (sparc) # define SMALL_IMMEDIATE(i) ((int)i<4096 && (int)i>=-4095) #endif static void linearize_dyadic_commutative_operator (int i_instruction_code,INSTRUCTION_GRAPH graph,ADDRESS *ad_p) { INSTRUCTION_GRAPH graph_1,graph_2; ADDRESS ad_1,ad_2; int reg_1; graph_1=graph->instruction_parameters[0].p; graph_2=graph->instruction_parameters[1].p; if (graph->order_left){ linearize_graph (graph_1,&ad_1); linearize_graph (graph_2,&ad_2); } else { linearize_graph (graph_2,&ad_2); linearize_graph (graph_1,&ad_1); } if (graph->instruction_d_min_a_cost<=0){ if (ad_1.ad_mode==P_REGISTER && is_d_register (ad_1.ad_register) && *ad_1.ad_count_p<=1 && !(ad_2.ad_mode==P_REGISTER && is_d_register (ad_2.ad_register) && *ad_2.ad_count_p<=1)) { instruction_ad_r (i_instruction_code,&ad_2,ad_1.ad_register); --*ad_1.ad_count_p; reg_1=ad_1.ad_register; } else { #ifndef M68000 /* optimization added 18-8-1998 */ if (ad_2.ad_mode==P_IMMEDIATE){ # if defined (G_POWER) || defined (sparc) if (ad_1.ad_mode==P_REGISTER && SMALL_IMMEDIATE (ad_2.ad_offset) && i_instruction_code==IADD){ if (--*ad_1.ad_count_p==0) free_register (ad_1.ad_register); reg_1=get_dregister(); i_addi_r_r (ad_2.ad_offset,ad_1.ad_register,reg_1); } else # endif { in_alterable_data_register (&ad_1); instruction_ad_r (i_instruction_code,&ad_2,ad_1.ad_register); --*ad_1.ad_count_p; reg_1=ad_1.ad_register; } } else { #endif #if defined (G_POWER) || defined (sparc) if (ad_1.ad_mode==P_IMMEDIATE && ad_2.ad_mode==P_REGISTER && SMALL_IMMEDIATE (ad_1.ad_offset) && i_instruction_code==IADD){ if (--*ad_2.ad_count_p==0) free_register (ad_2.ad_register); reg_1=get_dregister(); i_addi_r_r (ad_1.ad_offset,ad_2.ad_register,reg_1); } else #endif { #if 1 /* optimization added 9-1-2000 */ if (! (ad_1.ad_mode==P_REGISTER && ad_2.ad_mode==P_REGISTER && ad_1.ad_register==ad_2.ad_register && is_d_register (ad_1.ad_register) && *ad_1.ad_count_p==2 && ad_1.ad_count_p==ad_2.ad_count_p)) #endif in_alterable_data_register (&ad_2); instruction_ad_r (i_instruction_code,&ad_1,ad_2.ad_register); --*ad_2.ad_count_p; reg_1=ad_2.ad_register; } #ifndef M68000 } #endif } } else { # if defined (G_POWER) || defined (sparc) if (ad_1.ad_mode==P_IMMEDIATE && ad_2.ad_mode==P_REGISTER && SMALL_IMMEDIATE (ad_1.ad_offset) && i_instruction_code==IADD){ if (--*ad_2.ad_count_p==0) free_register (ad_2.ad_register); reg_1=get_aregister(); i_addi_r_r (ad_1.ad_offset,ad_2.ad_register,reg_1); } else if (ad_2.ad_mode==P_IMMEDIATE && ad_1.ad_mode==P_REGISTER && SMALL_IMMEDIATE (ad_2.ad_offset) && i_instruction_code==IADD){ if (--*ad_1.ad_count_p==0) free_register (ad_1.ad_register); reg_1=get_aregister(); i_addi_r_r (ad_2.ad_offset,ad_1.ad_register,reg_1); } else # endif if ((ad_1.ad_mode==P_REGISTER || ad_1.ad_mode==P_INDIRECT) && is_a_register (ad_1.ad_register) && *ad_1.ad_count_p<=1) { in_alterable_address_register (&ad_1); instruction_ad_r (i_instruction_code,&ad_2,ad_1.ad_register); --*ad_1.ad_count_p; reg_1=ad_1.ad_register; } else { in_alterable_address_register (&ad_2); instruction_ad_r (i_instruction_code,&ad_1,ad_2.ad_register); --*ad_2.ad_count_p; reg_1=ad_2.ad_register; } } ad_p->ad_mode=P_REGISTER; ad_p->ad_register=reg_1; ad_p->ad_count_p=&graph->node_count; if (*ad_p->ad_count_p>1) register_node (graph,reg_1); } static void linearize_dyadic_commutative_data_operator (int i_instruction_code,INSTRUCTION_GRAPH graph,ADDRESS *ad_p) { INSTRUCTION_GRAPH graph_1,graph_2; ADDRESS ad_1,ad_2; int reg_1; graph_1=graph->instruction_parameters[0].p; graph_2=graph->instruction_parameters[1].p; if (graph->order_left){ linearize_graph (graph_1,&ad_1); linearize_graph (graph_2,&ad_2); } else { linearize_graph (graph_2,&ad_2); linearize_graph (graph_1,&ad_1); } if (ad_1.ad_mode==P_REGISTER && (is_a_register (ad_1.ad_register) || *ad_1.ad_count_p<=1) && !(ad_2.ad_mode==P_REGISTER && is_d_register (ad_2.ad_register) && *ad_2.ad_count_p<=1)) { in_alterable_data_register (&ad_1); to_data_addressing_mode (&ad_2); instruction_ad_r (i_instruction_code,&ad_2,ad_1.ad_register); --*ad_1.ad_count_p; reg_1=ad_1.ad_register; } else { in_alterable_data_register (&ad_2); to_data_addressing_mode (&ad_1); instruction_ad_r (i_instruction_code,&ad_1,ad_2.ad_register); --*ad_2.ad_count_p; reg_1=ad_2.ad_register; } if (graph->instruction_d_min_a_cost>0){ int areg; areg=get_aregister(); i_move_r_r (reg_1,areg); free_dregister (reg_1); reg_1=areg; } ad_p->ad_mode=P_REGISTER; ad_p->ad_register=reg_1; ad_p->ad_count_p=&graph->node_count; if (*ad_p->ad_count_p>1) register_node (graph,reg_1); } #ifdef M68000 static void linearize_eor_operator (INSTRUCTION_GRAPH graph,ADDRESS *ad_p) { register INSTRUCTION_GRAPH graph_1,graph_2; ADDRESS ad_1,ad_2; int reg_1; graph_1=graph->instruction_parameters[0].p; graph_2=graph->instruction_parameters[1].p; if (graph->order_left){ linearize_graph (graph_1,&ad_1); linearize_graph (graph_2,&ad_2); } else { linearize_graph (graph_2,&ad_2); linearize_graph (graph_1,&ad_1); } in_alterable_data_register (&ad_2); if (ad_1.ad_mode!=P_IMMEDIATE) in_data_register (&ad_1); instruction_ad_r (IEOR,&ad_1,ad_2.ad_register); --*ad_2.ad_count_p; reg_1=ad_2.ad_register; if (graph->instruction_d_min_a_cost>0){ int areg; areg=get_aregister(); i_move_r_r (reg_1,areg); free_dregister (reg_1); reg_1=areg; } ad_p->ad_mode=P_REGISTER; ad_p->ad_register=reg_1; ad_p->ad_count_p=&graph->node_count; if (*ad_p->ad_count_p>1) register_node (graph,reg_1); } #endif static int compare_node (INSTRUCTION_GRAPH graph,int i_test_1,int i_test_2) { INSTRUCTION_GRAPH graph_1,graph_2; ADDRESS ad_1,ad_2; int mode_1,mode_2; graph_1=graph->instruction_parameters[0].p; graph_2=graph->instruction_parameters[1].p; #ifdef M68000 if (graph_1->instruction_code==GLOAD_DES_ID && graph_1->node_count==1 && graph_2->instruction_code==GLOAD_DES_I && graph_2->node_count==1) { linearize_graph (graph_1->instruction_parameters[1].p,&ad_1); in_address_register (&ad_1); if (--*ad_1.ad_count_p==0) free_aregister (ad_1.ad_register); i_cmpw_d_id (graph_2->instruction_parameters[0].l,graph_2->instruction_parameters[1].i, graph_1->instruction_parameters[0].i,ad_1.ad_register); return i_test_2; } if (graph_2->instruction_code==GLOAD_DES_ID && graph_2->node_count==1 && graph_1->instruction_code==GLOAD_DES_I && graph_1->node_count==1) { linearize_graph (graph_2->instruction_parameters[1].p,&ad_1); in_address_register (&ad_1); if (--*ad_1.ad_count_p==0) free_aregister (ad_1.ad_register); i_cmpw_d_id (graph_1->instruction_parameters[0].l, graph_1->instruction_parameters[1].i, graph_2->instruction_parameters[0].i,ad_1.ad_register); return i_test_1; } #endif if (graph->order_left){ linearize_graph (graph_1,&ad_1); linearize_graph (graph_2,&ad_2); } else { linearize_graph (graph_2,&ad_2); linearize_graph (graph_1,&ad_1); } mode_1=ad_1.ad_mode; mode_2=ad_2.ad_mode; if (mode_1==P_IMMEDIATE && ! (mode_2==P_IMMEDIATE || mode_2==P_DESCRIPTOR_NUMBER)){ LONG i; #ifdef M68000 int real_dreg_number; #endif i=ad_1.ad_offset; #ifdef M68000 if (i<128 && i>=-128 && i!=0 && (real_dreg_number=try_get_real_dregister_number())>=0){ int dreg; dreg=num_to_d_reg (real_dreg_number); i_move_i_r (i,dreg); instruction_ad_r (ICMP,&ad_2,dreg); free_dregister (dreg); return i_test_2; } else { #endif instruction_i_ad (ICMP,i,&ad_2); return i_test_1; #ifdef M68000 } #endif } else if (mode_1==P_DESCRIPTOR_NUMBER && ! (mode_2==P_IMMEDIATE || mode_2==P_DESCRIPTOR_NUMBER)){ instruction_d_ad (ICMP,ad_1.ad_label,ad_1.ad_offset,&ad_2); return i_test_1; } else if (mode_2==P_IMMEDIATE && ! (mode_1==P_IMMEDIATE || mode_1==P_DESCRIPTOR_NUMBER)){ LONG i; #ifdef M68000 int real_dreg_number; #endif i=ad_2.ad_offset; #ifdef M68000 if (i<128 && i>=-128 && i!=0 && (real_dreg_number=try_get_real_dregister_number())>=0){ int dreg; dreg=num_to_d_reg (real_dreg_number); i_move_i_r (i,dreg); instruction_ad_r (ICMP,&ad_1,dreg); free_dregister (dreg); return i_test_1; } else { #endif instruction_i_ad (ICMP,i,&ad_1); return i_test_2; #ifdef M68000 } #endif } else if (mode_2==P_DESCRIPTOR_NUMBER && ! (mode_1==P_IMMEDIATE || mode_1==P_DESCRIPTOR_NUMBER)){ instruction_d_ad (ICMP,ad_2.ad_label,ad_2.ad_offset,&ad_1); return i_test_2; } else if (mode_2==P_REGISTER || (mode_1!=P_REGISTER && mode_2==P_INDIRECT && *ad_2.ad_count_p==1)){ in_register (&ad_2); instruction_ad_r (ICMP,&ad_1,ad_2.ad_register); if (--*ad_2.ad_count_p==0) free_register (ad_2.ad_register); return i_test_1; } else { in_register (&ad_1); instruction_ad_r (ICMP,&ad_2,ad_1.ad_register); if (--*ad_1.ad_count_p==0) free_register (ad_1.ad_register); return i_test_2; } } enum { CEQ, CNE, CGT, CLT, CGE, CLE, CO, CNO, CGTU, CLTU, CGEU, CLEU, CFEQ, CFNE, CFGT, CFLT, CFGE, CFLE }; #define is_float_condition(c) ((c)>=CFEQ) int condition_to_set_instruction[]= { ISEQ, ISNE, ISGT, ISLT, ISGE, ISLE, ISO, ISNO, ISGTU, ISLTU, ISGEU, ISLEU, IFSEQ, IFSNE, IFSGT, IFSLT, IFSGE, IFSLE }; static int condition_to_branch_false_instruction[]= { IBNE, IBEQ, IBLE, IBGE, IBLT, IBGT, IBNO, IBO, IBLEU, IBGEU, IBLTU, IBGTU, #if defined (I486) && !defined (G_A64) IFCNE, IFCEQ, IFCLE, IFCGE, IFCLT, IFCGT #else IFBNE, IFBEQ, IFBLE, IFBGE, IFBLT, IFBGT #endif }; static int condition_to_branch_true_instruction[]= { IBEQ, IBNE, IBGT, IBLT, IBGE, IBLE, IBO, IBNO, IBGTU, IBLTU, IBGEU, IBLEU, #if defined (I486) && !defined (G_A64) IFCEQ, IFCNE, IFCGT, IFCLT, IFCGE, IFCLE #else IFBEQ, IFBNE, IFBGT, IFBLT, IFBGE, IFBLE #endif }; static void save_condition (INSTRUCTION_GRAPH graph,int condition) { int reg_1; reg_1=get_dregister(); instruction_r (condition_to_set_instruction[condition],reg_1); if (graph->instruction_d_min_a_cost>0){ int areg; areg=get_aregister(); i_move_r_r (reg_1,areg); reg_1=areg; } register_node (graph,reg_1); --graph->node_count; } static int float_compare_node (INSTRUCTION_GRAPH graph,int condition_1,int condition_2); static int linearize_not_condition (INSTRUCTION_GRAPH graph); static int linearize_condition (INSTRUCTION_GRAPH graph) { int condition; switch (graph->instruction_code){ case GCMP_EQ: condition=compare_node (graph,CEQ,CEQ); break; case GCMP_LT: condition=compare_node (graph,CLT,CGT); break; case GCMP_LTU: condition=compare_node (graph,CLTU,CGTU); break; case GCMP_GT: condition=compare_node (graph,CGT,CLT); break; case GCMP_GTU: condition=compare_node (graph,CGTU,CLTU); break; case GFCMP_EQ: condition=float_compare_node (graph,CFEQ,CFEQ); break; case GFCMP_LT: condition=float_compare_node (graph,CFLT,CFGT); break; case GFCMP_GT: condition=float_compare_node (graph,CFGT,CFLT); break; case GCNOT: condition=linearize_not_condition (graph->instruction_parameters[0].p); break; case GTEST_O: if (graph->node_count==0){ #ifdef sparc if (graph->inode_arity==0) return CNE; else #endif return CO; } /* else default */ default: { ADDRESS ad_1; linearize_graph (graph,&ad_1); if (ad_1.ad_mode==P_REGISTER && is_a_register (ad_1.ad_register)){ /* TST.L An is an illegal instruction, use CMP.L #0,An */ i_cmp_i_r (0,ad_1.ad_register); if (--*ad_1.ad_count_p==0) free_aregister (ad_1.ad_register); } else { if (ad_1.ad_mode==P_IMMEDIATE) /* TST #d is an illegal instruction */ in_data_register (&ad_1); instruction_ad (ITST,&ad_1); } return CNE; } } if (graph->node_count>1){ save_condition (graph,condition); condition=CNE; } return condition; } static int linearize_not_condition (INSTRUCTION_GRAPH graph) { int condition; switch (graph->instruction_code){ case GCMP_EQ: condition=compare_node (graph,CNE,CNE); break; case GCMP_LT: condition=compare_node (graph,CGE,CLE); break; case GCMP_LTU: condition=compare_node (graph,CGEU,CLEU); break; case GCMP_GT: condition=compare_node (graph,CLE,CGE); break; case GCMP_GTU: condition=compare_node (graph,CLEU,CGEU); break; case GFCMP_EQ: condition=float_compare_node (graph,CFNE,CFNE); break; case GFCMP_LT: condition=float_compare_node (graph,CFGE,CFLE); break; case GFCMP_GT: condition=float_compare_node (graph,CFLE,CFGE); break; case GCNOT: condition=linearize_condition (graph->instruction_parameters[0].p); break; case GTEST_O: if (graph->node_count==0){ #ifdef sparc if (graph->inode_arity==0) return CEQ; else #endif return CNO; } /* else default */ default: { ADDRESS ad_1; linearize_graph (graph,&ad_1); if (ad_1.ad_mode==P_REGISTER && is_a_register (ad_1.ad_register)){ /* TST.L An is an illegal instruction, use CMP.L #0,An */ /* (MOVE.L An,Dn would be faster */ i_cmp_i_r (0,ad_1.ad_register); if (--*ad_1.ad_count_p==0) free_aregister (ad_1.ad_register); } else { if (ad_1.ad_mode==P_IMMEDIATE) /* TST #d is an illegal instruction */ in_data_register (&ad_1); instruction_ad (ITST,&ad_1); } return CEQ; } } if (graph->node_count>1){ save_condition (graph,condition); condition=CEQ; } return condition; } static void condition_to_register (INSTRUCTION_GRAPH graph,int condition,ADDRESS *ad_p) { int reg_1; reg_1=get_dregister(); instruction_r (condition_to_set_instruction[condition],reg_1); if (graph->instruction_d_min_a_cost>0){ int areg; areg=get_aregister(); i_move_r_r (reg_1,areg); reg_1=areg; } ad_p->ad_mode=P_REGISTER; ad_p->ad_register=reg_1; ad_p->ad_count_p=&graph->node_count; if (*ad_p->ad_count_p>1) register_node (graph,reg_1); } static void linearize_compare_operator (int i_test_1,int i_test_2,INSTRUCTION_GRAPH graph,ADDRESS *ad_p) { int condition; condition=compare_node (graph,i_test_1,i_test_2); condition_to_register (graph,condition,ad_p); } static void linearize_dyadic_non_commutative_operator (int i_instruction_code,INSTRUCTION_GRAPH graph,ADDRESS *ad_p) { INSTRUCTION_GRAPH graph_1,graph_2; ADDRESS ad_1,ad_2; graph_1=graph->instruction_parameters[0].p; graph_2=graph->instruction_parameters[1].p; if (graph->order_left){ linearize_graph (graph_1,&ad_1); linearize_graph (graph_2,&ad_2); } else { linearize_graph (graph_2,&ad_2); linearize_graph (graph_1,&ad_1); } # if defined (G_POWER) || defined (sparc) if (ad_1.ad_mode==P_IMMEDIATE && ad_2.ad_mode==P_REGISTER && SMALL_IMMEDIATE (-ad_1.ad_offset) && i_instruction_code==ISUB){ int reg_1; if (--*ad_2.ad_count_p==0) free_register (ad_2.ad_register); if (graph->instruction_d_min_a_cost<=0) reg_1=get_dregister(); else reg_1=get_aregister(); i_addi_r_r (-ad_1.ad_offset,ad_2.ad_register,reg_1); ad_p->ad_mode=P_REGISTER; ad_p->ad_register=reg_1; ad_p->ad_count_p=&graph->node_count; if (*ad_p->ad_count_p>1) register_node (graph,reg_1); return; } # endif if (graph->instruction_d_min_a_cost<=0) in_alterable_data_register (&ad_2); else in_alterable_address_register (&ad_2); instruction_ad_r (i_instruction_code,&ad_1,ad_2.ad_register); --*ad_2.ad_count_p; ad_p->ad_mode=P_REGISTER; ad_p->ad_register=ad_2.ad_register; ad_p->ad_count_p=&graph->node_count; if (*ad_p->ad_count_p>1) register_node (graph,ad_p->ad_register); } static void linearize_dyadic_non_commutative_data_operator (int i_instruction_code,INSTRUCTION_GRAPH graph,ADDRESS *ad_p) { register INSTRUCTION_GRAPH graph_1,graph_2; ADDRESS ad_1,ad_2; int reg_1; graph_1=graph->instruction_parameters[0].p; graph_2=graph->instruction_parameters[1].p; if (graph->order_left){ linearize_graph (graph_1,&ad_1); linearize_graph (graph_2,&ad_2); } else { linearize_graph (graph_2,&ad_2); linearize_graph (graph_1,&ad_1); } in_alterable_data_register (&ad_2); to_data_addressing_mode (&ad_1); instruction_ad_r (i_instruction_code,&ad_1,ad_2.ad_register); --*ad_2.ad_count_p; reg_1=ad_2.ad_register; if (graph->instruction_d_min_a_cost>0){ int areg; areg=get_aregister(); i_move_r_r (reg_1,areg); free_dregister (reg_1); reg_1=areg; } ad_p->ad_mode=P_REGISTER; ad_p->ad_register=reg_1; ad_p->ad_count_p=&graph->node_count; if (*ad_p->ad_count_p>1) register_node (graph,reg_1); } static void linearize_monadic_data_operator (int i_instruction_code,INSTRUCTION_GRAPH graph,ADDRESS *ad_p) { INSTRUCTION_GRAPH graph_1; ADDRESS ad_1; int reg_1; graph_1=graph->instruction_parameters[0].p; linearize_graph (graph_1,&ad_1); in_alterable_data_register (&ad_1); reg_1=ad_1.ad_register; instruction_r (i_instruction_code,reg_1); if (graph->instruction_d_min_a_cost>0){ int areg; areg=get_aregister(); i_move_r_r (reg_1,areg); free_dregister (reg_1); reg_1=areg; } ad_p->ad_mode=P_REGISTER; ad_p->ad_register=reg_1; ad_p->ad_count_p=&graph->node_count; if (*ad_p->ad_count_p>1) register_node (graph,reg_1); } #if defined (I486) || defined (G_POWER) static void linearize_div_rem_operator (int i_instruction_code,INSTRUCTION_GRAPH graph,ADDRESS *ad_p) { INSTRUCTION_GRAPH graph_1,graph_2; ADDRESS ad_1,ad_2; int reg_1; graph_1=graph->instruction_parameters[0].p; graph_2=graph->instruction_parameters[1].p; if (graph->order_left){ linearize_graph (graph_1,&ad_1); linearize_graph (graph_2,&ad_2); } else { linearize_graph (graph_2,&ad_2); linearize_graph (graph_1,&ad_1); } in_alterable_data_register (&ad_2); to_data_addressing_mode (&ad_1); # ifdef I486 if (ad_1.ad_mode==P_IMMEDIATE){ if (i_instruction_code==IDIVU || i_instruction_code==IREMU){ in_data_register (&ad_1); instruction_ad_r (i_instruction_code,&ad_1,ad_2.ad_register); } else { int i; i=ad_1.ad_offset; if (i_instruction_code==IMOD && i<0 && i!=0x80000000) i=-i; if ((i & (i-1))==0 && (i_instruction_code==IMOD ? i>1 : i>0)) instruction_ad_r (i_instruction_code,&ad_1,ad_2.ad_register); else if (i>1 || (i<-1 && i!=0x80000000)){ int tmp_reg; tmp_reg=get_dregister(); instruction_ad_r_r (i_instruction_code==IDIV ? IDIVI : IREMI,&ad_1,ad_2.ad_register,tmp_reg); free_dregister (tmp_reg); } else { in_data_register (&ad_1); instruction_ad_r (i_instruction_code,&ad_1,ad_2.ad_register); } } } else { if (ad_1.ad_mode==P_INDEXED) in_data_register (&ad_1); instruction_ad_r (i_instruction_code,&ad_1,ad_2.ad_register); } # else instruction_ad_r (i_instruction_code,&ad_1,ad_2.ad_register); # endif --*ad_2.ad_count_p; reg_1=ad_2.ad_register; if (graph->instruction_d_min_a_cost>0){ int areg; areg=get_aregister(); i_move_r_r (reg_1,areg); free_dregister (reg_1); reg_1=areg; } ad_p->ad_mode=P_REGISTER; ad_p->ad_register=reg_1; ad_p->ad_count_p=&graph->node_count; if (*ad_p->ad_count_p>1) register_node (graph,reg_1); } #else static void linearize_mod_operator (int i_instruction_code,INSTRUCTION_GRAPH graph,ADDRESS *ad_p) { register INSTRUCTION_GRAPH graph_1,graph_2; ADDRESS ad_1,ad_2; int reg_1; graph_1=graph->instruction_parameters[0].p; graph_2=graph->instruction_parameters[1].p; if (graph->order_left){ linearize_graph (graph_1,&ad_1); linearize_graph (graph_2,&ad_2); } else { linearize_graph (graph_2,&ad_2); linearize_graph (graph_1,&ad_1); } in_alterable_data_register (&ad_2); to_data_addressing_mode (&ad_1); if (ad_1.ad_mode==P_INDEXED) in_data_register (&ad_1); if (ad_1.ad_mode==P_REGISTER && is_d_register (ad_1.ad_register)){ if (*ad_1.ad_count_p>1) in_alterable_data_register (&ad_1); ++*ad_1.ad_count_p; reg_1=ad_1.ad_register; } else reg_1=get_dregister(); instruction_ad_r_r (IMOD,&ad_1,reg_1,ad_2.ad_register); free_dregister (ad_2.ad_register); if (graph->instruction_d_min_a_cost>0){ int areg; areg=get_aregister(); i_move_r_r (reg_1,areg); free_dregister (reg_1); reg_1=areg; } ad_p->ad_mode=P_REGISTER; ad_p->ad_register=reg_1; ad_p->ad_count_p=&graph->node_count; if (*ad_p->ad_count_p>1) register_node (graph,reg_1); } #endif #ifdef I486 static int linearize_first_graph_first (INSTRUCTION_GRAPH a_graph_1,INSTRUCTION_GRAPH a_graph_2) { int i1,i2,u1,u2; int a,d; a=a_graph_1->i_aregs; d=a_graph_1->i_dregs; i1=AD_REG_WEIGHT (a,d); a=a_graph_2->i_aregs; d=a_graph_2->i_dregs; i2=AD_REG_WEIGHT (a,d); a=a_graph_1->u_aregs; d=a_graph_1->u_dregs; u1=AD_REG_WEIGHT (a,d); a=a_graph_2->u_aregs; d=a_graph_2->u_dregs; u2=AD_REG_WEIGHT (a,d); if (i1<0) return ! (i2<0 && (u2u1-i1 || (u2-i2==u1-i1 && i2instruction_parameters[0].p; if (graph->instruction_code==GMULUD){ INSTRUCTION_GRAPH graph_1,graph_2; graph_1=graph->instruction_parameters[0].p; graph_2=graph->instruction_parameters[1].p; if (graph->order_left){ linearize_graph (graph_1,&ad_1); linearize_graph (graph_2,&ad_2); } else { linearize_graph (graph_2,&ad_2); linearize_graph (graph_1,&ad_1); } in_preferred_alterable_register (&ad_2,REGISTER_D0); in_preferred_alterable_register (&ad_1,REGISTER_A1); reg_1=ad_1.ad_register; reg_2=ad_2.ad_register; i_mulud_r_r (reg_1,reg_2); } else if (graph->instruction_code==GDIVDU){ ADDRESS ad_3; linearize_3_graphs (graph->instruction_parameters[0].p,&ad_1, graph->instruction_parameters[1].p,&ad_2, graph->instruction_parameters[2].p,&ad_3); in_preferred_alterable_register (&ad_2,REGISTER_D0); in_preferred_alterable_register (&ad_1,REGISTER_A1); in_register (&ad_3); reg_1=ad_1.ad_register; reg_2=ad_2.ad_register; if (--*ad_3.ad_count_p==0) free_register (ad_3.ad_register); i_divdu_r_r_r (ad_3.ad_register,reg_1,reg_2); } else if (graph->instruction_code==GADDDU){ ADDRESS ad_3,ad_4; linearize_3_graphs (graph->instruction_parameters[0].p,&ad_1, graph->instruction_parameters[1].p,&ad_2, graph->instruction_parameters[2].p,&ad_3); in_alterable_data_register (&ad_2); instruction_ad_r (IADD,&ad_3,ad_2.ad_register); in_alterable_data_register (&ad_1); ad_4.ad_mode=P_IMMEDIATE; ad_4.ad_offset=0; instruction_ad_r (IADC,&ad_4,ad_1.ad_register); reg_1=ad_1.ad_register; reg_2=ad_2.ad_register; } else if (graph->instruction_code==GSUBDU){ ADDRESS ad_3,ad_4; linearize_3_graphs (graph->instruction_parameters[0].p,&ad_1, graph->instruction_parameters[1].p,&ad_2, graph->instruction_parameters[2].p,&ad_3); in_alterable_data_register (&ad_2); instruction_ad_r (ISUB,&ad_3,ad_2.ad_register); in_alterable_data_register (&ad_1); ad_4.ad_mode=P_IMMEDIATE; ad_4.ad_offset=0; instruction_ad_r (ISBB,&ad_4,ad_1.ad_register); reg_1=ad_1.ad_register; reg_2=ad_2.ad_register; } else internal_error_in_function ("linearize_two_results_operator"); result_graph2=result_graph->instruction_parameters[1].p; ad_p->ad_mode=P_REGISTER; ad_p->ad_count_p=&result_graph->node_count; if (result_graph->instruction_code==GRESULT0){ ad_p->ad_register=reg_1; if (result_graph->node_count>1) register_node (result_graph,reg_1); if (result_graph2->node_count>0) register_node (result_graph2,reg_2); else { --*ad_2.ad_count_p; free_register (reg_2); } } else { ad_p->ad_register=reg_2; if (result_graph->node_count>1) register_node (result_graph,reg_2); if (result_graph2->node_count>0) register_node (result_graph2,reg_1); else { --*ad_1.ad_count_p; free_register (reg_1); } } } #endif #ifndef I486 static void linearize_shift_operator (int i_instruction_code,INSTRUCTION_GRAPH graph,ADDRESS *ad_p) #else static void linearize_shift_operator (int i_instruction_code,int i_instruction_code_s,INSTRUCTION_GRAPH graph,ADDRESS *ad_p) #endif { INSTRUCTION_GRAPH graph_1,graph_2; ADDRESS ad_1,ad_2; int reg_1; graph_1=graph->instruction_parameters[0].p; graph_2=graph->instruction_parameters[1].p; if (graph->order_left){ linearize_graph (graph_1,&ad_1); linearize_graph (graph_2,&ad_2); } else { linearize_graph (graph_2,&ad_2); linearize_graph (graph_1,&ad_1); } #if defined (G_POWER) || defined (sparc) if (i_instruction_code==ILSL && ad_1.ad_mode==P_IMMEDIATE && (unsigned)ad_1.ad_offset<(unsigned)32){ in_register (&ad_2); if (--*ad_2.ad_count_p==0) free_register (ad_2.ad_register); if (graph->instruction_d_min_a_cost<=0) reg_1=get_dregister(); else reg_1=get_aregister(); i_lsli_r_r (ad_1.ad_offset,ad_2.ad_register,reg_1); } else { #endif in_alterable_data_register (&ad_2); #ifdef M68000 if (ad_1.ad_mode!=P_IMMEDIATE || ad_1.ad_offset<=0 || ad_1.ad_offset>8) #else # ifndef G_A64 if (ad_1.ad_mode!=P_IMMEDIATE || ad_1.ad_offset<0 || ad_1.ad_offset>=32) # else if (ad_1.ad_mode!=P_IMMEDIATE || ad_1.ad_offset<0 || ad_1.ad_offset>=64) # endif #endif in_data_register (&ad_1); #ifdef I486 if (ad_1.ad_mode!=P_IMMEDIATE){ int tmp_reg; if (try_allocate_register_number (REGISTER_A0)) tmp_reg=REGISTER_A0; else tmp_reg=get_dregister(); instruction_ad_r_r (i_instruction_code_s,&ad_1,ad_2.ad_register,tmp_reg); free_register (tmp_reg); } else #endif instruction_ad_r (i_instruction_code,&ad_1,ad_2.ad_register); --*ad_2.ad_count_p; reg_1=ad_2.ad_register; if (graph->instruction_d_min_a_cost>0){ int areg; areg=get_aregister(); i_move_r_r (reg_1,areg); free_dregister (reg_1); reg_1=areg; } #if defined (G_POWER) || defined (sparc) } #endif ad_p->ad_mode=P_REGISTER; ad_p->ad_register=reg_1; ad_p->ad_count_p=&graph->node_count; if (*ad_p->ad_count_p>1) register_node (graph,reg_1); } static void linearize_integer_o_operator (INSTRUCTION_GRAPH graph,ADDRESS *ad_r_p,ADDRESS *ad_f_p, void linearize_operator (int,INSTRUCTION_GRAPH,ADDRESS *),int i_instruction_code) { INSTRUCTION_GRAPH test_o_graph; int reg_1; test_o_graph=graph->instruction_parameters[2].p; if (ad_r_p!=NULL){ linearize_operator (i_instruction_code,graph,ad_r_p); } else { ADDRESS ad_r; linearize_operator (i_instruction_code,graph,&ad_r); if (graph->node_count>0){ register_node (graph,ad_r.ad_register); } else free_register (ad_r.ad_register); } if (test_o_graph->node_count!=0){ reg_1=get_dregister(); #ifdef sparc instruction_r (condition_to_set_instruction[test_o_graph->inode_arity==0 ? CNE : CO],reg_1); #else instruction_r (condition_to_set_instruction[CO],reg_1); #endif if (ad_f_p==NULL){ register_node (test_o_graph,reg_1); } else { ad_f_p->ad_mode=P_REGISTER; ad_f_p->ad_register=reg_1; ad_f_p->ad_count_p=&test_o_graph->node_count; if (test_o_graph->node_count>1) register_node (test_o_graph,reg_1); } } } static void linearize_add_o_operator (INSTRUCTION_GRAPH graph,ADDRESS *ad_r_p,ADDRESS *ad_f_p) { linearize_integer_o_operator (graph,ad_r_p,ad_f_p,linearize_dyadic_commutative_operator, #if defined (sparc) || defined (G_POWER) IADDO #else IADD #endif ); } static void linearize_sub_o_operator (INSTRUCTION_GRAPH graph,ADDRESS *ad_r_p,ADDRESS *ad_f_p) { linearize_integer_o_operator (graph,ad_r_p,ad_f_p,linearize_dyadic_non_commutative_operator, #if defined (sparc) || defined (G_POWER) ISUBO #else ISUB #endif ); } static void linearize_mul_o_operator (INSTRUCTION_GRAPH graph,ADDRESS *ad_r_p,ADDRESS *ad_f_p) { linearize_integer_o_operator (graph,ad_r_p,ad_f_p,linearize_dyadic_commutative_data_operator, #ifdef G_POWER IMULO #else IMUL #endif ); } static void linearize_test_o_operator (INSTRUCTION_GRAPH graph,ADDRESS *ad_p) { INSTRUCTION_GRAPH operator_graph; operator_graph=graph->instruction_parameters[0].p; switch (operator_graph->instruction_code){ case GADD_O: linearize_add_o_operator (operator_graph,NULL,ad_p); break; case GMUL_O: linearize_mul_o_operator (operator_graph,NULL,ad_p); break; case GSUB_O: linearize_sub_o_operator (operator_graph,NULL,ad_p); break; default: internal_error_in_function ("linearize_test_o_operator"); } } static void linearize_conditional_not_operator (INSTRUCTION_GRAPH graph,ADDRESS *ad_p) { int condition; condition=linearize_not_condition (graph->instruction_parameters[0].p); condition_to_register (graph,condition,ad_p); } static void linearize_float_graph (INSTRUCTION_GRAPH graph,ADDRESS *ad_p); #define MAX(a,b) ((a)>(b)?(a):(b)) static ADDRESS *evaluate_arguments (union instruction_parameter arguments[],int n_arguments) { int argument_number; char *argument_evaluated; ADDRESS *ad_a; char small_argument_evaluated[32]; ad_a=(ADDRESS*)memory_allocate (sizeof (ADDRESS) * n_arguments); if (n_arguments<32) argument_evaluated=small_argument_evaluated; else argument_evaluated=(char*)memory_allocate (sizeof (char) * n_arguments); for (argument_number=0; argument_number=n_arguments) break; a_graph_1=arguments[first_argument_number].p; for (argument_number=first_argument_number+1; argument_numberi_aregs; d=a_graph_1->i_dregs; i1=AD_REG_WEIGHT (a,d); a=a_graph_2->i_aregs; d=a_graph_2->i_dregs; i2=AD_REG_WEIGHT (a,d); a=a_graph_1->u_aregs; d=a_graph_1->u_dregs; u1=AD_REG_WEIGHT (a,d); a=a_graph_2->u_aregs; d=a_graph_2->u_dregs; u2=AD_REG_WEIGHT (a,d); if (i1<0){ if (i2<0 && (u2u1-i1 || (u2-i2==u1-i1 && i2instruction_code==GFROMF){ INSTRUCTION_GRAPH f_graph; f_graph=a_graph_1->instruction_parameters[0].p; arguments[first_argument_number].p=f_graph; { int f_graph_count; f_graph_count=f_graph->node_count; if (--a_graph_1->node_count==0) --f_graph_count; f_graph->node_count=f_graph_count+1; } linearize_float_graph (f_graph,&ad_a[first_argument_number]); argument_evaluated[first_argument_number]=1; ad_a[first_argument_number].ad_mode+=100; continue; } #else if (a_graph_1->instruction_code==GFHIGH && first_argument_number+1instruction_code==GFLOW && a_graph_1->instruction_parameters[0].p==next_graph->instruction_parameters[0].p) { INSTRUCTION_GRAPH f_graph; f_graph=a_graph_1->instruction_parameters[0].p; arguments[first_argument_number].p=f_graph; arguments[first_argument_number+1].p=f_graph; /* CHANGED 22-10-1999 */ { int f_graph_count; f_graph_count=f_graph->node_count; if (--a_graph_1->node_count==0) --f_graph_count; if (--next_graph->node_count==0) --f_graph_count; f_graph->node_count=f_graph_count+1; } /* --f_graph->node_count; */ linearize_float_graph (f_graph,&ad_a[first_argument_number]); argument_evaluated[first_argument_number]=1; argument_evaluated[first_argument_number+1]=1; ad_a[first_argument_number].ad_mode+=100; continue; } } #endif linearize_graph (a_graph_1,&ad_a[first_argument_number]); argument_evaluated[first_argument_number]=1; } if (argument_evaluated!=small_argument_evaluated) memory_free (argument_evaluated); return ad_a; } #ifdef M68000 static void move_float_ad_pi (ADDRESS *ad_p,int areg) { switch (ad_p->ad_mode){ case P_F_REGISTER: i_fmove_fr_pi (ad_p->ad_register,areg); if (--*ad_p->ad_count_p==0) free_fregister (ad_p->ad_register); return; case P_INDIRECT: if (ad_p->ad_offset==0 && *ad_p->ad_count_p==1){ i_move_pi_pi (ad_p->ad_register,areg); i_move_id_pi (0,ad_p->ad_register,areg); *ad_p->ad_count_p=0; free_aregister (ad_p->ad_register); } else { i_move_id_pi (ad_p->ad_offset,ad_p->ad_register,areg); i_move_id_pi (ad_p->ad_offset+4,ad_p->ad_register,areg); if (--*ad_p->ad_count_p==0) free_aregister (ad_p->ad_register); } return; case P_F_IMMEDIATE: i_move_i_pi (((LONG*)&ad_p->ad_register)[0],areg); i_move_i_pi (((LONG*)&ad_p->ad_register)[1],areg); return; case P_INDEXED: { INSTRUCTION_GRAPH load_x_graph; ADDRESS *i_ad_p; load_x_graph=(INSTRUCTION_GRAPH)ad_p->ad_offset; i_ad_p=(ADDRESS *)load_x_graph->instruction_parameters[1].p; if (load_x_graph->inode_arity & LOAD_X_TO_ADDRESS){ load_x_graph->inode_arity ^= (LOAD_X_TO_ADDRESS | LOAD_X_TO_REGISTER); if (i_ad_p->ad_mode==P_INDEXED){ i_move_x_pi (i_ad_p->ad_offset,i_ad_p->ad_areg,i_ad_p->ad_dreg,areg); i_move_x_pi (i_ad_p->ad_offset+(4<<2),i_ad_p->ad_areg,i_ad_p->ad_dreg,areg); if (--*i_ad_p->ad_count_p==0) free_aregister (i_ad_p->ad_areg); if (--*i_ad_p->ad_count_p2==0) free_dregister (i_ad_p->ad_dreg); } else { i_move_id_pi (i_ad_p->ad_offset,i_ad_p->ad_register,areg); i_move_id_pi (i_ad_p->ad_offset+4,i_ad_p->ad_register,areg); if (--*i_ad_p->ad_count_p==0) free_aregister (i_ad_p->ad_register); } } else { i_fmove_fr_pi (i_ad_p->ad_register,areg); if (--*i_ad_p->ad_count_p==0) free_fregister (i_ad_p->ad_register); } return; } default: internal_error_in_function ("move_float_ad_pi"); } } #endif #ifndef M68000 LONG offset_from_heap_register; #endif #ifdef G_POWER LONG heap_pointer_offset_in_basic_block; #endif void evaluate_arguments_and_free_addresses (union instruction_parameter arguments[],int n_arguments) { ADDRESS *ad_a; ad_a=evaluate_arguments (arguments,n_arguments); memory_free (ad_a); } static void move_float_ad_id (ADDRESS *ad_p,int offset,int areg) { switch (ad_p->ad_mode){ case P_F_REGISTER: i_fmove_fr_id (ad_p->ad_register,offset,areg); if (--*ad_p->ad_count_p==0){ #ifdef FP_STACK_OPTIMIZATIONS last_instruction->instruction_parameters[0].parameter_flags |= FP_REG_LAST_USE; #endif free_fregister (ad_p->ad_register); } return; case P_INDIRECT: #ifdef M68000 if (ad_p->ad_offset==0 && *ad_p->ad_count_p==1){ i_move_pi_id (ad_p->ad_register,offset,areg); i_move_id_id (0,ad_p->ad_register,offset+4,areg); *ad_p->ad_count_p=0; free_aregister (ad_p->ad_register); } else { #endif i_move_id_id (ad_p->ad_offset,ad_p->ad_register,offset,areg); #ifndef G_A64 i_move_id_id (ad_p->ad_offset+4,ad_p->ad_register,offset+4,areg); #endif if (--*ad_p->ad_count_p==0) free_aregister (ad_p->ad_register); #ifdef M68000 } #endif return; case P_F_IMMEDIATE: #ifdef G_A64 i_move_i_id (((int_64*)&ad_p->ad_register)[0],offset,areg); #else i_move_i_id (((LONG*)&ad_p->ad_register)[0],offset,areg); i_move_i_id (((LONG*)&ad_p->ad_register)[1],offset+4,areg); #endif return; case P_INDEXED: { INSTRUCTION_GRAPH load_x_graph; ADDRESS *i_ad_p; load_x_graph=ad_p->ad_load_x_graph; i_ad_p=(ADDRESS *)load_x_graph->instruction_parameters[1].p; if (load_x_graph->inode_arity & LOAD_X_TO_ADDRESS){ load_x_graph->inode_arity ^= (LOAD_X_TO_ADDRESS | LOAD_X_TO_REGISTER); if (i_ad_p->ad_mode==P_INDEXED){ #ifdef sparc if (i_ad_p->ad_offset!=0){ int a_reg,offset1; if (--*i_ad_p->ad_count_p==0) free_aregister (i_ad_p->ad_areg); a_reg=get_aregister(); offset1=i_ad_p->ad_offset>>2; i_lea_x_r (i_ad_p->ad_areg,i_ad_p->ad_dreg,a_reg); i_move_id_id (offset1,a_reg,offset,areg); i_move_id_id (offset1+4,a_reg,offset+4,areg); free_aregister (a_reg); if (--*i_ad_p->ad_count_p2==0) free_dregister (i_ad_p->ad_dreg); return; } #endif i_move_x_id (i_ad_p->ad_offset,i_ad_p->ad_areg,i_ad_p->ad_dreg,offset,areg); if (--*i_ad_p->ad_count_p==0) free_aregister (i_ad_p->ad_areg); #ifndef G_A64 # if defined (M68000) || defined (I486) i_move_x_id (i_ad_p->ad_offset+(4<<2),i_ad_p->ad_areg,i_ad_p->ad_dreg,offset+4,areg); # else { int a_reg; a_reg=get_aregister(); i_lea_x_r (i_ad_p->ad_areg,i_ad_p->ad_dreg,a_reg); i_move_id_id (4,a_reg,offset+4,areg); free_aregister (a_reg); } # endif #endif if (--*i_ad_p->ad_count_p2==0) free_dregister (i_ad_p->ad_dreg); } else { i_move_id_id (i_ad_p->ad_offset,i_ad_p->ad_register,offset,areg); #ifndef G_A64 i_move_id_id (i_ad_p->ad_offset+4,i_ad_p->ad_register,offset+4,areg); #endif if (--*i_ad_p->ad_count_p==0) free_aregister (i_ad_p->ad_register); } } else { i_fmove_fr_id (i_ad_p->ad_register,offset,areg); if (--*i_ad_p->ad_count_p==0){ #ifdef FP_STACK_OPTIMIZATIONS last_instruction->instruction_parameters[0].parameter_flags |= FP_REG_LAST_USE; #endif free_fregister (i_ad_p->ad_register); } } return; } default: internal_error_in_function ("move_float_ad_id"); } } static void linearize_load_graph (register INSTRUCTION_GRAPH load_graph) { if (load_graph!=NULL){ if (load_graph->node_count>0){ switch (load_graph->instruction_code){ case GLOAD: { int reg; if (load_graph->instruction_d_min_a_cost<=0) reg=get_dregister(); else reg=get_aregister(); i_move_id_r (load_graph->instruction_parameters[0].i,load_graph->instruction_parameters[1].i,reg); register_node (load_graph,reg); break; } case GFLOAD: { int reg; reg=get_fregister(); i_fmove_id_fr (load_graph->instruction_parameters[0].i,load_graph->instruction_parameters[1].i,reg); float_register_node (load_graph,reg); break; } case GREGISTER: case GGREGISTER: case GFREGISTER: case GGFREGISTER: break; #if defined (G_A64) case GFROMF: load_graph=load_graph->instruction_parameters[0].p; if (load_graph->node_count>0 && load_graph->instruction_code==GFLOAD){ int reg; reg=get_fregister(); i_fmove_id_fr (load_graph->instruction_parameters[0].i,load_graph->instruction_parameters[1].i,reg); float_register_node (load_graph,reg); } break; #endif default: internal_error_in_function ("linearize_load_graph"); } } #ifdef G_A64 else if (load_graph->instruction_code==GFROMF){ #else else if (load_graph->instruction_code==GFHIGH || load_graph->instruction_code==GFLOW){ #endif load_graph=load_graph->instruction_parameters[0].p; if (load_graph->node_count>0 && load_graph->instruction_code==GFLOAD){ int reg; reg=get_fregister(); i_fmove_id_fr (load_graph->instruction_parameters[0].i,load_graph->instruction_parameters[1].i,reg); float_register_node (load_graph,reg); } } } } static void linearize_create_operator (INSTRUCTION_GRAPH graph,ADDRESS *ad_p,int result_register) { int argument_number,arity; ADDRESS *ad_a; int reg_1,heap_offset; #ifndef M68000 int reg_1_allocated; reg_1_allocated=0; #endif arity=graph->inode_arity; last_block->block_n_new_heap_cells+=arity; #ifdef G_POWER for (argument_number=0; argument_numberinstruction_parameters[argument_number].p; if (a_graph!=NULL && a_graph->instruction_code==GCREATE && a_graph->node_count==1) a_graph->instruction_code=GCREATE_S; } #endif ad_a=evaluate_arguments (graph->instruction_parameters,arity); #ifndef M68000 # ifdef I486 if (offset_from_heap_register+(arity<<2) >= 127){ # else # ifdef G_POWER if (offset_from_heap_register+(arity<<2) >= 32767){ heap_pointer_offset_in_basic_block+=offset_from_heap_register; # else if (offset_from_heap_register+(arity<<2) >= 4096){ # endif # endif i_add_i_r (offset_from_heap_register,HEAP_POINTER); IF_G_POWER(last_heap_pointer_update=last_instruction;) offset_from_heap_register=0; } heap_offset=offset_from_heap_register; #else if (result_register!=0 && try_allocate_register_number (result_register>>1)) reg_1=result_register>>1; else if (graph->instruction_d_min_a_cost<=0) reg_1=get_dregister(); else reg_1=get_aregister(); i_move_r_r (HEAP_POINTER,reg_1); heap_offset=0; #endif for (argument_number=0; argument_numberinstruction_parameters[argument_number].p; if (a_graph!=NULL){ #ifdef M68000 if (heap_offset>0){ i_add_i_r (heap_offset,HEAP_POINTER); heap_offset=0; } #endif if (ad_a[argument_number].ad_mode>=100){ ad_a[argument_number].ad_mode-=100; #ifdef M68000 move_float_ad_pi (&ad_a[argument_number],HEAP_POINTER); #else # ifdef G_POWER move_float_ad_id (&ad_a[argument_number],heap_offset+4,HEAP_POINTER); # else move_float_ad_id (&ad_a[argument_number],heap_offset,HEAP_POINTER); # endif heap_offset+=8; #endif #ifndef G_A64 ++argument_number; #endif } else { #ifdef M68000 instruction_ad_pi (IMOVE,&ad_a[argument_number],HEAP_POINTER); #else # ifdef G_POWER if (ad_a[argument_number].ad_mode==P_STORE_HP_INSTRUCTION){ struct instruction *instruction; instruction = (struct instruction*)ad_a[argument_number].ad_offset; instruction->instruction_parameters[1].parameter_data.i= heap_pointer_offset_in_basic_block+heap_offset+STACK_ELEMENT_SIZE -instruction->instruction_parameters[1].parameter_data.i; } else instruction_ad_id (IMOVE,&ad_a[argument_number],heap_offset+STACK_ELEMENT_SIZE,HEAP_POINTER); # else instruction_ad_id (IMOVE,&ad_a[argument_number],heap_offset,HEAP_POINTER); # endif heap_offset+=STACK_ELEMENT_SIZE; #endif } } else { if (arity>3 && graph->instruction_parameters[0].p!=NULL){ #ifdef M68000 if (heap_offset>0){ i_add_i_r (heap_offset,HEAP_POINTER); heap_offset=0; } i_move_r_pi (reg_1,HEAP_POINTER); #else if (!reg_1_allocated){ if (result_register!=0 && try_allocate_register_number (result_register>>1)) reg_1=result_register>>1; else if (graph->instruction_d_min_a_cost<=0) reg_1=get_dregister(); else reg_1=get_aregister(); # ifdef G_POWER i_lea_id_r (offset_from_heap_register+STACK_ELEMENT_SIZE+NODE_POINTER_OFFSET,HEAP_POINTER,reg_1); # else if (offset_from_heap_register==0) i_move_r_r (HEAP_POINTER,reg_1); else i_lea_id_r (offset_from_heap_register,HEAP_POINTER,reg_1); # endif reg_1_allocated=1; } # ifdef G_POWER i_move_r_id (reg_1,heap_offset+STACK_ELEMENT_SIZE,HEAP_POINTER); # else i_move_r_id (reg_1,heap_offset,HEAP_POINTER); # endif heap_offset+=STACK_ELEMENT_SIZE; #endif } else heap_offset+=STACK_ELEMENT_SIZE; } } #ifndef M68000 if (!reg_1_allocated){ if (result_register!=0 && try_allocate_register_number (result_register>>1)) reg_1=result_register>>1; else if (graph->instruction_d_min_a_cost<=0) reg_1=get_dregister(); else reg_1=get_aregister(); # ifdef G_POWER i_lea_id_r (offset_from_heap_register+STACK_ELEMENT_SIZE+NODE_POINTER_OFFSET,HEAP_POINTER,reg_1); # else if (offset_from_heap_register==0) i_move_r_r (HEAP_POINTER,reg_1); else i_lea_id_r (offset_from_heap_register,HEAP_POINTER,reg_1); # endif } offset_from_heap_register=heap_offset; #else if (heap_offset>0) i_add_i_r (heap_offset,HEAP_POINTER); #endif ad_p->ad_mode=P_REGISTER; ad_p->ad_register=reg_1; ad_p->ad_count_p=&graph->node_count; if (*ad_p->ad_count_p>1) register_node (graph,reg_1); memory_free (ad_a); } #ifdef G_POWER static struct instruction * #else static void #endif linearize_store_create_operator (int offset,int stack_pointer,INSTRUCTION_GRAPH graph) { int argument_number; int arity,heap_offset; ADDRESS *ad_a; #ifdef G_POWER struct instruction *instruction; #endif arity=graph->inode_arity; last_block->block_n_new_heap_cells+=arity; #ifdef G_POWER for (argument_number=1; argument_numberinstruction_parameters[argument_number].p; if (a_graph!=NULL && a_graph->instruction_code==GCREATE && a_graph->node_count==1) a_graph->instruction_code=GCREATE_S; } #endif ad_a=evaluate_arguments (graph->instruction_parameters,arity); heap_offset=0-NODE_POINTER_OFFSET; argument_number=0; #ifdef G_POWER # if NODE_POINTER_OFFSET==0 if (arity>=1 && graph->instruction_parameters[0].p!=NULL && ad_a[0].ad_mode<100){ i_move_ad_idu (&ad_a[0],offset_from_heap_register+STACK_ELEMENT_SIZE,HEAP_POINTER); heap_pointer_offset_in_basic_block+=offset_from_heap_register+STACK_ELEMENT_SIZE; offset_from_heap_register=-STACK_ELEMENT_SIZE; heap_offset=STACK_ELEMENT_SIZE; ++argument_number; } else { #endif if (offset_from_heap_register!=-(STACK_ELEMENT_SIZE+NODE_POINTER_OFFSET)){ i_add_i_r (offset_from_heap_register+(STACK_ELEMENT_SIZE+NODE_POINTER_OFFSET),HEAP_POINTER); heap_pointer_offset_in_basic_block+=offset_from_heap_register+(STACK_ELEMENT_SIZE+NODE_POINTER_OFFSET); offset_from_heap_register=-(STACK_ELEMENT_SIZE+NODE_POINTER_OFFSET); } # if NODE_POINTER_OFFSET==0 } #endif if (stack_pointer==HEAP_POINTER) instruction=instruction_move_r_idhp (HEAP_POINTER,heap_pointer_offset_in_basic_block); else { i_move_r_id (HEAP_POINTER,offset,stack_pointer); instruction=NULL; } IF_G_POWER (last_heap_pointer_update=last_instruction;) #else # ifndef M68000 if (offset_from_heap_register>0){ i_add_i_r (offset_from_heap_register,HEAP_POINTER); IF_G_POWER (last_heap_pointer_update=last_instruction;) offset_from_heap_register=0; } # endif i_move_r_id (HEAP_POINTER,offset,stack_pointer); #endif for (; argument_numberinstruction_parameters[argument_number].p; if (a_graph!=NULL){ #ifdef M68000 if (heap_offset>0){ i_add_i_r (heap_offset,HEAP_POINTER); heap_offset=0; } #endif if (ad_a[argument_number].ad_mode>=100){ ad_a[argument_number].ad_mode-=100; #ifdef M68000 move_float_ad_pi (&ad_a[argument_number],HEAP_POINTER); #else move_float_ad_id (&ad_a[argument_number],heap_offset,HEAP_POINTER); heap_offset+=8; #endif #ifndef G_A64 ++argument_number; #endif } else { #ifdef M68000 instruction_ad_pi (IMOVE,&ad_a[argument_number],HEAP_POINTER); #else # ifdef G_POWER if (ad_a[argument_number].ad_mode==P_STORE_HP_INSTRUCTION){ struct instruction *instruction; instruction = (struct instruction*)ad_a[argument_number].ad_offset; instruction->instruction_parameters[1].parameter_data.i= heap_pointer_offset_in_basic_block+heap_offset -instruction->instruction_parameters[1].parameter_data.i; } else # endif instruction_ad_id (IMOVE,&ad_a[argument_number],heap_offset,HEAP_POINTER); heap_offset+=STACK_ELEMENT_SIZE; #endif } } else heap_offset+=STACK_ELEMENT_SIZE; } #ifndef M68000 # ifdef G_POWER offset_from_heap_register=heap_offset-STACK_ELEMENT_SIZE; # else offset_from_heap_register=heap_offset; # endif #else if (heap_offset>0) i_add_i_r (heap_offset,HEAP_POINTER); #endif memory_free (ad_a); #ifdef G_POWER return instruction; #endif } static void linearize_fill_operator (INSTRUCTION_GRAPH graph,ADDRESS *ad_p) { int argument_number; ADDRESS *ad_a; int reg_1,reg_2,n_arguments; n_arguments=graph->inode_arity; while (n_arguments>1 && graph->instruction_parameters[n_arguments-1].p==NULL) --n_arguments; ad_a=evaluate_arguments (graph->instruction_parameters,n_arguments); if (n_arguments==2 && graph->instruction_parameters[1].p!=NULL){ in_address_register (&ad_a[0]); reg_1=reg_2=ad_a[0].ad_register; instruction_ad_id (IMOVE,&ad_a[1],0-NODE_POINTER_OFFSET,reg_2); if (--*ad_a[0].ad_count_p==0 && graph->node_count==0) free_aregister (reg_2); } else if ( n_arguments==3 && graph->instruction_parameters[1].p!=NULL && graph->instruction_parameters[2].p!=NULL) { in_address_register (&ad_a[0]); reg_1=reg_2=ad_a[0].ad_register; if (ad_a[1].ad_mode>=100){ ad_a[1].ad_mode-=100; move_float_ad_id (&ad_a[1],0-NODE_POINTER_OFFSET,reg_2); } else #ifdef G_A64 instruction_ad_id (IMOVE,&ad_a[1],0-NODE_POINTER_OFFSET,reg_2); if (ad_a[2].ad_mode>=100){ ad_a[2].ad_mode-=100; move_float_ad_id (&ad_a[2],STACK_ELEMENT_SIZE-NODE_POINTER_OFFSET,reg_2); } else instruction_ad_id (IMOVE,&ad_a[2],STACK_ELEMENT_SIZE-NODE_POINTER_OFFSET,reg_2); #else { instruction_ad_id (IMOVE,&ad_a[1],0-NODE_POINTER_OFFSET,reg_2); instruction_ad_id (IMOVE,&ad_a[2],STACK_ELEMENT_SIZE-NODE_POINTER_OFFSET,reg_2); } #endif if (--*ad_a[0].ad_count_p==0 && graph->node_count==0) free_aregister (reg_2); } else { #ifndef M68000 int offset; offset=0-NODE_POINTER_OFFSET; #endif if (ad_a[0].ad_mode==P_REGISTER && is_d_register (ad_a[0].ad_register) && graph->instruction_d_min_a_cost<=0 && graph->node_count>0 && *ad_a[0].ad_count_p<=1) { reg_2=ad_a[0].ad_register; reg_1=get_aregister(); i_move_r_r (reg_2,reg_1); } else { #ifdef M68000 in_alterable_address_register (&ad_a[0]); #else in_address_register (&ad_a[0]); #endif reg_1=ad_a[0].ad_register; reg_2=reg_1; #ifdef M68000 if (graph->node_count>0){ if (graph->instruction_d_min_a_cost<=0) reg_2=get_dregister(); else reg_2=get_aregister(); i_move_r_r (reg_1,reg_2); } #endif } for (argument_number=1; argument_numberinstruction_parameters[argument_number].p; if (a_graph!=NULL){ if (ad_a[argument_number].ad_mode>=100){ ad_a[argument_number].ad_mode-=100; #ifdef M68000 move_float_ad_pi (&ad_a[argument_number],reg_1); #else move_float_ad_id (&ad_a[argument_number],offset,reg_1); offset+=8; #endif #ifndef G_A64 ++argument_number; #endif } else { #ifdef M68000 if (argument_number!=n_arguments-1) instruction_ad_pi (IMOVE,&ad_a[argument_number],reg_1); else instruction_ad_id (IMOVE,&ad_a[argument_number],0,reg_1); #else instruction_ad_id (IMOVE,&ad_a[argument_number],offset,reg_1); offset+=STACK_ELEMENT_SIZE; #endif } } else #ifdef M68000 i_add_i_r (STACK_ELEMENT_SIZE,reg_1); #else offset+=STACK_ELEMENT_SIZE; #endif } #ifndef M68000 if (reg_1!=reg_2) #endif free_aregister (reg_1); --*ad_a[0].ad_count_p; } ad_p->ad_mode=P_REGISTER; if (reg_1==reg_2 && *ad_a[0].ad_count_p>0 && graph->node_count>1){ int result_reg; if (graph->instruction_d_min_a_cost<=0) result_reg=get_aregister(); else result_reg=get_dregister(); i_move_r_r (reg_1,result_reg); --*ad_a[0].ad_count_p; ad_p->ad_register=result_reg; ad_p->ad_count_p=&graph->node_count; register_node (graph,result_reg); } else { ad_p->ad_register=reg_2; ad_p->ad_count_p=&graph->node_count; if (*ad_p->ad_count_p>1) register_node (graph,reg_2); if (reg_1==reg_2 && *ad_a[0].ad_count_p>0){ ad_p->ad_count_p=ad_a[0].ad_count_p; *ad_p->ad_count_p+=graph->node_count; } } memory_free (ad_a); } #ifdef ALIGN_REAL_ARRAYS static void move_float_ad_x (ADDRESS *ad_p,int offset,int areg,int dreg,int flags) #else static void move_float_ad_x (ADDRESS *ad_p,int offset,int areg,int dreg) #endif { switch (ad_p->ad_mode){ case P_F_REGISTER: #ifdef ALIGN_REAL_ARRAYS i_fmove_fr_x (ad_p->ad_register,offset,areg,dreg,flags); #else i_fmove_fr_x (ad_p->ad_register,offset,areg,dreg); #endif if (--*ad_p->ad_count_p==0){ #ifdef FP_STACK_OPTIMIZATIONS last_instruction->instruction_parameters[0].parameter_flags |= FP_REG_LAST_USE; #endif free_fregister (ad_p->ad_register); } return; #if defined (M68000) || defined (I486) case P_INDIRECT: # ifdef M68000 if (ad_p->ad_offset==0 && *ad_p->ad_count_p==1){ i_move_pi_x (ad_p->ad_register,offset,areg,dreg); i_move_id_x (0,ad_p->ad_register,offset+(4<<2),areg,dreg); *ad_p->ad_count_p=0; free_aregister (ad_p->ad_register); } else { # endif i_move_id_x (ad_p->ad_offset,ad_p->ad_register,offset,areg,dreg); # ifndef G_A64 i_move_id_x (ad_p->ad_offset+4,ad_p->ad_register,offset+(4<<2),areg,dreg); # endif if (--*ad_p->ad_count_p==0) free_aregister (ad_p->ad_register); # ifdef M68000 } # endif return; case P_F_IMMEDIATE: #ifdef G_A64 i_move_i_x (((int_64*)&ad_p->ad_register)[0],offset,areg,dreg); #else i_move_i_x (((LONG*)&ad_p->ad_register)[0],offset,areg,dreg); i_move_i_x (((LONG*)&ad_p->ad_register)[1],offset+(4<<2),areg,dreg); #endif return; #endif #ifdef M68000 case P_INDEXED: { INSTRUCTION_GRAPH load_x_graph; ADDRESS *i_ad_p; load_x_graph=(INSTRUCTION_GRAPH)ad_p->ad_offset; i_ad_p=(ADDRESS *)load_x_graph->instruction_parameters[1].p; if (load_x_graph->inode_arity & LOAD_X_TO_ADDRESS){ load_x_graph->inode_arity ^= (LOAD_X_TO_ADDRESS | LOAD_X_TO_REGISTER); if (i_ad_p->ad_mode==P_INDEXED){ i_move_x_x (i_ad_p->ad_offset,i_ad_p->ad_areg,i_ad_p->ad_dreg,offset,areg,dreg); i_move_x_x (i_ad_p->ad_offset+(4<<2),i_ad_p->ad_areg,i_ad_p->ad_dreg,offset+(4<<2),areg,dreg); if (--*i_ad_p->ad_count_p==0) free_aregister (i_ad_p->ad_areg); if (--*i_ad_p->ad_count_p2==0) free_dregister (i_ad_p->ad_dreg); } else { i_move_id_x (i_ad_p->ad_offset,i_ad_p->ad_register,offset,areg,dreg); i_move_id_x (i_ad_p->ad_offset+4,i_ad_p->ad_register,offset+(4<<2),areg,dreg); if (--*i_ad_p->ad_count_p==0) free_aregister (i_ad_p->ad_register); } } else { i_fmove_fr_x (i_ad_p->ad_register,offset,areg,dreg); if (--*i_ad_p->ad_count_p==0) free_fregister (i_ad_p->ad_register); } return; } #endif default: internal_error_in_function ("move_float_ad_x"); } } static void linearize_fill_r_operator (register INSTRUCTION_GRAPH graph,register ADDRESS *ad_p) { ADDRESS ad_a[3]; int reg_2; linearize_float_graph (graph->instruction_parameters[2].p,&ad_a[2]); linearize_graph (graph->instruction_parameters[0].p,&ad_a[0]); linearize_graph (graph->instruction_parameters[1].p,&ad_a[1]); in_address_register (&ad_a[0]); reg_2=ad_a[0].ad_register; instruction_ad_id (IMOVE,&ad_a[1],0,reg_2); move_float_ad_id (&ad_a[2],STACK_ELEMENT_SIZE,reg_2); if (graph->node_count==0) if (--*ad_a[0].ad_count_p==0) free_aregister (reg_2); ad_p->ad_mode=P_REGISTER; ad_p->ad_register=reg_2; ad_p->ad_count_p=&graph->node_count; if (*ad_p->ad_count_p>1) register_node (graph,reg_2); } static void in_float_register (ADDRESS *ad_p); static void linearize_store_fill_operator (INSTRUCTION_GRAPH s_graph,INSTRUCTION_GRAPH graph) { int argument_number,stack_offset,stack_pointer,n_arguments; ADDRESS *ad_a; int reg_1; #ifndef M68000 int offset; #endif n_arguments=graph->inode_arity; while (n_arguments>1 && graph->instruction_parameters[n_arguments-1].p==NULL) --n_arguments; ad_a=evaluate_arguments (graph->instruction_parameters,n_arguments); #ifdef M68000 if (n_arguments!=2 || graph->instruction_parameters[1].p==NULL) in_alterable_address_register (&ad_a[0]); else #endif in_address_register (&ad_a[0]); reg_1=ad_a[0].ad_register; stack_offset=s_graph->instruction_parameters[0].i; stack_pointer=s_graph->instruction_parameters[1].i; if (s_graph->instruction_parameters[3].p!=NULL){ for (argument_number=1; argument_numberinstruction_parameters[argument_number].p!=NULL){ ADDRESS *ad_p; ad_p=&ad_a[argument_number]; if (ad_p->ad_mode==100 + P_INDIRECT){ if (ad_p->ad_register==stack_pointer && (ad_p->ad_offset==stack_offset || ad_p->ad_offset-4==stack_offset)){ ad_p->ad_mode=P_INDIRECT; in_float_register (ad_p); ad_p->ad_mode+=100; } } else if (ad_p->ad_mode==P_INDIRECT){ if (ad_p->ad_register==stack_pointer && ad_p->ad_offset==stack_offset){ in_register (ad_p); } } } } linearize_load_graph (s_graph->instruction_parameters[3].p); } i_move_r_id (reg_1,stack_offset,stack_pointer); #ifndef M68000 offset=0-NODE_POINTER_OFFSET; #endif for (argument_number=1; argument_numberinstruction_parameters[argument_number].p; if (a_graph!=NULL){ if (ad_a[argument_number].ad_mode>=100){ ad_a[argument_number].ad_mode-=100; #ifdef M68000 move_float_ad_pi (&ad_a[argument_number],reg_1); #else move_float_ad_id (&ad_a[argument_number],offset,reg_1); offset+=8; #endif #ifndef G_A64 ++argument_number; #endif } else { #ifdef M68000 if (argument_number!=n_arguments-1) instruction_ad_pi (IMOVE,&ad_a[argument_number],reg_1); else instruction_ad_id (IMOVE,&ad_a[argument_number],0,reg_1); #else instruction_ad_id (IMOVE,&ad_a[argument_number],offset,reg_1); offset+=STACK_ELEMENT_SIZE; #endif } } else #ifdef M68000 i_add_i_r (STACK_ELEMENT_SIZE,reg_1); #else offset+=STACK_ELEMENT_SIZE; #endif } if (--*ad_a[0].ad_count_p==0) free_aregister (reg_1); memory_free (ad_a); } static int movem_registers (int a_reg,register int n_registers,int registers[],int offset,int update_a_reg) { #ifdef M68000 if (n_registers>=5){ i_movem_id (offset,a_reg,n_registers,registers); return offset+(n_registers<<2); } else { register int i; for (i=0; iinstruction_parameters[1].p,&ad_1); #ifdef M68000 in_alterable_address_register (&ad_1); #else in_address_register (&ad_1); #endif a_reg=ad_1.ad_register; arity=graph->inode_arity; offset=graph->instruction_parameters[0].i; address_register_used=0; n_registers=0; for (argument_number=0; argument_numberinstruction_parameters[2+argument_number].p; if (a_graph==NULL || a_graph->node_count<=0){ if (n_registers>0){ offset=movem_registers (a_reg,n_registers,registers,offset,1); address_register_used=0; n_registers=0; } offset+=STACK_ELEMENT_SIZE; } else { if (a_graph->instruction_code==GFMOVEMI){ int l_f_reg; l_f_reg=get_fregister(); float_register_node (a_graph,l_f_reg); if (n_registers>0){ offset=movem_registers (a_reg,n_registers,registers,offset,1); address_register_used=0; n_registers=0; } if (argument_numberinstruction_parameters[1].i!=0){ int reg_n; reg_n=a_graph->instruction_parameters[1].i>>1; if (try_allocate_register_number (reg_n)){ register_node (a_graph,reg_n); offset=movem_registers (a_reg,n_registers,registers,offset,1); address_register_used=0; n_registers=0; if (argument_numberinstruction_d_min_a_cost<=0){ int l_d_reg; l_d_reg=get_dregister(); register_node (a_graph,l_d_reg); if (d_reg_num (l_d_reg)>=N_DATA_PARAMETER_REGISTERS){ offset=movem_registers (a_reg,n_registers,registers,offset,1); n_registers=0; address_register_used=0; if (argument_number=N_ADDRESS_PARAMETER_REGISTERS){ offset=movem_registers (a_reg,n_registers,registers,offset,1); n_registers=0; address_register_used=0; if (argument_numberinstruction_parameters[0].p); ad_p->ad_mode=P_REGISTER; ad_p->ad_register=graph->instruction_parameters[0].i; ad_p->ad_count_p=&graph->node_count; } static void linearize_fmovemi_operator (INSTRUCTION_GRAPH graph,register ADDRESS *ad_p) { linearize_movem_operator (graph->instruction_parameters[0].p); ad_p->ad_mode=P_F_REGISTER; ad_p->ad_register=graph->instruction_parameters[0].i; ad_p->ad_count_p=&graph->node_count; } static void linearize_copy_operator (register INSTRUCTION_GRAPH graph,register ADDRESS *ad_p) { ADDRESS ad; int areg_1,areg_2; linearize_graph (graph->instruction_parameters[0].p,&ad); linearize_graph (graph->instruction_parameters[1].p,ad_p); #ifdef M68000 in_alterable_address_register (&ad); #else in_address_register (&ad); #endif in_alterable_address_register (ad_p); areg_1=ad.ad_register; areg_2=ad_p->ad_register; #ifdef M68000 i_move_pi_id (areg_1,0,areg_2); i_move_pi_id (areg_1,4,areg_2); i_move_pi_id (areg_1,8,areg_2); #else i_move_id_id (0,areg_1,0,areg_2); i_move_id_id (STACK_ELEMENT_SIZE,areg_1,STACK_ELEMENT_SIZE,areg_2); i_move_id_id (2*STACK_ELEMENT_SIZE,areg_1,2*STACK_ELEMENT_SIZE,areg_2); #endif if (--*ad.ad_count_p==0) free_aregister (ad.ad_register); if (*ad_p->ad_count_p>1) *ad_p->ad_count_p += graph->node_count-1; else { ad_p->ad_count_p=&graph->node_count; register_node (graph,areg_2); } } #define FLOAT_SIZE 8 static void in_alterable_float_register (ADDRESS *ad_p) { int freg; switch (ad_p->ad_mode){ case P_F_REGISTER: if (*ad_p->ad_count_p==1) return; freg=get_fregister(); i_fmove_fr_fr (ad_p->ad_register,freg); --*ad_p->ad_count_p; break; case P_INDIRECT: if (--*ad_p->ad_count_p==0) free_aregister (ad_p->ad_register); freg=get_fregister(); i_fmove_id_fr (ad_p->ad_offset,ad_p->ad_register,freg); break; case P_F_IMMEDIATE: freg=get_fregister(); i_fmove_if_fr (ad_p->ad_real,freg); break; case P_INDEXED: { INSTRUCTION_GRAPH load_x_graph; ADDRESS *i_ad_p; load_x_graph=ad_p->ad_load_x_graph; i_ad_p=(ADDRESS *)load_x_graph->instruction_parameters[1].p; if (load_x_graph->inode_arity & LOAD_X_TO_ADDRESS){ load_x_graph->inode_arity ^= (LOAD_X_TO_ADDRESS | LOAD_X_TO_REGISTER); if (i_ad_p->ad_mode==P_INDEXED){ if (--*i_ad_p->ad_count_p==0) free_aregister (i_ad_p->ad_areg); if (--*i_ad_p->ad_count_p2==0) free_dregister (i_ad_p->ad_dreg); freg=get_fregister(); #ifdef ALIGN_REAL_ARRAYS i_fmove_x_fr (i_ad_p->ad_offset,i_ad_p->ad_areg,i_ad_p->ad_dreg,freg,load_x_graph->inode_arity & LOAD_STORE_ALIGNED_REAL); #else i_fmove_x_fr (i_ad_p->ad_offset,i_ad_p->ad_areg,i_ad_p->ad_dreg,freg); #endif } else { if (--*i_ad_p->ad_count_p==0) free_aregister (i_ad_p->ad_register); freg=get_fregister(); #ifdef ALIGN_REAL_ARRAYS i_fmove_id_fr_f (i_ad_p->ad_offset,i_ad_p->ad_register,freg,load_x_graph->inode_arity & LOAD_STORE_ALIGNED_REAL); #else i_fmove_id_fr (i_ad_p->ad_offset,i_ad_p->ad_register,freg); #endif } i_ad_p->ad_register=freg; } else { freg=i_ad_p->ad_register; } break; } default: internal_error_in_function ("in_alterable_float_register"); return; } ad_p->ad_mode=P_F_REGISTER; ad_p->ad_register=freg; ad_p->ad_count_p=&ad_p->ad_count; ad_p->ad_count=1; } static void in_float_register (ADDRESS *ad_p) { int freg; switch (ad_p->ad_mode){ case P_F_REGISTER: return; case P_INDIRECT: if (--*ad_p->ad_count_p==0) free_aregister (ad_p->ad_register); freg=get_fregister(); i_fmove_id_fr (ad_p->ad_offset,ad_p->ad_register,freg); break; case P_F_IMMEDIATE: freg=get_fregister(); i_fmove_if_fr (ad_p->ad_real,freg); break; case P_INDEXED: { INSTRUCTION_GRAPH load_x_graph; ADDRESS *i_ad_p; load_x_graph=ad_p->ad_load_x_graph; i_ad_p=(ADDRESS *)load_x_graph->instruction_parameters[1].p; if (load_x_graph->inode_arity & LOAD_X_TO_ADDRESS){ load_x_graph->inode_arity ^= (LOAD_X_TO_ADDRESS | LOAD_X_TO_REGISTER); if (i_ad_p->ad_mode==P_INDEXED){ if (--*i_ad_p->ad_count_p==0) free_aregister (i_ad_p->ad_areg); if (--*i_ad_p->ad_count_p2==0) free_dregister (i_ad_p->ad_dreg); freg=get_fregister(); #ifdef ALIGN_REAL_ARRAYS i_fmove_x_fr (i_ad_p->ad_offset,i_ad_p->ad_areg,i_ad_p->ad_dreg,freg,load_x_graph->inode_arity & LOAD_STORE_ALIGNED_REAL); #else i_fmove_x_fr (i_ad_p->ad_offset,i_ad_p->ad_areg,i_ad_p->ad_dreg,freg); #endif } else { if (--*i_ad_p->ad_count_p==0) free_aregister (i_ad_p->ad_register); freg=get_fregister(); #ifdef ALIGN_REAL_ARRAYS i_fmove_id_fr_f (i_ad_p->ad_offset,i_ad_p->ad_register,freg,load_x_graph->inode_arity & LOAD_STORE_ALIGNED_REAL); #else i_fmove_id_fr (i_ad_p->ad_offset,i_ad_p->ad_register,freg); #endif } i_ad_p->ad_register=freg; } else { freg=i_ad_p->ad_register; } break; } default: internal_error_in_function ("in_float_register"); return; } ad_p->ad_mode=P_F_REGISTER; ad_p->ad_register=freg; ad_p->ad_count_p=&ad_p->ad_count; ad_p->ad_count=1; } static void instruction_ad_fr (int instruction_code,ADDRESS *ad_p,int register_1) { struct instruction *instruction; struct parameter *parameter_p; instruction=i_new_instruction2 (instruction_code); parameter_p=&instruction->instruction_parameters[0]; switch (ad_p->ad_mode){ case P_F_REGISTER: set_float_register_parameter (*parameter_p,ad_p->ad_register); #if defined (FMADD) parameter_p->parameter_flags=0; #endif if (--*ad_p->ad_count_p==0){ #if defined (FP_STACK_OPTIMIZATIONS) || defined (FMADD) parameter_p->parameter_flags |= FP_REG_LAST_USE; #endif free_fregister (ad_p->ad_register); } break; case P_INDIRECT: parameter_p->parameter_type=P_INDIRECT; parameter_p->parameter_offset=ad_p->ad_offset; parameter_p->parameter_data.i=ad_p->ad_register; #ifdef ALIGN_REAL_ARRAYS parameter_p->parameter_flags=0; #endif if (--*ad_p->ad_count_p==0) free_aregister (ad_p->ad_register); break; case P_F_IMMEDIATE: { DOUBLE *rp; parameter_p->parameter_type=P_F_IMMEDIATE; rp=(DOUBLE*)fast_memory_allocate (sizeof (DOUBLE)); parameter_p->parameter_data.r=rp; *rp=ad_p->ad_real; break; } case P_INDEXED: { struct index_registers *index_registers; INSTRUCTION_GRAPH load_x_graph; ADDRESS *i_ad_p; load_x_graph=ad_p->ad_load_x_graph; i_ad_p=(ADDRESS *)load_x_graph->instruction_parameters[1].p; if (load_x_graph->inode_arity & LOAD_X_TO_ADDRESS){ load_x_graph->inode_arity ^= (LOAD_X_TO_ADDRESS | LOAD_X_TO_REGISTER); if (i_ad_p->ad_mode==P_INDEXED){ index_registers=(struct index_registers*)fast_memory_allocate (sizeof (struct index_registers)); parameter_p->parameter_type=P_INDEXED; parameter_p->parameter_offset=i_ad_p->ad_offset; parameter_p->parameter_data.ir=index_registers; index_registers->a_reg.r=i_ad_p->ad_areg; index_registers->d_reg.r=i_ad_p->ad_dreg; if (--*i_ad_p->ad_count_p==0) free_aregister (i_ad_p->ad_areg); if (--*i_ad_p->ad_count_p2==0) free_dregister (i_ad_p->ad_dreg); } else { parameter_p->parameter_type=P_INDIRECT; parameter_p->parameter_offset=i_ad_p->ad_offset; parameter_p->parameter_data.i=i_ad_p->ad_register; if (--*i_ad_p->ad_count_p==0) free_aregister (i_ad_p->ad_register); } #ifdef ALIGN_REAL_ARRAYS parameter_p->parameter_flags = load_x_graph->inode_arity & LOAD_STORE_ALIGNED_REAL; #endif } else { set_float_register_parameter (*parameter_p,i_ad_p->ad_register); if (--*i_ad_p->ad_count_p==0){ #ifdef FP_STACK_OPTIMIZATIONS parameter_p->parameter_flags |= FP_REG_LAST_USE; #endif free_fregister (i_ad_p->ad_register); } } break; } default: internal_error_in_function ("instruction_ad_fr"); } set_float_register_parameter (instruction->instruction_parameters[1],register_1); } static void instruction_p_fr (int instruction_code,struct parameter *parameter1_p,int register_1) { struct instruction *instruction; instruction=i_new_instruction (instruction_code,2,2*sizeof (struct parameter)); instruction->instruction_parameters[0]=*parameter1_p; set_float_register_parameter (instruction->instruction_parameters[1],register_1); } static void instruction_lad_fr (int instruction_code,ADDRESS *ad_p,int f_register_1) { register struct instruction *instruction; instruction=i_new_instruction2 (instruction_code); ad_to_parameter (ad_p,&instruction->instruction_parameters[0]); set_float_register_parameter (instruction->instruction_parameters[1],f_register_1); } #ifdef G_A64 static void linearize_fromf_operator (INSTRUCTION_GRAPH graph,ADDRESS *ad_p) { linearize_float_graph (graph->instruction_parameters[0].p,ad_p); switch (ad_p->ad_mode){ case P_INDIRECT: if (graph->node_count>1){ int reg; if (graph->instruction_d_min_a_cost<=0) reg=get_dregister(); else reg=get_aregister(); i_move_id_r (ad_p->ad_offset,ad_p->ad_register,reg); if (--*ad_p->ad_count_p==0) free_aregister (ad_p->ad_register); ad_p->ad_mode=P_REGISTER; ad_p->ad_register=reg; ad_p->ad_count_p=&graph->node_count; graph->instruction_code=P_REGISTER; graph->instruction_parameters[0].i=reg; } return; case P_F_REGISTER: local_data_offset-=FLOAT_SIZE; i_fmove_fr_id (ad_p->ad_register,local_data_offset,B_STACK_POINTER); if (--*ad_p->ad_count_p==0){ free_fregister (ad_p->ad_register); } if (graph->node_count>1){ int reg; if (graph->instruction_d_min_a_cost<=0) reg=get_dregister(); else reg=get_aregister(); i_move_id_r (local_data_offset,B_STACK_POINTER,reg); ad_p->ad_mode=P_REGISTER; ad_p->ad_register=reg; ad_p->ad_count_p=&graph->node_count; register_node (graph,reg); } else { ad_p->ad_mode=P_INDIRECT; ad_p->ad_offset=local_data_offset; ad_p->ad_register=B_STACK_POINTER; ad_p->ad_count_p=&ad_p->ad_count; ad_p->ad_count=graph->node_count+1; } return; case P_F_IMMEDIATE: { DOUBLE r; r=ad_p->ad_real; if (graph->node_count>1){ int reg; if (graph->instruction_d_min_a_cost<=0) reg=get_dregister(); else reg=get_aregister(); i_move_i_r (((int_64*)&r)[0],reg); ad_p->ad_mode=P_REGISTER; ad_p->ad_register=reg; ad_p->ad_count_p=&graph->node_count; register_node (graph,reg); } else { ad_p->ad_mode=P_IMMEDIATE; ad_p->ad_offset=((LONG*)&r)[0]; } return; } case P_INDEXED: { INSTRUCTION_GRAPH load_x_graph; ADDRESS *i_ad_p; load_x_graph=ad_p->ad_load_x_graph; i_ad_p=(ADDRESS *)load_x_graph->instruction_parameters[1].p; if (graph->node_count>1){ int reg; if (load_x_graph->inode_arity==1){ load_x_graph->inode_arity=2; if (i_ad_p->ad_mode==P_INDEXED){ if (--*i_ad_p->ad_count_p==0) free_aregister (i_ad_p->ad_areg); if (--*i_ad_p->ad_count_p2==0) free_dregister (i_ad_p->ad_dreg); if (graph->instruction_d_min_a_cost<=0) reg=get_dregister(); else reg=get_aregister(); i_move_x_r (i_ad_p->ad_offset,i_ad_p->ad_areg,i_ad_p->ad_dreg,reg); } else { if (--*i_ad_p->ad_count_p==0) free_aregister (i_ad_p->ad_register); if (graph->instruction_d_min_a_cost<=0) reg=get_dregister(); else reg=get_aregister(); i_move_id_r (i_ad_p->ad_offset,i_ad_p->ad_register,reg); } i_ad_p->ad_register=reg; } else { int reg; local_data_offset-=FLOAT_SIZE; i_fmove_fr_id (i_ad_p->ad_register,local_data_offset,B_STACK_POINTER); free_fregister (i_ad_p->ad_register); if (graph->instruction_d_min_a_cost<=0) reg=get_dregister(); else reg=get_aregister(); i_move_id_r (local_data_offset,B_STACK_POINTER,reg); } ad_p->ad_mode=P_REGISTER; ad_p->ad_register=reg; ad_p->ad_count_p=&graph->node_count; graph->instruction_code=P_REGISTER; graph->instruction_parameters[0].i=reg; register_node (graph,reg); } else { if (load_x_graph->inode_arity==1){ } else { local_data_offset-=FLOAT_SIZE; i_fmove_fr_id (i_ad_p->ad_register,local_data_offset,B_STACK_POINTER); free_fregister (i_ad_p->ad_register); ad_p->ad_mode=P_INDIRECT; ad_p->ad_offset=local_data_offset; ad_p->ad_register=B_STACK_POINTER; ad_p->ad_count_p=&ad_p->ad_count; ad_p->ad_count=graph->node_count+1; } } return; } default: internal_error_in_function ("linearize_fromf_operator"); } } #else static void linearize_fhigh_operator (INSTRUCTION_GRAPH graph,ADDRESS *ad_p) { linearize_float_graph (graph->instruction_parameters[0].p,ad_p); switch (ad_p->ad_mode){ case P_INDIRECT: if (graph->node_count>1){ int reg; if (graph->instruction_d_min_a_cost<=0) reg=get_dregister(); else reg=get_aregister(); i_move_id_r (ad_p->ad_offset,ad_p->ad_register,reg); if (--*ad_p->ad_count_p==0) free_aregister (ad_p->ad_register); ad_p->ad_mode=P_REGISTER; ad_p->ad_register=reg; ad_p->ad_count_p=&graph->node_count; graph->instruction_code=P_REGISTER; graph->instruction_parameters[0].i=reg; } return; case P_F_REGISTER: local_data_offset-=FLOAT_SIZE; i_fmove_fr_id (ad_p->ad_register,local_data_offset,B_STACK_POINTER); if (--*ad_p->ad_count_p==0){ #ifdef FP_STACK_OPTIMIZATIONS last_instruction->instruction_parameters[0].parameter_flags |= FP_REG_LAST_USE; #endif free_fregister (ad_p->ad_register); } if (graph->node_count>1){ int reg; if (graph->instruction_d_min_a_cost<=0) reg=get_dregister(); else reg=get_aregister(); i_move_id_r (local_data_offset,B_STACK_POINTER,reg); ad_p->ad_mode=P_REGISTER; ad_p->ad_register=reg; ad_p->ad_count_p=&graph->node_count; register_node (graph,reg); } else { ad_p->ad_mode=P_INDIRECT; ad_p->ad_offset=local_data_offset; ad_p->ad_register=B_STACK_POINTER; ad_p->ad_count_p=&ad_p->ad_count; ad_p->ad_count=graph->node_count+1; } #ifdef g_fhighlow { INSTRUCTION_GRAPH low_graph; low_graph=graph->instruction_parameters[1].p; if (low_graph!=NULL){ low_graph->instruction_code=GLOAD; low_graph->instruction_parameters[0].i=local_data_offset+4; low_graph->instruction_parameters[1].i=B_STACK_POINTER; } } #endif return; case P_F_IMMEDIATE: { DOUBLE r; r=ad_p->ad_real; if (graph->node_count>1){ int reg; if (graph->instruction_d_min_a_cost<=0) reg=get_dregister(); else reg=get_aregister(); i_move_i_r (((LONG*)&r)[0],reg); ad_p->ad_mode=P_REGISTER; ad_p->ad_register=reg; ad_p->ad_count_p=&graph->node_count; register_node (graph,reg); } else { ad_p->ad_mode=P_IMMEDIATE; ad_p->ad_offset=((LONG*)&r)[0]; } return; } case P_INDEXED: { INSTRUCTION_GRAPH load_x_graph; ADDRESS *i_ad_p; load_x_graph=ad_p->ad_load_x_graph; i_ad_p=(ADDRESS *)load_x_graph->instruction_parameters[1].p; if (graph->node_count>1){ int reg; if (load_x_graph->inode_arity & LOAD_X_TO_ADDRESS){ load_x_graph->inode_arity ^= (LOAD_X_TO_ADDRESS | LOAD_X_TO_REGISTER); if (i_ad_p->ad_mode==P_INDEXED){ if (--*i_ad_p->ad_count_p==0) free_aregister (i_ad_p->ad_areg); if (--*i_ad_p->ad_count_p2==0) free_dregister (i_ad_p->ad_dreg); if (graph->instruction_d_min_a_cost<=0) reg=get_dregister(); else reg=get_aregister(); i_move_x_r (i_ad_p->ad_offset,i_ad_p->ad_areg,i_ad_p->ad_dreg,reg); } else { if (--*i_ad_p->ad_count_p==0) free_aregister (i_ad_p->ad_register); if (graph->instruction_d_min_a_cost<=0) reg=get_dregister(); else reg=get_aregister(); i_move_id_r (i_ad_p->ad_offset,i_ad_p->ad_register,reg); } i_ad_p->ad_register=reg; } else { int reg; local_data_offset-=FLOAT_SIZE; i_fmove_fr_id (i_ad_p->ad_register,local_data_offset,B_STACK_POINTER); #ifdef FP_STACK_OPTIMIZATIONS last_instruction->instruction_parameters[0].parameter_flags |= FP_REG_LAST_USE; #endif free_fregister (i_ad_p->ad_register); if (graph->instruction_d_min_a_cost<=0) reg=get_dregister(); else reg=get_aregister(); i_move_id_r (local_data_offset,B_STACK_POINTER,reg); } ad_p->ad_mode=P_REGISTER; ad_p->ad_register=reg; ad_p->ad_count_p=&graph->node_count; graph->instruction_code=P_REGISTER; graph->instruction_parameters[0].i=reg; register_node (graph,reg); } else { if (load_x_graph->inode_arity & LOAD_X_TO_ADDRESS){ } else { local_data_offset-=FLOAT_SIZE; i_fmove_fr_id (i_ad_p->ad_register,local_data_offset,B_STACK_POINTER); #ifdef FP_STACK_OPTIMIZATIONS last_instruction->instruction_parameters[0].parameter_flags |= FP_REG_LAST_USE; #endif free_fregister (i_ad_p->ad_register); ad_p->ad_mode=P_INDIRECT; ad_p->ad_offset=local_data_offset; ad_p->ad_register=B_STACK_POINTER; ad_p->ad_count_p=&ad_p->ad_count; ad_p->ad_count=graph->node_count+1; } } return; } default: internal_error_in_function ("linearize_fhigh_operator"); } } static void linearize_flow_operator (INSTRUCTION_GRAPH graph,ADDRESS *ad_p) { linearize_float_graph (graph->instruction_parameters[0].p,ad_p); switch (ad_p->ad_mode){ case P_INDIRECT: if (graph->node_count>1){ register int reg; if (graph->instruction_d_min_a_cost<=0) reg=get_dregister(); else reg=get_aregister(); i_move_id_r (ad_p->ad_offset+4,ad_p->ad_register,reg); if (--*ad_p->ad_count_p==0) free_aregister (ad_p->ad_register); ad_p->ad_mode=P_REGISTER; ad_p->ad_register=reg; ad_p->ad_count_p=&graph->node_count; register_node (graph,reg); } else ad_p->ad_offset+=4; return; case P_F_REGISTER: local_data_offset-=FLOAT_SIZE; i_fmove_fr_id (ad_p->ad_register,local_data_offset,B_STACK_POINTER); if (--*ad_p->ad_count_p==0) #ifdef FP_STACK_OPTIMIZATIONS last_instruction->instruction_parameters[0].parameter_flags |= FP_REG_LAST_USE; #endif free_fregister (ad_p->ad_register); if (graph->node_count>1){ int reg; if (graph->instruction_d_min_a_cost<=0) reg=get_dregister(); else reg=get_aregister(); i_move_id_r (local_data_offset+4,B_STACK_POINTER,reg); ad_p->ad_mode=P_REGISTER; ad_p->ad_register=reg; ad_p->ad_count_p=&graph->node_count; graph->instruction_code=P_REGISTER; graph->instruction_parameters[0].i=reg; } else { ad_p->ad_mode=P_INDIRECT; ad_p->ad_offset=local_data_offset+4; ad_p->ad_register=B_STACK_POINTER; ad_p->ad_count_p=&ad_p->ad_count; ad_p->ad_count=graph->node_count+1; } #ifdef g_fhighlow { INSTRUCTION_GRAPH high_graph; high_graph=graph->instruction_parameters[1].p; if (high_graph!=NULL){ high_graph->instruction_code=GLOAD; high_graph->instruction_parameters[0].i=local_data_offset; high_graph->instruction_parameters[1].i=B_STACK_POINTER; } } #endif return; case P_F_IMMEDIATE: { DOUBLE r; r=ad_p->ad_real; if (graph->node_count>1){ int reg; if (graph->instruction_d_min_a_cost<=0) reg=get_dregister(); else reg=get_aregister(); i_move_i_r (((LONG*)&r)[1],reg); ad_p->ad_mode=P_REGISTER; ad_p->ad_register=reg; ad_p->ad_count_p=&graph->node_count; register_node (graph,reg); } else { ad_p->ad_mode=P_IMMEDIATE; ad_p->ad_offset=((LONG*)&r)[1]; } return; } case P_INDEXED: { INSTRUCTION_GRAPH load_x_graph; ADDRESS *i_ad_p; load_x_graph=ad_p->ad_load_x_graph; i_ad_p=(ADDRESS *)load_x_graph->instruction_parameters[1].p; if (graph->node_count>1){ int reg; if (load_x_graph->inode_arity & LOAD_X_TO_ADDRESS){ load_x_graph->inode_arity ^= (LOAD_X_TO_ADDRESS | LOAD_X_TO_REGISTER); if (i_ad_p->ad_mode==P_INDEXED){ if (--*i_ad_p->ad_count_p==0) free_aregister (i_ad_p->ad_areg); if (--*i_ad_p->ad_count_p2==0) free_dregister (i_ad_p->ad_dreg); if (graph->instruction_d_min_a_cost<=0) reg=get_dregister(); else reg=get_aregister(); i_move_x_r (i_ad_p->ad_offset,i_ad_p->ad_areg,i_ad_p->ad_dreg,reg); } else { if (--*i_ad_p->ad_count_p==0) free_aregister (i_ad_p->ad_register); if (graph->instruction_d_min_a_cost<=0) reg=get_dregister(); else reg=get_aregister(); i_move_id_r (i_ad_p->ad_offset,i_ad_p->ad_register,reg); } i_ad_p->ad_register=reg; } else reg=i_ad_p->ad_register; ad_p->ad_mode=P_REGISTER; ad_p->ad_register=reg; ad_p->ad_count_p=&graph->node_count; graph->instruction_code=P_REGISTER; graph->instruction_parameters[0].i=reg; } else { if (load_x_graph->inode_arity & LOAD_X_TO_ADDRESS){ if (i_ad_p->ad_mode==P_INDEXED) i_ad_p->ad_offset+=4<<2; else i_ad_p->ad_offset+=4; } else { local_data_offset-=FLOAT_SIZE; i_fmove_fr_id (i_ad_p->ad_register,local_data_offset,B_STACK_POINTER); #ifdef FP_STACK_OPTIMIZATIONS last_instruction->instruction_parameters[0].parameter_flags |= FP_REG_LAST_USE; #endif free_fregister (i_ad_p->ad_register); ad_p->ad_mode=P_INDIRECT; ad_p->ad_offset=local_data_offset+4; ad_p->ad_register=B_STACK_POINTER; ad_p->ad_count_p=&ad_p->ad_count; ad_p->ad_count=graph->node_count+1; } } return; } default: internal_error_in_function ("linearize_flow_operator"); } } #endif #ifdef G_A64 static void linearize_tof_operator (INSTRUCTION_GRAPH graph,register ADDRESS *ad_p) { ADDRESS ad_1; linearize_graph (graph->instruction_parameters[0].p,&ad_1); local_data_offset-=FLOAT_SIZE; instruction_ad_id (IMOVE,&ad_1,local_data_offset,B_STACK_POINTER); if (graph->node_count>1){ int freg; freg=get_fregister(); i_fmove_id_fr (local_data_offset,B_STACK_POINTER,freg); ad_p->ad_mode=P_F_REGISTER; ad_p->ad_register=freg; ad_p->ad_count_p=&graph->node_count; float_register_node (graph,freg); } else { ad_p->ad_mode=P_INDIRECT; ad_p->ad_offset=local_data_offset; ad_p->ad_register=B_STACK_POINTER; ad_p->ad_count_p=&ad_p->ad_count; ad_p->ad_count=1+1; } } #else static void linearize_fjoin_operator (INSTRUCTION_GRAPH graph,register ADDRESS *ad_p) { INSTRUCTION_GRAPH high_graph,low_graph; ADDRESS ad_1,ad_2; high_graph=graph->instruction_parameters[0].p; low_graph=graph->instruction_parameters[1].p; linearize_graph (low_graph,&ad_2); linearize_graph (high_graph,&ad_1); # ifdef sparc if (ad_1.ad_mode==P_INDIRECT && ad_2.ad_mode==P_INDIRECT){ int freg; freg=get_fregister(); instruction_ad_fr (IFMOVEHI,&ad_1,freg); instruction_ad_fr (IFMOVELO,&ad_2,freg); ad_p->ad_mode=P_F_REGISTER; ad_p->ad_register=freg; ad_p->ad_count_p=&graph->node_count; if (graph->node_count>1) float_register_node (graph,freg); return; } # endif local_data_offset-=FLOAT_SIZE; instruction_ad_id (IMOVE,&ad_2,local_data_offset+4,B_STACK_POINTER); instruction_ad_id (IMOVE,&ad_1,local_data_offset,B_STACK_POINTER); if (graph->node_count>1){ int freg; freg=get_fregister(); i_fmove_id_fr (local_data_offset,B_STACK_POINTER,freg); ad_p->ad_mode=P_F_REGISTER; ad_p->ad_register=freg; ad_p->ad_count_p=&graph->node_count; float_register_node (graph,freg); } else { ad_p->ad_mode=P_INDIRECT; ad_p->ad_offset=local_data_offset; ad_p->ad_register=B_STACK_POINTER; ad_p->ad_count_p=&ad_p->ad_count; ad_p->ad_count=1+1; } } #endif static int float_compare_node (INSTRUCTION_GRAPH graph,int i_test_1,int i_test_2) { ADDRESS ad_1,ad_2; linearize_float_graph (graph->instruction_parameters[0].p,&ad_1); linearize_float_graph (graph->instruction_parameters[1].p,&ad_2); if (ad_1.ad_mode==P_F_REGISTER){ instruction_ad_fr (IFCMP,&ad_2,ad_1.ad_register); if (--*ad_1.ad_count_p==0){ #ifdef FP_STACK_OPTIMIZATIONS last_instruction->instruction_parameters[1].parameter_flags |= FP_REG_LAST_USE; #endif free_fregister (ad_1.ad_register); } return i_test_2; } else { in_float_register (&ad_2); instruction_ad_fr (IFCMP,&ad_1,ad_2.ad_register); if (--*ad_2.ad_count_p==0){ #ifdef FP_STACK_OPTIMIZATIONS last_instruction->instruction_parameters[1].parameter_flags |= FP_REG_LAST_USE; #endif free_fregister (ad_2.ad_register); } return i_test_1; } } static void linearize_float_compare_operator (int i_test_1,int i_test_2,INSTRUCTION_GRAPH graph,ADDRESS *ad_p) { int condition; condition=float_compare_node (graph,i_test_1,i_test_2); condition_to_register (graph,condition,ad_p); } static void linearize_dyadic_commutative_float_operator (int instruction_code,register INSTRUCTION_GRAPH graph,ADDRESS *ad_p) { ADDRESS ad_1,ad_2; int reg_1; if (graph->order_left){ linearize_float_graph (graph->instruction_parameters[0].p,&ad_1); linearize_float_graph (graph->instruction_parameters[1].p,&ad_2); } else { linearize_float_graph (graph->instruction_parameters[1].p,&ad_2); linearize_float_graph (graph->instruction_parameters[0].p,&ad_1); } if (ad_1.ad_mode==P_F_REGISTER && *ad_1.ad_count_p==1 /* added 17-3-1999: prefer result in lowest register number */ && !(ad_2.ad_mode==P_F_REGISTER && *ad_2.ad_count_p==1 && ad_2.ad_registerad_mode=P_F_REGISTER; ad_p->ad_register=reg_1; ad_p->ad_count_p=&graph->node_count; if (*ad_p->ad_count_p>1) float_register_node (graph,reg_1); } static void linearize_dyadic_non_commutative_float_operator (int instruction_code,INSTRUCTION_GRAPH graph,ADDRESS *ad_p) { ADDRESS ad_1,ad_2; int reg_1; if (graph->order_left){ linearize_float_graph (graph->instruction_parameters[0].p,&ad_1); linearize_float_graph (graph->instruction_parameters[1].p,&ad_2); } else { linearize_float_graph (graph->instruction_parameters[1].p,&ad_2); linearize_float_graph (graph->instruction_parameters[0].p,&ad_1); } #if 1 # if (defined (I486) && !defined (G_AI64)) || defined (G_POWER) if (ad_1.ad_mode==P_F_REGISTER && *ad_1.ad_count_p==1 && !(ad_2.ad_mode==P_F_REGISTER && ad_2.ad_registerinstruction_parameters[1].parameter_flags=1; *ad_1.ad_count_p=0; } else # endif { struct parameter parameter1; int free_f_register; # if defined (FMADD) parameter1.parameter_flags=0; # endif free_f_register=fad_to_parameter_without_freeing_fregister (&ad_1,¶meter1); in_alterable_float_register (&ad_2); if (free_f_register){ #if defined (FP_STACK_OPTIMIZATIONS) || defined (FMADD) parameter1.parameter_flags |= FP_REG_LAST_USE; #endif free_fregister (ad_1.ad_register); } reg_1=ad_2.ad_register; instruction_p_fr (instruction_code,¶meter1,reg_1); # if defined (I486) || defined (G_POWER) last_instruction->instruction_parameters[1].parameter_flags=0; # endif } #else in_alterable_float_register (&ad_2); reg_1=ad_2.ad_register; instruction_ad_fr (instruction_code,&ad_1,reg_1); # if defined (I486) || defined (G_POWER) last_instruction->instruction_parameters[1].parameter_flags=0; # endif #endif ad_p->ad_mode=P_F_REGISTER; ad_p->ad_register=reg_1; ad_p->ad_count_p=&graph->node_count; if (*ad_p->ad_count_p>1) float_register_node (graph,reg_1); } static void linearize_itor_operator (INSTRUCTION_GRAPH graph,register ADDRESS *ad_p) { int reg_1; linearize_graph (graph->instruction_parameters[0].p,ad_p); to_data_addressing_mode (ad_p); reg_1=get_fregister(); instruction_lad_fr (IFMOVEL,ad_p,reg_1); ad_p->ad_mode=P_F_REGISTER; ad_p->ad_register=reg_1; ad_p->ad_count_p=&graph->node_count; if (*ad_p->ad_count_p>1) float_register_node (graph,reg_1); } static void linearize_monadic_float_operator (INSTRUCTION_GRAPH graph,register ADDRESS *ad_p,int i_code) { int freg; linearize_float_graph (graph->instruction_parameters[0].p,ad_p); if (ad_p->ad_mode==P_F_REGISTER && *ad_p->ad_count_p==1){ free_fregister (ad_p->ad_register); freg=get_fregister(); instruction_fr_fr (i_code,ad_p->ad_register,freg); #ifdef FP_STACK_OPTIMIZATIONS last_instruction->instruction_parameters[0].parameter_flags |= FP_REG_LAST_USE; #endif } else { freg=get_fregister(); instruction_ad_fr (i_code,ad_p,freg); } ad_p->ad_mode=P_F_REGISTER; ad_p->ad_register=freg; ad_p->ad_count_p=&graph->node_count; if (*ad_p->ad_count_p>1) float_register_node (graph,freg); } static void linearize_float_keep_operator (INSTRUCTION_GRAPH graph,ADDRESS *ad_p) { INSTRUCTION_GRAPH graph_1,graph_2; ADDRESS ad_1; graph_1=graph->instruction_parameters[0].p; graph_2=graph->instruction_parameters[1].p; linearize_graph (graph_1,&ad_1); switch (ad_1.ad_mode){ case P_REGISTER: case P_INDIRECT: if (--*ad_1.ad_count_p==0) free_register (ad_1.ad_register); } linearize_float_graph (graph_2,ad_p); if (graph->node_count>1){ in_float_register (ad_p); /* changed 10-12-97 float_register_node (graph,ad_p->ad_register); ad_p->ad_count_p=&graph->node_count; */ float_register_node (graph_2,ad_p->ad_register); graph_2->node_count += graph->node_count; ad_p->ad_count_p=&graph_2->node_count; graph->instruction_parameters[0].p=graph_2; graph->instruction_code=GINDIRECTION; /* */ } } static void linearize_fload_x_operator (INSTRUCTION_GRAPH graph,ADDRESS *ad_p) { INSTRUCTION_GRAPH graph_1,graph_2; int offset; graph_1=graph->instruction_parameters[0].p; offset=graph->instruction_parameters[1].i; graph_2=graph->instruction_parameters[2].p; #if defined (sparc) || defined (G_POWER) if (offset!=0 && graph_2!=NULL){ graph_1=graph_2; graph_2=NULL; } #endif if (graph_2!=NULL){ ADDRESS ad_1; if (graph->order_left){ linearize_graph (graph_1,ad_p); linearize_graph (graph_2,&ad_1); } else { linearize_graph (graph_2,&ad_1); linearize_graph (graph_1,ad_p); } in_data_register (&ad_1); in_address_register (ad_p); if (graph->node_count<=1){ ADDRESS *i_ad_p; ad_p->ad_mode=P_INDEXED; ad_p->ad_load_x_graph=graph; i_ad_p=(ADDRESS*)fast_memory_allocate (sizeof (ADDRESS)); graph->instruction_parameters[1].p=(INSTRUCTION_GRAPH)i_ad_p; i_ad_p->ad_mode=P_INDEXED; i_ad_p->ad_offset=offset; i_ad_p->ad_areg=ad_p->ad_register; i_ad_p->ad_dreg=ad_1.ad_register; i_ad_p->ad_count_p=ad_p->ad_count_p; if (ad_1.ad_count_p!=&ad_1.ad_count) /* it points to a counter in a graph node */ i_ad_p->ad_count_p2=ad_1.ad_count_p; else { /* prevent a scope problem */ i_ad_p->ad_count_p2=&ad_p->ad_count2; ad_p->ad_count2=ad_1.ad_count; } graph->node_count=0; graph->inode_arity|=LOAD_X_TO_ADDRESS; } else { int reg_1; if (--*ad_p->ad_count_p==0) free_aregister (ad_p->ad_register); if (--*ad_1.ad_count_p==0) free_dregister (ad_1.ad_register); reg_1=get_fregister(); #ifdef ALIGN_REAL_ARRAYS i_fmove_x_fr (offset,ad_p->ad_register,ad_1.ad_register,reg_1,graph->inode_arity & LOAD_STORE_ALIGNED_REAL); #else i_fmove_x_fr (offset,ad_p->ad_register,ad_1.ad_register,reg_1); #endif ad_p->ad_mode=P_F_REGISTER; ad_p->ad_register=reg_1; ad_p->ad_count_p=&graph->node_count; float_register_node (graph,reg_1); } } else { linearize_graph (graph_1,ad_p); in_address_register (ad_p); if (graph->node_count<=1){ ADDRESS *i_ad_p; ad_p->ad_mode=P_INDEXED; ad_p->ad_load_x_graph=graph; i_ad_p=(ADDRESS*)fast_memory_allocate (sizeof (ADDRESS)); graph->instruction_parameters[1].p=(INSTRUCTION_GRAPH)i_ad_p; i_ad_p->ad_mode=P_INDIRECT; i_ad_p->ad_offset=offset>>2; i_ad_p->ad_register=ad_p->ad_register; i_ad_p->ad_count_p=ad_p->ad_count_p; graph->node_count=0; graph->inode_arity|=LOAD_X_TO_ADDRESS; } else { int reg_1; if (--*ad_p->ad_count_p==0) free_aregister (ad_p->ad_register); reg_1=get_fregister(); #ifdef ALIGN_REAL_ARRAYS i_fmove_id_fr_f (offset>>2,ad_p->ad_register,reg_1,graph->inode_arity & LOAD_STORE_ALIGNED_REAL); #else i_fmove_id_fr (offset>>2,ad_p->ad_register,reg_1); #endif ad_p->ad_mode=P_F_REGISTER; ad_p->ad_register=reg_1; ad_p->ad_count_p=&graph->node_count; float_register_node (graph,reg_1); } } } static void linearize_float_graph (register INSTRUCTION_GRAPH graph,register ADDRESS *ad_p) { switch (graph->instruction_code){ case GFREGISTER: ad_p->ad_mode=P_F_REGISTER; ad_p->ad_register=graph->instruction_parameters[0].i; ad_p->ad_count_p=&graph->node_count; break; case GGFREGISTER: ad_p->ad_mode=P_F_REGISTER; ad_p->ad_register=graph->instruction_parameters[0].i; ad_p->ad_count_p=&ad_p->ad_count; ad_p->ad_count=1+1; break; case GFLOAD: { if (graph->node_count<=1){ ad_p->ad_mode=P_INDIRECT; ad_p->ad_count_p=&ad_p->ad_count; ad_p->ad_count=1+1; ad_p->ad_offset=graph->instruction_parameters[0].i; ad_p->ad_register=graph->instruction_parameters[1].i; graph->node_count=0; } else { int reg_1; reg_1=get_fregister(); i_fmove_id_fr (graph->instruction_parameters[0].i, graph->instruction_parameters[1].i,reg_1); ad_p->ad_mode=P_F_REGISTER; ad_p->ad_register=reg_1; ad_p->ad_count_p=&graph->node_count; float_register_node (graph,reg_1); } return; } case GFLOAD_I: if (graph->node_count<=1){ ad_p->ad_mode=P_F_IMMEDIATE; ad_p->ad_real=*(DOUBLE*)&graph->instruction_parameters[0]; } else { int reg_1; reg_1=get_fregister(); i_fmove_if_fr (*(DOUBLE*)&graph->instruction_parameters[0],reg_1); ad_p->ad_mode=P_F_REGISTER; ad_p->ad_register=reg_1; ad_p->ad_count_p=&graph->node_count; float_register_node (graph,reg_1); } return; case GFLOAD_ID: { INSTRUCTION_GRAPH graph_1; graph_1=graph->instruction_parameters[1].p; linearize_graph (graph_1,ad_p); in_address_register (ad_p); if (graph->node_count<=1){ ad_p->ad_mode=P_INDIRECT; ad_p->ad_offset=graph->instruction_parameters[0].i; /* added 26-7-97 */ --graph->node_count; /* */ } else { int reg_1; if (--*ad_p->ad_count_p==0) free_aregister (ad_p->ad_register); reg_1=get_fregister(); i_fmove_id_fr (graph->instruction_parameters[0].i,ad_p->ad_register,reg_1); ad_p->ad_mode=P_F_REGISTER; ad_p->ad_register=reg_1; ad_p->ad_count_p=&graph->node_count; float_register_node (graph,reg_1); } return; } case GFMOVEMI: linearize_fmovemi_operator (graph,ad_p); return; case GFLOAD_X: linearize_fload_x_operator (graph,ad_p); return; case GFADD: linearize_dyadic_commutative_float_operator (IFADD,graph,ad_p); return; case GFDIV: linearize_dyadic_non_commutative_float_operator (IFDIV,graph,ad_p); return; case GFMUL: linearize_dyadic_commutative_float_operator (IFMUL,graph,ad_p); return; case GFREM: linearize_dyadic_non_commutative_float_operator (IFREM,graph,ad_p); return; case GFSUB: linearize_dyadic_non_commutative_float_operator (IFSUB,graph,ad_p); return; #ifndef G_A64 case GFJOIN: linearize_fjoin_operator (graph,ad_p); return; #endif case GFITOR: linearize_itor_operator (graph,ad_p); return; case GFCOS: linearize_monadic_float_operator (graph,ad_p,IFCOS); break; case GFNEG: linearize_monadic_float_operator (graph,ad_p,IFNEG); break; case GFABS: linearize_monadic_float_operator (graph,ad_p,IFABS); break; case GFSIN: linearize_monadic_float_operator (graph,ad_p,IFSIN); break; case GFTAN: linearize_monadic_float_operator (graph,ad_p,IFTAN); break; #ifdef M68000 case GFASIN: linearize_monadic_float_operator (graph,ad_p,IFASIN); break; case GFACOS: linearize_monadic_float_operator (graph,ad_p,IFACOS); break; case GFATAN: linearize_monadic_float_operator (graph,ad_p,IFATAN); break; case GFLN: linearize_monadic_float_operator (graph,ad_p,IFLN); break; case GFLOG10: linearize_monadic_float_operator (graph,ad_p,IFLOG10); break; case GFEXP: linearize_monadic_float_operator (graph,ad_p,IFEXP); break; #endif case GFKEEP: linearize_float_keep_operator (graph,ad_p); break; case GINDIRECTION: linearize_float_graph (graph->instruction_parameters[0].p,ad_p); break; #if !defined (G_POWER) case GFSQRT: linearize_monadic_float_operator (graph,ad_p,IFSQRT); break; #endif #ifdef G_A64 case GTOF: linearize_tof_operator (graph,ad_p); return; #endif default: /* printf ("%d %d\n",(int)graph,graph->instruction_code); */ internal_error_in_function ("linearize_float_graph"); } } static void linearize_fstore_operator (INSTRUCTION_GRAPH graph) { int offset,stack_pointer; ADDRESS ad_1; linearize_float_graph (graph->instruction_parameters[2].p,&ad_1); offset=graph->instruction_parameters[0].i; stack_pointer=graph->instruction_parameters[1].i; linearize_load_graph (graph->instruction_parameters[3].p); #ifndef G_A64 linearize_load_graph (graph->instruction_parameters[4].p); #endif move_float_ad_id (&ad_1,offset,stack_pointer); } static void linearize_fstore_x_operator (register INSTRUCTION_GRAPH graph,register ADDRESS *ad_p); static void linearize_fstore_r_operator (register INSTRUCTION_GRAPH graph) { INSTRUCTION_GRAPH *register_graph_1_p,*register_graph_2_p; register int reg_1; ADDRESS ad_1; linearize_float_graph (graph->instruction_parameters[1].p,&ad_1); reg_1=graph->instruction_parameters[0].i; if ((unsigned)reg_1<(unsigned)N_FLOAT_PARAMETER_REGISTERS) register_graph_1_p=&global_block.block_graph_f_register_parameter_node[reg_1]; else register_graph_1_p=NULL; if (ad_1.ad_mode==P_F_REGISTER && ad_1.ad_register==reg_1){ if (register_graph_1_p!=NULL && *register_graph_1_p!=NULL) (*register_graph_1_p)->instruction_code=GGFREGISTER; return; } if (ad_1.ad_mode==P_F_REGISTER){ register int reg_2; reg_2=ad_1.ad_register; if ((unsigned)reg_2<(unsigned)N_FLOAT_PARAMETER_REGISTERS) register_graph_2_p=&global_block.block_graph_f_register_parameter_node[reg_2]; else register_graph_2_p=NULL; if (register_graph_1_p!=NULL && *register_graph_1_p!=NULL && (*register_graph_1_p)->node_count>0){ #if defined (FP_STACK_OPTIMIZATIONS) && !defined (G_AI64) if (register_graph_2_p!=NULL && (*register_graph_2_p==NULL || (*register_graph_2_p)->instruction_code!=GGFREGISTER)){ INSTRUCTION_GRAPH graph; i_fexg_fr_fr (reg_2,reg_1); (*register_graph_1_p)->instruction_parameters[0].i=reg_2; if (*register_graph_2_p!=NULL){ (*register_graph_2_p)->instruction_code=GGFREGISTER; (*register_graph_2_p)->instruction_parameters[0].i=reg_1; } graph=*register_graph_1_p; *register_graph_1_p=*register_graph_2_p; *register_graph_2_p=graph; } else { #endif register int reg_2; reg_2=get_fregister(); if ((unsigned)reg_2<(unsigned)N_FLOAT_PARAMETER_REGISTERS) register_graph_2_p=&global_block.block_graph_f_register_parameter_node [reg_2]; else register_graph_2_p=NULL; i_fmove_fr_fr (reg_1,reg_2); instruction_ad_fr (IFMOVE,&ad_1,reg_1); (*register_graph_1_p)->instruction_parameters[0].i=reg_2; if (register_graph_2_p!=NULL) *register_graph_2_p=*register_graph_1_p; *register_graph_1_p=NULL; #if defined (FP_STACK_OPTIMIZATIONS) && !defined (G_AI64) } #endif } else { i_fmove_fr_fr (reg_2,reg_1); if (--*ad_1.ad_count_p==0){ #ifdef FP_STACK_OPTIMIZATIONS last_instruction->instruction_parameters[0].parameter_flags |= FP_REG_LAST_USE; #endif free_fregister (reg_2); } } } else { if (ad_1.ad_mode==P_INDIRECT) --*ad_1.ad_count_p; if (register_graph_1_p!=NULL && *register_graph_1_p!=NULL && (*register_graph_1_p)->node_count>0) { register int reg_2; reg_2=get_fregister(); if ((unsigned)reg_2<(unsigned)N_FLOAT_PARAMETER_REGISTERS) register_graph_2_p= &global_block.block_graph_f_register_parameter_node [reg_2]; else register_graph_2_p=NULL; i_fmove_fr_fr (reg_1,reg_2); (*register_graph_1_p)->instruction_parameters[0].i=reg_2; if (register_graph_2_p!=NULL) *register_graph_2_p=*register_graph_1_p; *register_graph_1_p=NULL; } if (ad_1.ad_mode==P_INDIRECT) ++*ad_1.ad_count_p; instruction_ad_fr (IFMOVE,&ad_1,reg_1); } allocate_fregister (reg_1); } static void linearize_create_r_operator (INSTRUCTION_GRAPH graph,ADDRESS *ad_p,int result_register) { ADDRESS ad_1,ad_2; int reg_1; #ifdef G_A64 last_block->block_n_new_heap_cells+=2; #else last_block->block_n_new_heap_cells+=3; #endif #ifndef M68000 # ifdef I486 if (offset_from_heap_register+(3<<2) >= 127){ # else # ifdef G_POWER if (offset_from_heap_register+(3<<2) >= 32767){ heap_pointer_offset_in_basic_block+=offset_from_heap_register; # else if (offset_from_heap_register+(3<<2) >= 4096){ # endif # endif i_add_i_r (offset_from_heap_register,HEAP_POINTER); IF_G_POWER (last_heap_pointer_update=last_instruction;) offset_from_heap_register=0; } #endif linearize_float_graph (graph->instruction_parameters[1].p,&ad_2); linearize_graph (graph->instruction_parameters[0].p,&ad_1); if (result_register!=0 && try_allocate_register_number (result_register>>1)) reg_1=result_register>>1; else if (graph->instruction_d_min_a_cost<=0) reg_1=get_dregister(); else reg_1=get_aregister(); #ifdef G_POWER i_lea_id_r (offset_from_heap_register+4+NODE_POINTER_OFFSET,HEAP_POINTER,reg_1); #else # ifndef M68000 if (offset_from_heap_register!=0) i_lea_id_r (offset_from_heap_register,HEAP_POINTER,reg_1); else # endif i_move_r_r (HEAP_POINTER,reg_1); #endif #ifdef M68000 instruction_ad_pi (IMOVE,&ad_1,HEAP_POINTER); move_float_ad_pi (&ad_2,HEAP_POINTER); #else # ifdef G_POWER instruction_ad_id (IMOVE,&ad_1,offset_from_heap_register+4,HEAP_POINTER); move_float_ad_id (&ad_2,offset_from_heap_register+4+STACK_ELEMENT_SIZE,HEAP_POINTER); # else instruction_ad_id (IMOVE,&ad_1,offset_from_heap_register,HEAP_POINTER); move_float_ad_id (&ad_2,offset_from_heap_register+STACK_ELEMENT_SIZE,HEAP_POINTER); # endif # ifdef G_A64 offset_from_heap_register+=16; # else offset_from_heap_register+=12; # endif #endif ad_p->ad_mode=P_REGISTER; ad_p->ad_register=reg_1; ad_p->ad_count_p=&graph->node_count; if (*ad_p->ad_count_p>1) register_node (graph,reg_1); } static void linearize_rtoi_operator (INSTRUCTION_GRAPH graph,register ADDRESS *ad_p) { int reg; linearize_float_graph (graph->instruction_parameters[0].p,ad_p); in_float_register (ad_p); reg=get_dregister(); i_fmovel_fr_r (ad_p->ad_register,reg); if (--*ad_p->ad_count_p==0){ #ifdef FP_STACK_OPTIMIZATIONS last_instruction->instruction_parameters[0].parameter_flags |= FP_REG_LAST_USE; #endif free_fregister (ad_p->ad_register); } if (graph->instruction_d_min_a_cost>0){ int areg; areg=get_aregister(); i_move_r_r (reg,areg); free_dregister (reg); reg=areg; } ad_p->ad_mode=P_REGISTER; ad_p->ad_register=reg; ad_p->ad_count_p=&graph->node_count; if (*ad_p->ad_count_p>1) register_node (graph,reg); } static void linearize_load_x_operator (INSTRUCTION_GRAPH graph,ADDRESS *ad_p #ifdef LOAD_X_PARAMETER_REGISTER ,int result_register #endif ) { INSTRUCTION_GRAPH graph_1,graph_2; int offset; graph_1=graph->instruction_parameters[0].p; offset=graph->instruction_parameters[1].i; graph_2=graph->instruction_parameters[2].p; #if defined (sparc) || defined (G_POWER) if (offset!=0 && graph_2!=NULL){ graph_1=graph_2; graph_2=NULL; } #endif if (graph_2!=NULL){ ADDRESS ad_1; if (graph->order_left){ linearize_graph (graph_1,ad_p); linearize_graph (graph_2,&ad_1); } else { linearize_graph (graph_2,&ad_1); linearize_graph (graph_1,ad_p); } in_data_register (&ad_1); in_address_register (ad_p); if (graph->node_count<=1){ ADDRESS *i_ad_p; ad_p->ad_mode=P_INDEXED; ad_p->ad_load_x_graph=graph; i_ad_p=(ADDRESS*)fast_memory_allocate (sizeof (ADDRESS)); graph->instruction_parameters[1].p=(INSTRUCTION_GRAPH)i_ad_p; i_ad_p->ad_mode=P_INDEXED; i_ad_p->ad_offset=offset; i_ad_p->ad_areg=ad_p->ad_register; i_ad_p->ad_dreg=ad_1.ad_register; i_ad_p->ad_count_p=ad_p->ad_count_p; if (ad_1.ad_count_p!=&ad_1.ad_count) /* it points to a counter in a graph node */ i_ad_p->ad_count_p2=ad_1.ad_count_p; else { /* prevent a scope problem */ i_ad_p->ad_count_p2=&ad_p->ad_count2; ad_p->ad_count2=ad_1.ad_count; } graph->node_count=0; graph->inode_arity|=LOAD_X_TO_ADDRESS; } else { int reg_1; if (--*ad_p->ad_count_p==0) free_aregister (ad_p->ad_register); if (--*ad_1.ad_count_p==0) free_dregister (ad_1.ad_register); #ifdef LOAD_X_PARAMETER_REGISTER if (result_register!=0 && try_allocate_register_number (result_register>>1)) reg_1=result_register>>1; else #endif if (graph->instruction_d_min_a_cost<=0) reg_1=get_dregister(); else reg_1=get_aregister(); i_move_x_r (offset,ad_p->ad_register,ad_1.ad_register,reg_1); ad_p->ad_mode=P_REGISTER; ad_p->ad_register=reg_1; ad_p->ad_count_p=&graph->node_count; register_node (graph,reg_1); } } else { linearize_graph (graph_1,ad_p); in_address_register (ad_p); if (graph->node_count<=1){ ADDRESS *i_ad_p; ad_p->ad_mode=P_INDEXED; ad_p->ad_load_x_graph=graph; i_ad_p=(ADDRESS*)fast_memory_allocate (sizeof (ADDRESS)); graph->instruction_parameters[1].p=(INSTRUCTION_GRAPH)i_ad_p; i_ad_p->ad_mode=P_INDIRECT; i_ad_p->ad_offset=offset>>2; i_ad_p->ad_register=ad_p->ad_register; i_ad_p->ad_count_p=ad_p->ad_count_p; graph->node_count=0; graph->inode_arity|=LOAD_X_TO_ADDRESS; } else { int reg_1; if (--*ad_p->ad_count_p==0) free_aregister (ad_p->ad_register); #ifdef LOAD_X_PARAMETER_REGISTER if (result_register!=0 && try_allocate_register_number (result_register>>1)) reg_1=result_register>>1; else #endif if (graph->instruction_d_min_a_cost<=0) reg_1=get_dregister(); else reg_1=get_aregister(); i_move_id_r (offset>>2,ad_p->ad_register,reg_1); ad_p->ad_mode=P_REGISTER; ad_p->ad_register=reg_1; ad_p->ad_count_p=&graph->node_count; register_node (graph,reg_1); } } } static void linearize_store_r_node (INSTRUCTION_GRAPH graph) { INSTRUCTION_GRAPH *register_graph_1_p,*register_graph_2_p; int reg_1; ADDRESS ad_1; switch (graph->instruction_parameters[1].p->instruction_code){ case GCREATE: linearize_create_operator (graph->instruction_parameters[1].p,&ad_1,(graph->instruction_parameters[0].i<<1)+1); break; case GCREATE_R: linearize_create_r_operator (graph->instruction_parameters[1].p,&ad_1,(graph->instruction_parameters[0].i<<1)+1); break; #ifdef LOAD_X_PARAMETER_REGISTER case GLOAD_X: linearize_load_x_operator (graph->instruction_parameters[1].p,&ad_1,(graph->instruction_parameters[0].i<<1)+1); break; #endif default: linearize_graph (graph->instruction_parameters[1].p,&ad_1); } reg_1=graph->instruction_parameters[0].i; register_graph_1_p=NULL; if (is_d_register (reg_1)){ if ((unsigned)d_reg_num (reg_1)<(unsigned)N_DATA_PARAMETER_REGISTERS #ifdef MORE_PARAMETER_REGISTERS + N_ADDRESS_PARAMETER_REGISTERS #endif ) register_graph_1_p=&global_block.block_graph_d_register_parameter_node[d_reg_num (reg_1)]; } else if ((unsigned)a_reg_num (reg_1)<(unsigned)N_ADDRESS_PARAMETER_REGISTERS) register_graph_1_p=&global_block.block_graph_a_register_parameter_node[a_reg_num (reg_1)]; if (ad_1.ad_mode==P_REGISTER && ad_1.ad_register==reg_1){ if (register_graph_1_p!=NULL && *register_graph_1_p!=NULL) (*register_graph_1_p)->instruction_code=GGREGISTER; return; } if (ad_1.ad_mode==P_REGISTER){ int reg_2; reg_2=ad_1.ad_register; register_graph_2_p=NULL; if ((unsigned)d_reg_num (reg_2)<(unsigned)N_DATA_PARAMETER_REGISTERS #ifdef MORE_PARAMETER_REGISTERS + N_ADDRESS_PARAMETER_REGISTERS #endif ) register_graph_2_p=&global_block.block_graph_d_register_parameter_node[d_reg_num (reg_2)]; if ((unsigned)a_reg_num (reg_2)<(unsigned)N_ADDRESS_PARAMETER_REGISTERS) register_graph_2_p=&global_block.block_graph_a_register_parameter_node[a_reg_num (reg_2)]; if (register_graph_1_p!=NULL && *register_graph_1_p!=NULL && (*register_graph_1_p)->node_count>0){ #if defined (M68000) || defined (I486) if (register_graph_2_p!=NULL && (*register_graph_2_p==NULL || (*register_graph_2_p)->instruction_code!=GGREGISTER)){ INSTRUCTION_GRAPH graph; i_exg_r_r (reg_2,reg_1); (*register_graph_1_p)->instruction_parameters[0].i=reg_2; if (*register_graph_2_p!=NULL){ (*register_graph_2_p)->instruction_code=GGREGISTER; (*register_graph_2_p)->instruction_parameters[0].i=reg_1; } graph=*register_graph_1_p; *register_graph_1_p=*register_graph_2_p; *register_graph_2_p=graph; } else { #endif register int reg_2; register_graph_2_p=NULL; if ((*register_graph_1_p)->instruction_d_min_a_cost<=0){ reg_2=get_dregister(); if ((unsigned)d_reg_num (reg_2)<(unsigned)N_DATA_PARAMETER_REGISTERS #ifdef MORE_PARAMETER_REGISTERS + N_ADDRESS_PARAMETER_REGISTERS #endif ) register_graph_2_p=&global_block.block_graph_d_register_parameter_node[d_reg_num (reg_2)]; } else { reg_2=get_aregister(); if ((unsigned)a_reg_num (reg_2)<(unsigned)N_ADDRESS_PARAMETER_REGISTERS) register_graph_2_p=&global_block.block_graph_a_register_parameter_node[a_reg_num (reg_2)]; } i_move_r_r (reg_1,reg_2); instruction_ad_r (IMOVE,&ad_1,reg_1); (*register_graph_1_p)->instruction_parameters[0].i=reg_2; if (register_graph_2_p!=NULL) *register_graph_2_p=*register_graph_1_p; *register_graph_1_p=NULL; #if defined (M68000) || defined (I486) } #endif } else { i_move_r_r (reg_2,reg_1); if (--*ad_1.ad_count_p==0) free_register (reg_2); } } else { switch (ad_1.ad_mode){ case P_INDIRECT: --*ad_1.ad_count_p; break; case P_INDEXED: { INSTRUCTION_GRAPH load_x_graph; ADDRESS *i_ad_p; load_x_graph=ad_1.ad_load_x_graph; i_ad_p=(ADDRESS *)load_x_graph->instruction_parameters[1].p; #ifdef M68000 if ((load_x_graph->inode_arity & LOAD_X_TO_ADDRESS) && i_ad_p->ad_mode==P_INDEXED) --*i_ad_p->ad_count_p2; #endif --*i_ad_p->ad_count_p; break; } } if (register_graph_1_p!=NULL && *register_graph_1_p!=NULL && (*register_graph_1_p)->node_count>0){ int reg_2; register_graph_2_p=NULL; if ((*register_graph_1_p)->instruction_d_min_a_cost<=0){ reg_2=get_dregister(); if ((unsigned)d_reg_num (reg_2)<(unsigned)N_DATA_PARAMETER_REGISTERS #ifdef MORE_PARAMETER_REGISTERS + N_ADDRESS_PARAMETER_REGISTERS #endif ) register_graph_2_p=&global_block.block_graph_d_register_parameter_node[d_reg_num (reg_2)]; } else { reg_2=get_aregister(); if ((unsigned)a_reg_num (reg_2)<(unsigned)N_ADDRESS_PARAMETER_REGISTERS) register_graph_2_p=&global_block.block_graph_a_register_parameter_node[a_reg_num (reg_2)]; } i_move_r_r (reg_1,reg_2); (*register_graph_1_p)->instruction_parameters[0].i=reg_2; if (register_graph_2_p!=NULL) *register_graph_2_p=*register_graph_1_p; *register_graph_1_p=NULL; } switch (ad_1.ad_mode){ case P_INDIRECT: ++*ad_1.ad_count_p; break; case P_INDEXED: { INSTRUCTION_GRAPH load_x_graph; ADDRESS *i_ad_p; load_x_graph=ad_1.ad_load_x_graph; i_ad_p=(ADDRESS *)load_x_graph->instruction_parameters[1].p; #ifdef M68000 if ((load_x_graph->inode_arity & LOAD_X_TO_ADDRESS) && i_ad_p->ad_mode==P_INDEXED) ++*i_ad_p->ad_count_p2; #endif ++*i_ad_p->ad_count_p; break; } } instruction_ad_r (IMOVE,&ad_1,reg_1); } if (is_a_register (reg_1)) allocate_aregister (reg_1); else allocate_dregister (reg_1); } static void linearize_load_b_x_operator (register INSTRUCTION_GRAPH graph,register ADDRESS *ad_p) { register INSTRUCTION_GRAPH graph_1,graph_2; register int offset; graph_1=graph->instruction_parameters[0].p; offset=graph->instruction_parameters[1].i; graph_2=graph->instruction_parameters[2].p; if (graph_2!=NULL){ ADDRESS ad_1; if (graph->order_left){ linearize_graph (graph_1,ad_p); linearize_graph (graph_2,&ad_1); } else { linearize_graph (graph_2,&ad_1); linearize_graph (graph_1,ad_p); } #if defined (sparc) || defined (G_POWER) { int reg_1,reg_2; in_register (&ad_1); in_register (ad_p); if (--*ad_1.ad_count_p==0) free_register (ad_1.ad_register); if (--*ad_p->ad_count_p==0) free_register (ad_p->ad_register); if (offset>>2==0){ if (graph->instruction_d_min_a_cost<=0) reg_2=get_dregister(); else reg_2=get_aregister(); i_moveb_x_r (ad_p->ad_register,ad_1.ad_register,reg_2); } else { reg_1=get_aregister(); i_lea_x_r (ad_p->ad_register,ad_1.ad_register,reg_1); free_aregister (reg_1); if (graph->instruction_d_min_a_cost<=0) reg_2=get_dregister(); else reg_2=get_aregister(); i_moveb_id_r (offset>>2,reg_1,reg_2); } # ifdef G_POWER if (offset & 1) i_extb_r (reg_2); # endif ad_p->ad_mode=P_REGISTER; ad_p->ad_register=reg_2; ad_p->ad_count_p=&graph->node_count; if (graph->node_count<=1) graph->inode_arity=(graph->inode_arity & ~LOAD_X_TO_ADDRESS) | LOAD_X_TO_REGISTER; else register_node (graph,reg_2); } #else { int reg_1; in_data_register (&ad_1); in_address_register (ad_p); if (--*ad_p->ad_count_p==0) free_aregister (ad_p->ad_register); if (--*ad_1.ad_count_p==0) free_dregister (ad_1.ad_register); reg_1=get_dregister(); # ifdef I486 i_moveb_x_r (offset & ~3,ad_p->ad_register,ad_1.ad_register,reg_1); # else if (offset & 1){ i_moveb_x_r (offset & ~3,ad_p->ad_register,ad_1.ad_register,reg_1); i_extb_r (reg_1); } else { if (ad_1.ad_register==reg_1){ i_moveb_x_r (offset,ad_p->ad_register,ad_1.ad_register,reg_1); i_and_i_r (255,reg_1); } else { i_move_i_r (0,reg_1); i_moveb_x_r (offset,ad_p->ad_register,ad_1.ad_register,reg_1); } } # endif ad_p->ad_mode=P_REGISTER; ad_p->ad_register=reg_1; ad_p->ad_count_p=&graph->node_count; if (graph->node_count<=1) graph->inode_arity=(graph->inode_arity & ~LOAD_X_TO_ADDRESS) | LOAD_X_TO_REGISTER; else register_node (graph,reg_1); } #endif } else { int reg_1; linearize_graph (graph_1,ad_p); in_address_register (ad_p); if (--*ad_p->ad_count_p==0) free_aregister (ad_p->ad_register); if (graph->instruction_d_min_a_cost<=0) reg_1=get_dregister(); else reg_1=get_aregister(); #ifdef M68000 if (!(offset & 1)) i_move_i_r (0,reg_1); #endif i_moveb_id_r (offset>>2,ad_p->ad_register,reg_1); #if defined (M68000) || defined (G_POWER) if (offset & 1) i_extb_r (reg_1); #endif ad_p->ad_mode=P_REGISTER; ad_p->ad_register=reg_1; ad_p->ad_count_p=&graph->node_count; if (graph->node_count<=1) graph->inode_arity=(graph->inode_arity & ~LOAD_X_TO_ADDRESS) | LOAD_X_TO_REGISTER; else register_node (graph,reg_1); } } #if 0 static int selects_from_array (INSTRUCTION_GRAPH select_graph,INSTRUCTION_GRAPH graph) { if (select_graph==graph) return 1; switch (select_graph->instruction_code){ case GLOAD_X: case GFLOAD_X: case GLOAD_B_X: return selects_from_array (select_graph->instruction_parameters[0].p,graph); case GLOAD_ID: return selects_from_array (select_graph->instruction_parameters[1].p,graph); default: return 0; } } #endif static void do_array_selects_before_update (INSTRUCTION_GRAPH select_graph,INSTRUCTION_GRAPH graph_1,INSTRUCTION_GRAPH graph_2) { for (; select_graph!=NULL; ){ switch (select_graph->instruction_code){ case GLOAD_X: #if 1 if (graph_2==select_graph->instruction_parameters[0].p){ #else if (selects_from_array (select_graph->instruction_parameters[0].p,graph_2)){ #endif if (select_graph->node_count>0){ ADDRESS s_ad; ++select_graph->node_count; linearize_load_x_operator (select_graph,&s_ad #ifdef LOAD_X_PARAMETER_REGISTER ,0 #endif ); --select_graph->node_count; } else if ((select_graph->inode_arity & LOAD_X_TO_ADDRESS) && select_graph!=graph_1){ ADDRESS *i_ad_p; int dreg; i_ad_p=(ADDRESS *)select_graph->instruction_parameters[1].p; select_graph->inode_arity ^= (LOAD_X_TO_ADDRESS | LOAD_X_TO_REGISTER); if (i_ad_p->ad_mode==P_INDEXED){ if (--*i_ad_p->ad_count_p==0) free_aregister (i_ad_p->ad_areg); if (--*i_ad_p->ad_count_p2==0) free_dregister (i_ad_p->ad_dreg); dreg=get_dregister(); i_move_x_r (i_ad_p->ad_offset,i_ad_p->ad_areg,i_ad_p->ad_dreg,dreg); } else { if (--*i_ad_p->ad_count_p==0) free_aregister (i_ad_p->ad_register); dreg=get_dregister(); i_move_id_r (i_ad_p->ad_offset,i_ad_p->ad_register,dreg); } i_ad_p->ad_register=dreg; } } break; case GLOAD_B_X: #if 1 if (graph_2==select_graph->instruction_parameters[0].p){ #else if (selects_from_array (select_graph->instruction_parameters[0].p,graph_2)){ #endif if (select_graph->node_count>0 /* added 29-2-2000: */ && !(select_graph->inode_arity & LOAD_X_TO_REGISTER) /**/){ ADDRESS s_ad; ++select_graph->node_count; linearize_load_b_x_operator (select_graph,&s_ad); --select_graph->node_count; } } break; case GFLOAD_X: #if 1 if (graph_2==select_graph->instruction_parameters[0].p){ #else if (selects_from_array (select_graph->instruction_parameters[0].p,graph_2)){ #endif if (select_graph->node_count>0){ ADDRESS s_ad; ++select_graph->node_count; linearize_fload_x_operator (select_graph,&s_ad); --select_graph->node_count; } else if ((select_graph->inode_arity & LOAD_X_TO_ADDRESS) && select_graph!=graph_1){ ADDRESS *i_ad_p; int freg; i_ad_p=(ADDRESS *)select_graph->instruction_parameters[1].p; select_graph->inode_arity ^= (LOAD_X_TO_ADDRESS | LOAD_X_TO_REGISTER);; if (i_ad_p->ad_mode==P_INDEXED){ if (--*i_ad_p->ad_count_p==0) free_aregister (i_ad_p->ad_areg); if (--*i_ad_p->ad_count_p2==0) free_dregister (i_ad_p->ad_dreg); freg=get_fregister(); #ifdef ALIGN_REAL_ARRAYS i_fmove_x_fr (i_ad_p->ad_offset,i_ad_p->ad_areg,i_ad_p->ad_dreg,freg,select_graph->inode_arity & LOAD_STORE_ALIGNED_REAL); #else i_fmove_x_fr (i_ad_p->ad_offset,i_ad_p->ad_areg,i_ad_p->ad_dreg,freg); #endif } else { if (--*i_ad_p->ad_count_p==0) free_aregister (i_ad_p->ad_register); freg=get_fregister(); #ifdef ALIGN_REAL_ARRAYS i_fmove_id_fr_f (i_ad_p->ad_offset,i_ad_p->ad_register,freg,select_graph->inode_arity & LOAD_STORE_ALIGNED_REAL); #else i_fmove_id_fr (i_ad_p->ad_offset,i_ad_p->ad_register,freg); #endif } i_ad_p->ad_register=freg; } } break; case GREGISTER: case GFREGISTER: #ifndef G_A64 case GFHIGH: case GFLOW: #endif case GGREGISTER: break; #if defined (G_A64) case GFROMF: select_graph=select_graph->instruction_parameters[0].p; continue; #endif default: internal_error_in_function ("do_array_selects_before_update"); } select_graph=select_graph->instruction_parameters[3].p; } } static void linearize_store_x_operator (int i_instruction_code,register INSTRUCTION_GRAPH graph,register ADDRESS *ad_p) { INSTRUCTION_GRAPH graph_1,graph_2,graph_3; int offset; ADDRESS ad_1,ad_3; graph_1=graph->instruction_parameters[0].p; graph_2=graph->instruction_parameters[1].p; offset=graph->instruction_parameters[2].i; graph_3=graph->instruction_parameters[3].p; if (graph_3==NULL){ if (graph->order_left){ linearize_graph (graph_1,&ad_1); linearize_graph (graph_2,ad_p); } else { linearize_graph (graph_1,&ad_1); linearize_graph (graph_2,ad_p); } } else { switch (graph->order_left){ case 0: linearize_graph (graph_1,&ad_1); linearize_graph (graph_2,ad_p); linearize_graph (graph_3,&ad_3); break; case 1: linearize_graph (graph_1,&ad_1); linearize_graph (graph_3,&ad_3); linearize_graph (graph_2,ad_p); break; case 2: linearize_graph (graph_2,ad_p); linearize_graph (graph_1,&ad_1); linearize_graph (graph_3,&ad_3); break; case 3: linearize_graph (graph_2,ad_p); linearize_graph (graph_3,&ad_3); linearize_graph (graph_1,&ad_1); break; case 4: linearize_graph (graph_3,&ad_3); linearize_graph (graph_2,ad_p); linearize_graph (graph_1,&ad_1); break; case 5: linearize_graph (graph_3,&ad_3); linearize_graph (graph_1,&ad_1); linearize_graph (graph_2,ad_p); break; default: internal_error_in_function ("linearize_store_x_operator"); } } do_array_selects_before_update (graph->instruction_parameters[4].p,graph_1,graph_2); in_address_register (ad_p); if (graph_3==NULL){ if (i_instruction_code==IMOVEB && ad_1.ad_mode!=P_IMMEDIATE) in_data_register (&ad_1); instruction_ad_id (i_instruction_code,&ad_1,offset>>2,ad_p->ad_register); #if defined (sparc) || defined (G_POWER) } else if (offset!=0){ if (i_instruction_code==IMOVEB && ad_1.ad_mode!=P_IMMEDIATE) in_data_register (&ad_1); instruction_ad_id (i_instruction_code,&ad_1,offset>>2,ad_3.ad_register); #endif } else { in_data_register (&ad_3); #ifndef M68000 if (ad_1.ad_mode==P_INDEXED) in_register (&ad_1); #endif if (i_instruction_code==IMOVEB && ad_1.ad_mode!=P_IMMEDIATE #ifdef M68000 && ad_1.ad_mode!=P_INDEXED #endif ) in_data_register (&ad_1); if (--*ad_3.ad_count_p==0) free_dregister (ad_3.ad_register); instruction_ad_x (i_instruction_code,&ad_1,offset,ad_p->ad_register,ad_3.ad_register); } if (graph->node_count>1){ while (graph_2->instruction_code==GINDIRECTION) graph_2=graph_2->instruction_parameters[0].p; if (graph_2->instruction_code==GREGISTER){ register_node (graph_2,ad_p->ad_register); graph_2->node_count += graph->node_count; ad_p->ad_count_p=&graph_2->node_count; graph->instruction_parameters[0].p=graph_2; graph->instruction_code=GINDIRECTION; } else { register_node (graph,ad_p->ad_register); ad_p->ad_count_p=&graph->node_count; } } else { if (graph_2->instruction_code==GREGISTER){ graph->instruction_parameters[0].p=graph_2; graph->instruction_code=GINDIRECTION; } else if (graph_2->instruction_code==GINDIRECTION){ graph->instruction_parameters[0].p=graph_2->instruction_parameters[0].p; graph->instruction_code=GINDIRECTION; } } } static void linearize_bounds_operator (INSTRUCTION_GRAPH graph,ADDRESS *ad_p) { ADDRESS ad_1; if (graph->order_left){ linearize_graph (graph->instruction_parameters[0].p,&ad_1); linearize_graph (graph->instruction_parameters[1].p,ad_p); } else { linearize_graph (graph->instruction_parameters[1].p,ad_p); linearize_graph (graph->instruction_parameters[0].p,&ad_1); } in_address_register (&ad_1); if (graph->node_count>1) in_alterable_data_register (ad_p); else in_data_register (ad_p); i_cmp_id_r (STACK_ELEMENT_SIZE,ad_1.ad_register,ad_p->ad_register); instruction_l (IBHS,index_error_label); if (--*ad_1.ad_count_p==0) free_aregister (ad_1.ad_register); if (graph->node_count>1){ register_node (graph,ad_p->ad_register); ad_p->ad_count_p=&graph->node_count; } } static void linearize_exit_if_operator (INSTRUCTION_GRAPH graph,ADDRESS *ad_p) { INSTRUCTION_GRAPH graph_1,graph_2; int condition; graph_1=graph->instruction_parameters[1].p; graph_2=graph->instruction_parameters[2].p; condition=linearize_condition (graph_1); #if defined (I486) && !defined (G_A64) if (is_float_condition (condition)){ int convert_instruction_code,branch_instruction_code,tmp_reg; if (try_allocate_register_number (REGISTER_D0)) tmp_reg=REGISTER_D0; else tmp_reg=get_dregister(); convert_instruction_code=condition_to_branch_false_instruction[condition]; instruction_r (convert_instruction_code,tmp_reg); free_register (tmp_reg); branch_instruction_code=convert_instruction_code==IFCNE ? IBNE : convert_instruction_code==IFCLE ? IBLTU : IBEQ; instruction_l (branch_instruction_code,graph->instruction_parameters[0].l); } else #endif instruction_l (condition_to_branch_false_instruction[condition],graph->instruction_parameters[0].l); linearize_graph (graph_2,ad_p); if (graph->node_count>1){ in_address_register (ad_p); register_node (graph_2,ad_p->ad_register); graph_2->node_count += graph->node_count; ad_p->ad_count_p=&graph_2->node_count; graph->instruction_parameters[0].p=graph_2; graph->instruction_code=GINDIRECTION; } } static void linearize_graph (INSTRUCTION_GRAPH graph,ADDRESS *ad_p) { switch (graph->instruction_code){ case GLOAD: { if (graph->node_count<=1){ ad_p->ad_mode=P_INDIRECT; ad_p->ad_count_p=&ad_p->ad_count; ad_p->ad_count=1+1; ad_p->ad_offset=graph->instruction_parameters[0].i; ad_p->ad_register=graph->instruction_parameters[1].i; graph->node_count=0; } else { int reg_1; if (graph->instruction_d_min_a_cost<=0) reg_1=get_dregister(); else reg_1=get_aregister(); i_move_id_r (graph->instruction_parameters[0].i,graph->instruction_parameters[1].i,reg_1); ad_p->ad_mode=P_REGISTER; ad_p->ad_register=reg_1; ad_p->ad_count_p=&graph->node_count; register_node (graph,reg_1); } return; } case GREGISTER: ad_p->ad_mode=P_REGISTER; ad_p->ad_register=graph->instruction_parameters[0].i; ad_p->ad_count_p=&graph->node_count; return; case GGREGISTER: ad_p->ad_mode=P_REGISTER; ad_p->ad_register=graph->instruction_parameters[0].i; ad_p->ad_count_p=&ad_p->ad_count; ad_p->ad_count=1+1; return; case GLOAD_I: if (graph->node_count<=1){ ad_p->ad_mode=P_IMMEDIATE; ad_p->ad_offset=graph->instruction_parameters[0].imm; } else { int reg_1; if (graph->instruction_d_min_a_cost<=0) reg_1=get_dregister(); else reg_1=get_aregister(); i_move_i_r (graph->instruction_parameters[0].imm,reg_1); ad_p->ad_mode=P_REGISTER; ad_p->ad_register=reg_1; ad_p->ad_count_p=&graph->node_count; register_node (graph,reg_1); } return; case GLOAD_DES_I: if (graph->node_count<=1){ ad_p->ad_mode=P_DESCRIPTOR_NUMBER; ad_p->ad_label=graph->instruction_parameters[0].l; ad_p->ad_offset=graph->instruction_parameters[1].i; } else { int reg_1; if (graph->instruction_d_min_a_cost<=0) reg_1=get_dregister(); else reg_1=get_aregister(); i_move_d_r (graph->instruction_parameters[0].l,graph->instruction_parameters[1].i,reg_1); ad_p->ad_mode=P_REGISTER; ad_p->ad_register=reg_1; ad_p->ad_count_p=&graph->node_count; register_node (graph,reg_1); } return; case GLEA: { register int reg_1; #ifdef I486 if (graph->node_count==1){ ad_p->ad_mode=P_DESCRIPTOR_NUMBER; if (graph->inode_arity==1) ad_p->ad_offset=graph->instruction_parameters[1].i; else ad_p->ad_offset=0; ad_p->ad_label=graph->instruction_parameters[0].l; ad_p->ad_count_p=&graph->node_count; return; } else { #endif #ifndef M68000 if (graph->instruction_d_min_a_cost<0) reg_1=get_dregister(); else #endif reg_1=get_aregister(); if (graph->inode_arity==1) i_lea_l_i_r (graph->instruction_parameters[0].l,graph->instruction_parameters[1].i,reg_1); else i_lea_l_i_r (graph->instruction_parameters[0].l,0,reg_1); #ifdef M68000 if (graph->instruction_d_min_a_cost<0){ int reg_2; reg_2=get_dregister(); i_move_r_r (reg_1,reg_2); free_aregister (reg_1); reg_1=reg_2; } #endif if (graph->node_count>1) register_node (graph,reg_1); ad_p->ad_mode=P_REGISTER; ad_p->ad_register=reg_1; ad_p->ad_count_p=&graph->node_count; return; #ifdef I486 } #endif } case GLOAD_ID: { INSTRUCTION_GRAPH graph_1; graph_1=graph->instruction_parameters[1].p; linearize_graph (graph_1,ad_p); in_address_register (ad_p); if (graph->node_count<=1){ ad_p->ad_mode=P_INDIRECT; ad_p->ad_offset=graph->instruction_parameters[0].i; --graph->node_count; } else { int reg_1; if (--*ad_p->ad_count_p==0) free_aregister (ad_p->ad_register); if (graph->instruction_d_min_a_cost<=0) reg_1=get_dregister(); else reg_1=get_aregister(); i_move_id_r (graph->instruction_parameters[0].i,ad_p->ad_register,reg_1); U3( ad_p, ad_mode=P_REGISTER, ad_register=reg_1, ad_count_p=&graph->node_count); register_node (graph,reg_1); } return; } case GLOAD_B_ID: { register INSTRUCTION_GRAPH graph_1; ADDRESS ad_1; register int reg_1; graph_1=graph->instruction_parameters[1].p; linearize_graph (graph_1,&ad_1); in_address_register (&ad_1); if (--*ad_1.ad_count_p==0) free_aregister (ad_1.ad_register); reg_1=get_dregister(); #ifdef M68000 i_move_i_r (0,reg_1); #endif i_moveb_id_r (graph->instruction_parameters[0].i,ad_1.ad_register,reg_1); if (graph->instruction_d_min_a_cost>0){ int reg_2; reg_2=get_aregister(); i_move_r_r (reg_1,reg_2); free_dregister (reg_1); reg_1=reg_2; } if (graph->node_count>1) register_node (graph,reg_1); ad_p->ad_mode=P_REGISTER; ad_p->ad_register=reg_1; ad_p->ad_count_p=&graph->node_count; return; } case GLOAD_DES_ID: { register INSTRUCTION_GRAPH graph_1; ADDRESS ad_1; register int reg_1; graph_1=graph->instruction_parameters[1].p; linearize_graph (graph_1,&ad_1); in_address_register (&ad_1); if (--*ad_1.ad_count_p==0) free_aregister (ad_1.ad_register); if (graph->instruction_d_min_a_cost<0){ reg_1=get_dregister(); i_movew_id_r (graph->instruction_parameters[0].i,ad_1.ad_register,reg_1); #ifdef M68000 i_ext_r (reg_1); #endif } else { reg_1=get_aregister(); i_movew_id_r (graph->instruction_parameters[0].i,ad_1.ad_register,reg_1); } if (graph->node_count>1) register_node (graph,reg_1); ad_p->ad_mode=P_REGISTER; ad_p->ad_register=reg_1; ad_p->ad_count_p=&graph->node_count; return; } case GSTORE: { INSTRUCTION_GRAPH a_graph; int offset,stack_pointer; a_graph=graph->instruction_parameters[2].p; if (a_graph->node_count==1) switch (a_graph->instruction_code){ case GFILL: linearize_store_fill_operator (graph,a_graph); return; case GCREATE: if (a_graph->inode_arity>3 && a_graph->instruction_parameters[0].p!=NULL){ int arity; arity=a_graph->inode_arity; while (--arity>0 && a_graph->instruction_parameters[arity].p!=NULL) ; if (arity>0) break; } offset=graph->instruction_parameters[0].i; stack_pointer=graph->instruction_parameters[1].i; linearize_load_graph (graph->instruction_parameters[3].p); linearize_store_create_operator (offset,stack_pointer,a_graph); return; } linearize_graph (a_graph,ad_p); offset=graph->instruction_parameters[0].i; stack_pointer=graph->instruction_parameters[1].i; linearize_load_graph (graph->instruction_parameters[3].p); instruction_ad_id (IMOVE,ad_p,offset,stack_pointer); return; } case GBEFORE0: case GBEFORE: { INSTRUCTION_GRAPH graph_1; int i; graph_1=graph->instruction_parameters[0].p; linearize_graph (graph_1,ad_p); if (graph->instruction_code==GBEFORE){ /* added 16-5-2000 */ for (i=1; iinode_arity; ++i){ INSTRUCTION_GRAPH graph_2; graph_2=graph->instruction_parameters[i].p; if (graph_2->node_count==1 && graph_2->instruction_code==GMOVEMI) graph_2->node_count=0; } /**/ for (i=1; iinode_arity; ++i){ INSTRUCTION_GRAPH graph_2; ADDRESS ad_1; graph_2=graph->instruction_parameters[i].p; if (graph_2->node_count>1){ linearize_graph (graph_2,&ad_1); in_register (&ad_1); register_node (graph_2,ad_1.ad_register); } } } if (graph->node_count>1){ in_address_register (ad_p); /* changed 27-12-2000 register_node (graph,ad_p->ad_register); ad_p->ad_count_p=&graph->node_count; */ register_node (graph_1,ad_p->ad_register); graph_1->node_count += graph->node_count; ad_p->ad_count_p=&graph_1->node_count; /* graph->instruction_parameters[0].p=graph_1; */ graph->instruction_code=GINDIRECTION; /* */ } return; } case GKEEP: { INSTRUCTION_GRAPH graph_1,graph_2; ADDRESS ad_1; graph_1=graph->instruction_parameters[0].p; graph_2=graph->instruction_parameters[1].p; linearize_graph (graph_1,&ad_1); switch (ad_1.ad_mode){ case P_REGISTER: case P_INDIRECT: if (--*ad_1.ad_count_p==0) free_register (ad_1.ad_register); } linearize_graph (graph_2,ad_p); if (graph->node_count>1){ in_address_register (ad_p); /* changed 10-12-97 register_node (graph,ad_p->ad_register); ad_p->ad_count_p=&graph->node_count; */ register_node (graph_2,ad_p->ad_register); graph_2->node_count += graph->node_count; ad_p->ad_count_p=&graph_2->node_count; graph->instruction_parameters[0].p=graph_2; graph->instruction_code=GINDIRECTION; /**/ } return; } /* added 10-12-97 */ case GINDIRECTION: linearize_graph (graph->instruction_parameters[0].p,ad_p); return; /* */ case GLOAD_X: linearize_load_x_operator (graph,ad_p #ifdef LOAD_X_PARAMETER_REGISTER ,0 #endif ); return; case GLOAD_B_X: linearize_load_b_x_operator (graph,ad_p); return; case GSTORE_X: linearize_store_x_operator (IMOVE,graph,ad_p); return; case GSTORE_B_X: linearize_store_x_operator (IMOVEB,graph,ad_p); return; case GSTORE_R: linearize_store_r_node (graph); break; case GFSTORE: linearize_fstore_operator (graph); return; case GFSTORE_X: linearize_fstore_x_operator (graph,ad_p); return; case GFSTORE_R: linearize_fstore_r_operator (graph); return; case GADD: linearize_dyadic_commutative_operator (IADD,graph,ad_p); return; case GAND: linearize_dyadic_commutative_data_operator (IAND,graph,ad_p); return; case GMUL: linearize_dyadic_commutative_data_operator (IMUL,graph,ad_p); return; case GOR: linearize_dyadic_commutative_data_operator (IOR,graph,ad_p); return; case GEOR: #ifdef M68000 linearize_eor_operator (graph,ad_p); #else linearize_dyadic_commutative_data_operator (IEOR,graph,ad_p); #endif return; case GSUB: linearize_dyadic_non_commutative_operator (ISUB,graph,ad_p); return; #if defined (I486) || defined (G_POWER) case GDIV: linearize_div_rem_operator (IDIV,graph,ad_p); return; case GMOD: linearize_div_rem_operator (IMOD,graph,ad_p); return; case GDIVU: linearize_div_rem_operator (IDIVU,graph,ad_p); return; # ifdef I486 case GREMU: linearize_div_rem_operator (IREMU,graph,ad_p); return; # endif #else case GDIV: linearize_dyadic_non_commutative_data_operator (IDIV,graph,ad_p); return; case GMOD: linearize_mod_operator (IMOD,graph,ad_p); return; #endif case GCMP_EQ: linearize_compare_operator (CEQ,CEQ,graph,ad_p); return; case GCMP_LT: linearize_compare_operator (CLT,CGT,graph,ad_p); return; case GCMP_LTU: linearize_compare_operator (CLTU,CGTU,graph,ad_p); return; case GCMP_GT: linearize_compare_operator (CGT,CLT,graph,ad_p); return; case GCMP_GTU: linearize_compare_operator (CGTU,CLTU,graph,ad_p); return; case GCNOT: linearize_conditional_not_operator (graph,ad_p); return; case GLSR: #ifndef I486 linearize_shift_operator (ILSR,graph,ad_p); #else linearize_shift_operator (ILSR,ILSR_S,graph,ad_p); #endif return; case GLSL: #ifndef I486 linearize_shift_operator (ILSL,graph,ad_p); #else linearize_shift_operator (ILSL,ILSL_S,graph,ad_p); #endif return; case GASR: #ifndef I486 linearize_shift_operator (IASR,graph,ad_p); #else linearize_shift_operator (IASR,IASR_S,graph,ad_p); #endif return; case GCREATE: linearize_create_operator (graph,ad_p,0); return; #ifdef G_POWER case GCREATE_S: ad_p->ad_mode=P_STORE_HP_INSTRUCTION; ad_p->ad_offset=(LONG) linearize_store_create_operator (0,HEAP_POINTER,graph); return; #endif case GCREATE_R: linearize_create_r_operator (graph,ad_p,0); return; case GFILL: linearize_fill_operator (graph,ad_p); return; case GFILL_R: linearize_fill_r_operator (graph,ad_p); return; case GNEG: linearize_monadic_data_operator (INEG,graph,ad_p); return; #if defined (I486) || defined (G_POWER) case GNOT: linearize_monadic_data_operator (INOT,graph,ad_p); return; #endif case GMOVEMI: linearize_movemi_operator (graph,ad_p); return; case GCOPY: linearize_copy_operator (graph,ad_p); return; #ifndef G_A64 case GFHIGH: linearize_fhigh_operator (graph,ad_p); return; case GFLOW: linearize_flow_operator (graph,ad_p); return; #endif case GFCMP_EQ: linearize_float_compare_operator (CFEQ,CFEQ,graph,ad_p); return; case GFCMP_LT: linearize_float_compare_operator (CFLT,CFGT,graph,ad_p); return; case GFCMP_GT: linearize_float_compare_operator (CFGT,CFLT,graph,ad_p); return; #ifdef G_A64 case GFROMF: linearize_fromf_operator (graph,ad_p); return; #endif case GFRTOI: linearize_rtoi_operator (graph,ad_p); return; case GBOUNDS: linearize_bounds_operator (graph,ad_p); return; case GEXIT_IF: linearize_exit_if_operator (graph,ad_p); return; case GADD_O: linearize_add_o_operator (graph,ad_p,NULL); return; case GMUL_O: linearize_mul_o_operator (graph,ad_p,NULL); break; case GSUB_O: linearize_sub_o_operator (graph,ad_p,NULL); return; case GTEST_O: linearize_test_o_operator (graph,ad_p); return; #ifdef G_POWER case GUMULH: linearize_dyadic_commutative_data_operator (IUMULH,graph,ad_p); return; #endif #ifdef I486 case GRESULT0: case GRESULT1: linearize_two_results_operator (graph,ad_p); return; #endif default: /* printf ("%d %d\n",(int)graph,graph->instruction_code); */ internal_error_in_function ("linearize_graph"); } } #pragma segment Code30 static void linearize_fstore_x_operator (register INSTRUCTION_GRAPH graph,register ADDRESS *ad_p) { INSTRUCTION_GRAPH graph_1,graph_2,graph_3; int offset; ADDRESS ad_1,ad_3; graph_1=graph->instruction_parameters[0].p; graph_2=graph->instruction_parameters[1].p; offset=graph->instruction_parameters[2].i; graph_3=graph->instruction_parameters[3].p; if (graph_3==NULL){ if (graph->order_left){ linearize_float_graph (graph_1,&ad_1); linearize_graph (graph_2,ad_p); } else { linearize_graph (graph_2,ad_p); linearize_float_graph (graph_1,&ad_1); } } else { switch (graph->order_left){ case 0: linearize_float_graph (graph_1,&ad_1); linearize_graph (graph_2,ad_p); linearize_graph (graph_3,&ad_3); break; case 1: linearize_float_graph (graph_1,&ad_1); linearize_graph (graph_3,&ad_3); linearize_graph (graph_2,ad_p); break; case 2: linearize_graph (graph_2,ad_p); linearize_float_graph (graph_1,&ad_1); linearize_graph (graph_3,&ad_3); break; case 3: linearize_graph (graph_2,ad_p); linearize_graph (graph_3,&ad_3); linearize_float_graph (graph_1,&ad_1); break; case 4: linearize_graph (graph_3,&ad_3); linearize_graph (graph_2,ad_p); linearize_float_graph (graph_1,&ad_1); break; case 5: linearize_graph (graph_3,&ad_3); linearize_float_graph (graph_1,&ad_1); linearize_graph (graph_2,ad_p); break; default: internal_error_in_function ("linearize_fstore_x_operator"); } } do_array_selects_before_update (graph->instruction_parameters[4].p,graph_1,graph_2); in_address_register (ad_p); if (graph_3==NULL){ #ifdef ALIGN_REAL_ARRAYS if (ad_1.ad_mode==P_F_REGISTER){ i_fmove_fr_id_f (ad_1.ad_register,offset>>2,ad_p->ad_register,graph->inode_arity & LOAD_STORE_ALIGNED_REAL); if (--*ad_1.ad_count_p==0){ # ifdef FP_STACK_OPTIMIZATIONS last_instruction->instruction_parameters[0].parameter_flags |= FP_REG_LAST_USE; # endif free_fregister (ad_1.ad_register); } } else #endif move_float_ad_id (&ad_1,offset>>2,ad_p->ad_register); #if defined (sparc) || defined (G_POWER) } else if (offset!=0){ in_address_register (&ad_3); # ifdef ALIGN_REAL_ARRAYS if (ad_1.ad_mode==P_F_REGISTER){ i_fmove_fr_id_f (ad_1.ad_register,offset>>2,ad_3.ad_register,graph->inode_arity & LOAD_STORE_ALIGNED_REAL); if (--*ad_1.ad_count_p==0){ # ifdef FP_STACK_OPTIMIZATIONS last_instruction->instruction_parameters[0].parameter_flags |= FP_REG_LAST_USE; # endif free_fregister (ad_1.ad_register); } } else # endif move_float_ad_id (&ad_1,offset>>2,ad_3.ad_register); #endif } else { in_data_register (&ad_3); if (--*ad_3.ad_count_p==0) free_dregister (ad_3.ad_register); #ifndef M68000 # ifdef I486 if (ad_1.ad_mode==P_INDEXED) # else if (ad_1.ad_mode!=P_F_REGISTER) # endif in_float_register (&ad_1); #endif #ifdef ALIGN_REAL_ARRAYS move_float_ad_x (&ad_1,offset,ad_p->ad_register,ad_3.ad_register,graph->inode_arity & LOAD_STORE_ALIGNED_REAL); #else move_float_ad_x (&ad_1,offset,ad_p->ad_register,ad_3.ad_register); #endif } if (graph->node_count>1){ register_node (graph,ad_p->ad_register); ad_p->ad_count_p=&graph->node_count; } } void calculate_and_linearize_branch_false (LABEL *label,INSTRUCTION_GRAPH graph) { int condition,condition_on_stack; calculate_graph_register_uses (graph); condition=linearize_condition (graph); #if defined (I486) && !defined (G_A64) if (is_float_condition (condition)){ int convert_instruction_code,branch_instruction_code,tmp_reg; if (try_allocate_register_number (REGISTER_D0)) tmp_reg=REGISTER_D0; else tmp_reg=get_dregister(); convert_instruction_code=condition_to_branch_false_instruction[condition]; instruction_r (convert_instruction_code,tmp_reg); free_register (tmp_reg); adjust_stack_pointers_without_altering_condition_codes (1,condition); branch_instruction_code=convert_instruction_code==IFCNE ? IBNE : convert_instruction_code==IFCLE ? IBLTU : IBEQ; instruction_l (branch_instruction_code,label); return; } #endif condition_on_stack=adjust_stack_pointers_without_altering_condition_codes (is_float_condition (condition),condition); #ifdef M68000 if (condition_on_stack){ i_tstb_pi (REGISTER_A7); instruction_l (IBEQ,label); } else #endif instruction_l (condition_to_branch_false_instruction[condition],label); } void calculate_and_linearize_branch_true (LABEL *label,INSTRUCTION_GRAPH graph) { int condition,condition_on_stack; calculate_graph_register_uses (graph); condition=linearize_condition (graph); #if defined (I486) && !defined (G_A64) if (is_float_condition (condition)){ int convert_instruction_code,branch_instruction_code,tmp_reg; if (try_allocate_register_number (REGISTER_D0)) tmp_reg=REGISTER_D0; else tmp_reg=get_dregister(); convert_instruction_code=condition_to_branch_true_instruction[condition]; instruction_r (convert_instruction_code,tmp_reg); free_register (tmp_reg); adjust_stack_pointers_without_altering_condition_codes (1,condition); branch_instruction_code=convert_instruction_code==IFCNE ? IBNE : convert_instruction_code==IFCLE ? IBLTU : IBEQ; instruction_l (branch_instruction_code,label); return; } #endif condition_on_stack=adjust_stack_pointers_without_altering_condition_codes (is_float_condition (condition),condition); #ifdef M68000 if (condition_on_stack){ i_tstb_pi (REGISTER_A7); instruction_l (IBNE,label); } else #endif instruction_l (condition_to_branch_true_instruction[condition],label); } void calculate_and_linearize_graph (INSTRUCTION_GRAPH graph) { ADDRESS ad; calculate_graph_register_uses (graph); linearize_graph (graph,&ad); } void initialize_linearization (VOID) { free_dregisters.r_s_list.r_l_next=NULL; free_aregisters.r_s_list.r_l_next=NULL; free_fregisters.r_s_list.r_l_next=NULL; free_all_aregisters(); free_all_dregisters(); free_all_fregisters(); IF_G_POWER (last_heap_pointer_update=NULL;) } #if 0 static char *i_instruction_names[] = { "ADD", "AND", "ASR", "BEQ", "BGE", "BGT", "BHS", "BLE", "BLT", "BMI", "BMOVE", "BNE", "CMP", "CMPW", "DIV", "EOR", "EXG", "EXT", "FACOS", "FADD", "FASIN", "FATAN", "FBEQ", "FBGE", "FBGT", "FBLE", "FBLT", "FBNE", "FCMP", "FCOS", "FDIV", "FEXP", "FLN", "FLOG10", "FMUL", "FREM", "FSEQ", "FSGE", "FSGT", "FSIN", "FSLE", "FSLT", "FSNE", "FSQRT", "FSUB", "FTAN", "FTST", "FMOVE", "FMOVEL", "JMP", "JSR", "LEA", "LSL", "LSR", "MOD", "MOVE", "MOVEB", "MOVEM", "MOVEW", "MUL", "OR", "RTS", "SEQ", "SGE", "SGT", "SLE", "SLT", "SNE", "SUB", "TST", "TSTB", "WORD" }; static void show_parameter (register struct parameter *parameter) { switch (parameter->parameter_type){ case P_REGISTER: { int reg=parameter->parameter_data.reg.r; if (is_d_register (reg)) printf ("D%d",d_reg_num (reg)); else printf ("A%d",a_reg_num (reg)); break; } case P_LABEL: if (parameter->parameter_data.l->label_number!=0) printf ("L%d",parameter->parameter_data.l->label_number); else printf ("%s",parameter->parameter_data.l->label_name); break; case P_DESCRIPTOR_NUMBER: printf ("#!%s+%d",parameter->parameter_data.l->label_name,parameter->parameter_offset); break; case P_INDIRECT: if (parameter->parameter_offset==0) printf ("(A%d)",a_reg_num (parameter->parameter_data.reg.r)); else printf ("%d(A%d)",parameter->parameter_offset, a_reg_num (parameter->parameter_data.reg.r)); break; case P_IMMEDIATE: printf ("#%ld",parameter->parameter_data.i); break; #ifdef M68000 case P_POST_INCREMENT: printf ("(A%d)+",a_reg_num (parameter->parameter_data.reg.r)); break; case P_PRE_DECREMENT: printf ("-(A%d)",a_reg_num (parameter->parameter_data.reg.r)); break; #endif case P_F_REGISTER: printf ("FP%d",parameter->parameter_data.reg.r); break; case P_F_IMMEDIATE: printf ("#%g",*parameter->parameter_data.r); break; case P_INDEXED: { struct index_registers *index_registers; int offset; index_registers=parameter->parameter_data.ir; offset=parameter->parameter_offset; printf ("%d(a%d,d%d*%d)",offset>>2,a_reg_num (index_registers->a_reg.r), d_reg_num (index_registers->d_reg.r),1<<(offset & 3)); } } } void show_instructions (register struct instruction *instructions) { while (instructions!=NULL){ register struct parameter *parameter; register int n_parameters; printf ("%s ",i_instruction_names[instructions->instruction_icode]); n_parameters=instructions->instruction_arity; parameter=instructions->instruction_parameters; while (n_parameters>1){ show_parameter (parameter); printf (","); ++parameter; --n_parameters; } if (n_parameters==1) show_parameter (parameter); printf ("\n"); instructions=instructions->instruction_next; } } #endif