summaryrefslogtreecommitdiff
path: root/cglin.c
diff options
context:
space:
mode:
authorJohn van Groningen2003-05-12 14:02:41 +0000
committerJohn van Groningen2003-05-12 14:02:41 +0000
commitf5a66e7200c23c2f12ed6f1056606b003be70ea1 (patch)
tree475b6402f35f3a37f0e39aacfbc715850c3de176 /cglin.c
parentcgcode.c (diff)
cglin.c
Diffstat (limited to 'cglin.c')
-rw-r--r--cglin.c7827
1 files changed, 7827 insertions, 0 deletions
diff --git a/cglin.c b/cglin.c
new file mode 100644
index 0000000..17ed82d
--- /dev/null
+++ b/cglin.c
@@ -0,0 +1,7827 @@
+/*
+ File: cglin.c
+ Author: John van Groningen
+ At: University of Nijmegen
+*/
+
+#include <stdio.h>
+#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
+
+/* 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)
+{
+ register 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)
+{
+ register 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;
+}
+
+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.i=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)
+{
+ register 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.i=value);
+}
+#endif
+
+#if defined (M68000) || defined (G_POWER)
+# 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.i=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.i;
+}
+#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.i=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.i=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.i=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);
+}
+
+static void i_cmpw_d_id (LABEL *descriptor,int arity,int offset_1,int register_1)
+{
+ register 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);
+}
+
+#if defined (M68000) || defined (I486)
+static 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)
+{
+ register 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)
+{
+ 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_INDIRECT;
+ instruction->instruction_parameters[1].parameter_offset=offset;
+ instruction->instruction_parameters[1].parameter_data.i=register_2;
+}
+
+#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
+
+static void i_fmove_fr_x (int register_1,int offset,int register_2,int register_3)
+{
+ 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);
+
+ 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;
+
+ set_float_register_parameter (instruction->instruction_parameters[1],register_1);
+}
+
+#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);
+}
+
+static void i_fmove_x_fr (int offset,int register_1,int register_2,int register_3)
+{
+ 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;
+
+ 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)
+{
+ register 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
+
+void i_lea_id_r (int offset,int register_1,int register_2)
+{
+ register 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.i=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_number<n_arguments; ++argument_number){
+ parameter->parameter_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_number<n_arguments; ++argument_number){
+ parameter->parameter_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_number<n_arguments; ++argument_number){
+ parameter->parameter_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
+
+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);
+}
+
+static void i_move_i_id (LONG i,int offset_1,int register_1)
+{
+ register struct instruction *instruction;
+
+ instruction=i_new_instruction2 (IMOVE);
+
+ S2 (instruction->instruction_parameters[0], parameter_type=P_IMMEDIATE,
+ parameter_data.i=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.i=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 (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.i=i);
+
+ S2 (instruction->instruction_parameters[1], parameter_type=P_REGISTER,
+ parameter_data.i=register_1);
+}
+
+#if defined (M68000) || defined (I486)
+static void i_move_i_x (LONG i,int offset,int register_1,int register_2)
+{
+ 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];
+
+ S2 (instruction->instruction_parameters[0], parameter_type=P_IMMEDIATE,
+ parameter_data.i=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 G_POWER
+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.i=value);
+
+ S2 (instruction->instruction_parameters[1], parameter_type=P_REGISTER,
+ parameter_data.i=register_1);
+}
+
+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.i=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.i=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.i=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.i=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.i=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.i=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.i=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.i=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_n<r_s_p->r_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<<bit_n)){
+ r_list->r_l_vector &= ~(1<<bit_n);
+ r_s_p->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<<bit_n);
+ return reg_n;
+}
+
+static void free_register_number (struct register_set *r_s_p,unsigned int reg_n)
+{
+ struct register_list *r_list;
+ register unsigned int bit_n;
+
+ if (reg_n<r_s_p->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<<bit_n);
+}
+
+static void allocate_register_number (struct register_set *r_s_p,unsigned int reg_n)
+{
+ struct register_list *r_list;
+ register unsigned int bit_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<<bit_n);
+}
+
+static int try_allocate_register_number (int reg_n)
+{
+ struct register_list *r_list;
+ register unsigned int bit_n;
+
+ if (is_d_register (reg_n)){
+ r_list=&free_dregisters.r_s_list;
+ bit_n=d_reg_num (reg_n);
+ } else {
+ r_list=&free_aregisters.r_s_list;
+ bit_n=a_reg_num (reg_n);
+ }
+
+ while (bit_n>=N_VECTOR_BITS){
+ bit_n-=N_VECTOR_BITS;
+ r_list=r_list->r_l_next;
+ }
+
+ if (r_list->r_l_vector & (1<<bit_n)){
+ r_list->r_l_vector &= ~(1<<bit_n);
+ return 1;
+ } else
+ return 0;
+}
+
+static int try_get_real_dregister_number (VOID)
+{
+ register struct register_list *r_list;
+ register unsigned int reg_n;
+ ULONG vector;
+
+ reg_n=free_dregisters.r_s_first_free;
+ r_list=&free_dregisters.r_s_list;
+ vector=r_list->r_l_vector;
+
+ while (reg_n<N_DATA_PARAMETER_REGISTERS && reg_n<free_dregisters.r_s_highest){
+ if (vector & (1<<reg_n)){
+ r_list->r_l_vector &= ~(1<<reg_n);
+ free_dregisters.r_s_first_free=reg_n+1;
+ return reg_n;
+ }
+ ++reg_n;
+ }
+
+ if (reg_n>=N_DATA_PARAMETER_REGISTERS)
+ return -1;
+
+ free_dregisters.r_s_highest=reg_n+1;
+ r_list->r_l_vector &= ~(1<<reg_n);
+ return reg_n;
+}
+
+static int get_dregister (VOID)
+{
+ return num_to_d_reg (get_free_register_number (&free_dregisters));
+}
+
+static void free_dregister (int dregister)
+{
+ free_register_number (&free_dregisters,d_reg_num (dregister));
+}
+
+void allocate_dregister (int dregister)
+{
+ allocate_register_number (&free_dregisters,d_reg_num (dregister));
+}
+
+void free_all_dregisters (VOID)
+{
+ free_dregisters.r_s_first_free=d_reg_num (REGISTER_D0);
+ free_dregisters.r_s_highest=8;
+#ifdef I486
+ free_dregisters.r_s_list.r_l_vector=
+ (1<<d_reg_num (REGISTER_D0)) | (1<<d_reg_num (REGISTER_D1));
+#else
+ if (parallel_flag)
+ free_dregisters.r_s_list.r_l_vector=
+ (1<<d_reg_num (REGISTER_D0)) | (1<<d_reg_num (REGISTER_D1))
+ | (1<<d_reg_num (REGISTER_D2)) | (1<<d_reg_num (REGISTER_D3))
+ | (1<<d_reg_num (REGISTER_D4)) | (1<<d_reg_num (REGISTER_D5));
+ else
+ free_dregisters.r_s_list.r_l_vector=
+ (1<<d_reg_num (REGISTER_D0)) | (1<<d_reg_num (REGISTER_D1))
+ | (1<<d_reg_num (REGISTER_D2)) | (1<<d_reg_num (REGISTER_D3))
+ | (1<<d_reg_num (REGISTER_D4)) | (1<<d_reg_num (REGISTER_D5))
+ | (1<<d_reg_num (REGISTER_D6));
+#endif
+ free_dregisters.r_s_list.r_l_next=NULL;
+}
+
+static int get_aregister (VOID)
+{
+ return num_to_a_reg (get_free_register_number (&free_aregisters));
+}
+
+static void free_aregister (int aregister)
+{
+ free_register_number (&free_aregisters,a_reg_num (aregister));
+}
+
+void allocate_aregister (int aregister)
+{
+ allocate_register_number (&free_aregisters,a_reg_num (aregister));
+}
+
+void free_all_aregisters (VOID)
+{
+ free_aregisters.r_s_first_free=a_reg_num (REGISTER_A0);
+ free_aregisters.r_s_highest=N_REAL_A_REGISTERS;
+ free_aregisters.r_s_list.r_l_vector= (1<<a_reg_num (REGISTER_A0))
+ | (1<<a_reg_num (REGISTER_A1))
+#ifndef I486
+ | (1<<a_reg_num (REGISTER_A2))
+#endif
+ ;
+ free_aregisters.r_s_list.r_l_next=NULL;
+}
+
+static int get_fregister (VOID)
+{
+ return get_free_register_number (&free_fregisters);
+}
+
+static void free_fregister (int fregister)
+{
+ free_register_number (&free_fregisters,fregister);
+}
+
+void allocate_fregister (int fregister)
+{
+ allocate_register_number (&free_fregisters,fregister);
+}
+
+void free_all_fregisters (VOID)
+{
+ free_fregisters.r_s_first_free=REGISTER_FP0;
+ free_fregisters.r_s_highest=8;
+ free_fregisters.r_s_list.r_l_vector= (1<<REGISTER_FP0) | (1<<REGISTER_FP1) |
+ (1<<REGISTER_FP2) | (1<<REGISTER_FP3) |
+ (1<<REGISTER_FP4) | (1<<REGISTER_FP5) |
+ (1<<REGISTER_FP6)
+#ifndef I486
+ | (1<<REGISTER_FP7)
+#endif
+ ;
+ free_fregisters.r_s_list.r_l_next=NULL;
+}
+
+static void free_register (int reg)
+{
+ if (is_d_register (reg))
+ free_dregister (reg);
+ else
+ free_aregister (reg);
+}
+
+typedef struct address {
+ int ad_mode;
+ union {
+ struct {
+ union {
+ LONG ad_register;
+ LABEL *ad_label;
+ struct {
+ WORD ad_areg;
+ WORD ad_dreg;
+ } s;
+ } u;
+ LONG ad_offset;
+ } s;
+ DOUBLE ad_real;
+ } u;
+ WORD *ad_count_p;
+ WORD *ad_count_p2;
+ WORD ad_count;
+ WORD ad_count2;
+} ADDRESS;
+
+#define ad_register u.s.u.ad_register
+#define ad_label u.s.u.ad_label
+#define ad_areg u.s.u.s.ad_areg
+#define ad_dreg u.s.u.s.ad_dreg
+#define ad_offset u.s.ad_offset
+#define ad_real u.ad_real
+
+static void ad_to_parameter (ADDRESS *ad_p,struct parameter *parameter_p)
+{
+ switch (ad_p->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.i=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=(INSTRUCTION_GRAPH)ad_p->ad_offset;
+ i_ad_p=(ADDRESS *)load_x_graph->instruction_parameters[1].p;
+
+ if (load_x_graph->inode_arity==1){
+ load_x_graph->inode_arity=2;
+
+ 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");
+ }
+}
+
+static int fad_to_parameter (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;
+ 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=(INSTRUCTION_GRAPH)ad_p->ad_offset;
+ i_ad_p=(ADDRESS *)load_x_graph->instruction_parameters[1].p;
+
+ if (load_x_graph->inode_arity==1){
+ load_x_graph->inode_arity=2;
+
+ 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");
+ }
+ 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)
+{
+ register 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.i=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)
+{
+ register 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)
+{
+ register 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)
+{
+ register 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 (register 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;
+ }
+}
+
+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=(INSTRUCTION_GRAPH)ad_p->ad_offset;
+ i_ad_p=(ADDRESS *)load_x_graph->instruction_parameters[1].p;
+
+ 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);
+ 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=(INSTRUCTION_GRAPH)ad_p->ad_offset;
+ i_ad_p=(ADDRESS *)load_x_graph->instruction_parameters[1].p;
+
+ 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);
+ 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 (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=(INSTRUCTION_GRAPH)ad_p->ad_offset;
+ i_ad_p=(ADDRESS *)load_x_graph->instruction_parameters[1].p;
+
+ 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);
+
+ 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;
+}
+
+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=(INSTRUCTION_GRAPH)ad_p->ad_offset;
+ i_ad_p=(ADDRESS *)load_x_graph->instruction_parameters[1].p;
+
+ 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);
+ 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=(INSTRUCTION_GRAPH)ad_p->ad_offset;
+ i_ad_p=(ADDRESS *)load_x_graph->instruction_parameters[1].p;
+
+ 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);
+ 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)
+{
+ 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);
+ }
+
+ 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);
+}
+
+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);
+}
+
+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;
+
+ 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;
+ } else
+ 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;
+ } else {
+ 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,
+ 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,
+ IFSEQ, IFSNE, IFSGT, IFSLT, IFSGE, IFSLE
+};
+
+static int condition_to_branch_false_instruction[]=
+{
+ IBNE, IBEQ, IBLE, IBGE, IBLT, IBGT, IBNO, IBO,
+ IFBNE, IFBEQ, IFBLE, IFBGE, IFBLT, IFBGT
+};
+
+static int condition_to_branch_true_instruction[]=
+{
+ IBEQ, IBNE, IBGT, IBLT, IBGE, IBLE, IBO, IBNO,
+ IFBEQ, IFBNE, IFBGT, IFBLT, IFBGE, IFBLE
+};
+
+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_GT:
+ condition=compare_node (graph,CGT,CLT);
+ 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_GT:
+ condition=compare_node (graph,CLE,CGE);
+ 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);
+}
+
+#if defined (I486) || defined (G_POWER)
+static void linearize_div_mod_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 && !((ad_1.ad_offset & (ad_1.ad_offset-1))==0 && ad_1.ad_offset>0)) || ad_1.ad_mode==P_INDEXED)
+ in_data_register (&ad_1);
+# 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;
+ }
+
+ 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
+
+static void linearize_shift_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 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
+ if (ad_1.ad_mode!=P_IMMEDIATE || ad_1.ad_offset<0 || ad_1.ad_offset>=32)
+#endif
+ in_data_register (&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;
+ }
+
+#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; ++argument_number)
+ argument_evaluated[argument_number]=(arguments[argument_number].p==NULL);
+
+ for (;;){
+ int first_argument_number;
+ INSTRUCTION_GRAPH a_graph_1;
+
+ first_argument_number=0;
+ while (first_argument_number<n_arguments && argument_evaluated[first_argument_number])
+ ++first_argument_number;
+
+ if (first_argument_number>=n_arguments)
+ break;
+
+ a_graph_1=arguments[first_argument_number].p;
+
+ for (argument_number=first_argument_number+1; argument_number<n_arguments; ++argument_number){
+ if (!argument_evaluated[argument_number]){
+ INSTRUCTION_GRAPH a_graph_2;
+ int i1,i2,u1,u2;
+ int a,d;
+
+ a_graph_2=arguments[argument_number].p;
+
+ 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){
+ if (i2<0 && (u2<u1 || (u1==u2 && i2<i1))){
+ first_argument_number=argument_number;
+ a_graph_1=a_graph_2;
+ }
+ } else if (i1==0){
+ if (i2<0 || (i2==0 && u2<u1)){
+ first_argument_number=argument_number;
+ a_graph_1=a_graph_2;
+ }
+ } else {
+ if (i2<=0 || (u2-i2>u1-i1 || (u2-i2==u1-i1 && i2<i1))){
+ first_argument_number=argument_number;
+ a_graph_1=a_graph_2;
+ }
+ }
+ }
+ }
+
+ if (a_graph_1->instruction_code==GFHIGH &&
+ first_argument_number+1<n_arguments &&
+ !argument_evaluated[first_argument_number+1])
+ {
+ INSTRUCTION_GRAPH next_graph;
+
+ next_graph=arguments[first_argument_number+1].p;
+ if (next_graph!=NULL && next_graph->instruction_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;
+ }
+ }
+
+ 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==1){
+ load_x_graph->inode_arity=2;
+
+ 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);
+}
+
+#if defined (FP_STACK_OPTIMIZATIONS) || defined (FMADD)
+#define FP_REG_LAST_USE 4
+#endif
+
+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);
+ i_move_id_id (ad_p->ad_offset+4,ad_p->ad_register,offset+4,areg);
+ if (--*ad_p->ad_count_p==0)
+ free_aregister (ad_p->ad_register);
+#ifdef M68000
+ }
+#endif
+ return;
+ case P_F_IMMEDIATE:
+ 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);
+ 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==1){
+ load_x_graph->inode_arity=2;
+
+ 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);
+#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
+ 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);
+ i_move_id_id (i_ad_p->ad_offset+4,i_ad_p->ad_register,offset+4,areg);
+ 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;
+ default:
+ internal_error_in_function ("linearize_load_graph");
+ }
+ }
+ /* added 24-8-1999 */
+ else if (load_graph->instruction_code==GFHIGH || load_graph->instruction_code==GFLOW){
+ 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_number<arity; ++argument_number){
+ INSTRUCTION_GRAPH a_graph;
+
+ a_graph=graph->instruction_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_number<arity; ++argument_number){
+ INSTRUCTION_GRAPH a_graph;
+
+ a_graph=graph->instruction_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
+ ++argument_number;
+ } 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+4
+ -instruction->instruction_parameters[1].parameter_data.i;
+ } else
+ instruction_ad_id (IMOVE,&ad_a[argument_number],heap_offset+4,HEAP_POINTER);
+# else
+ instruction_ad_id (IMOVE,&ad_a[argument_number],heap_offset,HEAP_POINTER);
+# endif
+ heap_offset+=4;
+#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+4+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+4,HEAP_POINTER);
+# else
+ i_move_r_id (reg_1,heap_offset,HEAP_POINTER);
+# endif
+ heap_offset+=4;
+#endif
+ } else
+ heap_offset+=4;
+ }
+ }
+
+#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+4+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_number<arity; ++argument_number){
+ INSTRUCTION_GRAPH a_graph;
+
+ a_graph=graph->instruction_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+4,HEAP_POINTER);
+ heap_pointer_offset_in_basic_block+=offset_from_heap_register+4;
+ offset_from_heap_register=-4;
+ heap_offset=4;
+ ++argument_number;
+ } else {
+#endif
+ if (offset_from_heap_register!=-(4+NODE_POINTER_OFFSET)){
+ i_add_i_r (offset_from_heap_register+(4+NODE_POINTER_OFFSET),HEAP_POINTER);
+ heap_pointer_offset_in_basic_block+=offset_from_heap_register+(4+NODE_POINTER_OFFSET);
+ offset_from_heap_register=-(4+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_number<arity; ++argument_number){
+ INSTRUCTION_GRAPH a_graph;
+
+ a_graph=graph->instruction_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
+ ++argument_number;
+ } 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+=4;
+#endif
+ }
+ } else
+ heap_offset+=4;
+ }
+
+#ifndef M68000
+# ifdef G_POWER
+ offset_from_heap_register=heap_offset-4;
+# 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 {
+ instruction_ad_id (IMOVE,&ad_a[1],0-NODE_POINTER_OFFSET,reg_2);
+ instruction_ad_id (IMOVE,&ad_a[2],4-NODE_POINTER_OFFSET,reg_2);
+ }
+ 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_number<n_arguments; ++argument_number){
+ register INSTRUCTION_GRAPH a_graph;
+
+ a_graph=graph->instruction_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
+ ++argument_number;
+ } 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+=4;
+#endif
+ }
+ } else
+#ifdef M68000
+ i_add_i_r (4,reg_1);
+#else
+ offset+=4;
+#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);
+}
+
+static void move_float_ad_x (ADDRESS *ad_p,int offset,int areg,int dreg)
+{
+ switch (ad_p->ad_mode){
+ case P_F_REGISTER:
+ i_fmove_fr_x (ad_p->ad_register,offset,areg,dreg);
+ 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);
+ i_move_id_x (ad_p->ad_offset+4,ad_p->ad_register,offset+(4<<2),areg,dreg);
+ if (--*ad_p->ad_count_p==0)
+ free_aregister (ad_p->ad_register);
+# ifdef M68000
+ }
+# endif
+ return;
+ case P_F_IMMEDIATE:
+ 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);
+ 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==1){
+ load_x_graph->inode_arity=2;
+
+ 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],4,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_number<n_arguments; ++argument_number){
+ if (graph->instruction_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_number<n_arguments; ++argument_number){
+ INSTRUCTION_GRAPH a_graph;
+
+ a_graph=graph->instruction_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
+ ++argument_number;
+ } 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+=4;
+#endif
+ }
+ } else
+#ifdef M68000
+ i_add_i_r (4,reg_1);
+#else
+ offset+=4;
+#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; i<n_registers; ++i)
+ if (i==n_registers-1 && !update_a_reg)
+ i_move_id_r (offset,a_reg,registers[i]);
+ else {
+ if (offset!=0){
+ i_add_i_r (offset,a_reg);
+ offset=0;
+ }
+ i_move_pi_r (a_reg,registers[i]);
+ }
+ return offset;
+ }
+#else
+ int i;
+
+ for (i=0; i<n_registers; ++i){
+ i_move_id_r (offset,a_reg,registers[i]);
+ offset+=4;
+ }
+ return offset;
+#endif
+}
+
+static void linearize_movem_operator (INSTRUCTION_GRAPH graph)
+{
+ ADDRESS ad_1;
+ int registers[16],offset,n_registers,a_reg,arity,address_register_used;
+ register int argument_number;
+
+ linearize_graph (graph->instruction_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_number<arity; ++argument_number){
+ register INSTRUCTION_GRAPH a_graph;
+
+ a_graph=graph->instruction_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+=4;
+ } 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_number<arity-2){
+#ifdef M68000
+ if (offset){
+ i_add_i_r (offset,a_reg);
+ offset=0;
+ }
+ i_fmove_pi_fr (a_reg,l_f_reg);
+#else
+ i_fmove_id_fr (offset,a_reg,l_f_reg);
+ offset+=8;
+#endif
+ } else
+ i_fmove_id_fr (offset,a_reg,l_f_reg);
+
+ ++argument_number;
+ } else {
+ if (a_graph->instruction_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_number<arity-1){
+#ifdef M68000
+ if (offset){
+ i_add_i_r (offset,a_reg);
+ offset=0;
+ }
+ i_move_pi_r (a_reg,reg_n);
+#else
+ i_move_id_r (offset,a_reg,reg_n);
+ offset+=4;
+#endif
+ } else
+ i_move_id_r (offset,a_reg,reg_n);
+ continue;
+ } else
+ if (reg_n==ad_1.ad_register && *ad_1.ad_count_p==1
+ && argument_number==arity-1)
+ {
+ 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_number<arity-1){
+#ifdef M68000
+ if (offset){
+ i_add_i_r (offset,a_reg);
+ offset=0;
+ }
+ i_move_pi_r (a_reg,reg_n);
+#else
+ i_move_id_r (offset,a_reg,reg_n);
+ offset+=4;
+#endif
+ } else
+ i_move_id_r (offset,a_reg,reg_n);
+
+ return;
+ }
+ }
+
+ if (a_graph->instruction_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<arity-1){
+#ifdef M68000
+ if (offset){
+ i_add_i_r (offset,a_reg);
+ offset=0;
+ }
+ i_move_pi_r (a_reg,l_d_reg);
+#else
+ i_move_id_r (offset,a_reg,l_d_reg);
+ offset+=4;
+#endif
+ } else
+ i_move_id_r (offset,a_reg,l_d_reg);
+ } else {
+ if (address_register_used){
+ offset=movem_registers (a_reg,n_registers,registers,offset,1);
+ n_registers=0;
+ address_register_used=0;
+ }
+ registers[n_registers++]=l_d_reg;
+ }
+ } else {
+ int l_a_reg;
+
+ l_a_reg=get_aregister();
+ register_node (a_graph,l_a_reg);
+
+ if (a_reg_num (l_a_reg)>=N_ADDRESS_PARAMETER_REGISTERS){
+ offset=movem_registers (a_reg,n_registers,registers,offset,1);
+ n_registers=0;
+ address_register_used=0;
+ if (argument_number<arity-1){
+#ifdef M68000
+ if (offset){
+ i_add_i_r (offset,a_reg);
+ offset=0;
+ }
+ i_move_pi_r (a_reg,l_a_reg);
+#else
+ i_move_id_r (offset,a_reg,l_a_reg);
+ offset+=4;
+#endif
+ } else
+ i_move_id_r (offset,a_reg,l_a_reg);
+ } else {
+ registers[n_registers++]=l_a_reg;
+ address_register_used=1;
+ }
+ }
+ }
+ }
+ }
+
+ offset=movem_registers (a_reg,n_registers,registers,offset,0);
+
+ if (--*ad_1.ad_count_p==0)
+ free_aregister (ad_1.ad_register);
+}
+
+static void linearize_movemi_operator (register INSTRUCTION_GRAPH graph,register ADDRESS *ad_p)
+{
+ linearize_movem_operator (graph->instruction_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 (4,areg_1,4,areg_2);
+ i_move_id_id (8,areg_1,8,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=(INSTRUCTION_GRAPH)ad_p->ad_offset;
+ i_ad_p=(ADDRESS *)load_x_graph->instruction_parameters[1].p;
+
+ 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);
+ freg=get_fregister();
+ i_fmove_x_fr (i_ad_p->ad_offset,i_ad_p->ad_areg,i_ad_p->ad_dreg,freg);
+ } else {
+ if (--*i_ad_p->ad_count_p==0)
+ free_aregister (i_ad_p->ad_register);
+ freg=get_fregister();
+ i_fmove_id_fr (i_ad_p->ad_offset,i_ad_p->ad_register,freg);
+ }
+ 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=(INSTRUCTION_GRAPH)ad_p->ad_offset;
+ i_ad_p=(ADDRESS *)load_x_graph->instruction_parameters[1].p;
+
+ 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);
+ freg=get_fregister();
+ i_fmove_x_fr (i_ad_p->ad_offset,i_ad_p->ad_areg,i_ad_p->ad_dreg,freg);
+ } else {
+ if (--*i_ad_p->ad_count_p==0)
+ free_aregister (i_ad_p->ad_register);
+ freg=get_fregister();
+ i_fmove_id_fr (i_ad_p->ad_offset,i_ad_p->ad_register,freg);
+ }
+ 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;
+ 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=(INSTRUCTION_GRAPH)ad_p->ad_offset;
+ i_ad_p=(ADDRESS *)load_x_graph->instruction_parameters[1].p;
+
+ if (load_x_graph->inode_arity==1){
+ load_x_graph->inode_arity=2;
+
+ 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);
+ }
+ } 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);
+}
+
+static void linearize_fhigh_operator (register INSTRUCTION_GRAPH graph,register 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=(INSTRUCTION_GRAPH)ad_p->ad_offset;
+ 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);
+#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==1){
+ } 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 (register INSTRUCTION_GRAPH graph,register 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=(INSTRUCTION_GRAPH)ad_p->ad_offset;
+ 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
+ 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==1){
+ 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");
+ }
+}
+
+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;
+
+#ifdef g_fhighlow
+ linearize_graph (low_graph,&ad_2);
+ linearize_graph (high_graph,&ad_1);
+#else
+ linearize_graph (high_graph,&ad_1);
+ linearize_graph (low_graph,&ad_2);
+#endif
+
+#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;
+
+#ifdef g_fhighlow
+ 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);
+#else
+ instruction_ad_id (IMOVE,&ad_1,local_data_offset,B_STACK_POINTER);
+ instruction_ad_id (IMOVE,&ad_2,local_data_offset+4,B_STACK_POINTER);
+#endif
+
+ 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;
+ }
+}
+
+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_register<ad_1.ad_register)
+ /* */
+ ){
+ reg_1=ad_1.ad_register;
+ instruction_ad_fr (instruction_code,&ad_2,reg_1);
+
+ *ad_1.ad_count_p=0;
+ } else {
+#if 1
+ struct parameter parameter1;
+ int free_f_register;
+
+#if defined (FMADD)
+ parameter1.parameter_flags=0;
+#endif
+ free_f_register=fad_to_parameter (&ad_1,&parameter1);
+ 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,&parameter1,reg_1);
+#else
+ in_alterable_float_register (&ad_2);
+ reg_1=ad_2.ad_register;
+ instruction_ad_fr (instruction_code,&ad_1,reg_1);
+#endif
+ --*ad_2.ad_count_p;
+ }
+
+ 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_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_POWER)
+ /* added 15-12-1998 */
+ if (ad_1.ad_mode==P_F_REGISTER && *ad_1.ad_count_p==1
+ && !(ad_2.ad_mode==P_F_REGISTER && ad_2.ad_register<ad_1.ad_register && *ad_2.ad_count_p==1)
+ ){
+ reg_1=ad_1.ad_register;
+ instruction_ad_fr (instruction_code,&ad_2,reg_1);
+ last_instruction->instruction_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 (&ad_1,&parameter1);
+ 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,&parameter1,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 (register INSTRUCTION_GRAPH graph,register 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 (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_offset=(LONG)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=1;
+ } 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();
+ i_fmove_x_fr (offset,ad_p->ad_register,ad_1.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);
+ }
+ } 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_offset=(LONG)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=1;
+ } 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 (offset>>2,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);
+ }
+ }
+}
+
+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;
+ case GFJOIN:
+ linearize_fjoin_operator (graph,ad_p);
+ return;
+ 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 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;
+/* added 10-12-97 */
+ 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
+ default:
+ /* printf ("%d %d\n",(int)graph,graph->instruction_code); */
+ internal_error_in_function ("linearize_float_graph");
+ }
+}
+
+static void linearize_fstore_operator (register 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);
+ linearize_load_graph (graph->instruction_parameters[4].p);
+
+ 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){
+#ifdef FP_STACK_OPTIMIZATIONS
+ 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;
+#ifdef FP_STACK_OPTIMIZATIONS
+ }
+#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;
+
+ last_block->block_n_new_heap_cells+=3;
+
+#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+8,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+4,HEAP_POINTER);
+# endif
+ offset_from_heap_register+=12;
+#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 (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_offset=(LONG)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=1;
+ } 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_offset=(LONG)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=1;
+ } 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=(INSTRUCTION_GRAPH)ad_1.ad_offset;
+ i_ad_p=(ADDRESS *)load_x_graph->instruction_parameters[1].p;
+#ifdef M68000
+ if (load_x_graph->inode_arity==1 && 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=(INSTRUCTION_GRAPH)ad_1.ad_offset;
+ i_ad_p=(ADDRESS *)load_x_graph->instruction_parameters[1].p;
+#ifdef M68000
+ if (load_x_graph->inode_arity==1 && 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=2;
+ 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=2;
+ 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=2;
+ 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; select_graph=select_graph->instruction_parameters[3].p){
+ 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==1 && select_graph!=graph_1){
+ ADDRESS *i_ad_p;
+ int dreg;
+
+ i_ad_p=(ADDRESS *)select_graph->instruction_parameters[1].p;
+
+ select_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);
+ 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!=2 /**/){
+ 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==1 && select_graph!=graph_1){
+ ADDRESS *i_ad_p;
+ int freg;
+
+ i_ad_p=(ADDRESS *)select_graph->instruction_parameters[1].p;
+
+ select_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);
+ freg=get_fregister();
+ i_fmove_x_fr (i_ad_p->ad_offset,i_ad_p->ad_areg,i_ad_p->ad_dreg,freg);
+ } else {
+ if (--*i_ad_p->ad_count_p==0)
+ free_aregister (i_ad_p->ad_register);
+ freg=get_fregister();
+ i_fmove_id_fr (i_ad_p->ad_offset,i_ad_p->ad_register,freg);
+ }
+ i_ad_p->ad_register=freg;
+ }
+ }
+ break;
+ case GREGISTER:
+ case GFREGISTER:
+ case GFHIGH:
+ case GFLOW:
+ case GGREGISTER:
+ break;
+ default:
+ internal_error_in_function ("do_array_selects_before_update");
+ }
+ }
+}
+
+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);
+ } 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){
+/* added 10-12-97 */
+ /* changed 27-6-2001 */
+
+ while (graph_2->instruction_code==GINDIRECTION)
+ graph_2=graph_2->instruction_parameters[0].p;
+
+ if (graph_2->instruction_code==GREGISTER){
+ /* if (graph_2->instruction_code==GREGISTER || graph_2->instruction_code==GINDIRECTION){ */
+
+ 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;
+ }
+ }
+/* added 27-6-2001 */
+ 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 (4,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);
+
+ 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].i;
+ } else {
+ register 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].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 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; i<graph->inode_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; i<graph->inode_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:
+ linearize_eor_operator (graph,ad_p);
+ return;
+ case GSUB:
+ linearize_dyadic_non_commutative_operator (ISUB,graph,ad_p);
+ return;
+#if defined (I486) || defined (G_POWER)
+ case GDIV:
+ linearize_div_mod_operator (IDIV,graph,ad_p);
+ return;
+ case GMOD:
+ linearize_div_mod_operator (IMOD,graph,ad_p);
+ return;
+#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_GT:
+ linearize_compare_operator (CGT,CLT,graph,ad_p);
+ return;
+ case GCNOT:
+ linearize_conditional_not_operator (graph,ad_p);
+ return;
+ case GLSR:
+ linearize_shift_operator (ILSR,graph,ad_p);
+ return;
+ case GLSL:
+ linearize_shift_operator (ILSL,graph,ad_p);
+ return;
+ case GASR:
+ linearize_shift_operator (IASR,graph,ad_p);
+ 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 GMOVEMI:
+ linearize_movemi_operator (graph,ad_p);
+ return;
+ case GCOPY:
+ linearize_copy_operator (graph,ad_p);
+ return;
+ case GFHIGH:
+ linearize_fhigh_operator (graph,ad_p);
+ return;
+ case GFLOW:
+ linearize_flow_operator (graph,ad_p);
+ return;
+ 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;
+ 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;
+ 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)
+{
+ register INSTRUCTION_GRAPH graph_1,graph_2,graph_3;
+ register 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)
+ move_float_ad_id (&ad_1,offset>>2,ad_p->ad_register);
+ 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
+ move_float_ad_x (&ad_1,offset,ad_p->ad_register,ad_3.ad_register);
+ }
+
+ 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);
+
+ 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);
+
+ 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