]> git.ipfire.org Git - thirdparty/gcc.git/blobdiff - gcc/config/vax/vax.h
Update copyright years.
[thirdparty/gcc.git] / gcc / config / vax / vax.h
index d52f31d854e3a9cbb1f0b950ae210cf295498a4c..c1d0171d94da15750225aeaf766b00d492cf080f 100644 (file)
@@ -1,23 +1,21 @@
 /* Definitions of target machine for GNU compiler.  VAX version.
-   Copyright (C) 1987, 1988, 1991, 1993, 1994, 1995, 1996, 1997, 1998,
-   1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+   Copyright (C) 1987-2020 Free Software Foundation, Inc.
 
-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/>.  */
 
 
 /* Target CPU builtins.  */
@@ -35,8 +33,6 @@ Boston, MA 02111-1307, USA.  */
     }                                          \
   while (0)
 
-#define VMS_TARGET 0
-
 /* Use -J option for long branch support with Unix assembler.  */
 
 #define ASM_SPEC "-J"
@@ -51,55 +47,13 @@ Boston, MA 02111-1307, USA.  */
   %{pg:%eprofiling not supported with -mg\n}}\
  %{!mg:%{!p:%{!pg:-lc}}%{p:-lc_p}%{pg:-lc_p}}"
 
-/* Print subsidiary information on the compiler version in use.  */
-
-#ifndef TARGET_NAME    /* A more specific value might be supplied via -D.  */
-#define TARGET_NAME "vax"
-#endif
-#define TARGET_VERSION fprintf (stderr, " (%s)", TARGET_NAME)
-
 /* Run-time compilation parameters selecting different hardware subsets.  */
 
-extern int target_flags;
-
-#define MASK_UNIX_ASM          1
-#define MASK_VAXC_ALIGNMENT    2
-#define MASK_G_FLOAT           4
-
-
-/* Macros used in the machine description to test the flags.  */
-
-/* Nonzero if compiling code that Unix assembler can assemble.  */
-#define TARGET_UNIX_ASM (target_flags & MASK_UNIX_ASM)
+/* Nonzero if ELF.  Redefined by vax/elf.h.  */
+#define TARGET_ELF 0
 
-/* Nonzero if compiling with VAX-11 "C" style structure alignment */
-#define        TARGET_VAXC_ALIGNMENT (target_flags & MASK_VAXC_ALIGNMENT)
-
-/* Nonzero if compiling with `G'-format floating point */
-#define TARGET_G_FLOAT (target_flags & MASK_G_FLOAT)
-
-/* Macro to define tables used to set the flags.
-   This is a list in braces of pairs in braces,
-   each pair being { "NAME", VALUE }
-   where VALUE is the bits to set or minus the bits to clear.
-   An empty string NAME is used to identify the default VALUE.  */
-
-#define TARGET_SWITCHES                                                \
-  { {"unix", MASK_UNIX_ASM,                                    \
-     "Generate code for UNIX assembler"},                      \
-    {"gnu", -MASK_UNIX_ASM,                                    \
-     "Generate code for GNU assembler (gas)"},                 \
-    {"vaxc-alignment", MASK_VAXC_ALIGNMENT,                    \
-     "Use VAXC structure conventions"},                        \
-    {"g", MASK_G_FLOAT,                                                \
-     "Generate GFLOAT double precision code"},                 \
-    {"g-float", MASK_G_FLOAT,                                  \
-     "Generate GFLOAT double precision code"},                 \
-    {"d", -MASK_G_FLOAT,                                       \
-     "Generate DFLOAT double precision code"},                 \
-    {"d-float", -MASK_G_FLOAT,                                 \
-     "Generate DFLOAT double precision code"},                 \
-    { "", TARGET_DEFAULT, 0}}
+/* Use BSD names for udiv and umod libgcc calls.  */
+#define TARGET_BSD_DIVMOD 1
 
 /* Default target_flags if no switches specified.  */
 
@@ -107,8 +61,6 @@ extern int target_flags;
 #define TARGET_DEFAULT (MASK_UNIX_ASM)
 #endif
 
-#define OVERRIDE_OPTIONS override_options ()
-
 \f
 /* Target machine storage layout */
 
@@ -183,51 +135,30 @@ extern int target_flags;
    Aside from that, you can include as many other registers as you like.  */
 #define CALL_USED_REGISTERS {1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1}
 
-/* Return number of consecutive hard regs needed starting at reg REGNO
-   to hold something of mode MODE.
-   This is ordinarily the length in words of a value of mode MODE
-   but can be less for certain modes in special long registers.
-   On the VAX, all registers are one word long.  */
-#define HARD_REGNO_NREGS(REGNO, MODE)   \
- ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
-
-/* Value is 1 if hard register REGNO can hold a value of machine-mode MODE.
-   On the VAX, all registers can hold all modes.  */
-#define HARD_REGNO_MODE_OK(REGNO, MODE) 1
-
-/* Value is 1 if it is a good idea to tie two pseudo registers
-   when one has mode MODE1 and one has mode MODE2.
-   If HARD_REGNO_MODE_OK could produce different values for MODE1 and MODE2,
-   for any hard reg, then this must be 0 for correct output.  */
-#define MODES_TIEABLE_P(MODE1, MODE2)  1
-
 /* Specify the registers used for certain standard purposes.
    The values of these macros are register numbers.  */
 
 /* VAX pc is overloaded on a register.  */
-#define PC_REGNUM 15
+#define PC_REGNUM VAX_PC_REGNUM
 
 /* Register to use for pushing function arguments.  */
-#define STACK_POINTER_REGNUM 14
+#define STACK_POINTER_REGNUM VAX_SP_REGNUM
 
 /* Base register for access to local variables of the function.  */
-#define FRAME_POINTER_REGNUM 13
+#define FRAME_POINTER_REGNUM VAX_FP_REGNUM
 
-/* Value should be nonzero if functions must have frame pointers.
-   Zero means the frame pointer need not be set up (and parms
-   may be accessed via the stack pointer) in functions that seem suitable.
-   This is computed in `reload', in reload1.c.  */
-#define FRAME_POINTER_REQUIRED 1
+/* Offset from the frame pointer register value to the top of stack.  */
+#define FRAME_POINTER_CFA_OFFSET(FNDECL) 0
 
 /* Base register for access to arguments of the function.  */
