Commit 0c14a54d by Bob Wilson Committed by Bob Wilson

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
parent e9873fd5
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,
......
......@@ -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));
......
......@@ -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
......
......@@ -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. */
......
......@@ -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")])
;;
;; ....................
;;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment