Sync with NetBSD's GCC, making changes to remove pointless whitespace
changes and re-doing GCC trunk changes.

diff --git a/gcc/config/vax/builtins.md b/gcc/config/vax/builtins.md
index bf4d2aeace2..a7e3e132523 100644
--- a/gcc/config/vax/builtins.md
+++ b/gcc/config/vax/builtins.md
@@ -24,6 +24,12 @@
   ]
 )
 
+(define_expand "condjump"
+  [(set (pc)
+	(if_then_else (match_operand 0)
+		      (label_ref (match_operand 1))
+		      (pc)))])
+
 (define_expand "ffssi2"
   [(set (match_operand:SI 0 "nonimmediate_operand" "")
 	(ffs:SI (match_operand:SI 1 "general_operand" "")))]
@@ -31,17 +37,17 @@
   "
 {
   rtx label = gen_label_rtx ();
-  emit_insn (gen_ffssi2_internal (operands[0], operands[1]));
-  emit_jump_insn (gen_bne (label));
-  emit_insn (gen_negsi2 (operands[0], const1_rtx));
+  emit_insn (gen_ctzsi2 (operands[0], operands[1]));
+  emit_jump_insn (gen_condjump (gen_rtx_NE(VOIDmode, cc0_rtx, const0_rtx), label));
+  emit_move_insn (operands[0], constm1_rtx);
   emit_label (label);
   emit_insn (gen_addsi3 (operands[0], operands[0], const1_rtx));
   DONE;
 }")
 
-(define_insn "ffssi2_internal"
+(define_insn "ctzsi2"
   [(set (match_operand:SI 0 "nonimmediate_operand" "=rQ")
-	(ffs:SI (match_operand:SI 1 "general_operand" "nrQt")))
+	(ctz:SI (match_operand:SI 1 "general_operand" "nrQT")))
    (set (cc0) (match_dup 0))]
   ""
   "ffs $0,$32,%1,%0")
@@ -71,13 +77,13 @@
   [(parallel
     [(set (pc)
 	  (if_then_else
-	    (ne (zero_extract:SI (match_operand:QI 0 "memory_operand" "g")
+	    (ne (zero_extract:SI (match_operand:QI 0 "volatile_mem_operand" "g")
 				 (const_int 1)
 				 (match_operand:SI 1 "general_operand" "nrm"))
 		(const_int 0))
 	    (label_ref (match_operand 2 "" ""))
 	    (pc)))
-     (set (zero_extract:SI (match_operand:QI 3 "memory_operand" "+0")
+     (set (zero_extract:SI (match_operand:QI 3 "volatile_mem_operand" "+0")
 			   (const_int 1)
 			   (match_dup 1))
 	  (const_int 1))])]
@@ -88,13 +94,13 @@
   [(parallel
     [(set (pc)
 	  (if_then_else
-	    (ne (zero_extract:SI (match_operand:HI 0 "memory_operand" "Q")
+	    (ne (zero_extract:SI (match_operand:HI 0 "volatile_mem_operand" "Q")
 				 (const_int 1)
 				 (match_operand:SI 1 "general_operand" "nrm"))
 		(const_int 0))
 	    (label_ref (match_operand 2 "" ""))
 	    (pc)))
-     (set (zero_extract:SI (match_operand:HI 3 "memory_operand" "+0")
+     (set (zero_extract:SI (match_operand:HI 3 "volatile_mem_operand" "+0")
 			   (const_int 1)
 			   (match_dup 1))
 	  (const_int 1))])]
@@ -105,13 +111,13 @@
   [(parallel
     [(set (pc)
 	  (if_then_else
-	    (ne (zero_extract:SI (match_operand:SI 0 "memory_operand" "Q")
+	    (ne (zero_extract:SI (match_operand:SI 0 "volatile_mem_operand" "Q")
 				 (const_int 1)
 				 (match_operand:SI 1 "general_operand" "nrm"))
 		(const_int 0))
 	    (label_ref (match_operand 2 "" ""))
 	    (pc)))
-     (set (zero_extract:SI (match_operand:SI 3 "memory_operand" "+0")
+     (set (zero_extract:SI (match_operand:SI 3 "volatile_mem_operand" "+0")
 			   (const_int 1)
 			   (match_dup 1))
 	  (const_int 1))])]
@@ -189,4 +195,3 @@
 	  (const_int 0))])]
   ""
   "jbcci %1,%0,%l2")
-
diff --git a/gcc/config/vax/constraints.md b/gcc/config/vax/constraints.md
index 8483bbfcaf3..7becc951094 100644
--- a/gcc/config/vax/constraints.md
+++ b/gcc/config/vax/constraints.md
@@ -25,32 +25,32 @@
 (define_constraint "U06"
    "unsigned 6 bit value (0..63)"
    (and (match_code "const_int")
-	(match_test "ival >= 0 && ival < 64")))
+	(match_test "0 <= ival && ival < 64")))
 
 (define_constraint "U08"
    "Unsigned 8 bit value"
    (and (match_code "const_int")
-	(match_test "ival >= 0 && ival < 256")))
+	(match_test "0 <= ival && ival < 256")))
 
 (define_constraint "U16"
    "Unsigned 16 bit value"
    (and (match_code "const_int")
-	(match_test "ival >= 0 && ival < 65536")))
+	(match_test "0 <= ival && ival < 65536")))
 
 (define_constraint "CN6"
    "negative 6 bit value (-63..-1)"
    (and (match_code "const_int")
-	(match_test "ival >= -63 && ival < 0")))
+	(match_test "-63 <= ival && ival < 0")))
 
 (define_constraint "S08"
    "signed 8 bit value [old]"
    (and (match_code "const_int")
-	(match_test "ival >= -128 && ival < 128")))
+	(match_test "-128 <= ival && ival < 128")))
 
 (define_constraint "S16"
    "signed 16 bit value [old]"
    (and (match_code "const_int")
-	(match_test "ival >= -32768 && ival < 32768")))
+	(match_test "-32768 <= ival && ival < 32768")))
 
 (define_constraint "I"
    "Match a CONST_INT of 0 [old]"
diff --git a/gcc/config/vax/elf.h b/gcc/config/vax/elf.h
index dd8d3d950fb..42b5c049b5f 100644
--- a/gcc/config/vax/elf.h
+++ b/gcc/config/vax/elf.h
@@ -65,7 +65,6 @@ along with GCC; see the file COPYING3.  If not see
 			      gen_rtx_REG (Pmode, FRAME_POINTER_REGNUM),\
 			      16))
 
