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
This commit is contained in:
Bob Wilson 2002-06-27 04:33:41 +00:00 committed by Bob Wilson
parent e9873fd5e1
commit 0c14a54df6
5 changed files with 57 additions and 18 deletions

View File

@ -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,

View File

@ -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));

View File

@ -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

View File

@ -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. */

View File

@ -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")])
;;
;; ....................
;;