-#define ARG_POINTER_REGNUM 12
+#define ARG_POINTER_REGNUM VAX_AP_REGNUM
 
 /* Register in which static-chain is passed to a function.  */
 #define STATIC_CHAIN_REGNUM 0
 
 /* Register in which address to store a structure value
    is passed to a function.  */
-#define STRUCT_VALUE_REGNUM 1
+#define VAX_STRUCT_VALUE_REGNUM 1
 \f
 /* Define the classes of registers for register constraints in the
    machine description.  Also define ranges of constants.
@@ -248,7 +179,7 @@ extern int target_flags;
 
    For any two classes, it is very desirable that there be another
    class that represents their union.  */
-   
+
 /* The VAX has only one kind of registers, so NO_REGS and ALL_REGS
    are the only classes.  */
 
@@ -263,8 +194,8 @@ enum reg_class { NO_REGS, ALL_REGS, LIM_REG_CLASSES };
 
 /* Give names of register classes as strings for dump file.  */
 
-#define REG_CLASS_NAMES \
{"NO_REGS", "ALL_REGS" }
+#define REG_CLASS_NAMES        \
 { "NO_REGS", "ALL_REGS" }
 
 /* Define which registers fit in which classes.
    This is an initializer for a vector of HARD_REG_SET
@@ -277,97 +208,30 @@ enum reg_class { NO_REGS, ALL_REGS, LIM_REG_CLASSES };
    reg number REGNO.  This could be a conditional expression
    or could index an array.  */
 
-#define REGNO_REG_CLASS(REGNO) ALL_REGS
+#define REGNO_REG_CLASS(REGNO) ((void)(REGNO), ALL_REGS)
 
 /* The class value for index registers, and the one for base regs.  */
 
 #define INDEX_REG_CLASS ALL_REGS
 #define BASE_REG_CLASS ALL_REGS
 
-/* Get reg_class from a letter such as appears in the machine description.  */
-
-#define REG_CLASS_FROM_LETTER(C) NO_REGS
-
-/* The letters I, J, K, L, M, N, and O in a register constraint string
-   can be used to stand for particular ranges of immediate operands.
-   This macro defines what the ranges are.
-   C is the letter, and VALUE is a constant value.
-   Return 1 if VALUE is in the range specified by C.
-
-   `I' is the constant zero.
-   `J' is a value between 0 .. 63 (inclusive)
-   `K' is a value between -128 and 127 (inclusive)
-   'L' is a value between -32768 and 32767 (inclusive)
-   `M' is a value between 0 and 255 (inclusive)
-   'N' is a value between 0 and 65535 (inclusive)
-   `O' is a value between -63 and -1 (inclusive)  */
-
-#define CONST_OK_FOR_LETTER_P(VALUE, C) \
-  (  (C) == 'I' ?      (VALUE) == 0                            \
-   : (C) == 'J' ?      0 <= (VALUE) && (VALUE) < 64            \
-   : (C) == 'O' ?      -63 <= (VALUE) && (VALUE) < 0           \
-   : (C) == 'K' ?      -128 <= (VALUE) && (VALUE) < 128        \
-   : (C) == 'M' ?      0 <= (VALUE) && (VALUE) < 256           \
-   : (C) == 'L' ?      -32768 <= (VALUE) && (VALUE) < 32768    \
-   : (C) == 'N' ?      0 <= (VALUE) && (VALUE) < 65536         \
-   : 0)
-
-/* Similar, but for floating constants, and defining letters G and H.
-   Here VALUE is the CONST_DOUBLE rtx itself. 
-
-   `G' is a floating-point zero.  */
-
-#define CONST_DOUBLE_OK_FOR_LETTER_P(VALUE, C) \
-  ((C) == 'G' ? ((VALUE) == CONST0_RTX (DFmode)                \
-                || (VALUE) == CONST0_RTX (SFmode))     \
-   : 0)
-
-/* Optional extra constraints for this machine.
-
-   For the VAX, `Q' means that OP is a MEM that does not have a mode-dependent
-   address.  */
-
-#define EXTRA_CONSTRAINT(OP, C) \
-  ((C) == 'Q'                                                          \
-   ? GET_CODE (OP) == MEM && ! mode_dependent_address_p (XEXP (OP, 0)) \
-   : 0)
-
-/* Given an rtx X being reloaded into a reg required to be
-   in class CLASS, return the class of reg to actually use.
-   In general this is just CLASS; but on some machines
-   in some cases it is preferable to use a more restrictive class.  */
-
-#define PREFERRED_RELOAD_CLASS(X,CLASS)  (CLASS)
-
-/* Return the maximum number of consecutive registers
-   needed to represent mode MODE in a register of class CLASS.  */
-/* On the VAX, this is always the size of MODE in words,
-   since all registers are the same size.  */
-#define CLASS_MAX_NREGS(CLASS, MODE)   \
- ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
 \f
 /* Stack layout; function entry, exit and calling.  */
 
 /* Define this if pushing a word on the stack
    makes the stack pointer a smaller address.  */
-#define STACK_GROWS_DOWNWARD
+#define STACK_GROWS_DOWNWARD 1
 
-/* Define this if the nominal address of the stack frame
+/* Define this to nonzero if the nominal address of the stack frame
    is at the high-address end of the local variables;
    that is, each additional local variable allocated
    goes at a more negative offset in the frame.  */
-#define FRAME_GROWS_DOWNWARD
-
-/* Offset within stack frame to start allocating local variables at.
-   If FRAME_GROWS_DOWNWARD, this is the offset to the END of the
-   first local allocated.  Otherwise, it is the offset to the BEGINNING
-   of the first local allocated.  */
-#define STARTING_FRAME_OFFSET 0
+#define FRAME_GROWS_DOWNWARD 1
 
 /* Given an rtx for the address of a frame,
    return an rtx for the address of the word in the frame
    that holds the dynamic chain--the previous frame's address.  */
-#define DYNAMIC_CHAIN_ADDRESS(FRAME) plus_constant ((FRAME), 12)
+#define DYNAMIC_CHAIN_ADDRESS(FRAME) plus_constant (Pmode, (FRAME), 12)
 
 /* If we generate an insn to push BYTES bytes,
    this says how many the stack pointer really advances by.
@@ -377,32 +241,20 @@ enum reg_class { NO_REGS, ALL_REGS, LIM_REG_CLASSES };
 /* Offset of first parameter from the argument pointer register value.  */
 #define FIRST_PARM_OFFSET(FNDECL) 4
 