-
 /* The VAX wants no space between the case instruction and the jump table.  */
 #undef  ASM_OUTPUT_BEFORE_CASE_LABEL
 #define ASM_OUTPUT_BEFORE_CASE_LABEL(FILE, PREFIX, NUM, TABLE)
@@ -104,5 +103,5 @@ along with GCC; see the file COPYING3.  If not see
     fputs (integer_asm_op (SIZE, FALSE), FILE);		\
     fprintf (FILE, "%%pcrel%d(", SIZE * 8);		\
     assemble_name (FILE, LABEL);			\
-    fputc (')', FILE);					\
+    fprintf (FILE, "%+d)", SIZE);			\
   } while (0)
diff --git a/gcc/config/vax/netbsd-elf.h b/gcc/config/vax/netbsd-elf.h
index e7cbe243201..b5ba43e7598 100644
--- a/gcc/config/vax/netbsd-elf.h
+++ b/gcc/config/vax/netbsd-elf.h
@@ -43,25 +43,17 @@ along with GCC; see the file COPYING3.  If not see
 #define NETBSD_ENTRY_POINT "__start"
 
 #undef LINK_SPEC
-#if 0
-/* FIXME: We must link all executables statically until PIC support
-   is added to the compiler.  */
-#define LINK_SPEC \
-  "%{assert*} %{R*} %{rpath*} \
-   %{shared:%ethe -shared option is not currently supported for VAX ELF} \
-   %{!shared: \
-     -dc -dp \
-     %{!nostdlib: \
-       %{!r: \
-	 %{!e*:-e %(netbsd_entry_point)}}} \
-     %{!static:-static} \
-     %{static:-static}}"
-#else
 #define LINK_SPEC NETBSD_LINK_SPEC_ELF
-#endif
 
-#define EXTRA_SPECS				\
-  { "netbsd_entry_point", NETBSD_ENTRY_POINT },
+#undef EXTRA_SPECS
+#define EXTRA_SPECS NETBSD_SUBTARGET_EXTRA_SPECS
+#undef SUBTARGET_EXTRA_SPECS
+
+#undef INTPTR_TYPE
+#define INTPTR_TYPE "long int"
+
+#undef UINTPTR_TYPE
+#define UINTPTR_TYPE "long unsigned int"
 
 /* We use gas, not the UNIX assembler.  */
 #undef TARGET_DEFAULT
diff --git a/gcc/config/vax/predicates.md b/gcc/config/vax/predicates.md
index c6d66f771ef..171691be067 100644
--- a/gcc/config/vax/predicates.md
+++ b/gcc/config/vax/predicates.md
@@ -109,3 +109,16 @@
    (and (match_code "const_int,const_double,subreg,reg,mem")
 	(and (match_operand:DI 0 "general_operand" "")
 	     (not (match_operand:DI 0 "illegal_addsub_di_memory_operand")))))
+
+;; Return 1 if the operand is in volatile memory.  Note that during the
+;; RTL generation phase, memory_operand does not return TRUE for volatile
+;; memory references.  So this function allows us to recognize volatile
+;; references where it's safe.
+(define_predicate "volatile_mem_operand"
+  (and (and (match_code "mem")
+	    (match_test "MEM_VOLATILE_P (op)"))
+       (if_then_else (match_test "reload_completed")
+         (match_operand 0 "memory_operand")
+         (if_then_else (match_test "reload_in_progress")
+	   (match_test "strict_memory_address_p (mode, XEXP (op, 0))")
+	   (match_test "memory_address_p (mode, XEXP (op, 0))")))))
diff --git a/gcc/config/vax/vax-protos.h b/gcc/config/vax/vax-protos.h
index a76cf023916..da960eb7646 100644
--- a/gcc/config/vax/vax-protos.h
+++ b/gcc/config/vax/vax-protos.h
@@ -16,8 +16,10 @@ GNU General Public License for more details.
 You should have received a copy of the GNU General Public License
 along with GCC; see the file COPYING3.  If not see
 <http://www.gnu.org/licenses/>.  */
+#include <stdbool.h>
 
 extern bool legitimate_constant_address_p (rtx);
+extern bool legitimate_pic_operand_p (rtx);
 extern void vax_expand_prologue (void);
 
 #ifdef RTX_CODE
@@ -28,6 +30,7 @@ extern void print_operand_address (FILE *, rtx);
 extern void print_operand (FILE *, rtx, int);
 extern void vax_notice_update_cc (rtx, rtx);
 extern void vax_expand_addsub_di_operands (rtx *, enum rtx_code);
+extern bool vax_decomposed_dimode_operand_p (rtx, rtx);
 extern const char * vax_output_int_move (rtx, rtx *, machine_mode);
 extern const char * vax_output_int_add (rtx_insn *, rtx *, machine_mode);
 extern const char * vax_output_int_subtract (rtx_insn *, rtx *, machine_mode);
diff --git a/gcc/config/vax/vax.c b/gcc/config/vax/vax.c
index fe21faebe4d..b070a7f47c3 100644
--- a/gcc/config/vax/vax.c
+++ b/gcc/config/vax/vax.c
@@ -65,7 +65,7 @@ static void vax_trampoline_init (rtx, tree, rtx);
 static poly_int64 vax_return_pops_args (tree, tree, poly_int64);
 static bool vax_mode_dependent_address_p (const_rtx, addr_space_t);
 static HOST_WIDE_INT vax_starting_frame_offset (void);
-
+
 /* Initialize the GCC target structure.  */
 #undef TARGET_ASM_ALIGNED_HI_OP
 #define TARGET_ASM_ALIGNED_HI_OP "\t.word\t"
@@ -137,6 +137,8 @@ vax_option_override (void)
   if (TARGET_G_FLOAT)
     REAL_MODE_FORMAT (DFmode) = &vax_g_format;
 
+  flag_dwarf2_cfi_asm = 0;
+
 #ifdef SUBTARGET_OVERRIDE_OPTIONS
   SUBTARGET_OVERRIDE_OPTIONS;
 #endif
@@ -170,9 +172,13 @@ vax_expand_prologue (void)
   HOST_WIDE_INT size;
   rtx insn;
 
+  offset = 20;
   for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
     if (df_regs_ever_live_p (regno) && !call_used_regs[regno])
-      mask |= 1 << regno;
+      {
+        mask |= 1 << regno;
+        offset += 4;
+      }
 
   insn = emit_insn (gen_procedure_entry_mask (GEN_INT (mask)));
   RTX_FRAME_RELATED_P (insn) = 1;
@@ -194,11 +200,23 @@ vax_expand_prologue (void)
 
      The rest of the prologue will adjust the SP for the local frame.  */
 
