#endif
static int mips_adjust_cost PARAMS ((rtx, rtx, rtx, int));
+static void mips_init_machine_status PARAMS ((struct function *));
+static void mips_free_machine_status PARAMS ((struct function *));
+static void mips_mark_machine_status PARAMS ((struct function *));
+
+struct machine_function {
+ /* Pseudo-reg holding the address of the current function when
+ generating embedded PIC code. Created by LEGITIMIZE_ADDRESS,
+ used by mips_finalize_pic if it was created. */
+ rtx embedded_pic_fnaddr_rtx;
+
+ /* Pseudo-reg holding the value of $28 in a mips16 function which
+ refers to GP relative global variables. */
+ rtx mips16_gp_pseudo_rtx;
+};
+
+
/* Global variables for machine-dependent things. */
/* Threshold for data being put into the small data/bss area, instead
/* Zero structure to initialize current_frame_info. */
struct mips_frame_info zero_frame_info;
-/* Pseudo-reg holding the address of the current function when
- generating embedded PIC code. Created by LEGITIMIZE_ADDRESS, used
- by mips_finalize_pic if it was created. */
-rtx embedded_pic_fnaddr_rtx;
-
/* The length of all strings seen when compiling for the mips16. This
is used to tell how many strings are in the constant pool, so that
we can see if we may have an overflow. This is reset each time the
constant pool is output. */
int mips_string_length;
-/* Pseudo-reg holding the value of $28 in a mips16 function which
- refers to GP relative global variables. */
-rtx mips16_gp_pseudo_rtx;
-
/* In mips16 mode, we build a list of all the string constants we see
in a particular function. */
}
\f
-/* Return RTL for the offset from the current function to the argument.
-
- ??? Which argument is this? */
+/* Return a pseudo that points to the address of the current function.
+ The first time it is called for a function, an initializer for the
+ pseudo is emitted in the beginning of the function. */
rtx
-embedded_pic_offset (x)
- rtx x;
+embedded_pic_fnaddr_reg ()
{
- if (embedded_pic_fnaddr_rtx == NULL)
+ if (cfun->machine->embedded_pic_fnaddr_rtx == NULL)
{
rtx seq;
- embedded_pic_fnaddr_rtx = gen_reg_rtx (Pmode);
+ cfun->machine->embedded_pic_fnaddr_rtx = gen_reg_rtx (Pmode);
/* Output code at function start to initialize the pseudo-reg. */
/* ??? We used to do this in FINALIZE_PIC, but that does not work for
initialize this value every time a function is inlined into another
function. */
start_sequence ();
- emit_insn (gen_get_fnaddr (embedded_pic_fnaddr_rtx,
+ emit_insn (gen_get_fnaddr (cfun->machine->embedded_pic_fnaddr_rtx,
XEXP (DECL_RTL (current_function_decl), 0)));
seq = gen_sequence ();
end_sequence ();
pop_topmost_sequence ();
}
+ return cfun->machine->embedded_pic_fnaddr_rtx;
+}
+
+/* Return RTL for the offset from the current function to the argument.
+ X is the symbol whose offset from the current function we want. */
+
+rtx
+embedded_pic_offset (x)
+ rtx x;
+{
+ /* Make sure it is emitted. */
+ embedded_pic_fnaddr_reg ();
+
return
gen_rtx_CONST (Pmode,
gen_rtx_MINUS (Pmode, x,
/* Register global variables with the garbage collector. */
mips_add_gc_roots ();
+
+ /* Functions to allocate, mark and deallocate machine-dependent
+ function status. */
+ init_machine_status = &mips_init_machine_status;
+ free_machine_status = &mips_free_machine_status;
+ mark_machine_status = &mips_mark_machine_status;
+}
+
+/* Allocate a chunk of memory for per-function machine-dependent data. */
+static void
+mips_init_machine_status (fn)
+ struct function *fn;
+{
+ fn->machine = ((struct machine_function *)
+ xcalloc (1, sizeof (struct machine_function)));
+}
+
+/* Release the chunk of memory for per-function machine-dependent data. */
+static void
+mips_free_machine_status (fn)
+ struct function *fn;
+{
+ free (fn->machine);
+ fn->machine = NULL;
+}
+
+/* Mark per-function machine-dependent data. */
+static void
+mips_mark_machine_status (fn)
+ struct function *fn;
+{
+ if (fn->machine)
+ {
+ ggc_mark_rtx (fn->machine->embedded_pic_fnaddr_rtx);
+ ggc_mark_rtx (fn->machine->mips16_gp_pseudo_rtx);
+ }
}
/* On the mips16, we want to allocate $24 (T_REG) before other
rtx
mips16_gp_pseudo_reg ()
{
- if (mips16_gp_pseudo_rtx == NULL_RTX)
+ if (cfun->machine->mips16_gp_pseudo_rtx == NULL_RTX)
{
rtx const_gp;
rtx insn, scan;
- mips16_gp_pseudo_rtx = gen_reg_rtx (Pmode);
- RTX_UNCHANGING_P (mips16_gp_pseudo_rtx) = 1;
+ cfun->machine->mips16_gp_pseudo_rtx = gen_reg_rtx (Pmode);
+ RTX_UNCHANGING_P (cfun->machine->mips16_gp_pseudo_rtx) = 1;
/* We want to initialize this to a value which gcc will believe
is constant. */
gen_rtx (REG, Pmode, GP_REG_FIRST + 28));
start_sequence ();
- emit_move_insn (mips16_gp_pseudo_rtx, const_gp);
+ emit_move_insn (cfun->machine->mips16_gp_pseudo_rtx,
+ const_gp);
insn = gen_sequence ();
end_sequence ();
pop_topmost_sequence ();
}
- return mips16_gp_pseudo_rtx;
+ return cfun->machine->mips16_gp_pseudo_rtx;
}
/* Return an RTX which represents the signed 16 bit offset from the
ggc_add_rtx_root (&mips_load_reg3, 1);
ggc_add_rtx_root (&mips_load_reg4, 1);
ggc_add_rtx_root (branch_cmp, ARRAY_SIZE (branch_cmp));
- ggc_add_rtx_root (&embedded_pic_fnaddr_rtx, 1);
- ggc_add_rtx_root (&mips16_gp_pseudo_rtx, 1);
}
static enum processor_type
extern struct rtx_def *mips_load_reg2; /* 2nd reg to check for load delay */
extern struct rtx_def *mips_load_reg3; /* 3rd reg to check for load delay */
extern struct rtx_def *mips_load_reg4; /* 4th reg to check for load delay */
-extern struct rtx_def *embedded_pic_fnaddr_rtx; /* function address */
extern int mips_string_length; /* length of strings for mips16 */
-extern struct rtx_def *mips16_gp_pseudo_rtx; /* psuedo reg holding $gp */
/* Functions to change what output section we are using. */
extern void rdata_section PARAMS ((void));
#define PIC_OFFSET_TABLE_REGNUM (GP_REG_FIRST + 28)
#define PIC_FUNCTION_ADDR_REGNUM (GP_REG_FIRST + 25)
-
-/* Initialize embedded_pic_fnaddr_rtx before RTL generation for
- each function. We used to do this in FINALIZE_PIC, but FINALIZE_PIC
- isn't always called for static inline functions. */
-#define INIT_EXPANDERS \
-do { \
- embedded_pic_fnaddr_rtx = NULL; \
- mips16_gp_pseudo_rtx = NULL; \
-} while (0)
\f
/* Define the classes of registers for register constraints in the
machine description. Also define ranges of constants.