diff options
| author | rth <rth@138bc75d-0d04-0410-961f-82ee72b054a4> | 1999-04-20 16:44:09 +0000 |
|---|---|---|
| committer | rth <rth@138bc75d-0d04-0410-961f-82ee72b054a4> | 1999-04-20 16:44:09 +0000 |
| commit | cd28cb76bf19eafdff2f3ccc4462d0f99faea04e (patch) | |
| tree | 1e6f7fd951b7d370a663e0ace5ecf5a8b9609290 | |
| parent | a6371e9a06a153264a0a61a58c851974bcb82377 (diff) | |
| download | ppe42-gcc-cd28cb76bf19eafdff2f3ccc4462d0f99faea04e.tar.gz ppe42-gcc-cd28cb76bf19eafdff2f3ccc4462d0f99faea04e.zip | |
* 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
| -rw-r--r-- | gcc/ChangeLog | 6 | ||||
| -rw-r--r-- | gcc/config/alpha/alpha.c | 37 | ||||
| -rw-r--r-- | gcc/config/alpha/alpha.md | 11 |
3 files changed, 38 insertions, 16 deletions
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 <rth@cygnus.com> + + * 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 <clm@cygnus.com> * 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" |

