OSDN Git Service

PR target/42113
[pf3gnuchains/gcc-fork.git] / gcc / config / alpha / alpha.md
index 48ac0f7..e5f8c12 100644 (file)
@@ -1,24 +1,24 @@
 ;; Machine description for DEC Alpha for GNU C compiler
 ;; Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-;; 2000, 2001 Free Software Foundation, Inc.
+;; 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009
+;; Free Software Foundation, Inc.
 ;; Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
 ;;
-;; This file is part of GNU CC.
+;; This file is part of GCC.
 ;;
-;; GNU CC is free software; you can redistribute it and/or modify
+;; GCC is free software; you can redistribute it and/or modify
 ;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation; either version 2, or (at your option)
+;; the Free Software Foundation; either version 3, or (at your option)
 ;; any later version.
 ;;
-;; GNU CC is distributed in the hope that it will be useful,
+;; GCC is distributed in the hope that it will be useful,
 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 ;; GNU General Public License for more details.
 ;;
 ;; You should have received a copy of the GNU General Public License
-;; along with GNU CC; see the file COPYING.  If not, write to
-;; the Free Software Foundation, 59 Temple Place - Suite 330,
-;; Boston, MA 02111-1307, USA.
+;; along with GCC; see the file COPYING3.  If not see
+;; <http://www.gnu.org/licenses/>.
 
 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
 
 
 (define_constants
   [(UNSPEC_ARG_HOME    0)
-   (UNSPEC_CTTZ                1)
+   (UNSPEC_LDGP1       1)
    (UNSPEC_INSXH       2)
    (UNSPEC_MSKXH       3)
    (UNSPEC_CVTQL       4)
-   (UNSPEC_NT_LDA      5)
+   (UNSPEC_CVTLQ       5)
    (UNSPEC_UMK_LAUM    6)
    (UNSPEC_UMK_LALM    7)
    (UNSPEC_UMK_LAL     8)
    (UNSPEC_LITERAL     11)
    (UNSPEC_LITUSE      12)
    (UNSPEC_SIBCALL     13)
+   (UNSPEC_SYMBOL      14)
+
+   ;; TLS Support
+   (UNSPEC_TLSGD_CALL  15)
+   (UNSPEC_TLSLDM_CALL 16)
+   (UNSPEC_TLSGD       17)
+   (UNSPEC_TLSLDM      18)
+   (UNSPEC_DTPREL      19)
+   (UNSPEC_TPREL       20)
+   (UNSPEC_TP          21)
+
+   ;; Builtins
+   (UNSPEC_CMPBGE      22)
+   (UNSPEC_ZAP         23)
+   (UNSPEC_AMASK       24)
+   (UNSPEC_IMPLVER     25)
+   (UNSPEC_PERR                26)
+   (UNSPEC_COPYSIGN     27)
+
+   ;; Atomic operations
+   (UNSPEC_MB          28)
+   (UNSPEC_ATOMIC      31)
+   (UNSPEC_CMPXCHG     32)
+   (UNSPEC_XCHG                33)
   ])
 
 ;; UNSPEC_VOLATILE:
    (UNSPECV_FORCE_MOV  9)
    (UNSPECV_LDGP1      10)
    (UNSPECV_PLDGP2     11)     ; prologue ldgp
+   (UNSPECV_SET_TP     12)
+   (UNSPECV_RPCC       13)
+   (UNSPECV_SETJMPR_ER 14)     ; builtin_setjmp_receiver fragment
+   (UNSPECV_LL         15)     ; load-locked
+   (UNSPECV_SC         16)     ; store-conditional
   ])
 
+;; On non-BWX targets, CQImode must be handled the similarly to HImode
+;; when generating reloads.
+(define_mode_iterator RELOAD12 [QI HI CQI])
+(define_mode_attr reloadmode [(QI "qi") (HI "hi") (CQI "hi")])
+
+;; Other mode iterators
+(define_mode_iterator I12MODE [QI HI])
+(define_mode_iterator I48MODE [SI DI])
+(define_mode_attr modesuffix [(SI "l") (DI "q")])
+
 ;; Where necessary, the suffixes _le and _be are used to distinguish between
 ;; little-endian and big-endian patterns.
 ;;
 ;; Processor type -- this attribute must exactly match the processor_type
 ;; enumeration in alpha.h.
 
-(define_attr "cpu" "ev4,ev5,ev6"
-  (const (symbol_ref "alpha_cpu")))
+(define_attr "tune" "ev4,ev5,ev6"
+  (const (symbol_ref "((enum attr_tune) alpha_tune)")))
 
 ;; Define an insn type attribute.  This is used in function unit delay
 ;; computations, among other purposes.  For the most part, we use the names
 ;; separately.
 
 (define_attr "type"
-  "ild,fld,ldsym,ist,fst,ibr,fbr,jsr,iadd,ilog,shift,icmov,fcmov,icmp,imul,\
-fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
+  "ild,fld,ldsym,ist,fst,ibr,callpal,fbr,jsr,iadd,ilog,shift,icmov,fcmov,
+   icmp,imul,fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,mb,ld_l,st_c,
+   multi,none"
   (const_string "iadd"))
 
 ;; Describe a user's asm statement.
@@ -99,7 +139,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
 
 ;; The ROUND_SUFFIX attribute marks which instructions require a
 ;; rounding-mode suffix.  The value NONE indicates no suffix,
-;; the value NORMAL indicates a suffix controled by alpha_fprm.
+;; the value NORMAL indicates a suffix controlled by alpha_fprm.
 
 (define_attr "round_suffix" "none,normal,c"
   (const_string "none"))
@@ -112,7 +152,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
 ;;   V_SV_SVI  accepts /v, /sv and /svi (cvttq only)
 ;;   U_SU_SUI  accepts /u, /su and /sui (most fp instructions)
 ;;
-;; The actual suffix emitted is controled by alpha_fptm.
+;; The actual suffix emitted is controlled by alpha_fptm.
 
 (define_attr "trap_suffix" "none,su,sui,v_sv,v_sv_svi,u_su_sui"
   (const_string "none"))
@@ -121,313 +161,38 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
 
 (define_attr "length" ""
   (const_int 4))
+
+;; The USEGP attribute marks instructions that have relocations that use
+;; the GP.
+
+(define_attr "usegp" "no,yes"
+  (cond [(eq_attr "type" "ldsym,jsr")
+          (const_string "yes")
+        (eq_attr "type" "ild,fld,ist,fst")
+          (symbol_ref "((enum attr_usegp) alpha_find_lo_sum_using_gp (insn))")
+       ]
+       (const_string "no")))
+
+;; The CANNOT_COPY attribute marks instructions with relocations that
+;; cannot easily be duplicated.  This includes insns with gpdisp relocs
+;; since they have to stay in 1-1 correspondence with one another.  This
+;; also includes jsr insns, since they must stay in correspondence with
+;; the immediately following gpdisp instructions.
+
+(define_attr "cannot_copy" "false,true"
+  (const_string "false"))
 \f
-;; On EV4 there are two classes of resources to consider: resources needed
-;; to issue, and resources needed to execute.  IBUS[01] are in the first
-;; category.  ABOX, BBOX, EBOX, FBOX, IMUL & FDIV make up the second.
-;; (There are a few other register-like resources, but ...)
-
-; First, describe all of the issue constraints with single cycle delays.
-; All insns need a bus, but all except loads require one or the other.
-(define_function_unit "ev4_ibus0" 1 0
-  (and (eq_attr "cpu" "ev4")
-       (eq_attr "type" "fst,fbr,iadd,imul,ilog,shift,icmov,icmp"))
-  1 1)
-
-(define_function_unit "ev4_ibus1" 1 0
-  (and (eq_attr "cpu" "ev4")
-       (eq_attr "type" "ist,ibr,jsr,fadd,fcmov,fcpys,fmul,fdiv,misc"))
-  1 1)
-
-; Memory delivers its result in three cycles.  Actually return one and
-; take care of this in adjust_cost, since we want to handle user-defined
-; memory latencies.
-(define_function_unit "ev4_abox" 1 0
-  (and (eq_attr "cpu" "ev4")
-       (eq_attr "type" "ild,fld,ldsym,ist,fst"))
-  1 1)
-
-; Branches have no delay cost, but do tie up the unit for two cycles.
-(define_function_unit "ev4_bbox" 1 1
-  (and (eq_attr "cpu" "ev4")
-       (eq_attr "type" "ibr,fbr,jsr"))
-  2 2)
-
-; Arithmetic insns are normally have their results available after
-; two cycles.  There are a number of exceptions.  They are encoded in
-; ADJUST_COST.  Some of the other insns have similar exceptions.
-(define_function_unit "ev4_ebox" 1 0
-  (and (eq_attr "cpu" "ev4")
-       (eq_attr "type" "iadd,ilog,shift,icmov,icmp,misc"))
-  2 1)
-
-(define_function_unit "imul" 1 0
-  (and (eq_attr "cpu" "ev4")
-       (and (eq_attr "type" "imul")
-           (eq_attr "opsize" "si")))
-  21 19)
-
-(define_function_unit "imul" 1 0
-  (and (eq_attr "cpu" "ev4")
-       (and (eq_attr "type" "imul")
-           (eq_attr "opsize" "!si")))
-  23 21)
-
-(define_function_unit "ev4_fbox" 1 0
-  (and (eq_attr "cpu" "ev4")
-       (eq_attr "type" "fadd,fmul,fcpys,fcmov"))
-  6 1)
-
-(define_function_unit "fdiv" 1 0
-  (and (eq_attr "cpu" "ev4")
-       (and (eq_attr "type" "fdiv")
-           (eq_attr "opsize" "si")))
-  34 30)
-
-(define_function_unit "fdiv" 1 0
-  (and (eq_attr "cpu" "ev4")
-       (and (eq_attr "type" "fdiv")
-           (eq_attr "opsize" "di")))
-  63 59)
-\f
-;; EV5 scheduling.  EV5 can issue 4 insns per clock.
-;;
-;; EV5 has two asymetric integer units.  Model this with E0 & E1 along
-;; with the combined resource EBOX.
-
-(define_function_unit "ev5_ebox" 2 0
-  (and (eq_attr "cpu" "ev5")
-       (eq_attr "type" "!fbr,fcmov,fadd,fmul,fcpys,fdiv"))
-  1 1)
-
-; Memory takes at least 2 clocks.  Return one from here and fix up with
-; user-defined latencies in adjust_cost.
-(define_function_unit "ev5_ebox" 2 0
-  (and (eq_attr "cpu" "ev5")
-       (eq_attr "type" "ild,fld,ldsym"))
-  1 1)
-
-; Loads can dual issue with one another, but loads and stores do not mix.
-(define_function_unit "ev5_e0" 1 0
-  (and (eq_attr "cpu" "ev5")
-       (eq_attr "type" "ild,fld,ldsym"))
-  1 1
-  [(eq_attr "type" "ist,fst")])
-
-; Stores, shifts, multiplies can only issue to E0
-(define_function_unit "ev5_e0" 1 0
-  (and (eq_attr "cpu" "ev5")
-       (eq_attr "type" "ist,fst,shift,imul"))
-  1 1)
-
-; Motion video insns also issue only to E0, and take two ticks.
-(define_function_unit "ev5_e0" 1 0
-  (and (eq_attr "cpu" "ev5")
-       (eq_attr "type" "mvi"))
-  2 1)
-
-; Conditional moves always take 2 ticks.
-(define_function_unit "ev5_ebox" 2 0
-  (and (eq_attr "cpu" "ev5")
-       (eq_attr "type" "icmov"))
-  2 1)
-
-; Branches can only issue to E1
-(define_function_unit "ev5_e1" 1 0
-  (and (eq_attr "cpu" "ev5")
-       (eq_attr "type" "ibr,jsr"))
-  1 1)
-
-; Multiplies also use the integer multiplier.
-; ??? How to: "No instruction can be issued to pipe E0 exactly two
-; cycles before an integer multiplication completes."
-(define_function_unit "imul" 1 0
-  (and (eq_attr "cpu" "ev5")
-       (and (eq_attr "type" "imul")
-           (eq_attr "opsize" "si")))
-  8 4)
-
-(define_function_unit "imul" 1 0
-  (and (eq_attr "cpu" "ev5")
-       (and (eq_attr "type" "imul")
-           (eq_attr "opsize" "di")))
-  12 8)
-
-(define_function_unit "imul" 1 0
-  (and (eq_attr "cpu" "ev5")
-       (and (eq_attr "type" "imul")
-           (eq_attr "opsize" "udi")))
-  14 8)
-
-;; Similarly for the FPU we have two asymetric units.  But fcpys can issue
-;; on either so we have to play the game again.
-
-(define_function_unit "ev5_fbox" 2 0
-  (and (eq_attr "cpu" "ev5")
-       (eq_attr "type" "fadd,fcmov,fmul,fcpys,fbr,fdiv"))
-  4 1)
-
-(define_function_unit "ev5_fm" 1 0
-  (and (eq_attr "cpu" "ev5")
-       (eq_attr "type" "fmul"))
-  4 1)
-
-; Add and cmov as you would expect; fbr never produces a result;
-; fdiv issues through fa to the divider,
-(define_function_unit "ev5_fa" 1 0
-  (and (eq_attr "cpu" "ev5")
-       (eq_attr "type" "fadd,fcmov,fbr,fdiv"))
-  4 1)
-
-; ??? How to: "No instruction can be issued to pipe FA exactly five
-; cycles before a floating point divide completes."
-(define_function_unit "fdiv" 1 0
-  (and (eq_attr "cpu" "ev5")
-       (and (eq_attr "type" "fdiv")
-           (eq_attr "opsize" "si")))
-  15 15)                               ; 15 to 31 data dependent
-
-(define_function_unit "fdiv" 1 0
-  (and (eq_attr "cpu" "ev5")
-       (and (eq_attr "type" "fdiv")
-           (eq_attr "opsize" "di")))
-  22 22)                               ; 22 to 60 data dependent
+;; Include scheduling descriptions.
+  
+(include "ev4.md")
+(include "ev5.md")
+(include "ev6.md")
+
 \f
-;; EV6 scheduling.  EV6 can issue 4 insns per clock.
-;;
-;; EV6 has two symmetric pairs ("clusters") of two asymetric integer units
-;; ("upper" and "lower"), yielding pipe names U0, U1, L0, L1.
-
-;; Conditional moves decompose into two independent primitives, each
-;; taking one cycle.  Since ev6 is out-of-order, we can't see anything
-;; but two cycles.
-(define_function_unit "ev6_ebox" 4 0
-  (and (eq_attr "cpu" "ev6")
-       (eq_attr "type" "icmov"))
-  2 1)
-
-(define_function_unit "ev6_ebox" 4 0
-  (and (eq_attr "cpu" "ev6")
-       (eq_attr "type" "!fbr,fcmov,fadd,fmul,fcpys,fdiv,fsqrt"))
-  1 1)
-
-;; Integer loads take at least 3 clocks, and only issue to lower units.
-;; Return one from here and fix up with user-defined latencies in adjust_cost.
-(define_function_unit "ev6_l" 2 0
-  (and (eq_attr "cpu" "ev6")
-       (eq_attr "type" "ild,ldsym,ist,fst"))
-  1 1)
-
-;; FP loads take at least 4 clocks.  Return two from here...
-(define_function_unit "ev6_l" 2 0
-  (and (eq_attr "cpu" "ev6")
-       (eq_attr "type" "fld"))
-  2 1)
-
-;; Motion video insns also issue only to U0, and take three ticks.
-(define_function_unit "ev6_u0" 1 0
-  (and (eq_attr "cpu" "ev6")
-       (eq_attr "type" "mvi"))
-  3 1)
-
-(define_function_unit "ev6_u" 2 0
-  (and (eq_attr "cpu" "ev6")
-       (eq_attr "type" "mvi"))
-  3 1)
-
-;; Shifts issue to either upper pipe.
-(define_function_unit "ev6_u" 2 0
-  (and (eq_attr "cpu" "ev6")
-       (eq_attr "type" "shift"))
-  1 1)
-
-;; Multiplies issue only to U1, and all take 7 ticks.
-;; Rather than create a new function unit just for U1, reuse IMUL
-(define_function_unit "imul" 1 0
-  (and (eq_attr "cpu" "ev6")
-       (eq_attr "type" "imul"))
-  7 1)
-
-(define_function_unit "ev6_u" 2 0
-  (and (eq_attr "cpu" "ev6")
-       (eq_attr "type" "imul"))
-  7 1)
-
-;; Branches issue to either upper pipe
-(define_function_unit "ev6_u" 2 0
-  (and (eq_attr "cpu" "ev6")
-       (eq_attr "type" "ibr"))
-  3 1)
-
-;; Calls only issue to L0.
-(define_function_unit "ev6_l0" 1 0
-  (and (eq_attr "cpu" "ev6")
-       (eq_attr "type" "jsr"))
-  1 1)
-
-(define_function_unit "ev6_l" 2 0
-  (and (eq_attr "cpu" "ev6")
-       (eq_attr "type" "jsr"))
-  1 1)
-
-;; Ftoi/itof only issue to lower pipes
-(define_function_unit "ev6_l" 2 0
-  (and (eq_attr "cpu" "ev6")
-       (eq_attr "type" "ftoi"))
-  3 1)
-
-(define_function_unit "ev6_l" 2 0
-  (and (eq_attr "cpu" "ev6")
-       (eq_attr "type" "itof"))
-  4 1)
-
-;; For the FPU we are very similar to EV5, except there's no insn that
-;; can issue to fm & fa, so we get to leave that out.
-
-(define_function_unit "ev6_fm" 1 0
-  (and (eq_attr "cpu" "ev6")
-       (eq_attr "type" "fmul"))
-  4 1)
-
-(define_function_unit "ev6_fa" 1 0
-  (and (eq_attr "cpu" "ev6")
-       (eq_attr "type" "fadd,fcpys,fbr,fdiv,fsqrt"))
-  4 1)
-
-(define_function_unit "ev6_fa" 1 0
-  (and (eq_attr "cpu" "ev6")
-       (eq_attr "type" "fcmov"))
-  8 1)
-
-(define_function_unit "fdiv" 1 0
-  (and (eq_attr "cpu" "ev6")
-       (and (eq_attr "type" "fdiv")
-           (eq_attr "opsize" "si")))
-  12 10)
-
-(define_function_unit "fdiv" 1 0
-  (and (eq_attr "cpu" "ev6")
-       (and (eq_attr "type" "fdiv")
-           (eq_attr "opsize" "di")))
-  15 13)
-
-(define_function_unit "fsqrt" 1 0
-  (and (eq_attr "cpu" "ev6")
-       (and (eq_attr "type" "fsqrt")
-           (eq_attr "opsize" "si")))
-  16 14)
-
-(define_function_unit "fsqrt" 1 0
-  (and (eq_attr "cpu" "ev6")
-       (and (eq_attr "type" "fsqrt")
-           (eq_attr "opsize" "di")))
-  32 30)
-
-; ??? The FPU communicates with memory and the integer register file
-; via two fp store units.  We need a slot in the fst immediately, and
-; a slot in LOW after the operand data is ready.  At which point the
-; data may be moved either to the store queue or the integer register
-; file and the insn retired.
+;; Operand and operator predicates and constraints
+
+(include "predicates.md")
+(include "constraints.md")
 
 \f
 ;; First define the arithmetic insns.  Note that the 32-bit forms also
@@ -446,41 +211,36 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
   ""
   "")
 
-(define_insn "*extendsidi2_nofix"
-  [(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,fadd,fld")
-   (set_attr "length" "*,*,*,8")])
+(define_insn "*cvtlq"
+  [(set (match_operand:DI 0 "register_operand" "=f")
+       (unspec:DI [(match_operand:SF 1 "reg_or_0_operand" "fG")]
+                  UNSPEC_CVTLQ))]
+  ""
+  "cvtlq %1,%0"
+  [(set_attr "type" "fadd")])
 
-(define_insn "*extendsidi2_fix"
-  [(set (match_operand:DI 0 "register_operand" "=r,r,r,?*f,?*f")
+(define_insn "*extendsidi2_1"
+  [(set (match_operand:DI 0 "register_operand" "=r,r,!*f")
        (sign_extend:DI
-         (match_operand:SI 1 "nonimmediate_operand" "r,m,*f,*f,m")))]
-  "TARGET_FIX"
+         (match_operand:SI 1 "nonimmediate_operand" "r,m,m")))]
+  ""
   "@
-   addl %1,$31,%0
+   addl $31,%1,%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")])
+  [(set_attr "type" "iadd,ild,fld")
+   (set_attr "length" "*,*,8")])
 
-;; Due to issues with CLASS_CANNOT_CHANGE_SIZE, we cannot use a subreg here.
 (define_split
   [(set (match_operand:DI 0 "hard_fp_register_operand" "")
        (sign_extend:DI (match_operand:SI 1 "memory_operand" "")))]
   "reload_completed"
   [(set (match_dup 2) (match_dup 1))
-   (set (match_dup 0) (sign_extend:DI (match_dup 2)))]
-  "operands[2] = gen_rtx_REG (SImode, REGNO (operands[0]));")
+   (set (match_dup 0) (unspec:DI [(match_dup 2)] UNSPEC_CVTLQ))]
+{
+  operands[1] = adjust_address (operands[1], SFmode, 0);
+  operands[2] = gen_rtx_REG (SFmode, REGNO (operands[0]));
+})
 
 ;; Optimize sign-extension of SImode loads.  This shows up in the wake of
 ;; reload when converting fp->int.
@@ -496,55 +256,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
        (sign_extend:DI (match_dup 1)))]
   "")
 
-(define_peephole2
-  [(set (match_operand:SI 0 "hard_int_register_operand" "")
-        (match_operand:SI 1 "hard_fp_register_operand" ""))
-   (set (match_operand:DI 2 "hard_int_register_operand" "")
-        (sign_extend:DI (match_dup 0)))]
-  "TARGET_FIX
-   && (true_regnum (operands[0]) == true_regnum (operands[2])
-       || peep2_reg_dead_p (2, operands[0]))"
-  [(set (match_dup 2)
-       (sign_extend:DI (match_dup 1)))]
-  "")
-
-(define_peephole2
-  [(set (match_operand:DI 0 "hard_fp_register_operand" "")
-        (sign_extend:DI (match_operand:SI 1 "hard_fp_register_operand" "")))
-   (set (match_operand:DI 2 "hard_int_register_operand" "")
-        (match_dup 0))]
-  "TARGET_FIX && peep2_reg_dead_p (2, operands[0])"
-  [(set (match_dup 2)
-       (sign_extend:DI (match_dup 1)))]
-  "")
-
-;; 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.
-(define_expand "addsi3"
-  [(set (match_operand:SI 0 "register_operand" "")
-       (plus:SI (match_operand:SI 1 "reg_or_0_operand" "")
-                (match_operand:SI 2 "add_operand" "")))]
-  ""
-{
-  if (optimize)
-    {
-      rtx op1 = gen_lowpart (DImode, operands[1]);
-      rtx op2 = gen_lowpart (DImode, operands[2]);
-
-      if (! cse_not_expected)
-        {
-          rtx tmp = gen_reg_rtx (DImode);
-          emit_insn (gen_adddi3 (tmp, op1, op2));
-          emit_move_insn (gen_lowpart (DImode, operands[0]), tmp);
-        }
-      else
-        emit_insn (gen_adddi3 (gen_lowpart (DImode, operands[0]), op1, op2));
-      DONE;
-    }
-})
-
-(define_insn "*addsi_internal"
+(define_insn "addsi3"
   [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
        (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ,rJ,rJ,rJ")
                 (match_operand:SI 2 "add_operand" "rI,O,K,L")))]
@@ -581,6 +293,17 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
    addl %r1,%2,%0
    subl %r1,%n2,%0")
 
+(define_insn "*addsi_se2"
+  [(set (match_operand:DI 0 "register_operand" "=r,r")
+       (sign_extend:DI
+        (subreg:SI (plus:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ,rJ")
+                            (match_operand:DI 2 "sext_add_operand" "rI,O"))
+                   0)))]
+  ""
+  "@
+   addl %r1,%2,%0
+   subl %r1,%n2,%0")
+
 (define_split
   [(set (match_operand:DI 0 "register_operand" "")
        (sign_extend:DI
@@ -642,12 +365,55 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
   ""
   "")
 
+(define_insn "*adddi_er_lo16_dtp"
+  [(set (match_operand:DI 0 "register_operand" "=r")
+       (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
+                  (match_operand:DI 2 "dtp16_symbolic_operand" "")))]
+  "HAVE_AS_TLS"
+  "lda %0,%2(%1)\t\t!dtprel")
+
+(define_insn "*adddi_er_hi32_dtp"
+  [(set (match_operand:DI 0 "register_operand" "=r")
+       (plus:DI (match_operand:DI 1 "register_operand" "r")
+                (high:DI (match_operand:DI 2 "dtp32_symbolic_operand" ""))))]
+  "HAVE_AS_TLS"
+  "ldah %0,%2(%1)\t\t!dtprelhi")
+
+(define_insn "*adddi_er_lo32_dtp"
+  [(set (match_operand:DI 0 "register_operand" "=r")
+       (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
+                  (match_operand:DI 2 "dtp32_symbolic_operand" "")))]
+  "HAVE_AS_TLS"
+  "lda %0,%2(%1)\t\t!dtprello")
+
+(define_insn "*adddi_er_lo16_tp"
+  [(set (match_operand:DI 0 "register_operand" "=r")
+       (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
+                  (match_operand:DI 2 "tp16_symbolic_operand" "")))]
+  "HAVE_AS_TLS"
+  "lda %0,%2(%1)\t\t!tprel")
+
+(define_insn "*adddi_er_hi32_tp"
+  [(set (match_operand:DI 0 "register_operand" "=r")
+       (plus:DI (match_operand:DI 1 "register_operand" "r")
+                (high:DI (match_operand:DI 2 "tp32_symbolic_operand" ""))))]
+  "HAVE_AS_TLS"
+  "ldah %0,%2(%1)\t\t!tprelhi")
+
+(define_insn "*adddi_er_lo32_tp"
+  [(set (match_operand:DI 0 "register_operand" "=r")
+       (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
+                  (match_operand:DI 2 "tp32_symbolic_operand" "")))]
+  "HAVE_AS_TLS"
+  "lda %0,%2(%1)\t\t!tprello")
+
 (define_insn "*adddi_er_high_l"
   [(set (match_operand:DI 0 "register_operand" "=r")
        (plus:DI (match_operand:DI 1 "register_operand" "r")
                 (high:DI (match_operand:DI 2 "local_symbolic_operand" ""))))]
-  "TARGET_EXPLICIT_RELOCS"
-  "ldah %0,%2(%1)\t\t!gprelhigh")
+  "TARGET_EXPLICIT_RELOCS && reload_completed"
+  "ldah %0,%2(%1)\t\t!gprelhigh"
+  [(set_attr "usegp" "yes")])
 
 (define_split
   [(set (match_operand:DI 0 "register_operand" "")
@@ -689,9 +455,9 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
 ;; and if we split before reload, we will require additional instructions.
 
 (define_insn "*adddi_fp_hack"
-  [(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")))]
+  [(set (match_operand:DI 0 "register_operand" "=r,r,r")
+        (plus:DI (match_operand:DI 1 "reg_no_subreg_operand" "r,r,r")
+                (match_operand:DI 2 "const_int_operand" "K,L,n")))]
   "NONSTRICT_REG_OK_FP_BASE_P (operands[1])
    && INTVAL (operands[2]) >= 0
    /* This is the largest constant an lda+ldah pair can add, minus
@@ -700,12 +466,15 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
    && INTVAL (operands[2])
        < (0x7fff8000
           - FIRST_PSEUDO_REGISTER * UNITS_PER_WORD
-          - ALPHA_ROUND(current_function_outgoing_args_size)
+          - ALPHA_ROUND(crtl->outgoing_args_size)
           - (ALPHA_ROUND (get_frame_size ()
                           + max_reg_num () * UNITS_PER_WORD
-                          + current_function_pretend_args_size)
-             - current_function_pretend_args_size))"
-  "#")
+                          + crtl->args.pretend_args_size)
+             - crtl->args.pretend_args_size))"
+  "@
+   lda %0,%2(%1)
+   ldah %0,%h2(%1)
+   #")
 
 ;; Don't do this if we are adjusting SP since we don't want to do it
 ;; in two steps.  Don't split FP sources for the reason listed above.
@@ -723,11 +492,12 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
   HOST_WIDE_INT val = INTVAL (operands[2]);
   HOST_WIDE_INT low = (val & 0xffff) - 2 * (val & 0x8000);
   HOST_WIDE_INT rest = val - low;
+  rtx rest_rtx = 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)
+  if (satisfies_constraint_L (rest_rtx))
+    operands[3] = rest_rtx;
+  else if (can_create_pseudo_p ())
     {
       operands[3] = gen_reg_rtx (DImode);
       emit_move_insn (operands[3], operands[2]);
@@ -840,30 +610,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
   ""
   "subqv $31,%1,%0")
 
-(define_expand "subsi3"
-  [(set (match_operand:SI 0 "register_operand" "")
-       (minus:SI (match_operand:SI 1 "reg_or_0_operand" "")
-                 (match_operand:SI 2 "reg_or_8bit_operand" "")))]
-  ""
-{
-  if (optimize)
-    {
-      rtx op1 = gen_lowpart (DImode, operands[1]);
-      rtx op2 = gen_lowpart (DImode, operands[2]);
-
-      if (! cse_not_expected)
-        {
-          rtx tmp = gen_reg_rtx (DImode);
-          emit_insn (gen_subdi3 (tmp, op1, op2));
-          emit_move_insn (gen_lowpart (DImode, operands[0]), tmp);
-        }
-      else
-        emit_insn (gen_subdi3 (gen_lowpart (DImode, operands[0]), op1, op2));
-      DONE;
-    }
-})
-
-(define_insn "*subsi_internal"
+(define_insn "subsi3"
   [(set (match_operand:SI 0 "register_operand" "=r")
        (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
                  (match_operand:SI 2 "reg_or_8bit_operand" "rI")))]
@@ -877,6 +624,15 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
   ""
   "subl %r1,%2,%0")
 
+(define_insn "*subsi_se2"
+  [(set (match_operand:DI 0 "register_operand" "=r")
+       (sign_extend:DI
+        (subreg:SI (minus:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
+                             (match_operand:DI 2 "reg_or_8bit_operand" "rI"))
+                   0)))]
+  ""
+  "subl %r1,%2,%0")
+
 (define_insn "subvsi3"
   [(set (match_operand:SI 0 "register_operand" "=r")
        (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
@@ -989,17 +745,31 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
   "mulqv %r1,%2,%0"
   [(set_attr "type" "imul")])
 
-(define_insn "umuldi3_highpart"
+(define_expand "umuldi3_highpart"
+  [(set (match_operand:DI 0 "register_operand" "")
+       (truncate:DI
+        (lshiftrt:TI
+         (mult:TI (zero_extend:TI
+                    (match_operand:DI 1 "register_operand" ""))
+                  (match_operand:DI 2 "reg_or_8bit_operand" ""))
+         (const_int 64))))]
+  ""
+{
+  if (REG_P (operands[2]))
+    operands[2] = gen_rtx_ZERO_EXTEND (TImode, operands[2]);
+})
+
+(define_insn "*umuldi3_highpart_reg"
   [(set (match_operand:DI 0 "register_operand" "=r")
        (truncate:DI
         (lshiftrt:TI
          (mult:TI (zero_extend:TI
-                    (match_operand:DI 1 "reg_or_0_operand" "%rJ"))
+                    (match_operand:DI 1 "register_operand" "r"))
                   (zero_extend:TI
-                    (match_operand:DI 2 "reg_or_8bit_operand" "rI")))
+                    (match_operand:DI 2 "register_operand" "r")))
          (const_int 64))))]
   ""
-  "umulh %r1,%2,%0"
+  "umulh %1,%2,%0"
   [(set_attr "type" "imul")
    (set_attr "opsize" "udi")])
 
@@ -1207,7 +977,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
    (clobber (reg:DI 23))
    (clobber (reg:DI 28))]
   "TARGET_EXPLICIT_RELOCS && ! TARGET_ABI_OPEN_VMS"
-  "ldq $27,__%E3($29)\t\t!literal!%#\;jsr $23,($27),__%E3\t\t!lituse_jsr!%#"
+  "#"
   "&& reload_completed"
   [(parallel [(set (match_dup 0)
                   (sign_extend:DI (match_dup 3)))
@@ -1232,7 +1002,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
       str = "__remlu";
       break;
     default:
-      abort ();
+      gcc_unreachable ();
     }
   operands[4] = GEN_INT (alpha_next_sequence_number++);
   emit_insn (gen_movdi_er_high_g (operands[0], pic_offset_table_rtx,
@@ -1252,7 +1022,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
    (clobber (reg:DI 23))
    (clobber (reg:DI 28))]
   "TARGET_EXPLICIT_RELOCS && ! TARGET_ABI_OPEN_VMS"
-  "jsr $23,($27),__%E3%J5"
+  "jsr $23,($27),__%E3%j5"
   [(set_attr "type" "jsr")
    (set_attr "length" "4")])
 
@@ -1276,7 +1046,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
    (clobber (reg:DI 23))
    (clobber (reg:DI 28))]
   "TARGET_EXPLICIT_RELOCS && ! TARGET_ABI_OPEN_VMS"
-  "ldq $27,__%E3($29)\t\t!literal!%#\;jsr $23,($27),__%E3\t\t!lituse_jsr!%#"
+  "#"
   "&& reload_completed"
   [(parallel [(set (match_dup 0) (match_dup 3))
              (use (match_dup 0))
@@ -1300,7 +1070,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
       str = "__remqu";
       break;
     default:
-      abort ();
+      gcc_unreachable ();
     }
   operands[4] = GEN_INT (alpha_next_sequence_number++);
   emit_insn (gen_movdi_er_high_g (operands[0], pic_offset_table_rtx,
@@ -1320,7 +1090,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
    (clobber (reg:DI 23))
    (clobber (reg:DI 28))]
   "TARGET_EXPLICIT_RELOCS && ! TARGET_ABI_OPEN_VMS"
-  "jsr $23,($27),__%E3%J5"
+  "jsr $23,($27),__%E3%j5"
   [(set_attr "type" "jsr")
    (set_attr "length" "4")])
 
@@ -1336,7 +1106,20 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
   [(set_attr "type" "jsr")
    (set_attr "length" "8")])
 \f
-;; Next are the basic logical operations.  These only exist in DImode.
+;; Next are the basic logical operations.  We only expose the DImode operations
+;; to the rtl expanders, but SImode versions exist for combine as well as for
+;; the atomic operation splitters.
+
+(define_insn "*andsi_internal"
+  [(set (match_operand:SI 0 "register_operand" "=r,r,r")
+       (and:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ,rJ,rJ")
+               (match_operand:SI 2 "and_operand" "rI,N,MH")))]
+  ""
+  "@
+   and %r1,%2,%0
+   bic %r1,%N2,%0
+   zapnot %r1,%m2,%0"
+  [(set_attr "type" "ilog,ilog,shift")])
 
 (define_insn "anddi3"
   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
@@ -1511,6 +1294,14 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
   "zapnot %1,15,%0"
   [(set_attr "type" "shift")])
 
+(define_insn "*andnotsi3"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+       (and:SI (not:SI (match_operand:SI 1 "reg_or_8bit_operand" "rI"))
+               (match_operand:SI 2 "reg_or_0_operand" "rJ")))]
+  ""
+  "bic %r2,%1,%0"
+  [(set_attr "type" "ilog")])
+
 (define_insn "andnotdi3"
   [(set (match_operand:DI 0 "register_operand" "=r")
        (and:DI (not:DI (match_operand:DI 1 "reg_or_8bit_operand" "rI"))
@@ -1519,6 +1310,16 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
   "bic %r2,%1,%0"
   [(set_attr "type" "ilog")])
 
+(define_insn "*iorsi_internal"
+  [(set (match_operand:SI 0 "register_operand" "=r,r")
+       (ior:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ,rJ")
+               (match_operand:SI 2 "or_operand" "rI,N")))]
+  ""
+  "@
+   bis %r1,%2,%0
+   ornot %r1,%N2,%0"
+  [(set_attr "type" "ilog")])
+
 (define_insn "iordi3"
   [(set (match_operand:DI 0 "register_operand" "=r,r")
        (ior:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ,rJ")
@@ -1529,6 +1330,13 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
    ornot %r1,%N2,%0"
   [(set_attr "type" "ilog")])
 
+(define_insn "*one_cmplsi_internal"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+       (not:SI (match_operand:SI 1 "reg_or_8bit_operand" "rI")))]
+  ""
+  "ornot $31,%1,%0"
+  [(set_attr "type" "ilog")])
+
 (define_insn "one_cmpldi2"
   [(set (match_operand:DI 0 "register_operand" "=r")
        (not:DI (match_operand:DI 1 "reg_or_8bit_operand" "rI")))]
@@ -1536,7 +1344,15 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
   "ornot $31,%1,%0"
   [(set_attr "type" "ilog")])
 
-(define_insn "*iornot"
+(define_insn "*iornotsi3"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+       (ior:SI (not:SI (match_operand:SI 1 "reg_or_8bit_operand" "rI"))
+               (match_operand:SI 2 "reg_or_0_operand" "rJ")))]
+  ""
+  "ornot %r2,%1,%0"
+  [(set_attr "type" "ilog")])
+
+(define_insn "*iornotdi3"
   [(set (match_operand:DI 0 "register_operand" "=r")
        (ior:DI (not:DI (match_operand:DI 1 "reg_or_8bit_operand" "rI"))
                (match_operand:DI 2 "reg_or_0_operand" "rJ")))]
@@ -1544,6 +1360,16 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
   "ornot %r2,%1,%0"
   [(set_attr "type" "ilog")])
 
+(define_insn "*xorsi_internal"
+  [(set (match_operand:SI 0 "register_operand" "=r,r")
+       (xor:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ,rJ")
+               (match_operand:SI 2 "or_operand" "rI,N")))]
+  ""
+  "@
+   xor %r1,%2,%0
+   eqv %r1,%N2,%0"
+  [(set_attr "type" "ilog")])
+
 (define_insn "xordi3"
   [(set (match_operand:DI 0 "register_operand" "=r,r")
        (xor:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ,rJ")
@@ -1554,7 +1380,15 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
    eqv %r1,%N2,%0"
   [(set_attr "type" "ilog")])
 
-(define_insn "*xornot"
+(define_insn "*xornotsi3"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+       (not:SI (xor:SI (match_operand:SI 1 "register_operand" "%rJ")
+                       (match_operand:SI 2 "register_operand" "rI"))))]
+  ""
+  "eqv %r1,%2,%0"
+  [(set_attr "type" "ilog")])
+
+(define_insn "*xornotdi3"
   [(set (match_operand:DI 0 "register_operand" "=r")
        (not:DI (xor:DI (match_operand:DI 1 "register_operand" "%rJ")
                        (match_operand:DI 2 "register_operand" "rI"))))]
@@ -1562,11 +1396,11 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
   "eqv %r1,%2,%0"
   [(set_attr "type" "ilog")])
 \f
-;; Handle the FFS insn iff we support CIX.
+;; Handle FFS and related insns iff we support CIX.
 
 (define_expand "ffsdi2"
   [(set (match_dup 2)
-       (unspec:DI [(match_operand:DI 1 "register_operand" "")] UNSPEC_CTTZ))
+       (ctz:DI (match_operand:DI 1 "register_operand" "")))
    (set (match_dup 3)
        (plus:DI (match_dup 2) (const_int 1)))
    (set (match_operand:DI 0 "register_operand" "")
@@ -1578,14 +1412,80 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
   operands[3] = gen_reg_rtx (DImode);
 })
 
-(define_insn "*cttz"
+(define_insn "clzdi2"
+  [(set (match_operand:DI 0 "register_operand" "=r")
+       (clz:DI (match_operand:DI 1 "register_operand" "r")))]
+  "TARGET_CIX"
+  "ctlz %1,%0"
+  [(set_attr "type" "mvi")])
+
+(define_insn "ctzdi2"
   [(set (match_operand:DI 0 "register_operand" "=r")
-       (unspec:DI [(match_operand:DI 1 "register_operand" "r")] UNSPEC_CTTZ))]
+       (ctz:DI (match_operand:DI 1 "register_operand" "r")))]
   "TARGET_CIX"
   "cttz %1,%0"
-  ; EV6 calls all mvi and cttz/ctlz/popc class imisc, so just
-  ; reuse the existing type name.
   [(set_attr "type" "mvi")])
+
+(define_insn "popcountdi2"
+  [(set (match_operand:DI 0 "register_operand" "=r")
+       (popcount:DI (match_operand:DI 1 "register_operand" "r")))]
+  "TARGET_CIX"
+  "ctpop %1,%0"
+  [(set_attr "type" "mvi")])
+
+(define_expand "bswapsi2"
+  [(set (match_operand:SI 0 "register_operand" "")
+       (bswap:SI (match_operand:SI 1 "register_operand" "")))]
+  "!optimize_size"
+{
+  rtx t0, t1;
+
+  t0 = gen_reg_rtx (DImode);
+  t1 = gen_reg_rtx (DImode);
+
+  emit_insn (gen_insxh (t0, gen_lowpart (DImode, operands[1]),
+                       GEN_INT (32), GEN_INT (WORDS_BIG_ENDIAN ? 0 : 7)));
+  emit_insn (gen_inswl_const (t1, gen_lowpart (HImode, operands[1]),
+                             GEN_INT (24)));
+  emit_insn (gen_iordi3 (t1, t0, t1));
+  emit_insn (gen_lshrdi3 (t0, t1, GEN_INT (16)));
+  emit_insn (gen_anddi3 (t1, t1, alpha_expand_zap_mask (0x5)));
+  emit_insn (gen_anddi3 (t0, t0, alpha_expand_zap_mask (0xa)));
+  emit_insn (gen_addsi3 (operands[0], gen_lowpart (SImode, t0),
+                        gen_lowpart (SImode, t1)));
+  DONE;
+})
+
+(define_expand "bswapdi2"
+  [(set (match_operand:DI 0 "register_operand" "")
+       (bswap:DI (match_operand:DI 1 "register_operand" "")))]
+  "!optimize_size"
+{
+  rtx t0, t1;
+
+  t0 = gen_reg_rtx (DImode);
+  t1 = gen_reg_rtx (DImode);
+
+  /* This method of shifting and masking is not specific to Alpha, but
+     is only profitable on Alpha because of our handy byte zap insn.  */
+
+  emit_insn (gen_lshrdi3 (t0, operands[1], GEN_INT (32)));
+  emit_insn (gen_ashldi3 (t1, operands[1], GEN_INT (32)));
+  emit_insn (gen_iordi3 (t1, t0, t1));
+
+  emit_insn (gen_lshrdi3 (t0, t1, GEN_INT (16)));
+  emit_insn (gen_ashldi3 (t1, t1, GEN_INT (16)));
+  emit_insn (gen_anddi3 (t0, t0, alpha_expand_zap_mask (0xcc)));
+  emit_insn (gen_anddi3 (t1, t1, alpha_expand_zap_mask (0x33)));
+  emit_insn (gen_iordi3 (t1, t0, t1));
+
+  emit_insn (gen_lshrdi3 (t0, t1, GEN_INT (8)));
+  emit_insn (gen_ashldi3 (t1, t1, GEN_INT (8)));
+  emit_insn (gen_anddi3 (t0, t0, alpha_expand_zap_mask (0xaa)));
+  emit_insn (gen_anddi3 (t1, t1, alpha_expand_zap_mask (0x55)));
+  emit_insn (gen_iordi3 (operands[0], t0, t1));
+  DONE;
+})
 \f
 ;; Next come the shifts and the various extract and insert operations.
 
@@ -1605,28 +1505,25 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
     case 1:
       return "sll %r1,%2,%0";
     default:
-      abort();
+      gcc_unreachable ();
     }
 }
   [(set_attr "type" "iadd,shift")])
 
-;; ??? The following pattern is made by combine, but earlier phases
-;; (specifically flow) can't handle it.  This occurs in jump.c.  Deal
-;; with this in a better way at some point.
-;;(define_insn ""
-;;  [(set (match_operand:DI 0 "register_operand" "=r")
-;;     (sign_extend:DI
-;;      (subreg:SI (ashift:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
-;;                            (match_operand:DI 2 "const_int_operand" "P"))
-;;                 0)))]
-;;  "INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 3"
-;;{
-;;  if (operands[2] == const1_rtx)
-;;    return "addl %r1,%r1,%0";
-;;  else
-;;    return "s%P2addl %r1,0,%0";
-;;}
-;;  [(set_attr "type" "iadd")])
+(define_insn "*ashldi_se"
+  [(set (match_operand:DI 0 "register_operand" "=r")
+       (sign_extend:DI
+        (subreg:SI (ashift:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
+                              (match_operand:DI 2 "const_int_operand" "P"))
+                   0)))]
+  "INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 3"
+{
+  if (operands[2] == const1_rtx)
+    return "addl %r1,%r1,%0";
+  else
+    return "s%P2addl %r1,0,%0";
+}
+  [(set_attr "type" "iadd")])
 
 (define_insn "lshrdi3"
   [(set (match_operand:DI 0 "register_operand" "=r")
@@ -1761,10 +1658,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
 
   if (unaligned_memory_operand (operands[1], QImode))
     {
-      rtx seq
-       = gen_unaligned_extendqidi (operands[0],
-                                   get_unaligned_address (operands[1], 1));
-
+      rtx seq = gen_unaligned_extendqidi (operands[0], XEXP (operands[1], 0));
       alpha_set_memflags (seq, operands[1]);
       emit_insn (seq);
       DONE;
@@ -1824,9 +1718,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
 
   if (unaligned_memory_operand (operands[1], HImode))
     {
-      rtx seq
-       = gen_unaligned_extendhidi (operands[0],
-                                   get_unaligned_address (operands[1], 2));
+      rtx seq = gen_unaligned_extendhidi (operands[0], XEXP (operands[1], 0));
 
       alpha_set_memflags (seq, operands[1]);
       emit_insn (seq);
@@ -1841,12 +1733,13 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
 ;; as a pattern saves one instruction.  The code is similar to that for
 ;; the unaligned loads (see below).
 ;;
-;; Operand 1 is the address + 1 (+2 for HI), operand 0 is the result.
+;; Operand 1 is the address, operand 0 is the result.
 (define_expand "unaligned_extendqidi"
   [(use (match_operand:QI 0 "register_operand" ""))
    (use (match_operand:DI 1 "address_operand" ""))]
   ""
 {
+  operands[0] = gen_lowpart (DImode, operands[0]);
   if (WORDS_BIG_ENDIAN)
     emit_insn (gen_unaligned_extendqidi_be (operands[0], operands[1]));
   else
@@ -1855,48 +1748,40 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
 })
 
 (define_expand "unaligned_extendqidi_le"
-  [(set (match_dup 2) (match_operand:DI 1 "address_operand" ""))
-   (set (match_dup 3)
-       (mem:DI (and:DI (plus:DI (match_dup 2) (const_int -1))
-                       (const_int -8))))
+  [(set (match_dup 3)
+       (mem:DI (and:DI (match_operand:DI 1 "" "") (const_int -8))))
    (set (match_dup 4)
        (ashift:DI (match_dup 3)
                   (minus:DI (const_int 64)
                             (ashift:DI
                              (and:DI (match_dup 2) (const_int 7))
                              (const_int 3)))))
-   (set (subreg:DI (match_operand:QI 0 "register_operand" "") 0)
+   (set (match_operand:DI 0 "register_operand" "")
        (ashiftrt:DI (match_dup 4) (const_int 56)))]
   "! WORDS_BIG_ENDIAN"
 {
-  operands[2] = gen_reg_rtx (DImode);
+  operands[2] = get_unaligned_offset (operands[1], 1);
   operands[3] = gen_reg_rtx (DImode);
   operands[4] = gen_reg_rtx (DImode);
 })
 
 (define_expand "unaligned_extendqidi_be"
-  [(set (match_dup 2) (match_operand:DI 1 "address_operand" ""))
-   (set (match_dup 3) (plus:DI (match_dup 2) (const_int -1)))
+  [(set (match_dup 3)
+       (mem:DI (and:DI (match_operand:DI 1 "" "") (const_int -8))))
    (set (match_dup 4)
-       (mem:DI (and:DI (match_dup 3)
-                       (const_int -8))))
-   (set (match_dup 5) (plus:DI (match_dup 2) (const_int -2)))
-   (set (match_dup 6)
-       (ashift:DI (match_dup 4)
+       (ashift:DI (match_dup 3)
                   (ashift:DI
                     (and:DI
-                      (plus:DI (match_dup 5) (const_int 1))
+                      (plus:DI (match_dup 2) (const_int 1))
                       (const_int 7))
                     (const_int 3))))
-   (set (subreg:DI (match_operand:QI 0 "register_operand" "") 0)
-       (ashiftrt:DI (match_dup 6) (const_int 56)))]
+   (set (match_operand:DI 0 "register_operand" "")
+       (ashiftrt:DI (match_dup 4) (const_int 56)))]
   "WORDS_BIG_ENDIAN"
 {
-  operands[2] = gen_reg_rtx (DImode);
+  operands[2] = get_unaligned_offset (operands[1], -1);
   operands[3] = gen_reg_rtx (DImode);
   operands[4] = gen_reg_rtx (DImode);
-  operands[5] = gen_reg_rtx (DImode);
-  operands[6] = gen_reg_rtx (DImode);
 })
 
 (define_expand "unaligned_extendhidi"
@@ -1905,17 +1790,16 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
   ""
 {
   operands[0] = gen_lowpart (DImode, operands[0]);
-  emit_insn ((WORDS_BIG_ENDIAN
-             ? gen_unaligned_extendhidi_be
-             : gen_unaligned_extendhidi_le) (operands[0], operands[1]));
+  if (WORDS_BIG_ENDIAN)
+    emit_insn (gen_unaligned_extendhidi_be (operands[0], operands[1]));
+  else
+    emit_insn (gen_unaligned_extendhidi_le (operands[0], operands[1]));
   DONE;
 })
 
 (define_expand "unaligned_extendhidi_le"
-  [(set (match_dup 2) (match_operand:DI 1 "address_operand" ""))
-   (set (match_dup 3)
-       (mem:DI (and:DI (plus:DI (match_dup 2) (const_int -2))
-                       (const_int -8))))
+  [(set (match_dup 3)
+       (mem:DI (and:DI (match_operand:DI 1 "" "") (const_int -8))))
    (set (match_dup 4)
        (ashift:DI (match_dup 3)
                   (minus:DI (const_int 64)
@@ -1926,34 +1810,28 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
        (ashiftrt:DI (match_dup 4) (const_int 48)))]
   "! WORDS_BIG_ENDIAN"
 {
-  operands[2] = gen_reg_rtx (DImode);
+  operands[2] = get_unaligned_offset (operands[1], 2);
   operands[3] = gen_reg_rtx (DImode);
   operands[4] = gen_reg_rtx (DImode);
 })
 
 (define_expand "unaligned_extendhidi_be"
-  [(set (match_dup 2) (match_operand:DI 1 "address_operand" ""))
-   (set (match_dup 3) (plus:DI (match_dup 2) (const_int -2)))
+  [(set (match_dup 3)
+       (mem:DI (and:DI (match_operand:DI 1 "" "") (const_int -8))))
    (set (match_dup 4)
-       (mem:DI (and:DI (match_dup 3)
-                       (const_int -8))))
-   (set (match_dup 5) (plus:DI (match_dup 2) (const_int -3)))
-   (set (match_dup 6)
-       (ashift:DI (match_dup 4)
+       (ashift:DI (match_dup 3)
                   (ashift:DI
                     (and:DI
-                      (plus:DI (match_dup 5) (const_int 1))
+                      (plus:DI (match_dup 2) (const_int 1))
                       (const_int 7))
                     (const_int 3))))
    (set (match_operand:DI 0 "register_operand" "")
-       (ashiftrt:DI (match_dup 6) (const_int 48)))]
+       (ashiftrt:DI (match_dup 4) (const_int 48)))]
   "WORDS_BIG_ENDIAN"
 {
-  operands[2] = gen_reg_rtx (DImode);
+  operands[2] = get_unaligned_offset (operands[1], -1);
   operands[3] = gen_reg_rtx (DImode);
   operands[4] = gen_reg_rtx (DImode);
-  operands[5] = gen_reg_rtx (DImode);
-  operands[6] = gen_reg_rtx (DImode);
 })
 
 (define_insn "*extxl_const"
@@ -1988,7 +1866,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
   "ext%M2l %r1,%3,%0"
   [(set_attr "type" "shift")])
 
-;; Combine has some strange notion of preserving existing undefined behaviour
+;; Combine has some strange notion of preserving existing undefined behavior
 ;; in shifts larger than a word size.  So capture these patterns that it
 ;; should have turned into zero_extracts.
 
@@ -2160,7 +2038,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
   "insbl %1,%s2,%0"
   [(set_attr "type" "shift")])
 
-(define_insn "*inswl_const"
+(define_insn "inswl_const"
   [(set (match_operand:DI 0 "register_operand" "=r")
        (ashift:DI (zero_extend:DI (match_operand:HI 1 "register_operand" "r"))
                   (match_operand:DI 2 "mul8_operand" "I")))]
@@ -2261,7 +2139,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
                           (match_operand:DI 2 "mul8_operand" "I"))
                (match_operand:DI 3 "immediate_operand" "i")))]
   "HOST_BITS_PER_WIDE_INT == 64
-   && GET_CODE (operands[3]) == CONST_INT
+   && CONST_INT_P (operands[3])
    && (((unsigned HOST_WIDE_INT) 0xff << INTVAL (operands[2])
         == (unsigned HOST_WIDE_INT) INTVAL (operands[3]))
        || ((unsigned HOST_WIDE_INT) 0xffff << INTVAL (operands[2])
@@ -2280,7 +2158,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
       == (unsigned HOST_WIDE_INT) INTVAL (operands[3]))
     return "insll %1,%s2,%0";
 #endif
-  abort();
+  gcc_unreachable ();
 }
   [(set_attr "type" "shift")])
 
@@ -2361,35 +2239,35 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
 
 (define_insn "abssf2"
   [(set (match_operand:SF 0 "register_operand" "=f")
-       (abs:SF (match_operand:SF 1 "reg_or_fp0_operand" "fG")))]
+       (abs:SF (match_operand:SF 1 "reg_or_0_operand" "fG")))]
   "TARGET_FP"
   "cpys $f31,%R1,%0"
   [(set_attr "type" "fcpys")])
 
 (define_insn "*nabssf2"
   [(set (match_operand:SF 0 "register_operand" "=f")
-       (neg:SF (abs:SF (match_operand:SF 1 "reg_or_fp0_operand" "fG"))))]
+       (neg:SF (abs:SF (match_operand:SF 1 "reg_or_0_operand" "fG"))))]
   "TARGET_FP"
   "cpysn $f31,%R1,%0"
   [(set_attr "type" "fadd")])
 
 (define_insn "absdf2"
   [(set (match_operand:DF 0 "register_operand" "=f")
-       (abs:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG")))]
+       (abs:DF (match_operand:DF 1 "reg_or_0_operand" "fG")))]
   "TARGET_FP"
   "cpys $f31,%R1,%0"
   [(set_attr "type" "fcpys")])
 
 (define_insn "*nabsdf2"
   [(set (match_operand:DF 0 "register_operand" "=f")
-       (neg:DF (abs:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG"))))]
+       (neg:DF (abs:DF (match_operand:DF 1 "reg_or_0_operand" "fG"))))]
   "TARGET_FP"
   "cpysn $f31,%R1,%0"
   [(set_attr "type" "fadd")])
 
 (define_expand "abstf2"
   [(parallel [(set (match_operand:TF 0 "register_operand" "")
-                  (neg:TF (match_operand:TF 1 "reg_or_fp0_operand" "")))
+                  (abs:TF (match_operand:TF 1 "reg_or_0_operand" "")))
              (use (match_dup 2))])]
   "TARGET_HAS_XFLOATING_LIBS"
 {
@@ -2402,7 +2280,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
 
 (define_insn_and_split "*abstf_internal"
   [(set (match_operand:TF 0 "register_operand" "=r")
-       (abs:TF (match_operand:TF 1 "reg_or_fp0_operand" "rG")))
+       (abs:TF (match_operand:TF 1 "reg_or_0_operand" "rG")))
    (use (match_operand:DI 2 "register_operand" "r"))]
   "TARGET_HAS_XFLOATING_LIBS"
   "#"
@@ -2412,21 +2290,21 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
 
 (define_insn "negsf2"
   [(set (match_operand:SF 0 "register_operand" "=f")
-       (neg:SF (match_operand:SF 1 "reg_or_fp0_operand" "fG")))]
+       (neg:SF (match_operand:SF 1 "reg_or_0_operand" "fG")))]
   "TARGET_FP"
   "cpysn %R1,%R1,%0"
   [(set_attr "type" "fadd")])
 
 (define_insn "negdf2"
   [(set (match_operand:DF 0 "register_operand" "=f")
-       (neg:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG")))]
+       (neg:DF (match_operand:DF 1 "reg_or_0_operand" "fG")))]
   "TARGET_FP"
   "cpysn %R1,%R1,%0"
   [(set_attr "type" "fadd")])
 
 (define_expand "negtf2"
   [(parallel [(set (match_operand:TF 0 "register_operand" "")
-                  (neg:TF (match_operand:TF 1 "reg_or_fp0_operand" "")))
+                  (neg:TF (match_operand:TF 1 "reg_or_0_operand" "")))
              (use (match_dup 2))])]
   "TARGET_HAS_XFLOATING_LIBS"
 {
@@ -2439,7 +2317,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
 
 (define_insn_and_split "*negtf_internal"
   [(set (match_operand:TF 0 "register_operand" "=r")
-       (neg:TF (match_operand:TF 1 "reg_or_fp0_operand" "rG")))
+       (neg:TF (match_operand:TF 1 "reg_or_0_operand" "rG")))
    (use (match_operand:DI 2 "register_operand" "r"))]
   "TARGET_HAS_XFLOATING_LIBS"
   "#"
@@ -2447,10 +2325,46 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
   [(const_int 0)]
   "alpha_split_tfmode_frobsign (operands, gen_xordi3); DONE;")
 
+(define_insn "copysignsf3"
+  [(set (match_operand:SF 0 "register_operand" "=f")
+       (unspec:SF [(match_operand:SF 1 "reg_or_0_operand" "fG")
+                   (match_operand:SF 2 "reg_or_0_operand" "fG")]
+                  UNSPEC_COPYSIGN))]
+  "TARGET_FP"
+  "cpys %R2,%R1,%0"
+  [(set_attr "type" "fadd")])
+
+(define_insn "*ncopysignsf3"
+  [(set (match_operand:SF 0 "register_operand" "=f")
+       (neg:SF (unspec:SF [(match_operand:SF 1 "reg_or_0_operand" "fG")
+                           (match_operand:SF 2 "reg_or_0_operand" "fG")]
+                          UNSPEC_COPYSIGN)))]
+  "TARGET_FP"
+  "cpysn %R2,%R1,%0"
+  [(set_attr "type" "fadd")])
+
+(define_insn "copysigndf3"
+  [(set (match_operand:DF 0 "register_operand" "=f")
+       (unspec:DF [(match_operand:DF 1 "reg_or_0_operand" "fG")
+                   (match_operand:DF 2 "reg_or_0_operand" "fG")]
+                  UNSPEC_COPYSIGN))]
+  "TARGET_FP"
+  "cpys %R2,%R1,%0"
+  [(set_attr "type" "fadd")])
+
+(define_insn "*ncopysigndf3"
+  [(set (match_operand:DF 0 "register_operand" "=f")
+       (neg:DF (unspec:DF [(match_operand:DF 1 "reg_or_0_operand" "fG")
+                           (match_operand:DF 2 "reg_or_0_operand" "fG")]
+                          UNSPEC_COPYSIGN)))]
+  "TARGET_FP"
+  "cpysn %R2,%R1,%0"
+  [(set_attr "type" "fadd")])
+
 (define_insn "*addsf_ieee"
   [(set (match_operand:SF 0 "register_operand" "=&f")
-       (plus:SF (match_operand:SF 1 "reg_or_fp0_operand" "%fG")
-                (match_operand:SF 2 "reg_or_fp0_operand" "fG")))]
+       (plus:SF (match_operand:SF 1 "reg_or_0_operand" "%fG")
+                (match_operand:SF 2 "reg_or_0_operand" "fG")))]
   "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
   "add%,%/ %R1,%R2,%0"
   [(set_attr "type" "fadd")
@@ -2460,8 +2374,8 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
 
 (define_insn "addsf3"
   [(set (match_operand:SF 0 "register_operand" "=f")
-       (plus:SF (match_operand:SF 1 "reg_or_fp0_operand" "%fG")
-                (match_operand:SF 2 "reg_or_fp0_operand" "fG")))]
+       (plus:SF (match_operand:SF 1 "reg_or_0_operand" "%fG")
+                (match_operand:SF 2 "reg_or_0_operand" "fG")))]
   "TARGET_FP"
   "add%,%/ %R1,%R2,%0"
   [(set_attr "type" "fadd")
@@ -2471,8 +2385,8 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
 
 (define_insn "*adddf_ieee"
   [(set (match_operand:DF 0 "register_operand" "=&f")
-       (plus:DF (match_operand:DF 1 "reg_or_fp0_operand" "%fG")
-                (match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
+       (plus:DF (match_operand:DF 1 "reg_or_0_operand" "%fG")
+                (match_operand:DF 2 "reg_or_0_operand" "fG")))]
   "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
   "add%-%/ %R1,%R2,%0"
   [(set_attr "type" "fadd")
@@ -2482,8 +2396,8 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
 
 (define_insn "adddf3"
   [(set (match_operand:DF 0 "register_operand" "=f")
-       (plus:DF (match_operand:DF 1 "reg_or_fp0_operand" "%fG")
-                (match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
+       (plus:DF (match_operand:DF 1 "reg_or_0_operand" "%fG")
+                (match_operand:DF 2 "reg_or_0_operand" "fG")))]
   "TARGET_FP"
   "add%-%/ %R1,%R2,%0"
   [(set_attr "type" "fadd")
@@ -2494,8 +2408,8 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
 (define_insn "*adddf_ext1"
   [(set (match_operand:DF 0 "register_operand" "=f")
        (plus:DF (float_extend:DF
-                 (match_operand:SF 1 "reg_or_fp0_operand" "fG"))
-                (match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
+                 (match_operand:SF 1 "reg_or_0_operand" "fG"))
+                (match_operand:DF 2 "reg_or_0_operand" "fG")))]
   "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
   "add%-%/ %R1,%R2,%0"
   [(set_attr "type" "fadd")
@@ -2506,9 +2420,9 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
 (define_insn "*adddf_ext2"
   [(set (match_operand:DF 0 "register_operand" "=f")
        (plus:DF (float_extend:DF
-                 (match_operand:SF 1 "reg_or_fp0_operand" "%fG"))
+                 (match_operand:SF 1 "reg_or_0_operand" "%fG"))
                 (float_extend:DF
-                 (match_operand:SF 2 "reg_or_fp0_operand" "fG"))))]
+                 (match_operand:SF 2 "reg_or_0_operand" "fG"))))]
   "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
   "add%-%/ %R1,%R2,%0"
   [(set_attr "type" "fadd")
@@ -2533,8 +2447,8 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
 ;; processing, it is cheaper to do the truncation in the int regs.
 
 (define_insn "*cvtql"
-  [(set (match_operand:SI 0 "register_operand" "=f")
-       (unspec:SI [(match_operand:DI 1 "reg_or_fp0_operand" "fG")]
+  [(set (match_operand:SF 0 "register_operand" "=f")
+       (unspec:SF [(match_operand:DI 1 "reg_or_0_operand" "fG")]
                   UNSPEC_CVTQL))]
   "TARGET_FP"
   "cvtql%/ %R1,%0"
@@ -2544,37 +2458,46 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
 
 (define_insn_and_split "*fix_truncdfsi_ieee"
   [(set (match_operand:SI 0 "memory_operand" "=m")
-       (subreg:SI (fix:DI (match_operand:DF 1 "reg_or_fp0_operand" "fG")) 0))
+       (subreg:SI
+         (match_operator:DI 4 "fix_operator" 
+           [(match_operand:DF 1 "reg_or_0_operand" "fG")]) 0))
    (clobber (match_scratch:DI 2 "=&f"))
-   (clobber (match_scratch:SI 3 "=&f"))]
+   (clobber (match_scratch:SF 3 "=&f"))]
   "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
   "#"
   "&& reload_completed"
-  [(set (match_dup 2) (fix:DI (match_dup 1)))
-   (set (match_dup 3) (unspec:SI [(match_dup 2)] UNSPEC_CVTQL))
-   (set (match_dup 0) (match_dup 3))]
-  ""
+  [(set (match_dup 2) (match_op_dup 4 [(match_dup 1)]))
+   (set (match_dup 3) (unspec:SF [(match_dup 2)] UNSPEC_CVTQL))
+   (set (match_dup 5) (match_dup 3))]
+{
+  operands[5] = adjust_address (operands[0], SFmode, 0);
+}
   [(set_attr "type" "fadd")
    (set_attr "trap" "yes")])
 
 (define_insn_and_split "*fix_truncdfsi_internal"
   [(set (match_operand:SI 0 "memory_operand" "=m")
-       (subreg:SI (fix:DI (match_operand:DF 1 "reg_or_fp0_operand" "fG")) 0))
+       (subreg:SI
+         (match_operator:DI 3 "fix_operator" 
+           [(match_operand:DF 1 "reg_or_0_operand" "fG")]) 0))
    (clobber (match_scratch:DI 2 "=f"))]
   "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
   "#"
   "&& reload_completed"
-  [(set (match_dup 2) (fix:DI (match_dup 1)))
-   (set (match_dup 3) (unspec:SI [(match_dup 2)] UNSPEC_CVTQL))
-   (set (match_dup 0) (match_dup 3))]
-  ;; Due to REG_CANNOT_CHANGE_SIZE issues, we cannot simply use SUBREG.
-  "operands[3] = gen_rtx_REG (SImode, REGNO (operands[2]));"
+  [(set (match_dup 2) (match_op_dup 3 [(match_dup 1)]))
+   (set (match_dup 4) (unspec:SF [(match_dup 2)] UNSPEC_CVTQL))
+   (set (match_dup 5) (match_dup 4))]
+{
+  operands[4] = gen_rtx_REG (SFmode, REGNO (operands[2]));
+  operands[5] = adjust_address (operands[0], SFmode, 0);
+}
   [(set_attr "type" "fadd")
    (set_attr "trap" "yes")])
 
 (define_insn "*fix_truncdfdi_ieee"
   [(set (match_operand:DI 0 "reg_no_subreg_operand" "=&f")
-       (fix:DI (match_operand:DF 1 "reg_or_fp0_operand" "fG")))]
+       (match_operator:DI 2 "fix_operator" 
+         [(match_operand:DF 1 "reg_or_0_operand" "fG")]))]
   "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
   "cvt%-q%/ %R1,%0"
   [(set_attr "type" "fadd")
@@ -2582,9 +2505,10 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
    (set_attr "round_suffix" "c")
    (set_attr "trap_suffix" "v_sv_svi")])
 
-(define_insn "fix_truncdfdi2"
+(define_insn "*fix_truncdfdi2"
   [(set (match_operand:DI 0 "reg_no_subreg_operand" "=f")
-       (fix:DI (match_operand:DF 1 "reg_or_fp0_operand" "fG")))]
+       (match_operator:DI 2 "fix_operator" 
+         [(match_operand:DF 1 "reg_or_0_operand" "fG")]))]
   "TARGET_FP"
   "cvt%-q%/ %R1,%0"
   [(set_attr "type" "fadd")
@@ -2592,44 +2516,64 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
    (set_attr "round_suffix" "c")
    (set_attr "trap_suffix" "v_sv_svi")])
 
+(define_expand "fix_truncdfdi2"
+  [(set (match_operand:DI 0 "reg_no_subreg_operand" "")
+       (fix:DI (match_operand:DF 1 "reg_or_0_operand" "")))]
+  "TARGET_FP"
+  "")
+
+(define_expand "fixuns_truncdfdi2"
+  [(set (match_operand:DI 0 "reg_no_subreg_operand" "")
+       (unsigned_fix:DI (match_operand:DF 1 "reg_or_0_operand" "")))]
+  "TARGET_FP"
+  "")
+
 ;; Likewise between SFmode and SImode.
 
 (define_insn_and_split "*fix_truncsfsi_ieee"
   [(set (match_operand:SI 0 "memory_operand" "=m")
-       (subreg:SI (fix:DI (float_extend:DF
-                (match_operand:SF 1 "reg_or_fp0_operand" "fG"))) 0))
+       (subreg:SI
+         (match_operator:DI 4 "fix_operator" 
+           [(float_extend:DF
+              (match_operand:SF 1 "reg_or_0_operand" "fG"))]) 0))
    (clobber (match_scratch:DI 2 "=&f"))
-   (clobber (match_scratch:SI 3 "=&f"))]
+   (clobber (match_scratch:SF 3 "=&f"))]
   "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
   "#"
   "&& reload_completed"
-  [(set (match_dup 2) (fix:DI (float_extend:DF (match_dup 1))))
-   (set (match_dup 3) (unspec:SI [(match_dup 2)] UNSPEC_CVTQL))
-   (set (match_dup 0) (match_dup 3))]
-  ""
+  [(set (match_dup 2) (match_op_dup 4 [(float_extend:DF (match_dup 1))]))
+   (set (match_dup 3) (unspec:SF [(match_dup 2)] UNSPEC_CVTQL))
+   (set (match_dup 5) (match_dup 3))]
+{
+  operands[5] = adjust_address (operands[0], SFmode, 0);
+}
   [(set_attr "type" "fadd")
    (set_attr "trap" "yes")])
 
 (define_insn_and_split "*fix_truncsfsi_internal"
   [(set (match_operand:SI 0 "memory_operand" "=m")
-       (subreg:SI (fix:DI (float_extend:DF
-                (match_operand:SF 1 "reg_or_fp0_operand" "fG"))) 0))
+       (subreg:SI
+         (match_operator:DI 3 "fix_operator" 
+           [(float_extend:DF
+              (match_operand:SF 1 "reg_or_0_operand" "fG"))]) 0))
    (clobber (match_scratch:DI 2 "=f"))]
   "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
   "#"
   "&& reload_completed"
-  [(set (match_dup 2) (fix:DI (float_extend:DF (match_dup 1))))
-   (set (match_dup 3) (unspec:SI [(match_dup 2)] UNSPEC_CVTQL))
-   (set (match_dup 0) (match_dup 3))]
-  ;; Due to REG_CANNOT_CHANGE_SIZE issues, we cannot simply use SUBREG.
-  "operands[3] = gen_rtx_REG (SImode, REGNO (operands[2]));"
+  [(set (match_dup 2) (match_op_dup 3 [(float_extend:DF (match_dup 1))]))
+   (set (match_dup 4) (unspec:SF [(match_dup 2)] UNSPEC_CVTQL))
+   (set (match_dup 5) (match_dup 4))]
+{
+  operands[4] = gen_rtx_REG (SFmode, REGNO (operands[2]));
+  operands[5] = adjust_address (operands[0], SFmode, 0);
+}
   [(set_attr "type" "fadd")
    (set_attr "trap" "yes")])
 
 (define_insn "*fix_truncsfdi_ieee"
   [(set (match_operand:DI 0 "reg_no_subreg_operand" "=&f")
-       (fix:DI (float_extend:DF
-                (match_operand:SF 1 "reg_or_fp0_operand" "fG"))))]
+       (match_operator:DI 2 "fix_operator" 
+         [(float_extend:DF (match_operand:SF 1 "reg_or_0_operand" "fG"))]))]
   "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
   "cvt%-q%/ %R1,%0"
   [(set_attr "type" "fadd")
@@ -2637,10 +2581,10 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
    (set_attr "round_suffix" "c")
    (set_attr "trap_suffix" "v_sv_svi")])
 
-(define_insn "fix_truncsfdi2"
+(define_insn "*fix_truncsfdi2"
   [(set (match_operand:DI 0 "reg_no_subreg_operand" "=f")
-       (fix:DI (float_extend:DF
-                (match_operand:SF 1 "reg_or_fp0_operand" "fG"))))]
+       (match_operator:DI 2 "fix_operator" 
+         [(float_extend:DF (match_operand:SF 1 "reg_or_0_operand" "fG"))]))]
   "TARGET_FP"
   "cvt%-q%/ %R1,%0"
   [(set_attr "type" "fadd")
@@ -2648,12 +2592,31 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
    (set_attr "round_suffix" "c")
    (set_attr "trap_suffix" "v_sv_svi")])
 
+(define_expand "fix_truncsfdi2"
+  [(set (match_operand:DI 0 "reg_no_subreg_operand" "")
+       (fix:DI (float_extend:DF (match_operand:SF 1 "reg_or_0_operand" ""))))]
+  "TARGET_FP"
+  "")
+
+(define_expand "fixuns_truncsfdi2"
+  [(set (match_operand:DI 0 "reg_no_subreg_operand" "")
+       (unsigned_fix:DI
+         (float_extend:DF (match_operand:SF 1 "reg_or_0_operand" ""))))]
+  "TARGET_FP"
+  "")
+
 (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_expand "fixuns_trunctfdi2"
+  [(use (match_operand:DI 0 "register_operand" ""))
+   (use (match_operand:TF 1 "general_operand" ""))]
+  "TARGET_HAS_XFLOATING_LIBS"
+  "alpha_emit_xfloating_cvt (UNSIGNED_FIX, operands); DONE;")
+
 (define_insn "*floatdisf_ieee"
   [(set (match_operand:SF 0 "register_operand" "=&f")
        (float:SF (match_operand:DI 1 "reg_no_subreg_operand" "f")))]
@@ -2674,15 +2637,44 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
    (set_attr "round_suffix" "normal")
    (set_attr "trap_suffix" "sui")])
 
-(define_insn "*floatdidf_ieee"
-  [(set (match_operand:DF 0 "register_operand" "=&f")
-       (float:DF (match_operand:DI 1 "reg_no_subreg_operand" "f")))]
+(define_insn_and_split "*floatsisf2_ieee"
+  [(set (match_operand:SF 0 "register_operand" "=&f")
+       (float:SF (match_operand:SI 1 "memory_operand" "m")))
+   (clobber (match_scratch:DI 2 "=&f"))
+   (clobber (match_scratch:SF 3 "=&f"))]
   "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
-  "cvtq%-%/ %1,%0"
-  [(set_attr "type" "fadd")
-   (set_attr "trap" "yes")
-   (set_attr "round_suffix" "normal")
-   (set_attr "trap_suffix" "sui")])
+  "#"
+  "&& reload_completed"
+  [(set (match_dup 3) (match_dup 1))
+   (set (match_dup 2) (unspec:DI [(match_dup 3)] UNSPEC_CVTLQ))
+   (set (match_dup 0) (float:SF (match_dup 2)))]
+{
+  operands[1] = adjust_address (operands[1], SFmode, 0);
+})
+
+(define_insn_and_split "*floatsisf2"
+  [(set (match_operand:SF 0 "register_operand" "=f")
+       (float:SF (match_operand:SI 1 "memory_operand" "m")))]
+  "TARGET_FP"
+  "#"
+  "&& reload_completed"
+  [(set (match_dup 0) (match_dup 1))
+   (set (match_dup 2) (unspec:DI [(match_dup 0)] UNSPEC_CVTLQ))
+   (set (match_dup 0) (float:SF (match_dup 2)))]
+{
+  operands[1] = adjust_address (operands[1], SFmode, 0);
+  operands[2] = gen_rtx_REG (DImode, REGNO (operands[0]));
+})
+
+(define_insn "*floatdidf_ieee"
+  [(set (match_operand:DF 0 "register_operand" "=&f")
+       (float:DF (match_operand:DI 1 "reg_no_subreg_operand" "f")))]
+  "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
+  "cvtq%-%/ %1,%0"
+  [(set_attr "type" "fadd")
+   (set_attr "trap" "yes")
+   (set_attr "round_suffix" "normal")
+   (set_attr "trap_suffix" "sui")])
 
 (define_insn "floatdidf2"
   [(set (match_operand:DF 0 "register_operand" "=f")
@@ -2694,6 +2686,36 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
    (set_attr "round_suffix" "normal")
    (set_attr "trap_suffix" "sui")])
 
+(define_insn_and_split "*floatsidf2_ieee"
+  [(set (match_operand:DF 0 "register_operand" "=&f")
+       (float:DF (match_operand:SI 1 "memory_operand" "m")))
+   (clobber (match_scratch:DI 2 "=&f"))
+   (clobber (match_scratch:SF 3 "=&f"))]
+  "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
+  "#"
+  "&& reload_completed"
+  [(set (match_dup 3) (match_dup 1))
+   (set (match_dup 2) (unspec:DI [(match_dup 3)] UNSPEC_CVTLQ))
+   (set (match_dup 0) (float:DF (match_dup 2)))]
+{
+  operands[1] = adjust_address (operands[1], SFmode, 0);
+})
+
+(define_insn_and_split "*floatsidf2"
+  [(set (match_operand:DF 0 "register_operand" "=f")
+       (float:DF (match_operand:SI 1 "memory_operand" "m")))]
+  "TARGET_FP"
+  "#"
+  "&& reload_completed"
+  [(set (match_dup 3) (match_dup 1))
+   (set (match_dup 2) (unspec:DI [(match_dup 3)] UNSPEC_CVTLQ))
+   (set (match_dup 0) (float:DF (match_dup 2)))]
+{
+  operands[1] = adjust_address (operands[1], SFmode, 0);
+  operands[2] = gen_rtx_REG (DImode, REGNO (operands[0]));
+  operands[3] = gen_rtx_REG (SFmode, REGNO (operands[0]));
+})
+
 (define_expand "floatditf2"
   [(use (match_operand:TF 0 "register_operand" ""))
    (use (match_operand:DI 1 "general_operand" ""))]
@@ -2748,9 +2770,12 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
    st%- %1,%0"
   [(set_attr "type" "fcpys,fld,fst")])
 
+;; Use register_operand for operand 1 to prevent compress_float_constant
+;; from doing something silly.  When optimizing we'll put things back 
+;; together anyway.
 (define_expand "extendsftf2"
   [(use (match_operand:TF 0 "register_operand" ""))
-   (use (match_operand:SF 1 "general_operand" ""))]
+   (use (match_operand:SF 1 "register_operand" ""))]
   "TARGET_HAS_XFLOATING_LIBS"
 {
   rtx tmp = gen_reg_rtx (DFmode);
@@ -2761,13 +2786,13 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
 
 (define_expand "extenddftf2"
   [(use (match_operand:TF 0 "register_operand" ""))
-   (use (match_operand:DF 1 "general_operand" ""))]
+   (use (match_operand:DF 1 "register_operand" ""))]
   "TARGET_HAS_XFLOATING_LIBS"
   "alpha_emit_xfloating_cvt (FLOAT_EXTEND, operands); DONE;")
 
 (define_insn "*truncdfsf2_ieee"
   [(set (match_operand:SF 0 "register_operand" "=&f")
-       (float_truncate:SF (match_operand:DF 1 "reg_or_fp0_operand" "fG")))]
+       (float_truncate:SF (match_operand:DF 1 "reg_or_0_operand" "fG")))]
   "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
   "cvt%-%,%/ %R1,%0"
   [(set_attr "type" "fadd")
@@ -2777,7 +2802,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
 
 (define_insn "truncdfsf2"
   [(set (match_operand:SF 0 "register_operand" "=f")
-       (float_truncate:SF (match_operand:DF 1 "reg_or_fp0_operand" "fG")))]
+       (float_truncate:SF (match_operand:DF 1 "reg_or_0_operand" "fG")))]
   "TARGET_FP"
   "cvt%-%,%/ %R1,%0"
   [(set_attr "type" "fadd")
@@ -2819,8 +2844,8 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
 
 (define_insn "*divsf3_ieee"
   [(set (match_operand:SF 0 "register_operand" "=&f")
-       (div:SF (match_operand:SF 1 "reg_or_fp0_operand" "fG")
-               (match_operand:SF 2 "reg_or_fp0_operand" "fG")))]
+       (div:SF (match_operand:SF 1 "reg_or_0_operand" "fG")
+               (match_operand:SF 2 "reg_or_0_operand" "fG")))]
   "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
   "div%,%/ %R1,%R2,%0"
   [(set_attr "type" "fdiv")
@@ -2831,8 +2856,8 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
 
 (define_insn "divsf3"
   [(set (match_operand:SF 0 "register_operand" "=f")
-       (div:SF (match_operand:SF 1 "reg_or_fp0_operand" "fG")
-               (match_operand:SF 2 "reg_or_fp0_operand" "fG")))]
+       (div:SF (match_operand:SF 1 "reg_or_0_operand" "fG")
+               (match_operand:SF 2 "reg_or_0_operand" "fG")))]
   "TARGET_FP"
   "div%,%/ %R1,%R2,%0"
   [(set_attr "type" "fdiv")
@@ -2843,8 +2868,8 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
 
 (define_insn "*divdf3_ieee"
   [(set (match_operand:DF 0 "register_operand" "=&f")
-       (div:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG")
-               (match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
+       (div:DF (match_operand:DF 1 "reg_or_0_operand" "fG")
+               (match_operand:DF 2 "reg_or_0_operand" "fG")))]
   "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
   "div%-%/ %R1,%R2,%0"
   [(set_attr "type" "fdiv")
@@ -2854,8 +2879,8 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
 
 (define_insn "divdf3"
   [(set (match_operand:DF 0 "register_operand" "=f")
-       (div:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG")
-               (match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
+       (div:DF (match_operand:DF 1 "reg_or_0_operand" "fG")
+               (match_operand:DF 2 "reg_or_0_operand" "fG")))]
   "TARGET_FP"
   "div%-%/ %R1,%R2,%0"
   [(set_attr "type" "fdiv")
@@ -2865,8 +2890,8 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
 
 (define_insn "*divdf_ext1"
   [(set (match_operand:DF 0 "register_operand" "=f")
-       (div:DF (float_extend:DF (match_operand:SF 1 "reg_or_fp0_operand" "fG"))
-               (match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
+       (div:DF (float_extend:DF (match_operand:SF 1 "reg_or_0_operand" "fG"))
+               (match_operand:DF 2 "reg_or_0_operand" "fG")))]
   "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
   "div%-%/ %R1,%R2,%0"
   [(set_attr "type" "fdiv")
@@ -2876,9 +2901,9 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
 
 (define_insn "*divdf_ext2"
   [(set (match_operand:DF 0 "register_operand" "=f")
-       (div:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG")
+       (div:DF (match_operand:DF 1 "reg_or_0_operand" "fG")
                (float_extend:DF
-                (match_operand:SF 2 "reg_or_fp0_operand" "fG"))))]
+                (match_operand:SF 2 "reg_or_0_operand" "fG"))))]
   "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
   "div%-%/ %R1,%R2,%0"
   [(set_attr "type" "fdiv")
@@ -2888,8 +2913,8 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
 
 (define_insn "*divdf_ext3"
   [(set (match_operand:DF 0 "register_operand" "=f")
-       (div:DF (float_extend:DF (match_operand:SF 1 "reg_or_fp0_operand" "fG"))
-               (float_extend:DF (match_operand:SF 2 "reg_or_fp0_operand" "fG"))))]
+       (div:DF (float_extend:DF (match_operand:SF 1 "reg_or_0_operand" "fG"))
+               (float_extend:DF (match_operand:SF 2 "reg_or_0_operand" "fG"))))]
   "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
   "div%-%/ %R1,%R2,%0"
   [(set_attr "type" "fdiv")
@@ -2906,8 +2931,8 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
 
 (define_insn "*mulsf3_ieee"
   [(set (match_operand:SF 0 "register_operand" "=&f")
-       (mult:SF (match_operand:SF 1 "reg_or_fp0_operand" "%fG")
-                (match_operand:SF 2 "reg_or_fp0_operand" "fG")))]
+       (mult:SF (match_operand:SF 1 "reg_or_0_operand" "%fG")
+                (match_operand:SF 2 "reg_or_0_operand" "fG")))]
   "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
   "mul%,%/ %R1,%R2,%0"
   [(set_attr "type" "fmul")
@@ -2917,8 +2942,8 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
 
 (define_insn "mulsf3"
   [(set (match_operand:SF 0 "register_operand" "=f")
-       (mult:SF (match_operand:SF 1 "reg_or_fp0_operand" "%fG")
-                (match_operand:SF 2 "reg_or_fp0_operand" "fG")))]
+       (mult:SF (match_operand:SF 1 "reg_or_0_operand" "%fG")
+                (match_operand:SF 2 "reg_or_0_operand" "fG")))]
   "TARGET_FP"
   "mul%,%/ %R1,%R2,%0"
   [(set_attr "type" "fmul")
@@ -2928,8 +2953,8 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
 
 (define_insn "*muldf3_ieee"
   [(set (match_operand:DF 0 "register_operand" "=&f")
-       (mult:DF (match_operand:DF 1 "reg_or_fp0_operand" "%fG")
-                (match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
+       (mult:DF (match_operand:DF 1 "reg_or_0_operand" "%fG")
+                (match_operand:DF 2 "reg_or_0_operand" "fG")))]
   "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
   "mul%-%/ %R1,%R2,%0"
   [(set_attr "type" "fmul")
@@ -2939,8 +2964,8 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
 
 (define_insn "muldf3"
   [(set (match_operand:DF 0 "register_operand" "=f")
-       (mult:DF (match_operand:DF 1 "reg_or_fp0_operand" "%fG")
-                (match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
+       (mult:DF (match_operand:DF 1 "reg_or_0_operand" "%fG")
+                (match_operand:DF 2 "reg_or_0_operand" "fG")))]
   "TARGET_FP"
   "mul%-%/ %R1,%R2,%0"
   [(set_attr "type" "fmul")
@@ -2951,8 +2976,8 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
 (define_insn "*muldf_ext1"
   [(set (match_operand:DF 0 "register_operand" "=f")
        (mult:DF (float_extend:DF
-                 (match_operand:SF 1 "reg_or_fp0_operand" "fG"))
-                (match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
+                 (match_operand:SF 1 "reg_or_0_operand" "fG"))
+                (match_operand:DF 2 "reg_or_0_operand" "fG")))]
   "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
   "mul%-%/ %R1,%R2,%0"
   [(set_attr "type" "fmul")
@@ -2963,9 +2988,9 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
 (define_insn "*muldf_ext2"
   [(set (match_operand:DF 0 "register_operand" "=f")
        (mult:DF (float_extend:DF
-                 (match_operand:SF 1 "reg_or_fp0_operand" "%fG"))
+                 (match_operand:SF 1 "reg_or_0_operand" "%fG"))
                 (float_extend:DF
-                 (match_operand:SF 2 "reg_or_fp0_operand" "fG"))))]
+                 (match_operand:SF 2 "reg_or_0_operand" "fG"))))]
   "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
   "mul%-%/ %R1,%R2,%0"
   [(set_attr "type" "fmul")
@@ -2982,8 +3007,8 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
 
 (define_insn "*subsf3_ieee"
   [(set (match_operand:SF 0 "register_operand" "=&f")
-       (minus:SF (match_operand:SF 1 "reg_or_fp0_operand" "fG")
-                 (match_operand:SF 2 "reg_or_fp0_operand" "fG")))]
+       (minus:SF (match_operand:SF 1 "reg_or_0_operand" "fG")
+                 (match_operand:SF 2 "reg_or_0_operand" "fG")))]
   "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
   "sub%,%/ %R1,%R2,%0"
   [(set_attr "type" "fadd")
@@ -2993,8 +3018,8 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
 
 (define_insn "subsf3"
   [(set (match_operand:SF 0 "register_operand" "=f")
-       (minus:SF (match_operand:SF 1 "reg_or_fp0_operand" "fG")
-                 (match_operand:SF 2 "reg_or_fp0_operand" "fG")))]
+       (minus:SF (match_operand:SF 1 "reg_or_0_operand" "fG")
+                 (match_operand:SF 2 "reg_or_0_operand" "fG")))]
   "TARGET_FP"
   "sub%,%/ %R1,%R2,%0"
   [(set_attr "type" "fadd")
@@ -3004,8 +3029,8 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
 
 (define_insn "*subdf3_ieee"
   [(set (match_operand:DF 0 "register_operand" "=&f")
-       (minus:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG")
-                 (match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
+       (minus:DF (match_operand:DF 1 "reg_or_0_operand" "fG")
+                 (match_operand:DF 2 "reg_or_0_operand" "fG")))]
   "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
   "sub%-%/ %R1,%R2,%0"
   [(set_attr "type" "fadd")
@@ -3015,8 +3040,8 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
 
 (define_insn "subdf3"
   [(set (match_operand:DF 0 "register_operand" "=f")
-       (minus:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG")
-                 (match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
+       (minus:DF (match_operand:DF 1 "reg_or_0_operand" "fG")
+                 (match_operand:DF 2 "reg_or_0_operand" "fG")))]
   "TARGET_FP"
   "sub%-%/ %R1,%R2,%0"
   [(set_attr "type" "fadd")
@@ -3027,8 +3052,8 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
 (define_insn "*subdf_ext1"
   [(set (match_operand:DF 0 "register_operand" "=f")
        (minus:DF (float_extend:DF
-                  (match_operand:SF 1 "reg_or_fp0_operand" "fG"))
-                 (match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
+                  (match_operand:SF 1 "reg_or_0_operand" "fG"))
+                 (match_operand:DF 2 "reg_or_0_operand" "fG")))]
   "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
   "sub%-%/ %R1,%R2,%0"
   [(set_attr "type" "fadd")
@@ -3038,9 +3063,9 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
 
 (define_insn "*subdf_ext2"
   [(set (match_operand:DF 0 "register_operand" "=f")
-       (minus:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG")
+       (minus:DF (match_operand:DF 1 "reg_or_0_operand" "fG")
                  (float_extend:DF
-                  (match_operand:SF 2 "reg_or_fp0_operand" "fG"))))]
+                  (match_operand:SF 2 "reg_or_0_operand" "fG"))))]
   "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
   "sub%-%/ %R1,%R2,%0"
   [(set_attr "type" "fadd")
@@ -3051,9 +3076,9 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
 (define_insn "*subdf_ext3"
   [(set (match_operand:DF 0 "register_operand" "=f")
        (minus:DF (float_extend:DF
-                  (match_operand:SF 1 "reg_or_fp0_operand" "fG"))
+                  (match_operand:SF 1 "reg_or_0_operand" "fG"))
                  (float_extend:DF
-                  (match_operand:SF 2 "reg_or_fp0_operand" "fG"))))]
+                  (match_operand:SF 2 "reg_or_0_operand" "fG"))))]
   "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
   "sub%-%/ %R1,%R2,%0"
   [(set_attr "type" "fadd")
@@ -3070,7 +3095,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
 
 (define_insn "*sqrtsf2_ieee"
   [(set (match_operand:SF 0 "register_operand" "=&f")
-       (sqrt:SF (match_operand:SF 1 "reg_or_fp0_operand" "fG")))]
+       (sqrt:SF (match_operand:SF 1 "reg_or_0_operand" "fG")))]
   "TARGET_FP && TARGET_FIX && alpha_fptm >= ALPHA_FPTM_SU"
   "sqrt%,%/ %R1,%0"
   [(set_attr "type" "fsqrt")
@@ -3081,7 +3106,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
 
 (define_insn "sqrtsf2"
   [(set (match_operand:SF 0 "register_operand" "=f")
-       (sqrt:SF (match_operand:SF 1 "reg_or_fp0_operand" "fG")))]
+       (sqrt:SF (match_operand:SF 1 "reg_or_0_operand" "fG")))]
   "TARGET_FP && TARGET_FIX"
   "sqrt%,%/ %R1,%0"
   [(set_attr "type" "fsqrt")
@@ -3092,7 +3117,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
 
 (define_insn "*sqrtdf2_ieee"
   [(set (match_operand:DF 0 "register_operand" "=&f")
-       (sqrt:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG")))]
+       (sqrt:DF (match_operand:DF 1 "reg_or_0_operand" "fG")))]
   "TARGET_FP && TARGET_FIX && alpha_fptm >= ALPHA_FPTM_SU"
   "sqrt%-%/ %R1,%0"
   [(set_attr "type" "fsqrt")
@@ -3102,9 +3127,9 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
 
 (define_insn "sqrtdf2"
   [(set (match_operand:DF 0 "register_operand" "=f")
-       (sqrt:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG")))]
+       (sqrt:DF (match_operand:DF 1 "reg_or_0_operand" "fG")))]
   "TARGET_FP && TARGET_FIX"
-  "sqrt%-%/ %1,%0"
+  "sqrt%-%/ %R1,%0"
   [(set_attr "type" "fsqrt")
    (set_attr "trap" "yes")
    (set_attr "round_suffix" "normal")
@@ -3167,7 +3192,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
                          (match_operand:DI 4 "reg_or_0_operand" "J,J,rJ,rJ")])
         (match_operand:QI 1 "add_operand" "rI,0,rI,0")
         (match_operand:QI 5 "add_operand" "0,rI,0,rI")))]
-  "(operands[3] == const0_rtx || operands[4] == const0_rtx)"
+  "(operands[3] == const0_rtx) ^ (operands[4] == const0_rtx)"
   "@
    cmov%C2 %r3,%1,%0
    cmov%D2 %r3,%5,%0
@@ -3183,7 +3208,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
                          (match_operand:DI 4 "reg_or_0_operand" "J,J,rJ,rJ")])
         (match_operand:HI 1 "add_operand" "rI,0,rI,0")
         (match_operand:HI 5 "add_operand" "0,rI,0,rI")))]
-  "(operands[3] == const0_rtx || operands[4] == const0_rtx)"
+  "(operands[3] == const0_rtx) ^ (operands[4] == const0_rtx)"
   "@
    cmov%C2 %r3,%1,%0
    cmov%D2 %r3,%5,%0
@@ -3199,7 +3224,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
                          (match_operand:DI 4 "reg_or_0_operand" "J,J,rJ,rJ")])
         (match_operand:SI 1 "add_operand" "rI,0,rI,0")
         (match_operand:SI 5 "add_operand" "0,rI,0,rI")))]
-  "(operands[3] == const0_rtx || operands[4] == const0_rtx)"
+  "(operands[3] == const0_rtx) ^ (operands[4] == const0_rtx)"
   "@
    cmov%C2 %r3,%1,%0
    cmov%D2 %r3,%5,%0
@@ -3215,7 +3240,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
                          (match_operand:DI 4 "reg_or_0_operand" "J,J,rJ,rJ")])
         (match_operand:DI 1 "add_operand" "rI,0,rI,0")
         (match_operand:DI 5 "add_operand" "0,rI,0,rI")))]
-  "(operands[3] == const0_rtx || operands[4] == const0_rtx)"
+  "(operands[3] == const0_rtx) ^ (operands[4] == const0_rtx)"
   "@
    cmov%C2 %r3,%1,%0
    cmov%D2 %r3,%5,%0
@@ -3477,7 +3502,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
                 (match_operand:HI 2 "reg_or_8bit_operand" "rI")))]
   "TARGET_MAX"
   "maxuw4 %r1,%2,%0"
-  [(set_attr "type" "shift")])
+  [(set_attr "type" "mvi")])
 
 (define_expand "smaxdi3"
   [(set (match_dup 3)
@@ -3662,8 +3687,8 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
 (define_insn "*cmpdf_ieee"
   [(set (match_operand:DF 0 "register_operand" "=&f")
        (match_operator:DF 1 "alpha_fp_comparison_operator"
-                          [(match_operand:DF 2 "reg_or_fp0_operand" "fG")
-                           (match_operand:DF 3 "reg_or_fp0_operand" "fG")]))]
+                          [(match_operand:DF 2 "reg_or_0_operand" "fG")
+                           (match_operand:DF 3 "reg_or_0_operand" "fG")]))]
   "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
   "cmp%-%C1%/ %R2,%R3,%0"
   [(set_attr "type" "fadd")
@@ -3673,21 +3698,9 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
 (define_insn "*cmpdf_internal"
   [(set (match_operand:DF 0 "register_operand" "=f")
        (match_operator:DF 1 "alpha_fp_comparison_operator"
-                          [(match_operand:DF 2 "reg_or_fp0_operand" "fG")
-                           (match_operand:DF 3 "reg_or_fp0_operand" "fG")]))]
-  "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
-  "cmp%-%C1%/ %R2,%R3,%0"
-  [(set_attr "type" "fadd")
-   (set_attr "trap" "yes")
-   (set_attr "trap_suffix" "su")])
-
-(define_insn "*cmpdf_ieee_ext1"
-  [(set (match_operand:DF 0 "register_operand" "=&f")
-       (match_operator:DF 1 "alpha_fp_comparison_operator"
-                          [(float_extend:DF
-                            (match_operand:SF 2 "reg_or_fp0_operand" "fG"))
-                           (match_operand:DF 3 "reg_or_fp0_operand" "fG")]))]
-  "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
+                          [(match_operand:DF 2 "reg_or_0_operand" "fG")
+                           (match_operand:DF 3 "reg_or_0_operand" "fG")]))]
+  "TARGET_FP"
   "cmp%-%C1%/ %R2,%R3,%0"
   [(set_attr "type" "fadd")
    (set_attr "trap" "yes")
@@ -3697,58 +3710,33 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
   [(set (match_operand:DF 0 "register_operand" "=f")
        (match_operator:DF 1 "alpha_fp_comparison_operator"
                           [(float_extend:DF
-                            (match_operand:SF 2 "reg_or_fp0_operand" "fG"))
-                           (match_operand:DF 3 "reg_or_fp0_operand" "fG")]))]
+                            (match_operand:SF 2 "reg_or_0_operand" "fG"))
+                           (match_operand:DF 3 "reg_or_0_operand" "fG")]))]
   "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
   "cmp%-%C1%/ %R2,%R3,%0"
   [(set_attr "type" "fadd")
    (set_attr "trap" "yes")
    (set_attr "trap_suffix" "su")])
 
-(define_insn "*cmpdf_ieee_ext2"
-  [(set (match_operand:DF 0 "register_operand" "=&f")
-       (match_operator:DF 1 "alpha_fp_comparison_operator"
-                          [(match_operand:DF 2 "reg_or_fp0_operand" "fG")
-                           (float_extend:DF
-                            (match_operand:SF 3 "reg_or_fp0_operand" "fG"))]))]
-  "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
-  "cmp%-%C1%/ %R2,%R3,%0"
-  [(set_attr "type" "fadd")
-   (set_attr "trap" "yes")
-   (set_attr "trap_suffix" "su")])
-
 (define_insn "*cmpdf_ext2"
   [(set (match_operand:DF 0 "register_operand" "=f")
        (match_operator:DF 1 "alpha_fp_comparison_operator"
-                          [(match_operand:DF 2 "reg_or_fp0_operand" "fG")
+                          [(match_operand:DF 2 "reg_or_0_operand" "fG")
                            (float_extend:DF
-                            (match_operand:SF 3 "reg_or_fp0_operand" "fG"))]))]
+                            (match_operand:SF 3 "reg_or_0_operand" "fG"))]))]
   "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
   "cmp%-%C1%/ %R2,%R3,%0"
   [(set_attr "type" "fadd")
    (set_attr "trap" "yes")
    (set_attr "trap_suffix" "su")])
 
-(define_insn "*cmpdf_ieee_ext3"
-  [(set (match_operand:DF 0 "register_operand" "=&f")
-       (match_operator:DF 1 "alpha_fp_comparison_operator"
-                          [(float_extend:DF
-                            (match_operand:SF 2 "reg_or_fp0_operand" "fG"))
-                           (float_extend:DF
-                            (match_operand:SF 3 "reg_or_fp0_operand" "fG"))]))]
-  "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
-  "cmp%-%C1%/ %R2,%R3,%0"
-  [(set_attr "type" "fadd")
-   (set_attr "trap" "yes")
-   (set_attr "trap_suffix" "su")])
-
 (define_insn "*cmpdf_ext3"
   [(set (match_operand:DF 0 "register_operand" "=f")
        (match_operator:DF 1 "alpha_fp_comparison_operator"
                           [(float_extend:DF
-                            (match_operand:SF 2 "reg_or_fp0_operand" "fG"))
+                            (match_operand:SF 2 "reg_or_0_operand" "fG"))
                            (float_extend:DF
-                            (match_operand:SF 3 "reg_or_fp0_operand" "fG"))]))]
+                            (match_operand:SF 3 "reg_or_0_operand" "fG"))]))]
   "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
   "cmp%-%C1%/ %R2,%R3,%0"
   [(set_attr "type" "fadd")
@@ -3759,10 +3747,10 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
   [(set (match_operand:DF 0 "register_operand" "=f,f")
        (if_then_else:DF
         (match_operator 3 "signed_comparison_operator"
-                        [(match_operand:DF 4 "reg_or_fp0_operand" "fG,fG")
-                         (match_operand:DF 2 "fp0_operand" "G,G")])
-        (match_operand:DF 1 "reg_or_fp0_operand" "fG,0")
-        (match_operand:DF 5 "reg_or_fp0_operand" "0,fG")))]
+                        [(match_operand:DF 4 "reg_or_0_operand" "fG,fG")
+                         (match_operand:DF 2 "const0_operand" "G,G")])
+        (match_operand:DF 1 "reg_or_0_operand" "fG,0")
+        (match_operand:DF 5 "reg_or_0_operand" "0,fG")))]
   "TARGET_FP"
   "@
    fcmov%C3 %R4,%R1,%0
