OSDN Git Service

* alpha/osf.h (TARGET_HAS_XFLOATING_LIBS): Define.
[pf3gnuchains/gcc-fork.git] / gcc / config / alpha / alpha.md
index f4f0ced..b1d7904 100644 (file)
@@ -27,7 +27,6 @@
 ;;     1       cttz
 ;;     2       insxh
 ;;     3       mskxh
-;;     4       cvtlq
 ;;     5       cvtql
 ;;     6       nt_lda
 ;;     
 
 ;; Handle 32-64 bit extension from memory to a floating point register
 ;; specially, since this ocurrs frequently in int->double conversions.
-;; This is done with a define_split after reload converting the plain
-;; sign-extension into a load+unspec, which of course results in lds+cvtlq.
 ;;
 ;; Note that while we must retain the =f case in the insn for reload's
 ;; benefit, it should be eliminated after reload, so we should never emit
 ;; code for that case.  But we don't reject the possibility.
 
-(define_insn "extendsidi2"
-  [(set (match_operand:DI 0 "register_operand" "=r,r,?f")
-       (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m,m")))]
+(define_expand "extendsidi2"
+  [(set (match_operand:DI 0 "register_operand" "")
+       (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
   ""
+  "")
+
+(define_insn ""
+  [(set (match_operand:DI 0 "register_operand" "=r,r,*f,?*f")
+       (sign_extend:DI
+         (match_operand:SI 1 "nonimmediate_operand" "r,m,*f,m")))]
+  "! TARGET_FIX"
   "@
    addl %1,$31,%0
    ldl %0,%1
+   cvtlq %1,%0
    lds %0,%1\;cvtlq %0,%0"
-  [(set_attr "type" "iadd,ild,fld")
-   (set_attr "length" "*,*,8")])
+  [(set_attr "type" "iadd,ild,fadd,fld")
+   (set_attr "length" "*,*,*,8")])
+
+(define_insn ""
+  [(set (match_operand:DI 0 "register_operand" "=r,r,r,*f,?*f")
+       (sign_extend:DI
+         (match_operand:SI 1 "nonimmediate_operand" "r,m,*f,*f,m")))]
+  "TARGET_FIX"
+  "@
+   addl %1,$31,%0
+   ldl %0,%1
+   ftois %1,%0
+   cvtlq %1,%0
+   lds %0,%1\;cvtlq %0,%0"
+  [(set_attr "type" "iadd,ild,ftoi,fadd,fld")
+   (set_attr "length" "*,*,*,*,8")])
 
 ;; Due to issues with CLASS_CANNOT_CHANGE_SIZE, we cannot use a subreg here.
 (define_split
        (sign_extend:DI (match_operand:SI 1 "memory_operand" "")))]
   "reload_completed"
   [(set (match_dup 2) (match_dup 1))
-   (set (match_dup 0) (unspec:DI [(match_dup 2)] 4))]
+   (set (match_dup 0) (sign_extend:DI (match_dup 2)))]
   "operands[2] = gen_rtx_REG (SImode, REGNO (operands[0]));")
 
-(define_insn ""
-  [(set (match_operand:DI 0 "register_operand" "=f")
-       (unspec:DI [(match_operand:SI 1 "register_operand" "f")] 4))]
-  ""
-  "cvtlq %1,%0"
-  [(set_attr "type" "fadd")])
-
 ;; Do addsi3 the way expand_binop would do if we didn't have one.  This
 ;; generates better code.  We have the anonymous addsi3 pattern below in
 ;; case combine wants to make it.
   operands[7] = gen_lowpart (SImode, operands[5]);
 }")
 
-(define_insn "adddi3"
-  [(set (match_operand:DI 0 "register_operand" "=r,r,r,r")
-       (plus:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ,rJ,rJ,rJ")
-                (match_operand:DI 2 "add_operand" "rI,O,K,L")))]
+(define_expand "adddi3"
+  [(set (match_operand:DI 0 "register_operand" "")
+       (plus:DI (match_operand:DI 1 "register_operand" "")
+                (match_operand:DI 2 "add_operand" "")))]
   ""
-  "*
-{
-  static const char * const pattern[4] = {
-    \"addq %r1,%2,%0\",
-    \"subq %r1,%n2,%0\",
-    \"lda %0,%2(%r1)\",
-    \"ldah %0,%h2(%r1)\"
-  };
-
-  /* The NT stack unwind code can't handle a subq to adjust the stack
-     (that's a bug, but not one we can do anything about).  As of NT4.0 SP3,
-     the exception handling code will loop if a subq is used and an
-     exception occurs.
-
-     The 19980616 change to emit prologues as RTL also confused some
-     versions of GDB, which also interprets prologues.  This has been
-     fixed as of GDB 4.18, but it does not harm to unconditionally
-     use lda here.  */
-
-  int which = which_alternative;
-
-  if (operands[0] == stack_pointer_rtx
-      && GET_CODE (operands[2]) == CONST_INT
-      && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))
-    which = 2;
-
-  return pattern[which];
-}")
+  "")
+
+;; This pattern exists so that register elimination tries to canonize
+;; (plus (plus reg c1) c2).
+
+(define_insn "*lda"
+  [(set (match_operand:DI 0 "register_operand" "=r")
+        (match_operand:DI 1 "addition_operation" "p"))]
+  ""
+  "lda %0,%a1")
+
+;; We used to expend quite a lot of effort choosing addq/subq/lda.
+;; With complications like
+;;
+;;   The NT stack unwind code can't handle a subq to adjust the stack
+;;   (that's a bug, but not one we can do anything about).  As of NT4.0 SP3,
+;;   the exception handling code will loop if a subq is used and an
+;;   exception occurs.
+;;  
+;;   The 19980616 change to emit prologues as RTL also confused some
+;;   versions of GDB, which also interprets prologues.  This has been
+;;   fixed as of GDB 4.18, but it does not harm to unconditionally
+;;   use lda here.
+;;
+;; and the fact that the three insns schedule exactly the same, it's
+;; just not worth the effort.
+
+(define_insn "*adddi_2"
+  [(set (match_operand:DI 0 "register_operand" "=r,r,r")
+       (plus:DI (match_operand:DI 1 "register_operand" "%r,r,r")
+                (match_operand:DI 2 "add_operand" "r,K,L")))]
+  ""
+  "@
+   addq %1,%2,%0
+   lda %0,%2(%1)
+   ldah %0,%h2(%1)")
 
 ;; ??? Allow large constants when basing off the frame pointer or some
 ;; virtual register that may eliminate to the frame pointer.  This is
   [(set (match_operand:DI 0 "register_operand" "=r")
         (plus:DI (match_operand:DI 1 "reg_no_subreg_operand" "r")
                 (match_operand:DI 2 "const_int_operand" "n")))]
-  "REG_OK_FP_BASE_P (operands[1])"
+  "REG_OK_FP_BASE_P (operands[1])
+   && INTVAL (operands[2]) >= 0
+   /* This is the largest constant an lda+ldah pair can add, minus
+      an upper bound on the displacement between SP and AP during
+      register elimination.  See INITIAL_ELIMINATION_OFFSET.  */
+   && INTVAL (operands[2])
+       < (0x7fff8000
+          - FIRST_PSEUDO_REGISTER * UNITS_PER_WORD
+          - ALPHA_ROUND(current_function_outgoing_args_size)
+          - (ALPHA_ROUND (get_frame_size ()
+                          + max_reg_num () * UNITS_PER_WORD
+                          + current_function_pretend_args_size)
+             - current_function_pretend_args_size))"
   "#")
 
 ;; Don't do this if we are adjusting SP since we don't want to do it
   HOST_WIDE_INT low = (val & 0xffff) - 2 * (val & 0x8000);
   HOST_WIDE_INT rest = val - low;
 
-  operands[3] = GEN_INT (rest);
   operands[4] = GEN_INT (low);
+  if (CONST_OK_FOR_LETTER_P (rest, 'L'))
+    operands[3] = GEN_INT (rest);
+  else if (! no_new_pseudos)
+    {
+      operands[3] = gen_reg_rtx (DImode);
+      emit_move_insn (operands[3], operands[2]);
+      emit_insn (gen_adddi3 (operands[0], operands[1], operands[3]));
+      DONE;
+    }
+  else
+    FAIL;
 }")
 
 (define_insn ""
                   (sign_extend:DI (div:SI (reg:DI 24) (reg:DI 25))))
              (clobber (reg:DI 23))
              (clobber (reg:DI 28))])