-  vax_add_reg_cfa_offset (insn, 4, arg_pointer_rtx);
-  vax_add_reg_cfa_offset (insn, 8, frame_pointer_rtx);
-  vax_add_reg_cfa_offset (insn, 12, pc_rtx);
+  add_reg_note (insn, REG_CFA_DEF_CFA,
+                plus_constant (Pmode, frame_pointer_rtx, offset));
+  insn = emit_insn (gen_blockage ());
+  RTX_FRAME_RELATED_P (insn) = 1;
+
+#ifdef notyet
+  /*
+   * We can't do this, the dwarf code asserts and we don't have yet a 
+   * way to get to the psw
+   */
+  vax_add_reg_cfa_offset (insn, 4, gen_rtx_REG (Pmode, PSW_REGNUM));
+#endif
+  vax_add_reg_cfa_offset (insn, 8, arg_pointer_rtx);
+  vax_add_reg_cfa_offset (insn, 12, frame_pointer_rtx);
+  vax_add_reg_cfa_offset (insn, 16, pc_rtx);
 
-  offset = 16;
+  offset = 20;
   for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
     if (mask & (1 << regno))
       {
@@ -206,12 +224,6 @@ vax_expand_prologue (void)
 	offset += 4;
       }
 
-  /* Because add_reg_note pushes the notes, adding this last means that
-     it will be processed first.  This is required to allow the other
-     notes be interpreted properly.  */
-  add_reg_note (insn, REG_CFA_DEF_CFA,
-		plus_constant (Pmode, frame_pointer_rtx, offset));
-
   /* Allocate the local stack frame.  */
   size = get_frame_size ();
   size -= vax_starting_frame_offset ();
@@ -362,7 +374,10 @@ print_operand_address (FILE * file, rtx addr)
 	  addr = XEXP (addr, 1);
 	}
       else
-	gcc_unreachable ();
+	{
+	   debug_rtx (orig);
+	   gcc_unreachable ();
+	}
 
       if (REG_P (addr))
 	{
@@ -373,9 +388,8 @@ print_operand_address (FILE * file, rtx addr)
 	}
       else if (GET_CODE (addr) == MULT)
 	ireg = addr;
-      else
+      else if (GET_CODE (addr) == PLUS)
 	{
-	  gcc_assert (GET_CODE (addr) == PLUS);
 	  if (CONSTANT_ADDRESS_P (XEXP (addr, 0))
 	      || MEM_P (XEXP (addr, 0)))
 	    {
@@ -400,12 +414,15 @@ print_operand_address (FILE * file, rtx addr)
 	      else
 		reg1 = XEXP (addr, 0);
 	    }
-	  else
+	  else if (GET_CODE (XEXP (addr, 0)) == MULT && !ireg)
 	    {
-	      gcc_assert (GET_CODE (XEXP (addr, 0)) == MULT);
-	      gcc_assert (!ireg);
 	      ireg = XEXP (addr, 0);
 	    }
+	  else
+	    {
+	      debug_rtx (orig);
+	      gcc_unreachable ();
+	    }
 
 	  if (CONSTANT_ADDRESS_P (XEXP (addr, 1))
 	      || MEM_P (XEXP (addr, 1)))
@@ -431,12 +448,20 @@ print_operand_address (FILE * file, rtx addr)
 	      else
 		reg1 = XEXP (addr, 1);
 	    }
-	  else
+	  else if (GET_CODE (XEXP (addr, 1)) == MULT && !ireg)
 	    {
-	      gcc_assert (GET_CODE (XEXP (addr, 1)) == MULT);
-	      gcc_assert (!ireg);
 	      ireg = XEXP (addr, 1);
 	    }
+	  else
+	    {
+	      debug_rtx (orig);
+	      gcc_unreachable ();
+	    }
+	}
+      else
+	{
+	  debug_rtx (orig);
+	  gcc_unreachable ();
 	}
 
       /* If REG1 is nonzero, figure out if it is a base or index register.  */
@@ -448,7 +473,11 @@ print_operand_address (FILE * file, rtx addr)
 		  && (MEM_P (offset)
 		      || (flag_pic && symbolic_operand (offset, SImode)))))
 	    {
-	      gcc_assert (!ireg);
+	      if (ireg)
+		{
+		  debug_rtx (orig);
+		  gcc_unreachable ();
+		}
 	      ireg = reg1;
 	    }
 	  else
