From 11d0a70ad143c6a87e762ef85467a60f331c7d92 Mon Sep 17 00:00:00 2001 From: Bob Wilson Date: Mon, 1 Jul 2002 15:58:44 +0000 Subject: [PATCH] xtensa-protos.h (xtensa_return_addr): Declare. * config/xtensa/xtensa-protos.h (xtensa_return_addr): Declare. config/xtensa/xtensa.c (xtensa_return_addr): New function. config/xtensa/xtensa.h (RETURN_ADDR_RTX): Use xtensa_return_addr. config/xtensa/xtensa.md (fix_return_addr): New pattern. From-SVN: r55137 --- gcc/ChangeLog | 7 +++++++ gcc/config/xtensa/xtensa-protos.h | 1 + gcc/config/xtensa/xtensa.c | 27 +++++++++++++++++++++++++++ gcc/config/xtensa/xtensa.h | 21 +++------------------ gcc/config/xtensa/xtensa.md | 19 +++++++++++++++++++ 5 files changed, 57 insertions(+), 18 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index a7055fca28a0..af9cb7000cab 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2002-06-28 Bob Wilson + + * config/xtensa/xtensa-protos.h (xtensa_return_addr): Declare. + config/xtensa/xtensa.c (xtensa_return_addr): New function. + config/xtensa/xtensa.h (RETURN_ADDR_RTX): Use xtensa_return_addr. + config/xtensa/xtensa.md (fix_return_addr): New pattern. + 2002-06-28 Bob Wilson * config/xtensa/xtensa.h (FUNCTION_PROFILER): Respect flag_pic diff --git a/gcc/config/xtensa/xtensa-protos.h b/gcc/config/xtensa/xtensa-protos.h index bb18e3ae84ad..b25205e52026 100644 --- a/gcc/config/xtensa/xtensa-protos.h +++ b/gcc/config/xtensa/xtensa-protos.h @@ -86,6 +86,7 @@ extern void print_operand_address PARAMS ((FILE *, rtx)); extern void xtensa_output_literal PARAMS ((FILE *, rtx, enum machine_mode, int labelno)); extern void xtensa_reorg PARAMS ((rtx)); +extern rtx xtensa_return_addr PARAMS ((int, rtx)); extern rtx xtensa_builtin_saveregs PARAMS ((void)); extern enum reg_class xtensa_secondary_reload_class PARAMS ((enum reg_class, enum machine_mode, rtx, int)); diff --git a/gcc/config/xtensa/xtensa.c b/gcc/config/xtensa/xtensa.c index c0ca2f861654..89adf52e08f4 100644 --- a/gcc/config/xtensa/xtensa.c +++ b/gcc/config/xtensa/xtensa.c @@ -2263,6 +2263,33 @@ xtensa_function_epilogue (file, size) } +rtx +xtensa_return_addr (count, frame) + int count; + rtx frame; +{ + rtx result, retaddr; + + if (count == -1) + retaddr = gen_rtx_REG (Pmode, 0); + else + { + rtx addr = plus_constant (frame, -4 * UNITS_PER_WORD); + addr = memory_address (Pmode, addr); + retaddr = gen_reg_rtx (Pmode); + emit_move_insn (retaddr, gen_rtx_MEM (Pmode, addr)); + } + + /* The 2 most-significant bits of the return address on Xtensa hold + the register window size. To get the real return address, these + bits must be replaced with the high bits from the current PC. */ + + result = gen_reg_rtx (Pmode); + emit_insn (gen_fix_return_addr (result, retaddr)); + return result; +} + + /* Create the va_list data type. This structure is set up by __builtin_saveregs. The __va_reg field points to a stack-allocated region holding the contents of the diff --git a/gcc/config/xtensa/xtensa.h b/gcc/config/xtensa/xtensa.h index 61c1db9d252e..cf3ddcf1daf4 100644 --- a/gcc/config/xtensa/xtensa.h +++ b/gcc/config/xtensa/xtensa.h @@ -1465,8 +1465,7 @@ typedef struct xtensa_args { we currently need to ensure that there is a frame pointer when these builtin functions are used. */ -#define SETUP_FRAME_ADDRESSES() \ - xtensa_setup_frame_addresses () +#define SETUP_FRAME_ADDRESSES xtensa_setup_frame_addresses /* A C expression whose value is RTL representing the address in a stack frame where the pointer to the caller's frame is stored. @@ -1491,22 +1490,8 @@ typedef struct xtensa_args { /* A C expression whose value is RTL representing the value of the return address for the frame COUNT steps up from the current - frame, after the prologue. FRAMEADDR is the frame pointer of the - COUNT frame, or the frame pointer of the COUNT - 1 frame if - 'RETURN_ADDR_IN_PREVIOUS_FRAME' is defined. - - The 2 most-significant bits of the return address on Xtensa hold - the register window size. To get the real return address, these bits - must be masked off and replaced with the high bits from the current - PC. Since it is unclear how the __builtin_return_address function - is used, the current code does not do this masking and simply returns - the raw return address from the a0 register. */ - -#define RETURN_ADDR_RTX(count, frame) \ - ((count) == -1 \ - ? gen_rtx_REG (Pmode, 0) \ - : gen_rtx_MEM (Pmode, memory_address \ - (Pmode, plus_constant (frame, -4 * UNITS_PER_WORD)))) + frame, after the prologue. */ +#define RETURN_ADDR_RTX xtensa_return_addr /* Addressing modes, and classification of registers for them. */ diff --git a/gcc/config/xtensa/xtensa.md b/gcc/config/xtensa/xtensa.md index f27a92e005a6..cee4347fde12 100644 --- a/gcc/config/xtensa/xtensa.md +++ b/gcc/config/xtensa/xtensa.md @@ -34,6 +34,7 @@ (UNSPEC_NSAU 1) (UNSPEC_NOP 2) (UNSPEC_PLT 3) + (UNSPEC_RET_ADDR 4) (UNSPECV_SET_FP 1) ]) @@ -1304,6 +1305,7 @@ (set_attr "mode" "SI") (set_attr "length" "6,6")]) + ;; ;; .................... ;; @@ -2366,6 +2368,23 @@ (set_attr "mode" "none") (set_attr "length" "0")]) +;; The fix_return_addr pattern sets the high 2 bits of an address in a +;; register to match the high bits of the current PC. + +(define_insn "fix_return_addr" + [(set (match_operand:SI 0 "register_operand" "=a") + (unspec:SI [(match_operand:SI 1 "register_operand" "r")] + UNSPEC_RET_ADDR)) + (clobber (match_scratch:SI 2 "=r")) + (clobber (match_scratch:SI 3 "=r"))] + "" + "mov\\t%2, a0\;call0\\t0f\;.align\\t4\;0:\;mov\\t%3, a0\;mov\\ta0, %2\;\ +srli\\t%3, %3, 30\;slli\\t%0, %1, 2\;ssai\\t2\;src\\t%0, %3, %0" + [(set_attr "type" "multi") + (set_attr "mode" "SI") + (set_attr "length" "24")]) + + ;; ;; .................... ;; -- 2.47.2