-/* Value is the number of bytes of arguments automatically
-   popped when returning from a subroutine call.
-   FUNDECL is the declaration node of the function (as a tree),
-   FUNTYPE is the data type of the function (as a tree),
-   or for a library call it is an identifier node for the subroutine name.
-   SIZE is the number of bytes of arguments passed on the stack.
-
-   On the VAX, the RET insn pops a maximum of 255 args for any function.  */
-
-#define RETURN_POPS_ARGS(FUNDECL,FUNTYPE,SIZE) \
-  ((SIZE) > 255*4 ? 0 : (SIZE))
-
 /* Define how to find the value returned by a function.
    VALTYPE is the data type of the value (as a tree).
    If the precise function being called is known, FUNC is its FUNCTION_DECL;
    otherwise, FUNC is 0.  */
 
-/* On the VAX the return value is in R0 regardless.  */   
+/* On the VAX the return value is in R0 regardless.  */
 
-#define FUNCTION_VALUE(VALTYPE, FUNC)  \
+#define FUNCTION_VALUE(VALTYPE, FUNC)  \
   gen_rtx_REG (TYPE_MODE (VALTYPE), 0)
 
 /* Define how to find the value returned by a library function
    assuming the value has mode MODE.  */
 
-/* On the VAX the return value is in R0 regardless.  */   
+/* On the VAX the return value is in R0 regardless.  */
 
 #define LIBCALL_VALUE(MODE)  gen_rtx_REG (MODE, 0)
 
@@ -419,7 +271,7 @@ enum reg_class { NO_REGS, ALL_REGS, LIM_REG_CLASSES };
 /* 1 if N is a possible register number for function argument passing.
    On the VAX, no registers are used in this way.  */
 
-#define FUNCTION_ARG_REGNO_P(N) 0
+#define FUNCTION_ARG_REGNO_P(N) ((void) (N), 0)
 \f
 /* Define a data type for recording info about an argument list
    during the scan of that argument list.  This data type should
@@ -438,35 +290,9 @@ enum reg_class { NO_REGS, ALL_REGS, LIM_REG_CLASSES };
 
    On the VAX, the offset starts at 0.  */
 
-#define INIT_CUMULATIVE_ARGS(CUM,FNTYPE,LIBNAME,INDIRECT)      \
+#define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, INDIRECT, N_NAMED_ARGS) \
  ((CUM) = 0)
 
-/* Update the data in CUM to advance over an argument
-   of mode MODE and data type TYPE.
-   (TYPE is null for libcalls where that information may not be available.)  */
-
-#define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED)   \
- ((CUM) += ((MODE) != BLKmode                  \
-           ? (GET_MODE_SIZE (MODE) + 3) & ~3   \
-           : (int_size_in_bytes (TYPE) + 3) & ~3))
-
-/* Define where to put the arguments to a function.
-   Value is zero to push the argument on the stack,
-   or a hard register in which to store the argument.
-
-   MODE is the argument's machine mode.
-   TYPE is the data type of the argument (as a tree).
-    This is null for libcalls where that information may
-    not be available.
-   CUM is a variable of type CUMULATIVE_ARGS which gives info about
-    the preceding args and about the function being called.
-   NAMED is nonzero if this argument is a named parameter
-    (otherwise it is an extra parameter matching an ellipsis).  */
-
-/* On the VAX all args are pushed.  */   
-
-#define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) 0
-
 /* Output assembler code to FILE to increment profiler label # LABELNO
    for profiling a function entry.  */
 
@@ -483,6 +309,16 @@ enum reg_class { NO_REGS, ALL_REGS, LIM_REG_CLASSES };
     }                                                          \
   while (0)
 
+/* This macro specifies a table of register pairs used to eliminate
+   unneeded registers that point into the stack frame.  */
+#define ELIMINABLE_REGS {{FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM}}
+
+/* On the VAX, FRAME_POINTER_REQUIRED is always 1, so the definition of this
+   macro doesn't matter for register eliminations, but it should still
+   give realistic data for rtx_addr_can_trap_p.  */
+#define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \
+  ((OFFSET) = get_frame_size ())
+
 /* EXIT_IGNORE_STACK should be nonzero if, when returning from a function,
    the stack pointer does not matter.  The value is tested only in
    functions that have frame pointers.
@@ -490,54 +326,10 @@ enum reg_class { NO_REGS, ALL_REGS, LIM_REG_CLASSES };
 
 #define EXIT_IGNORE_STACK 1
 
-/* Store in the variable DEPTH the initial difference between the
-   frame pointer reg contents and the stack pointer reg contents,
-   as of the start of the function body.  This depends on the layout
-   of the fixed parts of the stack frame and on how registers are saved.
-
-   On the VAX, FRAME_POINTER_REQUIRED is always 1, so the definition of this
-   macro doesn't matter.  But it must be defined.  */
-
-#define INITIAL_FRAME_POINTER_OFFSET(DEPTH) (DEPTH) = 0;
-
-/* Output assembler code for a block containing the constant parts
-   of a trampoline, leaving space for the variable parts.  */
-
-/* On the VAX, the trampoline contains an entry mask and two instructions:
-     .word NN
-     movl $STATIC,r0   (store the functions static chain)
-     jmp  *$FUNCTION   (jump to function code at address FUNCTION)  */
-
-#define TRAMPOLINE_TEMPLATE(FILE)                                      \
-{                                                                      \
-  assemble_aligned_integer (2, const0_rtx);                            \
-  assemble_aligned_integer (2, GEN_INT (0x8fd0));                      \
-  assemble_aligned_integer (4, const0_rtx);                            \
-  assemble_aligned_integer (1, GEN_INT (0x50 + STATIC_CHAIN_REGNUM));  \
-  assemble_aligned_integer (2, GEN_INT (0x9f17));                      \
-  assemble_aligned_integer (4, const0_rtx);                            \
-}
-
 /* Length in units of the trampoline for entering a nested function.  */
 
 #define TRAMPOLINE_SIZE 15
 