@@ -494,12 +523,17 @@ print_operand_address (FILE * file, rtx addr)
 	{
 	  if (GET_CODE (ireg) == MULT)
 	    ireg = XEXP (ireg, 0);
-	  gcc_assert (REG_P (ireg));
+	  if (! REG_P (ireg))
+	    {
+	      debug_rtx (orig);
+	      output_operand_lossage ("non-register index expression");
+	    }
 	  fprintf (file, "[%s]", reg_names[REGNO (ireg)]);
 	}
       break;
 
     default:
+      gcc_assert (! REG_P(addr));
       output_addr_const (file, addr);
     }
 }
@@ -554,6 +588,11 @@ print_operand (FILE *file, rtx x, int code)
 		       sizeof (dstr), 0, 1);
       fprintf (file, "$0%c%s", ASM_DOUBLE_CHAR, dstr);
     }
+  else if (GET_CODE (x) == SUBREG)
+    {
+      debug_rtx (x);
+      output_operand_lossage ("SUBREG operand");
+    }
   else
     {
       if (flag_pic > 1 && symbolic_operand (x, SImode))
@@ -1098,6 +1137,7 @@ vax_notice_update_cc (rtx exp, rtx insn ATTRIBUTE_UNUSED)
 	    case IOR:
 	    case XOR:
 	    case NOT:
+	    case CTZ:
 	    case MEM:
 	    case REG:
 	      cc_status.flags = CC_NO_OVERFLOW;
@@ -1273,7 +1313,7 @@ vax_output_int_move (rtx insn ATTRIBUTE_UNUSED, rtx *operands,
 
       if (operands[1] == const0_rtx)
 	{
-	  if (push_operand (operands[1], SImode))
+	  if (push_operand (operands[0], SImode))
 	    return "pushl %1";
 	  return "clrl %0";
 	}
@@ -1638,6 +1678,111 @@ vax_output_int_subtract (rtx_insn *insn, rtx *operands, machine_mode mode)
   }
 }
 
+static rtx
+mkrtx(enum rtx_code code, enum machine_mode mode, rtx base, HOST_WIDE_INT off)
+{
+  rtx tmp;
+
+  if (GET_CODE (base) == CONST)
+    base = XEXP (base, 0);
+
+  if (GET_CODE (base) == PLUS)
+    {
+      rtx a = XEXP (base, 0);
+      rtx b = XEXP (base, 1);
+      if (GET_CODE (b) == CONST)
+	b = XEXP (b, 0);
+      if (CONST_INT_P (b))
+	{
+          off += INTVAL (b);
+          base = a;
+	}
+      else if (REG_P (a) && GET_CODE (b) == SYMBOL_REF)
+	{
+	  if (off != 0)
+	    {
+	      base = gen_rtx_PLUS (Pmode, a, plus_constant(Pmode, b, off));
+	      off = 0;
+	    }
+	}
+      else if (REG_P (a) && GET_CODE (b) == PLUS)
+	{
+          off += INTVAL (XEXP (b, 1));
+	  base = gen_rtx_PLUS (Pmode, a, plus_constant(Pmode, XEXP (b, 0), off));
+	  off = 0;
+	}
+      else
+        {
+	  debug_rtx(base);
+	  gcc_unreachable ();
+	}
+    }
+  if (code == POST_INC)
+    tmp = gen_rtx_POST_INC (SImode, base);
+  else if (off == 0 || (REG_P (base) && code == REG))
+    tmp = base;
+  else
+    tmp = plus_constant (Pmode, base, off);
+  return gen_rtx_MEM (mode, tmp);
+}
+
+const char *
+vax_output_movmemsi (rtx insn, rtx *operands)
+{
+  HOST_WIDE_INT n = INTVAL (operands[2]);
+  HOST_WIDE_INT off;
+  rtx src, dest;
+  const char *pat = NULL;
+  const enum rtx_code *src_codes;
+  const enum rtx_code *dest_codes;
+  int code_idx = 0;
+  int mode_idx;
+
+  static const enum machine_mode xmodes[4] =
+    {
+      QImode, HImode, SImode, DImode
+    };
+  static const char * const pats[4] = 
+    {
+      "movb %1,%0", "movw %1,%0", "movl %1,%0", "movq %1,%0", 
+    };
+  static const enum rtx_code codes[2][3] =
+    {
+      { PLUS, PLUS, PLUS },
+      { POST_INC, POST_INC, REG },
+    };
+
+  src = XEXP (operands[1], 0);
+
+  src_codes =
+    codes[REG_P (src) && find_regno_note (insn, REG_DEAD, REGNO(src))];
+
+  dest = XEXP (operands[0], 0);
+
+  dest_codes =
+    codes[REG_P (dest) && find_regno_note (insn, REG_DEAD, REGNO(dest))];
+
+  for (off = 0, code_idx = 0, mode_idx = 3; mode_idx >= 0; mode_idx--)
+    {
+      const enum machine_mode mode = xmodes[mode_idx];
+      const HOST_WIDE_INT mode_len = GET_MODE_SIZE (mode);
+      for (; n >= mode_len; n -= mode_len, off += mode_len)
+	{
+	  if (pat != NULL)
+	    output_asm_insn (pat, operands);
+	  if (n == mode_len)
+	    code_idx = 2;
+	  operands[0] = mkrtx(dest_codes[code_idx], mode, dest, off);
+	  operands[1] = mkrtx(src_codes[code_idx], mode, src, off);
+	  if (pat == NULL)
+	    code_idx = 1;
+	  pat = pats[mode_idx];
+	}
+    }
+
+  return pat;
+}
+
 /* True if X is an rtx for a constant that is a valid address.  */
 
 bool