@@ -3773,10 +3761,10 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
   [(set (match_operand:SF 0 "register_operand" "=f,f")
        (if_then_else:SF
         (match_operator 3 "signed_comparison_operator"
-                        [(match_operand:DF 4 "reg_or_fp0_operand" "fG,fG")
-                         (match_operand:DF 2 "fp0_operand" "G,G")])
-        (match_operand:SF 1 "reg_or_fp0_operand" "fG,0")
-        (match_operand:SF 5 "reg_or_fp0_operand" "0,fG")))]
+                        [(match_operand:DF 4 "reg_or_0_operand" "fG,fG")
+                         (match_operand:DF 2 "const0_operand" "G,G")])
+        (match_operand:SF 1 "reg_or_0_operand" "fG,0")
+        (match_operand:SF 5 "reg_or_0_operand" "0,fG")))]
   "TARGET_FP"
   "@
    fcmov%C3 %R4,%R1,%0
@@ -3787,11 +3775,11 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
   [(set (match_operand:DF 0 "register_operand" "=f,f")
        (if_then_else:DF
         (match_operator 3 "signed_comparison_operator"
-                        [(match_operand:DF 4 "reg_or_fp0_operand" "fG,fG")
-                         (match_operand:DF 2 "fp0_operand" "G,G")])
-        (float_extend:DF (match_operand:SF 1 "reg_or_fp0_operand" "fG,0"))
-        (match_operand:DF 5 "reg_or_fp0_operand" "0,fG")))]
-  "TARGET_FP"
+                        [(match_operand:DF 4 "reg_or_0_operand" "fG,fG")
+                         (match_operand:DF 2 "const0_operand" "G,G")])
+        (float_extend:DF (match_operand:SF 1 "reg_or_0_operand" "fG,0"))
+        (match_operand:DF 5 "reg_or_0_operand" "0,fG")))]
+  "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
   "@
    fcmov%C3 %R4,%R1,%0
    fcmov%D3 %R4,%R5,%0"