-/* Emit RTL insns to initialize the variable parts of a trampoline.
-   FNADDR is an RTX for the address of the function's pure code.
-   CXT is an RTX for the static chain value for the function.  */
-
-/* We copy the register-mask from the function's pure code
-   to the start of the trampoline.  */
-#define INITIALIZE_TRAMPOLINE(TRAMP, FNADDR, CXT)                      \
-{                                                                      \
-  emit_move_insn (gen_rtx_MEM (HImode, TRAMP),                         \
-                 gen_rtx_MEM (HImode, FNADDR));                        \
-  emit_move_insn (gen_rtx_MEM (SImode, plus_constant (TRAMP, 4)), CXT);        \
-  emit_move_insn (gen_rtx_MEM (SImode, plus_constant (TRAMP, 11)),     \
-                 plus_constant (FNADDR, 2));                           \
-  emit_insn (gen_sync_istream ());                                     \
-}
-
 /* Byte offset of return address in a stack frame.  The "saved PC" field
    is in element [4] when treating the frame as an array of longwords.  */
 
@@ -548,9 +340,10 @@ enum reg_class { NO_REGS, ALL_REGS, LIM_REG_CLASSES };
    FRAMEADDR is already the frame pointer of the COUNT frame, so we
    can ignore COUNT.  */
 