@@ -1654,9 +1799,23 @@ legitimate_constant_address_p (rtx x)
       && !SYMBOL_REF_LOCAL_P (XEXP (XEXP (x, 0), 0)))
     return false;
 #endif
+   gcc_assert (! REG_P (x));
    return true;
 }
 
+bool
+legitimate_pic_operand_p (rtx x)
+{
+#ifdef NO_EXTERNAL_INDIRECT_ADDRESS
+  if (GET_CODE (x) != CONST)
+    return true;
+  if (GET_CODE (XEXP (XEXP (x, 0), 0)) == SYMBOL_REF
+      && !SYMBOL_REF_LOCAL_P (XEXP (XEXP (x, 0), 0)))
+    return false;
+#endif
+  return true;
+}
+
 /* The other macros defined here are used only in legitimate_address_p ().  */
 
 /* Nonzero if X is a hard reg that can be used as an index
@@ -1963,8 +2122,10 @@ vax_expand_addsub_di_operands (rtx * operands, enum rtx_code code)
 	 and that's just a left shift of 1.  */
       if (rtx_equal_p (operands[1], operands[2]))
 	{
-	  gcc_assert (code != MINUS);
-	  emit_insn (gen_ashldi3 (operands[0], operands[1], const1_rtx));
+	  if (code == MINUS)
+	    emit_insn (gen_movdi (operands[0], const0_rtx));
+	  else
+	    emit_insn (gen_ashldi3 (operands[0], operands[1], const1_rtx));
 	  return;
 	}
 
@@ -2029,7 +2190,7 @@ adjacent_operands_p (rtx lo, rtx hi, machine_mode mode)
   if (REG_P (lo))
     return mode == SImode && REGNO (lo) + 1 == REGNO (hi);
   if (CONST_INT_P (lo))
-    return INTVAL (hi) == 0 && UINTVAL (lo) < 64;
+    return INTVAL (hi) == 0 && 0 <= INTVAL (lo) && INTVAL (lo) < 64;
   if (CONST_INT_P (lo))
     return mode != SImode;
 
@@ -2194,3 +2355,53 @@ vax_starting_frame_offset (void)
   return TARGET_ELF ? -4 : 0;
 }
 
