diff options
author | Bob Wilson <bob.wilson@acm.org> | 2002-06-27 04:33:41 +0000 |
---|---|---|
committer | Bob Wilson <bwilson@gcc.gnu.org> | 2002-06-27 04:33:41 +0000 |
commit | 0c14a54df664db83ccd3954d34edbe7d298c83ad (patch) | |
tree | 38c67d5efdf712d104945d3513f73941e6148563 /gcc | |
parent | e9873fd5e10401fa9dab8f1524266b443ac0ede5 (diff) | |
download | gcc-0c14a54df664db83ccd3954d34edbe7d298c83ad.zip gcc-0c14a54df664db83ccd3954d34edbe7d298c83ad.tar.gz gcc-0c14a54df664db83ccd3954d34edbe7d298c83ad.tar.bz2 |
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: r55020
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/config/xtensa/xtensa-protos.h | 1 | ||||
-rw-r--r-- | gcc/config/xtensa/xtensa.c | 27 | ||||
-rw-r--r-- | gcc/config/xtensa/xtensa.h | 21 | ||||
-rw-r--r-- | gcc/config/xtensa/xtensa.md | 19 |
5 files changed, 57 insertions, 18 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 9d1a0a0..973df1e 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2002-06-26 Bob Wilson <bob.wilson@acm.org> + + * 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-26 Kaveh R. Ghazi <ghazi@caip.rutgers.edu> * mips.c (coprocessor_operand, coprocessor2_operand, diff --git a/gcc/config/xtensa/xtensa-protos.h b/gcc/config/xtensa/xtensa-protos.h index 76cf73c..bb640bb 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_preferred_reload_class PARAMS ((rtx, enum reg_class)); diff --git a/gcc/config/xtensa/xtensa.c b/gcc/config/xtensa/xtensa.c index dd9ad7d..bf669da 100644 --- a/gcc/config/xtensa/xtensa.c +++ b/gcc/config/xtensa/xtensa.c @@ -2281,6 +2281,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 e98c2c6..22fcb79 100644 --- a/gcc/config/xtensa/xtensa.h +++ b/gcc/config/xtensa/xtensa.h @@ -1060,8 +1060,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. @@ -1085,22 +1084,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 771edd5..cf07ffc 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) ]) @@ -1370,6 +1371,7 @@ (set_attr "mode" "SI") (set_attr "length" "6,6")]) + ;; ;; .................... ;; @@ -2432,6 +2434,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")]) + + ;; ;; .................... ;; |