@@ -3802,11 +3790,11 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
        (if_then_else:DF
         (match_operator 3 "signed_comparison_operator"
                         [(float_extend:DF
-                          (match_operand:SF 4 "reg_or_fp0_operand" "fG,fG"))
-                         (match_operand:DF 2 "fp0_operand" "G,G")])
-        (match_operand:DF 1 "reg_or_fp0_operand" "fG,0")
-        (match_operand:DF 5 "reg_or_fp0_operand" "0,fG")))]
-  "TARGET_FP"
+                          (match_operand:SF 4 "reg_or_0_operand" "fG,fG"))
+                         (match_operand:DF 2 "const0_operand" "G,G")])
+        (match_operand:DF 1 "reg_or_0_operand" "fG,0")
+        (match_operand:DF 5 "reg_or_0_operand" "0,fG")))]
+  "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
   "@
    fcmov%C3 %R4,%R1,%0
    fcmov%D3 %R4,%R5,%0"
@@ -3817,11 +3805,11 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
        (if_then_else:SF
         (match_operator 3 "signed_comparison_operator"
                         [(float_extend:DF
-                          (match_operand:SF 4 "reg_or_fp0_operand" "fG,fG"))
-                         (match_operand:DF 2 "fp0_operand" "G,G")])
-        (match_operand:SF 1 "reg_or_fp0_operand" "fG,0")
-        (match_operand:SF 5 "reg_or_fp0_operand" "0,fG")))]
-  "TARGET_FP"
+                          (match_operand:SF 4 "reg_or_0_operand" "fG,fG"))
+                         (match_operand:DF 2 "const0_operand" "G,G")])
+        (match_operand:SF 1 "reg_or_0_operand" "fG,0")
+        (match_operand:SF 5 "reg_or_0_operand" "0,fG")))]
+  "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
   "@
    fcmov%C3 %R4,%R1,%0
    fcmov%D3 %R4,%R5,%0"
@@ -3832,20 +3820,20 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
        (if_then_else:DF
         (match_operator 3 "signed_comparison_operator"
                         [(float_extend:DF
-                          (match_operand:SF 4 "reg_or_fp0_operand" "fG,fG"))
-                         (match_operand:DF 2 "fp0_operand" "G,G")])
-        (float_extend:DF (match_operand:SF 1 "reg_or_fp0_operand" "fG,0"))
-        (match_operand:DF 5 "reg_or_fp0_operand" "0,fG")))]
-  "TARGET_FP"
+                          (match_operand:SF 4 "reg_or_0_operand" "fG,fG"))
+                         (match_operand:DF 2 "const0_operand" "G,G")])
+        (float_extend:DF (match_operand:SF 1 "reg_or_0_operand" "fG,0"))
+        (match_operand:DF 5 "reg_or_0_operand" "0,fG")))]
+  "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
   "@
    fcmov%C3 %R4,%R1,%0
    fcmov%D3 %R4,%R5,%0"
   [(set_attr "type" "fcmov")])
 
-(define_expand "maxdf3"
+(define_expand "smaxdf3"
   [(set (match_dup 3)
-       (le:DF (match_operand:DF 1 "reg_or_fp0_operand" "")
-              (match_operand:DF 2 "reg_or_fp0_operand" "")))
+       (le:DF (match_operand:DF 1 "reg_or_0_operand" "")
+              (match_operand:DF 2 "reg_or_0_operand" "")))
    (set (match_operand:DF 0 "register_operand" "")
        (if_then_else:DF (eq (match_dup 3) (match_dup 4))
                         (match_dup 1) (match_dup 2)))]
@@ -3855,10 +3843,10 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
   operands[4] = CONST0_RTX (DFmode);
 })
 
-(define_expand "mindf3"
+(define_expand "smindf3"
   [(set (match_dup 3)
-       (lt:DF (match_operand:DF 1 "reg_or_fp0_operand" "")
-              (match_operand:DF 2 "reg_or_fp0_operand" "")))
+       (lt:DF (match_operand:DF 1 "reg_or_0_operand" "")
+              (match_operand:DF 2 "reg_or_0_operand" "")))
    (set (match_operand:DF 0 "register_operand" "")
        (if_then_else:DF (ne (match_dup 3) (match_dup 4))
                         (match_dup 1) (match_dup 2)))]
@@ -3868,27 +3856,27 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
   operands[4] = CONST0_RTX (DFmode);
 })
 
-(define_expand "maxsf3"
+(define_expand "smaxsf3"
   [(set (match_dup 3)
-       (le:DF (float_extend:DF (match_operand:SF 1 "reg_or_fp0_operand" ""))
-              (float_extend:DF (match_operand:SF 2 "reg_or_fp0_operand" ""))))
+       (le:DF (float_extend:DF (match_operand:SF 1 "reg_or_0_operand" ""))
+              (float_extend:DF (match_operand:SF 2 "reg_or_0_operand" ""))))
    (set (match_operand:SF 0 "register_operand" "")
        (if_then_else:SF (eq (match_dup 3) (match_dup 4))
                         (match_dup 1) (match_dup 2)))]
-  "TARGET_FP"
+  "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
 {
   operands[3] = gen_reg_rtx (DFmode);
   operands[4] = CONST0_RTX (DFmode);
 })
 
-(define_expand "minsf3"
+(define_expand "sminsf3"
   [(set (match_dup 3)
-       (lt:DF (float_extend:DF (match_operand:SF 1 "reg_or_fp0_operand" ""))
-              (float_extend:DF (match_operand:SF 2 "reg_or_fp0_operand" ""))))
+       (lt:DF (float_extend:DF (match_operand:SF 1 "reg_or_0_operand" ""))
+              (float_extend:DF (match_operand:SF 2 "reg_or_0_operand" ""))))
    (set (match_operand:SF 0 "register_operand" "")
        (if_then_else:SF (ne (match_dup 3) (match_dup 4))
                      (match_dup 1) (match_dup 2)))]
-  "TARGET_FP"
+  "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
 {
   operands[3] = gen_reg_rtx (DFmode);
   operands[4] = CONST0_RTX (DFmode);
@@ -3898,8 +3886,8 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
   [(set (pc)
        (if_then_else
         (match_operator 1 "signed_comparison_operator"
-                        [(match_operand:DF 2 "reg_or_fp0_operand" "fG")
-                         (match_operand:DF 3 "fp0_operand" "G")])
+                        [(match_operand:DF 2 "reg_or_0_operand" "fG")
+                         (match_operand:DF 3 "const0_operand" "G")])
         (label_ref (match_operand 0 "" ""))
         (pc)))]
   "TARGET_FP"
@@ -3911,8 +3899,8 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
        (if_then_else
         (match_operator 1 "signed_comparison_operator"
                         [(float_extend:DF
-                          (match_operand:SF 2 "reg_or_fp0_operand" "fG"))
-                         (match_operand:DF 3 "fp0_operand" "G")])
+                          (match_operand:SF 2 "reg_or_0_operand" "fG"))
+                         (match_operand:DF 3 "const0_operand" "G")])
         (label_ref (match_operand 0 "" ""))
         (pc)))]
   "TARGET_FP"
@@ -3922,206 +3910,53 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
 ;; These are the main define_expand's used to make conditional branches
 ;; and compares.
 
-(define_expand "cmpdf"
-  [(set (cc0) (compare (match_operand:DF 0 "reg_or_fp0_operand" "")
-                      (match_operand:DF 1 "reg_or_fp0_operand" "")))]
+(define_expand "cbranchdf4"
+  [(use (match_operator 0 "alpha_cbranch_operator"
+         [(match_operand:DF 1 "reg_or_0_operand" "")
+          (match_operand:DF 2 "reg_or_0_operand" "")]))
+   (use (match_operand 3 ""))]
   "TARGET_FP"
-{
-  alpha_compare.op0 = operands[0];
-  alpha_compare.op1 = operands[1];
-  alpha_compare.fp_p = 1;
-  DONE;
-})
+  { alpha_emit_conditional_branch (operands, DFmode); DONE; })
 
-(define_expand "cmptf"
-  [(set (cc0) (compare (match_operand:TF 0 "general_operand" "")
-                      (match_operand:TF 1 "general_operand" "")))]
+(define_expand "cbranchtf4"
+  [(use (match_operator 0 "alpha_cbranch_operator"
+         [(match_operand:TF 1 "general_operand")
+          (match_operand:TF 2 "general_operand")]))
+   (use (match_operand 3 ""))]
   "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 "general_operand" "")
-                      (match_operand:DI 1 "general_operand" "")))]
-  ""
-{
-  alpha_compare.op0 = operands[0];
-  alpha_compare.op1 = operands[1];
-  alpha_compare.fp_p = 0;
-  DONE;
-})
-
-(define_expand "beq"
-  [(set (pc)
-       (if_then_else (match_dup 1)
-                     (label_ref (match_operand 0 "" ""))
-                     (pc)))]
-  ""
-  "{ operands[1] = alpha_emit_conditional_branch (EQ); }")
-
-(define_expand "bne"
-  [(set (pc)
-       (if_then_else (match_dup 1)
-                     (label_ref (match_operand 0 "" ""))
-                     (pc)))]
-  ""
-  "{ operands[1] = alpha_emit_conditional_branch (NE); }")
-
-(define_expand "blt"
-  [(set (pc)
-       (if_then_else (match_dup 1)
-                     (label_ref (match_operand 0 "" ""))
-                     (pc)))]
-  ""
-  "{ operands[1] = alpha_emit_conditional_branch (LT); }")
-
-(define_expand "ble"
-  [(set (pc)
-       (if_then_else (match_dup 1)
-                     (label_ref (match_operand 0 "" ""))
-                     (pc)))]
-  ""
-  "{ operands[1] = alpha_emit_conditional_branch (LE); }")
-
-(define_expand "bgt"
-  [(set (pc)
-       (if_then_else (match_dup 1)
-                     (label_ref (match_operand 0 "" ""))
-                     (pc)))]
-  ""
-  "{ operands[1] = alpha_emit_conditional_branch (GT); }")
-
-(define_expand "bge"
-  [(set (pc)
-       (if_then_else (match_dup 1)
-                     (label_ref (match_operand 0 "" ""))
-                     (pc)))]
-  ""
-  "{ operands[1] = alpha_emit_conditional_branch (GE); }")
-
-(define_expand "bltu"
-  [(set (pc)
-       (if_then_else (match_dup 1)
-                     (label_ref (match_operand 0 "" ""))
-                     (pc)))]
-  ""
-  "{ operands[1] = alpha_emit_conditional_branch (LTU); }")
-
-(define_expand "bleu"
-  [(set (pc)
-       (if_then_else (match_dup 1)
-                     (label_ref (match_operand 0 "" ""))
-                     (pc)))]
-  ""
-  "{ operands[1] = alpha_emit_conditional_branch (LEU); }")
-
-(define_expand "bgtu"
-  [(set (pc)
-       (if_then_else (match_dup 1)
-                     (label_ref (match_operand 0 "" ""))
-                     (pc)))]
-  ""
-  "{ operands[1] = alpha_emit_conditional_branch (GTU); }")
-
-(define_expand "bgeu"
-  [(set (pc)
-       (if_then_else (match_dup 1)
-                     (label_ref (match_operand 0 "" ""))
-                     (pc)))]
-  ""
-  "{ operands[1] = alpha_emit_conditional_branch (GEU); }")
+  { alpha_emit_conditional_branch (operands, TFmode); DONE; })
 
-(define_expand "bunordered"
-  [(set (pc)
-       (if_then_else (match_dup 1)
-                     (label_ref (match_operand 0 "" ""))
-                     (pc)))]
-  ""
-  "{ operands[1] = alpha_emit_conditional_branch (UNORDERED); }")
-
-(define_expand "bordered"
-  [(set (pc)
-       (if_then_else (match_dup 1)
-                     (label_ref (match_operand 0 "" ""))
-                     (pc)))]
-  ""
-  "{ operands[1] = alpha_emit_conditional_branch (ORDERED); }")
-
-(define_expand "seq"
-  [(set (match_operand:DI 0 "register_operand" "")
-       (match_dup 1))]
-  ""
-  "{ if ((operands[1] = alpha_emit_setcc (EQ)) == NULL_RTX) FAIL; }")
-
-(define_expand "sne"
-  [(set (match_operand:DI 0 "register_operand" "")
-       (match_dup 1))]
-  ""
-  "{ if ((operands[1] = alpha_emit_setcc (NE)) == NULL_RTX) FAIL; }")
-
-(define_expand "slt"
-  [(set (match_operand:DI 0 "register_operand" "")
-       (match_dup 1))]
-  ""
-  "{ if ((operands[1] = alpha_emit_setcc (LT)) == NULL_RTX) FAIL; }")
-
-(define_expand "sle"
-  [(set (match_operand:DI 0 "register_operand" "")
-       (match_dup 1))]
-  ""
-  "{ if ((operands[1] = alpha_emit_setcc (LE)) == NULL_RTX) FAIL; }")
-
-(define_expand "sgt"
-  [(set (match_operand:DI 0 "register_operand" "")
-       (match_dup 1))]
-  ""
-  "{ if ((operands[1] = alpha_emit_setcc (GT)) == NULL_RTX) FAIL; }")
-
-(define_expand "sge"
-  [(set (match_operand:DI 0 "register_operand" "")
-       (match_dup 1))]
-  ""
-  "{ if ((operands[1] = alpha_emit_setcc (GE)) == NULL_RTX) FAIL; }")
-
-(define_expand "sltu"
-  [(set (match_operand:DI 0 "register_operand" "")
-       (match_dup 1))]
-  ""
-  "{ if ((operands[1] = alpha_emit_setcc (LTU)) == NULL_RTX) FAIL; }")
-
-(define_expand "sleu"
-  [(set (match_operand:DI 0 "register_operand" "")
-       (match_dup 1))]
-  ""
-  "{ if ((operands[1] = alpha_emit_setcc (LEU)) == NULL_RTX) FAIL; }")
-
-(define_expand "sgtu"
-  [(set (match_operand:DI 0 "register_operand" "")
-       (match_dup 1))]
+(define_expand "cbranchdi4"
+  [(use (match_operator 0 "alpha_cbranch_operator"
+         [(match_operand:DI 1 "some_operand")
+          (match_operand:DI 2 "some_operand")]))
+   (use (match_operand 3 ""))]
   ""
-  "{ if ((operands[1] = alpha_emit_setcc (GTU)) == NULL_RTX) FAIL; }")
+  { alpha_emit_conditional_branch (operands, DImode); DONE; })
 
-(define_expand "sgeu"
-  [(set (match_operand:DI 0 "register_operand" "")
-       (match_dup 1))]
-  ""
-  "{ if ((operands[1] = alpha_emit_setcc (GEU)) == NULL_RTX) FAIL; }")
+(define_expand "cstoredf4"
+  [(use (match_operator:DI 1 "alpha_cbranch_operator"
+         [(match_operand:DF 2 "reg_or_0_operand")
+          (match_operand:DF 3 "reg_or_0_operand")]))
+   (clobber (match_operand:DI 0 "register_operand"))]
+  "TARGET_FP"
+  { if (!alpha_emit_setcc (operands, DFmode)) FAIL; else DONE; })
 
-(define_expand "sunordered"
-  [(set (match_operand:DI 0 "register_operand" "")
-       (match_dup 1))]
-  ""
-  "{ if ((operands[1] = alpha_emit_setcc (UNORDERED)) == NULL_RTX) FAIL; }")
+(define_expand "cstoretf4"
+  [(use (match_operator:DI 1 "alpha_cbranch_operator"
+         [(match_operand:TF 2 "general_operand")
+          (match_operand:TF 3 "general_operand")]))
+   (clobber (match_operand:DI 0 "register_operand"))]
+  "TARGET_HAS_XFLOATING_LIBS"
+  { if (!alpha_emit_setcc (operands, TFmode)) FAIL; else DONE; })
 
-(define_expand "sordered"
-  [(set (match_operand:DI 0 "register_operand" "")
-       (match_dup 1))]
+(define_expand "cstoredi4"
+  [(use (match_operator:DI 1 "alpha_cbranch_operator"
+         [(match_operand:DI 2 "some_operand")
+          (match_operand:DI 3 "some_operand")]))
+   (clobber (match_operand:DI 0 "register_operand"))]
   ""
-  "{ if ((operands[1] = alpha_emit_setcc (ORDERED)) == NULL_RTX) FAIL; }")
+  { if (!alpha_emit_setcc (operands, DImode)) FAIL; else DONE; })
 \f
 ;; These are the main define_expand's used to make conditional moves.
 
@@ -4208,11 +4043,11 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
      register since that is more likely to match (and to produce better code
      if both would).  */
 
-  if (code == EQ && GET_CODE (operands[3]) == CONST_INT
+  if (code == EQ && CONST_INT_P (operands[3])
       && rtx_equal_p (operands[4], operands[3]))
     operands[4] = operands[2];
 
-  else if (code == NE && GET_CODE (operands[3]) == CONST_INT
+  else if (code == NE && CONST_INT_P (operands[3])
           && rtx_equal_p (operands[5], operands[3]))
     operands[5] = operands[2];
 
@@ -4220,7 +4055,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
       || (extended_count (operands[2], DImode, unsignedp) >= 1
          && extended_count (operands[3], DImode, unsignedp) >= 1))
     {
-      if (GET_CODE (operands[3]) == CONST_INT)
+      if (CONST_INT_P (operands[3]))
        operands[7] = gen_rtx_PLUS (DImode, operands[2],
                                    GEN_INT (- INTVAL (operands[3])));
       else
@@ -4267,7 +4102,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
             && extended_count (operands[3], DImode, unsignedp) >= 1)))
     FAIL;
 
-  if (GET_CODE (operands[3]) == CONST_INT)
+  if (CONST_INT_P (operands[3]))
     tem = gen_rtx_PLUS (SImode, operands[2],
                        GEN_INT (- INTVAL (operands[3])));
   else
@@ -4278,100 +4113,6 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
                                operands[6], const0_rtx);
 })
 
-(define_split
-  [(set (pc)
-       (if_then_else
-        (match_operator 1 "comparison_operator"
-                        [(match_operand:DI 2 "reg_or_0_operand" "")
-                         (match_operand:DI 3 "reg_or_cint_operand" "")])
-        (label_ref (match_operand 0 "" ""))
-        (pc)))
-   (clobber (match_operand:DI 4 "register_operand" ""))]
-  "operands[3] != const0_rtx"
-  [(set (match_dup 4) (match_dup 5))
-   (set (pc) (if_then_else (match_dup 6) (label_ref (match_dup 0)) (pc)))]
-{
-  enum rtx_code code = GET_CODE (operands[1]);
-  int unsignedp = (code == GEU || code == LEU || code == GTU || code == LTU);
-
-  if (code == NE || code == EQ
-      || (extended_count (operands[2], DImode, unsignedp) >= 1
-         && extended_count (operands[3], DImode, unsignedp) >= 1))
-    {
-      if (GET_CODE (operands[3]) == CONST_INT)
-       operands[5] = gen_rtx_PLUS (DImode, operands[2],
-                                   GEN_INT (- INTVAL (operands[3])));
-      else
-       operands[5] = gen_rtx_MINUS (DImode, operands[2], operands[3]);
-
-      operands[6] = gen_rtx_fmt_ee (code, VOIDmode, operands[4], const0_rtx);
-    }
-
-  else if (code == EQ || code == LE || code == LT
-          || code == LEU || code == LTU)
-    {
-      operands[5] = gen_rtx_fmt_ee (code, DImode, operands[2], operands[3]);
-      operands[6] = gen_rtx_NE (VOIDmode, operands[4], const0_rtx);
-    }
-  else
-    {
-      operands[5] = gen_rtx_fmt_ee (reverse_condition (code), DImode,
-                                   operands[2], operands[3]);
-      operands[6] = gen_rtx_EQ (VOIDmode, operands[4], const0_rtx);
-    }
-})
-
-(define_split
-  [(set (pc)
-       (if_then_else
-        (match_operator 1 "comparison_operator"
-                        [(match_operand:SI 2 "reg_or_0_operand" "")
-                         (match_operand:SI 3 "const_int_operand" "")])
-        (label_ref (match_operand 0 "" ""))
-        (pc)))
-   (clobber (match_operand:DI 4 "register_operand" ""))]
-  "operands[3] != const0_rtx
-   && (GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)"
-  [(set (match_dup 4) (match_dup 5))
-   (set (pc) (if_then_else (match_dup 6) (label_ref (match_dup 0)) (pc)))]
-{
-  rtx tem;
-
-  if (GET_CODE (operands[3]) == CONST_INT)
-    tem = gen_rtx_PLUS (SImode, operands[2],
-                       GEN_INT (- INTVAL (operands[3])));
-  else
-    tem = gen_rtx_MINUS (SImode, operands[2], operands[3]);
-
-  operands[5] = gen_rtx_SIGN_EXTEND (DImode, tem);
-  operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[1]), VOIDmode,
-                               operands[4], const0_rtx);
-})
-
-;; We can convert such things as "a > 0xffff" to "t = a & ~ 0xffff; t != 0".
-;; This eliminates one, and sometimes two, insns when the AND can be done
-;; with a ZAP.
-(define_split
-  [(set (match_operand:DI 0 "register_operand" "")
-       (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" ""))]
-  "exact_log2 (INTVAL (operands[3]) + 1) >= 0
-   && (GET_CODE (operands[1]) == GTU
-       || GET_CODE (operands[1]) == LEU
-       || ((GET_CODE (operands[1]) == GT || GET_CODE (operands[1]) == LE)
-          && extended_count (operands[2], DImode, 1) > 0))"
-  [(set (match_dup 4) (and:DI (match_dup 2) (match_dup 5)))
-   (set (match_dup 0) (match_dup 6))]
-{
-  operands[5] = GEN_INT (~ INTVAL (operands[3]));
-  operands[6] = gen_rtx_fmt_ee (((GET_CODE (operands[1]) == GTU
-                                 || GET_CODE (operands[1]) == GT)
-                                ? NE : EQ),
-                               DImode, operands[4], const0_rtx);
-})
-
 ;; Prefer to use cmp and arithmetic when possible instead of a cmove.
 
 (define_split
@@ -4423,14 +4164,14 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
    (clobber (match_scratch:DI 5 "=r"))]
   ""
   "#"
-  "! no_new_pseudos || reload_completed"
+  ""
   [(set (match_dup 5)
        (match_op_dup:DI 1 [(match_dup 2) (const_int 0)]))
    (set (match_dup 0)
        (plus:DI (mult:DI (match_dup 5) (match_dup 3))
                 (match_dup 4)))]
 {
-  if (! no_new_pseudos)
+  if (can_create_pseudo_p ())
     operands[5] = gen_reg_rtx (DImode);
   else if (reg_overlap_mentioned_p (operands[5], operands[4]))
     operands[5] = operands[0];
@@ -4445,20 +4186,22 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
                   (match_operand:SI 3 "const48_operand" "I")
                   (const_int 0))
                 (match_operand:SI 4 "sext_add_operand" "rIO")))
-   (clobber (match_scratch:SI 5 "=r"))]
+   (clobber (match_scratch:DI 5 "=r"))]
   ""
   "#"
-  "! no_new_pseudos || reload_completed"
+  ""
   [(set (match_dup 5)
-       (match_op_dup:SI 1 [(match_dup 2) (const_int 0)]))
+       (match_op_dup:DI 1 [(match_dup 2) (const_int 0)]))
    (set (match_dup 0)
-       (plus:SI (mult:SI (match_dup 5) (match_dup 3))
+       (plus:SI (mult:SI (match_dup 6) (match_dup 3))
                 (match_dup 4)))]
 {
-  if (! no_new_pseudos)
+  if (can_create_pseudo_p ())
     operands[5] = gen_reg_rtx (DImode);
   else if (reg_overlap_mentioned_p (operands[5], operands[4]))
-    operands[5] = operands[0];
+    operands[5] = gen_lowpart (DImode, operands[0]);
+
+  operands[6] = gen_lowpart (SImode, operands[5]);
 })
 
 (define_insn_and_split "*cmp_sadd_sidi"
@@ -4471,20 +4214,22 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
                     (match_operand:SI 3 "const48_operand" "I")
                     (const_int 0))
                   (match_operand:SI 4 "sext_add_operand" "rIO"))))
-   (clobber (match_scratch:SI 5 "=r"))]
+   (clobber (match_scratch:DI 5 "=r"))]
   ""
   "#"
-  "! no_new_pseudos || reload_completed"
+  ""
   [(set (match_dup 5)
-       (match_op_dup:SI 1 [(match_dup 2) (const_int 0)]))
+       (match_op_dup:DI 1 [(match_dup 2) (const_int 0)]))
    (set (match_dup 0)
-       (sign_extend:DI (plus:SI (mult:SI (match_dup 5) (match_dup 3))
+       (sign_extend:DI (plus:SI (mult:SI (match_dup 6) (match_dup 3))
                                 (match_dup 4))))]
 {
-  if (! no_new_pseudos)
+  if (can_create_pseudo_p ())
     operands[5] = gen_reg_rtx (DImode);
   else if (reg_overlap_mentioned_p (operands[5], operands[4]))
     operands[5] = operands[0];
+
+  operands[6] = gen_lowpart (SImode, operands[5]);
 })
 
 (define_insn_and_split "*cmp_ssub_di"
@@ -4499,14 +4244,14 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
    (clobber (match_scratch:DI 5 "=r"))]
   ""
   "#"