-   (set (match_operand:SI 0 "general_operand" "")
+   (set (match_operand:SI 0 "nonimmediate_operand" "")
        (subreg:SI (reg:DI 27) 0))]
   "!TARGET_OPEN_VMS"
   "")
                   (sign_extend:DI (udiv:SI (reg:DI 24) (reg:DI 25))))
              (clobber (reg:DI 23))
              (clobber (reg:DI 28))])
-   (set (match_operand:SI 0 "general_operand" "")
+   (set (match_operand:SI 0 "nonimmediate_operand" "")
        (subreg:SI (reg:DI 27) 0))]
   "!TARGET_OPEN_VMS"
   "")
                   (sign_extend:DI (mod:SI (reg:DI 24) (reg:DI 25))))
              (clobber (reg:DI 23))
              (clobber (reg:DI 28))])
-   (set (match_operand:SI 0 "general_operand" "")
+   (set (match_operand:SI 0 "nonimmediate_operand" "")
        (subreg:SI (reg:DI 27) 0))]
   "!TARGET_OPEN_VMS"
   "")
                   (sign_extend:DI (umod:SI (reg:DI 24) (reg:DI 25))))
              (clobber (reg:DI 23))
              (clobber (reg:DI 28))])
-   (set (match_operand:SI 0 "general_operand" "")
+   (set (match_operand:SI 0 "nonimmediate_operand" "")
        (subreg:SI (reg:DI 27) 0))]
   "!TARGET_OPEN_VMS"
   "")
                           (reg:DI 25)))
              (clobber (reg:DI 23))
              (clobber (reg:DI 28))])
-   (set (match_operand:DI 0 "general_operand" "")
+   (set (match_operand:DI 0 "nonimmediate_operand" "")
        (reg:DI 27))]
   "!TARGET_OPEN_VMS"
   "")
                            (reg:DI 25)))
              (clobber (reg:DI 23))
              (clobber (reg:DI 28))])