-#define RETURN_ADDR_RTX(COUNT, FRAME)  \
-  ((COUNT == 0)                                \
-   ? gen_rtx_MEM (Pmode, plus_constant (FRAME, RETURN_ADDRESS_OFFSET)) \
+#define RETURN_ADDR_RTX(COUNT, FRAME)                                  \
+  ((COUNT == 0)                                                                \
+   ? gen_rtx_MEM (Pmode, plus_constant (Pmode, FRAME,                  \
+                                       RETURN_ADDRESS_OFFSET))         \
    : (rtx) 0)
 
 \f
@@ -566,12 +359,13 @@ enum reg_class { NO_REGS, ALL_REGS, LIM_REG_CLASSES };
    They give nonzero only if REGNO is a hard reg of the suitable class
    or a pseudo reg currently allocated to a suitable hard reg.
    Since they use reg_renumber, they are safe only once reg_renumber
-   has been allocated, which happens in local-alloc.c.  */
+   has been allocated, which happens in reginfo.c during register
+   allocation.  */
 
-#define REGNO_OK_FOR_INDEX_P(regno)  \
-((regno) < FIRST_PSEUDO_REGISTER || reg_renumber[regno] >= 0)
-#define REGNO_OK_FOR_BASE_P(regno) \
-((regno) < FIRST_PSEUDO_REGISTER || reg_renumber[regno] >= 0)
+#define REGNO_OK_FOR_INDEX_P(regno)    \
+  ((regno) < FIRST_PSEUDO_REGISTER || reg_renumber[regno] >= 0)
+#define REGNO_OK_FOR_BASE_P(regno)     \
+  ((regno) < FIRST_PSEUDO_REGISTER || reg_renumber[regno] >= 0)
 \f
 /* Maximum number of registers that can appear in a valid memory address.  */
 
@@ -579,15 +373,7 @@ enum reg_class { NO_REGS, ALL_REGS, LIM_REG_CLASSES };
 
 /* 1 if X is an rtx for a constant that is a valid address.  */
 
-#define CONSTANT_ADDRESS_P(X)   \
-  (GET_CODE (X) == LABEL_REF || GET_CODE (X) == SYMBOL_REF             \
-   || GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST               \
-   || GET_CODE (X) == HIGH)
-
-/* Nonzero if the constant value X is a legitimate general operand.
-   It is given that X satisfies CONSTANT_P or is a CONST_DOUBLE.  */
-
-#define LEGITIMATE_CONSTANT_P(X) 1
+#define CONSTANT_ADDRESS_P(X) legitimate_constant_address_p (X)
 
 /* The macros REG_OK_FOR..._P assume that the arg is a REG rtx
    and check its validity for a certain class.
@@ -607,6 +393,7 @@ enum reg_class { NO_REGS, ALL_REGS, LIM_REG_CLASSES };
 /* Nonzero if X is a hard reg that can be used as an index
    or if it is a pseudo reg.  */
 #define REG_OK_FOR_INDEX_P(X) 1
+
 /* Nonzero if X is a hard reg that can be used as a base reg
    or if it is a pseudo reg.  */
 #define REG_OK_FOR_BASE_P(X) 1
@@ -615,179 +402,12 @@ enum reg_class { NO_REGS, ALL_REGS, LIM_REG_CLASSES };
 
 /* Nonzero if X is a hard reg that can be used as an index.  */
 #define REG_OK_FOR_INDEX_P(X) REGNO_OK_FOR_INDEX_P (REGNO (X))
+
 /* Nonzero if X is a hard reg that can be used as a base reg.  */
 #define REG_OK_FOR_BASE_P(X) REGNO_OK_FOR_BASE_P (REGNO (X))
 
 #endif
 \f
-/* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression
-   that is a valid memory address for an instruction.
-   The MODE argument is the machine mode for the MEM expression
-   that wants to use this address.
-
-   The other macros defined here are used only in GO_IF_LEGITIMATE_ADDRESS,
-   except for CONSTANT_ADDRESS_P which is actually machine-independent.  */
-
-#ifdef NO_EXTERNAL_INDIRECT_ADDRESS
-
-/* Zero if this contains a (CONST (PLUS (SYMBOL_REF) (...))) and the
-   symbol in the SYMBOL_REF is an external symbol.  */
-
-#define INDIRECTABLE_CONSTANT_P(X) \
- (! (GET_CODE ((X)) == CONST                                   \
-     && GET_CODE (XEXP ((X), 0)) == PLUS                       \
-     && GET_CODE (XEXP (XEXP ((X), 0), 0)) == SYMBOL_REF       \
-     && SYMBOL_REF_FLAG (XEXP (XEXP ((X), 0), 0))))
-
-/* Re-definition of CONSTANT_ADDRESS_P, which is true only when there
-   are no SYMBOL_REFs for external symbols present.  */
-
-#define INDIRECTABLE_CONSTANT_ADDRESS_P(X)                             \
-  (GET_CODE (X) == LABEL_REF                                           \
-   || (GET_CODE (X) == SYMBOL_REF && !SYMBOL_REF_FLAG (X))             \
-   || (GET_CODE (X) == CONST && INDIRECTABLE_CONSTANT_P(X))            \
-   || GET_CODE (X) == CONST_INT)
-
-
-/* Nonzero 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)  \
-  (INDIRECTABLE_CONSTANT_ADDRESS_P (X)                                         \
-   || (GET_CODE (X) == REG && REG_OK_FOR_BASE_P (X))                   \
-   || (GET_CODE (X) == PLUS                                            \
-       && GET_CODE (XEXP (X, 0)) == REG                                        \
-       && REG_OK_FOR_BASE_P (XEXP (X, 0))                              \
-       && INDIRECTABLE_CONSTANT_ADDRESS_P (XEXP (X, 1))))
-
-#else /* not NO_EXTERNAL_INDIRECT_ADDRESS */
-
-#define INDIRECTABLE_CONSTANT_ADDRESS_P(X) CONSTANT_ADDRESS_P(X)
-
-/* Nonzero if X is an address which can be indirected.  */
-#define INDIRECTABLE_ADDRESS_P(X)  \
-  (CONSTANT_ADDRESS_P (X)                                              \
-   || (GET_CODE (X) == REG && REG_OK_FOR_BASE_P (X))                   \
-   || (GET_CODE (X) == PLUS                                            \
-       && GET_CODE (XEXP (X, 0)) == REG                                        \
-       && REG_OK_FOR_BASE_P (XEXP (X, 0))                              \
-       && 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)  \
-{ register rtx xfoob = (X);                                            \
-  if (GET_CODE (xfoob) == REG)                                         \
-    {                                                                  \
-      extern rtx *reg_equiv_mem;                                       \
-      if (! reload_in_progress                                         \
-         || reg_equiv_mem[REGNO (xfoob)] == 0                          \
-         || INDIRECTABLE_ADDRESS_P (reg_equiv_mem[REGNO (xfoob)]))     \
-       goto ADDR;                                                      \
-    }                                                                  \
-  if (CONSTANT_ADDRESS_P (xfoob)) goto ADDR;                           \
-  if (INDIRECTABLE_ADDRESS_P (xfoob)) goto ADDR;                       \
-  xfoob = XEXP (X, 0);                                                 \
-  if (GET_CODE (X) == MEM && INDIRECTABLE_ADDRESS_P (xfoob))           \
-    goto ADDR;                                                         \
-  if ((GET_CODE (X) == PRE_DEC || GET_CODE (X) == POST_INC)            \
-      && GET_CODE (xfoob) == REG && REG_OK_FOR_BASE_P (xfoob))         \
-    goto ADDR; }
-
-/* 1 if PROD is either a reg times size of mode MODE and MODE is less
-   than or equal 8 bytes, or just a reg if MODE is 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)   \
-(GET_MODE_SIZE (MODE) == 1                                             \
- ? (GET_CODE (PROD) == REG && REG_OK_FOR_BASE_P (PROD))                        \
- : (GET_CODE (PROD) == MULT && GET_MODE_SIZE (MODE) <= 8               \
-    &&                                                                 \
-    (xfoo0 = XEXP (PROD, 0), xfoo1 = XEXP (PROD, 1),                   \
-     ((((GET_CODE (xfoo0) == CONST_INT                                 \
-         && GET_CODE (xfoo1) == REG)                                   \
-         && INTVAL (xfoo0) == (int)GET_MODE_SIZE (MODE))               \
-         && REG_OK_FOR_INDEX_P (xfoo1))                                        \
-        ||                                                             \
-      (((GET_CODE (xfoo1) == CONST_INT                                 \
-         && GET_CODE (xfoo0) == REG)                                   \
-         && INTVAL (xfoo1) == (int)GET_MODE_SIZE (MODE))               \
-         && REG_OK_FOR_INDEX_P (xfoo0))))))
-
-/* 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)    \
-{ register rtx xfooa;                                                  \
-  if (GET_CODE (X) == PLUS)                                            \
-    { if (GET_CODE (XEXP (X, 0)) == REG                                        \
-         && REG_OK_FOR_BASE_P (XEXP (X, 0))                            \
-         && (xfooa = XEXP (X, 1),                                      \
-             INDEX_TERM_P (xfooa, MODE)))                              \
-       goto ADDR;                                                      \
-      if (GET_CODE (XEXP (X, 1)) == REG                                        \
-         && REG_OK_FOR_BASE_P (XEXP (X, 1))                            \
-         && (xfooa = XEXP (X, 0),                                      \
-             INDEX_TERM_P (xfooa, MODE)))                              \
-       goto ADDR; } }
-
-#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR)  \
-{ register rtx xfoo, xfoo0, xfoo1;                                     \
-  GO_IF_NONINDEXED_ADDRESS (X, ADDR);                                  \
-  if (GET_CODE (X) == PLUS)                                            \
-    { /* Handle <address>[index] represented with index-sum outermost */\
-      xfoo = XEXP (X, 0);                                              \
-      if (INDEX_TERM_P (xfoo, MODE))                                   \
-       { GO_IF_NONINDEXED_ADDRESS (XEXP (X, 1), ADDR); }               \
-      xfoo = XEXP (X, 1);                                              \
-      if (INDEX_TERM_P (xfoo, MODE))                                   \
-       { GO_IF_NONINDEXED_ADDRESS (XEXP (X, 0), ADDR); }               \
-      /* Handle offset(reg)[index] with offset added outermost */      \
-      if (INDIRECTABLE_CONSTANT_ADDRESS_P (XEXP (X, 0)))               \
-       { if (GET_CODE (XEXP (X, 1)) == REG                             \
-             && REG_OK_FOR_BASE_P (XEXP (X, 1)))                       \
-           goto ADDR;                                                  \
-         GO_IF_REG_PLUS_INDEX (XEXP (X, 1), MODE, ADDR); }             \
-      if (INDIRECTABLE_CONSTANT_ADDRESS_P (XEXP (X, 1)))               \
-       { if (GET_CODE (XEXP (X, 0)) == REG                             \
-             && REG_OK_FOR_BASE_P (XEXP (X, 0)))                       \
-           goto ADDR;                                                  \
-         GO_IF_REG_PLUS_INDEX (XEXP (X, 0), MODE, ADDR); } } }
-\f
-/* Try machine-dependent ways of modifying an illegitimate address
-   to be legitimate.  If we find one, return the new, valid address.
-   This macro is used in only one place: `memory_address' in explow.c.
-
-   OLDX is the address as it was before break_out_memory_refs was called.
-   In some cases it is useful to look at this to decide what needs to be done.
-
-   MODE and WIN are passed so that this macro can use
-   GO_IF_LEGITIMATE_ADDRESS.
-
-   It is always safe for this macro to do nothing.  It exists to recognize
-   opportunities to optimize the output.
-
-   For the VAX, nothing needs to be done.  */
-
-#define LEGITIMIZE_ADDRESS(X,OLDX,MODE,WIN)  {}
-
-/* Go to LABEL if ADDR (a legitimate address expression)
-   has an effect that depends on the machine mode it is used for.
-   On the VAX, the predecrement and postincrement address depend thus
-   (the amount of decrement or increment being the length of the operand)
-   and all indexed address depend thus (because the index scale factor
-   is the length of the operand).  */
-#define GO_IF_MODE_DEPENDENT_ADDRESS(ADDR,LABEL)       \
- { if (GET_CODE (ADDR) == POST_INC || GET_CODE (ADDR) == PRE_DEC)      \
-     goto LABEL;                                                       \
-   if (GET_CODE (ADDR) == PLUS)                                                \
-     { if (CONSTANT_ADDRESS_P (XEXP (ADDR, 0))                         \
-          && GET_CODE (XEXP (ADDR, 1)) == REG);                        \
-       else if (CONSTANT_ADDRESS_P (XEXP (ADDR, 1))                    \
-               && GET_CODE (XEXP (ADDR, 0)) == REG);                   \
-       else goto LABEL; }}
-\f
 /* Specify the machine mode that this machine uses
    for the index in the tablejump instruction.  */
 #define CASE_VECTOR_MODE HImode
