$NetBSD: patch-bb,v 1.2 2002/03/28 10:11:54 jmc Exp $

--- ../gcc-2.95.3/gcc/config/vax/vax.c.orig 2000/07/26 00:18:55 1.1.1.1
+++ ../gcc-2.95.3/gcc/config/vax/vax.c 2002/02/23 21:02:50 1.11
@@ -19,19 +19,24 @@
 Boston, MA 02111-1307, USA.  */
 
 #include "config.h"
-#include <stdio.h>
+#include "system.h"
 #include "rtl.h"
 #include "regs.h"
 #include "hard-reg-set.h"
 #include "real.h"
 #include "insn-config.h"
+#include "insn-codes.h"
 #include "conditions.h"
 #include "insn-flags.h"
+/*#include "function.h"*/
 #include "output.h"
 #include "insn-attr.h"
 #ifdef VMS_TARGET
 #include "tree.h"
 #endif
+#include "reload.h"
+#include "recog.h"
+/*#include "tm_p.h"*/
 
 /* This is like nonimmediate_operand with a restriction on the type of MEM.  */
 
@@ -43,8 +48,9 @@
   int i;
   /* Split operands.  */
 
-  low[0] = low[1] = low[2] = 0;
-  for (i = 0; i < 3; i++)
+  for (i = 0; i < n; i++)
+    low[i] = 0;
+  for (i = 0; i < n; i++)
     {
       if (low[i])
 	/* it's already been figured out */;
@@ -52,7 +58,7 @@
 	       && (GET_CODE (XEXP (operands[i], 0)) == POST_INC))
 	{
 	  rtx addr = XEXP (operands[i], 0);
-	  operands[i] = low[i] = gen_rtx (MEM, SImode, addr);
+	  operands[i] = low[i] = gen_rtx_MEM (SImode, addr);
 	  if (which_alternative == 0 && i == 0)
 	    {
 	      addr = XEXP (operands[i], 0);
@@ -71,9 +77,25 @@
      FILE *file;
      register rtx addr;
 {
-  register rtx reg1, reg2, breg, ireg;
+  register rtx reg1, breg, ireg;
   rtx offset;
+  rtx orig_addr = addr;
 
+#if 0
+  if (GET_CODE (addr) == PLUS && GET_CODE (XEXP (addr, 1)) == CONST)
+    debug_rtx (addr);
+#endif
+#ifdef NO_EXTERNAL_INDIRECT_ADDRESS
+  if (flag_pic && GET_CODE (addr) == CONST &&
+      GET_CODE (XEXP (addr, 0)) == PLUS &&
+      GET_CODE (XEXP (XEXP (addr, 0), 0)) == SYMBOL_REF &&
+      !SYMBOL_REF_FLAG (XEXP (XEXP (addr, 0), 0)) &&
+      GET_CODE (XEXP (XEXP (addr, 0), 1)) == CONST_INT)
+    {
+      fatal_insn ("Non-PIC operand escaped:\n", addr);
+    }
+#endif
+
  retry:
   switch (GET_CODE (addr))
     {
@@ -83,15 +105,20 @@
       goto retry;
 
     case REG:
-      fprintf (file, "(%s)", reg_names[REGNO (addr)]);
+      if (REGNO (addr) >= 16)
+	{
+	  debug_rtx (orig_addr);
+	  abort ();
+	}
+      fprintf (file, "(%s%s)", REGISTER_PREFIX, reg_names[REGNO (addr)]);
       break;
 
     case PRE_DEC:
-      fprintf (file, "-(%s)", reg_names[REGNO (XEXP (addr, 0))]);
+      fprintf (file, "-(%s%s)", REGISTER_PREFIX, reg_names[REGNO (XEXP (addr, 0))]);
       break;
 
     case POST_INC:
-      fprintf (file, "(%s)+", reg_names[REGNO (XEXP (addr, 0))]);
+      fprintf (file, "(%s%s)+", REGISTER_PREFIX, reg_names[REGNO (XEXP (addr, 0))]);
       break;
 
     case PLUS:
@@ -139,7 +166,10 @@
 	  addr = XEXP (addr, 1);
 	}
       else
-	abort ();
+	{
+	  debug_rtx (orig_addr);
+	  abort ();
+	}
 
       if (GET_CODE (addr) == REG)
 	{
@@ -162,7 +192,10 @@
 		  else if (GET_CODE (XEXP (addr, 0)) == CONST_INT)
 		    offset = plus_constant (offset, INTVAL (XEXP (addr, 0)));
 		  else
-		    abort ();
+		    {
+		      debug_rtx (orig_addr);
+		      abort ();
+		    }
 		}
 	      offset = XEXP (addr, 0);
 	    }
@@ -176,11 +209,17 @@
 	  else if (GET_CODE (XEXP (addr, 0)) == MULT)
 	    {
 	      if (ireg)
-		abort ();
+		{
+		  debug_rtx (orig_addr);
+		  abort ();
+		}
 	      ireg = XEXP (addr, 0);
 	    }
 	  else
-	    abort ();
+	    {
+	      debug_rtx (orig_addr);
+	      abort ();
+	    }
 
 	  if (CONSTANT_ADDRESS_P (XEXP (addr, 1))
 	      || GET_CODE (XEXP (addr, 1)) == MEM)
@@ -192,7 +231,10 @@
 		  else if (GET_CODE (XEXP (addr, 1)) == CONST_INT)
 		    offset = plus_constant (offset, INTVAL (XEXP (addr, 1)));
 		  else
-		    abort ();
+		    {
+		      debug_rtx (orig_addr);
+		      abort ();
+		    }
 		}
 	      offset = XEXP (addr, 1);
 	    }
