aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorDJ Delorie <dj@redhat.com>2001-01-05 19:00:35 -0500
committerNick Clifton <nickc@gcc.gnu.org>2001-01-06 00:00:35 +0000
commita64761a3cab9218b7fd6ad7fb6ef9b8eb997ba87 (patch)
tree317568ee822f345a94f4188d78f1de88d1b68b82 /gcc
parentf4cdc368349bc046cd0874408bad7fc6f2104a3a (diff)
downloadgcc-a64761a3cab9218b7fd6ad7fb6ef9b8eb997ba87.zip
gcc-a64761a3cab9218b7fd6ad7fb6ef9b8eb997ba87.tar.gz
gcc-a64761a3cab9218b7fd6ad7fb6ef9b8eb997ba87.tar.bz2
Implement __builtin_return_address (0)
From-SVN: r38734
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog14
-rw-r--r--gcc/config/v850/v850-protos.h2
-rw-r--r--gcc/config/v850/v850.c76
-rw-r--r--gcc/config/v850/v850.h8
4 files changed, 97 insertions, 3 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 580133c..7f280c1 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,17 @@
+2001-01-05 DJ Delorie <dj@redhat.com>
+
+ * 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 <zack@wolery.stanford.edu>
* 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 03be134..f0b7b4e 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 c30b6e8..86c7144 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 ccf4967..36bce1a 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 }}, \