-  "! no_new_pseudos || reload_completed"
+  ""
   [(set (match_dup 5)
        (match_op_dup:DI 1 [(match_dup 2) (const_int 0)]))
    (set (match_dup 0)
        (minus:DI (mult:DI (match_dup 5) (match_dup 3))
                  (match_dup 4)))]
 {
-  if (! no_new_pseudos)
+  if (can_create_pseudo_p ())
     operands[5] = gen_reg_rtx (DImode);
   else if (reg_overlap_mentioned_p (operands[5], operands[4]))
     operands[5] = operands[0];
@@ -4521,20 +4266,22 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
                    (match_operand:SI 3 "const48_operand" "I")
                    (const_int 0))
                  (match_operand:SI 4 "reg_or_8bit_operand" "rI")))
-   (clobber (match_scratch:SI 5 "=r"))]
+   (clobber (match_scratch:DI 5 "=r"))]
   ""
   "#"
-  "! no_new_pseudos || reload_completed"
+  ""
   [(set (match_dup 5)
-       (match_op_dup:SI 1 [(match_dup 2) (const_int 0)]))
+       (match_op_dup:DI 1 [(match_dup 2) (const_int 0)]))
    (set (match_dup 0)
-       (minus:SI (mult:SI (match_dup 5) (match_dup 3))
+       (minus:SI (mult:SI (match_dup 6) (match_dup 3))
                 (match_dup 4)))]
 {
-  if (! no_new_pseudos)
+  if (can_create_pseudo_p ())
     operands[5] = gen_reg_rtx (DImode);
   else if (reg_overlap_mentioned_p (operands[5], operands[4]))
-    operands[5] = operands[0];
+    operands[5] = gen_lowpart (DImode, operands[0]);
+
+  operands[6] = gen_lowpart (SImode, operands[5]);
 })
 
 (define_insn_and_split "*cmp_ssub_sidi"
@@ -4547,20 +4294,22 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
                      (match_operand:SI 3 "const48_operand" "I")
                      (const_int 0))
                    (match_operand:SI 4 "reg_or_8bit_operand" "rI"))))
-   (clobber (match_scratch:SI 5 "=r"))]
+   (clobber (match_scratch:DI 5 "=r"))]
   ""
   "#"
-  "! no_new_pseudos || reload_completed"
+  ""
   [(set (match_dup 5)
-       (match_op_dup:SI 1 [(match_dup 2) (const_int 0)]))
+       (match_op_dup:DI 1 [(match_dup 2) (const_int 0)]))
    (set (match_dup 0)
-       (sign_extend:DI (minus:SI (mult:SI (match_dup 5) (match_dup 3))
+       (sign_extend:DI (minus:SI (mult:SI (match_dup 6) (match_dup 3))
                                  (match_dup 4))))]
 {
-  if (! no_new_pseudos)
+  if (can_create_pseudo_p ())
     operands[5] = gen_reg_rtx (DImode);
   else if (reg_overlap_mentioned_p (operands[5], operands[4]))
     operands[5] = operands[0];
+
+  operands[6] = gen_lowpart (SImode, operands[5]);
 })
 \f
 ;; Here are the CALL and unconditional branch insns.  Calls on NT and OSF
@@ -4600,8 +4349,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
              (unspec [(reg:DI 29)] UNSPEC_SIBCALL)])]
   "TARGET_ABI_OSF"
 {
-  if (GET_CODE (operands[0]) != MEM)
-    abort ();
+  gcc_assert (MEM_P (operands[0]));
   operands[0] = XEXP (operands[0], 0);
 })
 
@@ -4612,8 +4360,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
              (clobber (reg:DI 26))])]
   ""
 {
-  if (GET_CODE (operands[0]) != MEM)
-    abort ();
+  gcc_assert (MEM_P (operands[0]));
 
   operands[0] = XEXP (operands[0], 0);
   if (! call_operand (operands[0], Pmode))
@@ -4626,11 +4373,10 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
              (clobber (reg:DI 26))])]
   ""
 {
-  if (GET_CODE (operands[0]) != MEM)
-    abort ();
+  gcc_assert (MEM_P (operands[0]));
 
   operands[0] = XEXP (operands[0], 0);
-  if (GET_CODE (operands[0]) != SYMBOL_REF && GET_CODE (operands[0]) != REG)
+  if (GET_CODE (operands[0]) != SYMBOL_REF && !REG_P (operands[0]))
     operands[0] = force_reg (DImode, operands[0]);
 })
 
@@ -4645,14 +4391,13 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
               (clobber (reg:DI 26))])]
    ""
 {
-  if (GET_CODE (operands[0]) != MEM)
-    abort ();
+  gcc_assert (MEM_P (operands[0]));
 
   /* Always load the address of the called function into a register;
      load the CIW in $25.  */
 
   operands[0] = XEXP (operands[0], 0);
-  if (GET_CODE (operands[0]) != REG)
+  if (!REG_P (operands[0]))
     operands[0] = force_reg (DImode, operands[0]);
 
   emit_move_insn (gen_rtx_REG (DImode, 25), operands[1]);
@@ -4672,8 +4417,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
              (clobber (reg:DI 27))])]
   ""
 {
-  if (GET_CODE (operands[0]) != MEM)
-    abort ();
+  gcc_assert (MEM_P (operands[0]));
 
   operands[0] = XEXP (operands[0], 0);
 
@@ -4684,11 +4428,9 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
   emit_move_insn (gen_rtx_REG (DImode, 25), operands[1]);
   if (GET_CODE (operands[0]) == SYMBOL_REF)
     {
-      rtx linkage = alpha_need_linkage (XSTR (operands[0], 0), 0);
+      alpha_need_linkage (XSTR (operands[0], 0), 0);
 
-      emit_move_insn (gen_rtx_REG (Pmode, 26), gen_rtx_MEM (Pmode, linkage));
-      operands[2]
-       = validize_mem (gen_rtx_MEM (Pmode, plus_constant (linkage, 8)));
+      operands[2] = const0_rtx;
     }
   else
     {
@@ -4728,8 +4470,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
              (unspec [(reg:DI 29)] UNSPEC_SIBCALL)])]
   "TARGET_ABI_OSF"
 {
-  if (GET_CODE (operands[1]) != MEM)
-    abort ();
+  gcc_assert (MEM_P (operands[1]));
   operands[1] = XEXP (operands[1], 0);
 })
 
@@ -4741,8 +4482,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
              (clobber (reg:DI 26))])]
   ""
 {
-  if (GET_CODE (operands[1]) != MEM)
-    abort ();
+  gcc_assert (MEM_P (operands[1]));
 
   operands[1] = XEXP (operands[1], 0);
   if (! call_operand (operands[1], Pmode))
@@ -4756,11 +4496,10 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
              (clobber (reg:DI 26))])]
   ""
 {
-  if (GET_CODE (operands[1]) != MEM)
-    abort ();
+  gcc_assert (MEM_P (operands[1]));
 
   operands[1] = XEXP (operands[1], 0);
-  if (GET_CODE (operands[1]) != SYMBOL_REF && GET_CODE (operands[1]) != REG)
+  if (GET_CODE (operands[1]) != SYMBOL_REF && !REG_P (operands[1]))
     operands[1] = force_reg (DImode, operands[1]);
 })
 
@@ -4774,8 +4513,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
              (clobber (reg:DI 27))])]
   ""
 {
-  if (GET_CODE (operands[1]) != MEM)
-    abort ();
+  gcc_assert (MEM_P (operands[1]));
 
   operands[1] = XEXP (operands[1], 0);
 
@@ -4786,11 +4524,9 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
   emit_move_insn (gen_rtx_REG (DImode, 25), operands[2]);
   if (GET_CODE (operands[1]) == SYMBOL_REF)
     {
-      rtx linkage = alpha_need_linkage (XSTR (operands[1], 0), 0);
+      alpha_need_linkage (XSTR (operands[1], 0), 0);
 
-      emit_move_insn (gen_rtx_REG (Pmode, 26), gen_rtx_MEM (Pmode, linkage));
-      operands[3]
-       = validize_mem (gen_rtx_MEM (Pmode, plus_constant (linkage, 8)));
+      operands[3] = const0_rtx;
     }
   else
     {
@@ -4808,16 +4544,29 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
              (clobber (reg:DI 26))])]
   ""
 {
-  if (GET_CODE (operands[1]) != MEM)
-    abort ();
+  gcc_assert (MEM_P (operands[1]));
 
   operands[1] = XEXP (operands[1], 0);
-  if (GET_CODE (operands[1]) != REG)
+  if (!REG_P (operands[1]))
     operands[1] = force_reg (DImode, operands[1]);
 
   emit_move_insn (gen_rtx_REG (DImode, 25), operands[2]);
 })
 
+(define_insn "*call_osf_1_er_noreturn"
+  [(call (mem:DI (match_operand:DI 0 "call_operand" "c,R,s"))
+        (match_operand 1 "" ""))
+   (use (reg:DI 29))
+   (clobber (reg:DI 26))]
+  "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF
+   && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
+  "@
+   jsr $26,($27),0
+   bsr $26,%0\t\t!samegp
+   ldq $27,%0($29)\t\t!literal!%#\;jsr $26,($27),%0\t\t!lituse_jsr!%#"
+  [(set_attr "type" "jsr")
+   (set_attr "length" "*,*,8")])
+
 (define_insn "*call_osf_1_er"
   [(call (mem:DI (match_operand:DI 0 "call_operand" "c,R,s"))
         (match_operand 1 "" ""))
@@ -4826,7 +4575,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
   "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
   "@
    jsr $26,(%0),0\;ldah $29,0($26)\t\t!gpdisp!%*\;lda $29,0($29)\t\t!gpdisp!%*
-   bsr $26,$%0..ng
+   bsr $26,%0\t\t!samegp
    ldq $27,%0($29)\t\t!literal!%#\;jsr $26,($27),%0\t\t!lituse_jsr!%#\;ldah $29,0($26)\t\t!gpdisp!%*\;lda $29,0($29)\t\t!gpdisp!%*"
   [(set_attr "type" "jsr")
    (set_attr "length" "12,*,16")])
@@ -4839,15 +4588,16 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
              (use (reg:DI 29))
              (clobber (reg:DI 26))])]
   "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF && reload_completed
-   && ! current_file_function_operand (operands[0], Pmode)
-   && peep2_regno_dead_p (1, 29)"
+   && ! samegp_function_operand (operands[0], Pmode)
+   && (peep2_regno_dead_p (1, 29)
+       || find_reg_note (insn, REG_NORETURN, NULL_RTX))"
   [(parallel [(call (mem:DI (match_dup 2))
                    (match_dup 1))
-             (set (reg:DI 26) (plus:DI (pc) (const_int 4)))
-             (unspec_volatile [(reg:DI 29)] UNSPECV_BLOCKAGE)
+             (use (reg:DI 29))
              (use (match_dup 0))
-             (use (match_dup 3))])]
-{
+             (use (match_dup 3))
+             (clobber (reg:DI 26))])]
+{
   if (CONSTANT_P (operands[0]))
     {
       operands[2] = gen_rtx_REG (Pmode, 27);
@@ -4869,18 +4619,18 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
              (use (reg:DI 29))
              (clobber (reg:DI 26))])]
   "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF && reload_completed
-   && ! current_file_function_operand (operands[0], Pmode)
-   && ! peep2_regno_dead_p (1, 29)"
+   && ! samegp_function_operand (operands[0], Pmode)
+   && ! (peep2_regno_dead_p (1, 29)
+         || find_reg_note (insn, REG_NORETURN, NULL_RTX))"
   [(parallel [(call (mem:DI (match_dup 2))
                    (match_dup 1))
-             (set (reg:DI 26) (plus:DI (pc) (const_int 4)))
-             (unspec_volatile [(reg:DI 29)] UNSPECV_BLOCKAGE)
+             (set (match_dup 5)
+                  (unspec:DI [(match_dup 5) (match_dup 3)] UNSPEC_LDGP1))
              (use (match_dup 0))
-             (use (match_dup 4))])
-   (set (reg:DI 29)
-       (unspec_volatile:DI [(reg:DI 26) (match_dup 3)] UNSPECV_LDGP1))
-   (set (reg:DI 29)
-       (unspec:DI [(reg:DI 29) (match_dup 3)] UNSPEC_LDGP2))]
+             (use (match_dup 4))
+             (clobber (reg:DI 26))])
+   (set (match_dup 5)
+       (unspec:DI [(match_dup 5) (match_dup 3)] UNSPEC_LDGP2))]
 {
   if (CONSTANT_P (operands[0]))
     {
@@ -4896,22 +4646,35 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
       operands[4] = const0_rtx;
     }
   operands[3] = GEN_INT (alpha_next_sequence_number++);
+  operands[5] = pic_offset_table_rtx;
 })
 
-;; We add a blockage unspec_volatile to prevent insns from moving down
-;; from above the call to in between the call and the ldah gpdisp.
-
-(define_insn "*call_osf_2_er"
+(define_insn "*call_osf_2_er_nogp"
   [(call (mem:DI (match_operand:DI 0 "register_operand" "c"))
         (match_operand 1 "" ""))
-   (set (reg:DI 26) (plus:DI (pc) (const_int 4)))
-   (unspec_volatile [(reg:DI 29)] UNSPECV_BLOCKAGE)
+   (use (reg:DI 29))
    (use (match_operand 2 "" ""))
-   (use (match_operand 3 "const_int_operand" ""))]
+   (use (match_operand 3 "const_int_operand" ""))
+   (clobber (reg:DI 26))]
   "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
   "jsr $26,(%0),%2%J3"
   [(set_attr "type" "jsr")])
 
+(define_insn "*call_osf_2_er"
+  [(call (mem:DI (match_operand:DI 0 "register_operand" "c"))
+        (match_operand 1 "" ""))
+   (set (reg:DI 29)
+       (unspec:DI [(reg:DI 29) (match_operand 4 "const_int_operand" "")]
+                  UNSPEC_LDGP1))
+   (use (match_operand 2 "" ""))
+   (use (match_operand 3 "const_int_operand" ""))
+   (clobber (reg:DI 26))]
+  "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
+  "jsr $26,(%0),%2%J3\;ldah $29,0($26)\t\t!gpdisp!%4"
+  [(set_attr "type" "jsr")
+   (set_attr "cannot_copy" "true")
+   (set_attr "length" "8")])
+
 (define_insn "*call_osf_1_noreturn"
   [(call (mem:DI (match_operand:DI 0 "call_operand" "c,R,s"))
         (match_operand 1 "" ""))
@@ -4939,19 +4702,19 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
   [(set_attr "type" "jsr")
    (set_attr "length" "12,*,16")])
 
-;; Note that the DEC assembler expands "jmp foo" with $at, which
-;; doesn't do what we want.
 (define_insn "*sibcall_osf_1_er"
   [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "R,s"))
         (match_operand 1 "" ""))
    (unspec [(reg:DI 29)] UNSPEC_SIBCALL)]
   "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
   "@
-   br $31,$%0..ng
+   br $31,%0\t\t!samegp
    ldq $27,%0($29)\t\t!literal!%#\;jmp $31,($27),%0\t\t!lituse_jsr!%#"
   [(set_attr "type" "jsr")
    (set_attr "length" "*,8")])
 
+;; Note that the DEC assembler expands "jmp foo" with $at, which
+;; doesn't do what we want.
 (define_insn "*sibcall_osf_1"
   [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "R,s"))
         (match_operand 1 "" ""))
@@ -4975,17 +4738,30 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
   [(set_attr "type" "jsr")
    (set_attr "length" "*,*,12")])
 
+; GAS relies on the order and position of instructions output below in order
+; to generate relocs for VMS link to potentially optimize the call.
+; Please do not molest.
 (define_insn "*call_vms_1"
   [(call (mem:DI (match_operand:DI 0 "call_operand" "r,s"))
         (match_operand 1 "" ""))
-   (use (match_operand:DI 2 "nonimmediate_operand" "r,m"))
+   (use (match_operand:DI 2 "nonmemory_operand" "r,n"))
    (use (reg:DI 25))
    (use (reg:DI 26))
    (clobber (reg:DI 27))]
   "TARGET_ABI_OPEN_VMS"
-  "@
-   mov %2,$27\;jsr $26,0\;ldq $27,0($29)
-   ldq $27,%2\;jsr $26,%0\;ldq $27,0($29)"
+{
+  switch (which_alternative)
+    {
+    case 0:
+       return "mov %2,$27\;jsr $26,0\;ldq $27,0($29)";
+    case 1:
+       operands [2] = alpha_use_linkage (operands [0], cfun->decl, 1, 0);
+       operands [3] = alpha_use_linkage (operands [0], cfun->decl, 0, 0);
+       return "ldq $26,%3\;ldq $27,%2\;jsr $26,%0\;ldq $27,0($29)";
+    default:
+      gcc_unreachable ();
+    }
+}
   [(set_attr "type" "jsr")
    (set_attr "length" "12,16")])
 
@@ -5033,7 +4809,8 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
   ""
   ""
-  [(set_attr "length" "0")])
+  [(set_attr "length" "0")
+   (set_attr "type" "none")])
 
 (define_insn "jump"
   [(set (pc)
@@ -5100,17 +4877,78 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
   "jmp $31,(%0),0"
   [(set_attr "type" "ibr")])
 
-;; Cache flush.  Used by INITIALIZE_TRAMPOLINE.  0x86 is PAL_imb, but we don't
+;; Cache flush.  Used by alpha_trampoline_init.  0x86 is PAL_imb, but we don't
 ;; want to have to include pal.h in our .s file.
-;;
-;; Technically the type for call_pal is jsr, but we use that for determining
-;; if we need a GP.  Use ibr instead since it has the same EV5 scheduling
-;; characteristics.
 (define_insn "imb"
   [(unspec_volatile [(const_int 0)] UNSPECV_IMB)]
   ""
   "call_pal 0x86"
-  [(set_attr "type" "ibr")])
+  [(set_attr "type" "callpal")])
+
+;; BUGCHK is documented common to OSF/1 and VMS PALcode.
+;; NT does not document anything at 0x81 -- presumably it would generate
+;; the equivalent of SIGILL, but this isn't that important.
+;; ??? Presuming unicosmk uses either OSF/1 or VMS PALcode.
+(define_insn "trap"
+  [(trap_if (const_int 1) (const_int 0))]
+  "!TARGET_ABI_WINDOWS_NT"
+  "call_pal 0x81"
+  [(set_attr "type" "callpal")])
+
+;; For userland, we load the thread pointer from the TCB.
+;; For the kernel, we load the per-cpu private value.
+
+(define_insn "load_tp"
+  [(set (match_operand:DI 0 "register_operand" "=v")
+       (unspec:DI [(const_int 0)] UNSPEC_TP))]
+  "TARGET_ABI_OSF"
+{
+  if (TARGET_TLS_KERNEL)
+    return "call_pal 0x32";
+  else
+    return "call_pal 0x9e";
+}
+  [(set_attr "type" "callpal")])
+
+;; For completeness, and possibly a __builtin function, here's how to
+;; set the thread pointer.  Since we don't describe enough of this
+;; quantity for CSE, we have to use a volatile unspec, and then there's
+;; not much point in creating an R16_REG register class.
+
+(define_expand "set_tp"
+  [(set (reg:DI 16) (match_operand:DI 0 "input_operand" ""))
+   (unspec_volatile [(reg:DI 16)] UNSPECV_SET_TP)]
+  "TARGET_ABI_OSF"
+  "")
+
+(define_insn "*set_tp"
+  [(unspec_volatile [(reg:DI 16)] UNSPECV_SET_TP)]
+  "TARGET_ABI_OSF"
+{
+  if (TARGET_TLS_KERNEL)
+    return "call_pal 0x31";
+  else
+    return "call_pal 0x9f";
+}
+  [(set_attr "type" "callpal")])
+
+;; Special builtins for establishing and reverting VMS condition handlers.
+
+(define_expand "builtin_establish_vms_condition_handler"
+  [(set (reg:DI 0) (match_operand:DI 0 "register_operand" ""))
+   (use (match_operand:DI 1 "address_operand" ""))]
+  "TARGET_ABI_OPEN_VMS"
+{
+  alpha_expand_builtin_establish_vms_condition_handler (operands[0],
+                                                        operands[1]);
+})
+
+(define_expand "builtin_revert_vms_condition_handler"
+  [(set (reg:DI 0) (match_operand:DI 0 "register_operand" ""))]
+  "TARGET_ABI_OPEN_VMS"
+{
+  alpha_expand_builtin_revert_vms_condition_handler (operands[0]);
+})
 \f
 ;; Finally, we have the basic data motion insns.  The byte and word insns
 ;; are done via define_expand.  Start with the floating-point insns, since
@@ -5121,7 +4959,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
        (match_operand:SF 1 "input_operand" "fG,m,*rG,m,fG,*r"))]
   "TARGET_FPREGS && ! TARGET_FIX
    && (register_operand (operands[0], SFmode)
-       || reg_or_fp0_operand (operands[1], SFmode))"
+       || reg_or_0_operand (operands[1], SFmode))"
   "@
    cpys %R1,%R1,%0
    ld%, %0,%1
@@ -5136,7 +4974,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
        (match_operand:SF 1 "input_operand" "fG,m,*rG,m,fG,*r,*r,f"))]
   "TARGET_FPREGS && TARGET_FIX
    && (register_operand (operands[0], SFmode)
-       || reg_or_fp0_operand (operands[1], SFmode))"
+       || reg_or_0_operand (operands[1], SFmode))"
   "@
    cpys %R1,%R1,%0
    ld%, %0,%1
@@ -5153,7 +4991,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
        (match_operand:SF 1 "input_operand" "rG,m,r"))]
   "! TARGET_FPREGS
    && (register_operand (operands[0], SFmode)
-       || reg_or_fp0_operand (operands[1], SFmode))"
+       || reg_or_0_operand (operands[1], SFmode))"
   "@
    bis $31,%r1,%0
    ldl %0,%1
@@ -5165,7 +5003,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
        (match_operand:DF 1 "input_operand" "fG,m,*rG,m,fG,*r"))]
   "TARGET_FPREGS && ! TARGET_FIX
    && (register_operand (operands[0], DFmode)
-       || reg_or_fp0_operand (operands[1], DFmode))"
+       || reg_or_0_operand (operands[1], DFmode))"
   "@
    cpys %R1,%R1,%0
    ld%- %0,%1
@@ -5180,7 +5018,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
        (match_operand:DF 1 "input_operand" "fG,m,*rG,m,fG,*r,*r,f"))]
   "TARGET_FPREGS && TARGET_FIX
    && (register_operand (operands[0], DFmode)
-       || reg_or_fp0_operand (operands[1], DFmode))"
+       || reg_or_0_operand (operands[1], DFmode))"
   "@
    cpys %R1,%R1,%0
    ld%- %0,%1
@@ -5197,7 +5035,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
        (match_operand:DF 1 "input_operand" "rG,m,r"))]
   "! TARGET_FPREGS
    && (register_operand (operands[0], DFmode)
-       || reg_or_fp0_operand (operands[1], DFmode))"
+       || reg_or_0_operand (operands[1], DFmode))"
   "@
    bis $31,%r1,%0
    ldq %0,%1
@@ -5211,19 +5049,13 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
   [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o")
        (match_operand:TF 1 "input_operand" "roG,rG"))]
   "register_operand (operands[0], TFmode)
-   || reg_or_fp0_operand (operands[1], TFmode)"
+   || reg_or_0_operand (operands[1], TFmode)"
   "#"
   "reload_completed"
   [(set (match_dup 0) (match_dup 2))
    (set (match_dup 1) (match_dup 3))]
 {
-  alpha_split_tfmode_pair (operands);
-  if (reg_overlap_mentioned_p (operands[0], operands[3]))
-    {
-      rtx tmp;
-      tmp = operands[0], operands[0] = operands[1], operands[1] = tmp;
-      tmp = operands[2], operands[2] = operands[3], operands[3] = tmp;
-    }
+  alpha_split_tmode_pair (operands, TFmode, true); 
 })
 
 (define_expand "movsf"
@@ -5231,8 +5063,8 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
        (match_operand:SF 1 "general_operand" ""))]
   ""
 {
-  if (GET_CODE (operands[0]) == MEM
-      && ! reg_or_fp0_operand (operands[1], SFmode))
+  if (MEM_P (operands[0])
+      && ! reg_or_0_operand (operands[1], SFmode))
     operands[1] = force_reg (SFmode, operands[1]);
 })
 
@@ -5241,8 +5073,8 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
        (match_operand:DF 1 "general_operand" ""))]
   ""
 {
-  if (GET_CODE (operands[0]) == MEM
-      && ! reg_or_fp0_operand (operands[1], DFmode))
+  if (MEM_P (operands[0])
+      && ! reg_or_0_operand (operands[1], DFmode))
     operands[1] = force_reg (DFmode, operands[1]);
 })
 
@@ -5251,71 +5083,30 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
        (match_operand:TF 1 "general_operand" ""))]
   ""
 {
-  if (GET_CODE (operands[0]) == MEM
-      && ! reg_or_fp0_operand (operands[1], TFmode))
+  if (MEM_P (operands[0])
+      && ! reg_or_0_operand (operands[1], TFmode))
     operands[1] = force_reg (TFmode, operands[1]);
 })
 
-(define_insn "*movsi_nofix"
-  [(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_ABI_OSF || TARGET_ABI_UNICOSMK) && ! TARGET_FIX
-   && (register_operand (operands[0], SImode)
-       || reg_or_0_operand (operands[1], SImode))"
-  "@
-   bis $31,%r1,%0
-   lda %0,%1($31)
-   ldah %0,%h1($31)
-   ldl %0,%1
-   stl %r1,%0
-   cpys %R1,%R1,%0
-   ld%, %0,%1
-   st%, %R1,%0"
-  [(set_attr "type" "ilog,iadd,iadd,ild,ist,fcpys,fld,fst")])
-
-(define_insn "*movsi_fix"
-  [(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_ABI_OSF && TARGET_FIX
+(define_insn "*movsi"
+  [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,r,m")
+       (match_operand:SI 1 "input_operand" "rJ,K,L,n,m,rJ"))]
+  "(TARGET_ABI_OSF || TARGET_ABI_UNICOSMK)
    && (register_operand (operands[0], SImode)
        || reg_or_0_operand (operands[1], SImode))"
   "@
    bis $31,%r1,%0
    lda %0,%1($31)
    ldah %0,%h1($31)
+   #
    ldl %0,%1
-   stl %r1,%0
-   cpys %R1,%R1,%0
-   ld%, %0,%1
-   st%, %R1,%0
-   ftois %1,%0
-   itofs %1,%0"
-  [(set_attr "type" "ilog,iadd,iadd,ild,ist,fcpys,fld,fst,ftoi,itof")])
-
-(define_insn "*movsi_nt_vms_nofix"
-  [(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_ABI_WINDOWS_NT || TARGET_ABI_OPEN_VMS)
-    && !TARGET_FIX
-    && (register_operand (operands[0], SImode)
-        || reg_or_0_operand (operands[1], SImode))"
-  "@
-   bis $31,%1,%0
-   lda %0,%1
-   ldah %0,%h1
-   lda %0,%1
-   ldl %0,%1
-   stl %r1,%0
-   cpys %R1,%R1,%0
-   ld%, %0,%1
-   st%, %R1,%0"
-  [(set_attr "type" "ilog,iadd,iadd,ldsym,ild,ist,fcpys,fld,fst")])
+   stl %r1,%0"
+  [(set_attr "type" "ilog,iadd,iadd,multi,ild,ist")])
 
-(define_insn "*movsi_nt_vms_fix"
-  [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,r,m,*f,*f,m,r,*f")
-       (match_operand:SI 1 "input_operand" "rJ,K,L,s,m,rJ,*fJ,m,*f,*f,r"))]
+(define_insn "*movsi_nt_vms"
+  [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,r,r,m")
+       (match_operand:SI 1 "input_operand" "rJ,K,L,s,n,m,rJ"))]
   "(TARGET_ABI_WINDOWS_NT || TARGET_ABI_OPEN_VMS)
-    && TARGET_FIX
     && (register_operand (operands[0], SImode)
         || reg_or_0_operand (operands[1], SImode))"
   "@
@@ -5323,14 +5114,10 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
    lda %0,%1
    ldah %0,%h1
    lda %0,%1
+   #
    ldl %0,%1
-   stl %r1,%0
-   cpys %R1,%R1,%0
-   ld%, %0,%1
-   st%, %R1,%0
-   ftois %1,%0
-   itofs %1,%0"
-  [(set_attr "type" "ilog,iadd,iadd,ldsym,ild,ist,fcpys,fld,fst,ftoi,itof")])
+   stl %r1,%0"
+  [(set_attr "type" "ilog,iadd,iadd,ldsym,multi,ild,ist")])
 
 (define_insn "*movhi_nobwx"
   [(set (match_operand:HI 0 "register_operand" "=r,r")
@@ -5397,15 +5184,11 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
 
 (define_split
   [(set (match_operand:SI 0 "register_operand" "")
-       (match_operand:SI 1 "const_int_operand" ""))]
-  "! add_operand (operands[1], SImode)"
-  [(set (match_dup 0) (match_dup 2))
-   (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 3)))]
+       (match_operand:SI 1 "non_add_const_operand" ""))]
+  ""
+  [(const_int 0)]
 {
-  rtx tem
-    = alpha_emit_set_const (operands[0], SImode, INTVAL (operands[1]), 2);
-
-  if (tem == operands[0])
+  if (alpha_split_const_mov (SImode, operands))
     DONE;
   else
     FAIL;
@@ -5413,9 +5196,9 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
 
 ;; Split the load of an address into a four-insn sequence on Unicos/Mk.
 ;; Always generate a REG_EQUAL note for the last instruction to facilitate
-;; optimisations. If the symbolic operand is a label_ref, generate REG_LABEL
-;; notes and update LABEL_NUSES because this is not done automatically.
-;; Labels may be incorrectly deleted if we don't do this.
+;; optimizations. If the symbolic operand is a label_ref, generate
+;; REG_LABEL_OPERAND notes and update LABEL_NUSES because this is not done
+;; automatically.  Labels may be incorrectly deleted if we don't do this.
 ;;
 ;; Describing what the individual instructions do correctly is too complicated
 ;; so use UNSPECs for each of the three parts of an address.
@@ -5432,19 +5215,16 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
   emit_insn (gen_ashldi3 (operands[0], operands[0], GEN_INT (32)));
   insn2 = emit_insn (gen_umk_lalm (operands[0], operands[0], operands[1]));
   insn3 = emit_insn (gen_umk_lal (operands[0], operands[0], operands[1]));
-  REG_NOTES (insn3) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1],
-                                        REG_NOTES (insn3));
+  set_unique_reg_note (insn3, REG_EQUAL, operands[1]);
+
   if (GET_CODE (operands[1]) == LABEL_REF)
     {
       rtx label;
 
       label = XEXP (operands[1], 0);
-      REG_NOTES (insn1) = gen_rtx_EXPR_LIST (REG_LABEL, label,
-                                            REG_NOTES (insn1));
-      REG_NOTES (insn2) = gen_rtx_EXPR_LIST (REG_LABEL, label,
-                                            REG_NOTES (insn2));
-      REG_NOTES (insn3) = gen_rtx_EXPR_LIST (REG_LABEL, label,
-                                            REG_NOTES (insn3));
+      add_reg_note (insn1, REG_LABEL_OPERAND, label);
+      add_reg_note (insn2, REG_LABEL_OPERAND, label);
+      add_reg_note (insn3, REG_LABEL_OPERAND, label);
       LABEL_NUSES (label) += 3;
     }
   DONE;
@@ -5502,7 +5282,8 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
     return "lda %0,%2(%1)\t\t!gprel";
   else
     return "lda %0,%2(%1)\t\t!gprellow";