@@ -206,22 +248,49 @@
 	  else if (GET_CODE (XEXP (addr, 1)) == MULT)
 	    {
 	      if (ireg)
-		abort ();
+		{
+		  debug_rtx (orig_addr);
+		  abort ();
+		}
 	      ireg = XEXP (addr, 1);
 	    }
+	  else if (GET_CODE (addr) == SYMBOL_REF)
+	    {
+	      output_addr_const (file, addr);
+	      if (offset != 0)
+		{
+		  fputc ('+', file);
+		  output_address (offset);
+		  offset = 0;
+		}
+	    }
 	  else
-	    abort ();
+	    {
+	      debug_rtx (orig_addr);
+	      abort ();
+	    }
 	}
       else
-	abort ();
+	{
+	  debug_rtx (orig_addr);
+	  abort ();
+	}
 
       /* If REG1 is non-zero, figure out if it is a base or index register.  */
       if (reg1)
 	{
-	  if (breg != 0 || (offset && GET_CODE (offset) == MEM))
+	  if (breg != 0
+	      || GET_CODE (addr) == SYMBOL_REF
+	      || (offset
+		   && (GET_CODE (offset) == MEM
+		       || GET_CODE (offset) == SYMBOL_REF
+		       || GET_CODE (offset) == CONST)))
 	    {
 	      if (ireg)
-		abort ();
+		{
+		  debug_rtx (orig_addr);
+		  abort ();
+		}
 	      ireg = reg1;
 	    }
 	  else
@@ -232,15 +301,25 @@
 	output_address (offset);
 
       if (breg != 0)
-	fprintf (file, "(%s)", reg_names[REGNO (breg)]);
+	{
+	  if (REGNO (breg) >= 16)
+	    {
+	      debug_rtx (orig_addr);
+	      abort ();
+	    }
+	  fprintf (file, "(%s%s)", REGISTER_PREFIX, reg_names[REGNO (breg)]);
+	}
 
       if (ireg != 0)
 	{
 	  if (GET_CODE (ireg) == MULT)
 	    ireg = XEXP (ireg, 0);
 	  if (GET_CODE (ireg) != REG)
-	    abort ();
-	  fprintf (file, "[%s]", reg_names[REGNO (ireg)]);
+	    {
+	      debug_rtx (orig_addr);
+	      abort ();
+	    }
+	  fprintf (file, "[%s%s]", REGISTER_PREFIX, reg_names[REGNO (ireg)]);
 	}
       break;
 
@@ -249,7 +328,7 @@
     }
 }
 