@@ -798,11 +418,6 @@ enum reg_class { NO_REGS, ALL_REGS, LIM_REG_CLASSES };
    Do not define this if the table should contain absolute addresses.  */
 #define CASE_VECTOR_PC_RELATIVE 1
 
-/* Define this if the case instruction drops through after the table
-   when the index is out of range.  Don't define it if the case insn
-   jumps to the default label instead.  */
-#define CASE_DROPS_THROUGH
-
 /* Indicate that jump tables go in the text section.  This is
    necessary when compiling PIC code.  */
 #define JUMP_TABLES_IN_TEXT_SECTION 1
@@ -810,14 +425,15 @@ enum reg_class { NO_REGS, ALL_REGS, LIM_REG_CLASSES };
 /* Define this as 1 if `char' should by default be signed; else as 0.  */
 #define DEFAULT_SIGNED_CHAR 1
 
-/* This flag, if defined, says the same insns that convert to a signed fixnum
-   also convert validly to an unsigned one.  */
-#define FIXUNS_TRUNC_LIKE_FIX_TRUNC
-
 /* Max number of bytes we can move from memory to memory
    in one reasonably fast instruction.  */
 #define MOVE_MAX 8
 
+/* If a memory-to-memory move would take MOVE_RATIO or more simple
+   move-instruction pairs, we will do a cpymem or libcall instead.  */
+#define MOVE_RATIO(speed) ((speed) ? 6 : 3)
+#define CLEAR_RATIO(speed) ((speed) ? 6 : 2)
+
 /* Nonzero if access to memory by bytes is slow and undesirable.  */
 #define SLOW_BYTE_ACCESS 0
 
@@ -826,14 +442,6 @@ enum reg_class { NO_REGS, ALL_REGS, LIM_REG_CLASSES };
    of a shift count.  */
 /* #define SHIFT_COUNT_TRUNCATED */
 
-/* Value is 1 if truncating an integer of INPREC bits to OUTPREC bits
-   is done just by pretending it is already truncated.  */
-#define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1
-
-/* When a prototype says `char' or `short', really pass an `int'.
-   (On the VAX, this is required for system-library compatibility.)  */
-#define PROMOTE_PROTOTYPES 1
-
 /* Specify the machine mode that pointers have.
    After generation of rtl, the compiler makes no further distinction
    between pointers and any other objects of this machine mode.  */
@@ -844,25 +452,13 @@ enum reg_class { NO_REGS, ALL_REGS, LIM_REG_CLASSES };
    so give the MEM rtx a byte's mode.  */
 #define FUNCTION_MODE QImode
 
-/* This machine doesn't use IEEE floats.  */
-
-#define TARGET_FLOAT_FORMAT VAX_FLOAT_FORMAT
-
 /* Specify the cost of a branch insn; roughly the number of extra insns that
    should be added to avoid a branch.
 
    Branches are extremely cheap on the VAX while the shift insns often
    used to replace branches can be expensive.  */
 
-#define BRANCH_COST 0
-
-/*
- * We can use the BSD C library routines for the libgcc calls that are
- * still generated, since that's what they boil down to anyways.
- */
-
-#define UDIVSI3_LIBCALL "*udiv"
-#define UMODSI3_LIBCALL "*urem"
+#define BRANCH_COST(speed_p, predictable_p) 0
 \f
 /* Tell final.c how to eliminate redundant test instructions.  */
 
@@ -874,82 +470,22 @@ enum reg_class { NO_REGS, ALL_REGS, LIM_REG_CLASSES };
    after execution of an instruction whose pattern is EXP.
    Do not alter them if the instruction would not alter the cc's.  */
 