-})
+}
+  [(set_attr "usegp" "yes")])
 
 (define_split
   [(set (match_operand:DI 0 "register_operand" "")
@@ -5524,14 +5305,16 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
 
 (define_split
   [(match_operand 0 "some_small_symbolic_operand" "")]
-  "TARGET_EXPLICIT_RELOCS && reload_completed"
+  ""
   [(match_dup 0)]
   "operands[0] = split_small_symbolic_operand (operands[0]);")
 
+;; Accepts any symbolic, not just global, since function calls that
+;; don't go via bsr still use !literal in hopes of linker relaxation.
 (define_insn "movdi_er_high_g"
   [(set (match_operand:DI 0 "register_operand" "=r")
        (unspec:DI [(match_operand:DI 1 "register_operand" "r")
-                   (match_operand:DI 2 "global_symbolic_operand" "")
+                   (match_operand:DI 2 "symbolic_operand" "")
                    (match_operand 3 "const_int_operand" "")]
                   UNSPEC_LITERAL))]
   "TARGET_EXPLICIT_RELOCS"
@@ -5553,9 +5336,80 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
                    (const_int 0)] UNSPEC_LITERAL))]
   "operands[2] = pic_offset_table_rtx;")
 
+(define_insn "movdi_er_tlsgd"
+  [(set (match_operand:DI 0 "register_operand" "=r")
+       (unspec:DI [(match_operand:DI 1 "register_operand" "r")
+                   (match_operand:DI 2 "symbolic_operand" "")
+                   (match_operand 3 "const_int_operand" "")]
+                  UNSPEC_TLSGD))]
+  "HAVE_AS_TLS"
+{
+  if (INTVAL (operands[3]) == 0)
+    return "lda %0,%2(%1)\t\t!tlsgd";
+  else
+    return "lda %0,%2(%1)\t\t!tlsgd!%3";
+})
+
+(define_insn "movdi_er_tlsldm"
+  [(set (match_operand:DI 0 "register_operand" "=r")
+       (unspec:DI [(match_operand:DI 1 "register_operand" "r")
+                   (match_operand 2 "const_int_operand" "")]
+                  UNSPEC_TLSLDM))]
+  "HAVE_AS_TLS"
+{
+  if (INTVAL (operands[2]) == 0)
+    return "lda %0,%&(%1)\t\t!tlsldm";
+  else
+    return "lda %0,%&(%1)\t\t!tlsldm!%2";
+})
+
+(define_insn "*movdi_er_gotdtp"
+  [(set (match_operand:DI 0 "register_operand" "=r")
+       (unspec:DI [(match_operand:DI 1 "register_operand" "r")
+                   (match_operand:DI 2 "symbolic_operand" "")]
+                  UNSPEC_DTPREL))]
+  "HAVE_AS_TLS"
+  "ldq %0,%2(%1)\t\t!gotdtprel"
+  [(set_attr "type" "ild")
+   (set_attr "usegp" "yes")])
+
+(define_split
+  [(set (match_operand:DI 0 "register_operand" "")
+       (match_operand:DI 1 "gotdtp_symbolic_operand" ""))]
+  "HAVE_AS_TLS && reload_completed"
+  [(set (match_dup 0)
+       (unspec:DI [(match_dup 2)
+                   (match_dup 1)] UNSPEC_DTPREL))]
+{
+  operands[1] = XVECEXP (XEXP (operands[1], 0), 0, 0);
+  operands[2] = pic_offset_table_rtx;
+})
+
+(define_insn "*movdi_er_gottp"
+  [(set (match_operand:DI 0 "register_operand" "=r")
+       (unspec:DI [(match_operand:DI 1 "register_operand" "r")
+                   (match_operand:DI 2 "symbolic_operand" "")]
+                  UNSPEC_TPREL))]
+  "HAVE_AS_TLS"
+  "ldq %0,%2(%1)\t\t!gottprel"
+  [(set_attr "type" "ild")
+   (set_attr "usegp" "yes")])
+
+(define_split
+  [(set (match_operand:DI 0 "register_operand" "")
+       (match_operand:DI 1 "gottp_symbolic_operand" ""))]
+  "HAVE_AS_TLS && reload_completed"
+  [(set (match_dup 0)
+       (unspec:DI [(match_dup 2)
+                   (match_dup 1)] UNSPEC_TPREL))]
+{
+  operands[1] = XVECEXP (XEXP (operands[1], 0), 0, 0);
+  operands[2] = pic_offset_table_rtx;
+})
+
 (define_insn "*movdi_er_nofix"
-  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,r,r,m,*f,*f,Q")
-       (match_operand:DI 1 "input_operand" "rJ,K,L,T,s,m,rJ,*fJ,Q,*f"))]
+  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,r,r,r,m,*f,*f,Q")
+       (match_operand:DI 1 "input_operand" "rJ,K,L,T,s,n,m,rJ,*fJ,Q,*f"))]
   "TARGET_EXPLICIT_RELOCS && ! TARGET_FIX
    && (register_operand (operands[0], DImode)
        || reg_or_0_operand (operands[1], DImode))"
@@ -5565,20 +5419,22 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
    ldah %0,%h1($31)
    #
    #
+   #
    ldq%A1 %0,%1
    stq%A0 %r1,%0
    fmov %R1,%0
    ldt %0,%1
    stt %R1,%0"
-  [(set_attr "type" "ilog,iadd,iadd,iadd,ldsym,ild,ist,fcpys,fld,fst")])
+  [(set_attr "type" "ilog,iadd,iadd,iadd,ldsym,multi,ild,ist,fcpys,fld,fst")
+   (set_attr "usegp" "*,*,*,yes,*,*,*,*,*,*,*")])
 
 ;; The 'U' constraint matches symbolic operands on Unicos/Mk. Those should
 ;; have been split up by the rules above but we shouldn't reject the
 ;; possibility of them getting through.
 
 (define_insn "*movdi_nofix"
-  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,r,r,m,*f,*f,Q")
-       (match_operand:DI 1 "input_operand" "rJ,K,L,U,s,m,rJ,*fJ,Q,*f"))]
+  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,r,r,r,m,*f,*f,Q")
+       (match_operand:DI 1 "input_operand" "rJ,K,L,U,s,n,m,rJ,*fJ,Q,*f"))]
   "! TARGET_FIX
    && (register_operand (operands[0], DImode)
        || reg_or_0_operand (operands[1], DImode))"
@@ -5588,19 +5444,20 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
    ldah %0,%h1($31)
    laum %0,%t1($31)\;sll %0,32,%0\;lalm %0,%t1(%0)\;lal %0,%t1(%0)
    lda %0,%1
+   #
    ldq%A1 %0,%1
    stq%A0 %r1,%0
    cpys %R1,%R1,%0
    ldt %0,%1
    stt %R1,%0"
-  [(set_attr "type" "ilog,iadd,iadd,ldsym,ldsym,ild,ist,fcpys,fld,fst")
-   (set_attr "length" "*,*,*,16,*,*,*,*,*,*")])
+  [(set_attr "type" "ilog,iadd,iadd,ldsym,ldsym,multi,ild,ist,fcpys,fld,fst")
+   (set_attr "length" "*,*,*,16,*,*,*,*,*,*,*")])
 
 (define_insn "*movdi_er_fix"
   [(set (match_operand:DI 0 "nonimmediate_operand"
-                               "=r,r,r,r,r,r, m, *f,*f, Q, r,*f")
+                               "=r,r,r,r,r,r,r, m, *f,*f, Q, r,*f")
        (match_operand:DI 1 "input_operand"
-                               "rJ,K,L,T,s,m,rJ,*fJ, Q,*f,*f, r"))]
+                               "rJ,K,L,T,s,n,m,rJ,*fJ, Q,*f,*f, r"))]
   "TARGET_EXPLICIT_RELOCS && TARGET_FIX
    && (register_operand (operands[0], DImode)
        || reg_or_0_operand (operands[1], DImode))"
@@ -5610,6 +5467,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
    ldah %0,%h1($31)
    #
    #
+   #
    ldq%A1 %0,%1
    stq%A0 %r1,%0
    fmov %R1,%0
@@ -5617,11 +5475,12 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
    stt %R1,%0
    ftoit %1,%0
    itoft %1,%0"
-  [(set_attr "type" "ilog,iadd,iadd,iadd,ldsym,ild,ist,fcpys,fld,fst,ftoi,itof")])
+  [(set_attr "type" "ilog,iadd,iadd,iadd,ldsym,multi,ild,ist,fcpys,fld,fst,ftoi,itof")
+   (set_attr "usegp" "*,*,*,yes,*,*,*,*,*,*,*,*,*")])
 
 (define_insn "*movdi_fix"
-  [(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"))]
+  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,r,r,m,*f,*f,Q,r,*f")
+       (match_operand:DI 1 "input_operand" "rJ,K,L,s,n,m,rJ,*fJ,Q,*f,*f,r"))]
   "! TARGET_EXPLICIT_RELOCS && TARGET_FIX
    && (register_operand (operands[0], DImode)
        || reg_or_0_operand (operands[1], DImode))"
@@ -5630,6 +5489,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
    lda %0,%1($31)
    ldah %0,%h1($31)
    lda %0,%1
+   #
    ldq%A1 %0,%1
    stq%A0 %r1,%0
    cpys %R1,%R1,%0
@@ -5637,11 +5497,11 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
    stt %R1,%0
    ftoit %1,%0
    itoft %1,%0"
-  [(set_attr "type" "ilog,iadd,iadd,ldsym,ild,ist,fcpys,fld,fst,ftoi,itof")])
+  [(set_attr "type" "ilog,iadd,iadd,ldsym,multi,ild,ist,fcpys,fld,fst,ftoi,itof")])
 
 ;; VMS needs to set up "vms_base_regno" for unwinding.  This move
 ;; often appears dead to the life analysis code, at which point we
-;; abort for emitting dead prologue instructions.  Force this live.
+;; die for emitting dead prologue instructions.  Force this live.
 
 (define_insn "force_movdi"
   [(set (match_operand:DI 0 "register_operand" "=r")
@@ -5668,20 +5528,90 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
 
 (define_split
   [(set (match_operand:DI 0 "register_operand" "")
-       (match_operand:DI 1 "const_int_operand" ""))]
-  "! add_operand (operands[1], DImode)"
-  [(set (match_dup 0) (match_dup 2))
-   (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
+       (match_operand:DI 1 "non_add_const_operand" ""))]
+  ""
+  [(const_int 0)]
 {
-  rtx tem
-    = alpha_emit_set_const (operands[0], DImode, INTVAL (operands[1]), 2);
-
-  if (tem == operands[0])
+  if (alpha_split_const_mov (DImode, operands))
     DONE;
   else
     FAIL;
 })
 
+;; We need to prevent reload from splitting TImode moves, because it
+;; might decide to overwrite a pointer with the value it points to.
+;; In that case we have to do the loads in the appropriate order so
+;; that the pointer is not destroyed too early.
+
+(define_insn_and_split "*movti_internal"
+  [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
+        (match_operand:TI 1 "input_operand" "roJ,rJ"))]
+  "(register_operand (operands[0], TImode)
+    /* Prevent rematerialization of constants.  */
+    && ! CONSTANT_P (operands[1]))
+   || reg_or_0_operand (operands[1], TImode)"
+  "#"
+  "reload_completed"
+  [(set (match_dup 0) (match_dup 2))
+   (set (match_dup 1) (match_dup 3))]
+{
+  alpha_split_tmode_pair (operands, TImode, true);
+})
+
+(define_expand "movti"
+  [(set (match_operand:TI 0 "nonimmediate_operand" "")
+        (match_operand:TI 1 "general_operand" ""))]
+  ""
+{
+  if (MEM_P (operands[0])
+      && ! reg_or_0_operand (operands[1], TImode))
+    operands[1] = force_reg (TImode, operands[1]);
+
+  if (operands[1] == const0_rtx)
+    ;
+  /* We must put 64-bit constants in memory.  We could keep the
+     32-bit constants in TImode and rely on the splitter, but
+     this doesn't seem to be worth the pain.  */
+  else if (CONST_INT_P (operands[1])
+          || GET_CODE (operands[1]) == CONST_DOUBLE)
+    {
+      rtx in[2], out[2], target;
+
+      gcc_assert (can_create_pseudo_p ());
+
+      split_double (operands[1], &in[0], &in[1]);
+
+      if (in[0] == const0_rtx)
+       out[0] = const0_rtx;
+      else
+       {
+         out[0] = gen_reg_rtx (DImode);
+         emit_insn (gen_movdi (out[0], in[0]));
+       }
+
+      if (in[1] == const0_rtx)
+       out[1] = const0_rtx;
+      else
+       {
+         out[1] = gen_reg_rtx (DImode);
+         emit_insn (gen_movdi (out[1], in[1]));
+       }
+
+      if (!REG_P (operands[0]))
+       target = gen_reg_rtx (TImode);
+      else
+       target = operands[0];
+
+      emit_insn (gen_movdi (operand_subword (target, 0, 0, TImode), out[0]));
+      emit_insn (gen_movdi (operand_subword (target, 1, 0, TImode), out[1]));
+
+      if (target != operands[0])
+       emit_insn (gen_rtx_SET (VOIDmode, operands[0], target));
+
+      DONE;
+    }
+})
+
 ;; These are the partial-word cases.
 ;;
 ;; First we have the code to load an aligned word.  Operand 0 is the register
@@ -5694,7 +5624,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
 (define_expand "aligned_loadqi"
   [(set (match_operand:SI 3 "register_operand" "")
        (match_operand:SI 1 "memory_operand" ""))
-   (set (subreg:DI (match_operand:QI 0 "register_operand" "") 0)
+   (set (match_operand:DI 0 "register_operand" "")
        (zero_extract:DI (subreg:DI (match_dup 3) 0)
                         (const_int 8)
                         (match_operand:DI 2 "const_int_operand" "")))]
@@ -5705,7 +5635,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
 (define_expand "aligned_loadhi"
   [(set (match_operand:SI 3 "register_operand" "")
        (match_operand:SI 1 "memory_operand" ""))
-   (set (subreg:DI (match_operand:HI 0 "register_operand" "") 0)
+   (set (match_operand:DI 0 "register_operand" "")
        (zero_extract:DI (subreg:DI (match_dup 3) 0)
                         (const_int 16)
                         (match_operand:DI 2 "const_int_operand" "")))]
@@ -5721,7 +5651,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
 ;; operand 3 can overlap the input and output registers.
 
 (define_expand "unaligned_loadqi"
-  [(use (match_operand:QI 0 "register_operand" ""))
+  [(use (match_operand:DI 0 "register_operand" ""))
    (use (match_operand:DI 1 "address_operand" ""))
    (use (match_operand:DI 2 "register_operand" ""))
    (use (match_operand:DI 3 "register_operand" ""))]
@@ -5742,7 +5672,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
                        (const_int -8))))
    (set (match_operand:DI 3 "register_operand" "")
        (match_dup 1))
-   (set (subreg:DI (match_operand:QI 0 "register_operand" "") 0)
+   (set (match_operand:DI 0 "register_operand" "")
        (zero_extract:DI (match_dup 2)
                         (const_int 8)
                         (ashift:DI (match_dup 3) (const_int 3))))]
@@ -5755,7 +5685,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
                        (const_int -8))))
    (set (match_operand:DI 3 "register_operand" "")
        (match_dup 1))
-   (set (subreg:DI (match_operand:QI 0 "register_operand" "") 0)
+   (set (match_operand:DI 0 "register_operand" "")
        (zero_extract:DI (match_dup 2)
                         (const_int 8)
                         (minus:DI
@@ -5765,7 +5695,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
   "")
 
 (define_expand "unaligned_loadhi"
-  [(use (match_operand:QI 0 "register_operand" ""))
+  [(use (match_operand:DI 0 "register_operand" ""))
    (use (match_operand:DI 1 "address_operand" ""))
    (use (match_operand:DI 2 "register_operand" ""))
    (use (match_operand:DI 3 "register_operand" ""))]
@@ -5786,7 +5716,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
                        (const_int -8))))
    (set (match_operand:DI 3 "register_operand" "")
        (match_dup 1))
-   (set (subreg:DI (match_operand:QI 0 "register_operand" "") 0)
+   (set (match_operand:DI 0 "register_operand" "")
        (zero_extract:DI (match_dup 2)
                         (const_int 16)
                         (ashift:DI (match_dup 3) (const_int 3))))]
@@ -5799,7 +5729,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
                        (const_int -8))))
    (set (match_operand:DI 3 "register_operand" "")
        (plus:DI (match_dup 1) (const_int 1)))