-   (set (match_operand:DI 0 "general_operand" "")
+   (set (match_operand:DI 0 "nonimmediate_operand" "")
        (reg:DI 27))]
   "!TARGET_OPEN_VMS"
   "")
                           (reg:DI 25)))
              (clobber (reg:DI 23))
              (clobber (reg:DI 28))])
-   (set (match_operand:DI 0 "general_operand" "")
+   (set (match_operand:DI 0 "nonimmediate_operand" "")
        (reg:DI 27))]
   "!TARGET_OPEN_VMS"
   "")
                            (reg:DI 25)))
              (clobber (reg:DI 23))
              (clobber (reg:DI 28))])
-   (set (match_operand:DI 0 "general_operand" "")
+   (set (match_operand:DI 0 "nonimmediate_operand" "")
        (reg:DI 27))]
   "!TARGET_OPEN_VMS"
   "")
 
 (define_expand "ffsdi2"
   [(set (match_dup 2)
-       (unspec [(match_operand:DI 1 "register_operand" "")] 1))
+       (unspec:DI [(match_operand:DI 1 "register_operand" "")] 1))
    (set (match_dup 3)
        (plus:DI (match_dup 2) (const_int 1)))
    (set (match_operand:DI 0 "register_operand" "")
 
 (define_insn ""
   [(set (match_operand:DI 0 "register_operand" "=r")
-       (unspec [(match_operand:DI 1 "register_operand" "r")] 1))]
+       (unspec:DI [(match_operand:DI 1 "register_operand" "r")] 1))]
   "TARGET_CIX"
   "cttz %1,%0"
   ; EV6 calls all mvi and cttz/ctlz/popc class imisc, so just 
 
 (define_insn ""
   [(set (match_operand:DI 0 "register_operand" "=r")
-       (and (lshiftrt:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
-               (ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
-                          (const_int 3)))
+       (and:DI (lshiftrt:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
+                 (ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
+                            (const_int 3)))
             (match_operand:DI 3 "mode_mask_operand" "n")))]
   ""
   "ext%U3l %1,%2,%0"
 
 (define_insn "insxh"
   [(set (match_operand:DI 0 "register_operand" "=r")
-       (unspec [(match_operand:DI 1 "register_operand" "r")
-                (match_operand:DI 2 "mode_width_operand" "n")
-                (match_operand:DI 3 "reg_or_8bit_operand" "rI")] 2))]
+       (unspec:DI [(match_operand:DI 1 "register_operand" "r")
+                   (match_operand:DI 2 "mode_width_operand" "n")
+                   (match_operand:DI 3 "reg_or_8bit_operand" "rI")] 2))]
   ""
   "ins%M2h %1,%3,%0"
   [(set_attr "type" "shift")])
 
 (define_insn "mskxh"
   [(set (match_operand:DI 0 "register_operand" "=r")
-       (unspec [(match_operand:DI 1 "register_operand" "r")
-                (match_operand:DI 2 "mode_width_operand" "n")
-                (match_operand:DI 3 "reg_or_8bit_operand" "rI")] 3))]
+       (unspec:DI [(match_operand:DI 1 "register_operand" "r")
+                   (match_operand:DI 2 "mode_width_operand" "n")
+                   (match_operand:DI 3 "reg_or_8bit_operand" "rI")] 3))]
   ""
   "msk%M2h %1,%3,%0"
   [(set_attr "type" "shift")])
   [(set_attr "type" "fadd")
    (set_attr "trap" "yes")])
 
+(define_expand "addtf3"
+  [(use (match_operand 0 "register_operand" ""))
+   (use (match_operand 1 "general_operand" ""))
+   (use (match_operand 2 "general_operand" ""))]
+  "TARGET_HAS_XFLOATING_LIBS"
+  "alpha_emit_xfloating_arith (PLUS, operands); DONE;")
+
 ;; Define conversion operators between DFmode and SImode, using the cvtql
 ;; instruction.  To allow combine et al to do useful things, we keep the
 ;; operation as a unit until after reload, at which point we split the
   [(set_attr "type" "fadd")
    (set_attr "trap" "yes")])
 
+(define_expand "fix_trunctfdi2"
+  [(use (match_operand:DI 0 "register_operand" ""))
+   (use (match_operand:TF 1 "general_operand" ""))]
+  "TARGET_HAS_XFLOATING_LIBS"
+  "alpha_emit_xfloating_cvt (FIX, operands); DONE;")
+
 (define_insn ""
   [(set (match_operand:SF 0 "register_operand" "=&f")
        (float:SF (match_operand:DI 1 "reg_no_subreg_operand" "f")))]
   [(set_attr "type" "fadd")
    (set_attr "trap" "yes")])
 
+(define_expand "floatditf2"
+  [(use (match_operand:TF 0 "register_operand" ""))
+   (use (match_operand:DI 1 "general_operand" ""))]
+  "TARGET_HAS_XFLOATING_LIBS"
+  "alpha_emit_xfloating_cvt (FLOAT, operands); DONE;")
+
+(define_expand "floatunsditf2"
+  [(use (match_operand:TF 0 "register_operand" ""))
+   (use (match_operand:DI 1 "general_operand" ""))]
+  "TARGET_HAS_XFLOATING_LIBS"
+  "alpha_emit_xfloating_cvt (UNSIGNED_FLOAT, operands); DONE;")
+
 (define_expand "extendsfdf2"
   [(use (match_operand:DF 0 "register_operand" ""))
    (use (match_operand:SF 1 "nonimmediate_operand" ""))]
   [(set_attr "type" "fcpys,fld,fst")
    (set_attr "trap" "yes")])
 
