summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHiroaki Etoh <etoh@cvs.openbsd.org>2003-02-21 08:15:38 +0000
committerHiroaki Etoh <etoh@cvs.openbsd.org>2003-02-21 08:15:38 +0000
commitff4c3cd5bc0ad3a28d05f393606d027b6ebc319d (patch)
tree82a4a12def2011e8868bc18a457a44002f8d01df
parent73aadc7025b53bf36c4fbe643fdba5081a7cc238 (diff)
push_frame_in_operand: add the setup and restore code for setjmp on powerpc and alpha
-rw-r--r--gnu/egcs/gcc/protector.c55
1 files changed, 39 insertions, 16 deletions
diff --git a/gnu/egcs/gcc/protector.c b/gnu/egcs/gcc/protector.c
index 8cbf25bda8d..17568326dad 100644
--- a/gnu/egcs/gcc/protector.c
+++ b/gnu/egcs/gcc/protector.c
@@ -2200,9 +2200,41 @@ push_frame_in_operand (insn, orig, push_size, boundary)
return;
case SET:
- /* skip the insn that restores setjmp address */
- if (XEXP (x, 0) == frame_pointer_rtx)
+ /*
+ skip setjmp setup insn and setjmp restore insn
+ alpha case:
+ (set (MEM (reg:SI xx)) (frame_pointer_rtx)))
+ (set (frame_pointer_rtx) (REG))
+ */
+ if (GET_CODE (XEXP (x, 0)) == MEM
+ && XEXP (x, 1) == frame_pointer_rtx)
return;
+ if (XEXP (x, 0) == frame_pointer_rtx
+ && GET_CODE (XEXP (x, 1)) == REG)
+ return;
+
+ /*
+ powerpc case: restores setjmp address
+ (set (frame_pointer_rtx) (plus frame_pointer_rtx const_int -n))
+ or
+ (set (reg) (plus frame_pointer_rtx const_int -n))
+ (set (frame_pointer_rtx) (reg))
+ */
+ if (GET_CODE (XEXP (x, 0)) == REG
+ && GET_CODE (XEXP (x, 1)) == PLUS
+ && XEXP (XEXP (x, 1), 0) == frame_pointer_rtx
+ && CONSTANT_P (XEXP (XEXP (x, 1), 1))
+ && INTVAL (XEXP (XEXP (x, 1), 1)) < 0)
+ {
+ x = XEXP (x, 1);
+ offset = AUTO_OFFSET(x);
+ if (x->used || abs (offset) < boundary)
+ return;
+
+ XEXP (x, 1) = gen_rtx_CONST_INT (VOIDmode, offset - push_size);
+ x->used = 1; insn_pushed = TRUE;
+ return;
+ }
/* reset fp_equiv register */
else if (GET_CODE (XEXP (x, 0)) == REG
@@ -2235,15 +2267,10 @@ push_frame_in_operand (insn, orig, push_size, boundary)
if (CONSTANT_P (XEXP (x, 1))
&& XEXP (x, 0) == frame_pointer_rtx)
{
- if (x->used || abs (offset) < boundary)
+ if (x->used || offset < boundary)
return;
- if (offset > 0)
- offset += push_size;
- else
- offset -= push_size;
-
- XEXP (x, 1) = gen_rtx_CONST_INT (VOIDmode, offset);
+ XEXP (x, 1) = gen_rtx_CONST_INT (VOIDmode, offset + push_size);
x->used = 1; insn_pushed = TRUE;
return;
@@ -2280,15 +2307,11 @@ push_frame_in_operand (insn, orig, push_size, boundary)
{
HOST_WIDE_INT offset = INTVAL (SET_SRC (PATTERN (PREV_INSN (insn))));
- if (x->used || abs (offset) < boundary)
+ if (x->used || offset < boundary)
return;
- if (offset > 0)
- offset += push_size;
- else
- offset -= push_size;
-
- SET_SRC (PATTERN (PREV_INSN (insn))) = gen_rtx_CONST_INT (VOIDmode, offset);
+ SET_SRC (PATTERN (PREV_INSN (insn)))
+ = gen_rtx_CONST_INT (VOIDmode, offset + push_size);
x->used = 1;
XEXP (x, 1)->used = 1;