+bool
+vax_decomposed_dimode_operand_p (rtx lo, rtx hi)
+{
+  HOST_WIDE_INT lo_offset = 0;
+  HOST_WIDE_INT hi_offset = 0;
+
+  /* If the codes aren't the same, can't be a DImode operand.  */
+  if (GET_CODE (lo) != GET_CODE (hi))
+    return false;
+
+  /* If a register, hi regno must be one more than the lo regno.  */
+  if (REG_P (lo))
+    return REGNO (lo) + 1 == REGNO (hi);
+
+  /* If not memory, can't be a DImode operand.  */
+  if (!MEM_P (lo))
+    return false;
+
+  /* Get addresses of memory operands.  */
+  lo = XEXP(lo, 0);
+  hi = XEXP(hi, 0);
+
+  /* If POST_INC, regno must match.  */
+  if (GET_CODE (lo) == POST_INC && GET_CODE (hi) == POST_INC)
+    return REGNO (XEXP (lo, 0)) == REGNO (XEXP (hi, 0));
+
+  if (GET_CODE (lo) == PLUS)
+    {
+      /* If PLUS or MULT, this must an indexed address so fail.  */
+      if (GET_CODE (XEXP (lo, 0)) == PLUS
+	  || GET_CODE (XEXP (lo, 0)) == MULT
+	  || !CONST_INT_P (XEXP (lo, 1)))
+	return false;
+      lo_offset = INTVAL (XEXP (lo, 1));
+      lo = XEXP(lo, 0);
+    }
+
+  if (GET_CODE (hi) == PLUS)
+    {
+      /* If PLUS or MULT, this must an indexed address so fail.  */
+      if (GET_CODE (XEXP (hi, 0)) == PLUS
+	  || GET_CODE (XEXP (hi, 0)) == MULT
+	  || !CONST_INT_P (XEXP (hi, 1)))
+	return false;
+      hi_offset = INTVAL (XEXP (hi, 1));
+      hi = XEXP(hi, 0);
+    }
+
+  return rtx_equal_p(lo, hi) && lo_offset + 4 == hi_offset;
+}
diff --git a/gcc/config/vax/vax.h b/gcc/config/vax/vax.h
index a6a8227f7c2..31d7aa10bad 100644
--- a/gcc/config/vax/vax.h
+++ b/gcc/config/vax/vax.h
@@ -17,6 +17,7 @@ You should have received a copy of the GNU General Public License
 along with GCC; see the file COPYING3.  If not see
 <http://www.gnu.org/licenses/>.  */
 
+#include "vax-protos.h"
 
 /* Target CPU builtins.  */
 #define TARGET_CPU_CPP_BUILTINS()		\
@@ -138,6 +139,9 @@ along with GCC; see the file COPYING3.  If not see
 /* Specify the registers used for certain standard purposes.
    The values of these macros are register numbers.  */
 
+/* VAX PSW for DWARF-2 */
+#define PSW_REGNUM VAX_PSW_REGNUM
+
 /* VAX pc is overloaded on a register.  */
 #define PC_REGNUM VAX_PC_REGNUM
 
@@ -346,6 +350,10 @@ enum reg_class { NO_REGS, ALL_REGS, LIM_REG_CLASSES };
 					RETURN_ADDRESS_OFFSET))		\
    : (rtx) 0)
 
+/* A C expression that is nonzero if X is a legitimate immediate operand
+   on the target machine when generating position independent code.  */
+
+#define LEGITIMATE_PIC_OPERAND_P(X) legitimate_pic_operand_p (X)
 
 /* Addressing modes, and classification of registers for them.  */
 
diff --git a/gcc/config/vax/vax.md b/gcc/config/vax/vax.md
index bfeae7f80e1..3ea5e51aab6 100644
--- a/gcc/config/vax/vax.md
+++ b/gcc/config/vax/vax.md
@@ -40,6 +40,7 @@
    (VAX_FP_REGNUM 13)	    ; Register 13 contains the frame pointer
    (VAX_SP_REGNUM 14)	    ; Register 14 contains the stack pointer
    (VAX_PC_REGNUM 15)	    ; Register 15 contains the program counter
+   (VAX_PSW_REGNUM 16)	    ; Program Status Word
   ]
 )
 
@@ -215,6 +216,11 @@
   ""
   "
 {
+  if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) <= 48)
+    {
+      emit_insn (gen_movmemsi1_2 (operands[0], operands[1], operands[2]));
+      DONE;
+    }
   emit_insn (gen_movmemhi1 (operands[0], operands[1], operands[2]));
   DONE;
 }")
@@ -224,6 +230,13 @@
 ;; that anything generated as this insn will be recognized as one
 ;; and that it won't successfully combine with anything.
 
