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:
parent
e9873fd5e1
commit
0c14a54df6
|
@ -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,
|
||||
|
|
|
@ -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")])
|
||||
|
||||
|
||||
;;
|
||||
;; ....................
|
||||
;;
|
||||
|
|
Loading…
Reference in New Issue