-#define NOTICE_UPDATE_CC(EXP, INSN) \
-{ if (GET_CODE (EXP) == SET)                                   \
-    { if (GET_CODE (SET_SRC (EXP)) == CALL)                    \
-       CC_STATUS_INIT;                                         \
-      else if (GET_CODE (SET_DEST (EXP)) != ZERO_EXTRACT       \
-              && GET_CODE (SET_DEST (EXP)) != PC)              \
-       {                                                       \
-         cc_status.flags = 0;                                  \
-         /* The integer operations below don't set carry or    \
-            set it in an incompatible way.  That's ok though   \
-            as the Z bit is all we need when doing unsigned    \
-            comparisons on the result of these insns (since    \
-            they're always with 0).  Set CC_NO_OVERFLOW to     \
-            generate the correct unsigned branches.  */        \
-         switch (GET_CODE (SET_SRC (EXP)))                     \
-           {                                                   \
-           case NEG:                                           \
-             if (GET_MODE_CLASS (GET_MODE (EXP)) == MODE_FLOAT)\
-               break;                                          \
-           case AND:                                           \
-           case IOR:                                           \
-           case XOR:                                           \
-           case NOT:                                           \
-           case MEM:                                           \
-           case REG:                                           \
-             cc_status.flags = CC_NO_OVERFLOW;                 \
-             break;                                            \
-           default:                                            \
-             break;                                            \
-           }                                                   \
-         cc_status.value1 = SET_DEST (EXP);                    \
-         cc_status.value2 = SET_SRC (EXP); } }                 \
-  else if (GET_CODE (EXP) == PARALLEL                          \
-          && GET_CODE (XVECEXP (EXP, 0, 0)) == SET)            \
-    {                                                          \
-      if (GET_CODE (SET_SRC (XVECEXP (EXP, 0, 0))) == CALL)    \
-       CC_STATUS_INIT;                                         \
-      else if (GET_CODE (SET_DEST (XVECEXP (EXP, 0, 0))) != PC) \
-       { cc_status.flags = 0;                                  \
-         cc_status.value1 = SET_DEST (XVECEXP (EXP, 0, 0));    \
-         cc_status.value2 = SET_SRC (XVECEXP (EXP, 0, 0)); }   \
-      else                                                     \
-       /* PARALLELs whose first element sets the PC are aob,   \
-          sob insns.  They do change the cc's.  */             \
-       CC_STATUS_INIT; }                                       \
-  else CC_STATUS_INIT;                                         \
-  if (cc_status.value1 && GET_CODE (cc_status.value1) == REG   \
-      && cc_status.value2                                      \
-      && reg_overlap_mentioned_p (cc_status.value1, cc_status.value2)) \
-    cc_status.value2 = 0;                                      \
-  if (cc_status.value1 && GET_CODE (cc_status.value1) == MEM   \
-      && cc_status.value2                                      \
-      && GET_CODE (cc_status.value2) == MEM)                   \
-    cc_status.value2 = 0; }
-/* Actual condition, one line up, should be that value2's address
-   depends on value1, but that is too much of a pain.  */
-
-#define OUTPUT_JUMP(NORMAL, FLOAT, NO_OV)  \
-{ if (cc_status.flags & CC_NO_OVERFLOW)                                \
-    return NO_OV;                                              \
-  return NORMAL; }
+#define NOTICE_UPDATE_CC(EXP, INSN)    \
+  vax_notice_update_cc ((EXP), (INSN))
+
+#define OUTPUT_JUMP(NORMAL, FLOAT, NO_OV)      \
+  { if (cc_status.flags & CC_NO_OVERFLOW)      \
+      return NO_OV;                            \
+    return NORMAL;                             \
+  }
 \f
 /* Control the assembler format that we output.  */
 
-/* Output at beginning of assembler file.  */
-/* When debugging, we want to output an extra dummy label so that gas
-   can distinguish between D_float and G_float prior to processing the
-   .stabs directive identifying type double.  */
-
-#define ASM_FILE_START(FILE) \
-  do {                                                         \
-    fputs (ASM_APP_OFF, FILE);                                 \
-    if (write_symbols == DBX_DEBUG)                            \
-      fprintf (FILE, "___vax_%c_doubles:\n", ASM_DOUBLE_CHAR); \
-  } while (0)
+/* A C string constant describing how to begin a comment in the target
+   assembler language.  The compiler assumes that the comment will end at
+   the end of the line.  */
 
+#define ASM_COMMENT_START "#"
 
 /* Output to assembler file text saying following lines
    may contain character constants, extra white space, comments, etc.  */
@@ -974,9 +510,9 @@ enum reg_class { NO_REGS, ALL_REGS, LIM_REG_CLASSES };
    The register names will be prefixed by REGISTER_PREFIX, if any.  */
 
 #define REGISTER_PREFIX ""
-#define REGISTER_NAMES \
-{"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", \
"r9", "r10", "r11", "ap", "fp", "sp", "pc"}
+#define REGISTER_NAMES                                 \
+  { "r0", "r1",  "r2",  "r3", "r4", "r5", "r6", "r7",  \
   "r8", "r9", "r10", "r11", "ap", "fp", "sp", "pc", }
 
 /* This is BSD, so it wants DBX format.  */
 