-   (set (subreg:DI (match_operand:QI 0 "register_operand" "") 0)
+   (set (match_operand:DI 0 "register_operand" "")
        (zero_extract:DI (match_dup 2)
                         (const_int 16)
                         (minus:DI
@@ -5939,7 +5869,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
        (mem:DI (and:DI (match_operand:DI 0 "address_operand" "")
                        (const_int -8))))
    (set (match_operand:DI 2 "register_operand" "")
-       (plus:DI (match_dup 0) (const_int 1)))
+       (plus:DI (match_dup 5) (const_int 1)))
    (set (match_dup 3)
        (and:DI (not:DI (ashift:DI
                          (const_int 65535)
@@ -5954,7 +5884,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
    (set (mem:DI (and:DI (match_dup 0) (const_int -8)))
        (match_dup 4))]
   "WORDS_BIG_ENDIAN"
-  "")
+  "operands[5] = force_reg (DImode, operands[0]);")
 \f
 ;; Here are the define_expand's for QI and HI moves that use the above
 ;; patterns.  We have the normal sets, plus the ones that need scratch
@@ -5982,148 +5912,120 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
     DONE;
 })
 
-;; Here are the versions for reload.  Note that in the unaligned cases
-;; we know that the operand must not be a pseudo-register because stack
-;; slots are always aligned references.
-
-(define_expand "reload_inqi"
-  [(parallel [(match_operand:QI 0 "register_operand" "=r")
-             (match_operand:QI 1 "any_memory_operand" "m")
-             (match_operand:TI 2 "register_operand" "=&r")])]
-  "! TARGET_BWX"
+;; We need to hook into the extra support that we have for HImode 
+;; reloads when BWX insns are not available.
+(define_expand "movcqi"
+  [(set (match_operand:CQI 0 "nonimmediate_operand" "")
+       (match_operand:CQI 1 "general_operand" ""))]
+  "!TARGET_BWX"
 {
-  rtx scratch, seq;
-
-  if (GET_CODE (operands[1]) != MEM)
-    abort ();
-
-  if (aligned_memory_operand (operands[1], QImode))
+  if (GET_CODE (operands[0]) == CONCAT || GET_CODE (operands[1]) == CONCAT)
+    ;
+  else if (!any_memory_operand (operands[0], CQImode))
     {
-      seq = gen_reload_inqi_help (operands[0], operands[1],
-                                 gen_rtx_REG (SImode, REGNO (operands[2])));
+      if (!any_memory_operand (operands[1], CQImode))
+       {
+         emit_move_insn (gen_lowpart (HImode, operands[0]),
+                         gen_lowpart (HImode, operands[1]));
+         DONE;
+       }
+      if (aligned_memory_operand (operands[1], CQImode))
+       {
+         bool done;
+       do_aligned1:
+         operands[1] = gen_lowpart (HImode, operands[1]);
+       do_aligned2:
+         operands[0] = gen_lowpart (HImode, operands[0]);
+         done = alpha_expand_mov_nobwx (HImode, operands);
+         gcc_assert (done);
+         DONE;
+       }
     }
-  else
+  else if (aligned_memory_operand (operands[0], CQImode))
     {
-      rtx addr;
-
-      /* It is possible that one of the registers we got for operands[2]
-        might coincide with that of operands[0] (which is why we made
-        it TImode).  Pick the other one to use as our scratch.  */
-      if (REGNO (operands[0]) == REGNO (operands[2]))
-       scratch = gen_rtx_REG (DImode, REGNO (operands[2]) + 1);
-      else
-       scratch = gen_rtx_REG (DImode, REGNO (operands[2]));
-
-      addr = get_unaligned_address (operands[1], 0);
-      seq = gen_unaligned_loadqi (operands[0], addr, scratch,
-                         gen_rtx_REG (DImode, REGNO (operands[0])));
-      alpha_set_memflags (seq, operands[1]);
+      if (MEM_P (operands[1]))
+       {
+         rtx x = gen_reg_rtx (HImode);
+         emit_move_insn (gen_lowpart (CQImode, x), operands[1]);
+         operands[1] = x;
+         goto do_aligned2;
+       }
+      goto do_aligned1;
     }
-  emit_insn (seq);
+
+  gcc_assert (!reload_in_progress);
+  emit_move_complex_parts (operands[0], operands[1]);
   DONE;
 })
 
-(define_expand "reload_inhi"
-  [(parallel [(match_operand:HI 0 "register_operand" "=r")
-             (match_operand:HI 1 "any_memory_operand" "m")
+;; Here are the versions for reload.
+;; 
+;; The aligned input case is recognized early in alpha_secondary_reload
+;; in order to avoid allocating an unnecessary scratch register.
+;; 
+;; Note that in the unaligned cases we know that the operand must not be
+;; a pseudo-register because stack slots are always aligned references.
+
+(define_expand "reload_in<mode>"
+  [(parallel [(match_operand:RELOAD12 0 "register_operand" "=r")
+             (match_operand:RELOAD12 1 "any_memory_operand" "m")
              (match_operand:TI 2 "register_operand" "=&r")])]
-  "! TARGET_BWX"
+  "!TARGET_BWX"
 {
-  rtx scratch, seq;
-
-  if (GET_CODE (operands[1]) != MEM)
-    abort ();
+  rtx scratch, seq, addr;
+  unsigned regno = REGNO (operands[2]);
 
-  if (aligned_memory_operand (operands[1], HImode))
-    {
-      seq = gen_reload_inhi_help (operands[0], operands[1],
-                                 gen_rtx_REG (SImode, REGNO (operands[2])));
-    }
-  else
-    {
-      rtx addr;
+  /* It is possible that one of the registers we got for operands[2]
+     might coincide with that of operands[0] (which is why we made
+     it TImode).  Pick the other one to use as our scratch.  */
+  if (regno == REGNO (operands[0]))
+    regno++;
+  scratch = gen_rtx_REG (DImode, regno);
 
-      /* It is possible that one of the registers we got for operands[2]
-        might coincide with that of operands[0] (which is why we made
-        it TImode).  Pick the other one to use as our scratch.  */
-      if (REGNO (operands[0]) == REGNO (operands[2]))
-       scratch = gen_rtx_REG (DImode, REGNO (operands[2]) + 1);
-      else
-       scratch = gen_rtx_REG (DImode, REGNO (operands[2]));
+  addr = get_unaligned_address (operands[1]);
+  operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));
+  seq = gen_unaligned_load<reloadmode> (operands[0], addr,
+                                       scratch, operands[0]);
+  alpha_set_memflags (seq, operands[1]);
 
-      addr = get_unaligned_address (operands[1], 0);
-      seq = gen_unaligned_loadhi (operands[0], addr, scratch,
-                         gen_rtx_REG (DImode, REGNO (operands[0])));
-      alpha_set_memflags (seq, operands[1]);
-    }
   emit_insn (seq);
   DONE;
 })
 
-(define_expand "reload_outqi"
-  [(parallel [(match_operand:QI 0 "any_memory_operand" "=m")
-             (match_operand:QI 1 "register_operand" "r")
+(define_expand "reload_out<mode>"
+  [(parallel [(match_operand:RELOAD12 0 "any_memory_operand" "=m")
+             (match_operand:RELOAD12 1 "register_operand" "r")
              (match_operand:TI 2 "register_operand" "=&r")])]
   "! TARGET_BWX"
 {
-  if (GET_CODE (operands[0]) != MEM)
-    abort ();
+  unsigned regno = REGNO (operands[2]);
 
-  if (aligned_memory_operand (operands[0], QImode))
-    {
-      emit_insn (gen_reload_outqi_help
-                (operands[0], operands[1],
-                 gen_rtx_REG (SImode, REGNO (operands[2])),
-                 gen_rtx_REG (SImode, REGNO (operands[2]) + 1)));
-    }
-  else
+  if (<MODE>mode == CQImode)
     {
-      rtx addr = get_unaligned_address (operands[0], 0);
-      rtx scratch1 = gen_rtx_REG (DImode, REGNO (operands[2]));
-      rtx scratch2 = gen_rtx_REG (DImode, REGNO (operands[2]) + 1);
-      rtx scratch3 = scratch1;
-      rtx seq;
-
-      if (GET_CODE (addr) == REG)
-       scratch1 = addr;
-
-      seq = gen_unaligned_storeqi (addr, operands[1], scratch1,
-                                  scratch2, scratch3);
-      alpha_set_memflags (seq, operands[0]);
-      emit_insn (seq);
+      operands[0] = gen_lowpart (HImode, operands[0]);
+      operands[1] = gen_lowpart (HImode, operands[1]);
     }
-  DONE;
-})
-
-(define_expand "reload_outhi"
-  [(parallel [(match_operand:HI 0 "any_memory_operand" "=m")
-             (match_operand:HI 1 "register_operand" "r")
-             (match_operand:TI 2 "register_operand" "=&r")])]
-  "! TARGET_BWX"
-{
-  if (GET_CODE (operands[0]) != MEM)
-    abort ();
 
-  if (aligned_memory_operand (operands[0], HImode))
+  if (aligned_memory_operand (operands[0], <MODE>mode))
     {
-      emit_insn (gen_reload_outhi_help
+      emit_insn (gen_reload_out<reloadmode>_aligned
                 (operands[0], operands[1],
-                 gen_rtx_REG (SImode, REGNO (operands[2])),
-                 gen_rtx_REG (SImode, REGNO (operands[2]) + 1)));
+                 gen_rtx_REG (SImode, regno),
+                 gen_rtx_REG (SImode, regno + 1)));
     }
   else
     {
-      rtx addr = get_unaligned_address (operands[0], 0);
-      rtx scratch1 = gen_rtx_REG (DImode, REGNO (operands[2]));
-      rtx scratch2 = gen_rtx_REG (DImode, REGNO (operands[2]) + 1);
+      rtx addr = get_unaligned_address (operands[0]);
+      rtx scratch1 = gen_rtx_REG (DImode, regno);
+      rtx scratch2 = gen_rtx_REG (DImode, regno + 1);
       rtx scratch3 = scratch1;
       rtx seq;
 
-      if (GET_CODE (addr) == REG)
+      if (REG_P (addr))
        scratch1 = addr;
 
-      seq = gen_unaligned_storehi (addr, operands[1], scratch1,
-                                  scratch2, scratch3);
+      seq = gen_unaligned_store<reloadmode> (addr, operands[1], scratch1,
+                                            scratch2, scratch3);
       alpha_set_memflags (seq, operands[0]);
       emit_insn (seq);
     }
@@ -6134,95 +6036,246 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
 ;; always get a proper address for a stack slot during reload_foo
 ;; expansion, so we must delay our address manipulations until after.
 
-(define_insn "reload_inqi_help"
-  [(set (match_operand:QI 0 "register_operand" "=r")
-        (match_operand:QI 1 "memory_operand" "m"))
-   (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")
-        (match_operand:HI 1 "memory_operand" "m"))
-   (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")
-        (match_operand:QI 1 "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")
-        (match_operand:HI 1 "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" "")
-        (match_operand:QI 1 "memory_operand" ""))
-   (clobber (match_operand:SI 2 "register_operand" ""))]
-  "! TARGET_BWX && reload_completed"
+(define_insn_and_split "reload_in<mode>_aligned"
+  [(set (match_operand:I12MODE 0 "register_operand" "=r")
+        (match_operand:I12MODE 1 "memory_operand" "m"))]
+  "!TARGET_BWX && (reload_in_progress || reload_completed)"
+  "#"
+  "!TARGET_BWX && reload_completed"
   [(const_int 0)]
 {
   rtx aligned_mem, bitnum;
   get_aligned_mem (operands[1], &aligned_mem, &bitnum);
-
-  emit_insn (gen_aligned_loadqi (operands[0], aligned_mem, bitnum,
-                                operands[2]));
+  emit_insn (gen_aligned_load<reloadmode>
+            (gen_lowpart (DImode, operands[0]), aligned_mem, bitnum,
+             gen_rtx_REG (SImode, REGNO (operands[0]))));
   DONE;
 })
 
-(define_split
-  [(set (match_operand:HI 0 "register_operand" "")
-        (match_operand:HI 1 "memory_operand" ""))
-   (clobber (match_operand:SI 2 "register_operand" ""))]
-  "! TARGET_BWX && reload_completed"
+(define_insn_and_split "reload_out<mode>_aligned"
+  [(set (match_operand:I12MODE 0 "memory_operand" "=m")
+        (match_operand:I12MODE 1 "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)"
+  "#"
+  "!TARGET_BWX && reload_completed"
   [(const_int 0)]
 {
   rtx aligned_mem, bitnum;
-  get_aligned_mem (operands[1], &aligned_mem, &bitnum);
-
-  emit_insn (gen_aligned_loadhi (operands[0], aligned_mem, bitnum,
-                                operands[2]));
+  get_aligned_mem (operands[0], &aligned_mem, &bitnum);
+  emit_insn (gen_aligned_store (aligned_mem, operands[1], bitnum,
+                               operands[2], operands[3]));
   DONE;
 })
+\f
+;; Vector operations
 
-(define_split
-  [(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_mode_iterator VEC [V8QI V4HI V2SI])
+
+(define_expand "mov<mode>"
+  [(set (match_operand:VEC 0 "nonimmediate_operand" "")
+        (match_operand:VEC 1 "general_operand" ""))]
+  ""
 {
-  rtx aligned_mem, bitnum;
-  get_aligned_mem (operands[0], &aligned_mem, &bitnum);
-  emit_insn (gen_aligned_store (aligned_mem, operands[1], bitnum,
-                               operands[2], operands[3]));
-  DONE;
+  if (alpha_expand_mov (<MODE>mode, operands))
+    DONE;
 })
 
 (define_split
-  [(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"
+  [(set (match_operand:VEC 0 "register_operand" "")
+       (match_operand:VEC 1 "non_zero_const_operand" ""))]
+  ""
   [(const_int 0)]
 {
-  rtx aligned_mem, bitnum;
-  get_aligned_mem (operands[0], &aligned_mem, &bitnum);
-  emit_insn (gen_aligned_store (aligned_mem, operands[1], bitnum,
-                               operands[2], operands[3]));
+  if (alpha_split_const_mov (<MODE>mode, operands))
+    DONE;
+  else
+    FAIL;
+})
+
+
+(define_expand "movmisalign<mode>"
+  [(set (match_operand:VEC 0 "nonimmediate_operand" "")
+        (match_operand:VEC 1 "general_operand" ""))]
+  ""
+{
+  alpha_expand_movmisalign (<MODE>mode, operands);
   DONE;
 })
+
+(define_insn "*mov<mode>_fix"
+  [(set (match_operand:VEC 0 "nonimmediate_operand" "=r,r,r,m,*f,*f,m,r,*f")
+       (match_operand:VEC 1 "input_operand" "rW,i,m,rW,*fW,m,*f,*f,r"))]
+  "TARGET_FIX
+   && (register_operand (operands[0], <MODE>mode)
+       || reg_or_0_operand (operands[1], <MODE>mode))"
+  "@
+   bis $31,%r1,%0
+   #
+   ldq %0,%1
+   stq %r1,%0
+   cpys %R1,%R1,%0
+   ldt %0,%1
+   stt %R1,%0
+   ftoit %1,%0
+   itoft %1,%0"
+  [(set_attr "type" "ilog,multi,ild,ist,fcpys,fld,fst,ftoi,itof")])
+
+(define_insn "*mov<mode>_nofix"
+  [(set (match_operand:VEC 0 "nonimmediate_operand" "=r,r,r,m,*f,*f,m")
+       (match_operand:VEC 1 "input_operand" "rW,i,m,rW,*fW,m,*f"))]
+  "! TARGET_FIX
+   && (register_operand (operands[0], <MODE>mode)
+       || reg_or_0_operand (operands[1], <MODE>mode))"
+  "@
+   bis $31,%r1,%0
+   #
+   ldq %0,%1
+   stq %r1,%0
+   cpys %R1,%R1,%0
+   ldt %0,%1
+   stt %R1,%0"
+  [(set_attr "type" "ilog,multi,ild,ist,fcpys,fld,fst")])
+
+(define_insn "uminv8qi3"
+  [(set (match_operand:V8QI 0 "register_operand" "=r")
+       (umin:V8QI (match_operand:V8QI 1 "reg_or_0_operand" "rW")
+                  (match_operand:V8QI 2 "reg_or_0_operand" "rW")))]
+  "TARGET_MAX"
+  "minub8 %r1,%r2,%0"
+  [(set_attr "type" "mvi")])
+
+(define_insn "sminv8qi3"
+  [(set (match_operand:V8QI 0 "register_operand" "=r")
+       (smin:V8QI (match_operand:V8QI 1 "reg_or_0_operand" "rW")
+                  (match_operand:V8QI 2 "reg_or_0_operand" "rW")))]
+  "TARGET_MAX"
+  "minsb8 %r1,%r2,%0"
+  [(set_attr "type" "mvi")])
+
+(define_insn "uminv4hi3"
+  [(set (match_operand:V4HI 0 "register_operand" "=r")
+       (umin:V4HI (match_operand:V4HI 1 "reg_or_0_operand" "rW")
+                  (match_operand:V4HI 2 "reg_or_0_operand" "rW")))]
+  "TARGET_MAX"
+  "minuw4 %r1,%r2,%0"
+  [(set_attr "type" "mvi")])
+
+(define_insn "sminv4hi3"
+  [(set (match_operand:V4HI 0 "register_operand" "=r")
+       (smin:V4HI (match_operand:V4HI 1 "reg_or_0_operand" "rW")
+                  (match_operand:V4HI 2 "reg_or_0_operand" "rW")))]
+  "TARGET_MAX"
+  "minsw4 %r1,%r2,%0"
+  [(set_attr "type" "mvi")])
+
+(define_insn "umaxv8qi3"
+  [(set (match_operand:V8QI 0 "register_operand" "=r")
+       (umax:V8QI (match_operand:V8QI 1 "reg_or_0_operand" "rW")
+                  (match_operand:V8QI 2 "reg_or_0_operand" "rW")))]
+  "TARGET_MAX"
+  "maxub8 %r1,%r2,%0"
+  [(set_attr "type" "mvi")])
+
+(define_insn "smaxv8qi3"
+  [(set (match_operand:V8QI 0 "register_operand" "=r")
+       (smax:V8QI (match_operand:V8QI 1 "reg_or_0_operand" "rW")
+                  (match_operand:V8QI 2 "reg_or_0_operand" "rW")))]
+  "TARGET_MAX"
+  "maxsb8 %r1,%r2,%0"
+  [(set_attr "type" "mvi")])
+
+(define_insn "umaxv4hi3"
+  [(set (match_operand:V4HI 0 "register_operand" "=r")
+       (umax:V4HI (match_operand:V4HI 1 "reg_or_0_operand" "rW")
+                  (match_operand:V4HI 2 "reg_or_0_operand" "rW")))]
+  "TARGET_MAX"
+  "maxuw4 %r1,%r2,%0"
+  [(set_attr "type" "mvi")])
+
+(define_insn "smaxv4hi3"
+  [(set (match_operand:V4HI 0 "register_operand" "=r")
+       (smax:V4HI (match_operand:V4HI 1 "reg_or_0_operand" "rW")
+                  (match_operand:V4HI 2 "reg_or_0_operand" "rW")))]
+  "TARGET_MAX"
+  "maxsw4 %r1,%r2,%0"
+  [(set_attr "type" "mvi")])
+
+(define_insn "one_cmpl<mode>2"
+  [(set (match_operand:VEC 0 "register_operand" "=r")
+       (not:VEC (match_operand:VEC 1 "register_operand" "r")))]
+  ""
+  "ornot $31,%1,%0"
+  [(set_attr "type" "ilog")])
+
+(define_insn "and<mode>3"
+  [(set (match_operand:VEC 0 "register_operand" "=r")
+       (and:VEC (match_operand:VEC 1 "register_operand" "r")
+                (match_operand:VEC 2 "register_operand" "r")))]
+  ""
+  "and %1,%2,%0"
+  [(set_attr "type" "ilog")])
+
+(define_insn "*andnot<mode>3"
+  [(set (match_operand:VEC 0 "register_operand" "=r")
+       (and:VEC (not:VEC (match_operand:VEC 1 "register_operand" "r"))
+                (match_operand:VEC 2 "register_operand" "r")))]
+  ""
+  "bic %2,%1,%0"
+  [(set_attr "type" "ilog")])
+
+(define_insn "ior<mode>3"
+  [(set (match_operand:VEC 0 "register_operand" "=r")
+       (ior:VEC (match_operand:VEC 1 "register_operand" "r")
+                (match_operand:VEC 2 "register_operand" "r")))]
+  ""
+  "bis %1,%2,%0"
+  [(set_attr "type" "ilog")])
+
+(define_insn "*iornot<mode>3"
+  [(set (match_operand:VEC 0 "register_operand" "=r")
+       (ior:VEC (not:DI (match_operand:VEC 1 "register_operand" "r"))
+                (match_operand:VEC 2 "register_operand" "r")))]
+  ""
+  "ornot %2,%1,%0"
+  [(set_attr "type" "ilog")])
+
+(define_insn "xor<mode>3"
+  [(set (match_operand:VEC 0 "register_operand" "=r")
+       (xor:VEC (match_operand:VEC 1 "register_operand" "r")
+                (match_operand:VEC 2 "register_operand" "r")))]
+  ""
+  "xor %1,%2,%0"
+  [(set_attr "type" "ilog")])
+
+(define_insn "*xornot<mode>3"
+  [(set (match_operand:VEC 0 "register_operand" "=r")
+       (not:VEC (xor:VEC (match_operand:VEC 1 "register_operand" "r")
+                         (match_operand:VEC 2 "register_operand" "r"))))]
+  ""
+  "eqv %1,%2,%0"
+  [(set_attr "type" "ilog")])
+
+(define_expand "vec_shl_<mode>"
+  [(set (match_operand:VEC 0 "register_operand" "")
+       (ashift:DI (match_operand:VEC 1 "register_operand" "")
+                  (match_operand:DI 2 "reg_or_6bit_operand" "")))]
+  ""
+{
+  operands[0] = gen_lowpart (DImode, operands[0]);
+  operands[1] = gen_lowpart (DImode, operands[1]);
+})
+
+(define_expand "vec_shr_<mode>"
+  [(set (match_operand:VEC 0 "register_operand" "")
+        (lshiftrt:DI (match_operand:VEC 1 "register_operand" "")
+                     (match_operand:DI 2 "reg_or_6bit_operand" "")))]
+  ""
+{
+  operands[0] = gen_lowpart (DImode, operands[0]);
+  operands[1] = gen_lowpart (DImode, operands[1]);
+})
 \f
 ;; Bit field extract patterns which use ext[wlq][lh]
 
@@ -6244,7 +6297,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
 
   /* From mips.md: extract_bit_field doesn't verify that our source
      matches the predicate, so we force it to be a MEM here.  */
-  if (GET_CODE (operands[1]) != MEM)
+  if (!MEM_P (operands[1]))
     FAIL;
 
   /* The bit number is relative to the mode of operand 1 which is
@@ -6280,11 +6333,11 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
          && INTVAL (operands[2]) != 64))
     FAIL;
 
-  if (GET_CODE (operands[1]) == MEM)
+  if (MEM_P (operands[1]))
     {
       int ofs;
 
-      /* Fail 8 bit fields, falling back on a simple byte load.  */
+      /* Fail 8-bit fields, falling back on a simple byte load.  */
       if (INTVAL (operands[2]) == 8)
        FAIL;
 
@@ -6325,7 +6378,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
 
   /* From mips.md: store_bit_field doesn't verify that our source
      matches the predicate, so we force it to be a MEM here.  */
-  if (GET_CODE (operands[0]) != MEM)
+  if (!MEM_P (operands[0]))
     FAIL;
 
   /* The bit number is relative to the mode of operand 1 which is
@@ -6351,7 +6404,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
 ;; Argument 2 is the length
 ;; Argument 3 is the alignment
 
-(define_expand "movstrqi"
+(define_expand "movmemqi"
   [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
                   (match_operand:BLK 1 "memory_operand" ""))
              (use (match_operand:DI 2 "immediate_operand" ""))
@@ -6364,18 +6417,119 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
     FAIL;
 })
 
-(define_expand "clrstrqi"
+(define_expand "movmemdi"
   [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
-                  (const_int 0))
+                  (match_operand:BLK 1 "memory_operand" ""))
+             (use (match_operand:DI 2 "immediate_operand" ""))
+             (use (match_operand:DI 3 "immediate_operand" ""))
+             (use (match_dup 4))
+             (clobber (reg:DI 25))
+             (clobber (reg:DI 16))
+             (clobber (reg:DI 17))
+             (clobber (reg:DI 18))
+             (clobber (reg:DI 19))
+             (clobber (reg:DI 20))
+             (clobber (reg:DI 26))
+             (clobber (reg:DI 27))])]
+  "TARGET_ABI_OPEN_VMS"
+{
+  operands[4] = alpha_need_linkage ("OTS$MOVE", 0);
+})
+
+(define_insn "*movmemdi_1"
+  [(set (match_operand:BLK 0 "memory_operand" "=m,=m")
+       (match_operand:BLK 1 "memory_operand" "m,m"))
+   (use (match_operand:DI 2 "nonmemory_operand" "r,i"))
+   (use (match_operand:DI 3 "immediate_operand" ""))
+   (use (match_operand:DI 4 "call_operand" "i,i"))
+   (clobber (reg:DI 25))
+   (clobber (reg:DI 16))
+   (clobber (reg:DI 17))
+   (clobber (reg:DI 18))
+   (clobber (reg:DI 19))
+   (clobber (reg:DI 20))
+   (clobber (reg:DI 26))
+   (clobber (reg:DI 27))]
+  "TARGET_ABI_OPEN_VMS"
+{
+  operands [5] = alpha_use_linkage (operands [4], cfun->decl, 0, 1);
+  switch (which_alternative)
+    {
+    case 0:
+       return "lda $16,%0\;bis $31,%2,$17\;lda $18,%1\;ldq $26,%5\;lda $25,3($31)\;jsr $26,%4\;ldq $27,0($29)";
+    case 1:
+       return "lda $16,%0\;lda $17,%2($31)\;lda $18,%1\;ldq $26,%5\;lda $25,3($31)\;jsr $26,%4\;ldq $27,0($29)";
+    default:
+      gcc_unreachable ();
+    }
+}
+  [(set_attr "type" "multi")
+   (set_attr "length" "28")])
+
+(define_expand "setmemqi"
+  [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
+                  (match_operand 2 "const_int_operand" ""))
              (use (match_operand:DI 1 "immediate_operand" ""))
-             (use (match_operand:DI 2 "immediate_operand" ""))])]
+             (use (match_operand:DI 3 "immediate_operand" ""))])]
   ""
 {
+  /* If value to set is not zero, use the library routine.  */
+  if (operands[2] != const0_rtx)
+    FAIL;
+
   if (alpha_expand_block_clear (operands))
     DONE;
   else
     FAIL;
 })
+
+(define_expand "setmemdi"
+  [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
+                  (match_operand 2 "const_int_operand" ""))
+             (use (match_operand:DI 1 "immediate_operand" ""))
+             (use (match_operand:DI 3 "immediate_operand" ""))
+             (use (match_dup 4))
+             (clobber (reg:DI 25))
+             (clobber (reg:DI 16))
+             (clobber (reg:DI 17))
+             (clobber (reg:DI 26))
+             (clobber (reg:DI 27))])]
+  "TARGET_ABI_OPEN_VMS"
+{
+  /* If value to set is not zero, use the library routine.  */
+  if (operands[2] != const0_rtx)
+    FAIL;
+
+  operands[4] = alpha_need_linkage ("OTS$ZERO", 0);
+})
+
+(define_insn "*clrmemdi_1"
+  [(set (match_operand:BLK 0 "memory_operand" "=m,=m")
+                  (const_int 0))
+   (use (match_operand:DI 1 "nonmemory_operand" "r,i"))
+   (use (match_operand:DI 2 "immediate_operand" ""))
+   (use (match_operand:DI 3 "call_operand" "i,i"))
+   (clobber (reg:DI 25))
+   (clobber (reg:DI 16))
+   (clobber (reg:DI 17))
+   (clobber (reg:DI 26))
+   (clobber (reg:DI 27))]
+  "TARGET_ABI_OPEN_VMS"
+{
+  operands [4] = alpha_use_linkage (operands [3], cfun->decl, 0, 1);
+  switch (which_alternative)
+    {
+    case 0:
+       return "lda $16,%0\;bis $31,%1,$17\;ldq $26,%4\;lda $25,2($31)\;jsr $26,%3\;ldq $27,0($29)";
+    case 1:
+       return "lda $16,%0\;lda $17,%1($31)\;ldq $26,%4\;lda $25,2($31)\;jsr $26,%3\;ldq $27,0($29)";
+    default:
+      gcc_unreachable ();
+    }
+}
+  [(set_attr "type" "multi")
+   (set_attr "length" "24")])
+
 \f
 ;; Subroutine of stack space allocation.  Perform a stack probe.
 (define_expand "probe_stack"
@@ -6403,7 +6557,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
        (match_dup 2))]
   ""
 {
-  if (GET_CODE (operands[1]) == CONST_INT
+  if (CONST_INT_P (operands[1])
       && INTVAL (operands[1]) < 32768)
     {
       if (INTVAL (operands[1]) >= 4096)
@@ -6430,17 +6584,17 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
       rtx loop_label = gen_label_rtx ();
       rtx want = gen_reg_rtx (Pmode);
       rtx tmp = gen_reg_rtx (Pmode);
-      rtx memref;
+      rtx memref, test;
 
       emit_insn (gen_subdi3 (want, stack_pointer_rtx,
                             force_reg (Pmode, operands[1])));
       emit_insn (gen_adddi3 (tmp, stack_pointer_rtx, GEN_INT (-4096)));
 
-      if (GET_CODE (operands[1]) != CONST_INT)
+      if (!CONST_INT_P (operands[1]))
        {
          out_label = gen_label_rtx ();
-         emit_insn (gen_cmpdi (want, tmp));
-         emit_jump_insn (gen_bgeu (out_label));
+         test = gen_rtx_GEU (VOIDmode, want, tmp);
+         emit_jump_insn (gen_cbranchdi4 (test, want, tmp, out_label));
        }
 
       emit_label (loop_label);
@@ -6448,8 +6602,8 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
       MEM_VOLATILE_P (memref) = 1;
       emit_move_insn (memref, const0_rtx);
       emit_insn (gen_adddi3 (tmp, tmp, GEN_INT(-8192)));
-      emit_insn (gen_cmpdi (tmp, want));
-      emit_jump_insn (gen_bgtu (loop_label));
+      test = gen_rtx_GTU (VOIDmode, tmp, want);
+      emit_jump_insn (gen_cbranchdi4 (test, tmp, want, loop_label));
 
       memref = gen_rtx_MEM (DImode, want);
       MEM_VOLATILE_P (memref) = 1;
@@ -6475,7 +6629,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
   ""
 {
   operands[2] = gen_label_rtx ();
-  ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
+  (*targetm.asm_out.internal_label) (asm_out_file, "L",
                             CODE_LABEL_NUMBER (operands[2]));
 
   return "stq $31,-8192(%1)\;subq %0,1,%0\;lda %1,-8192(%1)\;bne %0,%l2";
@@ -6518,7 +6672,8 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
                             (match_operand 2 "const_int_operand" "")]
                            UNSPECV_LDGP1))]
   "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
-  "ldah %0,0(%1)\t\t!gpdisp!%2")
+  "ldah %0,0(%1)\t\t!gpdisp!%2"
+  [(set_attr "cannot_copy" "true")])
 
 (define_insn "*ldgp_er_2"
   [(set (match_operand:DI 0 "register_operand" "=r")
@@ -6526,7 +6681,8 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
                    (match_operand 2 "const_int_operand" "")]
                   UNSPEC_LDGP2))]
   "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
-  "lda %0,0(%1)\t\t!gpdisp!%2")
+  "lda %0,0(%1)\t\t!gpdisp!%2"
+  [(set_attr "cannot_copy" "true")])
 
 (define_insn "*prologue_ldgp_er_2"
   [(set (match_operand:DI 0 "register_operand" "=r")
@@ -6534,7 +6690,8 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
                             (match_operand 2 "const_int_operand" "")]
                            UNSPECV_PLDGP2))]
   "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
-  "lda %0,0(%1)\t\t!gpdisp!%2\n$%~..ng:")
+  "lda %0,0(%1)\t\t!gpdisp!%2\n$%~..ng:"
+  [(set_attr "cannot_copy" "true")])
 
 (define_insn "*prologue_ldgp_1"
   [(set (match_operand:DI 0 "register_operand" "=r")
@@ -6542,7 +6699,8 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
                             (match_operand 2 "const_int_operand" "")]
                            UNSPECV_LDGP1))]
   ""
-  "ldgp %0,0(%1)\n$%~..ng:")
+  "ldgp %0,0(%1)\n$%~..ng:"
+  [(set_attr "cannot_copy" "true")])
 
 (define_insn "*prologue_ldgp_2"
   [(set (match_operand:DI 0 "register_operand" "=r")
@@ -6592,17 +6750,6 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
   DONE;
 })
 
-;; 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")]
-                  UNSPEC_NT_LDA))]
-  ""
-  "lda %0,%1(%0)")
-
 (define_expand "builtin_longjmp"
   [(use (match_operand:DI 0 "register_operand" "r"))]
   "TARGET_ABI_OSF"
@@ -6617,8 +6764,8 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
   emit_move_insn (hard_frame_pointer_rtx, fp);
   emit_move_insn (pv, lab);
   emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
-  emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
-  emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
+  emit_use (hard_frame_pointer_rtx);
+  emit_use (stack_pointer_rtx);
 
   /* Load the label we are jumping through into $27 so that we know
      where to look for it when we get back to setjmp's function for
@@ -6638,98 +6785,93 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
   "jmp $31,(%0),0"
   [(set_attr "type" "ibr")])
 
-(define_insn "*builtin_setjmp_receiver_er_sl_1"
-  [(unspec_volatile [(label_ref (match_operand 0 "" ""))] UNSPECV_SETJMPR)]
-  "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF && TARGET_AS_CAN_SUBTRACT_LABELS"
-  "lda $27,$LSJ%=-%l0($27)\n$LSJ%=:")
-  
-(define_insn "*builtin_setjmp_receiver_er_1"
-  [(unspec_volatile [(label_ref (match_operand 0 "" ""))] UNSPECV_SETJMPR)]
-  "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
-  "br $27,$LSJ%=\n$LSJ%=:"
-  [(set_attr "type" "ibr")])
-
-(define_split
-  [(unspec_volatile [(label_ref (match_operand 0 "" ""))] UNSPECV_SETJMPR)]
-  "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF
-   && prev_nonnote_insn (insn) == operands[0]"
-  [(const_int 0)]
-  "DONE;")
-
-(define_insn "*builtin_setjmp_receiver_1"
+(define_expand "builtin_setjmp_receiver"
   [(unspec_volatile [(label_ref (match_operand 0 "" ""))] UNSPECV_SETJMPR)]
   "TARGET_ABI_OSF"
-  "br $27,$LSJ%=\n$LSJ%=:\;ldgp $29,0($27)"
-  [(set_attr "length" "12")
-   (set_attr "type" "multi")])
+  "")
 
-(define_expand "builtin_setjmp_receiver_er"
-  [(unspec_volatile [(label_ref (match_operand 0 "" ""))] UNSPECV_SETJMPR)
-   (set (match_dup 1)
+(define_insn_and_split "*builtin_setjmp_receiver_1"
+  [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_SETJMPR)]
+  "TARGET_ABI_OSF"
+{
+  if (TARGET_EXPLICIT_RELOCS)
+    return "#";
+  else
+    return "br $27,$LSJ%=\n$LSJ%=:\;ldgp $29,0($27)";
+}
+  "&& TARGET_EXPLICIT_RELOCS && reload_completed"
+  [(set (match_dup 1)
        (unspec_volatile:DI [(match_dup 2) (match_dup 3)] UNSPECV_LDGP1))
    (set (match_dup 1)
        (unspec:DI [(match_dup 1) (match_dup 3)] UNSPEC_LDGP2))]
-  ""
 {
+  if (prev_nonnote_insn (curr_insn) != XEXP (operands[0], 0))
+    emit_insn (gen_rtx_UNSPEC_VOLATILE (VOIDmode, gen_rtvec (1, operands[0]),
+                                       UNSPECV_SETJMPR_ER));
   operands[1] = pic_offset_table_rtx;
   operands[2] = gen_rtx_REG (Pmode, 27);
   operands[3] = GEN_INT (alpha_next_sequence_number++);
-})
+}
+  [(set_attr "length" "12")
+   (set_attr "type" "multi")])
 
-(define_expand "builtin_setjmp_receiver"
-  [(unspec_volatile [(label_ref (match_operand 0 "" ""))] UNSPECV_SETJMPR)]
-  "TARGET_ABI_OSF"
-{
-  if (TARGET_EXPLICIT_RELOCS)
-    {
-      emit_insn (gen_builtin_setjmp_receiver_er (operands[0]));
-      DONE;
-    }
-})
+(define_insn "*builtin_setjmp_receiver_er_sl_1"
+  [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_SETJMPR_ER)]
+  "TARGET_ABI_OSF && TARGET_EXPLICIT_RELOCS && TARGET_AS_CAN_SUBTRACT_LABELS"
+  "lda $27,$LSJ%=-%l0($27)\n$LSJ%=:")
+  
+(define_insn "*builtin_setjmp_receiver_er_1"
+  [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_SETJMPR_ER)]
+  "TARGET_ABI_OSF && TARGET_EXPLICIT_RELOCS"
+  "br $27,$LSJ%=\n$LSJ%=:"
+  [(set_attr "type" "ibr")])
 
-(define_expand "exception_receiver_er"
-  [(set (match_dup 0)
-       (unspec_volatile:DI [(match_dup 1) (match_dup 2)] UNSPECV_LDGP1))
-   (set (match_dup 0)
-       (unspec:DI [(match_dup 0) (match_dup 2)] UNSPEC_LDGP2))]
-  ""
-{
-  operands[0] = pic_offset_table_rtx;
-  operands[1] = gen_rtx_REG (Pmode, 26);
-  operands[2] = GEN_INT (alpha_next_sequence_number++);
-})
+;; When flag_reorder_blocks_and_partition is in effect, compiler puts
+;; exception landing pads in a cold section.  To prevent inter-section offset
+;; calculation, a jump to original landing pad is emitted in the place of the
+;; original landing pad.  Since landing pad is moved, RA-relative GP
+;; calculation in the prologue of landing pad breaks.  To solve this problem,
+;; we use alternative GP load approach, as in the case of TARGET_LD_BUGGY_LDGP.
 
 (define_expand "exception_receiver"
   [(unspec_volatile [(match_dup 0)] UNSPECV_EHR)]
   "TARGET_ABI_OSF"
 {
-  if (TARGET_LD_BUGGY_LDGP)
+  if (TARGET_LD_BUGGY_LDGP || flag_reorder_blocks_and_partition)
     operands[0] = alpha_gp_save_rtx ();
-  else if (TARGET_EXPLICIT_RELOCS)
-    {
-      emit_insn (gen_exception_receiver_er ());
-      DONE;
-    }
   else
     operands[0] = const0_rtx;
 })
 
-(define_insn "*exception_receiver_1"
+(define_insn "*exception_receiver_2"
+  [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")] UNSPECV_EHR)]
+  "TARGET_ABI_OSF 
+   && (TARGET_LD_BUGGY_LDGP || flag_reorder_blocks_and_partition)"
+  "ldq $29,%0"
+  [(set_attr "type" "ild")])
+
+(define_insn_and_split "*exception_receiver_1"
   [(unspec_volatile [(const_int 0)] UNSPECV_EHR)]
-  "! TARGET_LD_BUGGY_LDGP"
-  "ldgp $29,0($26)"
+  "TARGET_ABI_OSF"
+{
+  if (TARGET_EXPLICIT_RELOCS)
+    return "ldah $29,0($26)\t\t!gpdisp!%*\;lda $29,0($29)\t\t!gpdisp!%*";
+  else
+    return "ldgp $29,0($26)";
+}
+  "&& TARGET_EXPLICIT_RELOCS && reload_completed"
+  [(set (match_dup 0)
+       (unspec_volatile:DI [(match_dup 1) (match_dup 2)] UNSPECV_LDGP1))
+   (set (match_dup 0)
+       (unspec:DI [(match_dup 0) (match_dup 2)] UNSPEC_LDGP2))]
+{
+  operands[0] = pic_offset_table_rtx;
+  operands[1] = gen_rtx_REG (Pmode, 26);
+  operands[2] = GEN_INT (alpha_next_sequence_number++);
+}
   [(set_attr "length" "8")
    (set_attr "type" "multi")])
 
-(define_insn "*exception_receiver_2"
-  [(unspec_volatile [(match_operand:DI 0 "nonimmediate_operand" "r,m")]
-                   UNSPECV_EHR)]
-  "TARGET_LD_BUGGY_LDGP"
-  "@
-   bis $31,%0,$29
-   ldq $29,%0"
-  [(set_attr "type" "ilog,ild")])
-
 (define_expand "nonlocal_goto_receiver"
   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
    (set (reg:DI 27) (mem:DI (reg:DI 29)))
@@ -6830,19 +6972,19 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
   [(prefetch (match_operand:DI 0 "address_operand" "p")
             (match_operand:DI 1 "const_int_operand" "n")
             (match_operand:DI 2 "const_int_operand" "n"))]
-  "TARGET_FIXUP_EV5_PREFETCH || TARGET_CPU_EV6"
+  "TARGET_FIXUP_EV5_PREFETCH || alpha_cpu == PROCESSOR_EV6"
 {
   /* Interpret "no temporal locality" as this data should be evicted once
      it is used.  The "evict next" alternatives load the data into the cache
      and leave the LRU eviction counter pointing to that block.  */
   static const char * const alt[2][2] = {
     { 
-      "lds $f31,%a0",          /* read, evict next */
+      "ldq $31,%a0",           /* read, evict next */
       "ldl $31,%a0",           /* read, evict last */
     },
     {
       "ldt $f31,%a0",          /* write, evict next */
-      "ldq $31,%a0",           /* write, evict last */
+      "lds $f31,%a0",          /* write, evict last */
     }
   };
 
@@ -6895,25 +7037,699 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
   else
     return ".align %0 #realign";
 })
+\f
+;; Instructions to be emitted from __builtins.
 
-;; The call patterns are at the end of the file because their
-;; wildcard operand0 interferes with nice recognition.
-
-(define_insn "*call_value_osf_1_er"
-  [(set (match_operand 0 "" "")
-       (call (mem:DI (match_operand:DI 1 "call_operand" "c,R,s"))
-             (match_operand 2 "" "")))
-   (use (reg:DI 29))
-   (clobber (reg:DI 26))]
-  "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
-  "@
-   jsr $26,(%1),0\;ldah $29,0($26)\t\t!gpdisp!%*\;lda $29,0($29)\t\t!gpdisp!%*
-   bsr $26,$%1..ng
-   ldq $27,%1($29)\t\t!literal!%#\;jsr $26,($27),0\t\t!lituse_jsr!%#\;ldah $29,0($26)\t\t!gpdisp!%*\;lda $29,0($29)\t\t!gpdisp!%*"
-  [(set_attr "type" "jsr")
-   (set_attr "length" "12,*,16")])
+(define_insn "builtin_cmpbge"
+  [(set (match_operand:DI 0 "register_operand" "=r")
+       (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rJ")
+                   (match_operand:DI 2 "reg_or_8bit_operand" "rI")]
+                  UNSPEC_CMPBGE))]
+  ""
+  "cmpbge %r1,%2,%0"
+  ;; The EV6 data sheets list this as ILOG.  OTOH, EV6 doesn't 
+  ;; actually differentiate between ILOG and ICMP in the schedule.
+  [(set_attr "type" "icmp")])
 
