From: rth Date: Tue, 20 Apr 1999 16:44:09 +0000 (+0000) Subject: * alpha.md (nt_lda): New pattern. X-Git-Url: http://git.sourceforge.jp/view?a=commitdiff_plain;h=cd28cb76bf19eafdff2f3ccc4462d0f99faea04e;p=pf3gnuchains%2Fgcc-fork.git * alpha.md (nt_lda): New pattern. * alpha.c (alpha_expand_prologue): Use it for large frames under windows nt. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@26565 138bc75d-0d04-0410-961f-82ee72b054a4 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index fd67f315e45..52e50a8ce84 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +Tue Apr 20 16:38:11 1999 Richard Henderson + + * alpha.md (nt_lda): New pattern. + * alpha.c (alpha_expand_prologue): Use it for large frames + under windows nt. + Tue Apr 20 17:57:14 1999 Catherine Moore * config/arm/arm.md (movhi): Add check for odd offset. diff --git a/gcc/config/alpha/alpha.c b/gcc/config/alpha/alpha.c index c910278a00c..ca282786aca 100644 --- a/gcc/config/alpha/alpha.c +++ b/gcc/config/alpha/alpha.c @@ -3421,6 +3421,7 @@ alpha_expand_prologue () HOST_WIDE_INT leftover = frame_size + 4096 - blocks * 8192; rtx ptr = gen_rtx_REG (DImode, 22); rtx count = gen_rtx_REG (DImode, 23); + rtx seq; emit_move_insn (count, GEN_INT (blocks)); emit_insn (gen_adddi3 (ptr, stack_pointer_rtx, GEN_INT (4096))); @@ -3441,33 +3442,37 @@ alpha_expand_prologue () /* For NT stack unwind (done by 'reverse execution'), it's not OK to take the result of a loop, even though the value is already in ptr, so we reload it via a single operation - and add it to sp. */ + and subtract it to sp. + + Yes, that's correct -- we have to reload the whole constant + into a temporary via ldah+lda then subtract from sp. To + ensure we get ldah+lda, we use a special pattern. */ HOST_WIDE_INT lo, hi; lo = ((-frame_size & 0xffff) ^ 0x8000) - 0x8000; hi = -frame_size - lo; - FRP (emit_insn (gen_adddi3 (ptr, stack_pointer_rtx, GEN_INT (hi)))); - FRP (emit_insn (gen_adddi3 (stack_pointer_rtx, ptr, GEN_INT (lo)))); + emit_move_insn (ptr, GEN_INT (hi)); + emit_insn (gen_nt_lda (ptr, GEN_INT (lo))); + seq = emit_insn (gen_subdi3 (stack_pointer_rtx, stack_pointer_rtx, + ptr)); } else { - rtx seq; - seq = emit_insn (gen_adddi3 (stack_pointer_rtx, ptr, GEN_INT (-leftover))); - - /* This alternative is special, because the DWARF code cannot - possibly intuit through the loop above. So we invent this - note it looks at instead. */ - RTX_FRAME_RELATED_P (seq) = 1; - REG_NOTES (seq) - = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR, - gen_rtx_SET (VOIDmode, stack_pointer_rtx, - gen_rtx_PLUS (Pmode, stack_pointer_rtx, - GEN_INT (-frame_size))), - REG_NOTES (seq)); } + + /* This alternative is special, because the DWARF code cannot + possibly intuit through the loop above. So we invent this + note it looks at instead. */ + RTX_FRAME_RELATED_P (seq) = 1; + REG_NOTES (seq) + = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR, + gen_rtx_SET (VOIDmode, stack_pointer_rtx, + gen_rtx_PLUS (Pmode, stack_pointer_rtx, + GEN_INT (-frame_size))), + REG_NOTES (seq)); } /* Cope with very large offsets to the register save area. */ diff --git a/gcc/config/alpha/alpha.md b/gcc/config/alpha/alpha.md index 501443799af..dbc8b33d18e 100644 --- a/gcc/config/alpha/alpha.md +++ b/gcc/config/alpha/alpha.md @@ -29,6 +29,7 @@ ;; 3 mskxh ;; 4 cvtlq ;; 5 cvtql +;; 6 nt_lda ;; ;; UNSPEC_VOLATILE: ;; @@ -5161,6 +5162,16 @@ } }") +;; In creating a large stack frame, NT _must_ use ldah+lda to load +;; the frame size into a register. We use this pattern to ensure +;; we get lda instead of addq. +(define_insn "nt_lda" + [(set (match_operand:DI 0 "register_operand" "r") + (unspec:DI [(match_dup 0) + (match_operand:DI 1 "const_int_operand" "n")] 6))] + "" + "lda %0,%1(%0)") + (define_expand "builtin_longjmp" [(unspec_volatile [(match_operand 0 "register_operand" "r")] 3)] "! TARGET_OPEN_VMS && ! TARGET_WINDOWS_NT"