-char *
+const char *
 rev_cond_name (op)
      rtx op;
 {
@@ -286,8 +365,10 @@
     register rtx c;
 {
   register enum machine_mode mode;
+#if HOST_FLOAT_FORMAT == VAX_FLOAT_FORMAT
   int i;
   union {double d; int i[2];} val;
+#endif
 
   if (GET_CODE (c) != CONST_DOUBLE)
     return 0;
@@ -323,7 +404,8 @@
    2 - indirect */
 
 
-int vax_address_cost(addr)
+int
+vax_address_cost (addr)
     register rtx addr;
 {
   int reg = 0, indexed = 0, indir = 0, offset = 0, predec = 0;
@@ -365,6 +447,8 @@
       indir = 2;	/* 3 on VAX 2 */
       addr = XEXP (addr, 0);
       goto restart;
+    default:
+      break;
     }
 
   /* Up to 3 things can be added in an address.  They are stored in
@@ -402,7 +486,7 @@
   enum machine_mode mode = GET_MODE (x);
   register int c;
   int i = 0;				/* may be modified in switch */
-  char *fmt = GET_RTX_FORMAT (code);	/* may be modified in switch */
+  const char *fmt = GET_RTX_FORMAT (code); /* may be modified in switch */
 
   switch (code)
     {
@@ -427,6 +511,8 @@
 	case QImode:
 	  c = 10;		/* 3-4 on VAX 9000, 20-28 on VAX 2 */
 	  break;
+	default:
+	  break;
 	}
       break;
     case UDIV:
@@ -582,7 +668,7 @@
 
 /* Check a `double' value for validity for a particular machine mode.  */
 
-static char *float_strings[] =
+static const char *const float_strings[] =
 {
    "1.70141173319264430e+38", /* 2^127 (2^24 - 1) / 2^24 */
   "-1.70141173319264430e+38",
@@ -621,7 +707,7 @@
   if ((mode) == SFmode)
     {
       REAL_VALUE_TYPE r;
-      bcopy ((char *) d, (char *) &r, sizeof (REAL_VALUE_TYPE));
+      memcpy (&r, d, sizeof (REAL_VALUE_TYPE));
       if (REAL_VALUES_LESS (float_values[0], r))
 	{
 	  bcopy ((char *) &float_values[0], (char *) d,
@@ -651,6 +737,338 @@
   return 0;
 }
 
+/* Nonzero if X is a hard reg that can be used as an index.  */
+#define XREG_OK_FOR_INDEX_P(X, STRICT) (!(STRICT) || REGNO_OK_FOR_INDEX_P (REGNO (X)))
+/* Nonzero if X is a hard reg that can be used as a base reg.  */
+#define XREG_OK_FOR_BASE_P(X, STRICT) (!(STRICT) || REGNO_OK_FOR_BASE_P (REGNO (X)))
+
+#ifdef NO_EXTERNAL_INDIRECT_ADDRESS
+
+/* Re-definition of CONSTANT_ADDRESS_P, which is true only when there
+   are no SYMBOL_REFs for external symbols present and allow valid
+   addressing modes.  */
+
+#define INDIRECTABLE_CONSTANT_ADDRESS_P(X, INDEXED, INDIRECT)		\
+  (GET_CODE (X) == LABEL_REF 						\
+   || (!INDEXED && GET_CODE (X) == SYMBOL_REF				\
+       && (!INDIRECT || SYMBOL_REF_FLAG (X)))				\
+   || (!INDEXED && GET_CODE (X) == CONST				\
+       && GET_CODE (XEXP ((X), 0)) == PLUS				\
+       && GET_CODE (XEXP (XEXP ((X), 0), 0)) == SYMBOL_REF		\
+       && ((!INDIRECT && !flag_pic)					\
+           || SYMBOL_REF_FLAG (XEXP (XEXP ((X), 0), 0))))		\
+   || GET_CODE (X) == CONST_INT)
+
+/* Non-zero if X is an address which can be indirected.  External symbols
+   could be in a sharable image library, so we disallow those.  */
+
+#define INDIRECTABLE_ADDRESS_P(X, STRICT, INDEXED, INDIRECT)		\
+  (INDIRECTABLE_CONSTANT_ADDRESS_P (X, INDEXED, INDIRECT) 		\
+   || (GET_CODE (X) == REG && XREG_OK_FOR_BASE_P (X, STRICT))		\
+   || (GET_CODE (X) == PLUS						\
+       && GET_CODE (XEXP (X, 0)) == REG					\
+       && XREG_OK_FOR_BASE_P (XEXP (X, 0), STRICT)			\
+       && GET_CODE (XEXP (X, 1)) != SYMBOL_REF				\
+       && !(GET_CODE (XEXP (X, 1)) == CONST				\
+	    && GET_CODE (XEXP (XEXP (X, 1), 0)) == PLUS			\
+	    && GET_CODE (XEXP (XEXP (XEXP (X, 1), 0), 0)) == SYMBOL_REF) \
+       && INDIRECTABLE_CONSTANT_ADDRESS_P (XEXP (X, 1), INDEXED, INDIRECT)))
+
+#else /* not NO_EXTERNAL_INDIRECT_ADDRESS */
+
+#define INDIRECTABLE_CONSTANT_ADDRESS_P(X, INDEXED, INDIRECT) \
+   CONSTANT_ADDRESS_P (X)
+
+/* Non-zero if X is an address which can be indirected.  */
+#define INDIRECTABLE_ADDRESS_P(X, STRICT, INDEXED, INDIRECT)	\
+  (INDIRECTABLE_CONSTANT_ADDRESS_P (X, INDEXED, INDIRECT)	\
+   || (GET_CODE (X) == REG && XREG_OK_FOR_BASE_P (X, STRICT))	\
+   || (GET_CODE (X) == PLUS					\
+       && GET_CODE (XEXP (X, 0)) == REG				\
+       && XREG_OK_FOR_BASE_P (XEXP (X, 0), STRICT)		\
+       && CONSTANT_ADDRESS_P (XEXP (X, 1))))
+
+#endif /* not NO_EXTERNAL_INDIRECT_ADDRESS */
+
+/* Go to ADDR if X is a valid address not using indexing.
+   (This much is the easy part.)  */
+#define GO_IF_NONINDEXED_ADDRESS(X, ADDR, STRICT, INDEXED)		\
+{ register rtx xfoob = (X);						\
+  if (GET_CODE (X) == REG)						\
+    {									\
+      extern rtx *reg_equiv_mem;					\
+      if (! reload_in_progress)						\
+	goto ADDR;							\
+      if (!STRICT)							\
+	{								\
+	  if ((xfoob = reg_equiv_mem[REGNO (xfoob)]) == 0)		\
+	    goto ADDR;							\
+	}								\
+      if (INDIRECTABLE_ADDRESS_P (xfoob, STRICT, INDEXED, 0))		\
+	goto ADDR;							\
+    }									\
+  if (INDIRECTABLE_CONSTANT_ADDRESS_P (X, INDEXED, 0)) goto ADDR;	\
+  if (INDIRECTABLE_ADDRESS_P (X, STRICT, INDEXED, 0)) goto ADDR;	\
+  xfoob = XEXP (X, 0);							\
+  if (GET_CODE (X) == MEM						\
+      && INDIRECTABLE_ADDRESS_P (xfoob, STRICT, INDEXED, !TARGET_INDIRECT)) \
+    goto ADDR;								\
+  if ((GET_CODE (X) == PRE_DEC || GET_CODE (X) == POST_INC)		\
+      && GET_CODE (xfoob) == REG					\
+      && XREG_OK_FOR_BASE_P (xfoob, STRICT))				\
+    goto ADDR; }
+
+/* 1 if PROD is either a reg times size of mode MODE
+   or just a reg, if MODE is just one byte.
+   This macro's expansion uses the temporary variables xfoo0 and xfoo1
+   that must be declared in the surrounding context.  */
+#define INDEX_TERM_P(PROD, MODE, STRICT)   \
+(GET_MODE_SIZE (MODE) == 1						\
+ ? (GET_CODE (PROD) == REG && XREG_OK_FOR_BASE_P (PROD, STRICT))	\
+ : (GET_CODE (PROD) == MULT						\
+    &&									\
+    (xfoo0 = XEXP (PROD, 0), xfoo1 = XEXP (PROD, 1),			\
+     ((GET_CODE (xfoo0) == CONST_INT					\
+       && GET_CODE (xfoo1) == REG					\
+       && INTVAL (xfoo0) == (int)GET_MODE_SIZE (MODE)			\
+       && XREG_OK_FOR_INDEX_P (xfoo1, STRICT))				\
+      ||								\
+      (GET_CODE (xfoo1) == CONST_INT					\
+       && GET_CODE (xfoo0) == REG					\
+       && INTVAL (xfoo1) == (int)GET_MODE_SIZE (MODE)			\
+       && XREG_OK_FOR_INDEX_P (xfoo0, STRICT))))))
+
+/* Go to ADDR if X is the sum of a register
+   and a valid index term for mode MODE.  */
+#define GO_IF_REG_PLUS_INDEX(X, MODE, ADDR, STRICT)	\
+{ register rtx xfooa;					\
+  if (GET_CODE (X) == PLUS)				\
+    { if (GET_CODE (XEXP (X, 0)) == REG			\
+	  && XREG_OK_FOR_BASE_P (XEXP (X, 0), STRICT)	\
+	  && (xfooa = XEXP (X, 1),			\
+	      INDEX_TERM_P (xfooa, MODE, STRICT)))	\
+	goto ADDR;					\
+      if (GET_CODE (XEXP (X, 1)) == REG			\
+	  && XREG_OK_FOR_BASE_P (XEXP (X, 1), STRICT)	\
+	  && (xfooa = XEXP (X, 0),			\
+	      INDEX_TERM_P (xfooa, MODE, STRICT)))	\
+	goto ADDR; } }
+
+int
+legitimate_pic_operand_p(x, strict)
+     register rtx x;
+     int strict ATTRIBUTE_UNUSED;
+{
+  if (GET_CODE (x) != SYMBOL_REF
+      && !(GET_CODE (x) == CONST
+	  && GET_CODE (XEXP (x, 0)) == PLUS
+	  && GET_CODE (XEXP (XEXP (x, 0), 0)) == SYMBOL_REF))
+    {
+      return 1;
+    }
+  return 0;
+}
+
+int
+legitimate_address_p(mode, xbar, strict)
+     enum machine_mode mode;
+     register rtx xbar;
+     int strict;
+{
+  register rtx xfoo, xfoo0, xfoo1;
+  int from = __LINE__;
+  GO_IF_NONINDEXED_ADDRESS (xbar, win, strict, 0);
+  if (GET_CODE (xbar) == PLUS)
+    {
+      /* Handle <address>[index] represented with index-sum outermost */
+      xfoo = XEXP (xbar, 0);
+      if (INDEX_TERM_P (xfoo, mode, strict))
+	{
+	  from = __LINE__;
+	  GO_IF_NONINDEXED_ADDRESS (XEXP (xbar, 1), win, strict, 0);
+	}
+      xfoo = XEXP (xbar, 1);
+      if (INDEX_TERM_P (xfoo, mode, strict))
+	{
+	  from = __LINE__;
+	  GO_IF_NONINDEXED_ADDRESS (XEXP (xbar, 0), win, strict, 0);
+	}
+      /* Handle offset(reg)[index] with offset added outermost */
+      if (INDIRECTABLE_CONSTANT_ADDRESS_P (XEXP (xbar, 0), 1, 0))
+	{
+	  from = __LINE__;
+	   if (GET_CODE (XEXP (xbar, 1)) == REG
+	      && XREG_OK_FOR_BASE_P (XEXP (xbar, 1), strict))
+	    goto win;
+	  from = __LINE__;
+	  GO_IF_REG_PLUS_INDEX (XEXP (xbar, 1), mode, win, strict);
+	}
+      if (INDIRECTABLE_CONSTANT_ADDRESS_P (XEXP (xbar, 1), 1, 0))
+	{
+	  from = __LINE__;
+	  if (GET_CODE (XEXP (xbar, 0)) == REG
+	      && XREG_OK_FOR_BASE_P (XEXP (xbar, 0), strict))
+	    goto win;
+	  from = __LINE__;
+	  GO_IF_REG_PLUS_INDEX (XEXP (xbar, 0), mode, win, strict);
+	}
+  }
+  return 0;
+
+ win:
+#if 0
+  if (strict)
+    {
+      fprintf(stderr, "line=%d\n", from);
+      debug_rtx (xbar);
+    }
+#endif
+  if (flag_pic && GET_CODE (xbar) == SYMBOL_REF
+#ifdef NO_EXTERNAL_INDIRECT_ADDRESS
+	     && !SYMBOL_REF_FLAG (xbar)
+#endif
+	     && mode == DImode)
+    return 0;
+  return 1;
+}
+
+int
+vax_symbolic_operand (op, mode)
+     register rtx op;
+     enum machine_mode mode ATTRIBUTE_UNUSED;
+{
+  if (!general_operand(op, mode))
+    return 0;
+  if (GET_CODE (op) == SYMBOL_REF
+	 || GET_CODE (op) == LABEL_REF
+	 || (GET_CODE (op) == CONST
+	     && GET_CODE (XEXP (op, 0)) == PLUS
+	     && GET_CODE (XEXP (XEXP (op, 0), 0)) == SYMBOL_REF
+#ifdef NO_EXTERNAL_INDIRECT_ADDRESS
+	     && (SYMBOL_REF_FLAG (XEXP (XEXP (op, 0), 0)) || !flag_pic)
+#endif
+	     && GET_CODE (XEXP (XEXP (op, 0), 1)) == CONST_INT)
+	 || (GET_CODE (op) == PLUS
+	     && GET_CODE (XEXP (op, 1)) == SYMBOL_REF
+#ifdef NO_EXTERNAL_INDIRECT_ADDRESS
+	     && (SYMBOL_REF_FLAG (XEXP (op, 1)) || !flag_pic)
+#endif
+	     && GET_CODE (XEXP (op, 0)) == CONST_INT)
+	 || (GET_CODE (op) == PLUS
+	     && GET_CODE (XEXP (op, 0)) == SYMBOL_REF
+#ifdef NO_EXTERNAL_INDIRECT_ADDRESS
+	     && (SYMBOL_REF_FLAG (XEXP (op, 0)) || !flag_pic)
+#endif
+	     && GET_CODE (XEXP (op, 1)) == CONST_INT))
+    {
+      return 1;
+    }
+  return 0;
+}
+
+int
+vax_nonsymbolic_operand (op, mode)
+     register rtx op;
+     enum machine_mode mode ATTRIBUTE_UNUSED;
+{
+  if (!general_operand(op, mode))
+    return 0;
+  if (GET_CODE (op) == SYMBOL_REF
+	 || GET_CODE (op) == LABEL_REF
+	 || (GET_CODE (op) == CONST
+	     && GET_CODE (XEXP (op, 0)) == PLUS
+	     && GET_CODE (XEXP (XEXP (op, 0), 0)) == SYMBOL_REF)
+	 || (GET_CODE (op) == MEM
+	     && GET_CODE (XEXP (op, 0)) == CONST
+	     && GET_CODE (XEXP (XEXP (op, 0), 0)) == PLUS
+	     && GET_CODE (XEXP (XEXP (XEXP (op, 0), 0), 0)) == SYMBOL_REF)
+	 || (GET_CODE (op) == PLUS
+	     && GET_CODE (XEXP (op, 0)) == SYMBOL_REF
+	     && GET_CODE (XEXP (op, 1)) == CONST_INT))
+    return 0;
+#if 0
+  if (GET_CODE (op) == PLUS)
+    debug_rtx (op);
+#endif
+  if (vax_symbolic_operand (op, mode))
+    return 0;
+#if 0
+  if (GET_CODE (op) != CONST_INT && GET_CODE (op) != REG &&
+      GET_CODE (op) != MEM)
+    debug_rtx (op);
+#endif
+  return 1;
+}
+
+int
+vax_lvalue_operand(op, mode)
+     register rtx op;
+     enum machine_mode mode;
+{
+  if (!general_operand(op, mode))
+    return 0;
+  return GET_CODE (op) == REG
+	|| GET_CODE (op) == SUBREG
+	|| GET_CODE (op) == MEM
+	|| GET_CODE (op) == CONCAT
+	|| GET_CODE (op) == PARALLEL
+	|| GET_CODE (op) == STRICT_LOW_PART;
+}
+
+int
+vax_general_operand(op, mode)
+     register rtx op;
+     enum machine_mode mode;
+{
+  if (!general_operand(op, mode))
+    return 0;
+  if (!flag_pic)
+    return 1;
+  if ((GET_CODE (op) == CONST
+       && GET_CODE (XEXP (op, 0)) == PLUS
+       && GET_CODE (XEXP (XEXP (op, 0), 0)) == SYMBOL_REF
+#ifdef NO_EXTERNAL_INDIRECT_ADDRESS
+       && !SYMBOL_REF_FLAG (XEXP (XEXP (op, 0), 0))
+#endif
+      ) || (GET_CODE (op) == MEM
+          && GET_CODE (XEXP (op, 0)) == CONST
+          && GET_CODE (XEXP (XEXP (op, 0), 0)) == PLUS
+          && GET_CODE (XEXP (XEXP (XEXP (op, 0), 0), 0)) == SYMBOL_REF
+#ifdef NO_EXTERNAL_INDIRECT_ADDRESS
+          && !SYMBOL_REF_FLAG (XEXP (XEXP (op, 0), 0))
+#endif
+      ) || (GET_CODE (op) == PLUS
+          && GET_CODE (XEXP (op, 0)) == SYMBOL_REF
+          && GET_CODE (XEXP (op, 1)) == CONST_INT
+#ifdef NO_EXTERNAL_INDIRECT_ADDRESS
+          && !SYMBOL_REF_FLAG (XEXP (op, 0))
+#endif
+     ))
+    return 0;
+#if 0
+  debug_rtx (op);
+#endif
+  return 1;
+}
+
+int
+vax_reg_used_p(operand, reg)
+     rtx operand;
+     int reg;
+{
+   if (GET_CODE (operand) == REG && REGNO (operand) == reg)
+     return 1;
+   if (GET_CODE (operand) == MEM ||
+       GET_CODE (operand) == PRE_DEC ||
+       GET_CODE (operand) == POST_DEC)
+     return vax_reg_used_p (XEXP(operand, 0), reg);
+   if (GET_CODE (operand) == PLUS ||
+       GET_CODE (operand) == MULT)
+     return vax_reg_used_p (XEXP(operand, 0), reg) ||
+	    vax_reg_used_p (XEXP(operand, 1), reg);
+   return 0;
+}
+
 #ifdef VMS_TARGET
 /* Additional support code for VMS target. */
 
@@ -661,7 +1079,7 @@
 static
 struct extern_list {
   struct extern_list *next;	/* next external */
-  char *name;			/* name of the external */
+  const char *name;		/* name of the external */
   int size;			/* external's actual size */
   int in_const;			/* section type flag */
 } *extern_head = 0, *pending_head = 0;
@@ -672,7 +1090,7 @@
 void
 vms_check_external (decl, name, pending)
      tree decl;
-     char *name;
+     const char *name;
      int pending;
 {
   register struct extern_list *p, *p0;