-;; We must use peep2 instead of a split because we need accurate life
+(define_expand "builtin_extbl"
+  [(match_operand:DI 0 "register_operand" "")
+   (match_operand:DI 1 "reg_or_0_operand" "")
+   (match_operand:DI 2 "reg_or_8bit_operand" "")]
+  ""
+{
+  rtx (*gen) (rtx, rtx, rtx, rtx);
+  if (WORDS_BIG_ENDIAN)
+    gen = gen_extxl_be;
+  else
+    gen = gen_extxl_le;
+  emit_insn ((*gen) (operands[0], operands[1], GEN_INT (8), operands[2]));
+  DONE;
+})
+
+(define_expand "builtin_extwl"
+  [(match_operand:DI 0 "register_operand" "")
+   (match_operand:DI 1 "reg_or_0_operand" "")
+   (match_operand:DI 2 "reg_or_8bit_operand" "")]
+  ""
+{
+  rtx (*gen) (rtx, rtx, rtx, rtx);
+  if (WORDS_BIG_ENDIAN)
+    gen = gen_extxl_be;
+  else
+    gen = gen_extxl_le;
+  emit_insn ((*gen) (operands[0], operands[1], GEN_INT (16), operands[2]));
+  DONE;
+})
+
+(define_expand "builtin_extll"
+  [(match_operand:DI 0 "register_operand" "")
+   (match_operand:DI 1 "reg_or_0_operand" "")
+   (match_operand:DI 2 "reg_or_8bit_operand" "")]
+  ""
+{
+  rtx (*gen) (rtx, rtx, rtx, rtx);
+  if (WORDS_BIG_ENDIAN)
+    gen = gen_extxl_be;
+  else
+    gen = gen_extxl_le;
+  emit_insn ((*gen) (operands[0], operands[1], GEN_INT (32), operands[2]));
+  DONE;
+})
+
+(define_expand "builtin_extql"
+  [(match_operand:DI 0 "register_operand" "")
+   (match_operand:DI 1 "reg_or_0_operand" "")
+   (match_operand:DI 2 "reg_or_8bit_operand" "")]
+  ""
+{
+  rtx (*gen) (rtx, rtx, rtx, rtx);
+  if (WORDS_BIG_ENDIAN)
+    gen = gen_extxl_be;
+  else
+    gen = gen_extxl_le;
+  emit_insn ((*gen) (operands[0], operands[1], GEN_INT (64), operands[2]));
+  DONE;
+})
+
+(define_expand "builtin_extwh"
+  [(match_operand:DI 0 "register_operand" "")
+   (match_operand:DI 1 "reg_or_0_operand" "")
+   (match_operand:DI 2 "reg_or_8bit_operand" "")]
+  ""
+{
+  rtx (*gen) (rtx, rtx, rtx);
+  if (WORDS_BIG_ENDIAN)
+    gen = gen_extwh_be;
+  else
+    gen = gen_extwh_le;
+  emit_insn ((*gen) (operands[0], operands[1], operands[2]));
+  DONE;
+})
+
+(define_expand "builtin_extlh"
+  [(match_operand:DI 0 "register_operand" "")
+   (match_operand:DI 1 "reg_or_0_operand" "")
+   (match_operand:DI 2 "reg_or_8bit_operand" "")]
+  ""
+{
+  rtx (*gen) (rtx, rtx, rtx);
+  if (WORDS_BIG_ENDIAN)
+    gen = gen_extlh_be;
+  else
+    gen = gen_extlh_le;
+  emit_insn ((*gen) (operands[0], operands[1], operands[2]));
+  DONE;
+})
+
+(define_expand "builtin_extqh"
+  [(match_operand:DI 0 "register_operand" "")
+   (match_operand:DI 1 "reg_or_0_operand" "")
+   (match_operand:DI 2 "reg_or_8bit_operand" "")]
+  ""
+{
+  rtx (*gen) (rtx, rtx, rtx);
+  if (WORDS_BIG_ENDIAN)
+    gen = gen_extqh_be;
+  else
+    gen = gen_extqh_le;
+  emit_insn ((*gen) (operands[0], operands[1], operands[2]));
+  DONE;
+})
+
+(define_expand "builtin_insbl"
+  [(match_operand:DI 0 "register_operand" "")
+   (match_operand:DI 1 "register_operand" "")
+   (match_operand:DI 2 "reg_or_8bit_operand" "")]
+  ""
+{
+  rtx (*gen) (rtx, rtx, rtx);
+  if (WORDS_BIG_ENDIAN)
+    gen = gen_insbl_be;
+  else
+    gen = gen_insbl_le;
+  operands[1] = gen_lowpart (QImode, operands[1]);
+  emit_insn ((*gen) (operands[0], operands[1], operands[2]));
+  DONE;
+})
+
+(define_expand "builtin_inswl"
+  [(match_operand:DI 0 "register_operand" "")
+   (match_operand:DI 1 "register_operand" "")
+   (match_operand:DI 2 "reg_or_8bit_operand" "")]
+  ""
+{
+  rtx (*gen) (rtx, rtx, rtx);
+  if (WORDS_BIG_ENDIAN)
+    gen = gen_inswl_be;
+  else
+    gen = gen_inswl_le;
+  operands[1] = gen_lowpart (HImode, operands[1]);
+  emit_insn ((*gen) (operands[0], operands[1], operands[2]));
+  DONE;
+})
+
+(define_expand "builtin_insll"
+  [(match_operand:DI 0 "register_operand" "")
+   (match_operand:DI 1 "register_operand" "")
+   (match_operand:DI 2 "reg_or_8bit_operand" "")]
+  ""
+{
+  rtx (*gen) (rtx, rtx, rtx);
+  if (WORDS_BIG_ENDIAN)
+    gen = gen_insll_be;
+  else
+    gen = gen_insll_le;
+  operands[1] = gen_lowpart (SImode, operands[1]);
+  emit_insn ((*gen) (operands[0], operands[1], operands[2]));
+  emit_insn ((*gen) (operands[0], operands[1], operands[2]));
+  DONE;
+})
+
+(define_expand "builtin_insql"
+  [(match_operand:DI 0 "register_operand" "")
+   (match_operand:DI 1 "reg_or_0_operand" "")
+   (match_operand:DI 2 "reg_or_8bit_operand" "")]
+  ""
+{
+  rtx (*gen) (rtx, rtx, rtx);
+  if (WORDS_BIG_ENDIAN)
+    gen = gen_insql_be;
+  else
+    gen = gen_insql_le;
+  emit_insn ((*gen) (operands[0], operands[1], operands[2]));
+  DONE;
+})
+
+(define_expand "builtin_inswh"
+  [(match_operand:DI 0 "register_operand" "")
+   (match_operand:DI 1 "register_operand" "")
+   (match_operand:DI 2 "reg_or_8bit_operand" "")]
+  ""
+{
+  emit_insn (gen_insxh (operands[0], operands[1], GEN_INT (16), operands[2]));
+  DONE;
+})
+
+(define_expand "builtin_inslh"
+  [(match_operand:DI 0 "register_operand" "")
+   (match_operand:DI 1 "register_operand" "")
+   (match_operand:DI 2 "reg_or_8bit_operand" "")]
+  ""
+{
+  emit_insn (gen_insxh (operands[0], operands[1], GEN_INT (32), operands[2]));
+  DONE;
+})
+
+(define_expand "builtin_insqh"
+  [(match_operand:DI 0 "register_operand" "")
+   (match_operand:DI 1 "register_operand" "")
+   (match_operand:DI 2 "reg_or_8bit_operand" "")]
+  ""
+{
+  emit_insn (gen_insxh (operands[0], operands[1], GEN_INT (64), operands[2]));
+  DONE;
+})
+
+(define_expand "builtin_mskbl"
+  [(match_operand:DI 0 "register_operand" "")
+   (match_operand:DI 1 "reg_or_0_operand" "")
+   (match_operand:DI 2 "reg_or_8bit_operand" "")]
+  ""
+{
+  rtx (*gen) (rtx, rtx, rtx, rtx);
+  rtx mask;
+  if (WORDS_BIG_ENDIAN)
+    gen = gen_mskxl_be;
+  else
+    gen = gen_mskxl_le;
+  mask = GEN_INT (0xff);
+  emit_insn ((*gen) (operands[0], operands[1], mask, operands[2]));
+  DONE;
+})
+
+(define_expand "builtin_mskwl"
+  [(match_operand:DI 0 "register_operand" "")
+   (match_operand:DI 1 "reg_or_0_operand" "")
+   (match_operand:DI 2 "reg_or_8bit_operand" "")]
+  ""
+{
+  rtx (*gen) (rtx, rtx, rtx, rtx);
+  rtx mask;
+  if (WORDS_BIG_ENDIAN)
+    gen = gen_mskxl_be;
+  else
+    gen = gen_mskxl_le;
+  mask = GEN_INT (0xffff);
+  emit_insn ((*gen) (operands[0], operands[1], mask, operands[2]));
+  DONE;
+})
+
+(define_expand "builtin_mskll"
+  [(match_operand:DI 0 "register_operand" "")
+   (match_operand:DI 1 "reg_or_0_operand" "")
+   (match_operand:DI 2 "reg_or_8bit_operand" "")]
+  ""
+{
+  rtx (*gen) (rtx, rtx, rtx, rtx);
+  rtx mask;
+  if (WORDS_BIG_ENDIAN)
+    gen = gen_mskxl_be;
+  else
+    gen = gen_mskxl_le;
+  mask = immed_double_const (0xffffffff, 0, DImode);
+  emit_insn ((*gen) (operands[0], operands[1], mask, operands[2]));
+  DONE;
+})
+
+(define_expand "builtin_mskql"
+  [(match_operand:DI 0 "register_operand" "")
+   (match_operand:DI 1 "reg_or_0_operand" "")
+   (match_operand:DI 2 "reg_or_8bit_operand" "")]
+  ""
+{
+  rtx (*gen) (rtx, rtx, rtx, rtx);
+  rtx mask;
+  if (WORDS_BIG_ENDIAN)
+    gen = gen_mskxl_be;
+  else
+    gen = gen_mskxl_le;
+  mask = constm1_rtx;
+  emit_insn ((*gen) (operands[0], operands[1], mask, operands[2]));
+  DONE;
+})
+
+(define_expand "builtin_mskwh"
+  [(match_operand:DI 0 "register_operand" "")
+   (match_operand:DI 1 "register_operand" "")
+   (match_operand:DI 2 "reg_or_8bit_operand" "")]
+  ""
+{
+  emit_insn (gen_mskxh (operands[0], operands[1], GEN_INT (16), operands[2]));
+  DONE;
+})
+
+(define_expand "builtin_msklh"
+  [(match_operand:DI 0 "register_operand" "")
+   (match_operand:DI 1 "register_operand" "")
+   (match_operand:DI 2 "reg_or_8bit_operand" "")]
+  ""
+{
+  emit_insn (gen_mskxh (operands[0], operands[1], GEN_INT (32), operands[2]));
+  DONE;
+})
+
+(define_expand "builtin_mskqh"
+  [(match_operand:DI 0 "register_operand" "")
+   (match_operand:DI 1 "register_operand" "")
+   (match_operand:DI 2 "reg_or_8bit_operand" "")]
+  ""
+{
+  emit_insn (gen_mskxh (operands[0], operands[1], GEN_INT (64), operands[2]));
+  DONE;
+})
+
+(define_expand "builtin_zap"
+  [(set (match_operand:DI 0 "register_operand" "")
+       (and:DI (unspec:DI
+                 [(match_operand:DI 2 "reg_or_cint_operand" "")]
+                 UNSPEC_ZAP)
+               (match_operand:DI 1 "reg_or_cint_operand" "")))]
+  ""
+{
+  if (CONST_INT_P (operands[2]))
+    {
+      rtx mask = alpha_expand_zap_mask (INTVAL (operands[2]));
+
+      if (mask == const0_rtx)
+       {
+         emit_move_insn (operands[0], const0_rtx);
+         DONE;
+       }
+      if (mask == constm1_rtx)
+       {
+         emit_move_insn (operands[0], operands[1]);
+         DONE;
+       }
+
+      operands[1] = force_reg (DImode, operands[1]);
+      emit_insn (gen_anddi3 (operands[0], operands[1], mask));
+      DONE;
+    }
+
+  operands[1] = force_reg (DImode, operands[1]);
+  operands[2] = gen_lowpart (QImode, operands[2]);
+})
+
+(define_insn "*builtin_zap_1"
+  [(set (match_operand:DI 0 "register_operand" "=r,r,r,r")
+       (and:DI (unspec:DI
+                 [(match_operand:QI 2 "reg_or_cint_operand" "n,n,r,r")]
+                 UNSPEC_ZAP)
+               (match_operand:DI 1 "reg_or_cint_operand" "n,r,J,r")))]
+  ""
+  "@
+   #
+   #
+   bis $31,$31,%0
+   zap %r1,%2,%0"
+  [(set_attr "type" "shift,shift,ilog,shift")])
+
+(define_split
+  [(set (match_operand:DI 0 "register_operand" "")
+       (and:DI (unspec:DI
+                 [(match_operand:QI 2 "const_int_operand" "")]
+                 UNSPEC_ZAP)
+               (match_operand:DI 1 "const_int_operand" "")))]
+  ""
+  [(const_int 0)]
+{
+  rtx mask = alpha_expand_zap_mask (INTVAL (operands[2]));
+  if (HOST_BITS_PER_WIDE_INT >= 64 || CONST_INT_P (mask))
+    operands[1] = gen_int_mode (INTVAL (operands[1]) & INTVAL (mask), DImode);
+  else
+    {
+      HOST_WIDE_INT c_lo = INTVAL (operands[1]);
+      HOST_WIDE_INT c_hi = (c_lo < 0 ? -1 : 0);
+      operands[1] = immed_double_const (c_lo & CONST_DOUBLE_LOW (mask),
+                                       c_hi & CONST_DOUBLE_HIGH (mask),
+                                       DImode);
+    }
+  emit_move_insn (operands[0], operands[1]);
+  DONE;
+})
+
+(define_split
+  [(set (match_operand:DI 0 "register_operand" "")
+       (and:DI (unspec:DI
+                 [(match_operand:QI 2 "const_int_operand" "")]
+                 UNSPEC_ZAP)
+               (match_operand:DI 1 "register_operand" "")))]
+  ""
+  [(set (match_dup 0)
+       (and:DI (match_dup 1) (match_dup 2)))]
+{
+  operands[2] = alpha_expand_zap_mask (INTVAL (operands[2]));
+  if (operands[2] == const0_rtx)
+    {
+      emit_move_insn (operands[0], const0_rtx);
+      DONE;
+    }
+  if (operands[2] == constm1_rtx)
+    {
+      emit_move_insn (operands[0], operands[1]);
+      DONE;
+    }
+})
+
+(define_expand "builtin_zapnot"
+  [(set (match_operand:DI 0 "register_operand" "")
+       (and:DI (unspec:DI
+                 [(not:QI (match_operand:DI 2 "reg_or_cint_operand" ""))]
+                 UNSPEC_ZAP)
+               (match_operand:DI 1 "reg_or_cint_operand" "")))]
+  ""
+{
+  if (CONST_INT_P (operands[2]))
+    {
+      rtx mask = alpha_expand_zap_mask (~ INTVAL (operands[2]));
+
+      if (mask == const0_rtx)
+       {
+         emit_move_insn (operands[0], const0_rtx);
+         DONE;
+       }
+      if (mask == constm1_rtx)
+       {
+         emit_move_insn (operands[0], operands[1]);
+         DONE;
+       }
+
+      operands[1] = force_reg (DImode, operands[1]);
+      emit_insn (gen_anddi3 (operands[0], operands[1], mask));
+      DONE;
+    }
+
+  operands[1] = force_reg (DImode, operands[1]);
+  operands[2] = gen_lowpart (QImode, operands[2]);
+})
+
+(define_insn "*builtin_zapnot_1"
+  [(set (match_operand:DI 0 "register_operand" "=r")
+       (and:DI (unspec:DI
+                  [(not:QI (match_operand:QI 2 "register_operand" "r"))]
+                  UNSPEC_ZAP)
+               (match_operand:DI 1 "reg_or_0_operand" "rJ")))]
+  ""
+  "zapnot %r1,%2,%0"
+  [(set_attr "type" "shift")])
+
+(define_insn "builtin_amask"
+  [(set (match_operand:DI 0 "register_operand" "=r")
+       (unspec:DI [(match_operand:DI 1 "reg_or_8bit_operand" "rI")]
+                  UNSPEC_AMASK))]
+  ""
+  "amask %1,%0"
+  [(set_attr "type" "ilog")])
+
+(define_insn "builtin_implver"
+  [(set (match_operand:DI 0 "register_operand" "=r")
+       (unspec:DI [(const_int 0)] UNSPEC_IMPLVER))]
+  ""
+  "implver %0"
+  [(set_attr "type" "ilog")])
+
+(define_insn "builtin_rpcc"
+  [(set (match_operand:DI 0 "register_operand" "=r")
+       (unspec_volatile:DI [(const_int 0)] UNSPECV_RPCC))]
+  ""
+  "rpcc %0"
+  [(set_attr "type" "ilog")])
+
+(define_expand "builtin_minub8"
+  [(match_operand:DI 0 "register_operand" "")
+   (match_operand:DI 1 "reg_or_0_operand" "")
+   (match_operand:DI 2 "reg_or_0_operand" "")]
+  "TARGET_MAX"
+{
+  alpha_expand_builtin_vector_binop (gen_uminv8qi3, V8QImode, operands[0],
+                                    operands[1], operands[2]);
+  DONE;
+})
+
+(define_expand "builtin_minsb8"
+  [(match_operand:DI 0 "register_operand" "")
+   (match_operand:DI 1 "reg_or_0_operand" "")
+   (match_operand:DI 2 "reg_or_0_operand" "")]
+  "TARGET_MAX"
+{
+  alpha_expand_builtin_vector_binop (gen_sminv8qi3, V8QImode, operands[0],
+                                    operands[1], operands[2]);
+  DONE;
+})
+
+(define_expand "builtin_minuw4"
+  [(match_operand:DI 0 "register_operand" "")
+   (match_operand:DI 1 "reg_or_0_operand" "")
+   (match_operand:DI 2 "reg_or_0_operand" "")]
+  "TARGET_MAX"
+{
+  alpha_expand_builtin_vector_binop (gen_uminv4hi3, V4HImode, operands[0],
+                                    operands[1], operands[2]);
+  DONE;
+})
+
+(define_expand "builtin_minsw4"
+  [(match_operand:DI 0 "register_operand" "")
+   (match_operand:DI 1 "reg_or_0_operand" "")
+   (match_operand:DI 2 "reg_or_0_operand" "")]
+  "TARGET_MAX"
+{
+  alpha_expand_builtin_vector_binop (gen_sminv4hi3, V4HImode, operands[0],
+                                    operands[1], operands[2]);
+  DONE;
+})
+
+(define_expand "builtin_maxub8"
+  [(match_operand:DI 0 "register_operand" "")
+   (match_operand:DI 1 "reg_or_0_operand" "")
+   (match_operand:DI 2 "reg_or_0_operand" "")]
+  "TARGET_MAX"
+{
+  alpha_expand_builtin_vector_binop (gen_umaxv8qi3, V8QImode, operands[0],
+                                    operands[1], operands[2]);
+  DONE;
+})
+
+(define_expand "builtin_maxsb8"
+  [(match_operand:DI 0 "register_operand" "")
+   (match_operand:DI 1 "reg_or_0_operand" "")
+   (match_operand:DI 2 "reg_or_0_operand" "")]
+  "TARGET_MAX"
+{
+  alpha_expand_builtin_vector_binop (gen_smaxv8qi3, V8QImode, operands[0],
+                                    operands[1], operands[2]);
+  DONE;
+})
+
+(define_expand "builtin_maxuw4"
+  [(match_operand:DI 0 "register_operand" "")
+   (match_operand:DI 1 "reg_or_0_operand" "")
+   (match_operand:DI 2 "reg_or_0_operand" "")]
+  "TARGET_MAX"
+{
+  alpha_expand_builtin_vector_binop (gen_umaxv4hi3, V4HImode, operands[0],
+                                    operands[1], operands[2]);
+  DONE;
+})
+
+(define_expand "builtin_maxsw4"
+  [(match_operand:DI 0 "register_operand" "")
+   (match_operand:DI 1 "reg_or_0_operand" "")
+   (match_operand:DI 2 "reg_or_0_operand" "")]
+  "TARGET_MAX"
+{
+  alpha_expand_builtin_vector_binop (gen_smaxv4hi3, V4HImode, operands[0],
+                                    operands[1], operands[2]);
+  DONE;
+})
+
+(define_insn "builtin_perr"
+  [(set (match_operand:DI 0 "register_operand" "=r")
+       (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "%rJ")
+                   (match_operand:DI 2 "reg_or_8bit_operand" "rJ")]
+                  UNSPEC_PERR))]
+  "TARGET_MAX"
+  "perr %r1,%r2,%0"
+  [(set_attr "type" "mvi")])
+
+(define_expand "builtin_pklb"
+  [(set (match_operand:DI 0 "register_operand" "")
+       (vec_concat:V8QI
+         (vec_concat:V4QI
+           (truncate:V2QI (match_operand:DI 1 "register_operand" ""))
+           (match_dup 2))
+         (match_dup 3)))]
+  "TARGET_MAX"
+{
+  operands[0] = gen_lowpart (V8QImode, operands[0]);
+  operands[1] = gen_lowpart (V2SImode, operands[1]);
+  operands[2] = CONST0_RTX (V2QImode);
+  operands[3] = CONST0_RTX (V4QImode);
+})
+
+(define_insn "*pklb"
+  [(set (match_operand:V8QI 0 "register_operand" "=r")
+       (vec_concat:V8QI
+         (vec_concat:V4QI
+           (truncate:V2QI (match_operand:V2SI 1 "register_operand" "r"))
+           (match_operand:V2QI 2 "const0_operand" ""))
+         (match_operand:V4QI 3 "const0_operand" "")))]
+  "TARGET_MAX"
+  "pklb %r1,%0"
+  [(set_attr "type" "mvi")])
+
+(define_expand "builtin_pkwb"
+  [(set (match_operand:DI 0 "register_operand" "")
+       (vec_concat:V8QI
+         (truncate:V4QI (match_operand:DI 1 "register_operand" ""))
+         (match_dup 2)))]
+  "TARGET_MAX"
+{
+  operands[0] = gen_lowpart (V8QImode, operands[0]);
+  operands[1] = gen_lowpart (V4HImode, operands[1]);
+  operands[2] = CONST0_RTX (V4QImode);
+})
+
+(define_insn "*pkwb"
+  [(set (match_operand:V8QI 0 "register_operand" "=r")
+       (vec_concat:V8QI
+         (truncate:V4QI (match_operand:V4HI 1 "register_operand" "r"))
+         (match_operand:V4QI 2 "const0_operand" "")))]
+  "TARGET_MAX"
+  "pkwb %r1,%0"
+  [(set_attr "type" "mvi")])
+
+(define_expand "builtin_unpkbl"
+  [(set (match_operand:DI 0 "register_operand" "")
+       (zero_extend:V2SI
+         (vec_select:V2QI (match_operand:DI 1 "register_operand" "")
+                          (parallel [(const_int 0) (const_int 1)]))))]
+  "TARGET_MAX"
+{
+  operands[0] = gen_lowpart (V2SImode, operands[0]);
+  operands[1] = gen_lowpart (V8QImode, operands[1]);
+})
+
+(define_insn "*unpkbl"
+  [(set (match_operand:V2SI 0 "register_operand" "=r")
+       (zero_extend:V2SI
+         (vec_select:V2QI (match_operand:V8QI 1 "reg_or_0_operand" "rW")
+                          (parallel [(const_int 0) (const_int 1)]))))]
+  "TARGET_MAX"
+  "unpkbl %r1,%0"
+  [(set_attr "type" "mvi")])
+
+(define_expand "builtin_unpkbw"
+  [(set (match_operand:DI 0 "register_operand" "")
+       (zero_extend:V4HI
+         (vec_select:V4QI (match_operand:DI 1 "register_operand" "")
+                          (parallel [(const_int 0)
+                                     (const_int 1)
+                                     (const_int 2)
+                                     (const_int 3)]))))]
+  "TARGET_MAX"
+{
+  operands[0] = gen_lowpart (V4HImode, operands[0]);
+  operands[1] = gen_lowpart (V8QImode, operands[1]);
+})
+
+(define_insn "*unpkbw"
+  [(set (match_operand:V4HI 0 "register_operand" "=r")
+       (zero_extend:V4HI
+         (vec_select:V4QI (match_operand:V8QI 1 "reg_or_0_operand" "rW")
+                          (parallel [(const_int 0)
+                                     (const_int 1)
+                                     (const_int 2)
+                                     (const_int 3)]))))]
+  "TARGET_MAX"
+  "unpkbw %r1,%0"
+  [(set_attr "type" "mvi")])
+\f
+(include "sync.md")
+\f
+;; The call patterns are at the end of the file because their
+;; wildcard operand0 interferes with nice recognition.
+
+(define_insn "*call_value_osf_1_er_noreturn"
+  [(set (match_operand 0 "" "")
+       (call (mem:DI (match_operand:DI 1 "call_operand" "c,R,s"))
+             (match_operand 2 "" "")))
+   (use (reg:DI 29))
+   (clobber (reg:DI 26))]
+  "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF
+   && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
+  "@
+   jsr $26,($27),0
+   bsr $26,%1\t\t!samegp
+   ldq $27,%1($29)\t\t!literal!%#\;jsr $26,($27),%1\t\t!lituse_jsr!%#"
+  [(set_attr "type" "jsr")
+   (set_attr "length" "*,*,8")])
+
+(define_insn "*call_value_osf_1_er"
+  [(set (match_operand 0 "" "")
+       (call (mem:DI (match_operand:DI 1 "call_operand" "c,R,s"))
+             (match_operand 2 "" "")))
+   (use (reg:DI 29))
+   (clobber (reg:DI 26))]
+  "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
+  "@
+   jsr $26,(%1),0\;ldah $29,0($26)\t\t!gpdisp!%*\;lda $29,0($29)\t\t!gpdisp!%*
+   bsr $26,%1\t\t!samegp
+   ldq $27,%1($29)\t\t!literal!%#\;jsr $26,($27),0\t\t!lituse_jsr!%#\;ldah $29,0($26)\t\t!gpdisp!%*\;lda $29,0($29)\t\t!gpdisp!%*"
+  [(set_attr "type" "jsr")
+   (set_attr "length" "12,*,16")])
+
+;; We must use peep2 instead of a split because we need accurate life
 ;; information for $gp.  Consider the case of { bar(); while (1); }.
 (define_peephole2
   [(parallel [(set (match_operand 0 "" "")
@@ -6922,15 +7738,16 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
              (use (reg:DI 29))
              (clobber (reg:DI 26))])]
   "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF && reload_completed
-   && ! current_file_function_operand (operands[1], Pmode)
-   && peep2_regno_dead_p (1, 29)"
+   && ! samegp_function_operand (operands[1], Pmode)
+   && (peep2_regno_dead_p (1, 29)
+       || find_reg_note (insn, REG_NORETURN, NULL_RTX))"
   [(parallel [(set (match_dup 0)
                   (call (mem:DI (match_dup 3))
                         (match_dup 2)))
-             (set (reg:DI 26) (plus:DI (pc) (const_int 4)))
-             (unspec_volatile [(reg:DI 29)] UNSPECV_BLOCKAGE)
+             (use (reg:DI 29))
              (use (match_dup 1))
-             (use (match_dup 4))])]
+             (use (match_dup 4))
+             (clobber (reg:DI 26))])]
 {
   if (CONSTANT_P (operands[1]))
     {
@@ -6954,19 +7771,19 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
              (use (reg:DI 29))
              (clobber (reg:DI 26))])]
   "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF && reload_completed
-   && ! current_file_function_operand (operands[1], Pmode)
-   && ! peep2_regno_dead_p (1, 29)"
+   && ! samegp_function_operand (operands[1], Pmode)
+   && ! (peep2_regno_dead_p (1, 29)
+         || find_reg_note (insn, REG_NORETURN, NULL_RTX))"
   [(parallel [(set (match_dup 0)
                   (call (mem:DI (match_dup 3))
                         (match_dup 2)))
-             (set (reg:DI 26) (plus:DI (pc) (const_int 4)))
-             (unspec_volatile [(reg:DI 29)] UNSPECV_BLOCKAGE)
+             (set (match_dup 6)
+                  (unspec:DI [(match_dup 6) (match_dup 4)] UNSPEC_LDGP1))
              (use (match_dup 1))
-             (use (match_dup 5))])
-   (set (reg:DI 29)
-       (unspec_volatile:DI [(reg:DI 26) (match_dup 4)] UNSPECV_LDGP1))
-   (set (reg:DI 29)
-       (unspec:DI [(reg:DI 29) (match_dup 4)] UNSPEC_LDGP2))]
+             (use (match_dup 5))
+             (clobber (reg:DI 26))])
+   (set (match_dup 6)
+       (unspec:DI [(match_dup 6) (match_dup 4)] UNSPEC_LDGP2))]
 {
   if (CONSTANT_P (operands[1]))
     {
@@ -6982,23 +7799,37 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
       operands[5] = const0_rtx;
     }
   operands[4] = GEN_INT (alpha_next_sequence_number++);
+  operands[6] = pic_offset_table_rtx;
 })
 
-;; We add a blockage unspec_volatile to prevent insns from moving down
-;; from above the call to in between the call and the ldah gpdisp.
-(define_insn "*call_value_osf_2_er"
+(define_insn "*call_value_osf_2_er_nogp"
   [(set (match_operand 0 "" "")
        (call (mem:DI (match_operand:DI 1 "register_operand" "c"))
              (match_operand 2 "" "")))
-   (set (reg:DI 26)
-       (plus:DI (pc) (const_int 4)))
-   (unspec_volatile [(reg:DI 29)] UNSPECV_BLOCKAGE)
+   (use (reg:DI 29))
    (use (match_operand 3 "" ""))
-   (use (match_operand 4 "const_int_operand" ""))]
+   (use (match_operand 4 "" ""))
+   (clobber (reg:DI 26))]
   "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
   "jsr $26,(%1),%3%J4"
   [(set_attr "type" "jsr")])
 
+(define_insn "*call_value_osf_2_er"
+  [(set (match_operand 0 "" "")
+       (call (mem:DI (match_operand:DI 1 "register_operand" "c"))
+             (match_operand 2 "" "")))
+   (set (reg:DI 29)
+       (unspec:DI [(reg:DI 29) (match_operand 5 "const_int_operand" "")]
+                  UNSPEC_LDGP1))
+   (use (match_operand 3 "" ""))
+   (use (match_operand 4 "" ""))
+   (clobber (reg:DI 26))]
+  "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
+  "jsr $26,(%1),%3%J4\;ldah $29,0($26)\t\t!gpdisp!%5"
+  [(set_attr "type" "jsr")
+   (set_attr "cannot_copy" "true")
+   (set_attr "length" "8")])
+
 (define_insn "*call_value_osf_1_noreturn"
   [(set (match_operand 0 "" "")
        (call (mem:DI (match_operand:DI 1 "call_operand" "c,R,s"))
@@ -7014,6 +7845,68 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
   [(set_attr "type" "jsr")
    (set_attr "length" "*,*,8")])
 
+(define_insn_and_split "call_value_osf_tlsgd"
+  [(set (match_operand 0 "" "")
+       (call (mem:DI (match_operand:DI 1 "symbolic_operand" ""))
+             (const_int 0)))
+   (unspec [(match_operand:DI 2 "const_int_operand" "")] UNSPEC_TLSGD_CALL)
+   (use (reg:DI 29))
+   (clobber (reg:DI 26))]
+  "HAVE_AS_TLS"
+  "#"
+  "&& reload_completed"
+  [(set (match_dup 3)
+       (unspec:DI [(match_dup 5)
+                   (match_dup 1)
+                   (match_dup 2)] UNSPEC_LITERAL))
+   (parallel [(set (match_dup 0)
+                  (call (mem:DI (match_dup 3))
+                        (const_int 0)))
+             (set (match_dup 5)
+                  (unspec:DI [(match_dup 5) (match_dup 4)] UNSPEC_LDGP1))
+             (use (match_dup 1))
+             (use (unspec [(match_dup 2)] UNSPEC_TLSGD_CALL))
+             (clobber (reg:DI 26))])
+   (set (match_dup 5)
+       (unspec:DI [(match_dup 5) (match_dup 4)] UNSPEC_LDGP2))]
+{
+  operands[3] = gen_rtx_REG (Pmode, 27);
+  operands[4] = GEN_INT (alpha_next_sequence_number++);
+  operands[5] = pic_offset_table_rtx;
+}
+  [(set_attr "type" "multi")])
+
+(define_insn_and_split "call_value_osf_tlsldm"
+  [(set (match_operand 0 "" "")
+       (call (mem:DI (match_operand:DI 1 "symbolic_operand" ""))
+             (const_int 0)))
+   (unspec [(match_operand:DI 2 "const_int_operand" "")] UNSPEC_TLSLDM_CALL)
+   (use (reg:DI 29))
+   (clobber (reg:DI 26))]
+  "HAVE_AS_TLS"
+  "#"
+  "&& reload_completed"
+  [(set (match_dup 3)
+       (unspec:DI [(match_dup 5)
+                   (match_dup 1)
+                   (match_dup 2)] UNSPEC_LITERAL))
+   (parallel [(set (match_dup 0)
+                  (call (mem:DI (match_dup 3))
+                        (const_int 0)))
+             (set (match_dup 5)
+                  (unspec:DI [(match_dup 5) (match_dup 4)] UNSPEC_LDGP1))
+             (use (match_dup 1))
+             (use (unspec [(match_dup 2)] UNSPEC_TLSLDM_CALL))
+             (clobber (reg:DI 26))])
+   (set (match_dup 5)
+       (unspec:DI [(match_dup 5) (match_dup 4)] UNSPEC_LDGP2))]
+{
+  operands[3] = gen_rtx_REG (Pmode, 27);
+  operands[4] = GEN_INT (alpha_next_sequence_number++);
+  operands[5] = pic_offset_table_rtx;
+}
+  [(set_attr "type" "multi")])
+
 (define_insn "*call_value_osf_1"
   [(set (match_operand 0 "" "")
        (call (mem:DI (match_operand:DI 1 "call_operand" "c,R,s"))
@@ -7035,7 +7928,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
    (unspec [(reg:DI 29)] UNSPEC_SIBCALL)]
   "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
   "@
-   br $31,$%1..ng
+   br $31,%1\t\t!samegp
    ldq $27,%1($29)\t\t!literal!%#\;jmp $31,($27),%1\t\t!lituse_jsr!%#"
   [(set_attr "type" "jsr")
    (set_attr "length" "*,8")])
@@ -7065,18 +7958,31 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
   [(set_attr "type" "jsr")
    (set_attr "length" "*,*,12")])
 
+; GAS relies on the order and position of instructions output below in order
+; to generate relocs for VMS link to potentially optimize the call.
+; Please do not molest.
 (define_insn "*call_value_vms_1"
   [(set (match_operand 0 "" "")
        (call (mem:DI (match_operand:DI 1 "call_operand" "r,s"))
              (match_operand 2 "" "")))
-   (use (match_operand:DI 3 "nonimmediate_operand" "r,m"))
+   (use (match_operand:DI 3 "nonmemory_operand" "r,n"))
    (use (reg:DI 25))
    (use (reg:DI 26))
    (clobber (reg:DI 27))]
   "TARGET_ABI_OPEN_VMS"
-  "@
-   mov %3,$27\;jsr $26,0\;ldq $27,0($29)
-   ldq $27,%3\;jsr $26,%1\;ldq $27,0($29)"
+{
+  switch (which_alternative)
+    {
+    case 0:
+       return "mov %3,$27\;jsr $26,0\;ldq $27,0($29)";
+    case 1:
+       operands [3] = alpha_use_linkage (operands [1], cfun->decl, 1, 0);
+       operands [4] = alpha_use_linkage (operands [1], cfun->decl, 0, 0);
+       return "ldq $26,%4\;ldq $27,%3\;jsr $26,%1\;ldq $27,0($29)";
+    default:
+      gcc_unreachable ();
+    }
+}
   [(set_attr "type" "jsr")
    (set_attr "length" "12,16")])
 
@@ -7089,4 +7995,3 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
   "TARGET_ABI_UNICOSMK"
   "jsr $26,(%1)"
   [(set_attr "type" "jsr")])
-