aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Henderson <rth@cygnus.com>1999-04-20 09:44:09 -0700
committerRichard Henderson <rth@gcc.gnu.org>1999-04-20 09:44:09 -0700
commit37679e060354a880f3c7cdd8deb852aa67c1206d (patch)
tree1e6f7fd951b7d370a663e0ace5ecf5a8b9609290
parent0f834f0a3e618d5af3dfdeb1dba4ffe085fd4484 (diff)
downloadgcc-37679e060354a880f3c7cdd8deb852aa67c1206d.zip
gcc-37679e060354a880f3c7cdd8deb852aa67c1206d.tar.gz
gcc-37679e060354a880f3c7cdd8deb852aa67c1206d.tar.bz2
alpha.md (nt_lda): New pattern.
* alpha.md (nt_lda): New pattern. * alpha.c (alpha_expand_prologue): Use it for large frames under windows nt. From-SVN: r26565
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/config/alpha/alpha.c37
-rw-r--r--gcc/config/alpha/alpha.md11
3 files changed, 38 insertions, 16 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index fd67f31..52e50a8 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 c910278..ca28278 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 5014437..dbc8b33 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"