+(define_expand "extenddftf2"
+  [(use (match_operand:TF 0 "register_operand" ""))
+   (use (match_operand:DF 1 "general_operand" ""))]
+  "TARGET_HAS_XFLOATING_LIBS"
+  "alpha_emit_xfloating_cvt (FLOAT_EXTEND, operands); DONE;")
+
 (define_insn ""
   [(set (match_operand:SF 0 "register_operand" "=&f")
        (float_truncate:SF (match_operand:DF 1 "reg_or_fp0_operand" "fG")))]
   [(set_attr "type" "fadd")
    (set_attr "trap" "yes")])
 
+(define_expand "trunctfdf2"
+  [(use (match_operand:DF 0 "register_operand" ""))
+   (use (match_operand:TF 1 "general_operand" ""))]
+  "TARGET_HAS_XFLOATING_LIBS"
+  "alpha_emit_xfloating_cvt (FLOAT_TRUNCATE, operands); DONE;")
+
 (define_insn ""
   [(set (match_operand:SF 0 "register_operand" "=&f")
        (div:SF (match_operand:SF 1 "reg_or_fp0_operand" "fG")
   [(set_attr "type" "fdiv")
    (set_attr "trap" "yes")])
 
+(define_expand "divtf3"
+  [(use (match_operand 0 "register_operand" ""))
+   (use (match_operand 1 "general_operand" ""))
+   (use (match_operand 2 "general_operand" ""))]
+  "TARGET_HAS_XFLOATING_LIBS"
+  "alpha_emit_xfloating_arith (DIV, operands); DONE;")
+
 (define_insn ""
   [(set (match_operand:SF 0 "register_operand" "=&f")
        (mult:SF (match_operand:SF 1 "reg_or_fp0_operand" "%fG")
   [(set_attr "type" "fmul")
    (set_attr "trap" "yes")])
 
+(define_expand "multf3"
+  [(use (match_operand 0 "register_operand" ""))
+   (use (match_operand 1 "general_operand" ""))
+   (use (match_operand 2 "general_operand" ""))]
+  "TARGET_HAS_XFLOATING_LIBS"
+  "alpha_emit_xfloating_arith (MULT, operands); DONE;")
+
 (define_insn ""
   [(set (match_operand:SF 0 "register_operand" "=&f")
        (minus:SF (match_operand:SF 1 "reg_or_fp0_operand" "fG")
   [(set_attr "type" "fadd")
    (set_attr "trap" "yes")])
 
+(define_expand "subtf3"
+  [(use (match_operand 0 "register_operand" ""))
+   (use (match_operand 1 "general_operand" ""))
+   (use (match_operand 2 "general_operand" ""))]
+  "TARGET_HAS_XFLOATING_LIBS"
+  "alpha_emit_xfloating_arith (MINUS, operands); DONE;")
+
 (define_insn ""
   [(set (match_operand:SF 0 "register_operand" "=&f")
        (sqrt:SF (match_operand:SF 1 "reg_or_fp0_operand" "fG")))]
   DONE;
 }")
 
+(define_expand "cmptf"
+  [(set (cc0) (compare (match_operand:TF 0 "general_operand" "")
+                      (match_operand:TF 1 "general_operand" "")))]
+  "TARGET_HAS_XFLOATING_LIBS"
+  "
+{
+  alpha_compare.op0 = operands[0];
+  alpha_compare.op1 = operands[1];
+  alpha_compare.fp_p = 1;
+  DONE;
+}")
+
 (define_expand "cmpdi"
   [(set (cc0) (compare (match_operand:DI 0 "reg_or_0_operand" "")
                       (match_operand:DI 1 "reg_or_8bit_operand" "")))]
 ;; with a ZAP.
 (define_split
   [(set (match_operand:DI 0 "register_operand" "")
-       (match_operator 1 "comparison_operator"
+       (match_operator:DI 1 "comparison_operator"
                        [(match_operand:DI 2 "register_operand" "")
                         (match_operand:DI 3 "const_int_operand" "")]))
    (clobber (match_operand:DI 4 "register_operand" ""))]
 (define_insn ""
   [(call (mem:DI (match_operand:DI 0 "call_operand" "r,i"))
         (match_operand 1 "" ""))
-   (use (match_operand:DI 2 "general_operand" "r,m"))
+   (use (match_operand:DI 2 "nonimmediate_operand" "r,m"))
    (use (reg:DI 25))
    (use (reg:DI 26))
    (clobber (reg:DI 27))]
   [(set_attr "type" "jsr")
    (set_attr "length" "12,16")])
 
-(define_insn ""
-  [(set (match_operand 0 "" "")
-       (call (mem:DI (match_operand:DI 1 "call_operand" "r,R,i"))
-             (match_operand 2 "" "")))
-   (clobber (reg:DI 27))
-   (clobber (reg:DI 26))]
-  "! TARGET_WINDOWS_NT && ! TARGET_OPEN_VMS"
-  "@
-   jsr $26,($27),0\;ldgp $29,0($26)
-   bsr $26,$%1..ng
-   jsr $26,%1\;ldgp $29,0($26)"
-  [(set_attr "type" "jsr")
-   (set_attr "length" "12,*,16")])
-
-(define_insn ""
-  [(set (match_operand 0 "" "")
-       (call (mem:DI (match_operand:DI 1 "call_operand" "r,R,i"))
-             (match_operand 2 "" "")))
-   (clobber (reg:DI 26))]
-  "TARGET_WINDOWS_NT"
-  "@
-   jsr $26,(%1)
-   bsr $26,%1
-   jsr $26,%1"
-  [(set_attr "type" "jsr")
-   (set_attr "length" "*,*,12")])
-
-(define_insn ""
-  [(set (match_operand 0 "" "")
-       (call (mem:DI (match_operand:DI 1 "call_operand" "r,i"))
-             (match_operand 2 "" "")))
-   (use (match_operand:DI 3 "general_operand" "r,m"))
-   (use (reg:DI 25))
-   (use (reg:DI 26))
-   (clobber (reg:DI 27))]
-  "TARGET_OPEN_VMS"
-  "@
-   mov %3,$27\;jsr $26,0\;ldq $27,0($29)
-   ldq $27,%3\;jsr $26,%1\;ldq $27,0($29)"
-  [(set_attr "type" "jsr")
-   (set_attr "length" "12,16")])
-
 ;; Call subroutine returning any type.
 
 (define_expand "untyped_call"
        (sign_extend:DI (match_operand:SI 0 "register_operand" "")))
    (parallel [(set (pc)
                   (plus:DI (match_dup 3)
-                           (label_ref:DI (match_operand 1 "" ""))))
+                           (label_ref (match_operand 1 "" ""))))
              (clobber (match_scratch:DI 2 "=r"))])]
   ""
   "
       (match_operand:DI 0 "register_operand" ""))
         (set (pc)
        (plus:DI (match_dup 2)
-               (label_ref:DI (match_operand 1 "" ""))))]
+               (label_ref (match_operand 1 "" ""))))]
   ""
   "
 { operands[2] = gen_reg_rtx (DImode); }")
 
 (define_insn ""
   [(set (pc)
-       (plus:DI (match_operand:DI 0 "register_operand" "r")
-                (label_ref:DI (match_operand 1 "" ""))))
+       (plus (match_operand:DI 0 "register_operand" "r")
+             (label_ref (match_operand 1 "" ""))))
    (clobber (match_scratch:DI 2 "=r"))]
   "! TARGET_WINDOWS_NT && ! TARGET_OPEN_VMS && next_active_insn (insn) != 0
    && GET_CODE (PATTERN (next_active_insn (insn))) == ADDR_DIFF_VEC
 
 (define_insn ""
   [(set (pc)
-       (plus:DI (match_operand 0 "register_operand" "r")
-               (label_ref (match_operand 1 "" ""))))]
+       (plus (match_operand:DI 0 "register_operand" "r")
+             (label_ref (match_operand 1 "" ""))))]
   "TARGET_OPEN_VMS"
   "jmp $31,(%0),0"
   [(set_attr "type" "ibr")])
 ;; they are simpler.
 
 (define_insn ""
-  [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,r,r,m,m")
-       (match_operand:SF 1 "input_operand" "fG,m,rG,m,fG,r"))]
+  [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,*r,*r,m,m")
+       (match_operand:SF 1 "input_operand" "fG,m,*rG,m,fG,*r"))]
   "! TARGET_FIX
    && (register_operand (operands[0], SFmode)
        || reg_or_fp0_operand (operands[1], SFmode))"
   [(set_attr "type" "fcpys,fld,ilog,ild,fst,ist")])
 
 (define_insn ""
-  [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,r,r,m,m,f,*r")
-       (match_operand:SF 1 "input_operand" "fG,m,rG,m,fG,r,r,*f"))]
+  [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,*r,*r,m,m,f,*r")
+       (match_operand:SF 1 "input_operand" "fG,m,*rG,m,fG,*r,*r,f"))]
   "TARGET_FIX
    && (register_operand (operands[0], SFmode)
        || reg_or_fp0_operand (operands[1], SFmode))"
   [(set_attr "type" "fcpys,fld,ilog,ild,fst,ist,itof,ftoi")])
 
 (define_insn ""
-  [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,r,r,m,m")
-       (match_operand:DF 1 "input_operand" "fG,m,rG,m,fG,r"))]
+  [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,*r,*r,m,m")
+       (match_operand:DF 1 "input_operand" "fG,m,*rG,m,fG,*r"))]
   "! TARGET_FIX
    && (register_operand (operands[0], DFmode)
        || reg_or_fp0_operand (operands[1], DFmode))"
   [(set_attr "type" "fcpys,fld,ilog,ild,fst,ist")])
 
 (define_insn ""
-  [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,r,r,m,m,f,*r")
-       (match_operand:DF 1 "input_operand" "fG,m,rG,m,fG,r,r,*f"))]
+  [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,*r,*r,m,m,f,*r")
+       (match_operand:DF 1 "input_operand" "fG,m,*rG,m,fG,*r,*r,f"))]
   "TARGET_FIX
    && (register_operand (operands[0], DFmode)
        || reg_or_fp0_operand (operands[1], DFmode))"
 }")
 
 (define_insn ""
-  [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,m,f,f,m")
-       (match_operand:SI 1 "input_operand" "rJ,K,L,m,rJ,fJ,m,f"))]
+  [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,m,*f,*f,m")
+       (match_operand:SI 1 "input_operand" "rJ,K,L,m,rJ,*fJ,m,*f"))]
   "! TARGET_WINDOWS_NT && ! TARGET_OPEN_VMS && ! TARGET_FIX
    && (register_operand (operands[0], SImode)
        || reg_or_0_operand (operands[1], SImode))"
   [(set_attr "type" "ilog,iadd,iadd,ild,ist,fcpys,fld,fst")])
 
 (define_insn ""
-  [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,m,f,f,m,r,*f")
-       (match_operand:SI 1 "input_operand" "rJ,K,L,m,rJ,fJ,m,f,f,*r"))]
+  [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,m,*f,*f,m,r,*f")
+       (match_operand:SI 1 "input_operand" "rJ,K,L,m,rJ,*fJ,m,*f,*f,r"))]
   "! TARGET_WINDOWS_NT && ! TARGET_OPEN_VMS && TARGET_FIX
    && (register_operand (operands[0], SImode)
        || reg_or_0_operand (operands[1], SImode))"
   [(set_attr "type" "ilog,iadd,iadd,ild,ist,fcpys,fld,fst,ftoi,itof")])
 
 (define_insn ""
-  [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,r,m,f,f,m")
-       (match_operand:SI 1 "input_operand" "rJ,K,L,s,m,rJ,fJ,m,f"))]
+  [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,r,m,*f,*f,m")
+       (match_operand:SI 1 "input_operand" "rJ,K,L,s,m,rJ,*fJ,m,*f"))]
   "(TARGET_WINDOWS_NT || TARGET_OPEN_VMS)
     && (register_operand (operands[0], SImode)
         || reg_or_0_operand (operands[1], SImode))"
 ;; constants.
 
 (define_expand "movsi"
-  [(set (match_operand:SI 0 "general_operand" "")
+  [(set (match_operand:SI 0 "nonimmediate_operand" "")
        (match_operand:SI 1 "general_operand" ""))]
   ""
   "
 }")
 
 (define_insn ""
-  [(set (match_operand:DI 0 "general_operand" "=r,r,r,r,r,m,f,f,Q")
-       (match_operand:DI 1 "input_operand" "rJ,K,L,s,m,rJ,fJ,Q,f"))]
+  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,r,m,*f,*f,Q")
+       (match_operand:DI 1 "input_operand" "rJ,K,L,s,m,rJ,*fJ,Q,*f"))]
   "! TARGET_FIX
    && (register_operand (operands[0], DImode)
        || reg_or_0_operand (operands[1], DImode))"
   [(set_attr "type" "ilog,iadd,iadd,ldsym,ild,ist,fcpys,fld,fst")])
 
 (define_insn ""
-  [(set (match_operand:DI 0 "general_operand" "=r,r,r,r,r,m,f,f,Q,r,*f")
-       (match_operand:DI 1 "input_operand" "rJ,K,L,s,m,rJ,fJ,Q,f,f,*r"))]
+  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,r,m,*f,*f,Q,r,*f")
+       (match_operand:DI 1 "input_operand" "rJ,K,L,s,m,rJ,*fJ,Q,*f,*f,r"))]
   "TARGET_FIX
    && (register_operand (operands[0], DImode)
        || reg_or_0_operand (operands[1], DImode))"
 ;; memory, and construct long 32-bit constants.
 
 (define_expand "movdi"
-  [(set (match_operand:DI 0 "general_operand" "")
+  [(set (match_operand:DI 0 "nonimmediate_operand" "")
        (match_operand:DI 1 "general_operand" ""))]
   ""
   "
 ;; registers for reload.
 
 (define_expand "movqi"
-  [(set (match_operand:QI 0 "general_operand" "")
+  [(set (match_operand:QI 0 "nonimmediate_operand" "")
        (match_operand:QI 1 "general_operand" ""))]
   ""
   "
 }")
 
 (define_expand "movhi"
-  [(set (match_operand:HI 0 "general_operand" "")
+  [(set (match_operand:HI 0 "nonimmediate_operand" "")
        (match_operand:HI 1 "general_operand" ""))]
   ""
   "
 ;; expansion, so we must delay our address manipulations until after.
 
 (define_insn "reload_inqi_help"
-  [(set (match_operand:QI 0 "register_operand" "r")
+  [(set (match_operand:QI 0 "register_operand" "=r")
         (match_operand:QI 1 "memory_operand" "m"))
-   (clobber (match_operand:SI 2 "register_operand" "r"))]
+   (clobber (match_operand:SI 2 "register_operand" "=r"))]
   "! TARGET_BWX && (reload_in_progress || reload_completed)"
   "#")
 
 (define_insn "reload_inhi_help"
-  [(set (match_operand:HI 0 "register_operand" "r")
+  [(set (match_operand:HI 0 "register_operand" "=r")
         (match_operand:HI 1 "memory_operand" "m"))
-   (clobber (match_operand:SI 2 "register_operand" "r"))]
+   (clobber (match_operand:SI 2 "register_operand" "=r"))]
   "! TARGET_BWX && (reload_in_progress || reload_completed)"
   "#")
 
 (define_insn "reload_outqi_help"
-  [(set (match_operand:QI 0 "memory_operand" "m")
+  [(set (match_operand:QI 0 "memory_operand" "=m")
         (match_operand:QI 1 "register_operand" "r"))
-   (clobber (match_operand:SI 2 "register_operand" "r"))
-   (clobber (match_operand:SI 3 "register_operand" "r"))]
+   (clobber (match_operand:SI 2 "register_operand" "=r"))
+   (clobber (match_operand:SI 3 "register_operand" "=r"))]
   "! TARGET_BWX && (reload_in_progress || reload_completed)"
   "#")
 
 (define_insn "reload_outhi_help"
-  [(set (match_operand:HI 0 "memory_operand" "m")
+  [(set (match_operand:HI 0 "memory_operand" "=m")
         (match_operand:HI 1 "register_operand" "r"))
-   (clobber (match_operand:SI 2 "register_operand" "r"))
-   (clobber (match_operand:SI 3 "register_operand" "r"))]
+   (clobber (match_operand:SI 2 "register_operand" "=r"))
+   (clobber (match_operand:SI 3 "register_operand" "=r"))]
   "! TARGET_BWX && (reload_in_progress || reload_completed)"
   "#")
 
 (define_split
-  [(set (match_operand:QI 0 "register_operand" "r")
-        (match_operand:QI 1 "memory_operand" "m"))
-   (clobber (match_operand:SI 2 "register_operand" "r"))]
+  [(set (match_operand:QI 0 "register_operand" "")
+        (match_operand:QI 1 "memory_operand" ""))
+   (clobber (match_operand:SI 2 "register_operand" ""))]
   "! TARGET_BWX && reload_completed"
   [(const_int 0)]
   "
 }")
   
 (define_split
-  [(set (match_operand:HI 0 "register_operand" "r")
-        (match_operand:HI 1 "memory_operand" "m"))
-   (clobber (match_operand:SI 2 "register_operand" "r"))]
+  [(set (match_operand:HI 0 "register_operand" "")
+        (match_operand:HI 1 "memory_operand" ""))
+   (clobber (match_operand:SI 2 "register_operand" ""))]
   "! TARGET_BWX && reload_completed"
   [(const_int 0)]
   "
 }")
   
 (define_split
-  [(set (match_operand:QI 0 "memory_operand" "m")
-        (match_operand:QI 1 "register_operand" "r"))
-   (clobber (match_operand:SI 2 "register_operand" "r"))
-   (clobber (match_operand:SI 3 "register_operand" "r"))]
+  [(set (match_operand:QI 0 "memory_operand" "")
+        (match_operand:QI 1 "register_operand" ""))
+   (clobber (match_operand:SI 2 "register_operand" ""))
+   (clobber (match_operand:SI 3 "register_operand" ""))]
   "! TARGET_BWX && reload_completed"
   [(const_int 0)]
   "
 }")
 
 (define_split
-  [(set (match_operand:HI 0 "memory_operand" "m")
-        (match_operand:HI 1 "register_operand" "r"))
-   (clobber (match_operand:SI 2 "register_operand" "r"))
-   (clobber (match_operand:SI 3 "register_operand" "r"))]
+  [(set (match_operand:HI 0 "memory_operand" "")
+        (match_operand:HI 1 "register_operand" ""))
+   (clobber (match_operand:SI 2 "register_operand" ""))
+   (clobber (match_operand:SI 3 "register_operand" ""))]
   "! TARGET_BWX && reload_completed"
   [(const_int 0)]
   "
 
 (define_expand "extzv"
   [(set (match_operand:DI 0 "register_operand" "")
-       (zero_extract:DI (match_operand:DI 1 "general_operand" "")
+       (zero_extract:DI (match_operand:DI 1 "nonimmediate_operand" "")
                         (match_operand:DI 2 "immediate_operand" "")
                         (match_operand:DI 3 "immediate_operand" "")))]
   ""
 ;; Argument 3 is the alignment
 
 (define_expand "movstrqi"
-  [(parallel [(set (match_operand:BLK 0 "general_operand" "")
-                  (match_operand:BLK 1 "general_operand" ""))
+  [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
+                  (match_operand:BLK 1 "memory_operand" ""))
              (use (match_operand:DI 2 "immediate_operand" ""))
              (use (match_operand:DI 3 "immediate_operand" ""))])]
   ""
 }")
 
 (define_expand "clrstrqi"
-  [(parallel [(set (match_operand:BLK 0 "general_operand" "")
+  [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
                   (const_int 0))
              (use (match_operand:DI 1 "immediate_operand" ""))
              (use (match_operand:DI 2 "immediate_operand" ""))])]
       emit_insn (gen_adddi3 (tmp, tmp, GEN_INT(-8192)));
       emit_insn (gen_cmpdi (tmp, want));
       emit_jump_insn (gen_bgtu (loop_label));
-      if (obey_regdecls)
-       gen_rtx_USE (VOIDmode, tmp);
 
       memref = gen_rtx_MEM (DImode, want);
       MEM_VOLATILE_P (memref) = 1;
 ;; the loop in this one insn.
 
 (define_insn "prologue_stack_probe_loop"
-  [(unspec_volatile [(match_operand 0 "register_operand" "r")
-                    (match_operand 1 "register_operand" "r")] 5)]
+  [(unspec_volatile [(match_operand:DI 0 "register_operand" "r")
+                    (match_operand:DI 1 "register_operand" "r")] 5)]
   ""
   "*
 {
   "alpha_expand_prologue (); DONE;")
 
 (define_insn "init_fp"
-  [(set (match_operand:DI 0 "register_operand" "r")
+  [(set (match_operand:DI 0 "register_operand" "=r")
         (match_operand:DI 1 "register_operand" "r"))
-   (clobber (mem:BLK (match_operand:DI 2 "register_operand" "r")))]
+   (clobber (mem:BLK (match_operand:DI 2 "register_operand" "=r")))]
   ""
   "mov %1,%0")
 
   "! TARGET_OPEN_VMS"
   "
 {
-  current_function->machine->eh_epilogue_sp_ofs = operands[1];
+  cfun->machine->eh_epilogue_sp_ofs = operands[1];
   if (GET_CODE (operands[2]) != REG || REGNO (operands[2]) != 26)
     {
       rtx ra = gen_rtx_REG (Pmode, 26);
 ;; 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")
+  [(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)]
+  [(unspec_volatile [(match_operand:DI 0 "register_operand" "r")] 3)]
   "! TARGET_OPEN_VMS && ! TARGET_WINDOWS_NT"
   "
 {
   [(unspec_volatile [(match_operand 0 "immediate_operand" "i")] 6)]
   ""
   ".align %0 #realign")
+
+;; The call patterns are at the end of the file because their
+;; wildcard operand0 interferes with nice recognition.
+
+(define_insn ""
+  [(set (match_operand 0 "" "")
+       (call (mem:DI (match_operand:DI 1 "call_operand" "r,R,i"))
+             (match_operand 2 "" "")))
+   (clobber (reg:DI 27))
+   (clobber (reg:DI 26))]
+  "! TARGET_WINDOWS_NT && ! TARGET_OPEN_VMS"
+  "@
+   jsr $26,($27),0\;ldgp $29,0($26)
+   bsr $26,$%1..ng
+   jsr $26,%1\;ldgp $29,0($26)"
+  [(set_attr "type" "jsr")
+   (set_attr "length" "12,*,16")])
+
+(define_insn ""
+  [(set (match_operand 0 "" "")
+       (call (mem:DI (match_operand:DI 1 "call_operand" "r,R,i"))
+             (match_operand 2 "" "")))
+   (clobber (reg:DI 26))]
+  "TARGET_WINDOWS_NT"
+  "@
+   jsr $26,(%1)
+   bsr $26,%1
+   jsr $26,%1"
+  [(set_attr "type" "jsr")
+   (set_attr "length" "*,*,12")])
+
+(define_insn ""
+  [(set (match_operand 0 "" "")
+       (call (mem:DI (match_operand:DI 1 "call_operand" "r,i"))
+             (match_operand 2 "" "")))
+   (use (match_operand:DI 3 "nonimmediate_operand" "r,m"))
+   (use (reg:DI 25))
+   (use (reg:DI 26))
+   (clobber (reg:DI 27))]
+  "TARGET_OPEN_VMS"
+  "@
+   mov %3,$27\;jsr $26,0\;ldq $27,0($29)
+   ldq $27,%3\;jsr $26,%1\;ldq $27,0($29)"
+  [(set_attr "type" "jsr")
+   (set_attr "length" "12,16")])
+
 \f
 ;; Peepholes go at the end.
 
 ;; Optimize sign-extension of SImode loads.  This shows up in the wake of
 ;; reload when converting fp->int.
-;;
-;; ??? What to do now that we actually care about the packing and
-;; alignment of instructions?  Perhaps reload can be enlightened, or
-;; the peephole pass moved up after reload but before sched2?
-;
-;(define_peephole
-;  [(set (match_operand:SI 0 "register_operand" "=r")
-;        (match_operand:SI 1 "memory_operand" "m"))
-;   (set (match_operand:DI 2 "register_operand" "=r")
-;        (sign_extend:DI (match_dup 0)))]
-;  "dead_or_set_p (insn, operands[0])"
-;  "ldl %2,%1")
-;
-;(define_peephole
-;  [(set (match_operand:SI 0 "register_operand" "=r")
-;        (match_operand:SI 1 "hard_fp_register_operand" "f"))
-;   (set (match_operand:DI 2 "register_operand" "=r")
-;        (sign_extend:DI (match_dup 0)))]
-;  "TARGET_FIX && dead_or_set_p (insn, operands[0])"
-;  "ftois %1,%2")
+
+(define_peephole2
+  [(set (match_operand:SI 0 "register_operand" "=r")
+        (match_operand:SI 1 "memory_operand" "m"))
+   (set (match_operand:DI 2 "register_operand" "=r")
+        (sign_extend:DI (match_dup 0)))]
+  "dead_or_set_p (next_nonnote_insn (insn), operands[0])"
+  [(set (match_dup 2)
+       (sign_extend:DI (match_dup 1)))]
+  "")
+
+(define_peephole2
+  [(set (match_operand:SI 0 "register_operand" "=r")
+        (match_operand:SI 1 "hard_fp_register_operand" "f"))
+   (set (match_operand:DI 2 "register_operand" "=r")
+        (sign_extend:DI (match_dup 0)))]
+  "TARGET_FIX && dead_or_set_p (next_nonnote_insn (insn), operands[0])"
+  [(set (match_dup 2)
+       (sign_extend:DI (match_dup 1)))]
+  "")