@@ -1019,7 +555,7 @@ enum reg_class { NO_REGS, ALL_REGS, LIM_REG_CLASSES };
    This is suitable for output with `assemble_name'.  */
 
 #define ASM_GENERATE_INTERNAL_LABEL(LABEL,PREFIX,NUM)  \
-  sprintf (LABEL, "*%s%d", PREFIX, NUM)
+  sprintf (LABEL, "*%s%ld", PREFIX, (long)(NUM))
 
 /* This is how to output an insn to push a register on the stack.
    It need not be very fast code.  */
@@ -1030,8 +566,8 @@ enum reg_class { NO_REGS, ALL_REGS, LIM_REG_CLASSES };
 /* This is how to output an insn to pop a register from the stack.
    It need not be very fast code.  */
 
-#define ASM_OUTPUT_REG_POP(FILE,REGNO)  \
-  fprintf (FILE, "\tmovl (%s)+,%s\n", reg_names[STACK_POINTER_REGNUM], \
+#define ASM_OUTPUT_REG_POP(FILE,REGNO)                                 \
+  fprintf (FILE, "\tmovl (%s)+,%s\n", reg_names[STACK_POINTER_REGNUM], \
           reg_names[REGNO])
 
 /* This is how to output an element of a case-vector that is absolute.
@@ -1076,31 +612,23 @@ enum reg_class { NO_REGS, ALL_REGS, LIM_REG_CLASSES };
    that says to advance the location counter by SIZE bytes.  */
 
 #define ASM_OUTPUT_SKIP(FILE,SIZE)  \
-  fprintf (FILE, "\t.space %u\n", (SIZE))
+  fprintf (FILE, "\t.space %u\n", (int)(SIZE))
 
 /* This says how to output an assembler line
    to define a global common symbol.  */
 
-#define ASM_OUTPUT_COMMON(FILE, NAME, SIZE, ROUNDED)  \
-( fputs (".comm ", (FILE)),                    \
-  assemble_name ((FILE), (NAME)),              \
-  fprintf ((FILE), ",%u\n", (ROUNDED)))
+#define ASM_OUTPUT_COMMON(FILE, NAME, SIZE, ROUNDED)   \
+  ( fputs (".comm ", (FILE)),                          \
+    assemble_name ((FILE), (NAME)),                    \
+    fprintf ((FILE), ",%u\n", (int)(ROUNDED)))
 
 /* This says how to output an assembler line
    to define a local common symbol.  */
 
-#define ASM_OUTPUT_LOCAL(FILE, NAME, SIZE, ROUNDED)  \
-( fputs (".lcomm ", (FILE)),                   \
-  assemble_name ((FILE), (NAME)),              \
-  fprintf ((FILE), ",%u\n", (ROUNDED)))
-
-/* Store in OUTPUT a string (made with alloca) containing
-   an assembler-name for a local static variable named NAME.
-   LABELNO is an integer which is different for each call.  */
-
-#define ASM_FORMAT_PRIVATE_NAME(OUTPUT, NAME, LABELNO) \
-( (OUTPUT) = (char *) alloca (strlen ((NAME)) + 10),   \
-  sprintf ((OUTPUT), "%s.%d", (NAME), (LABELNO)))
+#define ASM_OUTPUT_LOCAL(FILE, NAME, SIZE, ROUNDED)    \
+  ( fputs (".lcomm ", (FILE)),                         \
+    assemble_name ((FILE), (NAME)),                    \
+    fprintf ((FILE), ",%u\n", (int)(ROUNDED)))
 
 /* Print an instruction operand X on file FILE.
    CODE is the code from the %-spec that requested printing this operand;
@@ -1109,6 +637,7 @@ enum reg_class { NO_REGS, ALL_REGS, LIM_REG_CLASSES };
 VAX operand formatting codes:
 
  letter           print
+   c   direct branch condition
    C   reverse branch condition
    D   64-bit immediate operand
    B   the low 8 bits of the complement of a constant operand
@@ -1124,59 +653,28 @@ VAX operand formatting codes:
 
 /* The purpose of D is to get around a quirk or bug in VAX assembler
    whereby -1 in a 64-bit immediate operand means 0x00000000ffffffff,
-   which is not a 64-bit minus one.  */
+   which is not a 64-bit minus one.  As a workaround, we output negative
+   values in hex.  */
+#if HOST_BITS_PER_WIDE_INT == 64
+#  define NEG_HWI_PRINT_HEX16 HOST_WIDE_INT_PRINT_HEX
+#else
+#  define NEG_HWI_PRINT_HEX16 "0xffffffff%08lx"
+#endif
 
-#define PRINT_OPERAND_PUNCT_VALID_P(CODE)                              \
+#define PRINT_OPERAND_PUNCT_VALID_P(CODE)  \
   ((CODE) == '#' || (CODE) == '|')
 
 #define PRINT_OPERAND(FILE, X, CODE)  \
-{ if (CODE == '#') fputc (ASM_DOUBLE_CHAR, FILE);                      \
-  else if (CODE == '|')                                                        \
-    fputs (REGISTER_PREFIX, FILE);                                     \
-  else if (CODE == 'C')                                                        \
-    fputs (rev_cond_name (X), FILE);                                   \
-  else if (CODE == 'D' && GET_CODE (X) == CONST_INT && INTVAL (X) < 0) \
-    fprintf (FILE, "$0xffffffff%08x", INTVAL (X));                     \
-  else if (CODE == 'P' && GET_CODE (X) == CONST_INT)                   \
-    fprintf (FILE, "$%d", INTVAL (X) + 1);                             \
-  else if (CODE == 'N' && GET_CODE (X) == CONST_INT)                   \
-    fprintf (FILE, "$%d", ~ INTVAL (X));                               \
-  /* rotl instruction cannot deal with negative arguments.  */         \
-  else if (CODE == 'R' && GET_CODE (X) == CONST_INT)                   \
-    fprintf (FILE, "$%d", 32 - INTVAL (X));                            \
-  else if (CODE == 'H' && GET_CODE (X) == CONST_INT)                   \
-    fprintf (FILE, "$%d", 0xffff & ~ INTVAL (X));                      \
-  else if (CODE == 'h' && GET_CODE (X) == CONST_INT)                   \
-    fprintf (FILE, "$%d", (short) - INTVAL (x));                       \
-  else if (CODE == 'B' && GET_CODE (X) == CONST_INT)                   \
-    fprintf (FILE, "$%d", 0xff & ~ INTVAL (X));                                \
-  else if (CODE == 'b' && GET_CODE (X) == CONST_INT)                   \
-    fprintf (FILE, "$%d", 0xff & - INTVAL (X));                                \
-  else if (CODE == 'M' && GET_CODE (X) == CONST_INT)                   \
-    fprintf (FILE, "$%d", ~((1 << INTVAL (x)) - 1));                   \
-  else if (GET_CODE (X) == REG)                                                \
-    fprintf (FILE, "%s", reg_names[REGNO (X)]);                                \
-  else if (GET_CODE (X) == MEM)                                                \
-    output_address (XEXP (X, 0));                                      \
-  else if (GET_CODE (X) == CONST_DOUBLE && GET_MODE (X) == SFmode)     \
-    { char dstr[30];                                                   \
-      real_to_decimal (dstr, CONST_DOUBLE_REAL_VALUE (X),              \
-                      sizeof (dstr), 0, 1);                            \
-      fprintf (FILE, "$0f%s", dstr); }                                 \
-  else if (GET_CODE (X) == CONST_DOUBLE && GET_MODE (X) == DFmode)     \
-    { char dstr[30];                                                   \
-      real_to_decimal (dstr, CONST_DOUBLE_REAL_VALUE (X),              \
-                      sizeof (dstr), 0, 1);                            \
-      fprintf (FILE, "$0%c%s", ASM_DOUBLE_CHAR, dstr); }               \
-  else { putc ('$', FILE); output_addr_const (FILE, X); }}
+  print_operand (FILE, X, CODE)
 
 /* Print a memory operand whose address is X, on file FILE.
    This uses a function in output-vax.c.  */
 
 #define PRINT_OPERAND_ADDRESS(FILE, ADDR)  \
- print_operand_address (FILE, ADDR)
 print_operand_address (FILE, ADDR)
 
 /* This is a blatent lie.  However, it's good enough, since we don't
    actually have any code whatsoever for which this isn't overridden
    by the proper FDE definition.  */
 #define INCOMING_RETURN_ADDR_RTX gen_rtx_REG (Pmode, PC_REGNUM)
+