From a64761a3cab9218b7fd6ad7fb6ef9b8eb997ba87 Mon Sep 17 00:00:00 2001 From: DJ Delorie Date: Fri, 5 Jan 2001 19:00:35 -0500 Subject: [PATCH] Implement __builtin_return_address (0) From-SVN: r38734 --- gcc/ChangeLog | 14 +++++++ gcc/config/v850/v850-protos.h | 2 + gcc/config/v850/v850.c | 76 ++++++++++++++++++++++++++++++++++- gcc/config/v850/v850.h | 8 +++- 4 files changed, 97 insertions(+), 3 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 580133ce0bb..7f280c1f329 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,17 @@ +2001-01-05 DJ Delorie + + * config/v850/v850.h (RETURN_ADDR_RTX): Define. + (INIT_EXPANDERS): Define. + + * config/v850/v850.c (struct machine_function): Define. + (v850_save_machine_status): New function. + (v850_restore_machine_status): New function. + (v850_return_addr): New function. + (v850_init_expanders): New function. + + * config/v850/v850-protos.h: Add prototypes for v850_return_addr + and v850_init_expanders. + 2001-01-05 Zack Weinberg * cpplib.h (struct cpp_reader): Add help_only field. diff --git a/gcc/config/v850/v850-protos.h b/gcc/config/v850/v850-protos.h index 03be1346ebb..f0b7b4ed27f 100644 --- a/gcc/config/v850/v850-protos.h +++ b/gcc/config/v850/v850-protos.h @@ -39,8 +39,10 @@ extern void asm_file_start PARAMS ((FILE *)); extern void override_options PARAMS ((void)); extern int compute_register_save_size PARAMS ((long *)); extern int compute_frame_size PARAMS ((int, long *)); +extern void v850_init_expanders PARAMS ((void)); #ifdef RTX_CODE +extern rtx v850_return_addr PARAMS ((int)); extern void print_operand PARAMS ((FILE *, rtx, int )); extern void print_operand_address PARAMS ((FILE *, rtx)); extern int const_costs PARAMS ((rtx, enum rtx_code)); diff --git a/gcc/config/v850/v850.c b/gcc/config/v850/v850.c index c30b6e8651c..86c7144206c 100644 --- a/gcc/config/v850/v850.c +++ b/gcc/config/v850/v850.c @@ -1,5 +1,6 @@ /* Subroutines for insn-output.c for NEC V850 series - Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc. + Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001 + Free Software Foundation, Inc. Contributed by Jeff Law (law@cygnus.com). This file is part of GNU CC. @@ -52,6 +53,8 @@ static int const_costs_int PARAMS ((HOST_WIDE_INT, int)); static void substitute_ep_register PARAMS ((rtx, rtx, int, int, rtx *, rtx *)); static int ep_memory_offset PARAMS ((enum machine_mode, int)); static void v850_set_data_area PARAMS ((tree, v850_data_area)); +static void v850_save_machine_status PARAMS ((struct function *)); +static void v850_restore_machine_status PARAMS ((struct function *)); /* True if the current function has anonymous arguments. */ int current_function_anonymous_args; @@ -2783,3 +2786,74 @@ v850_va_arg (valist, type) return addr_rtx; } + +/* Functions to save and restore machine-specific function data. */ + +static rtx ra_rtx; + +struct machine_function +{ + /* Records __builtin_return address. */ + struct rtx_def * ra_rtx; +}; + +static void +v850_save_machine_status (p) + struct function * p; +{ + p->machine = + (struct machine_function *) xcalloc (1, sizeof (struct machine_function)); + p->machine->ra_rtx = ra_rtx; +} + +static void +v850_restore_machine_status (p) + struct function * p; +{ + ra_rtx = p->machine->ra_rtx; + free (p->machine); + p->machine = NULL; +} + +/* Return an RTX indicating where the return address to the + calling function can be found. */ + +rtx +v850_return_addr (count) + int count; +{ + if (count != 0) + return const0_rtx; + + if (ra_rtx == NULL) + { + rtx init; + + /* No rtx yet. Invent one, and initialize it for r31 (lp) in + the prologue. */ + ra_rtx = gen_reg_rtx (Pmode); + + init = gen_rtx_REG (Pmode, LINK_POINTER_REGNUM); + + init = gen_rtx_SET (VOIDmode, ra_rtx, init); + + /* Emit the insn to the prologue with the other argument copies. */ + push_topmost_sequence (); + emit_insn_after (init, get_insns ()); + pop_topmost_sequence (); + } + + debug_rtx (ra_rtx); + return ra_rtx; +} + +/* Do anything needed before RTL is emitted for each function. */ + +void +v850_init_expanders () +{ + ra_rtx = NULL; + + save_machine_status = v850_save_machine_status; + restore_machine_status = v850_restore_machine_status; +} diff --git a/gcc/config/v850/v850.h b/gcc/config/v850/v850.h index ccf49674d1d..36bce1a84bb 100644 --- a/gcc/config/v850/v850.h +++ b/gcc/config/v850/v850.h @@ -1,5 +1,5 @@ /* Definitions of target machine for GNU compiler. NEC V850 series - Copyright (C) 1996, 1997, 1998, 1999, 2000 Free Software Foundation, Inc. + Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc. Contributed by Jeff Law (law@cygnus.com). This file is part of GNU CC. @@ -681,6 +681,7 @@ enum reg_class #define RETURN_POPS_ARGS(FUNDECL,FUNTYPE,SIZE) 0 +#define RETURN_ADDR_RTX(COUNT, FP) v850_return_addr (COUNT) /* Define a data type for recording info about an argument list during the scan of that argument list. This data type should @@ -789,6 +790,10 @@ extern int current_function_anonymous_args; #define EXIT_IGNORE_STACK 1 +/* Initialize data used by insn expanders. This is called from insn_emit, + once for every function before code is generated. */ +#define INIT_EXPANDERS v850_init_expanders () + /* Output assembler code to FILE to increment profiler label # LABELNO for profiling a function entry. */ @@ -1618,7 +1623,6 @@ extern union tree_node * GHS_current_section_names [(int) COUNT_OF_GHS_SECTION_K matched by the predicate. The list should have a trailing comma. */ #define PREDICATE_CODES \ -{ "ep_memory_operand", { MEM }}, \ { "reg_or_0_operand", { REG, SUBREG, CONST_INT, CONST_DOUBLE }}, \ { "reg_or_int5_operand", { REG, SUBREG, CONST_INT }}, \ { "call_address_operand", { REG, SYMBOL_REF }}, \