+(define_insn "movmemsi1_2"
+  [(set (match_operand:BLK 0 "memory_operand" "=B")
+	(match_operand:BLK 1 "memory_operand" "B"))
+   (use (match_operand:SI 2 "const_int_operand" "g"))]
+  "INTVAL (operands[2]) <= 48"
+  "* return vax_output_movmemsi (insn, operands);")
+
 (define_insn "movmemhi1"
   [(set (match_operand:BLK 0 "memory_operand" "=o")
 	(match_operand:BLK 1 "memory_operand" "o"))
@@ -773,6 +786,9 @@
 ;; These handle aligned 8-bit and 16-bit fields,
 ;; which can usually be done with move instructions.
 
+;; netbsd changed this to REG_P (operands[0]) || (MEM_P (operands[0]) && ...
+;; but gcc made it just !MEM_P (operands[0]) || ...
+
 (define_insn ""
   [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+ro")
 			 (match_operand:QI 1 "const_int_operand" "n")
@@ -780,9 +796,10 @@
 	(match_operand:SI 3 "general_operand" "g"))]
    "(INTVAL (operands[1]) == 8 || INTVAL (operands[1]) == 16)
    && INTVAL (operands[2]) % INTVAL (operands[1]) == 0
-   && (!MEM_P (operands[0])
-       || ! mode_dependent_address_p (XEXP (operands[0], 0),
-				       MEM_ADDR_SPACE (operands[0])))"
+   && (REG_P (operands[0])
+       || (MEM_P (operands[0])
+          && ! mode_dependent_address_p (XEXP (operands[0], 0),
+				       MEM_ADDR_SPACE (operands[0]))))"
   "*
 {
   if (REG_P (operands[0]))
@@ -809,9 +826,10 @@
 			 (match_operand:SI 3 "const_int_operand" "n")))]
   "(INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 16)
    && INTVAL (operands[3]) % INTVAL (operands[2]) == 0
-   && (!MEM_P (operands[1])
-       || ! mode_dependent_address_p (XEXP (operands[1], 0),
-				      MEM_ADDR_SPACE (operands[1])))"
+   && (REG_P (operands[1])
+       || (MEM_P (operands[1])
+          && ! mode_dependent_address_p (XEXP (operands[1], 0),
+				      MEM_ADDR_SPACE (operands[1]))))"
   "*
 {
   if (REG_P (operands[1]))
@@ -837,9 +855,10 @@
 			 (match_operand:SI 3 "const_int_operand" "n")))]
   "(INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 16)
    && INTVAL (operands[3]) % INTVAL (operands[2]) == 0
-   && (!MEM_P (operands[1])
-       || ! mode_dependent_address_p (XEXP (operands[1], 0),
-				      MEM_ADDR_SPACE (operands[1])))"
+   && (REG_P (operands[1])
+       || (MEM_P (operands[1])
+          && ! mode_dependent_address_p (XEXP (operands[1], 0),
+				      MEM_ADDR_SPACE (operands[1]))))"
   "*
 {
   if (REG_P (operands[1]))
@@ -1660,3 +1679,50 @@
   emit_barrier ();
   DONE;
 })
+
+(include "builtins.md")
+
+(define_peephole2
+  [(set (match_operand:SI 0 "push_operand" "")
+        (const_int 0))
+   (set (match_dup 0)
+        (match_operand:SI 1 "const_int_operand" ""))]
+  "INTVAL (operands[1]) >= 0"
+  [(set (match_dup 0)
+        (match_dup 1))]
+  "operands[0] = gen_rtx_MEM(DImode, XEXP (operands[0], 0));")
+
+(define_peephole2
+  [(set (match_operand:SI 0 "push_operand" "")
+        (match_operand:SI 1 "general_operand" ""))
+   (set (match_dup 0)
+        (match_operand:SI 2 "general_operand" ""))]
+  "vax_decomposed_dimode_operand_p (operands[2], operands[1])"
+  [(set (match_dup 0)
+        (match_dup 2))]
+  "{
+    operands[0] = gen_rtx_MEM(DImode, XEXP (operands[0], 0));
+    operands[2] = REG_P (operands[2])
+      ? gen_rtx_REG(DImode, REGNO (operands[2]))
+      : gen_rtx_MEM(DImode, XEXP (operands[2], 0));
+}")
+
+; Leave this commented out until we can determine whether the second move
+; precedes a jump which relies on the CC flags being set correctly.
+(define_peephole2
+  [(set (match_operand:SI 0 "nonimmediate_operand" "")
+        (match_operand:SI 1 "general_operand" ""))
+   (set (match_operand:SI 2 "nonimmediate_operand" "")
+        (match_operand:SI 3 "general_operand" ""))]
+  "0 && vax_decomposed_dimode_operand_p (operands[1], operands[3])
+   && vax_decomposed_dimode_operand_p (operands[0], operands[2])"
+  [(set (match_dup 0)
+        (match_dup 1))]
+  "{
+    operands[0] = REG_P (operands[0])
+      ? gen_rtx_REG(DImode, REGNO (operands[0]))
+      : gen_rtx_MEM(DImode, XEXP (operands[0], 0));
+    operands[1] = REG_P (operands[1])
+      ? gen_rtx_REG(DImode, REGNO (operands[1]))
+      : gen_rtx_MEM(DImode, XEXP (operands[1], 0));
+}")
