OSDN Git Service

* config/d30v: New port.
authorrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 30 Apr 2000 11:17:13 +0000 (11:17 +0000)
committerrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 30 Apr 2000 11:17:13 +0000 (11:17 +0000)
        * configure.in (d30v-*): Set fp format.
        * configure: Rebuild.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@33548 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/config/d30v/abi [new file with mode: 0644]
gcc/config/d30v/d30v-protos.h [new file with mode: 0644]
gcc/config/d30v/d30v.c [new file with mode: 0644]
gcc/config/d30v/d30v.h [new file with mode: 0644]
gcc/config/d30v/d30v.md [new file with mode: 0644]
gcc/config/d30v/libgcc1.asm [new file with mode: 0644]
gcc/config/d30v/t-d30v [new file with mode: 0644]
gcc/config/d30v/xm-d30v.h [new file with mode: 0644]
gcc/configure
gcc/configure.in

index 312ec98..0d19e4b 100644 (file)
@@ -1,5 +1,12 @@
 2000-04-30  Richard Henderson  <rth@cygnus.com>
 
 2000-04-30  Richard Henderson  <rth@cygnus.com>
 
+       * config/d30v: New port.
+
+       * configure.in (d30v-*): Set fp format.
+       * configure: Rebuild.
+
+2000-04-30  Richard Henderson  <rth@cygnus.com>
+
        * ifcvt.c: New file.
        * Makefile.in (OBJS): Add it.
        (ifcvt.o): New target.
        * ifcvt.c: New file.
        * Makefile.in (OBJS): Add it.
        (ifcvt.o): New target.
diff --git a/gcc/config/d30v/abi b/gcc/config/d30v/abi
new file mode 100644 (file)
index 0000000..c706e94
--- /dev/null
@@ -0,0 +1,231 @@
+-*- Text -*-
+
+This document describes the proposed ABI for the D30V processor.  This is
+revision 2 of the document.
+
+Revision history:
+
+Revision 1:
+       Original revision of this document.
+
+Revision 2:
+       Done after consultation with Mitsubshi about the calling sequence.
+       This revision now reduces the number of registers the compiler will not
+       touch from 18 registers down to 8.
+
+       Register 1 is now a normal temporary register, since mvfacc rx,ay,32 is
+       legal.
+
+       Arguments greater than 4 bytes must be passed in an even register or at
+       a double word alignment.
+
+       The va_list type is a structure, not a char *.
+
+       The stack must be aligned to 8 byte boundary.  Doubles and long longs
+       must also be aligned to 8 byte boundaries.
+
+       System calls are specified via trap 31.
+
+Revision 3:
+       I added discussion about compiler switches.
+
+Register usage:
+===============
+
+       Registers       Call Status     Usage
+       ---------       -----------     -----
+       R0              hardware        Hardwired to 0
+       R1              volatile        temp
+       R2              volatile        Arg 1 and main return value.
+       R3              volatile        Arg 2 and low bits of 64 bit returns
+       R4 - R17        volatile        Args 3-16
+       R18             volatile        Static chain if used
+       R19 - R25       volatile        temps
+       R26 - R33       saved           Reserved for user use
+       R34 - R60       saved           Registers preserved across calls
+       R61             saved           Frame pointer if needed.
+       R62             saved           Return address pointer (hardware)
+       R63             saved           Stack pointer
+       CR0 - CR3       hardware        {normal,backup} {psw,pc}
+       CR4 - CR6       hardware        Reserved for future use
+       CR7 - CR9       volatile        Repeat count, addresses
+       CR10 - CR11     saved           Modulo start/end
+       CR12 - CR14     hardware        Reserved for future use
+       CR15 - CR17     hardware        Interrupt support
+       F0 - F1         volatile        Execution flags
+       F2 - F3         volatile        General flags
+       F4 - F7         volatile        Special purpose flags
+       A0              volatile        Accumulator
+       A1              saved           Accumulator
+
+Notes on the register usage:
+============================
+
+   1)  R61 will hold the frame pointer if it is needed.  Normally the frame
+       pointer will not be needed, in which case this will become another
+       saved register.
+
+   2)  Repeat instructions and delayed branches cannot cross call boundaries.
+       Similarly, all flags are assumed to not be preserved across calls.
+
+   3)  Since so many registers are available, I reserved 8 registers (r26-r33)
+       for the user to use for any purpose (global variables, interrupt
+       routines, thread pointer, etc.).  These registers will not be used by
+       the compiler for any purpose.
+
+   4)  One of the two accumulators is saved across calls.
+
+   5)  Doubles and long longs will only be allocated to even/odd register
+       pairs to allow use of the ld2w/st2w instructions.
+
+Miscellaneous call information:
+===============================
+
+   1)  Structures are passed in registers, rounding them up to word
+       boundaries.
+
+   2)  Any argument that is greater than word size (4 bytes) must be aligned
+       to a double word boundary and/or start in an even register.  The
+       intention here is to be able to use the ld2w/st2w instructions for
+       moving doubles and long longs.
+
+   3)  Variable argument functions are called with the same calling sequence
+       as non-variable argument functions.  When called, a variable argument
+       function first saves the 16 registers (R2 - R17) used for passing
+       arguments.  The va_list type is a structure.  The first element of the
+       structure is a pointer to the first word saved on the stack, and the
+       second element is a number that gives which argument number is being
+       processed.
+
+   4)  Word and double word sized structures/unions are returned in registers,
+       other functions returning structures expect a temporary area address to
+       be passed as the first argument.
+
+
+The stack frame when a function is called looks like:
+
+high           |  ....                         |
+               +-------------------------------+
+               | Argument word #20             |
+               +-------------------------------+
+               | Argument word #19             |
+               +-------------------------------+
+               | Argument word #18             |
+               +-------------------------------+
+               | Argument word #17             |
+low    SP----> +-------------------------------+
+
+After the prologue is executed, the stack frame will look like:
+
+high           |  ....                         |
+               +-------------------------------+
+               | Argument word #20             |
+               +-------------------------------+
+               | Argument word #19             |
+               +-------------------------------+
+               | Argument word #18             |
+               +-------------------------------+
+               | Argument word #17             |
+       Prev sp +-------------------------------+
+               |                               |
+               | Save for arguments 1..16 if   |
+               | the func. uses stdarg/varargs |
+               |                               |
+               +-------------------------------+
+               |                               |
+               | Save area for preserved regs  |
+               |                               |
+               +-------------------------------+
+               |                               |
+               | Local variables               |
+               |                               |
+               +-------------------------------+
+               |                               |
+               | alloca space if used          |
+               |                               |
+               +-------------------------------+
+               |                               |
+               | Space for outgoing arguments  |
+               |                               |
+low    SP----> +-------------------------------+
+
+System Calls
+============
+
+System calls will be done using "TRAP 31".  Input arguments will be in R2 - R5,
+and the system call number will be in R6.  Return values from the system call
+will be in R2.  Negative values of the return indicate the system call failed,
+and the value is the negative of the error code.  Here are the assigned system
+call numbers (value in R6):
+
+       exit    1
+       open    2
+       close   3
+       read    4
+       write   5
+       lseek   6
+       unlink  7
+       getpid  8
+       kill    9
+       fstat   10
+                       (11 is reserved for sbrk)
+       argvlen 12
+       argv    13
+       chdir   14
+       stat    15
+       chmod   16
+       utime   17
+       time    18
+
+Compiler Switches
+=================
+
+The following d30v specific compiler switches are currently supported:
+
+    -mextmem           Link .text/.data/.bss/etc in external memory.
+
+    -mextmemory                Same as -mextmem.
+
+    -monchip           Link .text/.data/.bss/etc in the onchip data/text
+                       memory.
+
+    -mno-asm-optimize  Do not pass -O to the assembler when optimizing (the -O
+                       switch will mark two short instructions that don't
+                       interfere with each other as being done parallel
+                       instead of sequentially).
+
+    -masm-optimize     [default] If optimizing, pass -O to the assembler.
+
+    -mbranch-cost=n    Increase the internal costs of branches to n.  Higher
+                       costs means that the compiler will issue more
+                       instructions to avoid doing a branch. The default is
+                       2.
+
+    -mcond-exec=n      Replace branches around n insns with conditional
+                       execution if we can.  Default is 4.
+
+
+Sections
+========
+
+You can override the effect of the -mextmem/-monchip options by putting
+functions into either the ".stext" or ".etext" sections.  If you put them into
+the ".stext" section, the linker will always link the function into the onchip
+memory area.  Similarly, if you put the function in the ".etext" section, the
+linker will always link the function into the external memory area.
+
+Data can be controlled as well.  If you put the data in the ".sdata" section,
+the linker will put the data into the onchip data area.  Similarly, if you put
+the data in the ".edata" section, the linker will put the data into the
+external memory.
+
+
+Stack pointer
+=============
+
+The crt0.o that we ship loads up the stack pointer with the value of the label
+__stack.  If you do not define a value for __stack, the linker will choose the
+top of the onchip data area (0x20008000) for the stack pointer.  You can set a
+new value via the options:
+
+       -Wl,-defsym,__stack=0x20008000
diff --git a/gcc/config/d30v/d30v-protos.h b/gcc/config/d30v/d30v-protos.h
new file mode 100644 (file)
index 0000000..6e774fd
--- /dev/null
@@ -0,0 +1,149 @@
+/* d30v prototypes.
+   Copyright (C) 1999, 2000 Free Software Foundation, Inc.
+   Contributed by Cygnus Solutions.
+
+This file is part of GNU CC.
+
+GNU CC 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)
+any later version.
+
+GNU CC 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.  */
+
+/* External functions called.  */
+
+extern void override_options           PARAMS ((void));
+#ifdef RTX_CODE
+extern int short_memory_operand                PARAMS ((rtx, enum machine_mode));
+extern int long_memory_operand         PARAMS ((rtx, enum machine_mode));
+extern int d30v_memory_operand         PARAMS ((rtx, enum machine_mode));
+extern int single_reg_memory_operand   PARAMS ((rtx, enum machine_mode));
+extern int const_addr_memory_operand   PARAMS ((rtx, enum machine_mode));
+extern int call_operand                        PARAMS ((rtx, enum machine_mode));
+extern int gpr_operand                 PARAMS ((rtx, enum machine_mode));
+extern int accum_operand               PARAMS ((rtx, enum machine_mode));
+extern int gpr_or_accum_operand                PARAMS ((rtx, enum machine_mode));
+extern int cr_operand                  PARAMS ((rtx, enum machine_mode));
+extern int repeat_operand              PARAMS ((rtx, enum machine_mode));
+extern int flag_operand                        PARAMS ((rtx, enum machine_mode));
+extern int br_flag_operand             PARAMS ((rtx, enum machine_mode));
+extern int br_flag_or_constant_operand PARAMS ((rtx, enum machine_mode));
+extern int gpr_br_flag_operand         PARAMS ((rtx, enum machine_mode));
+extern int f0_operand                  PARAMS ((rtx, enum machine_mode));
+extern int f1_operand                  PARAMS ((rtx, enum machine_mode));
+extern int carry_operand               PARAMS ((rtx, enum machine_mode));
+extern int reg_or_0_operand            PARAMS ((rtx, enum machine_mode));
+extern int gpr_or_signed6_operand      PARAMS ((rtx, enum machine_mode));
+extern int gpr_or_unsigned5_operand    PARAMS ((rtx, enum machine_mode));
+extern int gpr_or_unsigned6_operand    PARAMS ((rtx, enum machine_mode));
+extern int gpr_or_constant_operand     PARAMS ((rtx, enum machine_mode));
+extern int gpr_or_dbl_const_operand    PARAMS ((rtx, enum machine_mode));
+extern int gpr_or_memory_operand       PARAMS ((rtx, enum machine_mode));
+extern int move_input_operand          PARAMS ((rtx, enum machine_mode));
+extern int move_output_operand         PARAMS ((rtx, enum machine_mode));
+extern int signed6_operand             PARAMS ((rtx, enum machine_mode));
+extern int unsigned5_operand           PARAMS ((rtx, enum machine_mode));
+extern int unsigned6_operand           PARAMS ((rtx, enum machine_mode));
+extern int bitset_operand              PARAMS ((rtx, enum machine_mode));
+extern int condexec_test_operator      PARAMS ((rtx, enum machine_mode));
+extern int condexec_branch_operator    PARAMS ((rtx, enum machine_mode));
+extern int condexec_unary_operator     PARAMS ((rtx, enum machine_mode));
+extern int condexec_addsub_operator    PARAMS ((rtx, enum machine_mode));
+extern int condexec_binary_operator    PARAMS ((rtx, enum machine_mode));
+extern int condexec_shiftl_operator    PARAMS ((rtx, enum machine_mode));
+extern int condexec_extend_operator    PARAMS ((rtx, enum machine_mode));
+extern int branch_zero_operator                PARAMS ((rtx, enum machine_mode));
+extern int cond_move_dest_operand      PARAMS ((rtx, enum machine_mode));
+extern int cond_move_operand           PARAMS ((rtx, enum machine_mode));
+extern int cond_exec_operand           PARAMS ((rtx, enum machine_mode));
+extern int srelational_si_operand      PARAMS ((rtx, enum machine_mode));
+extern int urelational_si_operand      PARAMS ((rtx, enum machine_mode));
+extern int relational_di_operand       PARAMS ((rtx, enum machine_mode));
+#endif
+extern d30v_stack_t *d30v_stack_info   PARAMS ((void));
+extern int direct_return               PARAMS ((void));
+
+#ifdef TREE_CODE
+#ifdef RTX_CODE
+extern void d30v_init_cumulative_args  PARAMS ((CUMULATIVE_ARGS *, tree,
+                                                rtx, int, int));
+#endif
+extern int d30v_function_arg_boundary  PARAMS ((enum machine_mode, tree));
+#ifdef RTX_CODE
+extern rtx d30v_function_arg           PARAMS ((CUMULATIVE_ARGS *,
+                                                enum machine_mode,
+                                                tree, int, int));
+#endif
+extern int d30v_function_arg_partial_nregs PARAMS ((CUMULATIVE_ARGS *,
+                                                   enum machine_mode,
+                                                   tree, int));
+
+extern int d30v_function_arg_pass_by_reference PARAMS ((CUMULATIVE_ARGS *,
+                                                       enum machine_mode,
+                                                       tree, int));
+
+extern void d30v_function_arg_advance  PARAMS ((CUMULATIVE_ARGS *,
+                                                enum machine_mode,
+                                                tree, int));
+#endif
+
+#ifdef RTX_CODE
+extern rtx d30v_expand_builtin_saveregs        PARAMS ((void));
+#endif
+#ifdef TREE_CODE
+extern void d30v_setup_incoming_varargs        PARAMS ((CUMULATIVE_ARGS *,
+                                                enum machine_mode,
+                                                tree, int *, int));
+extern tree d30v_build_va_list         PARAMS ((void));
+#ifdef RTX_CODE
+extern void d30v_expand_builtin_va_start PARAMS ((int, tree, rtx));
+extern rtx d30v_expand_builtin_va_arg  PARAMS ((tree, tree));
+#endif /* RTX_CODE */
+#endif /* TREE_CODE */
+
+extern void d30v_function_prologue     PARAMS ((FILE *, int));
+extern void d30v_function_epilogue     PARAMS ((FILE *, int));
+extern void d30v_function_profiler     PARAMS ((FILE *, int));
+#ifdef RTX_CODE
+extern void d30v_split_double          PARAMS ((rtx, rtx *, rtx *));
+extern void d30v_print_operand         PARAMS ((FILE *, rtx, int));
+extern void d30v_print_operand_address PARAMS ((FILE *, rtx));
+#endif
+extern int d30v_trampoline_size                PARAMS ((void));
+#ifdef RTX_CODE
+extern void d30v_initialize_trampoline PARAMS ((rtx, rtx, rtx));
+extern int d30v_legitimate_address_p   PARAMS ((enum machine_mode, rtx, int));
+extern rtx d30v_legitimize_address     PARAMS ((rtx, rtx,
+                                                enum machine_mode, int));
+extern int d30v_mode_dependent_address_p PARAMS ((rtx));
+extern rtx d30v_emit_comparison                PARAMS ((int, rtx, rtx, rtx));
+extern char *d30v_move_2words          PARAMS ((rtx *, rtx));
+extern int d30v_emit_cond_move         PARAMS ((rtx, rtx, rtx, rtx));
+extern void d30v_machine_dependent_reorg PARAMS ((rtx));
+extern int d30v_adjust_cost            PARAMS ((rtx, rtx, rtx, int));
+extern rtx d30v_return_addr            PARAMS ((void));
+#endif
+
+\f
+/* External variables referenced */
+
+/* Define the information needed to generate branch and scc insns.  This is
+   stored from the compare operation.  */
+
+extern struct rtx_def *d30v_compare_op0;
+extern struct rtx_def *d30v_compare_op1;
+
+/* Define the information needed to modify the epilogue for EH.  */
+
+#ifdef RTX_CODE
+extern rtx d30v_eh_epilogue_sp_ofs;
+#endif
diff --git a/gcc/config/d30v/d30v.c b/gcc/config/d30v/d30v.c
new file mode 100644 (file)
index 0000000..7421bfc
--- /dev/null
@@ -0,0 +1,3671 @@
+/* Definitions of target machine for Mitsubishi D30V.
+   Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
+   Contributed by Cygnus Solutions.
+
+   This file is part of GNU CC.
+
+   GNU CC 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)
+   any later version.
+
+   GNU CC 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.  */
+
+#include "config.h"
+#include "system.h"
+#include "rtl.h"
+#include "tree.h"
+#include "regs.h"
+#include "hard-reg-set.h"
+#include "real.h"
+#include "insn-config.h"
+#include "conditions.h"
+#include "insn-flags.h"
+#include "output.h"
+#include "insn-attr.h"
+#include "flags.h"
+#include "recog.h"
+#include "expr.h"
+#include "obstack.h"
+#include "tm_p.h"
+#include "except.h"
+#include "function.h"
+#include "toplev.h"
+#include "ggc.h"
+
+static void d30v_print_operand_memory_reference PARAMS ((FILE *, rtx));
+static void d30v_build_long_insn PARAMS ((HOST_WIDE_INT, HOST_WIDE_INT,
+                                         rtx, rtx));
+static void d30v_add_gc_roots PARAMS ((void));
+
+/* Define the information needed to generate branch and scc insns.  This is
+   stored from the compare operation.  */
+
+struct rtx_def *d30v_compare_op0;
+struct rtx_def *d30v_compare_op1;
+
+/* Define the information needed to modify the epilogue for EH.  */
+
+rtx d30v_eh_epilogue_sp_ofs;
+
+/* Cached value of d30v_stack_info */
+static d30v_stack_t *d30v_stack_cache = (d30v_stack_t *)0;
+
+/* Cache for __builtin_return_addr */
+static rtx d30v_return_addr_rtx;
+
+/* Values of the -mbranch-cost=n string.  */
+int d30v_branch_cost = D30V_DEFAULT_BRANCH_COST;
+const char *d30v_branch_cost_string = (const char *)0;
+
+/* Values of the -mcond-exec=n string.  */
+int d30v_cond_exec = D30V_DEFAULT_MAX_CONDITIONAL_EXECUTE;
+const char *d30v_cond_exec_string = (const char *)0;
+
+/* Whether or not a hard register can accept a register */
+unsigned char hard_regno_mode_ok[ (int)MAX_MACHINE_MODE ][FIRST_PSEUDO_REGISTER];
+
+/* Whether to try and avoid moves between two different modes */
+unsigned char modes_tieable_p[ (NUM_MACHINE_MODES) * (NUM_MACHINE_MODES) ];
+
+/* Map register number to smallest register class.  */
+enum reg_class regno_reg_class[FIRST_PSEUDO_REGISTER];
+
+/* Map class letter into register class */
+enum reg_class reg_class_from_letter[256];
+
+\f
+/* Sometimes certain combinations of command options do not make
+   sense on a particular target machine.  You can define a macro
+   `OVERRIDE_OPTIONS' to take account of this.  This macro, if
+   defined, is executed once just after all the command options have
+   been parsed.
+
+   Don't use this macro to turn on various extra optimizations for
+   `-O'.  That is what `OPTIMIZATION_OPTIONS' is for.  */
+
+void
+override_options ()
+{
+  int regno, i, ok_p;
+  enum machine_mode mode1, mode2;
+
+  /* Set up the branch cost information */
+  if (d30v_branch_cost_string)
+    d30v_branch_cost = atoi (d30v_branch_cost_string);
+
+  /* Set up max # instructions to use with conditional execution */
+  if (d30v_cond_exec_string)
+    d30v_cond_exec = atoi (d30v_cond_exec_string);
+
+  /* Setup hard_regno_mode_ok/modes_tieable_p */
+  for (mode1 = VOIDmode;
+       (int)mode1 < NUM_MACHINE_MODES;
+       mode1 = (enum machine_mode)((int)mode1 + 1))
+    {
+      int size = GET_MODE_SIZE (mode1);
+      int large_p = size > UNITS_PER_WORD;
+      int int_p = GET_MODE_CLASS (mode1) == MODE_INT;
+
+      for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
+       {
+         if (mode1 == VOIDmode)
+           ok_p = FALSE;
+
+         else if (GPR_P (regno))
+           {
+             if (!large_p)
+               ok_p = TRUE;
+             else
+               ok_p = (((regno - GPR_FIRST) & 1) == 0);
+           }
+
+         else if (FLAG_P (regno))
+           ok_p = (mode1 == CCmode);
+
+         else if (CR_P (regno))
+           ok_p = int_p && !large_p;
+
+         else if (ACCUM_P (regno))
+           ok_p = (mode1 == DImode);
+
+         else if (SPECIAL_REG_P (regno))
+           ok_p = (mode1 == SImode);
+
+         else
+           ok_p = FALSE;
+
+         hard_regno_mode_ok[ (int)mode1 ][ regno ] = ok_p;
+       }
+
+      /* A C expression that is nonzero if it is desirable to choose
+        register allocation so as to avoid move instructions between a
+        value of mode MODE1 and a value of mode MODE2.
+
+        If `HARD_REGNO_MODE_OK (R, MODE1)' and `HARD_REGNO_MODE_OK (R,
+        MODE2)' are ever different for any R, then `MODES_TIEABLE_P (MODE1,
+        MODE2)' must be zero. */
+      for (mode2 = VOIDmode;
+          (int)mode2 <= NUM_MACHINE_MODES;
+          mode2 = (enum machine_mode)((int)mode2 + 1))
+       {
+         if (mode1 == mode2)
+           ok_p = TRUE;
+
+#if 0
+         else if (GET_MODE_CLASS (mode1) == MODE_INT
+                  && GET_MODE_SIZE (mode1) <= UNITS_PER_WORD
+                  && GET_MODE_CLASS (mode2) == MODE_INT
+                  && GET_MODE_SIZE (mode2) <= UNITS_PER_WORD)
+           ok_p = TRUE;
+#endif
+
+         else
+           ok_p = FALSE;
+
+         modes_tieable_p[ ((int)mode1 * (NUM_MACHINE_MODES)) + (int)mode2 ] = ok_p;
+       }
+    }
+
+#if 0
+  for (mode1 = VOIDmode;
+       (int)mode1 < NUM_MACHINE_MODES;
+       mode1 = (enum machine_mode)((int)mode1 + 1))
+    {
+      for (mode2 = VOIDmode;
+          (int)mode2 <= NUM_MACHINE_MODES;
+          mode2 = (enum machine_mode)((int)mode2 + 1))
+       {
+         for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
+           if (ok_p
+               && (hard_regno_mode_ok[(int)mode1][regno]
+                   != hard_regno_mode_ok[(int)mode2][regno]))
+             error ("Bad modes_tieable_p for register %s, mode1 %s, mode2 %s",
+                    reg_names[regno], GET_MODE_NAME (mode1),
+                    GET_MODE_NAME (mode2));
+       }
+    }
+#endif
+
+  /* A C expression whose value is a register class containing hard
+     register REGNO.  In general there is more than one such class;
+     choose a class which is "minimal", meaning that no smaller class
+     also contains the register. */
+  for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
+    {
+      enum reg_class class;
+
+      if (GPR_P (regno))
+       class = (IN_RANGE_P (regno, GPR_FIRST+2, GPR_FIRST+62)
+                && ((regno - GPR_FIRST) & 1) == 0) ? EVEN_REGS : GPR_REGS;
+
+      else if (regno == FLAG_F0)
+       class = F0_REGS;
+
+      else if (regno == FLAG_F1)
+       class = F1_REGS;
+
+      else if (FLAG_P (regno))
+       class = OTHER_FLAG_REGS;
+
+      else if (ACCUM_P (regno))
+       class = ACCUM_REGS;
+
+      else if (regno == CR_RPT_C)
+       class = REPEAT_REGS;
+
+      else if (CR_P (regno))
+       class = CR_REGS;
+
+      else if (SPECIAL_REG_P (regno))
+       class = GPR_REGS;
+
+      else
+       class = NO_REGS;
+
+      regno_reg_class[regno] = class;
+
+#if 0
+      {
+       static char *names[] = REG_CLASS_NAMES;
+       fprintf (stderr, "Register %s class is %s, can hold modes", reg_names[regno], names[class]);
+       for (mode1 = VOIDmode;
+            (int)mode1 < NUM_MACHINE_MODES;
+            mode1 = (enum machine_mode)((int)mode1 + 1))
+         {
+           if (hard_regno_mode_ok[ (int)mode1 ][ regno ])
+             fprintf (stderr, " %s", GET_MODE_NAME (mode1));
+         }
+       fprintf (stderr, "\n");
+      }
+#endif
+    }
+
+  /* A C expression which defines the machine-dependent operand
+     constraint letters for register classes.  If CHAR is such a
+     letter, the value should be the register class corresponding to
+     it.  Otherwise, the value should be `NO_REGS'.  The register
+     letter `r', corresponding to class `GENERAL_REGS', will not be
+     passed to this macro; you do not need to handle it.
+
+     The following letters are unavailable, due to being used as
+     constraints:
+       '0'..'9'
+       '<', '>'
+       'E', 'F', 'G', 'H'
+       'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P'
+       'Q', 'R', 'S', 'T', 'U'
+       'V', 'X'
+       'g', 'i', 'm', 'n', 'o', 'p', 'r', 's' */
+
+  for (i = 0; i < 256; i++)
+    reg_class_from_letter[i] = NO_REGS;
+
+  reg_class_from_letter['a'] = ACCUM_REGS;
+  reg_class_from_letter['b'] = BR_FLAG_REGS;
+  reg_class_from_letter['c'] = CR_REGS;
+  reg_class_from_letter['d'] = GPR_REGS;
+  reg_class_from_letter['e'] = EVEN_REGS;
+  reg_class_from_letter['f'] = FLAG_REGS;
+  reg_class_from_letter['l'] = REPEAT_REGS;
+  reg_class_from_letter['x'] = F0_REGS;
+  reg_class_from_letter['y'] = F1_REGS;
+  reg_class_from_letter['z'] = OTHER_FLAG_REGS;
+
+  d30v_add_gc_roots ();
+}
+
+\f
+/* Return true if a memory operand is a short memory operand.  */
+
+int
+short_memory_operand (op, mode)
+     register rtx op;
+     enum machine_mode mode;
+{
+  if (GET_CODE (op) != MEM)
+    return FALSE;
+
+  if (GET_MODE (op) != mode && mode != VOIDmode)
+    return FALSE;
+
+  return (d30v_legitimate_address_p (mode, XEXP (op, 0), reload_completed)
+         == 1);
+}
+
+/* Return true if a memory operand is a long operand.  */
+
+int
+long_memory_operand (op, mode)
+     rtx op;
+     enum machine_mode mode;
+{
+  if (GET_CODE (op) != MEM)
+    return FALSE;
+
+  if (GET_MODE (op) != mode && mode != VOIDmode)
+    return FALSE;
+
+  return (d30v_legitimate_address_p (mode, XEXP (op, 0), reload_completed)
+         == 2);
+}
+
+/* Return true if a memory operand is valid for the D30V.  */
+
+int
+d30v_memory_operand (op, mode)
+     rtx op;
+     enum machine_mode mode;
+{
+  if (GET_CODE (op) != MEM)
+    return FALSE;
+
+  if (GET_MODE (op) != mode && mode != VOIDmode)
+    return FALSE;
+
+  return (d30v_legitimate_address_p (mode, XEXP (op, 0), reload_completed)
+         != 0);
+}
+
+/* Return true if a memory operand uses a single register for the
+   address.  */
+
+int
+single_reg_memory_operand (op, mode)
+     rtx op;
+     enum machine_mode mode;
+{
+  rtx addr;
+
+  if (GET_CODE (op) != MEM)
+    return FALSE;
+
+  if (GET_MODE (op) != mode && mode != VOIDmode)
+    return FALSE;
+
+  addr = XEXP (op, 0);
+  if (! d30v_legitimate_address_p (mode, addr, reload_completed))
+    return FALSE;
+
+  if (GET_CODE (addr) == SUBREG)
+    addr = SUBREG_REG (addr);
+
+  return (GET_CODE (addr) == REG);
+}
+
+/* Return true if a memory operand uses a constant address.  */
+
+int
+const_addr_memory_operand (op, mode)
+     rtx op;
+     enum machine_mode mode;
+{
+  if (GET_CODE (op) != MEM)
+    return FALSE;
+
+  if (GET_MODE (op) != mode && mode != VOIDmode)
+    return FALSE;
+
+  if (! d30v_legitimate_address_p (mode, XEXP (op, 0), reload_completed))
+    return FALSE;
+
+  switch (GET_CODE (XEXP (op, 0)))
+    {
+    default:
+      break;
+
+    case SYMBOL_REF:
+    case LABEL_REF:
+    case CONST_INT:
+    case CONST:
+      return TRUE;
+    }
+
+  return FALSE;
+}
+
+/* Return true if operand is a memory reference suitable for a call.  */
+
+int
+call_operand (op, mode)
+     rtx op;
+     enum machine_mode mode;
+{
+  if (GET_CODE (op) != MEM)
+    return FALSE;
+
+  if (GET_MODE (op) != mode && mode != VOIDmode)
+    return FALSE;
+
+  if (! d30v_legitimate_address_p (mode, XEXP (op, 0), reload_completed))
+    return FALSE;
+
+  switch (GET_CODE (XEXP (op, 0)))
+    {
+    default:
+      break;
+
+    case SUBREG:
+      op = SUBREG_REG (op);
+      if (GET_CODE (op) != REG)
+       return FALSE;
+
+      /* fall through */
+
+    case REG:
+      return (GPR_OR_PSEUDO_P (REGNO (XEXP (op, 0))));
+
+    case SYMBOL_REF:
+    case LABEL_REF:
+    case CONST_INT:
+    case CONST:
+      return TRUE;
+    }
+
+  return FALSE;
+}
+
+/* Return true if operand is a GPR register.  */
+
+int
+gpr_operand (op, mode)
+     rtx op;
+     enum machine_mode mode;
+{
+  if (GET_MODE (op) != mode && mode != VOIDmode)
+    return FALSE;
+
+  if (GET_CODE (op) == SUBREG)
+    {
+      if (GET_CODE (SUBREG_REG (op)) != REG)
+       return register_operand (op, mode);
+
+      op = SUBREG_REG (op);
+    }
+
+  if (GET_CODE (op) != REG)
+    return FALSE;
+
+  return GPR_OR_PSEUDO_P (REGNO (op));
+}
+
+/* Return true if operand is an accumulator register.  */
+
+int
+accum_operand (op, mode)
+     rtx op;
+     enum machine_mode mode;
+{
+  if (GET_MODE (op) != mode && mode != VOIDmode)
+    return FALSE;
+
+  if (GET_CODE (op) == SUBREG)
+    {
+      if (GET_CODE (SUBREG_REG (op)) != REG)
+       return register_operand (op, mode);
+
+      op = SUBREG_REG (op);
+    }
+
+  if (GET_CODE (op) != REG)
+    return FALSE;
+
+  return ACCUM_OR_PSEUDO_P (REGNO (op));
+}
+
+/* Return true if operand is a GPR or an accumulator register.  */
+
+int
+gpr_or_accum_operand (op, mode)
+     rtx op;
+     enum machine_mode mode;
+{
+  if (GET_MODE (op) != mode && mode != VOIDmode)
+    return FALSE;
+
+  if (GET_CODE (op) == SUBREG)
+    {
+      if (GET_CODE (SUBREG_REG (op)) != REG)
+       return register_operand (op, mode);
+
+      op = SUBREG_REG (op);
+    }
+
+  if (GET_CODE (op) != REG)
+    return FALSE;
+
+  if (ACCUM_P (REGNO (op)))
+    return TRUE;
+
+  return GPR_OR_PSEUDO_P (REGNO (op));
+}
+
+/* Return true if operand is a CR register.  */
+
+int
+cr_operand (op, mode)
+     rtx op;
+     enum machine_mode mode;
+{
+  if (GET_MODE (op) != mode && mode != VOIDmode)
+    return FALSE;
+
+  if (GET_CODE (op) == SUBREG)
+    {
+      if (GET_CODE (SUBREG_REG (op)) != REG)
+       return register_operand (op, mode);
+
+      op = SUBREG_REG (op);
+    }
+
+  if (GET_CODE (op) != REG)
+    return FALSE;
+
+  return CR_OR_PSEUDO_P (REGNO (op));
+}
+
+/* Return true if operand is the repeat count register.  */
+
+int
+repeat_operand (op, mode)
+     rtx op;
+     enum machine_mode mode;
+{
+  if (GET_MODE (op) != mode && mode != VOIDmode)
+    return FALSE;
+
+  if (GET_CODE (op) == SUBREG)
+    {
+      if (GET_CODE (SUBREG_REG (op)) != REG)
+       return register_operand (op, mode);
+
+      op = SUBREG_REG (op);
+    }
+
+  if (GET_CODE (op) != REG)
+    return FALSE;
+
+  return (REGNO (op) == CR_RPT_C || REGNO (op) >= FIRST_PSEUDO_REGISTER);
+}
+
+/* Return true if operand is a FLAG register.  */
+
+int
+flag_operand (op, mode)
+     rtx op;
+     enum machine_mode mode;
+{
+  if (GET_MODE (op) != mode && mode != VOIDmode)
+    return FALSE;
+
+  if (GET_CODE (op) == SUBREG)
+    {
+      if (GET_CODE (SUBREG_REG (op)) != REG)
+       return register_operand (op, mode);
+
+      op = SUBREG_REG (op);
+    }
+
+  if (GET_CODE (op) != REG)
+    return FALSE;
+
+  return FLAG_OR_PSEUDO_P (REGNO (op));
+}
+
+/* Return true if operand is either F0 or F1.  */
+
+int
+br_flag_operand (op, mode)
+     rtx op;
+     enum machine_mode mode;
+{
+  if (GET_MODE (op) != mode && mode != VOIDmode)
+    return FALSE;
+
+  if (GET_CODE (op) == SUBREG)
+    {
+      if (GET_CODE (SUBREG_REG (op)) != REG)
+       return register_operand (op, mode);
+
+      op = SUBREG_REG (op);
+    }
+
+  if (GET_CODE (op) != REG)
+    return FALSE;
+
+  return BR_FLAG_OR_PSEUDO_P (REGNO (op));
+}
+
+/* Return true if operand is either F0/F1 or the constants 0/1.  */
+
+int
+br_flag_or_constant_operand (op, mode)
+     rtx op;
+     enum machine_mode mode;
+{
+  if (GET_MODE (op) != mode && mode != VOIDmode)
+    return FALSE;
+
+  if (GET_CODE (op) == SUBREG)
+    {
+      if (GET_CODE (SUBREG_REG (op)) != REG)
+       return register_operand (op, mode);
+
+      op = SUBREG_REG (op);
+    }
+
+  if (GET_CODE (op) == CONST_INT)
+    return (INTVAL (op) == 0 || INTVAL (op) == 1);
+
+  if (GET_CODE (op) != REG)
+    return FALSE;
+
+  return BR_FLAG_OR_PSEUDO_P (REGNO (op));
+}
+
+/* Return true if operand is either F0 or F1, or a GPR register.  */
+
+int
+gpr_or_br_flag_operand (op, mode)
+     rtx op;
+     enum machine_mode mode;
+{
+  if (GET_MODE (op) != mode && mode != VOIDmode)
+    return FALSE;
+
+  if (GET_CODE (op) == SUBREG)
+    {
+      if (GET_CODE (SUBREG_REG (op)) != REG)
+       return register_operand (op, mode);
+
+      op = SUBREG_REG (op);
+    }
+
+  if (GET_CODE (op) != REG)
+    return FALSE;
+
+  return GPR_OR_PSEUDO_P (REGNO (op)) || BR_FLAG_P (REGNO (op));
+}
+
+/* Return true if operand is the F0 register.  */
+
+int
+f0_operand (op, mode)
+     rtx op;
+     enum machine_mode mode;
+{
+  if (GET_MODE (op) != mode && mode != VOIDmode)
+    return FALSE;
+
+  if (GET_CODE (op) == SUBREG)
+    {
+      if (GET_CODE (SUBREG_REG (op)) != REG)
+       return register_operand (op, mode);
+
+      op = SUBREG_REG (op);
+    }
+
+  if (GET_CODE (op) != REG)
+    return FALSE;
+
+  return (REGNO (op) == FLAG_F0 || REGNO (op) >= FIRST_PSEUDO_REGISTER);
+}
+
+/* Return true if operand is the F1 register.  */
+
+int
+f1_operand (op, mode)
+     rtx op;
+     enum machine_mode mode;
+{
+  if (GET_MODE (op) != mode && mode != VOIDmode)
+    return FALSE;
+
+  if (GET_CODE (op) == SUBREG)
+    {
+      if (GET_CODE (SUBREG_REG (op)) != REG)
+       return register_operand (op, mode);
+
+      op = SUBREG_REG (op);
+    }
+
+  if (GET_CODE (op) != REG)
+    return FALSE;
+
+  return (REGNO (op) == FLAG_F1 || REGNO (op) >= FIRST_PSEUDO_REGISTER);
+}
+
+/* Return true if operand is the F1 register.  */
+
+int
+carry_operand (op, mode)
+     rtx op;
+     enum machine_mode mode;
+{
+  if (GET_MODE (op) != mode && mode != VOIDmode)
+    return FALSE;
+
+  if (GET_CODE (op) == SUBREG)
+    {
+      if (GET_CODE (SUBREG_REG (op)) != REG)
+       return register_operand (op, mode);
+
+      op = SUBREG_REG (op);
+    }
+
+  if (GET_CODE (op) != REG)
+    return FALSE;
+
+  return (REGNO (op) == FLAG_CARRY || REGNO (op) >= FIRST_PSEUDO_REGISTER);
+}
+
+/* Return true if operand is a register of any flavor or a 0 of the
+   appropriate type.  */
+
+int
+reg_or_0_operand (op, mode)
+     rtx op;
+     enum machine_mode mode;
+{
+  switch (GET_CODE (op))
+    {
+    default:
+      break;
+
+    case REG:
+    case SUBREG:
+      if (GET_MODE (op) != mode && mode != VOIDmode)
+       return FALSE;
+
+      return register_operand (op, mode);
+
+    case CONST_INT:
+      return INTVAL (op) == 0;
+
+    case CONST_DOUBLE:
+      return CONST_DOUBLE_HIGH (op) == 0 && CONST_DOUBLE_LOW (op) == 0;
+    }
+
+  return FALSE;
+}
+
+/* Return true if operand is a GPR register or a signed 6 bit immediate.  */
+
+int
+gpr_or_signed6_operand (op, mode)
+     rtx op;
+     enum machine_mode mode;
+{
+  if (GET_CODE (op) == SUBREG)
+    {
+      if (GET_CODE (SUBREG_REG (op)) != REG)
+       return register_operand (op, mode);
+
+      op = SUBREG_REG (op);
+    }
+
+  if (GET_CODE (op) == CONST_INT)
+    return IN_RANGE_P (INTVAL (op), -32, 31);
+
+  if (GET_CODE (op) != REG)
+    return FALSE;
+
+  if (GET_MODE (op) != mode && mode != VOIDmode)
+    return FALSE;
+
+  return GPR_OR_PSEUDO_P (REGNO (op));
+}
+
+/* Return true if operand is a GPR register or an unsigned 5 bit immediate.  */
+
+int
+gpr_or_unsigned5_operand (op, mode)
+     rtx op;
+     enum machine_mode mode;
+{
+  if (GET_CODE (op) == SUBREG)
+    {
+      if (GET_CODE (SUBREG_REG (op)) != REG)
+       return register_operand (op, mode);
+
+      op = SUBREG_REG (op);
+    }
+
+  if (GET_CODE (op) == CONST_INT)
+    return IN_RANGE_P (INTVAL (op), 0, 31);
+
+  if (GET_CODE (op) != REG)
+    return FALSE;
+
+  if (GET_MODE (op) != mode && mode != VOIDmode)
+    return FALSE;
+
+  return GPR_OR_PSEUDO_P (REGNO (op));
+}
+
+/* Return true if operand is a GPR register or an unsigned 6 bit immediate.  */
+
+int
+gpr_or_unsigned6_operand (op, mode)
+     rtx op;
+     enum machine_mode mode;
+{
+  if (GET_CODE (op) == SUBREG)
+    {
+      if (GET_CODE (SUBREG_REG (op)) != REG)
+       return register_operand (op, mode);
+
+      op = SUBREG_REG (op);
+    }
+
+  if (GET_CODE (op) == CONST_INT)
+    return IN_RANGE_P (INTVAL (op), 0, 63);
+
+  if (GET_CODE (op) != REG)
+    return FALSE;
+
+  if (GET_MODE (op) != mode && mode != VOIDmode)
+    return FALSE;
+
+  return GPR_OR_PSEUDO_P (REGNO (op));
+}
+
+/* Return true if operand is a GPR register or a constant of some form.  */
+
+int
+gpr_or_constant_operand (op, mode)
+     rtx op;
+     enum machine_mode mode;
+{
+  switch (GET_CODE (op))
+    {
+    default:
+      break;
+
+    case CONST_INT:
+    case SYMBOL_REF:
+    case LABEL_REF:
+    case CONST:
+      return TRUE;
+
+    case SUBREG:
+      if (GET_CODE (SUBREG_REG (op)) != REG)
+       return register_operand (op, mode);
+
+      op = SUBREG_REG (op);
+      /* fall through */
+
+    case REG:
+      if (GET_MODE (op) != mode && mode != VOIDmode)
+       return FALSE;
+
+      return GPR_OR_PSEUDO_P (REGNO (op));
+    }
+
+  return FALSE;
+}
+
+/* Return true if operand is a GPR register or a constant of some form,
+   including a CONST_DOUBLE, which gpr_or_constant_operand doesn't recognize.  */
+
+int
+gpr_or_dbl_const_operand (op, mode)
+     rtx op;
+     enum machine_mode mode;
+{
+  switch (GET_CODE (op))
+    {
+    default:
+      break;
+
+    case CONST_INT:
+    case CONST_DOUBLE:
+    case SYMBOL_REF:
+    case LABEL_REF:
+    case CONST:
+      return TRUE;
+
+    case SUBREG:
+      if (GET_CODE (SUBREG_REG (op)) != REG)
+       return register_operand (op, mode);
+
+      op = SUBREG_REG (op);
+      /* fall through */
+
+    case REG:
+      if (GET_MODE (op) != mode && mode != VOIDmode)
+       return FALSE;
+
+      return GPR_OR_PSEUDO_P (REGNO (op));
+    }
+
+  return FALSE;
+}
+
+/* Return true if operand is a gpr register or a valid memory operation.  */
+
+int
+gpr_or_memory_operand (op, mode)
+     rtx op;
+     enum machine_mode mode;
+{
+  switch (GET_CODE (op))
+    {
+    default:
+      break;
+
+    case SUBREG:
+      if (GET_CODE (SUBREG_REG (op)) != REG)
+       return register_operand (op, mode);
+
+      op = SUBREG_REG (op);
+      /* fall through */
+
+    case REG:
+      if (GET_MODE (op) != mode && mode != VOIDmode)
+       return FALSE;
+
+      return GPR_OR_PSEUDO_P (REGNO (op));
+
+    case MEM:
+      return d30v_legitimate_address_p (mode, XEXP (op, 0), reload_completed);
+    }
+
+  return FALSE;
+}
+
+/* Return true if operand is something that can be an input for a move
+   operation.  */
+
+int
+move_input_operand (op, mode)
+     rtx op;
+     enum machine_mode mode;
+{
+  rtx subreg;
+  enum rtx_code code;
+
+  switch (GET_CODE (op))
+    {
+    default:
+      break;
+
+    case CONST_INT:
+    case CONST_DOUBLE:
+    case SYMBOL_REF:
+    case LABEL_REF:
+    case CONST:
+      return TRUE;
+
+    case SUBREG:
+      if (GET_MODE (op) != mode && mode != VOIDmode)
+        return FALSE;
+
+      subreg = SUBREG_REG (op);
+      code = GET_CODE (subreg);
+      if (code == MEM)
+       return d30v_legitimate_address_p ((int)mode, XEXP (subreg, 0),
+                                         reload_completed);
+
+      return (code == REG);
+
+    case REG:
+      if (GET_MODE (op) != mode && mode != VOIDmode)
+       return FALSE;
+
+      return TRUE;
+
+    case MEM:
+      if (GET_CODE (XEXP (op, 0)) == ADDRESSOF)
+       return TRUE;
+      return d30v_legitimate_address_p (mode, XEXP (op, 0),
+                                       reload_completed);
+    }
+
+  return FALSE;
+}
+
+/* Return true if operand is something that can be an output for a move
+   operation.  */
+
+int
+move_output_operand (op, mode)
+     rtx op;
+     enum machine_mode mode;
+{
+  rtx subreg;
+  enum rtx_code code;
+
+  switch (GET_CODE (op))
+    {
+    default:
+      break;
+
+    case SUBREG:
+      if (GET_MODE (op) != mode && mode != VOIDmode)
+        return FALSE;
+
+      subreg = SUBREG_REG (op);
+      code = GET_CODE (subreg);
+      if (code == MEM)
+       return d30v_legitimate_address_p ((int)mode, XEXP (subreg, 0),
+                                         reload_completed);
+
+      return (code == REG);
+
+    case REG:
+      if (GET_MODE (op) != mode && mode != VOIDmode)
+       return FALSE;
+
+      return TRUE;
+
+    case MEM:
+      if (GET_CODE (XEXP (op, 0)) == ADDRESSOF)
+       return TRUE;
+      return d30v_legitimate_address_p (mode, XEXP (op, 0),
+                                       reload_completed);
+    }
+
+  return FALSE;
+}
+
+/* Return true if operand is a signed 6 bit immediate.  */
+
+int
+signed6_operand (op, mode)
+     rtx op;
+     enum machine_mode mode ATTRIBUTE_UNUSED;
+{
+  if (GET_CODE (op) == CONST_INT)
+    return IN_RANGE_P (INTVAL (op), -32, 31);
+
+  return FALSE;
+}
+
+/* Return true if operand is an unsigned 5 bit immediate.  */
+
+int
+unsigned5_operand (op, mode)
+     rtx op;
+     enum machine_mode mode ATTRIBUTE_UNUSED;
+{
+  if (GET_CODE (op) == CONST_INT)
+    return IN_RANGE_P (INTVAL (op), 0, 31);
+
+  return FALSE;
+}
+
+/* Return true if operand is an unsigned 6 bit immediate.  */
+
+int
+unsigned6_operand (op, mode)
+     rtx op;
+     enum machine_mode mode ATTRIBUTE_UNUSED;
+{
+  if (GET_CODE (op) == CONST_INT)
+    return IN_RANGE_P (INTVAL (op), 0, 63);
+
+  return FALSE;
+}
+
+/* Return true if operand is a constant with a single bit set.  */
+
+int
+bitset_operand (op, mode)
+     rtx op;
+     enum machine_mode mode ATTRIBUTE_UNUSED;
+{
+  if (GET_CODE (op) == CONST_INT)
+    return IN_RANGE_P (exact_log2 (INTVAL (op)), 0, 31);
+
+  return FALSE;
+}
+
+/* Return true if the operator is a ==/!= test against f0 or f1 that can be
+   used in conditional execution.  */
+
+int
+condexec_test_operator (op, mode)
+     rtx op;
+     enum machine_mode mode;
+{
+  rtx x0, x1;
+
+  if (GET_MODE (op) != mode && mode != VOIDmode)
+    return FALSE;
+
+  if (GET_CODE (op) != EQ && GET_CODE (op) != NE)
+    return FALSE;
+
+  x0 = XEXP (op, 0);
+  if (GET_CODE (x0) != REG || !BR_FLAG_OR_PSEUDO_P (REGNO (x0)))
+    return FALSE;
+
+  x1 = XEXP (op, 1);
+  if (GET_CODE (x1) != CONST_INT || INTVAL (x1) != 0)
+    return FALSE;
+
+  return TRUE;
+}
+
+/* Return true if the operator is a ==/!= test against f0, f1, or a general
+   register that can be used in a branch instruction.  */
+
+int
+condexec_branch_operator (op, mode)
+     rtx op;
+     enum machine_mode mode;
+{
+  rtx x0, x1;
+
+  if (GET_MODE (op) != mode && mode != VOIDmode)
+    return FALSE;
+
+  if (GET_CODE (op) != EQ && GET_CODE (op) != NE)
+    return FALSE;
+
+  x0 = XEXP (op, 0);
+  if (GET_CODE (x0) == REG)
+    {
+      int regno = REGNO (x0);
+      if (!GPR_OR_PSEUDO_P (regno) && !BR_FLAG_P (regno))
+       return FALSE;
+    }
+  /* Allow the optimizer to generate things like:
+     (if_then_else (ne (const_int 1) (const_int 0))) */
+  else if (GET_CODE (x0) != CONST_INT)
+    return FALSE;
+
+  x1 = XEXP (op, 1);
+  if (GET_CODE (x1) != CONST_INT || INTVAL (x1) != 0)
+    return FALSE;
+
+  return TRUE;
+}
+
+/* Return true if the unary operator can be executed with conditional
+   execution.  */
+
+int
+condexec_unary_operator (op, mode)
+     rtx op;
+     enum machine_mode mode ATTRIBUTE_UNUSED;
+{
+  rtx op0;
+
+  /* Only do this after register allocation, so that we can look at the register # */
+  if (!reload_completed)
+    return FALSE;
+
+  if (GET_RTX_CLASS (GET_CODE (op)) != '1')
+    return FALSE;
+
+  op0 = XEXP (op, 0);
+  if (GET_CODE (op0) == SUBREG)
+    op0 = SUBREG_REG (op0);
+
+  switch (GET_CODE (op))
+    {
+    default:
+      break;
+
+    case ABS:
+    case NOT:
+      if (GET_MODE (op) == SImode && GET_CODE (op0) == REG && GPR_P (REGNO (op0)))
+       return TRUE;
+
+      break;
+    }
+
+  return FALSE;
+}
+
+/* Return true if the add or subtraction can be executed with conditional
+   execution.  */
+
+int
+condexec_addsub_operator (op, mode)
+     rtx op;
+     enum machine_mode mode ATTRIBUTE_UNUSED;
+{
+  rtx op0, op1;
+
+  /* Only do this after register allocation, so that we can look at the register # */
+  if (!reload_completed)
+    return FALSE;
+
+  if (GET_RTX_CLASS (GET_CODE (op)) != '2' && GET_RTX_CLASS (GET_CODE (op)) != 'c')
+    return FALSE;
+
+  op0 = XEXP (op, 0);
+  op1 = XEXP (op, 1);
+
+  if (GET_CODE (op0) == SUBREG)
+    op0 = SUBREG_REG (op0);
+
+  if (GET_CODE (op1) == SUBREG)
+    op1 = SUBREG_REG (op1);
+
+  if (GET_CODE (op0) != REG)
+    return FALSE;
+
+  switch (GET_CODE (op))
+    {
+    default:
+      break;
+
+    case PLUS:
+    case MINUS:
+      return (GET_MODE (op) == SImode && GPR_P (REGNO (op0))
+             && gpr_or_constant_operand (op1, SImode));
+    }
+
+  return FALSE;
+}
+
+/* Return true if the binary operator can be executed with conditional
+   execution.  We don't include add/sub here, since they have extra
+   clobbers for the flags registers.  */
+
+int
+condexec_binary_operator (op, mode)
+     rtx op;
+     enum machine_mode mode ATTRIBUTE_UNUSED;
+{
+  rtx op0, op1;
+
+  /* Only do this after register allocation, so that we can look at the register # */
+  if (!reload_completed)
+    return FALSE;
+
+  if (GET_RTX_CLASS (GET_CODE (op)) != '2' && GET_RTX_CLASS (GET_CODE (op)) != 'c')
+    return FALSE;
+
+  op0 = XEXP (op, 0);
+  op1 = XEXP (op, 1);
+
+  if (GET_CODE (op0) == SUBREG)
+    op0 = SUBREG_REG (op0);
+
+  if (GET_CODE (op1) == SUBREG)
+    op1 = SUBREG_REG (op1);
+
+  if (GET_CODE (op0) != REG)
+    return FALSE;
+
+  /* MULT is not included here, because it is an IU only instruction.  */
+  switch (GET_CODE (op))
+    {
+    default:
+      break;
+
+    case AND:
+    case IOR:
+    case XOR:
+    case ASHIFTRT:
+    case LSHIFTRT:
+    case ROTATERT:
+      return (GET_MODE (op) == SImode && GPR_P (REGNO (op0))
+             && gpr_or_constant_operand (op1, SImode));
+
+    case ASHIFT:
+    case ROTATE:
+      return (GET_MODE (op) == SImode && GPR_P (REGNO (op0))
+             && GET_CODE (op1) == CONST_INT);
+    }
+
+  return FALSE;
+}
+
+/* Return true if the shift/rotate left operator can be executed with
+   conditional execution.  */
+
+int
+condexec_shiftl_operator (op, mode)
+     rtx op;
+     enum machine_mode mode ATTRIBUTE_UNUSED;
+{
+  rtx op0, op1;
+
+  /* Only do this after register allocation, so that we can look at the register # */
+  if (!reload_completed)
+    return FALSE;
+
+  if (GET_RTX_CLASS (GET_CODE (op)) != '2' && GET_RTX_CLASS (GET_CODE (op)) != 'c')
+    return FALSE;
+
+  op0 = XEXP (op, 0);
+  op1 = XEXP (op, 1);
+
+  if (GET_CODE (op0) == SUBREG)
+    op0 = SUBREG_REG (op0);
+
+  if (GET_CODE (op1) == SUBREG)
+    op1 = SUBREG_REG (op1);
+
+  if (GET_CODE (op0) != REG)
+    return FALSE;
+
+  switch (GET_CODE (op))
+    {
+    default:
+      break;
+
+    case ASHIFT:
+    case ROTATE:
+      return (GET_MODE (op) == SImode && GPR_P (REGNO (op0))
+             && GET_CODE (op1) == NEG
+             && GET_CODE (XEXP (op1, 0)) == REG
+             && GPR_P (REGNO (XEXP (op1, 0))));
+    }
+
+  return FALSE;
+}
+
+/* Return true if the {sign,zero} extend operator from memory can be
+   conditionally executed.  */
+
+int
+condexec_extend_operator (op, mode)
+     rtx op;
+     enum machine_mode mode ATTRIBUTE_UNUSED;
+{
+  /* Only do this after register allocation, so that we can look at the register # */
+  if (!reload_completed)
+    return FALSE;
+
+  if (GET_RTX_CLASS (GET_CODE (op)) != '1')
+    return FALSE;
+
+  switch (GET_CODE (op))
+    {
+    default:
+      break;
+
+    case SIGN_EXTEND:
+    case ZERO_EXTEND:
+      if ((GET_MODE (op) == SImode && GET_MODE (XEXP (op, 0)) == QImode)
+         || (GET_MODE (op) == SImode && GET_MODE (XEXP (op, 0)) == HImode)
+         || (GET_MODE (op) == HImode && GET_MODE (XEXP (op, 0)) == QImode))
+       return TRUE;
+
+      break;
+    }
+
+  return FALSE;
+}
+
+/* Return true for comparisons against 0 that can be turned into a
+   bratnz/bratzr instruction.  */
+
+int
+branch_zero_operator (op, mode)
+     rtx op;
+     enum machine_mode mode;
+{
+  rtx x0, x1;
+
+  if (GET_MODE (op) != mode && mode != VOIDmode)
+    return FALSE;
+
+  if (GET_CODE (op) != EQ && GET_CODE (op) != NE)
+    return FALSE;
+
+  x0 = XEXP (op, 0);
+  if (GET_CODE (x0) != REG || !GPR_OR_PSEUDO_P (REGNO (x0)))
+    return FALSE;
+
+  x1 = XEXP (op, 1);
+  if (GET_CODE (x1) != CONST_INT || INTVAL (x1) != 0)
+    return FALSE;
+
+  return TRUE;
+}
+
+/* Return true if an operand is simple, suitable for use as the destination of
+   a conditional move */
+
+int
+cond_move_dest_operand (op, mode)
+     register rtx op;
+     enum machine_mode mode ATTRIBUTE_UNUSED;
+{
+  rtx addr;
+
+  if (mode != QImode && mode != HImode && mode != SImode && mode != SFmode)
+    return FALSE;
+
+  switch (GET_CODE (op))
+    {
+    default:
+      break;
+
+    case REG:
+    case SUBREG:
+      return gpr_operand (op, mode);
+
+    /* Don't allow post dec/inc, since we might not get the side effects correct. */
+    case MEM:
+      addr = XEXP (op, 0);
+      return (GET_CODE (addr) != POST_DEC
+             && GET_CODE (addr) != POST_INC
+             && d30v_legitimate_address_p (mode, addr, reload_completed));
+    }
+
+  return FALSE;
+}
+
+/* Return true if an operand is simple, suitable for use in a conditional move */
+
+int
+cond_move_operand (op, mode)
+     register rtx op;
+     enum machine_mode mode ATTRIBUTE_UNUSED;
+{
+  rtx addr;
+
+  if (mode != QImode && mode != HImode && mode != SImode && mode != SFmode)
+    return FALSE;
+
+  switch (GET_CODE (op))
+    {
+    default:
+      break;
+
+    case REG:
+    case SUBREG:
+      return gpr_operand (op, mode);
+
+    case CONST_DOUBLE:
+      return GET_MODE (op) == SFmode;
+
+    case CONST_INT:
+    case SYMBOL_REF:
+    case LABEL_REF:
+    case CONST:
+      return TRUE;
+
+    /* Don't allow post dec/inc, since we might not get the side effects correct. */
+    case MEM:
+      addr = XEXP (op, 0);
+      return (GET_CODE (addr) != POST_DEC
+             && GET_CODE (addr) != POST_INC
+             && d30v_legitimate_address_p (mode, addr, reload_completed));
+    }
+
+  return FALSE;
+}
+
+/* Return true if an operand is simple, suitable for use in conditional execution.
+   Unlike cond_move, we can allow auto inc/dec.  */
+
+int
+cond_exec_operand (op, mode)
+     register rtx op;
+     enum machine_mode mode;
+{
+  if (mode != QImode && mode != HImode && mode != SImode && mode != SFmode)
+    return FALSE;
+
+  switch (GET_CODE (op))
+    {
+    default:
+      break;
+
+    case REG:
+    case SUBREG:
+      return gpr_operand (op, mode);
+
+    case CONST_DOUBLE:
+      return GET_MODE (op) == SFmode;
+
+    case CONST_INT:
+    case SYMBOL_REF:
+    case LABEL_REF:
+    case CONST:
+      return TRUE;
+
+    case MEM:
+      return memory_operand (op, mode);
+    }
+
+  return FALSE;
+}
+
+/* Return true if operand is a SI mode signed relational test.  */
+
+int
+srelational_si_operator (op, mode)
+     register rtx op;
+     enum machine_mode mode;
+{
+  rtx x0, x1;
+
+  if (GET_MODE (op) != mode && mode != VOIDmode)
+    return FALSE;
+
+  switch (GET_CODE (op))
+    {
+    default:
+      return FALSE;
+
+    case EQ:
+    case NE:
+    case LT:
+    case LE:
+    case GT:
+    case GE:
+      break;
+    }
+
+  x0 = XEXP (op, 0);
+  if (GET_CODE (x0) != REG && GET_CODE (x0) != SUBREG)
+    return FALSE;
+
+  if (GET_MODE (x0) != SImode)
+    return FALSE;
+
+  x1 = XEXP (op, 1);
+  switch (GET_CODE (x1))
+    {
+    default:
+      return FALSE;
+
+    case REG:
+    case SUBREG:
+    case CONST_INT:
+    case LABEL_REF:
+    case SYMBOL_REF:
+    case CONST:
+      break;
+    }
+
+  return TRUE;
+}
+
+/* Return true if operand is a SI mode unsigned relational test.  */
+
+int
+urelational_si_operator (op, mode)
+     register rtx op;
+     enum machine_mode mode;
+{
+  rtx x0, x1;
+
+  if (GET_MODE (op) != mode && mode != VOIDmode)
+    return FALSE;
+
+  switch (GET_CODE (op))
+    {
+    default:
+      return FALSE;
+
+    case LTU:
+    case LEU:
+    case GTU:
+    case GEU:
+      break;
+    }
+
+  x0 = XEXP (op, 0);
+  if (GET_CODE (x0) != REG && GET_CODE (x0) != SUBREG)
+    return FALSE;
+
+  if (GET_MODE (x0) != SImode)
+    return FALSE;
+
+  x1 = XEXP (op, 1);
+  switch (GET_CODE (x1))
+    {
+    default:
+      return FALSE;
+
+    case REG:
+    case SUBREG:
+    case CONST_INT:
+    case LABEL_REF:
+    case SYMBOL_REF:
+    case CONST:
+      break;
+    }
+
+  return TRUE;
+}
+
+/* Return true if operand is a DI mode relational test.  */
+
+int
+relational_di_operator (op, mode)
+     register rtx op;
+     enum machine_mode mode;
+{
+  rtx x0, x1;
+
+  if (GET_MODE (op) != mode && mode != VOIDmode)
+    return FALSE;
+
+  if (GET_RTX_CLASS (GET_CODE (op)) != '<')
+    return FALSE;
+
+  x0 = XEXP (op, 0);
+  if (GET_CODE (x0) != REG && GET_CODE (x0) != SUBREG)
+    return FALSE;
+
+  if (GET_MODE (x0) != DImode)
+    return FALSE;
+
+  x1 = XEXP (op, 1);
+  if (GET_CODE (x1) != REG && GET_CODE (x1) != SUBREG
+      && GET_CODE (x1) != CONST_INT && GET_CODE (x1) != CONST_DOUBLE)
+    return FALSE;
+
+  return TRUE;
+}
+
+\f
+/* Calculate the stack information for the current function.
+
+   D30V stack frames look like:
+
+       high            |  ....                         |
+                       +-------------------------------+
+                       | Argument word #19             |
+                       +-------------------------------+
+                       | Argument word #18             |
+                       +-------------------------------+
+                       | Argument word #17             |
+                       +-------------------------------+
+                       | Argument word #16             |
+               Prev sp +-------------------------------+
+                       |                               |
+                       | Save for arguments 1..16 if   |
+                       | the func. uses stdarg/varargs |
+                       |                               |
+                       +-------------------------------+
+                       |                               |
+                       | Save area for GPR registers   |
+                       |                               |
+                       +-------------------------------+
+                       |                               |
+                       | Save area for accumulators    |
+                       |                               |
+                       +-------------------------------+
+                       |                               |
+                       | Local variables               |
+                       |                               |
+                       +-------------------------------+
+                       |                               |
+                       | alloca space if used          |
+                       |                               |
+                       +-------------------------------+
+                       |                               |
+                       | Space for outgoing arguments  |
+                       |                               |
+       low     SP----> +-------------------------------+
+*/
+
+d30v_stack_t *
+d30v_stack_info ()
+{
+  static d30v_stack_t info, zero_info;
+  d30v_stack_t *info_ptr = &info;
+  tree fndecl           = current_function_decl;
+  tree fntype           = TREE_TYPE (fndecl);
+  int varargs_p                 = 0;
+  tree cur_arg;
+  tree next_arg;
+  int saved_gprs;
+  int saved_accs;
+  int memrefs_2words;
+  int memrefs_1word;
+  unsigned char save_gpr_p[GPR_LAST];
+  int i;
+
+  /* If we've already calculated the values and reload is complete, just return now */
+  if (d30v_stack_cache)
+    return d30v_stack_cache;
+
+  /* Zero all fields */
+  info = zero_info;
+
+  if (profile_flag)
+    regs_ever_live[GPR_LINK] = 1;
+
+  /* Determine if this is a stdarg function */
+  if (TYPE_ARG_TYPES (fntype) != 0
+      && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype))) != void_type_node))
+    varargs_p = 1;
+  else
+    {
+      /* Find the last argument, and see if it is __builtin_va_alist.  */
+      for (cur_arg = DECL_ARGUMENTS (fndecl); cur_arg != (tree)0; cur_arg = next_arg)
+       {
+         next_arg = TREE_CHAIN (cur_arg);
+         if (next_arg == (tree)0)
+           {
+             if (DECL_NAME (cur_arg)
+                 && !strcmp (IDENTIFIER_POINTER (DECL_NAME (cur_arg)), "__builtin_va_alist"))
+               varargs_p = 1;
+
+             break;
+           }
+       }
+    }
+
+  /* Calculate which registers need to be saved & save area size */
+  saved_accs = 0;
+  memrefs_2words = 0;
+  memrefs_1word = 0;
+  for (i = ACCUM_FIRST; i <= ACCUM_LAST; i++)
+    {
+      if (regs_ever_live[i] && !call_used_regs[i])
+       {
+         info_ptr->save_p[i] = 2;
+         saved_accs++;
+         memrefs_2words++;
+       }
+    }
+
+  saved_gprs = 0;
+  for (i = GPR_FIRST; i <= GPR_LAST; i++)
+    {
+      if (regs_ever_live[i] && (!call_used_regs[i] || i == GPR_LINK))
+       {
+         save_gpr_p[i] = 1;
+         saved_gprs++;
+       }
+      else
+       save_gpr_p[i] = 0;
+    }
+
+  /* Determine which register pairs can be saved together with ld2w/st2w  */
+  for (i = GPR_FIRST; i <= GPR_LAST; i++)
+    {
+      if (((i - GPR_FIRST) & 1) == 0 && save_gpr_p[i] && save_gpr_p[i+1])
+       {
+         memrefs_2words++;
+         info_ptr->save_p[i++] = 2;
+       }
+      else if (save_gpr_p[i])
+       {
+         memrefs_1word++;
+         info_ptr->save_p[i] = 1;
+       }
+    }
+
+  /* Determine various sizes */
+  info_ptr->varargs_p   = varargs_p;
+  info_ptr->varargs_size = ((varargs_p)
+                           ? (GPR_ARG_LAST + 1 - GPR_ARG_FIRST) * UNITS_PER_WORD
+                           : 0);
+
+  info_ptr->accum_size  = 2 * UNITS_PER_WORD * saved_accs;
+  info_ptr->gpr_size    = D30V_ALIGN (UNITS_PER_WORD * saved_gprs,
+                                      2 * UNITS_PER_WORD);
+  info_ptr->vars_size    = D30V_ALIGN (get_frame_size (), 2 * UNITS_PER_WORD);
+  info_ptr->parm_size    = D30V_ALIGN (current_function_outgoing_args_size,
+                                      2 * UNITS_PER_WORD);
+
+  info_ptr->total_size  = D30V_ALIGN ((info_ptr->gpr_size
+                                       + info_ptr->accum_size
+                                       + info_ptr->vars_size
+                                       + info_ptr->parm_size
+                                       + info_ptr->varargs_size
+                                       + current_function_pretend_args_size),
+                                      (STACK_BOUNDARY / BITS_PER_UNIT));
+
+  info_ptr->save_offset  = (info_ptr->total_size
+                           - (current_function_pretend_args_size
+                              + info_ptr->varargs_size
+                              + info_ptr->gpr_size
+                              + info_ptr->accum_size));
+
+  /* The link register is the last GPR saved, but there might be some padding
+     bytes after it, so account for that.  */
+  info_ptr->link_offset  = (info_ptr->total_size
+                           - (current_function_pretend_args_size
+                              + info_ptr->varargs_size
+                              + (info_ptr->gpr_size
+                                 - UNITS_PER_WORD * saved_gprs)
+                              + UNITS_PER_WORD));
+
+  info_ptr->memrefs_varargs = info_ptr->varargs_size / (2 * UNITS_PER_WORD);
+  info_ptr->memrefs_2words  = memrefs_2words;
+  info_ptr->memrefs_1word   = memrefs_1word;
+
+  if (reload_completed)
+    d30v_stack_cache = info_ptr;
+
+  return info_ptr;
+}
+
+\f
+/* Internal function to print all of the information about the stack */
+
+void
+debug_stack_info (info)
+     d30v_stack_t *info;
+{
+  int i;
+
+  if (!info)
+    info = d30v_stack_info ();
+
+  fprintf (stderr, "\nStack information for function %s:\n",
+          ((current_function_decl && DECL_NAME (current_function_decl))
+           ? IDENTIFIER_POINTER (DECL_NAME (current_function_decl))
+           : "<unknown>"));
+
+  fprintf (stderr, "\tsave_offset     = %d\n", info->save_offset);
+  fprintf (stderr, "\tmemrefs_varargs = %d\n", info->memrefs_varargs);
+  fprintf (stderr, "\tmemrefs_2words  = %d\n", info->memrefs_2words);
+  fprintf (stderr, "\tmemrefs_1word   = %d\n", info->memrefs_1word);
+  fprintf (stderr, "\tvarargs_p       = %d\n", info->varargs_p);
+  fprintf (stderr, "\tvarargs_size    = %d\n", info->varargs_size);
+  fprintf (stderr, "\tvars_size       = %d\n", info->vars_size);
+  fprintf (stderr, "\tparm_size       = %d\n", info->parm_size);
+  fprintf (stderr, "\tgpr_size        = %d\n", info->gpr_size);
+  fprintf (stderr, "\taccum_size      = %d\n", info->accum_size);
+  fprintf (stderr, "\ttotal_size      = %d\n", info->total_size);
+  fprintf (stderr, "\tsaved registers =");
+
+  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
+    {
+      if (info->save_p[i] == 2)
+       {
+         fprintf (stderr, " %s-%s", reg_names[i], reg_names[i+1]);
+         i++;
+       }
+      else if (info->save_p[i])
+       fprintf (stderr, " %s", reg_names[i]);
+    }
+
+  putc ('\n', stderr);
+  fflush (stderr);
+}
+
+\f
+/* Return non-zero if this function is known to have a null or 1 instruction epilogue.  */
+
+int
+direct_return ()
+{
+  if (reload_completed)
+    {
+      d30v_stack_t *info = d30v_stack_info ();
+
+      /* If no epilogue code is needed, can use just a simple jump */
+      if (info->total_size == 0)
+       return 1;
+
+#if 0
+      /* If just a small amount of local stack was allocated and no registers
+         saved, skip forward branch */
+      if (info->total_size == info->vars_size
+         && IN_RANGE_P (info->total_size, 1, 31))
+       return 1;
+#endif
+    }
+
+  return 0;
+}
+
+\f
+/* A C statement (sans semicolon) for initializing the variable CUM for the
+   state at the beginning of the argument list.  The variable has type
+   `CUMULATIVE_ARGS'.  The value of FNTYPE is the tree node for the data type
+   of the function which will receive the args, or 0 if the args are to a
+   compiler support library function.  The value of INDIRECT is nonzero when
+   processing an indirect call, for example a call through a function pointer.
+   The value of INDIRECT is zero for a call to an explicitly named function, a
+   library function call, or when `INIT_CUMULATIVE_ARGS' is used to find
+   arguments for the function being compiled.
+
+   When processing a call to a compiler support library function, LIBNAME
+   identifies which one.  It is a `symbol_ref' rtx which contains the name of
+   the function, as a string.  LIBNAME is 0 when an ordinary C function call is
+   being processed.  Thus, each time this macro is called, either LIBNAME or
+   FNTYPE is nonzero, but never both of them at once.  */
+
+void
+d30v_init_cumulative_args (cum, fntype, libname, indirect, incoming)
+     CUMULATIVE_ARGS *cum;
+     tree fntype;
+     rtx libname;
+     int indirect;
+     int incoming;
+{
+  *cum = GPR_ARG_FIRST;
+
+  if (TARGET_DEBUG_ARG)
+    {
+      fprintf (stderr, "\ninit_cumulative_args:");
+      if (indirect)
+       fputs (" indirect", stderr);
+
+      if (incoming)
+       fputs (" incoming", stderr);
+
+      if (fntype)
+       {
+         tree ret_type = TREE_TYPE (fntype);
+         fprintf (stderr, " return=%s,",
+                  tree_code_name[ (int)TREE_CODE (ret_type) ]);
+       }
+
+      if (libname && GET_CODE (libname) == SYMBOL_REF)
+       fprintf (stderr, " libname=%s", XSTR (libname, 0));
+
+      putc ('\n', stderr);
+    }
+}
+
+\f
+/* If defined, a C expression that gives the alignment boundary, in bits, of an
+   argument with the specified mode and type.  If it is not defined,
+   `PARM_BOUNDARY' is used for all arguments.  */
+
+int
+d30v_function_arg_boundary (mode, type)
+     enum machine_mode mode;
+     tree type;
+{
+  int size = ((mode == BLKmode && type)
+             ? int_size_in_bytes (type)
+             : GET_MODE_SIZE (mode));
+
+  return (size > UNITS_PER_WORD) ? 2*UNITS_PER_WORD : UNITS_PER_WORD;
+}
+
+\f
+/* A C expression that controls whether a function argument is passed in a
+   register, and which register.
+
+   The arguments are CUM, which summarizes all the previous arguments; MODE,
+   the machine mode of the argument; TYPE, the data type of the argument as a
+   tree node or 0 if that is not known (which happens for C support library
+   functions); and NAMED, which is 1 for an ordinary argument and 0 for
+   nameless arguments that correspond to `...' in the called function's
+   prototype.
+
+   The value of the expression should either be a `reg' RTX for the hard
+   register in which to pass the argument, or zero to pass the argument on the
+   stack.
+
+   For machines like the Vax and 68000, where normally all arguments are
+   pushed, zero suffices as a definition.
+
+   The usual way to make the ANSI library `stdarg.h' work on a machine where
+   some arguments are usually passed in registers, is to cause nameless
+   arguments to be passed on the stack instead.  This is done by making
+   `FUNCTION_ARG' return 0 whenever NAMED is 0.
+
+   You may use the macro `MUST_PASS_IN_STACK (MODE, TYPE)' in the definition of
+   this macro to determine if this argument is of a type that must be passed in
+   the stack.  If `REG_PARM_STACK_SPACE' is not defined and `FUNCTION_ARG'
+   returns non-zero for such an argument, the compiler will abort.  If
+   `REG_PARM_STACK_SPACE' is defined, the argument will be computed in the
+   stack and then loaded into a register.  */
+
+rtx
+d30v_function_arg (cum, mode, type, named, incoming)
+     CUMULATIVE_ARGS *cum;
+     enum machine_mode mode;
+     tree type;
+     int named;
+     int incoming ATTRIBUTE_UNUSED;
+{
+  int size = ((mode == BLKmode && type)
+             ? int_size_in_bytes (type)
+             : GET_MODE_SIZE (mode));
+  int adjust = (size > UNITS_PER_WORD && (*cum & 1) != 0);
+  rtx ret;
+
+  /* Return a marker for use in the call instruction.  */
+  if (mode == VOIDmode)
+    ret = const0_rtx;
+
+  else if (*cum + adjust <= GPR_ARG_LAST)
+    ret = gen_rtx (REG, mode, *cum + adjust);
+
+  else
+    ret = NULL_RTX;
+
+  if (TARGET_DEBUG_ARG)
+    fprintf (stderr,
+            "function_arg: words = %2d, mode = %4s, named = %d, size = %3d, adjust = %1d, arg = %s\n",
+            *cum, GET_MODE_NAME (mode), named, size, adjust,
+            (ret) ? ((ret == const0_rtx) ? "<0>" : reg_names[ REGNO (ret) ]) : "memory");
+
+  return ret;
+}
+
+\f
+/* A C expression for the number of words, at the beginning of an argument,
+   must be put in registers.  The value must be zero for arguments that are
+   passed entirely in registers or that are entirely pushed on the stack.
+
+   On some machines, certain arguments must be passed partially in registers
+   and partially in memory.  On these machines, typically the first N words of
+   arguments are passed in registers, and the rest on the stack.  If a
+   multi-word argument (a `double' or a structure) crosses that boundary, its
+   first few words must be passed in registers and the rest must be pushed.
+   This macro tells the compiler when this occurs, and how many of the words
+   should go in registers.
+
+   `FUNCTION_ARG' for these arguments should return the first register to be
+   used by the caller for this argument; likewise `FUNCTION_INCOMING_ARG', for
+   the called function.  */
+
+int
+d30v_function_arg_partial_nregs (cum, mode, type, named)
+     CUMULATIVE_ARGS *cum;
+     enum machine_mode mode;
+     tree type;
+     int named ATTRIBUTE_UNUSED;
+{
+  int bytes = ((mode == BLKmode)
+              ? int_size_in_bytes (type)
+              : GET_MODE_SIZE (mode));
+  int words = (bytes + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
+  int adjust = (bytes > UNITS_PER_WORD && (*cum & 1) != 0);
+  int arg_num = *cum + adjust;
+  int ret;
+
+  ret = ((arg_num <= GPR_ARG_LAST && arg_num + words > GPR_ARG_LAST+1)
+        ? GPR_ARG_LAST - arg_num + 1
+        : 0);
+
+  if (TARGET_DEBUG_ARG && ret)
+    fprintf (stderr, "function_arg_partial_nregs: %d\n", ret);
+
+  return ret;
+}
+
+\f
+/* A C expression that indicates when an argument must be passed by reference.
+   If nonzero for an argument, a copy of that argument is made in memory and a
+   pointer to the argument is passed instead of the argument itself.  The
+   pointer is passed in whatever way is appropriate for passing a pointer to
+   that type.
+
+   On machines where `REG_PARM_STACK_SPACE' is not defined, a suitable
+   definition of this macro might be
+        #define FUNCTION_ARG_PASS_BY_REFERENCE\
+        (CUM, MODE, TYPE, NAMED)  \
+          MUST_PASS_IN_STACK (MODE, TYPE)  */
+
+int
+d30v_function_arg_pass_by_reference (cum, mode, type, named)
+     CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED;
+     enum machine_mode mode;
+     tree type;
+     int named ATTRIBUTE_UNUSED;
+{
+  int ret = MUST_PASS_IN_STACK (mode, type);
+
+  if (TARGET_DEBUG_ARG && ret)
+    fprintf (stderr, "function_arg_pass_by_reference: %d\n", ret);
+
+  return ret;
+}
+
+\f
+/* A C statement (sans semicolon) to update the summarizer variable CUM to
+   advance past an argument in the argument list.  The values MODE, TYPE and
+   NAMED describe that argument.  Once this is done, the variable CUM is
+   suitable for analyzing the *following* argument with `FUNCTION_ARG', etc.
+
+   This macro need not do anything if the argument in question was passed on
+   the stack.  The compiler knows how to track the amount of stack space used
+   for arguments without any special help.  */
+
+void
+d30v_function_arg_advance (cum, mode, type, named)
+     CUMULATIVE_ARGS *cum;
+     enum machine_mode mode;
+     tree type;
+     int named;
+{
+  int bytes = ((mode == BLKmode)
+              ? int_size_in_bytes (type)
+              : GET_MODE_SIZE (mode));
+  int words = D30V_ALIGN (bytes, UNITS_PER_WORD) / UNITS_PER_WORD;
+  int adjust = (bytes > UNITS_PER_WORD && (*cum & 1) != 0);
+
+  *cum += words + adjust;
+
+  if (TARGET_DEBUG_ARG)
+    fprintf (stderr,
+            "function_adv: words = %2d, mode = %4s, named = %d, size = %3d, adjust = %1d\n",
+            *cum, GET_MODE_NAME (mode), named, words * UNITS_PER_WORD, adjust);
+}
+
+\f
+/* If defined, is a C expression that produces the machine-specific code for a
+   call to `__builtin_saveregs'.  This code will be moved to the very beginning
+   of the function, before any parameter access are made.  The return value of
+   this function should be an RTX that contains the value to use as the return
+   of `__builtin_saveregs'.
+
+   If this macro is not defined, the compiler will output an ordinary call to
+   the library function `__builtin_saveregs'.  */
+
+rtx
+d30v_expand_builtin_saveregs ()
+{
+  int offset = UNITS_PER_WORD * (GPR_ARG_LAST + 1 - GPR_ARG_FIRST);
+
+  if (TARGET_DEBUG_ARG)
+    fprintf (stderr, "expand_builtin_saveregs: offset from ap = %d\n",
+            offset);
+
+  return gen_rtx (PLUS, Pmode, virtual_incoming_args_rtx, GEN_INT (- offset));
+}
+
+\f
+/* This macro offers an alternative to using `__builtin_saveregs' and defining
+   the macro `EXPAND_BUILTIN_SAVEREGS'.  Use it to store the anonymous register
+   arguments into the stack so that all the arguments appear to have been
+   passed consecutively on the stack.  Once this is done, you can use the
+   standard implementation of varargs that works for machines that pass all
+   their arguments on the stack.
+
+   The argument ARGS_SO_FAR is the `CUMULATIVE_ARGS' data structure, containing
+   the values that obtain after processing of the named arguments.  The
+   arguments MODE and TYPE describe the last named argument--its machine mode
+   and its data type as a tree node.
+
+   The macro implementation should do two things: first, push onto the stack
+   all the argument registers *not* used for the named arguments, and second,
+   store the size of the data thus pushed into the `int'-valued variable whose
+   name is supplied as the argument PRETEND_ARGS_SIZE.  The value that you
+   store here will serve as additional offset for setting up the stack frame.
+
+   Because you must generate code to push the anonymous arguments at compile
+   time without knowing their data types, `SETUP_INCOMING_VARARGS' is only
+   useful on machines that have just a single category of argument register and
+   use it uniformly for all data types.
+
+   If the argument SECOND_TIME is nonzero, it means that the arguments of the
+   function are being analyzed for the second time.  This happens for an inline
+   function, which is not actually compiled until the end of the source file.
+   The macro `SETUP_INCOMING_VARARGS' should not generate any instructions in
+   this case.  */
+
+void
+d30v_setup_incoming_varargs (cum, mode, type, pretend_size, second_time)
+     CUMULATIVE_ARGS *cum;
+     enum machine_mode mode;
+     tree type ATTRIBUTE_UNUSED;
+     int *pretend_size ATTRIBUTE_UNUSED;
+     int second_time;
+{
+  if (TARGET_DEBUG_ARG)
+    fprintf (stderr,
+            "setup_vararg: words = %2d, mode = %4s, second_time = %d\n",
+            *cum, GET_MODE_NAME (mode), second_time);
+}
+
+\f
+/* Create the va_list data type.  */
+
+tree
+d30v_build_va_list ()
+{
+  tree f_arg_ptr, f_arg_num, record, type_decl;
+  tree int_type_node;
+
+  record = make_lang_type (RECORD_TYPE);
+  type_decl = build_decl (TYPE_DECL, get_identifier ("__va_list_tag"), record);
+  int_type_node = make_signed_type (INT_TYPE_SIZE);
+
+  f_arg_ptr = build_decl (FIELD_DECL, get_identifier ("__va_arg_ptr"), 
+                         ptr_type_node);
+  f_arg_num = build_decl (FIELD_DECL, get_identifier ("__va_arg_num"),
+                         int_type_node);
+
+  DECL_FIELD_CONTEXT (f_arg_ptr) = record;
+  DECL_FIELD_CONTEXT (f_arg_num) = record;
+
+  TREE_CHAIN (record) = type_decl;
+  TYPE_NAME (record) = type_decl;
+  TYPE_FIELDS (record) = f_arg_ptr;
+  TREE_CHAIN (f_arg_ptr) = f_arg_num;
+
+  layout_type (record);
+
+  /* The correct type is an array type of one element.  */
+  return build_array_type (record, build_index_type (size_zero_node));
+}
+
+\f
+/* Expand __builtin_va_start to do the va_start macro.  */
+
+void 
+d30v_expand_builtin_va_start (stdarg_p, valist, nextarg)
+     int stdarg_p ATTRIBUTE_UNUSED;
+     tree valist;
+     rtx nextarg ATTRIBUTE_UNUSED;
+{
+  HOST_WIDE_INT words;
+  tree f_arg_ptr, f_arg_num;
+  tree arg_ptr, arg_num, saveregs, t;
+
+  f_arg_ptr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
+  f_arg_num = TREE_CHAIN (f_arg_ptr);
+
+  valist = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (valist)), valist);
+  arg_ptr = build (COMPONENT_REF, TREE_TYPE (f_arg_ptr), valist, f_arg_ptr);
+  arg_num = build (COMPONENT_REF, TREE_TYPE (f_arg_num), valist, f_arg_num);
+
+  words = current_function_args_info;  /* __builtin_args_info (0) */
+
+  /* (AP)->__va_arg_ptr = (int *) __builtin_saveregs (); */
+  saveregs = make_tree (TREE_TYPE (arg_ptr), d30v_expand_builtin_saveregs ());
+  t = build (MODIFY_EXPR, TREE_TYPE (arg_ptr), arg_ptr, saveregs);
+  TREE_SIDE_EFFECTS (t) = 1;
+  expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
+
+  /* (AP)->__va_arg_num = __builtin_args_info (0) - 2; */
+  t = build (PLUS_EXPR, TREE_TYPE (arg_num), build_int_2 (words, 0),
+            build_int_2 (-GPR_ARG_FIRST, 0));
+  t = build (MODIFY_EXPR, TREE_TYPE (arg_num), arg_num, t);
+  TREE_SIDE_EFFECTS (t) = 1;
+  expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
+}
+
+\f
+/* Expand __builtin_va_arg to do the va_arg macro.  */
+
+rtx
+d30v_expand_builtin_va_arg(valist, type)
+     tree valist;
+     tree type;
+{
+  tree f_arg_ptr, f_arg_num;
+  tree arg_ptr, arg_num, t, ptr;
+  int num, size;
+  rtx lab_false, ptr_rtx, r;
+
+  f_arg_ptr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
+  f_arg_num = TREE_CHAIN (f_arg_ptr);
+
+  valist = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (valist)), valist);
+  arg_ptr = build (COMPONENT_REF, TREE_TYPE (f_arg_ptr), valist, f_arg_ptr);
+  arg_num = build (COMPONENT_REF, TREE_TYPE (f_arg_num), valist, f_arg_num);
+
+  size = int_size_in_bytes (type);
+
+  lab_false = gen_label_rtx ();
+  ptr_rtx = gen_reg_rtx (Pmode);
+
+  /* if (sizeof (TYPE) > 4 && ((AP)->__va_arg_num & 1) != 0)
+       (AP)->__va_arg_num++; */
+
+  if (size > UNITS_PER_WORD) 
+    {
+      t = build (BIT_AND_EXPR, TREE_TYPE (arg_num), arg_num, 
+                build_int_2 (1, 0));
+
+      emit_cmp_and_jump_insns (expand_expr (t, NULL_RTX, QImode, EXPAND_NORMAL),
+                              GEN_INT (0), EQ, const1_rtx, QImode, 1, 1,
+                              lab_false);
+
+      t = build (POSTINCREMENT_EXPR, TREE_TYPE (arg_num), arg_num,
+                build_int_2 (1, 0));
+      TREE_SIDE_EFFECTS (t) = 1;
+      expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
+
+      emit_label (lab_false);
+    }
+
+
+  /* __ptr = (TYPE *)(((char *)(void *)((AP)->__va_arg_ptr 
+            + (AP)->__va_arg_num))); */
+
+  t = build (MULT_EXPR, TREE_TYPE (arg_num), arg_num, build_int_2 (4, 0));
+  t = build (PLUS_EXPR, ptr_type_node, arg_ptr, t);
+
+  /* if (sizeof (TYPE) < 4)
+       __ptr = (void *)__ptr + 4 - sizeof (TYPE); */
+
+  if (size < UNITS_PER_WORD)
+    t = build (PLUS_EXPR, ptr_type_node, t,
+              build_int_2 (UNITS_PER_WORD - size, 0));
+
+  TREE_SIDE_EFFECTS (t) = 1;
+
+  ptr = build1 (NOP_EXPR, build_pointer_type (type), t);
+  t = build (MODIFY_EXPR, type, ptr, t);
+
+  r = expand_expr (t, ptr_rtx, Pmode, EXPAND_NORMAL);
+  if (r != ptr_rtx)
+    emit_move_insn (ptr_rtx, r);
+
+
+  /* (AP)->__va_arg_num += (sizeof (TYPE) + 3) / 4; */
+  num = (size + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD;
+  t = build (POSTINCREMENT_EXPR, TREE_TYPE (arg_num), arg_num, 
+            build_int_2 (num, 0));
+  expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
+
+  return ptr_rtx;
+}
+\f
+
+/* A C compound statement that outputs the assembler code for entry to a
+   function.  The prologue is responsible for setting up the stack frame,
+   initializing the frame pointer register, saving registers that must be
+   saved, and allocating SIZE additional bytes of storage for the local
+   variables.  SIZE is an integer.  FILE is a stdio stream to which the
+   assembler code should be output.
+
+   The label for the beginning of the function need not be output by this
+   macro.  That has already been done when the macro is run.
+
+   To determine which registers to save, the macro can refer to the array
+   `regs_ever_live': element R is nonzero if hard register R is used anywhere
+   within the function.  This implies the function prologue should save
+   register R, provided it is not one of the call-used registers.
+   (`FUNCTION_EPILOGUE' must likewise use `regs_ever_live'.)
+
+   On machines that have "register windows", the function entry code does not
+   save on the stack the registers that are in the windows, even if they are
+   supposed to be preserved by function calls; instead it takes appropriate
+   steps to "push" the register stack, if any non-call-used registers are used
+   in the function.
+
+   On machines where functions may or may not have frame-pointers, the function
+   entry code must vary accordingly; it must set up the frame pointer if one is
+   wanted, and not otherwise.  To determine whether a frame pointer is in
+   wanted, the macro can refer to the variable `frame_pointer_needed'.  The
+   variable's value will be 1 at run time in a function that needs a frame
+   pointer.  *Note Elimination::.
+
+   The function entry code is responsible for allocating any stack space
+   required for the function.  This stack space consists of the regions listed
+   below.  In most cases, these regions are allocated in the order listed, with
+   the last listed region closest to the top of the stack (the lowest address
+   if `STACK_GROWS_DOWNWARD' is defined, and the highest address if it is not
+   defined).  You can use a different order for a machine if doing so is more
+   convenient or required for compatibility reasons.  Except in cases where
+   required by standard or by a debugger, there is no reason why the stack
+   layout used by GCC need agree with that used by other compilers for a
+   machine.
+
+      * A region of `current_function_pretend_args_size' bytes of
+        uninitialized space just underneath the first argument
+        arriving on the stack.  (This may not be at the very start of
+        the allocated stack region if the calling sequence has pushed
+        anything else since pushing the stack arguments.  But
+        usually, on such machines, nothing else has been pushed yet,
+        because the function prologue itself does all the pushing.)
+        This region is used on machines where an argument may be
+        passed partly in registers and partly in memory, and, in some
+        cases to support the features in `varargs.h' and `stdargs.h'.
+
+      * An area of memory used to save certain registers used by the
+        function.  The size of this area, which may also include
+        space for such things as the return address and pointers to
+        previous stack frames, is machine-specific and usually
+        depends on which registers have been used in the function.
+        Machines with register windows often do not require a save
+        area.
+
+      * A region of at least SIZE bytes, possibly rounded up to an
+        allocation boundary, to contain the local variables of the
+        function.  On some machines, this region and the save area
+        may occur in the opposite order, with the save area closer to
+        the top of the stack.
+
+      * Optionally, when `ACCUMULATE_OUTGOING_ARGS' is defined, a
+        region of `current_function_outgoing_args_size' bytes to be
+        used for outgoing argument lists of the function.  *Note
+        Stack Arguments::.
+
+   Normally, it is necessary for the macros `FUNCTION_PROLOGUE' and
+   `FUNCTION_EPILOGUE' to treat leaf functions specially.  The C variable
+   `leaf_function' is nonzero for such a function.  */
+
+/* For the d30v, move all of the prologue processing into separate insns.  */
+void
+d30v_function_prologue (stream, size)
+     FILE *stream ATTRIBUTE_UNUSED;
+     int size ATTRIBUTE_UNUSED;
+{
+}
+
+\f
+/* Called after register allocation to add any instructions needed for the
+   prologue.  Using a prologue insn is favored compared to putting all of the
+   instructions in the FUNCTION_PROLOGUE macro, since it allows the scheduler
+   to intermix instructions with the saves of the caller saved registers.  In
+   some cases, it might be necessary to emit a barrier instruction as the last
+   insn to prevent such scheduling.  */
+
+void
+d30v_expand_prologue ()
+{
+  rtx sp = stack_pointer_rtx;
+  d30v_stack_t *info = d30v_stack_info ();
+  int i;
+  rtx mem_di = NULL_RTX;
+  rtx mem_si = NULL_RTX;
+  int num_memrefs = (info->memrefs_2words
+                    + info->memrefs_1word
+                    + info->memrefs_varargs);
+
+  if (TARGET_DEBUG_STACK)
+    debug_stack_info (info);
+
+  /* Grow the stack.  */
+  if (info->total_size)
+    emit_insn (gen_addsi3 (sp, sp, GEN_INT (- info->total_size)));
+
+  /* If there is more than one save, use post-increment addressing which will
+     result in smaller code, than would the normal references.  If there is
+     only one save, just do the store as normal.  */
+
+  if (num_memrefs > 1)
+    {
+      rtx save_tmp = gen_rtx (REG, Pmode, GPR_STACK_TMP);
+      rtx post_inc = gen_rtx (POST_INC, Pmode, save_tmp);
+      mem_di = gen_rtx (MEM, DImode, post_inc);
+      mem_si = gen_rtx (MEM, SImode, post_inc);
+      emit_insn (gen_addsi3 (save_tmp, sp, GEN_INT (info->save_offset)));
+    }
+  else if (num_memrefs == 1)
+    {
+      rtx addr = plus_constant (sp, info->save_offset);
+      mem_di = gen_rtx (MEM, DImode, addr);
+      mem_si = gen_rtx (MEM, SImode, addr);
+    }
+
+  /* Save the accumulators.  */
+  for (i = ACCUM_FIRST; i <= ACCUM_LAST; i++)
+    if (info->save_p[i])
+      {
+       rtx acc_tmp = gen_rtx (REG, DImode, GPR_ATMP_FIRST);
+       emit_insn (gen_movdi (acc_tmp, gen_rtx (REG, DImode, i)));
+       emit_insn (gen_movdi (mem_di, acc_tmp));
+      }
+
+  /* Save the GPR registers that are adjacent to each other with st2w.  */
+  for (i = GPR_FIRST; i <= GPR_LAST; i += 2)
+    if (info->save_p[i] == 2)
+      emit_insn (gen_movdi (mem_di, gen_rtx (REG, DImode, i)));
+
+  /* Save the GPR registers that need to be saved with a single word store.  */
+  for (i = GPR_FIRST; i <= GPR_LAST; i++)
+    if (info->save_p[i] == 1)
+      emit_insn (gen_movsi (mem_si, gen_rtx (REG, SImode, i)));
+
+  /* Save the argument registers if this function accepts variable args.  */
+  if (info->varargs_p)
+    {
+      /* Realign r22 if an odd # of GPRs were saved.  */
+      if ((info->memrefs_1word & 1) != 0)
+       {
+         rtx save_tmp = XEXP (XEXP (mem_si, 0), 0);
+         emit_insn (gen_addsi3 (save_tmp, save_tmp, GEN_INT (UNITS_PER_WORD)));
+       }
+
+      for (i = GPR_ARG_FIRST; i <= GPR_ARG_LAST; i += 2)
+       emit_insn (gen_movdi (mem_di, gen_rtx (REG, DImode, i)));
+    }
+
+  /* Update the frame pointer.  */
+  if (frame_pointer_needed)
+    emit_move_insn (frame_pointer_rtx, sp);
+
+  /* Hack for now, to prevent scheduler from being too cleaver */
+  emit_insn (gen_blockage ());
+}
+
+\f
+/* A C compound statement that outputs the assembler code for exit from a
+   function.  The epilogue is responsible for restoring the saved registers and
+   stack pointer to their values when the function was called, and returning
+   control to the caller.  This macro takes the same arguments as the macro
+   `FUNCTION_PROLOGUE', and the registers to restore are determined from
+   `regs_ever_live' and `CALL_USED_REGISTERS' in the same way.
+
+   On some machines, there is a single instruction that does all the work of
+   returning from the function.  On these machines, give that instruction the
+   name `return' and do not define the macro `FUNCTION_EPILOGUE' at all.
+
+   Do not define a pattern named `return' if you want the `FUNCTION_EPILOGUE'
+   to be used.  If you want the target switches to control whether return
+   instructions or epilogues are used, define a `return' pattern with a
+   validity condition that tests the target switches appropriately.  If the
+   `return' pattern's validity condition is false, epilogues will be used.
+
+   On machines where functions may or may not have frame-pointers, the function
+   exit code must vary accordingly.  Sometimes the code for these two cases is
+   completely different.  To determine whether a frame pointer is wanted, the
+   macro can refer to the variable `frame_pointer_needed'.  The variable's
+   value will be 1 when compiling a function that needs a frame pointer.
+
+   Normally, `FUNCTION_PROLOGUE' and `FUNCTION_EPILOGUE' must treat leaf
+   functions specially.  The C variable `leaf_function' is nonzero for such a
+   function.  *Note Leaf Functions::.
+
+   On some machines, some functions pop their arguments on exit while others
+   leave that for the caller to do.  For example, the 68020 when given `-mrtd'
+   pops arguments in functions that take a fixed number of arguments.
+
+   Your definition of the macro `RETURN_POPS_ARGS' decides which functions pop
+   their own arguments.  `FUNCTION_EPILOGUE' needs to know what was decided.
+   The variable that is called `current_function_pops_args' is the number of
+   bytes of its arguments that a function should pop.  *Note Scalar Return::.  */
+
+/* For the d30v, move all processing to be as insns, but do any cleanup
+   here, since it is done after handling all of the insns.  */
+void
+d30v_function_epilogue (stream, size)
+     FILE *stream ATTRIBUTE_UNUSED;
+     int size ATTRIBUTE_UNUSED;
+{
+  d30v_stack_cache = (d30v_stack_t *)0;        /* reset stack cache */
+}
+
+\f
+
+/* Called after register allocation to add any instructions needed for the
+   epilogue.  Using a epilogue insn is favored compared to putting all of the
+   instructions in the FUNCTION_PROLOGUE macro, since it allows the scheduler
+   to intermix instructions with the saves of the caller saved registers.  In
+   some cases, it might be necessary to emit a barrier instruction as the last
+   insn to prevent such scheduling.  */
+
+void
+d30v_expand_epilogue ()
+{
+  rtx sp = stack_pointer_rtx;
+  d30v_stack_t *info = d30v_stack_info ();
+  int i;
+  rtx mem_di = NULL_RTX;
+  rtx mem_si = NULL_RTX;
+  rtx post_inc;
+  int extra_stack;
+
+  /* Hack for now, to prevent scheduler from being too cleaver */
+  emit_insn (gen_blockage ());
+
+  /* Restore sp from fp.  */
+  if (frame_pointer_needed)
+    emit_move_insn (sp, frame_pointer_rtx);
+
+  /* For the epilogue, use post-increment addressing all of the time.  First
+     adjust the sp, to eliminate all of the stack, except for the save area.  */
+
+  if (info->save_offset)
+    emit_insn (gen_addsi3 (sp, sp, GEN_INT (info->save_offset)));
+
+  post_inc = gen_rtx (POST_INC, Pmode, sp);
+  mem_di = gen_rtx (MEM, DImode, post_inc);
+  mem_si = gen_rtx (MEM, SImode, post_inc);
+
+  /* Restore the accumulators.  */
+  for (i = ACCUM_FIRST; i <= ACCUM_LAST; i++)
+    if (info->save_p[i])
+      {
+       rtx acc_tmp = gen_rtx (REG, DImode, GPR_ATMP_FIRST);
+       emit_insn (gen_movdi (acc_tmp, mem_di));
+       emit_insn (gen_movdi (gen_rtx (REG, DImode, i), acc_tmp));
+      }
+
+  /* Restore the GPR registers that are adjacent to each other with ld2w.  */
+  for (i = GPR_FIRST; i <= GPR_LAST; i += 2)
+    if (info->save_p[i] == 2)
+      emit_insn (gen_movdi (gen_rtx (REG, DImode, i), mem_di));
+
+  /* Save the GPR registers that need to be saved with a single word store.  */
+  extra_stack = 0;
+  for (i = GPR_FIRST; i <= GPR_LAST; i++)
+    if (info->save_p[i] == 1)
+      {
+       if (d30v_eh_epilogue_sp_ofs && i == GPR_LINK)
+         extra_stack = 4;
+       else
+         {
+           if (extra_stack)
+             {
+               emit_insn (gen_addsi3 (sp, sp, GEN_INT (extra_stack)));
+               extra_stack = 0;
+             }
+           emit_insn (gen_movsi (gen_rtx (REG, SImode, i), mem_si));
+         }
+      }
+
+  /* Release any remaining stack that was allocated for saving the
+     varargs registers or because an odd # of registers were stored.  */
+  if ((info->memrefs_1word & 1) != 0)
+    extra_stack += UNITS_PER_WORD;
+  extra_stack += current_function_pretend_args_size + info->varargs_size;
+
+  if (extra_stack)
+    {
+      if (d30v_eh_epilogue_sp_ofs)
+       emit_insn (gen_addsi3 (d30v_eh_epilogue_sp_ofs,
+                              d30v_eh_epilogue_sp_ofs,
+                              GEN_INT (extra_stack)));
+      else
+        emit_insn (gen_addsi3 (sp, sp, GEN_INT (extra_stack)));
+    }
+  if (d30v_eh_epilogue_sp_ofs)
+    emit_insn (gen_addsi3 (sp, sp, d30v_eh_epilogue_sp_ofs));
+
+  /* Now emit the return instruction.  */
+  emit_jump_insn (gen_rtx_RETURN (VOIDmode));
+}
+
+\f
+/* A C statement or compound statement to output to FILE some assembler code to
+   call the profiling subroutine `mcount'.  Before calling, the assembler code
+   must load the address of a counter variable into a register where `mcount'
+   expects to find the address.  The name of this variable is `LP' followed by
+   the number LABELNO, so you would generate the name using `LP%d' in a
+   `fprintf'.
+
+   The details of how the address should be passed to `mcount' are determined
+   by your operating system environment, not by GNU CC.  To figure them out,
+   compile a small program for profiling using the system's installed C
+   compiler and look at the assembler code that results.  */
+
+void
+d30v_function_profiler (stream, labelno)
+     FILE *stream;
+     int labelno ATTRIBUTE_UNUSED;
+{
+  fprintf (stream, "# profile\n");
+}
+
+\f
+/* Split a 64 bit item into an upper and a lower part.  We specifically do not
+   want to call gen_highpart/gen_lowpart on CONST_DOUBLEs since it will give us
+   the wrong part for floating point in cross compilers, and split_double does
+   not handle registers.  Also abort if the register is not a general purpose
+   register.  */
+
+void
+d30v_split_double (value, p_high, p_low)
+     rtx value;
+     rtx *p_high;
+     rtx *p_low;
+{
+  int offset = 0;
+  int regno;
+
+  if (!reload_completed)
+    abort ();
+
+  switch (GET_CODE (value))
+    {
+    case SUBREG:
+      offset = SUBREG_WORD (value);
+      value = SUBREG_REG (value);
+      if (GET_CODE (value) != REG)
+       abort ();
+
+      /* fall through */
+
+    case REG:
+      regno = REGNO (value) + offset;
+      if (!GPR_P (regno))
+       abort ();
+
+      *p_high = gen_rtx (REG, SImode, regno);
+      *p_low =  gen_rtx (REG, SImode, regno+1);
+      break;
+
+    case CONST_INT:
+    case CONST_DOUBLE:
+      split_double (value, p_high, p_low);
+      break;
+
+    default:
+      abort ();
+    }
+}
+
+\f
+/* A C compound statement to output to stdio stream STREAM the assembler syntax
+   for an instruction operand that is a memory reference whose address is X.  X
+   is an RTL expression.
+
+   On some machines, the syntax for a symbolic address depends on the section
+   that the address refers to.  On these machines, define the macro
+   `ENCODE_SECTION_INFO' to store the information into the `symbol_ref', and
+   then check for it here.  *Note Assembler Format::.  */
+
+void
+d30v_print_operand_address (stream, x)
+     FILE *stream;
+     rtx x;
+{
+  if (GET_CODE (x) == MEM)
+    x = XEXP (x, 0);
+
+  switch (GET_CODE (x))
+    {
+    default:
+      break;
+
+    case REG:
+      fputs (reg_names[ REGNO (x) ], stream);
+      return;
+
+    case CONST_INT:
+      fprintf (stream, "%ld", (long) INTVAL (x));
+      return;
+
+    /* We wrap simple symbol refs inside a parenthesis, so that a name
+       like `r2' is not taken for a register name.  */
+    case SYMBOL_REF:
+      fputs ("(", stream);
+      assemble_name (stream, XSTR (x, 0));
+      fputs (")", stream);
+      return;
+
+    case LABEL_REF:
+    case CONST:
+      output_addr_const (stream, x);
+      return;
+    }
+
+  fatal_insn ("Bad insn to d30v_print_operand_address:", x);
+}
+
+\f
+/* Print a memory reference suitable for the ld/st instructions.  */
+
+static void
+d30v_print_operand_memory_reference (stream, x)
+     FILE *stream;
+     rtx x;
+{
+  rtx x0 = NULL_RTX;
+  rtx x1 = NULL_RTX;
+
+  switch (GET_CODE (x))
+    {
+    default:
+      fatal_insn ("Bad insn to d30v_print_operand_memory_reference:", x);
+      break;
+
+    case SUBREG:
+    case REG:
+    case POST_DEC:
+    case POST_INC:
+      x0 = x;
+      break;
+
+    case CONST_INT:
+    case SYMBOL_REF:
+    case LABEL_REF:
+    case CONST:
+      x1 = x;
+      break;
+
+    case PLUS:
+      x0 = XEXP (x, 0);
+      x1 = XEXP (x, 1);
+      if (GET_CODE (x0) == CONST_INT || GET_CODE (x0) == SYMBOL_REF
+         || GET_CODE (x0) == CONST || GET_CODE (x0) == LABEL_REF)
+       {
+         x0 = XEXP (x, 1);
+         x1 = XEXP (x, 0);
+       }
+      break;
+    }
+
+  fputs ("@(", stream);
+  if (!x0)
+    fputs (reg_names[GPR_R0], stream);
+
+  else
+    {
+      char *suffix = "";
+      int offset0  = 0;
+
+      if (GET_CODE (x0) == SUBREG)
+       {
+         offset0 = SUBREG_WORD (x0);
+         x0 = SUBREG_REG (x0);
+       }
+
+      if (GET_CODE (x0) == POST_INC)
+       {
+         x0 = XEXP (x0, 0);
+         suffix = "+";
+       }
+      else if (GET_CODE (x0) == POST_DEC)
+       {
+         x0 = XEXP (x0, 0);
+         suffix = "-";
+       }
+
+      if (GET_CODE (x0) == REG && GPR_P (REGNO (x0)))
+       fprintf (stream, "%s%s", reg_names[REGNO (x0) + offset0], suffix);
+      else
+       fatal_insn ("Bad insn to d30v_print_operand_memory_reference:", x);
+    }
+
+  fputs (",", stream);
+
+  if (!x1)
+    fputs (reg_names[GPR_R0], stream);
+
+  else
+    {
+      int offset1 = 0;
+
+      switch (GET_CODE (x1))
+       {
+       case SUBREG:
+         offset1 = SUBREG_WORD (x1);
+         x1 = SUBREG_REG (x1);
+         if (GET_CODE (x1) != REG)
+           fatal_insn ("Bad insn to d30v_print_operand_memory_reference:", x);
+
+         /* fall through */
+       case REG:
+         fputs (reg_names[REGNO (x1) + offset1], stream);
+         break;
+
+       case CONST_INT:
+         fprintf (stream, "%ld", (long) INTVAL (x1));
+         break;
+
+       case SYMBOL_REF:
+       case LABEL_REF:
+       case CONST:
+         d30v_print_operand_address (stream, x1);
+         break;
+
+       default:
+         fatal_insn ("Bad insn to d30v_print_operand_memory_reference:", x);
+       }
+    }
+
+  fputs (")", stream);
+}
+
+\f
+/* A C compound statement to output to stdio stream STREAM the assembler syntax
+   for an instruction operand X.  X is an RTL expression.
+
+   LETTER is a value that can be used to specify one of several ways of
+   printing the operand.  It is used when identical operands must be printed
+   differently depending on the context.  LETTER comes from the `%'
+   specification that was used to request printing of the operand.  If the
+   specification was just `%DIGIT' then LETTER is 0; if the specification was
+   `%LTR DIGIT' then LETTER is the ASCII code for LTR.
+
+   If X is a register, this macro should print the register's name.  The names
+   can be found in an array `reg_names' whose type is `char *[]'.  `reg_names'
+   is initialized from `REGISTER_NAMES'.
+
+   When the machine description has a specification `%PUNCT' (a `%' followed by
+   a punctuation character), this macro is called with a null pointer for X and
+   the punctuation character for LETTER.
+
+   Standard operand flags that are handled elsewhere:
+       `='  Output a number unique to each instruction in the compilation.
+       `a'  Substitute an operand as if it were a memory reference.
+       `c'  Omit the syntax that indicates an immediate operand.
+       `l'  Substitute a LABEL_REF into a jump instruction.
+       `n'  Like %cDIGIT, except negate the value before printing.
+
+   The d30v specific operand flags are:
+       `.'  Print r0.
+       `f'  Print a SF constant as an int.
+       `s'  Subtract 32 and negate.
+       `A'  Print accumulator number without an `a' in front of it.
+       `B'  Print bit offset for BSET, etc. instructions.
+       `E'  Print u if this is zero extend, nothing if this is sign extend.
+       `F'  Emit /{f,t,x}{f,t,x} for executing a false condition.
+       `L'  Print the lower half of a 64 bit item.
+       `M'  Print a memory reference for ld/st instructions.
+       `R'  Return appropriate cmp instruction for relational test.
+       `S'  Subtract 32.
+       `T'  Emit /{f,t,x}{f,t,x} for executing a true condition.
+       `U'  Print the upper half of a 64 bit item.  */
+
+void
+d30v_print_operand (stream, x, letter)
+     FILE *stream;
+     rtx x;
+     int letter;
+{
+  enum rtx_code code = (x) ? GET_CODE (x) : NIL;
+  rtx split_values[2];
+  REAL_VALUE_TYPE rv;
+  long num;
+  int log;
+
+  switch (letter)
+    {
+    case '.':  /* Output r0 */
+      fputs (reg_names[GPR_R0], stream);
+      break;
+
+    case 'f':  /* Print a SF floating constant as an int */
+      if (GET_CODE (x) != CONST_DOUBLE)
+       fatal_insn ("Bad insn to d30v_print_operand, 'f' modifier:", x);
+
+      REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
+      REAL_VALUE_TO_TARGET_SINGLE (rv, num);
+      fprintf (stream, "%ld", num);
+      break;
+
+    case 'A':  /* Print accumulator number without an `a' in front of it.  */
+      if (GET_CODE (x) != REG || !ACCUM_P (REGNO (x)))
+       fatal_insn ("Bad insn to d30v_print_operand, 'A' modifier:", x);
+
+      putc ('0' + REGNO (x) - ACCUM_FIRST, stream);
+      break;
+
+    case 'M':  /* Print a memory reference for ld/st */
+      if (GET_CODE (x) != MEM)
+       fatal_insn ("Bad insn to d30v_print_operand, 'M' modifier:", x);
+
+      d30v_print_operand_memory_reference (stream, XEXP (x, 0));
+      break;
+
+    case 'L':  /* print lower part of 64 bit item. */
+    case 'U':  /* print upper part of 64 bit item. */
+      d30v_split_double (x, &split_values[0], &split_values[1]);
+      d30v_print_operand (stream, split_values[ letter == 'L' ], '\0');
+      break;
+
+    case 'F':  /* Print an appropriate suffix for a false comparision.  */
+    case 'T':  /* Print an appropriate suffix for a true  comparision.  */
+      /* Note that the sense of appropriate suffix is for conditional execution
+        and opposite of what branches want.  Branches just use the inverse
+        operation.  */
+      if ((GET_CODE (x) == NE || GET_CODE (x) == EQ)
+         && GET_MODE (x) == CCmode
+         && GET_CODE (XEXP (x, 0)) == REG
+         && (GPR_P (REGNO (XEXP (x, 0))) || BR_FLAG_P (REGNO (XEXP (x, 0))))
+         && GET_CODE (XEXP (x, 1)) == CONST_INT && INTVAL (XEXP (x, 1)) == 0)
+       {
+         int true_false = (letter == 'T');
+
+         if (GET_CODE (x) == EQ)
+           true_false = !true_false;
+
+         if (REGNO (XEXP (x, 0)) == FLAG_F0)
+           fprintf (stream, "/%cx", (true_false) ? 'f' : 't');
+
+         else if (REGNO (XEXP (x, 0)) == FLAG_F1)
+           fprintf (stream, "/x%c", (true_false) ? 'f' : 't');
+
+         else
+           fputs ((true_false) ? "tnz" : "tzr", stream);
+       }
+
+      else if (GET_CODE (x) == REG && REGNO (x) == FLAG_F0)
+       fprintf (stream, "/%cx", (letter == 'T') ? 't' : 'f');
+
+      else if (GET_CODE (x) == REG && REGNO (x) == FLAG_F1)
+       fprintf (stream, "/x%c", (letter == 'T') ? 't' : 'f');
+
+      else if (GET_CODE (x) == REG && GPR_P (REGNO (x)))
+       fputs ((letter == 'T') ? "tnz" : "tzr", stream);
+
+      else
+       fatal_insn ("Bad insn to print_operand, 'F' or 'T' modifier:", x);
+      break;
+
+    case 'B':  /* emit offset single bit to change */
+      if (GET_CODE (x) == CONST_INT && (log = exact_log2 (INTVAL (x))) >= 0)
+       fprintf (stream, "%d", 31 - log);
+
+      else if (GET_CODE (x) == CONST_INT && (log = exact_log2 (~ INTVAL (x))) >= 0)
+       fprintf (stream, "%d", 31 - log);
+
+      else
+       fatal_insn ("Bad insn to print_operand, 'B' modifier:", x);
+      break;
+
+    case 'E':  /* Print u if this is zero extend, nothing if sign extend. */
+      if (GET_CODE (x) == ZERO_EXTEND)
+       putc ('u', stream);
+      else if (GET_CODE (x) != SIGN_EXTEND)
+       fatal_insn ("Bad insn to print_operand, 'E' modifier:", x);
+      break;
+
+    case 'R':  /* Return appropriate cmp instruction for relational test.  */
+      switch (GET_CODE (x))
+       {
+       case EQ:  fputs ("cmpeq",  stream); break;
+       case NE:  fputs ("cmpne",  stream); break;
+       case LT:  fputs ("cmplt",  stream); break;
+       case LE:  fputs ("cmple",  stream); break;
+       case GT:  fputs ("cmpgt",  stream); break;
+       case GE:  fputs ("cmpge",  stream); break;
+       case LTU: fputs ("cmpult", stream); break;
+       case LEU: fputs ("cmpule", stream); break;
+       case GTU: fputs ("cmpugt", stream); break;
+       case GEU: fputs ("cmpuge", stream); break;
+
+       default:
+         fatal_insn ("Bad insn to print_operand, 'R' modifier:", x);
+       }
+      break;
+
+    case 's':  /* Subtract 32 and negate (for 64 bit shifts).  */
+      if (GET_CODE (x) == CONST_INT)
+       fprintf (stream, "%d", (int) (32 - INTVAL (x)));
+
+      else
+       fatal_insn ("Bad insn to print_operand, 's' modifier:", x);
+      break;
+
+    case 'S':  /* Subtract 32.  */
+      if (GET_CODE (x) == CONST_INT)
+       fprintf (stream, "%d", (int)(INTVAL (x) - 32));
+
+      else
+       fatal_insn ("Bad insn to print_operand, 's' modifier:", x);
+      break;
+
+
+    case 'z':  /* If arg is 0 or 0.0, print r0, otherwise print as normal */
+      if ((GET_CODE (x) == CONST_INT && INTVAL (x) == 0)
+         || (GET_CODE (x) == CONST_DOUBLE && CONST_DOUBLE_LOW (x) == 0
+             && CONST_DOUBLE_HIGH (x) == 0))
+       {
+         fputs (reg_names[GPR_FIRST], stream);
+         return;
+       }
+
+      /* fall through */
+
+    case '\0':
+      if (code == REG)
+       fputs (reg_names[ REGNO (x) ], stream);
+
+      else if (code == CONST_INT)
+       fprintf (stream, "%d", (int)INTVAL (x));
+
+      else if (code == MEM)
+       d30v_print_operand_address (stream, XEXP (x, 0));
+
+      else if (CONSTANT_ADDRESS_P (x))
+       d30v_print_operand_address (stream, x);
+
+      else
+       fatal_insn ("Bad insn in d30v_print_operand, 0 case", x);
+
+      return;
+
+    default:
+      {
+       char buf[80];
+
+       sprintf (buf, "Invalid asm template character '%%%c'", letter);
+       fatal_insn (buf, x);
+      }
+    }
+}
+
+\f
+/* A C expression for the size in bytes of the trampoline, as an integer.  */
+
+int
+d30v_trampoline_size ()
+{
+  return 16;
+}
+
+\f
+/* Create a long instruction for building up a trampoline.  */
+
+static void
+d30v_build_long_insn (high_bits, low_bits, imm, mem)
+     HOST_WIDE_INT high_bits;
+     HOST_WIDE_INT low_bits;
+     rtx imm;
+     rtx mem;
+{
+  rtx reg = gen_reg_rtx (DImode);
+  rtx high_word = gen_highpart (SImode, reg);
+  rtx low_word = gen_lowpart (SImode, reg);
+  rtx tmp1 = gen_reg_rtx (SImode);
+  rtx tmp2 = gen_reg_rtx (SImode);
+  rtx tmp3 = gen_reg_rtx (SImode);
+  rtx tmp4 = gen_reg_rtx (SImode);
+  rtx tmp5 = gen_reg_rtx (SImode);
+  rtx tmp6 = gen_reg_rtx (SImode);
+
+  imm = force_reg (SImode, imm);
+
+  /* Stuff top 6 bits of immediate value into high word */
+  emit_insn (gen_lshrsi3 (tmp1, imm, GEN_INT (26)));
+  emit_insn (gen_andsi3 (tmp2, tmp1, GEN_INT (0x3F)));
+  emit_insn (gen_iorsi3 (high_word, tmp2, GEN_INT (high_bits)));
+
+  /* Now get the next 8 bits for building the low word */
+  emit_insn (gen_andsi3 (tmp3, imm, GEN_INT (0x03FC0000)));
+  emit_insn (gen_ashlsi3 (tmp4, tmp3, GEN_INT (2)));
+
+  /* And the bottom 18 bits */
+  emit_insn (gen_andsi3 (tmp5, imm, GEN_INT (0x0003FFFF)));
+  emit_insn (gen_iorsi3 (tmp6, tmp4, tmp5));
+  emit_insn (gen_iorsi3 (low_word, tmp6, GEN_INT (low_bits)));
+
+  /* Store the instruction */
+  emit_insn (gen_movdi (mem, reg));
+}
+
+\f
+/* A C statement to initialize the variable parts of a trampoline.  ADDR is an
+   RTX for the address of the trampoline; FNADDR is an RTX for the address of
+   the nested function; STATIC_CHAIN is an RTX for the static chain value that
+   should be passed to the function when it is called.  */
+
+void
+d30v_initialize_trampoline (addr, fnaddr, static_chain)
+     rtx addr;
+     rtx fnaddr;
+     rtx static_chain;
+{
+  /* The instruction space can only be accessed by ld2w/st2w.
+     Generate on the fly:
+       or r18,r0,<static-chain>
+       jmp <fnaddr> */
+  d30v_build_long_insn (0x83A80000 | ((STATIC_CHAIN_REGNUM - GPR_FIRST) << 12),
+                       0x80000000, static_chain,
+                       gen_rtx (MEM, DImode, addr));
+
+  d30v_build_long_insn (0x80180000, 0x80000000, fnaddr,
+                       gen_rtx (MEM, DImode, plus_constant (addr, 8)));
+}
+
+\f
+/* A C compound statement with a conditional `goto LABEL;' executed if X (an
+   RTX) is a legitimate memory address on the target machine for a memory
+   operand of mode MODE.
+
+   It usually pays to define several simpler macros to serve as subroutines for
+   this one.  Otherwise it may be too complicated to understand.
+
+   This macro must exist in two variants: a strict variant and a non-strict
+   one.  The strict variant is used in the reload pass.  It must be defined so
+   that any pseudo-register that has not been allocated a hard register is
+   considered a memory reference.  In contexts where some kind of register is
+   required, a pseudo-register with no hard register must be rejected.
+
+   The non-strict variant is used in other passes.  It must be defined to
+   accept all pseudo-registers in every context where some kind of register is
+   required.
+
+   Compiler source files that want to use the strict variant of this macro
+   define the macro `REG_OK_STRICT'.  You should use an `#ifdef REG_OK_STRICT'
+   conditional to define the strict variant in that case and the non-strict
+   variant otherwise.
+
+   Subroutines to check for acceptable registers for various purposes (one for
+   base registers, one for index registers, and so on) are typically among the
+   subroutines used to define `GO_IF_LEGITIMATE_ADDRESS'.  Then only these
+   subroutine macros need have two variants; the higher levels of macros may be
+   the same whether strict or not.
+
+   Normally, constant addresses which are the sum of a `symbol_ref' and an
+   integer are stored inside a `const' RTX to mark them as constant.
+   Therefore, there is no need to recognize such sums specifically as
+   legitimate addresses.  Normally you would simply recognize any `const' as
+   legitimate.
+
+   Usually `PRINT_OPERAND_ADDRESS' is not prepared to handle constant sums that
+   are not marked with `const'.  It assumes that a naked `plus' indicates
+   indexing.  If so, then you *must* reject such naked constant sums as
+   illegitimate addresses, so that none of them will be given to
+   `PRINT_OPERAND_ADDRESS'.
+
+   On some machines, whether a symbolic address is legitimate depends on the
+   section that the address refers to.  On these machines, define the macro
+   `ENCODE_SECTION_INFO' to store the information into the `symbol_ref', and
+   then check for it here.  When you see a `const', you will have to look
+   inside it to find the `symbol_ref' in order to determine the section.  *Note
+   Assembler Format::.
+
+   The best way to modify the name string is by adding text to the beginning,
+   with suitable punctuation to prevent any ambiguity.  Allocate the new name
+   in `saveable_obstack'.  You will have to modify `ASM_OUTPUT_LABELREF' to
+   remove and decode the added text and output the name accordingly, and define
+   `STRIP_NAME_ENCODING' to access the original name string.
+
+   You can check the information stored here into the `symbol_ref' in the
+   definitions of the macros `GO_IF_LEGITIMATE_ADDRESS' and
+   `PRINT_OPERAND_ADDRESS'.
+
+   Return 0 if the address is not legitimate, 1 if the address would fit
+   in a short instruction, or 2 if the address would fit in a long
+   instruction.  */
+
+#define XREGNO_OK_FOR_BASE_P(REGNO, STRICT_P)                          \
+((STRICT_P)                                                            \
+ ? REGNO_OK_FOR_BASE_P (REGNO)                                         \
+ : GPR_OR_PSEUDO_P (REGNO))
+
+int
+d30v_legitimate_address_p (mode, x, strict_p)
+     enum machine_mode mode;
+     rtx x;
+     int strict_p;
+{
+  rtx x0, x1;
+  int ret = 0;
+
+  switch (GET_CODE (x))
+    {
+    default:
+      break;
+
+    case SUBREG:
+      x = SUBREG_REG (x);
+      if (GET_CODE (x) != REG)
+       break;
+
+      /* fall through */
+
+    case REG:
+      ret = XREGNO_OK_FOR_BASE_P (REGNO (x), strict_p);
+      break;
+
+    case PLUS:
+      x0 = XEXP (x, 0);
+      x1 = XEXP (x, 1);
+
+      if (GET_CODE (x0) == SUBREG)
+       x0 = SUBREG_REG (x0);
+
+      if (GET_CODE (x0) == POST_INC || GET_CODE (x0) == POST_DEC)
+       x0 = XEXP (x0, 0);
+
+      if (GET_CODE (x0) != REG || !XREGNO_OK_FOR_BASE_P (REGNO (x0), strict_p))
+       break;
+
+      switch (GET_CODE (x1))
+       {
+       default:
+         break;
+
+       case SUBREG:
+         x1 = SUBREG_REG (x1);
+         if (GET_CODE (x1) != REG)
+           break;
+
+         /* fall through */
+
+       case REG:
+         ret = XREGNO_OK_FOR_BASE_P (REGNO (x1), strict_p);
+         break;
+
+       case CONST_INT:
+         ret = (IN_RANGE_P (INTVAL (x1), -32, 31)) ? 1 : 2;
+         break;
+
+       case SYMBOL_REF:
+       case LABEL_REF:
+       case CONST:
+         ret = 2;
+         break;
+       }
+      break;
+
+    case CONST_INT:
+      ret = (IN_RANGE_P (INTVAL (x), -32, 31)) ? 1 : 2;
+      break;
+
+    case SYMBOL_REF:
+    case LABEL_REF:
+    case CONST:
+      ret = 2;
+      break;
+
+    case POST_INC:
+    case POST_DEC:
+      x0 = XEXP (x, 0);
+      if (GET_CODE (x0) == REG && XREGNO_OK_FOR_BASE_P (REGNO (x0), strict_p))
+       ret = 1;
+      break;
+    }
+
+  if (TARGET_DEBUG_ADDR)
+    {
+      fprintf (stderr, "\n========== GO_IF_LEGITIMATE_ADDRESS, mode = %s, result = %d, addresses are %sstrict\n",
+              GET_MODE_NAME (mode), ret, (strict_p) ? "" : "not ");
+      debug_rtx (x);
+    }
+
+  return ret;
+}
+
+\f
+/* A C compound statement that attempts to replace X with a valid memory
+   address for an operand of mode MODE.  WIN will be a C statement label
+   elsewhere in the code; the macro definition may use
+
+        GO_IF_LEGITIMATE_ADDRESS (MODE, X, WIN);
+
+   to avoid further processing if the address has become legitimate.
+
+   X will always be the result of a call to `break_out_memory_refs', and OLDX
+   will be the operand that was given to that function to produce X.
+
+   The code generated by this macro should not alter the substructure of X.  If
+   it transforms X into a more legitimate form, it should assign X (which will
+   always be a C variable) a new value.
+
+   It is not necessary for this macro to come up with a legitimate address.
+   The compiler has standard ways of doing so in all cases.  In fact, it is
+   safe for this macro to do nothing.  But often a machine-dependent strategy
+   can generate better code.  */
+
+rtx
+d30v_legitimize_address (x, oldx, mode, strict_p)
+     rtx x;
+     rtx oldx ATTRIBUTE_UNUSED;
+     enum machine_mode mode ATTRIBUTE_UNUSED;
+     int strict_p ATTRIBUTE_UNUSED;
+{
+  rtx ret = NULL_RTX;
+
+  if (TARGET_DEBUG_ADDR)
+    {
+      if (ret)
+       {
+         fprintf (stderr, "\n========== LEGITIMIZE_ADDRESS, transformed:\n");
+         debug_rtx (x);
+         fprintf (stderr, "\ninto:\n");
+         debug_rtx (ret);
+       }
+      else
+       {
+         fprintf (stderr, "\n========== LEGITIMIZE_ADDRESS, did nothing with:\n");
+         debug_rtx (x);
+       }
+    }
+
+  return ret;
+}
+
+\f
+/* A C statement or compound statement with a conditional `goto LABEL;'
+   executed if memory address X (an RTX) can have different meanings depending
+   on the machine mode of the memory reference it is used for or if the address
+   is valid for some modes but not others.
+
+   Autoincrement and autodecrement addresses typically have mode-dependent
+   effects because the amount of the increment or decrement is the size of the
+   operand being addressed.  Some machines have other mode-dependent addresses.
+   Many RISC machines have no mode-dependent addresses.
+
+   You may assume that ADDR is a valid address for the machine.  */
+
+int
+d30v_mode_dependent_address_p (addr)
+     rtx addr;
+{
+  switch (GET_CODE (addr))
+    {
+    default:
+      break;
+
+    case POST_INC:
+    case POST_DEC:
+      return TRUE;
+    }
+
+  return FALSE;
+}
+
+\f
+/* Generate the appropriate comparison code for a test.  */
+
+rtx
+d30v_emit_comparison (test_int, result, arg1, arg2)
+     int test_int;
+     rtx result;
+     rtx arg1;
+     rtx arg2;
+{
+  enum rtx_code test = (enum rtx_code) test_int;
+  enum machine_mode mode = GET_MODE (arg1);
+  rtx rtx_test = gen_rtx (SET, VOIDmode, result, gen_rtx (test, CCmode, arg1, arg2));
+
+  if (mode == SImode
+      || (mode == DImode && (test == EQ || test == NE))
+      || (mode == DImode && (test == LT || test == GE)
+         && GET_CODE (arg2) == CONST_INT && INTVAL (arg2) == 0))
+    return rtx_test;
+
+  else if (mode == DImode)
+    return gen_rtx (PARALLEL, VOIDmode,
+                   gen_rtvec (2,
+                              rtx_test,
+                              gen_rtx (CLOBBER, VOIDmode,
+                                       gen_reg_rtx (CCmode))));
+
+  else
+    fatal_insn ("d30v_emit_comparison", rtx_test);
+}
+
+\f
+/* Return appropriate code to move 2 words.  Since DImode registers must start
+   on even register numbers, there is no possibility of overlap.  */
+
+char *
+d30v_move_2words (operands, insn)
+     rtx operands[];
+     rtx insn;
+{
+  if (GET_CODE (operands[0]) == REG && GPR_P (REGNO (operands[0])))
+    {
+      if (GET_CODE (operands[1]) == REG && GPR_P (REGNO (operands[1])))
+       return "or %U0,%.,%U1\n\tor %L0,%.,%L1";
+
+      else if (GET_CODE (operands[1]) == REG && ACCUM_P (REGNO (operands[1])))
+       return "mvfacc %L0,%1,%.\n\tmvfacc %U0,%1,32";
+
+      else if (GET_CODE (operands[1]) == MEM)
+       return "ld2w %0,%M1";
+
+      else if (GET_CODE (operands[1]) == CONST_INT
+              || GET_CODE (operands[1]) == CONST_DOUBLE)
+       return "or %U0,%.,%U1\n\tor %L0,%.,%L1";
+    }
+
+  else if (GET_CODE (operands[0]) == REG && ACCUM_P (REGNO (operands[0])))
+    {
+      if (GET_CODE (operands[1]) == REG
+         && GPR_P (REGNO (operands[1])))
+       return "mvtacc %0,%U1,%L1";
+
+      if (GET_CODE (operands[1]) == CONST_INT
+         && INTVAL (operands[1]) == 0)
+       return "mvtacc %0,%.,%.";
+    }
+
+  else if (GET_CODE (operands[0]) == MEM
+          && GET_CODE (operands[1]) == REG
+          && GPR_P (REGNO (operands[1])))
+    return "st2w %1,%M0";
+
+  fatal_insn ("Bad call to d30v_move_2words", insn);
+}
+
+\f
+/* Emit the code to do a conditional move instruction.  Return FALSE
+   if the conditional move could not be executed.  */
+
+int
+d30v_emit_cond_move (dest, test, true_value, false_value)
+     rtx dest;
+     rtx test;
+     rtx true_value;
+     rtx false_value;
+{
+  rtx br_reg;
+  enum machine_mode mode = GET_MODE (dest);
+  int two_mem_moves_p = FALSE;
+
+  if (GET_CODE (dest) == MEM)
+    {
+      if (!reg_or_0_operand (true_value, mode))
+       return FALSE;
+
+      if (rtx_equal_p (dest, false_value))
+       two_mem_moves_p = TRUE;
+
+      else if (!reg_or_0_operand (false_value, mode))
+       return FALSE;
+    }
+
+  /* We used to try to optimize setting 0/1 by using mvfsys, but that turns out
+     to be slower than just doing the conditional execution.  */
+
+  br_reg = gen_reg_rtx (CCmode);
+  emit_insn (d30v_emit_comparison (GET_CODE (test), br_reg,
+                                  d30v_compare_op0, d30v_compare_op1));
+
+  if (!two_mem_moves_p)
+    emit_insn (gen_rtx_SET (VOIDmode,
+                           dest,
+                           gen_rtx_IF_THEN_ELSE (mode,
+                                                 gen_rtx_NE (CCmode, br_reg,
+                                                             const0_rtx),
+                                                 true_value,
+                                                 false_value)));
+  else
+    {
+      /* Emit conditional stores as two separate stores.  This avoids a problem
+         where you have a conditional store, and one of the arms of the
+         conditional store is spilled to memory.  */
+      emit_insn (gen_rtx_SET (VOIDmode,
+                             dest,
+                             gen_rtx_IF_THEN_ELSE (mode,
+                                                   gen_rtx_NE (CCmode, br_reg,
+                                                               const0_rtx),
+                                                   true_value,
+                                                   dest)));
+
+      emit_insn (gen_rtx_SET (VOIDmode,
+                             dest,
+                             gen_rtx_IF_THEN_ELSE (mode,
+                                                   gen_rtx_EQ (CCmode, br_reg,
+                                                               const0_rtx),
+                                                   false_value,
+                                                   dest)));
+        
+    }
+
+  return TRUE;
+}
+
+\f
+/* In rare cases, correct code generation requires extra machine dependent
+   processing between the second jump optimization pass and delayed branch
+   scheduling.  On those machines, define this macro as a C statement to act on
+   the code starting at INSN.  */
+
+void
+d30v_machine_dependent_reorg (insn)
+     rtx insn ATTRIBUTE_UNUSED;
+{
+}
+
+\f
+/* A C statement (sans semicolon) to update the integer variable COST based on
+   the relationship between INSN that is dependent on DEP_INSN through the
+   dependence LINK.  The default is to make no adjustment to COST.  This can be
+   used for example to specify to the scheduler that an output- or
+   anti-dependence does not incur the same cost as a data-dependence.  */
+
+/* For the d30v, try to insure that the source operands for a load/store are
+   set 2 cycles before the memory reference.  */
+
+int
+d30v_adjust_cost (insn, link, dep_insn, cost)
+     rtx insn;
+     rtx link ATTRIBUTE_UNUSED;
+     rtx dep_insn;
+     int cost;
+{
+  rtx set_dep = single_set (dep_insn);
+  rtx set_insn = single_set (insn);
+
+  if (set_dep != NULL_RTX && set_insn != NULL_RTX
+      && GET_CODE (SET_DEST (set_dep)) == REG)
+    {
+      rtx reg = SET_DEST (set_dep);
+      rtx mem;
+
+      if ((GET_CODE (mem = SET_SRC (set_insn)) == MEM
+          && reg_mentioned_p (reg, XEXP (mem, 0)))
+         || (GET_CODE (mem = SET_DEST (set_insn)) == MEM
+             && reg_mentioned_p (reg, XEXP (mem, 0))))
+       {
+         return cost + ((HAIFA_P) ? 2 : 4);
+       }
+    }
+
+  return cost;
+}
+
+\f
+/* Functions to save and restore d30v_return_addr_rtx.  */
+
+struct machine_function
+{
+  rtx ra_rtx;
+};
+
+static void
+d30v_save_machine_status (p)
+     struct function *p;
+{
+  struct machine_function *machine =
+    (struct machine_function *) xmalloc (sizeof (struct machine_function));
+
+  p->machine = machine;
+  machine->ra_rtx = d30v_return_addr_rtx;
+}
+
+static void
+d30v_restore_machine_status (p)
+     struct function *p;
+{
+  struct machine_function *machine = p->machine;
+
+  d30v_return_addr_rtx = machine->ra_rtx;
+
+  free (machine);
+  p->machine = (struct machine_function *)0;
+}
+
+/* Do anything needed before RTL is emitted for each function.  */
+
+void
+d30v_init_expanders ()
+{
+  d30v_return_addr_rtx = NULL_RTX;
+  d30v_eh_epilogue_sp_ofs = NULL_RTX;
+
+  /* Arrange to save and restore machine status around nested functions.  */
+  save_machine_status = d30v_save_machine_status;
+  restore_machine_status = d30v_restore_machine_status;
+}
+
+/* Find the current function's return address.
+
+   ??? It would be better to arrange things such that if we would ordinarily
+   have been a leaf function and we didn't spill the hard reg that we
+   wouldn't have to save the register in the prolog.  But it's not clear
+   how to get the right information at the right time.  */
+
+rtx
+d30v_return_addr ()
+{
+  rtx ret;
+
+  if ((ret = d30v_return_addr_rtx) == NULL)
+    {
+      rtx init;
+
+      d30v_return_addr_rtx = ret = gen_reg_rtx (Pmode);
+
+      init = gen_rtx (SET, VOIDmode, ret, gen_rtx (REG, Pmode, GPR_LINK));
+      push_topmost_sequence ();
+      emit_insn_after (init, get_insns ());
+      pop_topmost_sequence ();
+    }
+
+  return ret;
+}
+
+/* Called to register all of our global variables with the garbage
+   collector.  */
+
+static void
+d30v_add_gc_roots ()
+{
+  ggc_add_rtx_root (&d30v_compare_op0, 1);
+  ggc_add_rtx_root (&d30v_compare_op1, 1);
+  ggc_add_rtx_root (&d30v_eh_epilogue_sp_ofs, 1);
+  ggc_add_rtx_root (&d30v_return_addr_rtx, 1);
+}
diff --git a/gcc/config/d30v/d30v.h b/gcc/config/d30v/d30v.h
new file mode 100644 (file)
index 0000000..6b7b974
--- /dev/null
@@ -0,0 +1,6104 @@
+/* Definitions of target machine for Mitsubishi D30V.
+   Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
+   Contributed by Cygnus Solutions.
+
+   This file is part of GNU CC.
+
+   GNU CC 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)
+   any later version.
+
+   GNU CC 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.  */
+
+/* D30V specific macros */
+
+/* Align an address */
+#define D30V_ALIGN(addr,align) (((addr) + (align) - 1) & ~((align) - 1))
+
+\f
+/* Set up System V.4 (aka ELF) defaults.  */
+#include "svr4.h"
+
+\f
+/* Driver configuration */
+
+/* A C expression which determines whether the option `-CHAR' takes arguments.
+   The value should be the number of arguments that option takes-zero, for many
+   options.
+
+   By default, this macro is defined to handle the standard options properly.
+   You need not define it unless you wish to add additional options which take
+   arguments.
+
+   Defined in svr4.h.  */
+/* #define SWITCH_TAKES_ARG(CHAR) */
+
+/* A C expression which determines whether the option `-NAME' takes arguments.
+   The value should be the number of arguments that option takes-zero, for many
+   options.  This macro rather than `SWITCH_TAKES_ARG' is used for
+   multi-character option names.
+
+   By default, this macro is defined as `DEFAULT_WORD_SWITCH_TAKES_ARG', which
+   handles the standard options properly.  You need not define
+   `WORD_SWITCH_TAKES_ARG' unless you wish to add additional options which take
+   arguments.  Any redefinition should call `DEFAULT_WORD_SWITCH_TAKES_ARG' and
+   then check for additional options.
+
+   Defined in svr4.h.  */
+/* #define WORD_SWITCH_TAKES_ARG(NAME) */
+
+/* A string-valued C expression which is nonempty if the linker needs a space
+   between the `-L' or `-o' option and its argument.
+
+   If this macro is not defined, the default value is 0.  */
+/* #define SWITCHES_NEED_SPACES "" */
+
+/* A C string constant that tells the GNU CC driver program options to pass to
+   CPP.  It can also specify how to translate options you give to GNU CC into
+   options for GNU CC to pass to the CPP.
+
+   Do not define this macro if it does not need to do anything.  */
+/* #define CPP_SPEC "" */
+
+/* If this macro is defined, the preprocessor will not define the builtin macro
+   `__SIZE_TYPE__'.  The macro `__SIZE_TYPE__' must then be defined by
+   `CPP_SPEC' instead.
+
+   This should be defined if `SIZE_TYPE' depends on target dependent flags
+   which are not accessible to the preprocessor.  Otherwise, it should not be
+   defined.  */
+/* #define NO_BUILTIN_SIZE_TYPE */
+
+/* If this macro is defined, the preprocessor will not define the builtin macro
+   `__PTRDIFF_TYPE__'.  The macro `__PTRDIFF_TYPE__' must then be defined by
+   `CPP_SPEC' instead.
+
+   This should be defined if `PTRDIFF_TYPE' depends on target dependent flags
+   which are not accessible to the preprocessor.  Otherwise, it should not be
+   defined.  */
+/* #define NO_BUILTIN_PTRDIFF_TYPE */
+
+/* A C string constant that tells the GNU CC driver program options to pass to
+   CPP.  By default, this macro is defined to pass the option
+   `-D__CHAR_UNSIGNED__' to CPP if `char' will be treated as `unsigned char' by
+   `cc1'.
+
+   Do not define this macro unless you need to override the default definition.  */
+/* #if DEFAULT_SIGNED_CHAR
+   #define SIGNED_CHAR_SPEC "%{funsigned-char:-D__CHAR_UNSIGNED__}"
+   #else
+   #define SIGNED_CHAR_SPEC "%{!fsigned-char:-D__CHAR_UNSIGNED__}"
+   #endif */
+
+/* A C string constant that tells the GNU CC driver program options to pass to
+   `cc1'.  It can also specify how to translate options you give to GNU CC into
+   options for GNU CC to pass to the `cc1'.
+
+   Do not define this macro if it does not need to do anything.  */
+/* #define CC1_SPEC "" */
+
+/* A C string constant that tells the GNU CC driver program options to pass to
+   `cc1plus'.  It can also specify how to translate options you give to GNU CC
+   into options for GNU CC to pass to the `cc1plus'.
+
+   Do not define this macro if it does not need to do anything.  */
+/* #define CC1PLUS_SPEC "" */
+
+/* A C string constant that tells the GNU CC driver program options to pass to
+   the assembler.  It can also specify how to translate options you give to GNU
+   CC into options for GNU CC to pass to the assembler.  See the file `sun3.h'
+   for an example of this.
+
+   Do not define this macro if it does not need to do anything.
+
+   Defined in svr4.h.  */
+#undef ASM_SPEC
+#define ASM_SPEC "\
+%{!mno-asm-optimize: %{O*: %{!O0: -O} %{O0: %{masm-optimize: -O}}}} \
+%{v} %{n} %{T} %{Ym,*} %{Yd,*} %{Wa,*:%*}"
+
+/* A C string constant that tells the GNU CC driver program how to run any
+   programs which cleanup after the normal assembler.  Normally, this is not
+   needed.  See the file `mips.h' for an example of this.
+
+   Do not define this macro if it does not need to do anything.
+
+   Defined in svr4.h.  */
+/* #define ASM_FINAL_SPEC "" */
+
+/* A C string constant that tells the GNU CC driver program options to pass to
+   the linker.  It can also specify how to translate options you give to GNU CC
+   into options for GNU CC to pass to the linker.
+
+   Do not define this macro if it does not need to do anything.
+
+   Defined in svr4.h.  */
+#undef LINK_SPEC
+#define LINK_SPEC "\
+%{h*} %{v:-V} \
+%{b} %{Wl,*:%*} \
+%{static:-dn -Bstatic} \
+%{shared:-G -dy -z text} \
+%{symbolic:-Bsymbolic -G -dy -z text} \
+%{G:-G} \
+%{YP,*} \
+%{Qy:} %{!Qn:-Qy} \
+%{mextmem: -m d30v_e} %{mextmemory: -m d30v_e} %{monchip: -m d30v_o}"
+
+/* Another C string constant used much like `LINK_SPEC'.  The difference
+   between the two is that `LIB_SPEC' is used at the end of the command given
+   to the linker.
+
+   If this macro is not defined, a default is provided that loads the standard
+   C library from the usual place.  See `gcc.c'.
+
+   Defined in svr4.h.  */
+#undef LIB_SPEC
+#define LIB_SPEC "--start-group -lsim -lc --end-group"
+
+/* Another C string constant that tells the GNU CC driver program how and when
+   to place a reference to `libgcc.a' into the linker command line.  This
+   constant is placed both before and after the value of `LIB_SPEC'.
+
+   If this macro is not defined, the GNU CC driver provides a default that
+   passes the string `-lgcc' to the linker unless the `-shared' option is
+   specified.  */
+/* #define LIBGCC_SPEC "" */
+
+/* Another C string constant used much like `LINK_SPEC'.  The difference
+   between the two is that `STARTFILE_SPEC' is used at the very beginning of
+   the command given to the linker.
+
+   If this macro is not defined, a default is provided that loads the standard
+   C startup file from the usual place.  See `gcc.c'.
+
+   Defined in svr4.h.  */
+
+#undef STARTFILE_SPEC
+#define STARTFILE_SPEC "crt0%O%s crtbegin%O%s"
+
+/* Another C string constant used much like `LINK_SPEC'.  The difference
+   between the two is that `ENDFILE_SPEC' is used at the very end of the
+   command given to the linker.
+
+   Do not define this macro if it does not need to do anything.
+
+   Defined in svr4.h.  */
+
+#undef ENDFILE_SPEC
+#define ENDFILE_SPEC "crtend%O%s"
+
+/* Define this macro if the driver program should find the library `libgcc.a'
+   itself and should not pass `-L' options to the linker.  If you do not define
+   this macro, the driver program will pass the argument `-lgcc' to tell the
+   linker to do the search and will pass `-L' options to it.  */
+/* #define LINK_LIBGCC_SPECIAL */
+
+/* Define this macro if the driver program should find the library `libgcc.a'.
+   If you do not define this macro, the driver program will pass the argument
+   `-lgcc' to tell the linker to do the search.  This macro is similar to
+   `LINK_LIBGCC_SPECIAL', except that it does not affect `-L' options.  */
+/* #define LINK_LIBGCC_SPECIAL_1 */
+
+/* Define this macro to provide additional specifications to put in the `specs'
+   file that can be used in various specifications like `CC1_SPEC'.
+
+   The definition should be an initializer for an array of structures,
+   containing a string constant, that defines the specification name, and a
+   string constant that provides the specification.
+
+   Do not define this macro if it does not need to do anything.  */
+/* #define EXTRA_SPECS {{}} */
+
+/* Define this macro as a C expression for the initializer of an array of
+   string to tell the driver program which options are defaults for this target
+   and thus do not need to be handled specially when using `MULTILIB_OPTIONS'.
+
+   Do not define this macro if `MULTILIB_OPTIONS' is not defined in the target
+   makefile fragment or if none of the options listed in `MULTILIB_OPTIONS' are
+   set by default.  *Note Target Fragment::.  */
+/* #define MULTILIB_DEFAULTS {} */
+
+/* Define this macro to tell `gcc' that it should only translate a `-B' prefix
+   into a `-L' linker option if the prefix indicates an absolute file name. */
+/* #define RELATIVE_PREFIX_NOT_LINKDIR */
+
+/* Define this macro as a C string constant if you wish to override the
+   standard choice of `/usr/local/lib/gcc-lib/' as the default prefix to try
+   when searching for the executable files of the compiler. */
+/* #define STANDARD_EXEC_PREFIX "" */
+
+/* If defined, this macro is an additional prefix to try after
+   `STANDARD_EXEC_PREFIX'.  `MD_EXEC_PREFIX' is not searched when the `-b'
+   option is used, or the compiler is built as a cross compiler.
+
+   Defined in svr4.h for host compilers.  */
+/* #define MD_EXEC_PREFIX "" */
+
+/* Define this macro as a C string constant if you wish to override the
+   standard choice of `/usr/local/lib/' as the default prefix to try when
+   searching for startup files such as `crt0.o'. */
+/* #define STANDARD_STARTFILE_PREFIX "" */
+
+/* If defined, this macro supplies an additional prefix to try after the
+   standard prefixes.  `MD_EXEC_PREFIX' is not searched when the `-b' option is
+   used, or when the compiler is built as a cross compiler.
+
+   Defined in svr4.h for host compilers.  */
+/* #define MD_STARTFILE_PREFIX "" */
+
+/* If defined, this macro supplies yet another prefix to try after the standard
+   prefixes.  It is not searched when the `-b' option is used, or when the
+   compiler is built as a cross compiler. */
+/* #define MD_STARTFILE_PREFIX_1 "" */
+
+/* Define this macro as a C string constant if you with to set environment
+   variables for programs called by the driver, such as the assembler and
+   loader.  The driver passes the value of this macro to `putenv' to initialize
+   the necessary environment variables. */
+/* #define INIT_ENVIRONMENT "" */
+
+/* Define this macro as a C string constant if you wish to override the
+   standard choice of `/usr/local/include' as the default prefix to try when
+   searching for local header files.  `LOCAL_INCLUDE_DIR' comes before
+   `SYSTEM_INCLUDE_DIR' in the search order.
+
+   Cross compilers do not use this macro and do not search either
+   `/usr/local/include' or its replacement.  */
+/* #define LOCAL_INCLUDE_DIR "" */
+
+/* Define this macro as a C string constant if you wish to specify a
+   system-specific directory to search for header files before the standard
+   directory.  `SYSTEM_INCLUDE_DIR' comes before `STANDARD_INCLUDE_DIR' in the
+   search order.
+
+   Cross compilers do not use this macro and do not search the directory
+   specified. */
+/* #define SYSTEM_INCLUDE_DIR "" */
+
+/* Define this macro as a C string constant if you wish to override the
+   standard choice of `/usr/include' as the default prefix to try when
+   searching for header files.
+
+   Cross compilers do not use this macro and do not search either
+   `/usr/include' or its replacement. */
+/* #define STANDARD_INCLUDE_DIR "" */
+
+/* Define this macro if you wish to override the entire default search path for
+   include files.  The default search path includes `GCC_INCLUDE_DIR',
+   `LOCAL_INCLUDE_DIR', `SYSTEM_INCLUDE_DIR', `GPLUSPLUS_INCLUDE_DIR', and
+   `STANDARD_INCLUDE_DIR'.  In addition, `GPLUSPLUS_INCLUDE_DIR' and
+   `GCC_INCLUDE_DIR' are defined automatically by `Makefile', and specify
+   private search areas for GCC.  The directory `GPLUSPLUS_INCLUDE_DIR' is used
+   only for C++ programs.
+
+     The definition should be an initializer for an array of structures.  Each
+     array element should have two elements: the directory name (a string
+     constant) and a flag for C++-only directories.  Mark the end of the array
+     with a null element.  For example, here is the definition used for VMS:
+
+          #define INCLUDE_DEFAULTS \
+          {                                       \
+            { "GNU_GXX_INCLUDE:", 1},             \
+            { "GNU_CC_INCLUDE:", 0},              \
+            { "SYS$SYSROOT:[SYSLIB.]", 0},        \
+            { ".", 0},                            \
+            { 0, 0}                               \
+          }
+
+   Here is the order of prefixes tried for exec files:
+
+  1. Any prefixes specified by the user with `-B'.
+
+  2. The environment variable `GCC_EXEC_PREFIX', if any.
+
+  3. The directories specified by the environment variable
+     `COMPILER_PATH'.
+
+  4. The macro `STANDARD_EXEC_PREFIX'.
+
+  5. `/usr/lib/gcc/'.
+
+  6. The macro `MD_EXEC_PREFIX', if any.
+
+   Here is the order of prefixes tried for startfiles:
+
+  1. Any prefixes specified by the user with `-B'.
+
+  2. The environment variable `GCC_EXEC_PREFIX', if any.
+
+  3. The directories specified by the environment variable
+     `LIBRARY_PATH' (native only, cross compilers do not use this).
+
+  4. The macro `STANDARD_EXEC_PREFIX'.
+
+  5. `/usr/lib/gcc/'.
+
+  6. The macro `MD_EXEC_PREFIX', if any.
+
+  7. The macro `MD_STARTFILE_PREFIX', if any.
+
+  8. The macro `STANDARD_STARTFILE_PREFIX'.
+
+  9. `/lib/'.
+
+ 10. `/usr/lib/'.  */
+/* #define INCLUDE_DEFAULTS {{ }} */
+
+\f
+/* Run-time target specifications */
+
+/* Define this to be a string constant containing `-D' options to define the
+   predefined macros that identify this machine and system.  These macros will
+   be predefined unless the `-ansi' option is specified.
+
+   In addition, a parallel set of macros are predefined, whose names are made
+   by appending `__' at the beginning and at the end.  These `__' macros are
+   permitted by the ANSI standard, so they are predefined regardless of whether
+   `-ansi' is specified.
+
+   For example, on the Sun, one can use the following value:
+
+        "-Dmc68000 -Dsun -Dunix"
+
+   The result is to define the macros `__mc68000__', `__sun__' and `__unix__'
+   unconditionally, and the macros `mc68000', `sun' and `unix' provided `-ansi'
+   is not specified.  */
+#define CPP_PREDEFINES "-D__D30V__ -Amachine(d30v)"
+
+/* This declaration should be present.  */
+extern int target_flags;
+
+/* This series of macros is to allow compiler command arguments to enable or
+   disable the use of optional features of the target machine.  For example,
+   one machine description serves both the 68000 and the 68020; a command
+   argument tells the compiler whether it should use 68020-only instructions or
+   not.  This command argument works by means of a macro `TARGET_68020' that
+   tests a bit in `target_flags'.
+
+   Define a macro `TARGET_FEATURENAME' for each such option.  Its definition
+   should test a bit in `target_flags'; for example:
+
+        #define TARGET_68020 (target_flags & 1)
+
+   One place where these macros are used is in the condition-expressions of
+   instruction patterns.  Note how `TARGET_68020' appears frequently in the
+   68000 machine description file, `m68k.md'.  Another place they are used is
+   in the definitions of the other macros in the `MACHINE.h' file.  */
+
+#define MASK_NO_COND_MOVE      0x00000001      /* disable conditional moves */
+
+#define MASK_DEBUG_ARG         0x10000000      /* debug argument handling */
+#define MASK_DEBUG_STACK       0x20000000      /* debug stack allocations */
+#define MASK_DEBUG_ADDR                0x40000000      /* debug GO_IF_LEGITIMATE_ADDRESS */
+
+#define TARGET_NO_COND_MOVE    (target_flags & MASK_NO_COND_MOVE)
+#define TARGET_DEBUG_ARG       (target_flags & MASK_DEBUG_ARG)
+#define TARGET_DEBUG_STACK     (target_flags & MASK_DEBUG_STACK)
+#define TARGET_DEBUG_ADDR      (target_flags & MASK_DEBUG_ADDR)
+
+#define TARGET_COND_MOVE       (! TARGET_NO_COND_MOVE)
+
+/* Default switches used.  */
+#ifndef TARGET_DEFAULT
+#define TARGET_DEFAULT 0
+#endif
+
+/* This macro defines names of command options to set and clear bits in
+   `target_flags'.  Its definition is an initializer with a subgrouping for
+   each command option.
+
+   Each subgrouping contains a string constant, that defines the option name,
+   and a number, which contains the bits to set in `target_flags'.  A negative
+   number says to clear bits instead; the negative of the number is which bits
+   to clear.  The actual option name is made by appending `-m' to the specified
+   name.
+
+   One of the subgroupings should have a null string.  The number in this
+   grouping is the default value for `target_flags'.  Any target options act
+   starting with that value.
+
+   Here is an example which defines `-m68000' and `-m68020' with opposite
+   meanings, and picks the latter as the default:
+
+        #define TARGET_SWITCHES \
+          { { "68020", 1},      \
+            { "68000", -1},     \
+            { "", 1}}  */
+
+#define TARGET_SWITCHES                                                        \
+{                                                                      \
+  { "cond-move",       -MASK_NO_COND_MOVE },                           \
+  { "no-cond-move",     MASK_NO_COND_MOVE },                           \
+  { "debug-arg",        MASK_DEBUG_ARG },                              \
+  { "debug-stack",      MASK_DEBUG_STACK },                            \
+  { "debug-addr",       MASK_DEBUG_ADDR },                             \
+  { "asm-optimize",     0 },                                           \
+  { "no-asm-optimize",  0 },                                           \
+  { "extmem",           0 },                                           \
+  { "extmemory",        0 },                                           \
+  { "onchip",           0 },                                           \
+  { "",                         TARGET_DEFAULT },                              \
+}
+
+/* This macro is similar to `TARGET_SWITCHES' but defines names of command
+   options that have values.  Its definition is an initializer with a
+   subgrouping for each command option.
+
+   Each subgrouping contains a string constant, that defines the fixed part of
+   the option name, and the address of a variable.  The variable, type `char
+   *', is set to the variable part of the given option if the fixed part
+   matches.  The actual option name is made by appending `-m' to the specified
+   name.
+
+   Here is an example which defines `-mshort-data-NUMBER'.  If the given option
+   is `-mshort-data-512', the variable `m88k_short_data' will be set to the
+   string `"512"'.
+
+        extern char *m88k_short_data;
+        #define TARGET_OPTIONS \
+         { { "short-data-", &m88k_short_data } }  */
+
+#define TARGET_OPTIONS                                                 \
+{                                                                      \
+   {"branch-cost=",  &d30v_branch_cost_string},                                \
+   {"cond-exec=",    &d30v_cond_exec_string},                          \
+}
+
+/* This macro is a C statement to print on `stderr' a string describing the
+   particular machine description choice.  Every machine description should
+   define `TARGET_VERSION'.  For example:
+
+        #ifdef MOTOROLA
+        #define TARGET_VERSION \
+          fprintf (stderr, " (68k, Motorola syntax)");
+        #else
+        #define TARGET_VERSION \
+          fprintf (stderr, " (68k, MIT syntax)");
+        #endif  */
+#define TARGET_VERSION fprintf (stderr, " d30v")
+
+/* Sometimes certain combinations of command options do not make sense on a
+   particular target machine.  You can define a macro `OVERRIDE_OPTIONS' to
+   take account of this.  This macro, if defined, is executed once just after
+   all the command options have been parsed.
+
+   Don't use this macro to turn on various extra optimizations for `-O'.  That
+   is what `OPTIMIZATION_OPTIONS' is for.  */
+
+#define OVERRIDE_OPTIONS override_options ()
+
+/* Some machines may desire to change what optimizations are performed for
+   various optimization levels.  This macro, if defined, is executed once just
+   after the optimization level is determined and before the remainder of the
+   command options have been parsed.  Values set in this macro are used as the
+   default values for the other command line options.
+
+   LEVEL is the optimization level specified; 2 if `-O2' is specified, 1 if
+   `-O' is specified, and 0 if neither is specified.
+
+   SIZE is non-zero if `-Os' is specified, 0 otherwise.  
+
+   You should not use this macro to change options that are not
+   machine-specific.  These should uniformly selected by the same optimization
+   level on all supported machines.  Use this macro to enable machbine-specific
+   optimizations.
+
+   *Do not examine `write_symbols' in this macro!* The debugging options are
+   *not supposed to alter the generated code.  */
+/* #define OPTIMIZATION_OPTIONS(LEVEL,SIZE) */
+
+/* Define this macro if debugging can be performed even without a frame
+   pointer.  If this macro is defined, GNU CC will turn on the
+   `-fomit-frame-pointer' option whenever `-O' is specified.  */
+#define CAN_DEBUG_WITHOUT_FP
+
+\f
+/* Storage Layout */
+
+/* Define this macro to have the value 1 if the most significant bit in a byte
+   has the lowest number; otherwise define it to have the value zero.  This
+   means that bit-field instructions count from the most significant bit.  If
+   the machine has no bit-field instructions, then this must still be defined,
+   but it doesn't matter which value it is defined to.  This macro need not be
+   a constant.
+
+   This macro does not affect the way structure fields are packed into bytes or
+   words; that is controlled by `BYTES_BIG_ENDIAN'.  */
+#define BITS_BIG_ENDIAN 1
+
+/* Define this macro to have the value 1 if the most significant byte in a word
+   has the lowest number.  This macro need not be a constant.  */
+#define BYTES_BIG_ENDIAN 1
+
+/* Define this macro to have the value 1 if, in a multiword object, the most
+   significant word has the lowest number.  This applies to both memory
+   locations and registers; GNU CC fundamentally assumes that the order of
+   words in memory is the same as the order in registers.  This macro need not
+   be a constant.  */
+#define WORDS_BIG_ENDIAN 1
+
+/* Define this macro if WORDS_BIG_ENDIAN is not constant.  This must be a
+   constant value with the same meaning as WORDS_BIG_ENDIAN, which will be used
+   only when compiling libgcc2.c.  Typically the value will be set based on
+   preprocessor defines.  */
+/* #define LIBGCC2_WORDS_BIG_ENDIAN */
+
+/* Define this macro to have the value 1 if `DFmode', `XFmode' or `TFmode'
+   floating point numbers are stored in memory with the word containing the
+   sign bit at the lowest address; otherwise define it to have the value 0.
+   This macro need not be a constant.
+
+   You need not define this macro if the ordering is the same as for multi-word
+   integers.  */
+/* #define FLOAT_WORDS_BIG_EnNDIAN */
+
+/* Define this macro to be the number of bits in an addressable storage unit
+   (byte); normally 8.  */
+#define BITS_PER_UNIT 8
+
+/* Number of bits in a word; normally 32.  */
+#define BITS_PER_WORD 32
+
+/* Maximum number of bits in a word.  If this is undefined, the default is
+   `BITS_PER_WORD'.  Otherwise, it is the constant value that is the largest
+   value that `BITS_PER_WORD' can have at run-time.  */
+/* #define MAX_BITS_PER_WORD */
+
+/* Number of storage units in a word; normally 4.  */
+#define UNITS_PER_WORD 4
+
+/* Minimum number of units in a word.  If this is undefined, the default is
+   `UNITS_PER_WORD'.  Otherwise, it is the constant value that is the smallest
+   value that `UNITS_PER_WORD' can have at run-time.  */
+/* #define MIN_UNITS_PER_WORD */
+
+/* Width of a pointer, in bits.  You must specify a value no wider than the
+   width of `Pmode'.  If it is not equal to the width of `Pmode', you must
+   define `POINTERS_EXTEND_UNSIGNED'.  */
+#define POINTER_SIZE 32
+
+/* A C expression whose value is nonzero if pointers that need to be extended
+   from being `POINTER_SIZE' bits wide to `Pmode' are sign-extended and zero if
+   they are zero-extended.
+
+   You need not define this macro if the `POINTER_SIZE' is equal to the width
+   of `Pmode'.  */
+/* #define POINTERS_EXTEND_UNSIGNED */
+
+/* A macro to update M and UNSIGNEDP when an object whose type is TYPE and
+   which has the specified mode and signedness is to be stored in a register.
+   This macro is only called when TYPE is a scalar type.
+
+   On most RISC machines, which only have operations that operate on a full
+   register, define this macro to set M to `word_mode' if M is an integer mode
+   narrower than `BITS_PER_WORD'.  In most cases, only integer modes should be
+   widened because wider-precision floating-point operations are usually more
+   expensive than their narrower counterparts.
+
+   For most machines, the macro definition does not change UNSIGNEDP.  However,
+   some machines, have instructions that preferentially handle either signed or
+   unsigned quantities of certain modes.  For example, on the DEC Alpha, 32-bit
+   loads from memory and 32-bit add instructions sign-extend the result to 64
+   bits.  On such machines, set UNSIGNEDP according to which kind of extension
+   is more efficient.
+
+   Do not define this macro if it would never modify M.  */
+#define PROMOTE_MODE(MODE,UNSIGNEDP,TYPE)                              \
+do {                                                                   \
+  if (GET_MODE_CLASS (MODE) == MODE_INT                                        \
+      && GET_MODE_SIZE (MODE) < 4)                                     \
+    (MODE) = SImode;                                                   \
+} while (0)
+
+/* Define this macro if the promotion described by `PROMOTE_MODE' should also
+   be done for outgoing function arguments.  */
+/* #define PROMOTE_FUNCTION_ARGS */
+
+/* Define this macro if the promotion described by `PROMOTE_MODE' should also
+   be done for the return value of functions.
+
+   If this macro is defined, `FUNCTION_VALUE' must perform the same promotions
+   done by `PROMOTE_MODE'.  */
+/* #define PROMOTE_FUNCTION_RETURN */
+
+/* Define this macro if the promotion described by `PROMOTE_MODE' should *only*
+   be performed for outgoing function arguments or function return values, as
+   specified by `PROMOTE_FUNCTION_ARGS' and `PROMOTE_FUNCTION_RETURN',
+   respectively.  */
+/* #define PROMOTE_FOR_CALL_ONLY */
+
+/* Normal alignment required for function parameters on the stack, in bits.
+   All stack parameters receive at least this much alignment regardless of data
+   type.  On most machines, this is the same as the size of an integer.  */
+
+#define PARM_BOUNDARY 32
+
+/* Define this macro if you wish to preserve a certain alignment for the stack
+   pointer.  The definition is a C expression for the desired alignment
+   (measured in bits).
+
+   If `PUSH_ROUNDING' is not defined, the stack will always be aligned to the
+   specified boundary.  If `PUSH_ROUNDING' is defined and specifies a less
+   strict alignment than `STACK_BOUNDARY', the stack may be momentarily
+   unaligned while pushing arguments.  */
+
+#define STACK_BOUNDARY 64
+
+/* Alignment required for a function entry point, in bits.  */
+
+#define FUNCTION_BOUNDARY 64
+
+/* Biggest alignment that any data type can require on this machine,
+   in bits.  */
+
+#define BIGGEST_ALIGNMENT 64
+
+/* Biggest alignment that any structure field can require on this machine, in
+   bits.  If defined, this overrides `BIGGEST_ALIGNMENT' for structure fields
+   only.  */
+/* #define BIGGEST_FIELD_ALIGNMENT */
+
+/* Biggest alignment supported by the object file format of this machine.  Use
+   this macro to limit the alignment which can be specified using the
+   `__attribute__ ((aligned (N)))' construct.  If not defined, the default
+   value is `BIGGEST_ALIGNMENT'.
+
+   Defined in svr4.h.  */
+/* #define MAX_OFILE_ALIGNMENT */
+
+/* If defined, a C expression to compute the alignment for a static variable.
+   TYPE is the data type, and BASIC-ALIGN is the alignment that the object
+   would ordinarily have.  The value of this macro is used instead of that
+   alignment to align the object.
+
+   If this macro is not defined, then BASIC-ALIGN is used.
+
+   One use of this macro is to increase alignment of medium-size data to make
+   it all fit in fewer cache lines.  Another is to cause character arrays to be
+   word-aligned so that `strcpy' calls that copy constants to character arrays
+   can be done inline.  */
+
+#define DATA_ALIGNMENT(TYPE, ALIGN)            \
+  (TREE_CODE (TYPE) == ARRAY_TYPE              \
+   && TYPE_MODE (TREE_TYPE (TYPE)) == QImode   \
+   && (ALIGN) < BITS_PER_WORD ? BITS_PER_WORD : (ALIGN))
+
+/* If defined, a C expression to compute the alignment given to a constant that
+   is being placed in memory.  CONSTANT is the constant and BASIC-ALIGN is the
+   alignment that the object would ordinarily have.  The value of this macro is
+   used instead of that alignment to align the object.
+
+   If this macro is not defined, then BASIC-ALIGN is used.
+
+   The typical use of this macro is to increase alignment for string constants
+   to be word aligned so that `strcpy' calls that copy constants can be done
+   inline.  */
+
+#define CONSTANT_ALIGNMENT(EXP, ALIGN)  \
+  (TREE_CODE (EXP) == STRING_CST       \
+   && (ALIGN) < BITS_PER_WORD ? BITS_PER_WORD : (ALIGN))
+
+/* Alignment in bits to be given to a structure bit field that follows an empty
+   field such as `int : 0;'.
+
+   Note that `PCC_BITFIELD_TYPE_MATTERS' also affects the alignment that
+   results from an empty field.  */
+/* #define EMPTY_FIELD_BOUNDARY */
+
+/* Number of bits which any structure or union's size must be a multiple of.
+   Each structure or union's size is rounded up to a multiple of this.
+
+   If you do not define this macro, the default is the same as `BITS_PER_UNIT'.  */
+/* #define STRUCTURE_SIZE_BOUNDARY */
+
+/* Define this macro to be the value 1 if instructions will fail to work if
+   given data not on the nominal alignment.  If instructions will merely go
+   slower in that case, define this macro as 0.  */
+
+#define STRICT_ALIGNMENT 1
+
+/* Define this if you wish to imitate the way many other C compilers handle
+   alignment of bitfields and the structures that contain them.
+
+   The behavior is that the type written for a bitfield (`int', `short', or
+   other integer type) imposes an alignment for the entire structure, as if the
+   structure really did contain an ordinary field of that type.  In addition,
+   the bitfield is placed within the structure so that it would fit within such
+   a field, not crossing a boundary for it.
+
+   Thus, on most machines, a bitfield whose type is written as `int' would not
+   cross a four-byte boundary, and would force four-byte alignment for the
+   whole structure.  (The alignment used may not be four bytes; it is
+   controlled by the other alignment parameters.)
+
+   If the macro is defined, its definition should be a C expression; a nonzero
+   value for the expression enables this behavior.
+
+   Note that if this macro is not defined, or its value is zero, some bitfields
+   may cross more than one alignment boundary.  The compiler can support such
+   references if there are `insv', `extv', and `extzv' insns that can directly
+   reference memory.
+
+   The other known way of making bitfields work is to define
+   `STRUCTURE_SIZE_BOUNDARY' as large as `BIGGEST_ALIGNMENT'.  Then every
+   structure can be accessed with fullwords.
+
+   Unless the machine has bitfield instructions or you define
+   `STRUCTURE_SIZE_BOUNDARY' that way, you must define
+   `PCC_BITFIELD_TYPE_MATTERS' to have a nonzero value.
+
+   If your aim is to make GNU CC use the same conventions for laying out
+   bitfields as are used by another compiler, here is how to investigate what
+   the other compiler does.  Compile and run this program:
+
+        struct foo1
+        {
+          char x;
+          char :0;
+          char y;
+        };
+
+        struct foo2
+        {
+          char x;
+          int :0;
+          char y;
+        };
+
+        main ()
+        {
+          printf ("Size of foo1 is %d\n",
+                  sizeof (struct foo1));
+          printf ("Size of foo2 is %d\n",
+                  sizeof (struct foo2));
+          exit (0);
+        }
+
+   If this prints 2 and 5, then the compiler's behavior is what you would get
+   from `PCC_BITFIELD_TYPE_MATTERS'.
+
+   Defined in svr4.h.  */
+
+#define PCC_BITFIELD_TYPE_MATTERS 1
+
+/* Like PCC_BITFIELD_TYPE_MATTERS except that its effect is limited to aligning
+   a bitfield within the structure.  */
+/* #define BITFIELD_NBYTES_LIMITED */
+
+/* Define this macro as an expression for the overall size of a structure
+   (given by STRUCT as a tree node) when the size computed from the fields is
+   SIZE and the alignment is ALIGN.
+
+   The default is to round SIZE up to a multiple of ALIGN.  */
+/* #define ROUND_TYPE_SIZE(STRUCT, SIZE, ALIGN) */
+
+/* Define this macro as an expression for the alignment of a structure (given
+   by STRUCT as a tree node) if the alignment computed in the usual way is
+   COMPUTED and the alignment explicitly specified was SPECIFIED.
+
+   The default is to use SPECIFIED if it is larger; otherwise, use the smaller
+   of COMPUTED and `BIGGEST_ALIGNMENT' */
+/* #define ROUND_TYPE_ALIGN(STRUCT, COMPUTED, SPECIFIED) */
+
+/* An integer expression for the size in bits of the largest integer machine
+   mode that should actually be used.  All integer machine modes of this size
+   or smaller can be used for structures and unions with the appropriate sizes.
+   If this macro is undefined, `GET_MODE_BITSIZE (DImode)' is assumed.  */
+/* #define MAX_FIXED_MODE_SIZE */
+
+/* A C statement to validate the value VALUE (of type `double') for mode MODE.
+   This means that you check whether VALUE fits within the possible range of
+   values for mode MODE on this target machine.  The mode MODE is always a mode
+   of class `MODE_FLOAT'.  OVERFLOW is nonzero if the value is already known to
+   be out of range.
+
+   If VALUE is not valid or if OVERFLOW is nonzero, you should set OVERFLOW to
+   1 and then assign some valid value to VALUE.  Allowing an invalid value to
+   go through the compiler can produce incorrect assembler code which may even
+   cause Unix assemblers to crash.
+
+   This macro need not be defined if there is no work for it to do.  */
+/* #define CHECK_FLOAT_VALUE(MODE, VALUE, OVERFLOW) */
+
+/* A code distinguishing the floating point format of the target machine.
+   There are three defined values:
+
+   IEEE_FLOAT_FORMAT'
+        This code indicates IEEE floating point.  It is the default;
+        there is no need to define this macro when the format is IEEE.
+
+   VAX_FLOAT_FORMAT'
+        This code indicates the peculiar format used on the Vax.
+
+   UNKNOWN_FLOAT_FORMAT'
+        This code indicates any other format.
+
+   The value of this macro is compared with `HOST_FLOAT_FORMAT' (*note
+   Config::.) to determine whether the target machine has the same format as
+   the host machine.  If any other formats are actually in use on supported
+   machines, new codes should be defined for them.
+
+   The ordering of the component words of floating point values stored in
+   memory is controlled by `FLOAT_WORDS_BIG_ENDIAN' for the target machine and
+   `HOST_FLOAT_WORDS_BIG_ENDIAN' for the host.  */
+#define TARGET_FLOAT_FORMAT IEEE_FLOAT_FORMAT
+
+/* GNU CC supports two ways of implementing C++ vtables: traditional or with
+   so-called "thunks".  The flag `-fvtable-thunk' chooses between them.  Define
+   this macro to be a C expression for the default value of that flag.  If
+   `DEFAULT_VTABLE_THUNKS' is 0, GNU CC uses the traditional implementation by
+   default.  The "thunk" implementation is more efficient (especially if you
+   have provided an implementation of `ASM_OUTPUT_MI_THUNK', see *Note Function
+   Entry::), but is not binary compatible with code compiled using the
+   traditional implementation.  If you are writing a new ports, define
+   `DEFAULT_VTABLE_THUNKS' to 1.
+
+   If you do not define this macro, the default for `-fvtable-thunk' is 0.  */
+#define DEFAULT_VTABLE_THUNKS 0
+
+\f
+/* Layout of Source Language Data Types */
+
+/* A C expression for the size in bits of the type `int' on the target machine.
+   If you don't define this, the default is one word.  */
+#define INT_TYPE_SIZE 32
+
+/* Maximum number for the size in bits of the type `int' on the target machine.
+   If this is undefined, the default is `INT_TYPE_SIZE'.  Otherwise, it is the
+   constant value that is the largest value that `INT_TYPE_SIZE' can have at
+   run-time.  This is used in `cpp'.  */
+/* #define MAX_INT_TYPE_SIZE */
+
+/* A C expression for the size in bits of the type `short' on the target
+   machine.  If you don't define this, the default is half a word.  (If this
+   would be less than one storage unit, it is rounded up to one unit.)  */
+#define SHORT_TYPE_SIZE 16
+
+/* A C expression for the size in bits of the type `long' on the target
+   machine.  If you don't define this, the default is one word.  */
+#define LONG_TYPE_SIZE 32
+
+/* Maximum number for the size in bits of the type `long' on the target
+   machine.  If this is undefined, the default is `LONG_TYPE_SIZE'.  Otherwise,
+   it is the constant value that is the largest value that `LONG_TYPE_SIZE' can
+   have at run-time.  This is used in `cpp'.  */
+/* #define MAX_LONG_TYPE_SIZE */
+
+/* A C expression for the size in bits of the type `long long' on the target
+   machine.  If you don't define this, the default is two words.  If you want
+   to support GNU Ada on your machine, the value of macro must be at least 64.  */
+#define LONG_LONG_TYPE_SIZE 64
+
+/* A C expression for the size in bits of the type `char' on the target
+   machine.  If you don't define this, the default is one quarter of a word.
+   (If this would be less than one storage unit, it is rounded up to one unit.)  */
+#define CHAR_TYPE_SIZE 8
+
+/* Maximum number for the size in bits of the type `char' on the target
+   machine.  If this is undefined, the default is `CHAR_TYPE_SIZE'.  Otherwise,
+   it is the constant value that is the largest value that `CHAR_TYPE_SIZE' can
+   have at run-time.  This is used in `cpp'.  */
+/* #define MAX_CHAR_TYPE_SIZE */
+
+/* A C expression for the size in bits of the type `float' on the target
+   machine.  If you don't define this, the default is one word.  */
+#define FLOAT_TYPE_SIZE 32
+
+/* A C expression for the size in bits of the type `double' on the target
+   machine.  If you don't define this, the default is two words.  */
+#define DOUBLE_TYPE_SIZE 64
+
+/* A C expression for the size in bits of the type `long double' on the target
+   machine.  If you don't define this, the default is two words.  */
+#define LONG_DOUBLE_TYPE_SIZE 64
+
+/* An expression whose value is 1 or 0, according to whether the type `char'
+   should be signed or unsigned by default.  The user can always override this
+   default with the options `-fsigned-char' and `-funsigned-char'.  */
+#define DEFAULT_SIGNED_CHAR 1
+
+/* A C expression to determine whether to give an `enum' type only as many
+   bytes as it takes to represent the range of possible values of that type.  A
+   nonzero value means to do that; a zero value means all `enum' types should
+   be allocated like `int'.
+
+   If you don't define the macro, the default is 0.  */
+/* #define DEFAULT_SHORT_ENUMS */
+
+/* A C expression for a string describing the name of the data type to use for
+   size values.  The typedef name `size_t' is defined using the contents of the
+   string.
+
+   The string can contain more than one keyword.  If so, separate them with
+   spaces, and write first any length keyword, then `unsigned' if appropriate,
+   and finally `int'.  The string must exactly match one of the data type names
+   defined in the function `init_decl_processing' in the file `c-decl.c'.  You
+   may not omit `int' or change the order--that would cause the compiler to
+   crash on startup.
+
+   If you don't define this macro, the default is `"long unsigned int"'.
+
+   Defined in svr4.h.  */
+/* #define SIZE_TYPE */
+
+/* A C expression for a string describing the name of the data type to use for
+   the result of subtracting two pointers.  The typedef name `ptrdiff_t' is
+   defined using the contents of the string.  See `SIZE_TYPE' above for more
+   information.
+
+   If you don't define this macro, the default is `"long int"'.
+
+   Defined in svr4.h.  */
+/* #define PTRDIFF_TYPE */
+
+/* A C expression for a string describing the name of the data type to use for
+   wide characters.  The typedef name `wchar_t' is defined using the contents
+   of the string.  See `SIZE_TYPE' above for more information.
+
+   If you don't define this macro, the default is `"int"'.
+
+   Defined in svr4.h.  */
+/* #define WCHAR_TYPE */
+
+/* A C expression for the size in bits of the data type for wide characters.
+   This is used in `cpp', which cannot make use of `WCHAR_TYPE'.
+
+   Defined in svr4.h.  */
+/* #define WCHAR_TYPE_SIZE */
+
+/* Maximum number for the size in bits of the data type for wide characters.
+   If this is undefined, the default is `WCHAR_TYPE_SIZE'.  Otherwise, it is
+   the constant value that is the largest value that `WCHAR_TYPE_SIZE' can have
+   at run-time.  This is used in `cpp'.  */
+/* #define MAX_WCHAR_TYPE_SIZE */
+
+/* Define this macro if the type of Objective C selectors should be `int'.
+
+   If this macro is not defined, then selectors should have the type `struct
+   objc_selector *'.  */
+/* #define OBJC_INT_SELECTORS */
+
+/* Define this macro if the compiler can group all the selectors together into
+   a vector and use just one label at the beginning of the vector.  Otherwise,
+   the compiler must give each selector its own assembler label.
+
+   On certain machines, it is important to have a separate label for each
+   selector because this enables the linker to eliminate duplicate selectors.  */
+/* #define OBJC_SELECTORS_WITHOUT_LABELS */
+
+/* A C constant expression for the integer value for escape sequence
+   `\a'.  */
+#define TARGET_BELL 0x7
+
+/* C constant expressions for the integer values for escape sequences
+   `\b', `\t' and `\n'.  */
+#define TARGET_BS      0x8
+#define TARGET_TAB     0x9
+#define TARGET_NEWLINE 0xa
+
+/* C constant expressions for the integer values for escape sequences
+   `\v', `\f' and `\r'.  */
+#define TARGET_VT      0xb
+#define TARGET_FF      0xc
+#define TARGET_CR      0xd
+
+\f
+/* D30V register layout.  */
+
+/* Return true if a value is inside a range */
+#define IN_RANGE_P(VALUE, LOW, HIGH) \
+  (((unsigned)((VALUE) - (LOW))) <= ((unsigned)((HIGH) - (LOW))))
+
+/* General purpose registers.  */
+#define GPR_FIRST      0                       /* First gpr */
+#define GPR_LAST       (GPR_FIRST + 63)        /* Last gpr */
+#define GPR_R0         GPR_FIRST               /* R0, constant 0 */
+#define GPR_ARG_FIRST  (GPR_FIRST + 2)         /* R2, first argument reg */
+#define GPR_ARG_LAST   (GPR_FIRST + 17)        /* R17, last argument reg */
+#define GPR_RET_VALUE  GPR_ARG_FIRST           /* R2, function return reg */
+#define GPR_ATMP_FIRST (GPR_FIRST + 20)        /* R20, tmp to save accs */
+#define GPR_ATMP_LAST  (GPR_FIRST + 21)        /* R21, tmp to save accs */
+#define GPR_STACK_TMP  (GPR_FIRST + 22)        /* R22, tmp for saving stack */
+#define GPR_RES_FIRST  (GPR_FIRST + 32)        /* R32, first reserved reg */
+#define GPR_RES_LAST   (GPR_FIRST + 35)        /* R35, last reserved reg */
+#define GPR_FP         (GPR_FIRST + 61)        /* Frame pointer */
+#define GPR_LINK       (GPR_FIRST + 62)        /* Return address register */
+#define GPR_SP         (GPR_FIRST + 63)        /* Stack pointer */
+
+/* Argument register that is eliminated in favor of the frame and/or stack
+   pointer.  Also add register to point to where the return address is
+   stored.  */
+#define SPECIAL_REG_FIRST              (GPR_LAST + 1)
+#define SPECIAL_REG_LAST               (SPECIAL_REG_FIRST)
+#define ARG_POINTER_REGNUM             (SPECIAL_REG_FIRST + 0)
+#define SPECIAL_REG_P(R)               ((R) == SPECIAL_REG_FIRST)
+
+#define GPR_OR_SPECIAL_REG_P(R)                IN_RANGE_P (R, GPR_FIRST, SPECIAL_REG_LAST)
+#define GPR_P(R)                       IN_RANGE_P (R, GPR_FIRST, GPR_LAST)
+#define GPR_OR_PSEUDO_P(R)             (GPR_OR_SPECIAL_REG_P (R)       \
+                                        || (R) >= FIRST_PSEUDO_REGISTER)
+
+/* Flag bits.  */
+#define FLAG_FIRST     (SPECIAL_REG_LAST + 1)  /* First flag */
+#define FLAG_LAST      (FLAG_FIRST + 7)        /* Last flag */
+#define FLAG_F0                (FLAG_FIRST)            /* F0, used in prediction */
+#define FLAG_F1                (FLAG_FIRST + 1)        /* F1, used in prediction */
+#define FLAG_F2                (FLAG_FIRST + 2)        /* F2, general flag */
+#define FLAG_F3                (FLAG_FIRST + 3)        /* F3, general flag */
+#define FLAG_SAT       (FLAG_FIRST + 4)        /* F4, saturation flag */
+#define FLAG_OVERFLOW  (FLAG_FIRST + 5)        /* F5, overflow flag */
+#define FLAG_ACC_OVER  (FLAG_FIRST + 6)        /* F6, accumulated overflow */
+#define FLAG_CARRY     (FLAG_FIRST + 7)        /* F7, carry/borrow flag */
+#define FLAG_BORROW    FLAG_CARRY
+
+#define FLAG_P(R)              IN_RANGE_P (R, FLAG_FIRST, FLAG_LAST)
+#define FLAG_OR_PSEUDO_P(R)    (FLAG_P (R) || (R) >= FIRST_PSEUDO_REGISTER)
+
+#define BR_FLAG_P(R)           IN_RANGE_P (R, FLAG_F0, FLAG_F1)
+#define BR_FLAG_OR_PSEUDO_P(R) (BR_FLAG_P (R) || (R) >= FIRST_PSEUDO_REGISTER)
+
+/* Accumulators */
+#define ACCUM_FIRST    (FLAG_LAST + 1)         /* First accumulator */
+#define ACCUM_A0       ACCUM_FIRST             /* Register A0 */
+#define ACCUM_A1       (ACCUM_FIRST + 1)       /* Register A1 */
+#define ACCUM_LAST     (ACCUM_FIRST + 1)       /* Last accumulator */
+
+#define ACCUM_P(R)             IN_RANGE_P (R, ACCUM_FIRST, ACCUM_LAST)
+#define ACCUM_OR_PSEUDO_P(R)   (ACCUM_P (R) || (R) >= FIRST_PSEUDO_REGISTER)
+
+/* Special registers.  Note, we only define the registers that can actually
+   be used.  */
+#define CR_FIRST       (ACCUM_LAST + 1)        /* First CR */
+#define CR_LAST                (CR_FIRST + 14)         /* Last CR */
+#define CR_PSW         (CR_FIRST + 0)          /* CR0, Program status word */
+#define CR_BPSW                (CR_FIRST + 1)          /* CR1, Backup PSW */
+#define CR_PC          (CR_FIRST + 2)          /* CR2, Program counter */
+#define CR_BPC         (CR_FIRST + 3)          /* CR3, Backup PC */
+#define CR_DPSW                (CR_FIRST + 4)          /* CR4, Debug PSW */
+#define CR_DPC         (CR_FIRST + 5)          /* CR5, Debug PC */
+#define CR_RPT_C       (CR_FIRST + 6)          /* CR7, loop count register */
+#define CR_RPT_S       (CR_FIRST + 7)          /* CR8, loop start address */
+#define CR_RPT_E       (CR_FIRST + 8)          /* CR9, loop end address */
+#define CR_MOD_S       (CR_FIRST + 9)          /* CR10, modulo address start*/
+#define CR_MOD_E       (CR_FIRST + 10)         /* CR11, modulo address */
+#define CR_IBA         (CR_FIRST + 11)         /* CR14, Interrupt break addr */
+#define CR_EIT_VB      (CR_FIRST + 12)         /* CR15, EIT vector address */
+#define CR_INT_S       (CR_FIRST + 13)         /* CR16, Interrupt status */
+#define CR_INT_M       (CR_FIRST + 14)         /* CR17, Interrupt mask */
+
+#define CR_P(R)                        IN_RANGE_P (R, CR_FIRST, CR_LAST)
+#define CR_OR_PSEUDO_P(R)      (CR_P (R) || (R) >= FIRST_PSEUDO_REGISTER)
+
+\f
+/* Register Basics */
+
+/* Number of hardware registers known to the compiler.  They receive numbers 0
+   through `FIRST_PSEUDO_REGISTER-1'; thus, the first pseudo register's number
+   really is assigned the number `FIRST_PSEUDO_REGISTER'.  */
+#define FIRST_PSEUDO_REGISTER (CR_LAST + 1)
+
+/* An initializer that says which registers are used for fixed purposes all
+   throughout the compiled code and are therefore not available for general
+   allocation.  These would include the stack pointer, the frame pointer
+   (except on machines where that can be used as a general register when no
+   frame pointer is needed), the program counter on machines where that is
+   considered one of the addressable registers, and any other numbered register
+   with a standard use.
+
+   This information is expressed as a sequence of numbers, separated by commas
+   and surrounded by braces.  The Nth number is 1 if register N is fixed, 0
+   otherwise.
+
+   The table initialized from this macro, and the table initialized by the
+   following one, may be overridden at run time either automatically, by the
+   actions of the macro `CONDITIONAL_REGISTER_USAGE', or by the user with the
+   command options `-ffixed-REG', `-fcall-used-REG' and `-fcall-saved-REG'.  */
+#define FIXED_REGISTERS                                                        \
+{                                                                      \
+  1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  /* R0  - R15 */     \
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1,  /* R16 - R31 */     \
+  1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  /* R32 - R47 */     \
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,  /* R48 - R63 */     \
+  1,                                              /* ARG ptr */        \
+  0, 0, 0, 0, 1, 1, 1, 1,                         /* F0 - F7 */        \
+  0, 0,                                                   /* A0 - A1 */        \
+  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,    /* CRs */            \
+}
+
+/* Like `FIXED_REGISTERS' but has 1 for each register that is clobbered (in
+   general) by function calls as well as for fixed registers.  This macro
+   therefore identifies the registers that are not available for general
+   allocation of values that must live across function calls.
+
+   If a register has 0 in `CALL_USED_REGISTERS', the compiler automatically
+   saves it on function entry and restores it on function exit, if the register
+   is used within the function.  */
+#define CALL_USED_REGISTERS                                            \
+{                                                                      \
+  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  /* R0  - R15 */     \
+  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  /* R16 - R31 */     \
+  1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  /* R32 - R47 */     \
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,  /* R48 - R63 */     \
+  1,                                              /* ARG ptr */        \
+  1, 1, 1, 1, 1, 1, 1, 1,                         /* F0 - F7 */        \
+  1, 0,                                                   /* A0 - A1 */        \
+  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,    /* CRs */            \
+}
+
+/* Zero or more C statements that may conditionally modify two variables
+   `fixed_regs' and `call_used_regs' (both of type `char []') after they have
+   been initialized from the two preceding macros.
+
+   This is necessary in case the fixed or call-clobbered registers depend on
+   target flags.
+
+   You need not define this macro if it has no work to do.
+
+   If the usage of an entire class of registers depends on the target flags,
+   you may indicate this to GCC by using this macro to modify `fixed_regs' and
+   `call_used_regs' to 1 for each of the registers in the classes which should
+   not be used by GCC.  Also define the macro `REG_CLASS_FROM_LETTER' to return
+   `NO_REGS' if it is called with a letter for a class that shouldn't be used.
+
+   (However, if this class is not included in `GENERAL_REGS' and all of the
+   insn patterns whose constraints permit this class are controlled by target
+   switches, then GCC will automatically avoid using these registers when the
+   target switches are opposed to them.)  */
+/* #define CONDITIONAL_REGISTER_USAGE */
+
+/* If this macro is defined and has a nonzero value, it means that `setjmp' and
+   related functions fail to save the registers, or that `longjmp' fails to
+   restore them.  To compensate, the compiler avoids putting variables in
+   registers in functions that use `setjmp'.  */
+/* #define NON_SAVING_SETJMP */
+
+/* Define this macro if the target machine has register windows.  This C
+   expression returns the register number as seen by the called function
+   corresponding to the register number OUT as seen by the calling function.
+   Return OUT if register number OUT is not an outbound register.  */
+/* #define INCOMING_REGNO(OUT) */
+
+/* Define this macro if the target machine has register windows.  This C
+   expression returns the register number as seen by the calling function
+   corresponding to the register number IN as seen by the called function.
+   Return IN if register number IN is not an inbound register.  */
+/* #define OUTGOING_REGNO(IN) */
+
+\f
+/* Order of allocation of registers */
+
+/* If defined, an initializer for a vector of integers, containing the numbers
+   of hard registers in the order in which GNU CC should prefer to use them
+   (from most preferred to least).
+
+   If this macro is not defined, registers are used lowest numbered first (all
+   else being equal).
+
+   One use of this macro is on machines where the highest numbered registers
+   must always be saved and the save-multiple-registers instruction supports
+   only sequences of consecutive registers.  On such machines, define
+   `REG_ALLOC_ORDER' to be an initializer that lists the highest numbered
+   allocatable register first.  */
+
+#define REG_ALLOC_ORDER                                                        \
+{                                                                      \
+  /* volatile registers */                                             \
+  GPR_FIRST + 2,    GPR_FIRST + 3,    GPR_FIRST + 4,    GPR_FIRST + 5, \
+  GPR_FIRST + 6,    GPR_FIRST + 7,    GPR_FIRST + 8,    GPR_FIRST + 9, \
+  GPR_FIRST + 10,   GPR_FIRST + 11,   GPR_FIRST + 12,   GPR_FIRST + 13,        \
+  GPR_FIRST + 14,   GPR_FIRST + 15,   GPR_FIRST + 16,   GPR_FIRST + 17,        \
+  GPR_FIRST + 18,   GPR_FIRST + 19,   GPR_FIRST + 20,   GPR_FIRST + 21,        \
+  GPR_FIRST + 22,   GPR_FIRST + 23,   GPR_FIRST + 24,   GPR_FIRST + 25, \
+  GPR_FIRST + 1,                                                       \
+                                                                       \
+  /* saved registers */                                                        \
+  GPR_FIRST + 34,   GPR_FIRST + 35,   GPR_FIRST + 36,   GPR_FIRST + 37,        \
+  GPR_FIRST + 38,   GPR_FIRST + 39,   GPR_FIRST + 40,   GPR_FIRST + 41,        \
+  GPR_FIRST + 42,   GPR_FIRST + 43,   GPR_FIRST + 44,   GPR_FIRST + 45,        \
+  GPR_FIRST + 46,   GPR_FIRST + 47,   GPR_FIRST + 48,   GPR_FIRST + 49,        \
+  GPR_FIRST + 50,   GPR_FIRST + 51,   GPR_FIRST + 52,   GPR_FIRST + 53,        \
+  GPR_FIRST + 54,   GPR_FIRST + 55,   GPR_FIRST + 56,   GPR_FIRST + 57,        \
+  GPR_FIRST + 58,   GPR_FIRST + 59,   GPR_FIRST + 60,   GPR_FIRST + 61,        \
+  GPR_FIRST + 62,                                                      \
+                                                                       \
+  /* flags */                                                          \
+  FLAG_F2,          FLAG_F3,          FLAG_F0,          FLAG_F1,       \
+  FLAG_SAT,         FLAG_OVERFLOW,    FLAG_ACC_OVER,    FLAG_CARRY,    \
+                                                                       \
+  /* accumultors */                                                    \
+  ACCUM_FIRST + 0,  ACCUM_FIRST + 1,                                   \
+                                                                       \
+  /* fixed registers */                                                        \
+  GPR_FIRST + 0,    GPR_FIRST + 26,   GPR_FIRST + 27,   GPR_FIRST + 28,        \
+  GPR_FIRST + 29,   GPR_FIRST + 30,   GPR_FIRST + 31,   GPR_FIRST + 32,        \
+  GPR_FIRST + 33,   GPR_FIRST + 63,                                    \
+  CR_PSW,          CR_BPSW,          CR_PC,            CR_BPC,         \
+  CR_DPSW,         CR_DPC,           CR_RPT_C,         CR_RPT_S,       \
+  CR_RPT_E,        CR_MOD_S,         CR_MOD_E,         CR_IBA,         \
+  CR_EIT_VB,       CR_INT_S,         CR_INT_M,                         \
+  ARG_POINTER_REGNUM,                                                  \
+}
+
+/* A C statement (sans semicolon) to choose the order in which to allocate hard
+   registers for pseudo-registers local to a basic block.
+
+   Store the desired register order in the array `reg_alloc_order'.  Element 0
+   should be the register to allocate first; element 1, the next register; and
+   so on.
+
+   The macro body should not assume anything about the contents of
+   `reg_alloc_order' before execution of the macro.
+
+   On most machines, it is not necessary to define this macro.  */
+/* #define ORDER_REGS_FOR_LOCAL_ALLOC */
+
+\f
+/* How Values Fit in Registers */
+
+/* A C expression for the number of consecutive hard registers, starting at
+   register number REGNO, required to hold a value of mode MODE.
+
+   On a machine where all registers are exactly one word, a suitable definition
+   of this macro is
+
+        #define HARD_REGNO_NREGS(REGNO, MODE)            \
+           ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1)  \
+            / UNITS_PER_WORD))  */
+
+#define HARD_REGNO_NREGS(REGNO, MODE)                                  \
+(ACCUM_P (REGNO) ? ((GET_MODE_SIZE (MODE) + 2*UNITS_PER_WORD - 1)      \
+                   / (2*UNITS_PER_WORD))                               \
+                : ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1)         \
+                   / UNITS_PER_WORD))
+
+/* A C expression that is nonzero if it is permissible to store a value of mode
+   MODE in hard register number REGNO (or in several registers starting with
+   that one).  For a machine where all registers are equivalent, a suitable
+   definition is
+
+        #define HARD_REGNO_MODE_OK(REGNO, MODE) 1
+
+   It is not necessary for this macro to check for the numbers of fixed
+   registers, because the allocation mechanism considers them to be always
+   occupied.
+
+   On some machines, double-precision values must be kept in even/odd register
+   pairs.  The way to implement that is to define this macro to reject odd
+   register numbers for such modes.
+
+   The minimum requirement for a mode to be OK in a register is that the
+   `movMODE' instruction pattern support moves between the register and any
+   other hard register for which the mode is OK; and that moving a value into
+   the register and back out not alter it.
+
+   Since the same instruction used to move `SImode' will work for all narrower
+   integer modes, it is not necessary on any machine for `HARD_REGNO_MODE_OK'
+   to distinguish between these modes, provided you define patterns `movhi',
+   etc., to take advantage of this.  This is useful because of the interaction
+   between `HARD_REGNO_MODE_OK' and `MODES_TIEABLE_P'; it is very desirable for
+   all integer modes to be tieable.
+
+   Many machines have special registers for floating point arithmetic.  Often
+   people assume that floating point machine modes are allowed only in floating
+   point registers.  This is not true.  Any registers that can hold integers
+   can safely *hold* a floating point machine mode, whether or not floating
+   arithmetic can be done on it in those registers.  Integer move instructions
+   can be used to move the values.
+
+   On some machines, though, the converse is true: fixed-point machine modes
+   may not go in floating registers.  This is true if the floating registers
+   normalize any value stored in them, because storing a non-floating value
+   there would garble it.  In this case, `HARD_REGNO_MODE_OK' should reject
+   fixed-point machine modes in floating registers.  But if the floating
+   registers do not automatically normalize, if you can store any bit pattern
+   in one and retrieve it unchanged without a trap, then any machine mode may
+   go in a floating register, so you can define this macro to say so.
+
+   The primary significance of special floating registers is rather that they
+   are the registers acceptable in floating point arithmetic instructions.
+   However, this is of no concern to `HARD_REGNO_MODE_OK'.  You handle it by
+   writing the proper constraints for those instructions.
+
+   On some machines, the floating registers are especially slow to access, so
+   that it is better to store a value in a stack frame than in such a register
+   if floating point arithmetic is not being done.  As long as the floating
+   registers are not in class `GENERAL_REGS', they will not be used unless some
+   pattern's constraint asks for one.  */
+
+extern unsigned char hard_regno_mode_ok[][FIRST_PSEUDO_REGISTER];
+#define HARD_REGNO_MODE_OK(REGNO, MODE) hard_regno_mode_ok[ (int)MODE ][ REGNO ]
+
+/* A C expression that is nonzero if it is desirable to choose register
+   allocation so as to avoid move instructions between a value of mode MODE1
+   and a value of mode MODE2.
+
+   If `HARD_REGNO_MODE_OK (R, MODE1)' and `HARD_REGNO_MODE_OK (R, MODE2)' are
+   ever different for any R, then `MODES_TIEABLE_P (MODE1, MODE2)' must be
+   zero.  */
+
+extern unsigned char modes_tieable_p[];
+#define MODES_TIEABLE_P(MODE1, MODE2) \
+  modes_tieable_p[ (((int)(MODE1)) * (NUM_MACHINE_MODES)) + (int)(MODE2) ]
+
+/* Define this macro if the compiler should avoid copies to/from CCmode
+   registers.  You should only define this macro if support fo copying to/from
+   CCmode is incomplete.  */
+   
+/* On the D30V, copying to/from CCmode is complete, but since there are only
+   two CC registers usable for conditional tests, this helps gcse not compound
+   the reload problem.  */
+#define AVOID_CCMODE_COPIES
+
+\f
+/* Handling Leaf Functions */
+
+/* A C initializer for a vector, indexed by hard register number, which
+   contains 1 for a register that is allowable in a candidate for leaf function
+   treatment.
+
+   If leaf function treatment involves renumbering the registers, then the
+   registers marked here should be the ones before renumbering--those that GNU
+   CC would ordinarily allocate.  The registers which will actually be used in
+   the assembler code, after renumbering, should not be marked with 1 in this
+   vector.
+
+   Define this macro only if the target machine offers a way to optimize the
+   treatment of leaf functions.  */
+/* #define LEAF_REGISTERS */
+
+/* A C expression whose value is the register number to which REGNO should be
+   renumbered, when a function is treated as a leaf function.
+
+   If REGNO is a register number which should not appear in a leaf function
+   before renumbering, then the expression should yield -1, which will cause
+   the compiler to abort.
+
+   Define this macro only if the target machine offers a way to optimize the
+   treatment of leaf functions, and registers need to be renumbered to do this.  */
+/* #define LEAF_REG_REMAP(REGNO) */
+
+\f
+/* Registers That Form a Stack.  */
+
+/* Define this if the machine has any stack-like registers.  */
+/* #define STACK_REGS */
+
+/* The number of the first stack-like register.  This one is the top
+   of the stack.  */
+/* #define FIRST_STACK_REG */
+
+/* The number of the last stack-like register.  This one is the
+   bottom of the stack.  */
+/* #define LAST_STACK_REG */
+
+\f
+/* Register Classes */
+
+/* An enumeral type that must be defined with all the register class names as
+   enumeral values.  `NO_REGS' must be first.  `ALL_REGS' must be the last
+   register class, followed by one more enumeral value, `LIM_REG_CLASSES',
+   which is not a register class but rather tells how many classes there are.
+
+   Each register class has a number, which is the value of casting the class
+   name to type `int'.  The number serves as an index in many of the tables
+   described below.  */
+enum reg_class
+{
+  NO_REGS,
+  REPEAT_REGS,
+  CR_REGS,
+  ACCUM_REGS,
+  OTHER_FLAG_REGS,
+  F0_REGS,
+  F1_REGS,
+  BR_FLAG_REGS,
+  FLAG_REGS,
+  EVEN_REGS,
+  GPR_REGS,
+  ALL_REGS,
+  LIM_REG_CLASSES
+};
+
+#define GENERAL_REGS GPR_REGS
+
+/* The number of distinct register classes, defined as follows:
+
+        #define N_REG_CLASSES (int) LIM_REG_CLASSES  */
+#define N_REG_CLASSES ((int) LIM_REG_CLASSES)
+
+/* An initializer containing the names of the register classes as C string
+   constants.  These names are used in writing some of the debugging dumps.  */
+#define REG_CLASS_NAMES                                                        \
+{                                                                      \
+  "NO_REGS",                                                           \
+  "REPEAT_REGS",                                                       \
+  "CR_REGS",                                                           \
+  "ACCUM_REGS",                                                                \
+  "OTHER_FLAG_REGS",                                                   \
+  "F0_REGS",                                                           \
+  "F1_REGS",                                                           \
+  "BR_FLAG_REGS",                                                      \
+  "FLAG_REGS",                                                         \
+  "EVEN_REGS",                                                         \
+  "GPR_REGS",                                                          \
+  "ALL_REGS",                                                          \
+}
+
+/* Create mask bits for 3rd word of REG_CLASS_CONTENTS */
+#define MASK_WORD3(REG) ((long)1 << ((REG) - 64))
+
+#define NO_MASK                0
+#define REPEAT_MASK    MASK_WORD3 (CR_RPT_C)
+#define CR_MASK                (MASK_WORD3 (CR_PSW)     | MASK_WORD3 (CR_BPSW)   \
+                        | MASK_WORD3 (CR_PC)    | MASK_WORD3 (CR_BPC)    \
+                        | MASK_WORD3 (CR_DPSW)  | MASK_WORD3 (CR_DPC)    \
+                        | MASK_WORD3 (CR_RPT_C) | MASK_WORD3 (CR_RPT_S)  \
+                        | MASK_WORD3 (CR_RPT_E) | MASK_WORD3 (CR_MOD_S)  \
+                        | MASK_WORD3 (CR_MOD_E) | MASK_WORD3 (CR_IBA)    \
+                        | MASK_WORD3 (CR_EIT_VB) | MASK_WORD3 (CR_INT_S) \
+                        | MASK_WORD3 (CR_INT_M))
+
+#define ACCUM_MASK     (MASK_WORD3 (ACCUM_A0)   | MASK_WORD3 (ACCUM_A1))
+#define OTHER_FLAG_MASK        (MASK_WORD3 (FLAG_F2)    | MASK_WORD3 (FLAG_F3) \
+                        | MASK_WORD3 (FLAG_SAT) | MASK_WORD3 (FLAG_OVERFLOW) \
+                        | MASK_WORD3 (FLAG_ACC_OVER) | MASK_WORD3 (FLAG_CARRY))
+
+#define F0_MASK                MASK_WORD3 (FLAG_F0)
+#define F1_MASK                MASK_WORD3 (FLAG_F1)
+#define BR_FLAG_MASK   (F0_MASK | F1_MASK)
+#define FLAG_MASK      (BR_FLAG_MASK | OTHER_FLAG_MASK)
+#define SPECIAL_MASK   MASK_WORD3 (ARG_POINTER_REGNUM)
+
+#define ALL_MASK       (CR_MASK | ACCUM_MASK | FLAG_MASK | SPECIAL_MASK)
+
+/* An initializer containing the contents of the register classes, as integers
+   which are bit masks.  The Nth integer specifies the contents of class N.
+   The way the integer MASK is interpreted is that register R is in the class
+   if `MASK & (1 << R)' is 1.
+
+   When the machine has more than 32 registers, an integer does not suffice.
+   Then the integers are replaced by sub-initializers, braced groupings
+   containing several integers.  Each sub-initializer must be suitable as an
+   initializer for the type `HARD_REG_SET' which is defined in
+   `hard-reg-set.h'.  */
+#define REG_CLASS_CONTENTS                                             \
+{                                                                      \
+  { 0x00000000, 0x00000000, NO_MASK },         /* NO_REGS */           \
+  { 0x00000000, 0x00000000, REPEAT_MASK },     /* REPEAT_REGS */       \
+  { 0x00000000, 0x00000000, CR_MASK },         /* CR_REGS */           \
+  { 0x00000000, 0x00000000, ACCUM_MASK },      /* ACCUM_REGS */        \
+  { 0x00000000, 0x00000000, OTHER_FLAG_MASK }, /* OTHER_FLAG_REGS */   \
+  { 0x00000000, 0x00000000, F0_MASK },         /* F0_REGS */           \
+  { 0x00000000, 0x00000000, F1_MASK },         /* F1_REGS */           \
+  { 0x00000000, 0x00000000, BR_FLAG_MASK },    /* BR_FLAG_REGS */      \
+  { 0x00000000, 0x00000000, FLAG_MASK },       /* FLAG_REGS */         \
+  { 0xfffffffc, 0x3fffffff, NO_MASK },         /* EVEN_REGS */         \
+  { 0xffffffff, 0xffffffff, SPECIAL_MASK },    /* GPR_REGS */          \
+  { 0xffffffff, 0xffffffff, ALL_MASK },                /* ALL_REGS */          \
+}
+
+/* A C expression whose value is a register class containing hard register
+   REGNO.  In general there is more than one such class; choose a class which
+   is "minimal", meaning that no smaller class also contains the register.  */
+
+extern enum reg_class regno_reg_class[];
+#define REGNO_REG_CLASS(REGNO) regno_reg_class[ (REGNO) ]
+
+/* A macro whose definition is the name of the class to which a valid base
+   register must belong.  A base register is one used in an address which is
+   the register value plus a displacement.  */
+#define BASE_REG_CLASS GPR_REGS
+
+/* A macro whose definition is the name of the class to which a valid index
+   register must belong.  An index register is one used in an address where its
+   value is either multiplied by a scale factor or added to another register
+   (as well as added to a displacement).  */
+#define INDEX_REG_CLASS GPR_REGS
+
+/* A C expression which defines the machine-dependent operand constraint
+   letters for register classes.  If CHAR is such a letter, the value should be
+   the register class corresponding to it.  Otherwise, the value should be
+   `NO_REGS'.  The register letter `r', corresponding to class `GENERAL_REGS',
+   will not be passed to this macro; you do not need to handle it.
+
+   The following letters are unavailable, due to being used as
+   constraints:
+       '0'..'9'
+       '<', '>'
+       'E', 'F', 'G', 'H'
+       'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P'
+       'Q', 'R', 'S', 'T', 'U'
+       'V', 'X'
+       'g', 'i', 'm', 'n', 'o', 'p', 'r', 's' */
+
+extern enum reg_class reg_class_from_letter[];
+#define REG_CLASS_FROM_LETTER(CHAR) reg_class_from_letter[ CHAR ]
+
+/* A C expression which is nonzero if register number NUM is suitable for use
+   as a base register in operand addresses.  It may be either a suitable hard
+   register or a pseudo register that has been allocated such a hard register.  */
+
+#define REGNO_OK_FOR_BASE_P(NUM)                                       \
+((NUM) < FIRST_PSEUDO_REGISTER                                         \
+ ? GPR_P (NUM)                                                         \
+ : (reg_renumber[NUM] >= 0 && GPR_P (reg_renumber[NUM])))
+
+
+/* A C expression which is nonzero if register number NUM is suitable for use
+   as an index register in operand addresses.  It may be either a suitable hard
+   register or a pseudo register that has been allocated such a hard register.
+
+   The difference between an index register and a base register is that the
+   index register may be scaled.  If an address involves the sum of two
+   registers, neither one of them scaled, then either one may be labeled the
+   "base" and the other the "index"; but whichever labeling is used must fit
+   the machine's constraints of which registers may serve in each capacity.
+   The compiler will try both labelings, looking for one that is valid, and
+   will reload one or both registers only if neither labeling works.  */
+
+#define REGNO_OK_FOR_INDEX_P(NUM)                                      \
+((NUM) < FIRST_PSEUDO_REGISTER                                         \
+ ? GPR_P (NUM)                                                         \
+ : (reg_renumber[NUM] >= 0 && GPR_P (reg_renumber[NUM])))
+
+/* A C expression that places additional restrictions on the register class to
+   use when it is necessary to copy value X into a register in class CLASS.
+   The value is a register class; perhaps CLASS, or perhaps another, smaller
+   class.  On many machines, the following definition is safe:
+
+        #define PREFERRED_RELOAD_CLASS(X,CLASS) CLASS
+
+   Sometimes returning a more restrictive class makes better code.  For
+   example, on the 68000, when X is an integer constant that is in range for a
+   `moveq' instruction, the value of this macro is always `DATA_REGS' as long
+   as CLASS includes the data registers.  Requiring a data register guarantees
+   that a `moveq' will be used.
+
+   If X is a `const_double', by returning `NO_REGS' you can force X into a
+   memory constant.  This is useful on certain machines where immediate
+   floating values cannot be loaded into certain kinds of registers.  */
+#define PREFERRED_RELOAD_CLASS(X, CLASS) CLASS
+
+/* Like `PREFERRED_RELOAD_CLASS', but for output reloads instead of input
+   reloads.  If you don't define this macro, the default is to use CLASS,
+   unchanged.  */
+/* #define PREFERRED_OUTPUT_RELOAD_CLASS(X, CLASS) */
+
+/* A C expression that places additional restrictions on the register class to
+   use when it is necessary to be able to hold a value of mode MODE in a reload
+   register for which class CLASS would ordinarily be used.
+
+   Unlike `PREFERRED_RELOAD_CLASS', this macro should be used when there are
+   certain modes that simply can't go in certain reload classes.
+
+   The value is a register class; perhaps CLASS, or perhaps another, smaller
+   class.
+
+   Don't define this macro unless the target machine has limitations which
+   require the macro to do something nontrivial.  */
+/* #define LIMIT_RELOAD_CLASS(MODE, CLASS) */
+
+/* Many machines have some registers that cannot be copied directly to or from
+   memory or even from other types of registers.  An example is the `MQ'
+   register, which on most machines, can only be copied to or from general
+   registers, but not memory.  Some machines allow copying all registers to and
+   from memory, but require a scratch register for stores to some memory
+   locations (e.g., those with symbolic address on the RT, and those with
+   certain symbolic address on the Sparc when compiling PIC).  In some cases,
+   both an intermediate and a scratch register are required.
+
+   You should define these macros to indicate to the reload phase that it may
+   need to allocate at least one register for a reload in addition to the
+   register to contain the data.  Specifically, if copying X to a register
+   CLASS in MODE requires an intermediate register, you should define
+   `SECONDARY_INPUT_RELOAD_CLASS' to return the largest register class all of
+   whose registers can be used as intermediate registers or scratch registers.
+
+   If copying a register CLASS in MODE to X requires an intermediate or scratch
+   register, `SECONDARY_OUTPUT_RELOAD_CLASS' should be defined to return the
+   largest register class required.  If the requirements for input and output
+   reloads are the same, the macro `SECONDARY_RELOAD_CLASS' should be used
+   instead of defining both macros identically.
+
+   The values returned by these macros are often `GENERAL_REGS'.  Return
+   `NO_REGS' if no spare register is needed; i.e., if X can be directly copied
+   to or from a register of CLASS in MODE without requiring a scratch register.
+   Do not define this macro if it would always return `NO_REGS'.
+
+   If a scratch register is required (either with or without an intermediate
+   register), you should define patterns for `reload_inM' or `reload_outM', as
+   required (*note Standard Names::..  These patterns, which will normally be
+   implemented with a `define_expand', should be similar to the `movM'
+   patterns, except that operand 2 is the scratch register.
+
+   Define constraints for the reload register and scratch register that contain
+   a single register class.  If the original reload register (whose class is
+   CLASS) can meet the constraint given in the pattern, the value returned by
+   these macros is used for the class of the scratch register.  Otherwise, two
+   additional reload registers are required.  Their classes are obtained from
+   the constraints in the insn pattern.
+
+   X might be a pseudo-register or a `subreg' of a pseudo-register, which could
+   either be in a hard register or in memory.  Use `true_regnum' to find out;
+   it will return -1 if the pseudo is in memory and the hard register number if
+   it is in a register.
+
+   These macros should not be used in the case where a particular class of
+   registers can only be copied to memory and not to another class of
+   registers.  In that case, secondary reload registers are not needed and
+   would not be helpful.  Instead, a stack location must be used to perform the
+   copy and the `movM' pattern should use memory as a intermediate storage.
+   This case often occurs between floating-point and general registers.  */
+
+#define SECONDARY_RELOAD_CLASS(CLASS, MODE, X)                         \
+((CLASS) == GPR_REGS           ? NO_REGS                               \
+ : (CLASS) == EVEN_REGS                ? NO_REGS                               \
+ : (CLASS) == ACCUM_REGS       ? EVEN_REGS                             \
+ :                               GPR_REGS)
+
+/* #define SECONDARY_INPUT_RELOAD_CLASS(CLASS, MODE, X) */
+/* #define SECONDARY_OUTPUT_RELOAD_CLASS(CLASS, MODE, X) */
+
+/* Certain machines have the property that some registers cannot be copied to
+   some other registers without using memory.  Define this macro on those
+   machines to be a C expression that is non-zero if objects of mode M in
+   registers of CLASS1 can only be copied to registers of class CLASS2 by
+   storing a register of CLASS1 into memory and loading that memory location
+   into a register of CLASS2.
+
+   Do not define this macro if its value would always be zero.  */
+/* #define SECONDARY_MEMORY_NEEDED(CLASS1, CLASS2, M) */
+
+/* Normally when `SECONDARY_MEMORY_NEEDED' is defined, the compiler allocates a
+   stack slot for a memory location needed for register copies.  If this macro
+   is defined, the compiler instead uses the memory location defined by this
+   macro.
+
+   Do not define this macro if you do not define
+   `SECONDARY_MEMORY_NEEDED'.  */
+/* #define SECONDARY_MEMORY_NEEDED_RTX(MODE) */
+
+/* When the compiler needs a secondary memory location to copy between two
+   registers of mode MODE, it normally allocates sufficient memory to hold a
+   quantity of `BITS_PER_WORD' bits and performs the store and load operations
+   in a mode that many bits wide and whose class is the same as that of MODE.
+
+   This is right thing to do on most machines because it ensures that all bits
+   of the register are copied and prevents accesses to the registers in a
+   narrower mode, which some machines prohibit for floating-point registers.
+
+   However, this default behavior is not correct on some machines, such as the
+   DEC Alpha, that store short integers in floating-point registers differently
+   than in integer registers.  On those machines, the default widening will not
+   work correctly and you must define this macro to suppress that widening in
+   some cases.  See the file `alpha.h' for details.
+
+   Do not define this macro if you do not define `SECONDARY_MEMORY_NEEDED' or
+   if widening MODE to a mode that is `BITS_PER_WORD' bits wide is correct for
+   your machine.  */
+/* #define SECONDARY_MEMORY_NEEDED_MODE(MODE) */
+
+/* Normally the compiler avoids choosing registers that have been explicitly
+   mentioned in the rtl as spill registers (these registers are normally those
+   used to pass parameters and return values).  However, some machines have so
+   few registers of certain classes that there would not be enough registers to
+   use as spill registers if this were done.
+
+   Define `SMALL_REGISTER_CLASSES' to be an expression with a non-zero value on
+   these machines.  When this macro has a non-zero value, the compiler allows
+   registers explicitly used in the rtl to be used as spill registers but
+   avoids extending the lifetime of these registers.
+
+   It is always safe to define this macro with a non-zero value, but if you
+   unnecessarily define it, you will reduce the amount of optimizations that
+   can be performed in some cases.  If you do not define this macro with a
+   non-zero value when it is required, the compiler will run out of spill
+   registers and print a fatal error message.  For most machines, you should
+   not define this macro at all.  */
+/* #define SMALL_REGISTER_CLASSES */
+
+/* A C expression whose value is nonzero if pseudos that have been assigned to
+   registers of class CLASS would likely be spilled because registers of CLASS
+   are needed for spill registers.
+
+   The default value of this macro returns 1 if CLASS has exactly one register
+   and zero otherwise.  On most machines, this default should be used.  Only
+   define this macro to some other expression if pseudo allocated by
+   `local-alloc.c' end up in memory because their hard registers were needed
+   for spill registers.  If this macro returns nonzero for those classes, those
+   pseudos will only be allocated by `global.c', which knows how to reallocate
+   the pseudo to another register.  If there would not be another register
+   available for reallocation, you should not change the definition of this
+   macro since the only effect of such a definition would be to slow down
+   register allocation.  */
+#define CLASS_LIKELY_SPILLED_P(CLASS) \
+  ((CLASS) != GPR_REGS && (CLASS) != EVEN_REGS)
+
+/* A C expression for the maximum number of consecutive registers of
+   class CLASS needed to hold a value of mode MODE.
+
+   This is closely related to the macro `HARD_REGNO_NREGS'.  In fact, the value
+   of the macro `CLASS_MAX_NREGS (CLASS, MODE)' should be the maximum value of
+   `HARD_REGNO_NREGS (REGNO, MODE)' for all REGNO values in the class CLASS.
+
+   This macro helps control the handling of multiple-word values in
+   the reload pass.  */
+
+#define CLASS_MAX_NREGS(CLASS, MODE)                                   \
+(((CLASS) == ACCUM_REGS)                                               \
+ ? ((GET_MODE_SIZE (MODE) + 8 - 1) / 8)                                        \
+ : ((GET_MODE_SIZE (MODE) + 4 - 1) / 4))
+
+/* If defined, a C expression for a class that contains registers which the
+   compiler must always access in a mode that is the same size as the mode in
+   which it loaded the register.
+
+   For the example, loading 32-bit integer or floating-point objects into
+   floating-point registers on the Alpha extends them to 64-bits.  Therefore
+   loading a 64-bit object and then storing it as a 32-bit object does not
+   store the low-order 32-bits, as would be the case for a normal register.
+   Therefore, `alpha.h' defines this macro as `FLOAT_REGS'.  */
+/* #define CLASS_CANNOT_CHANGE_SIZE */
+
+/* A C expression that defines the machine-dependent operand constraint letters
+   (`I', `J', `K', .. 'P') that specify particular ranges of integer values.
+   If C is one of those letters, the expression should check that VALUE, an
+   integer, is in the appropriate range and return 1 if so, 0 otherwise.  If C
+   is not one of those letters, the value should be 0 regardless of VALUE.  */
+#define CONST_OK_FOR_LETTER_P(VALUE, C)                                        \
+((C) == 'I'    ? IN_RANGE_P (VALUE, -32, 31)                           \
+ : (C) == 'J'  ? IN_RANGE_P (VALUE, 0, 31)                             \
+ : (C) == 'K'  ? IN_RANGE_P (exact_log2 (VALUE), 0, 31)                \
+ : (C) == 'L'  ? IN_RANGE_P (exact_log2 (~ (VALUE)), 0, 31)            \
+ : (C) == 'M'  ? ((VALUE) == 32)                                       \
+ : (C) == 'N'  ? ((VALUE) == 1)                                        \
+ : (C) == 'O'  ? ((VALUE) == 0)                                        \
+ : (C) == 'P'  ? IN_RANGE_P (VALUE, 32, 63)                            \
+ :               FALSE)
+
+/* A C expression that defines the machine-dependent operand constraint letters
+   (`G', `H') that specify particular ranges of `const_double' values.
+
+   If C is one of those letters, the expression should check that VALUE, an RTX
+   of code `const_double', is in the appropriate range and return 1 if so, 0
+   otherwise.  If C is not one of those letters, the value should be 0
+   regardless of VALUE.
+
+   `const_double' is used for all floating-point constants and for `DImode'
+   fixed-point constants.  A given letter can accept either or both kinds of
+   values.  It can use `GET_MODE' to distinguish between these kinds.  */
+#define CONST_DOUBLE_OK_FOR_LETTER_P(VALUE, C)                         \
+((C) == 'G'    ? (CONST_DOUBLE_LOW (VALUE) == 0                        \
+                  && CONST_DOUBLE_HIGH (VALUE) == 0)                   \
+ : (C) == 'H'  ? FALSE                                                 \
+ :               FALSE)
+
+/* A C expression that defines the optional machine-dependent constraint
+   letters (`Q', `R', `S', `T', `U') that can be used to segregate specific
+   types of operands, usually memory references, for the target machine.
+   Normally this macro will not be defined.  If it is required for a particular
+   target machine, it should return 1 if VALUE corresponds to the operand type
+   represented by the constraint letter C.  If C is not defined as an extra
+   constraint, the value returned should be 0 regardless of VALUE.
+
+   For example, on the ROMP, load instructions cannot have their output in r0
+   if the memory reference contains a symbolic address.  Constraint letter `Q'
+   is defined as representing a memory address that does *not* contain a
+   symbolic address.  An alternative is specified with a `Q' constraint on the
+   input and `r' on the output.  The next alternative specifies `m' on the
+   input and a register class that does not include r0 on the output.  */
+
+#define EXTRA_CONSTRAINT(VALUE, C)                                     \
+(((C) == 'Q')  ? short_memory_operand ((VALUE), GET_MODE (VALUE))      \
+ : ((C) == 'R')        ? single_reg_memory_operand ((VALUE), GET_MODE (VALUE)) \
+ : ((C) == 'S')        ? const_addr_memory_operand ((VALUE), GET_MODE (VALUE)) \
+ : ((C) == 'T')        ? long_memory_operand ((VALUE), GET_MODE (VALUE))       \
+ : ((C) == 'U')        ? FALSE                                                 \
+ :               FALSE)
+
+\f
+/* Basic Stack Layout */
+
+/* Stack layout */
+
+/* Structure used to define the d30v stack */
+typedef struct d30v_stack {
+  int varargs_p;               /* whether this is a varargs function */
+  int varargs_size;            /* size to hold varargs args passed in regs */
+  int vars_size;               /* variable save area size */
+  int parm_size;               /* outgoing parameter size */
+  int gpr_size;                        /* size of saved GPR registers */
+  int accum_size;              /* size of saved ACCUM registers */
+  int total_size;              /* total bytes allocated for stack */
+                               /* which registers are to be saved */
+  int save_offset;             /* offset from new sp to start saving vars at */
+  int link_offset;             /* offset r62 is saved at */
+  int memrefs_varargs;         /* # of 2 word memory references for varargs */
+  int memrefs_2words;          /* # of 2 word memory references */
+  int memrefs_1word;           /* # of 1 word memory references */
+                               /* 1 for ldw/stw ops; 2 for ld2w/st2w ops */
+  unsigned char save_p[FIRST_PSEUDO_REGISTER];
+} d30v_stack_t;
+
+/* Define this macro if pushing a word onto the stack moves the stack pointer
+   to a smaller address.
+
+   When we say, "define this macro if ...," it means that the compiler checks
+   this macro only with `#ifdef' so the precise definition used does not
+   matter.  */
+#define STACK_GROWS_DOWNWARD 1
+
+/* Define this macro if the addresses of local variable slots are at negative
+   offsets from the frame pointer.  */
+/* #define FRAME_GROWS_DOWNWARD */
+
+/* Define this macro if successive arguments to a function occupy decreasing
+   addresses on the stack.  */
+/* #define ARGS_GROW_DOWNWARD */
+
+/* Offset from the frame pointer to the first local variable slot to be
+   allocated.
+
+   If `FRAME_GROWS_DOWNWARD', find the next slot's offset by subtracting the
+   first slot's length from `STARTING_FRAME_OFFSET'.  Otherwise, it is found by
+   adding the length of the first slot to the value `STARTING_FRAME_OFFSET'.  */
+
+#define STARTING_FRAME_OFFSET                                          \
+  (D30V_ALIGN (current_function_outgoing_args_size,                    \
+              (STACK_BOUNDARY / BITS_PER_UNIT)))
+
+/* Offset from the stack pointer register to the first location at which
+   outgoing arguments are placed.  If not specified, the default value of zero
+   is used.  This is the proper value for most machines.
+
+   If `ARGS_GROW_DOWNWARD', this is the offset to the location above the first
+   location at which outgoing arguments are placed.  */
+/* #define STACK_POINTER_OFFSET */
+
+/* Offset from the argument pointer register to the first argument's address.
+   On some machines it may depend on the data type of the function.
+
+   If `ARGS_GROW_DOWNWARD', this is the offset to the location above the first
+   argument's address.  */
+#define FIRST_PARM_OFFSET(FUNDECL) 0
+
+/* Offset from the stack pointer register to an item dynamically allocated on
+   the stack, e.g., by `alloca'.
+
+   The default value for this macro is `STACK_POINTER_OFFSET' plus the length
+   of the outgoing arguments.  The default is correct for most machines.  See
+   `function.c' for details.  */
+/* #define STACK_DYNAMIC_OFFSET(FUNDECL) */
+
+/* A C expression whose value is RTL representing the address in a stack frame
+   where the pointer to the caller's frame is stored.  Assume that FRAMEADDR is
+   an RTL expression for the address of the stack frame itself.
+
+   If you don't define this macro, the default is to return the value of
+   FRAMEADDR--that is, the stack frame address is also the address of the stack
+   word that points to the previous frame.  */
+/* #define DYNAMIC_CHAIN_ADDRESS(FRAMEADDR) */
+
+/* If defined, a C expression that produces the machine-specific code to setup
+   the stack so that arbitrary frames can be accessed.  For example, on the
+   Sparc, we must flush all of the register windows to the stack before we can
+   access arbitrary stack frames.  This macro will seldom need to be defined.  */
+/* #define SETUP_FRAME_ADDRESSES() */
+
+/* A C expression whose value is RTL representing the value of the return
+   address for the frame COUNT steps up from the current frame, after the
+   prologue.  FRAMEADDR is the frame pointer of the COUNT frame, or the frame
+   pointer of the COUNT - 1 frame if `RETURN_ADDR_IN_PREVIOUS_FRAME' is
+   defined.
+
+   The value of the expression must always be the correct address when COUNT is
+   zero, but may be `NULL_RTX' if there is not way to determine the return
+   address of other frames.  */
+
+/* ??? This definition fails for leaf functions.  There is currently no
+   general solution for this problem.  */
+
+/* ??? There appears to be no way to get the return address of any previous
+   frame except by disassembling instructions in the prologue/epilogue.
+   So currently we support only the current frame.  */
+
+#define RETURN_ADDR_RTX(COUNT, FRAME)                                  \
+  ((COUNT) == 0 ? d30v_return_addr() : const0_rtx)
+
+/* Define this if the return address of a particular stack frame is
+   accessed from the frame pointer of the previous stack frame.  */
+/* #define RETURN_ADDR_IN_PREVIOUS_FRAME */
+
+/* A C expression whose value is RTL representing the location of the incoming
+   return address at the beginning of any function, before the prologue.  This
+   RTL is either a `REG', indicating that the return value is saved in `REG',
+   or a `MEM' representing a location in the stack.
+
+   You only need to define this macro if you want to support call frame
+   debugging information like that provided by DWARF 2.  */
+
+/* Before the prologue, RA lives in r62.  */
+#define INCOMING_RETURN_ADDR_RTX  gen_rtx (REG, Pmode, GPR_LINK)
+
+/* A C expression whose value is an integer giving the offset, in bytes, from
+   the value of the stack pointer register to the top of the stack frame at the
+   beginning of any function, before the prologue.  The top of the frame is
+   defined to be the value of the stack pointer in the previous frame, just
+   before the call instruction.
+
+   You only need to define this macro if you want to support call frame
+   debugging information like that provided by DWARF 2.  */
+#define INCOMING_FRAME_SP_OFFSET 0
+
+/* Initialize data used by insn expanders.  This is called from insn_emit,
+   once for every function before code is generated.  */
+
+#define INIT_EXPANDERS  d30v_init_expanders ()
+extern void d30v_init_expanders ();
+\f
+/* Stack Checking.  */
+
+/* A nonzero value if stack checking is done by the configuration files in a
+   machine-dependent manner.  You should define this macro if stack checking is
+   require by the ABI of your machine or if you would like to have to stack
+   checking in some more efficient way than GNU CC's portable approach.  The
+   default value of this macro is zero.  */
+/* #define STACK_CHECK_BUILTIN */
+
+/* An integer representing the interval at which GNU CC must generate stack
+   probe instructions.  You will normally define this macro to be no larger
+   than the size of the "guard pages" at the end of a stack area.  The default
+   value of 4096 is suitable for most systems.  */
+/* #define STACK_CHECK_PROBE_INTERVAL */
+
+/* A integer which is nonzero if GNU CC should perform the stack probe as a
+   load instruction and zero if GNU CC should use a store instruction.  The
+   default is zero, which is the most efficient choice on most systems.  */
+/* #define STACK_CHECK_PROBE_LOAD */
+
+/* The number of bytes of stack needed to recover from a stack overflow, for
+   languages where such a recovery is supported.  The default value of 75 words
+   should be adequate for most machines.  */
+/* #define STACK_CHECK_PROTECT */
+
+/* The maximum size of a stack frame, in bytes.  GNU CC will generate probe
+   instructions in non-leaf functions to ensure at least this many bytes of
+   stack are available.  If a stack frame is larger than this size, stack
+   checking will not be reliable and GNU CC will issue a warning.  The default
+   is chosen so that GNU CC only generates one instruction on most systems.
+   You should normally not change the default value of this macro.  */
+/* #define STACK_CHECK_MAX_FRAME_SIZE */
+
+/* GNU CC uses this value to generate the above warning message.  It represents
+   the amount of fixed frame used by a function, not including space for any
+   callee-saved registers, temporaries and user variables.  You need only
+   specify an upper bound for this amount and will normally use the default of
+   four words.  */
+/* #define STACK_CHECK_FIXED_FRAME_SIZE */
+
+/* The maximum size, in bytes, of an object that GNU CC will place in the fixed
+   area of the stack frame when the user specifies `-fstack-check'.  GNU CC
+   computed the default from the values of the above macros and you will
+   normally not need to override that default.  */
+/* #define STACK_CHECK_MAX_VAR_SIZE */
+
+\f
+/* Register That Address the Stack Frame.  */
+
+/* The register number of the stack pointer register, which must also be a
+   fixed register according to `FIXED_REGISTERS'.  On most machines, the
+   hardware determines which register this is.  */
+#define STACK_POINTER_REGNUM GPR_SP
+
+/* The register number of the frame pointer register, which is used to access
+   automatic variables in the stack frame.  On some machines, the hardware
+   determines which register this is.  On other machines, you can choose any
+   register you wish for this purpose.  */
+#define FRAME_POINTER_REGNUM GPR_FP
+
+/* On some machines the offset between the frame pointer and starting offset of
+   the automatic variables is not known until after register allocation has
+   been done (for example, because the saved registers are between these two
+   locations).  On those machines, define `FRAME_POINTER_REGNUM' the number of
+   a special, fixed register to be used internally until the offset is known,
+   and define `HARD_FRAME_POINTER_REGNUM' to be actual the hard register number
+   used for the frame pointer.
+
+   You should define this macro only in the very rare circumstances when it is
+   not possible to calculate the offset between the frame pointer and the
+   automatic variables until after register allocation has been completed.
+   When this macro is defined, you must also indicate in your definition of
+   `ELIMINABLE_REGS' how to eliminate `FRAME_POINTER_REGNUM' into either
+   `HARD_FRAME_POINTER_REGNUM' or `STACK_POINTER_REGNUM'.
+
+   Do not define this macro if it would be the same as `FRAME_POINTER_REGNUM'.  */
+/* #define HARD_FRAME_POINTER_REGNUM */
+
+/* The register number of the arg pointer register, which is used to access the
+   function's argument list.  On some machines, this is the same as the frame
+   pointer register.  On some machines, the hardware determines which register
+   this is.  On other machines, you can choose any register you wish for this
+   purpose.  If this is not the same register as the frame pointer register,
+   then you must mark it as a fixed register according to `FIXED_REGISTERS', or
+   arrange to be able to eliminate it (*note Elimination::.).  */
+/* #define ARG_POINTER_REGNUM */
+
+/* The register number of the return address pointer register, which is used to
+   access the current function's return address from the stack.  On some
+   machines, the return address is not at a fixed offset from the frame pointer
+   or stack pointer or argument pointer.  This register can be defined to point
+   to the return address on the stack, and then be converted by
+   `ELIMINABLE_REGS' into either the frame pointer or stack pointer.
+
+   Do not define this macro unless there is no other way to get the return
+   address from the stack.  */
+/* #define RETURN_ADDRESS_POINTER_REGNUM */
+
+/* Register numbers used for passing a function's static chain pointer.  If
+   register windows are used, the register number as seen by the called
+   function is `STATIC_CHAIN_INCOMING_REGNUM', while the register number as
+   seen by the calling function is `STATIC_CHAIN_REGNUM'.  If these registers
+   are the same, `STATIC_CHAIN_INCOMING_REGNUM' need not be defined.
+
+   The static chain register need not be a fixed register.
+
+   If the static chain is passed in memory, these macros should not be defined;
+   instead, the next two macros should be defined.  */
+
+#define STATIC_CHAIN_REGNUM (GPR_FIRST + 18)
+/* #define STATIC_CHAIN_INCOMING_REGNUM */
+
+/* If the static chain is passed in memory, these macros provide rtx giving
+   `mem' expressions that denote where they are stored.  `STATIC_CHAIN' and
+   `STATIC_CHAIN_INCOMING' give the locations as seen by the calling and called
+   functions, respectively.  Often the former will be at an offset from the
+   stack pointer and the latter at an offset from the frame pointer.
+
+   The variables `stack_pointer_rtx', `frame_pointer_rtx', and
+   `arg_pointer_rtx' will have been initialized prior to the use of these
+   macros and should be used to refer to those items.
+
+   If the static chain is passed in a register, the two previous
+   macros should be defined instead.  */
+/* #define STATIC_CHAIN */
+/* #define STATIC_CHAIN_INCOMING */
+
+\f
+/* Eliminating the Frame Pointer and the Arg Pointer */
+
+/* A C expression which is nonzero if a function must have and use a frame
+   pointer.  This expression is evaluated in the reload pass.  If its value is
+   nonzero the function will have a frame pointer.
+
+   The expression can in principle examine the current function and decide
+   according to the facts, but on most machines the constant 0 or the constant
+   1 suffices.  Use 0 when the machine allows code to be generated with no
+   frame pointer, and doing so saves some time or space.  Use 1 when there is
+   no possible advantage to avoiding a frame pointer.
+
+   In certain cases, the compiler does not know how to produce valid code
+   without a frame pointer.  The compiler recognizes those cases and
+   automatically gives the function a frame pointer regardless of what
+   `FRAME_POINTER_REQUIRED' says.  You don't need to worry about them.
+
+   In a function that does not require a frame pointer, the frame pointer
+   register can be allocated for ordinary usage, unless you mark it as a fixed
+   register.  See `FIXED_REGISTERS' for more information.  */
+#define FRAME_POINTER_REQUIRED 0
+
+/* A C statement to store in the variable DEPTH-VAR the difference between the
+   frame pointer and the stack pointer values immediately after the function
+   prologue.  The value would be computed from information such as the result
+   of `get_frame_size ()' and the tables of registers `regs_ever_live' and
+   `call_used_regs'.
+
+   If `ELIMINABLE_REGS' is defined, this macro will be not be used and need not
+   be defined.  Otherwise, it must be defined even if `FRAME_POINTER_REQUIRED'
+   is defined to always be true; in that case, you may set DEPTH-VAR to
+   anything.  */
+/* #define INITIAL_FRAME_POINTER_OFFSET(DEPTH_VAR) */
+
+/* If defined, this macro specifies a table of register pairs used to eliminate
+   unneeded registers that point into the stack frame.  If it is not defined,
+   the only elimination attempted by the compiler is to replace references to
+   the frame pointer with references to the stack pointer.
+
+   The definition of this macro is a list of structure initializations, each of
+   which specifies an original and replacement register.
+
+   On some machines, the position of the argument pointer is not known until
+   the compilation is completed.  In such a case, a separate hard register must
+   be used for the argument pointer.  This register can be eliminated by
+   replacing it with either the frame pointer or the argument pointer,
+   depending on whether or not the frame pointer has been eliminated.
+
+   In this case, you might specify:
+        #define ELIMINABLE_REGS  \
+        {{ARG_POINTER_REGNUM, STACK_POINTER_REGNUM}, \
+         {ARG_POINTER_REGNUM, FRAME_POINTER_REGNUM}, \
+         {FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM}}
+
+   Note that the elimination of the argument pointer with the stack pointer is
+   specified first since that is the preferred elimination.  */
+#define ELIMINABLE_REGS                                                        \
+{                                                                      \
+  { ARG_POINTER_REGNUM,                STACK_POINTER_REGNUM },                 \
+  { ARG_POINTER_REGNUM,                FRAME_POINTER_REGNUM },                 \
+  { FRAME_POINTER_REGNUM,      STACK_POINTER_REGNUM }                  \
+}
+
+/* A C expression that returns non-zero if the compiler is allowed to try to
+   replace register number FROM-REG with register number TO-REG.  This macro
+   need only be defined if `ELIMINABLE_REGS' is defined, and will usually be
+   the constant 1, since most of the cases preventing register elimination are
+   things that the compiler already knows about.  */
+
+#define CAN_ELIMINATE(FROM, TO)                                                \
+ ((FROM) == ARG_POINTER_REGNUM && (TO) == STACK_POINTER_REGNUM         \
+  ? ! frame_pointer_needed                                             \
+  : 1)
+
+/* This macro is similar to `INITIAL_FRAME_POINTER_OFFSET'.  It specifies the
+   initial difference between the specified pair of registers.  This macro must
+   be defined if `ELIMINABLE_REGS' is defined.  */
+
+#define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET)                   \
+{                                                                      \
+  d30v_stack_t *info = d30v_stack_info ();                             \
+                                                                       \
+  if ((FROM) == FRAME_POINTER_REGNUM)                                  \
+    (OFFSET) = 0;                                                      \
+  else if ((FROM) == ARG_POINTER_REGNUM)                               \
+    (OFFSET) = info->total_size - current_function_pretend_args_size;  \
+  else                                                                 \
+    abort ();                                                          \
+}
+
+/* Define this macro if the `longjmp' function restores registers from the
+   stack frames, rather than from those saved specifically by `setjmp'.
+   Certain quantities must not be kept in registers across a call to `setjmp'
+   on such machines.  */
+/* #define LONGJMP_RESTORE_FROM_STACK */
+
+\f
+/* Passing Function Arguments on the Stack */
+
+/* Define this macro if an argument declared in a prototype as an integral type
+   smaller than `int' should actually be passed as an `int'.  In addition to
+   avoiding errors in certain cases of mismatch, it also makes for better code
+   on certain machines.  */
+/* #define PROMOTE_PROTOTYPES */
+
+/* A C expression that is the number of bytes actually pushed onto the stack
+   when an instruction attempts to push NPUSHED bytes.
+
+   If the target machine does not have a push instruction, do not define this
+   macro.  That directs GNU CC to use an alternate strategy: to allocate the
+   entire argument block and then store the arguments into it.
+
+   On some machines, the definition
+
+        #define PUSH_ROUNDING(BYTES) (BYTES)
+
+   will suffice.  But on other machines, instructions that appear to push one
+   byte actually push two bytes in an attempt to maintain alignment.  Then the
+   definition should be
+
+        #define PUSH_ROUNDING(BYTES) (((BYTES) + 1) & ~1)  */
+/* #define PUSH_ROUNDING(NPUSHED) */
+
+/* If defined, the maximum amount of space required for outgoing arguments will
+   be computed and placed into the variable
+   `current_function_outgoing_args_size'.  No space will be pushed onto the
+   stack for each call; instead, the function prologue should increase the
+   stack frame size by this amount.
+
+   Defining both `PUSH_ROUNDING' and `ACCUMULATE_OUTGOING_ARGS' is not
+   proper.  */
+#define ACCUMULATE_OUTGOING_ARGS 1
+
+/* Define this macro if functions should assume that stack space has been
+   allocated for arguments even when their values are passed in registers.
+
+   The value of this macro is the size, in bytes, of the area reserved for
+   arguments passed in registers for the function represented by FNDECL.
+
+   This space can be allocated by the caller, or be a part of the
+   machine-dependent stack frame: `OUTGOING_REG_PARM_STACK_SPACE' says
+   which.  */
+/* #define REG_PARM_STACK_SPACE(FNDECL) */
+
+/* Define these macros in addition to the one above if functions might allocate
+   stack space for arguments even when their values are passed in registers.
+   These should be used when the stack space allocated for arguments in
+   registers is not a simple constant independent of the function declaration.
+
+   The value of the first macro is the size, in bytes, of the area that we
+   should initially assume would be reserved for arguments passed in registers.
+
+   The value of the second macro is the actual size, in bytes, of the area that
+   will be reserved for arguments passed in registers.  This takes two
+   arguments: an integer representing the number of bytes of fixed sized
+   arguments on the stack, and a tree representing the number of bytes of
+   variable sized arguments on the stack.
+
+   When these macros are defined, `REG_PARM_STACK_SPACE' will only be called
+   for libcall functions, the current function, or for a function being called
+   when it is known that such stack space must be allocated.  In each case this
+   value can be easily computed.
+
+   When deciding whether a called function needs such stack space, and how much
+   space to reserve, GNU CC uses these two macros instead of
+   `REG_PARM_STACK_SPACE'.  */
+/* #define MAYBE_REG_PARM_STACK_SPACE */
+/* #define FINAL_REG_PARM_STACK_SPACE(CONST_SIZE, VAR_SIZE) */
+
+/* Define this if it is the responsibility of the caller to allocate the area
+   reserved for arguments passed in registers.
+
+   If `ACCUMULATE_OUTGOING_ARGS' is defined, this macro controls whether the
+   space for these arguments counts in the value of
+   `current_function_outgoing_args_size'.  */
+/* #define OUTGOING_REG_PARM_STACK_SPACE */
+
+/* Define this macro if `REG_PARM_STACK_SPACE' is defined, but the stack
+   parameters don't skip the area specified by it.
+
+   Normally, when a parameter is not passed in registers, it is placed on the
+   stack beyond the `REG_PARM_STACK_SPACE' area.  Defining this macro
+   suppresses this behavior and causes the parameter to be passed on the stack
+   in its natural location.  */
+/* #define STACK_PARMS_IN_REG_PARM_AREA */
+
+/* A C expression that should indicate the number of bytes of its own arguments
+   that a function pops on returning, or 0 if the function pops no arguments
+   and the caller must therefore pop them all after the function returns.
+
+   FUNDECL is a C variable whose value is a tree node that describes the
+   function in question.  Normally it is a node of type `FUNCTION_DECL' that
+   describes the declaration of the function.  From this it is possible to
+   obtain the DECL_MACHINE_ATTRIBUTES of the function.
+
+   FUNTYPE is a C variable whose value is a tree node that describes the
+   function in question.  Normally it is a node of type `FUNCTION_TYPE' that
+   describes the data type of the function.  From this it is possible to obtain
+   the data types of the value and arguments (if known).
+
+   When a call to a library function is being considered, FUNTYPE will contain
+   an identifier node for the library function.  Thus, if you need to
+   distinguish among various library functions, you can do so by their names.
+   Note that "library function" in this context means a function used to
+   perform arithmetic, whose name is known specially in the compiler and was
+   not mentioned in the C code being compiled.
+
+   STACK-SIZE is the number of bytes of arguments passed on the stack.  If a
+   variable number of bytes is passed, it is zero, and argument popping will
+   always be the responsibility of the calling function.
+
+   On the Vax, all functions always pop their arguments, so the definition of
+   this macro is STACK-SIZE.  On the 68000, using the standard calling
+   convention, no functions pop their arguments, so the value of the macro is
+   always 0 in this case.  But an alternative calling convention is available
+   in which functions that take a fixed number of arguments pop them but other
+   functions (such as `printf') pop nothing (the caller pops all).  When this
+   convention is in use, FUNTYPE is examined to determine whether a function
+   takes a fixed number of arguments.  */
+#define RETURN_POPS_ARGS(FUNDECL, FUNTYPE, STACK_SIZE) 0
+
+\f
+/* Function Arguments in Registers */
+
+/* A C expression that controls whether a function argument is passed in a
+   register, and which register.
+
+   The arguments are CUM, which summarizes all the previous arguments; MODE,
+   the machine mode of the argument; TYPE, the data type of the argument as a
+   tree node or 0 if that is not known (which happens for C support library
+   functions); and NAMED, which is 1 for an ordinary argument and 0 for
+   nameless arguments that correspond to `...' in the called function's
+   prototype.
+
+   The value of the expression should either be a `reg' RTX for the hard
+   register in which to pass the argument, or zero to pass the argument on the
+   stack.
+
+   For machines like the Vax and 68000, where normally all arguments are
+   pushed, zero suffices as a definition.
+
+   The usual way to make the ANSI library `stdarg.h' work on a machine where
+   some arguments are usually passed in registers, is to cause nameless
+   arguments to be passed on the stack instead.  This is done by making
+   `FUNCTION_ARG' return 0 whenever NAMED is 0.
+
+   You may use the macro `MUST_PASS_IN_STACK (MODE, TYPE)' in the definition of
+   this macro to determine if this argument is of a type that must be passed in
+   the stack.  If `REG_PARM_STACK_SPACE' is not defined and `FUNCTION_ARG'
+   returns non-zero for such an argument, the compiler will abort.  If
+   `REG_PARM_STACK_SPACE' is defined, the argument will be computed in the
+   stack and then loaded into a register.  */
+
+#define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) \
+  d30v_function_arg (&CUM, (int)MODE, TYPE, NAMED, FALSE)
+
+/* Define this macro if the target machine has "register windows", so that the
+   register in which a function sees an arguments is not necessarily the same
+   as the one in which the caller passed the argument.
+
+   For such machines, `FUNCTION_ARG' computes the register in which the caller
+   passes the value, and `FUNCTION_INCOMING_ARG' should be defined in a similar
+   fashion to tell the function being called where the arguments will arrive.
+
+   If `FUNCTION_INCOMING_ARG' is not defined, `FUNCTION_ARG' serves both
+   purposes.  */
+
+#define FUNCTION_INCOMING_ARG(CUM, MODE, TYPE, NAMED) \
+  d30v_function_arg (&CUM, (int)MODE, TYPE, NAMED, TRUE)
+
+/* A C expression for the number of words, at the beginning of an argument,
+   must be put in registers.  The value must be zero for arguments that are
+   passed entirely in registers or that are entirely pushed on the stack.
+
+   On some machines, certain arguments must be passed partially in registers
+   and partially in memory.  On these machines, typically the first N words of
+   arguments are passed in registers, and the rest on the stack.  If a
+   multi-word argument (a `double' or a structure) crosses that boundary, its
+   first few words must be passed in registers and the rest must be pushed.
+   This macro tells the compiler when this occurs, and how many of the words
+   should go in registers.
+
+   `FUNCTION_ARG' for these arguments should return the first register to be
+   used by the caller for this argument; likewise `FUNCTION_INCOMING_ARG', for
+   the called function.  */
+#define FUNCTION_ARG_PARTIAL_NREGS(CUM, MODE, TYPE, NAMED) \
+  d30v_function_arg_partial_nregs (&CUM, (int)MODE, TYPE, NAMED)
+
+/* A C expression that indicates when an argument must be passed by reference.
+   If nonzero for an argument, a copy of that argument is made in memory and a
+   pointer to the argument is passed instead of the argument itself.  The
+   pointer is passed in whatever way is appropriate for passing a pointer to
+   that type.
+
+   On machines where `REG_PARM_STACK_SPACE' is not defined, a suitable
+   definition of this macro might be
+        #define FUNCTION_ARG_PASS_BY_REFERENCE\
+        (CUM, MODE, TYPE, NAMED)  \
+          MUST_PASS_IN_STACK (MODE, TYPE)  */
+#define FUNCTION_ARG_PASS_BY_REFERENCE(CUM, MODE, TYPE, NAMED) 0
+
+/* If defined, a C expression that indicates when it is more
+   desirable to keep an argument passed by invisible reference as a
+   reference, rather than copying it to a pseudo register.  */
+/* #define FUNCTION_ARG_KEEP_AS_REFERENCE(CUM, MODE, TYPE, NAMED) */
+
+/* If defined, a C expression that indicates when it is the called function's
+   responsibility to make a copy of arguments passed by invisible reference.
+   Normally, the caller makes a copy and passes the address of the copy to the
+   routine being called.  When FUNCTION_ARG_CALLEE_COPIES is defined and is
+   nonzero, the caller does not make a copy.  Instead, it passes a pointer to
+   the "live" value.  The called function must not modify this value.  If it
+   can be determined that the value won't be modified, it need not make a copy;
+   otherwise a copy must be made.  */
+/* #define FUNCTION_ARG_CALLEE_COPIES(CUM, MODE, TYPE, NAMED) */
+
+/* If defined, a C expression that indicates when it is more desirable to keep
+   an argument passed by invisible reference as a reference, rather than
+   copying it to a pseudo register.  */
+/* #define FUNCTION_ARG_KEEP_AS_REFERENCE(CUM, MODE, TYPE, NAMED) */
+
+/* A C type for declaring a variable that is used as the first argument of
+   `FUNCTION_ARG' and other related values.  For some target machines, the type
+   `int' suffices and can hold the number of bytes of argument so far.
+
+   There is no need to record in `CUMULATIVE_ARGS' anything about the arguments
+   that have been passed on the stack.  The compiler has other variables to
+   keep track of that.  For target machines on which all arguments are passed
+   on the stack, there is no need to store anything in `CUMULATIVE_ARGS';
+   however, the data structure must exist and should not be empty, so use
+   `int'.  */
+typedef int CUMULATIVE_ARGS;
+
+/* A C statement (sans semicolon) for initializing the variable CUM for the
+   state at the beginning of the argument list.  The variable has type
+   `CUMULATIVE_ARGS'.  The value of FNTYPE is the tree node for the data type
+   of the function which will receive the args, or 0 if the args are to a
+   compiler support library function.  The value of INDIRECT is nonzero when
+   processing an indirect call, for example a call through a function pointer.
+   The value of INDIRECT is zero for a call to an explicitly named function, a
+   library function call, or when `INIT_CUMULATIVE_ARGS' is used to find
+   arguments for the function being compiled.
+
+   When processing a call to a compiler support library function, LIBNAME
+   identifies which one.  It is a `symbol_ref' rtx which contains the name of
+   the function, as a string.  LIBNAME is 0 when an ordinary C function call is
+   being processed.  Thus, each time this macro is called, either LIBNAME or
+   FNTYPE is nonzero, but never both of them at once.  */
+
+#define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, INDIRECT) \
+  d30v_init_cumulative_args (&CUM, FNTYPE, LIBNAME, INDIRECT, FALSE)
+
+/* Like `INIT_CUMULATIVE_ARGS' but overrides it for the purposes of finding the
+   arguments for the function being compiled.  If this macro is undefined,
+   `INIT_CUMULATIVE_ARGS' is used instead.
+
+   The value passed for LIBNAME is always 0, since library routines with
+   special calling conventions are never compiled with GNU CC.  The argument
+   LIBNAME exists for symmetry with `INIT_CUMULATIVE_ARGS'.  */
+
+#define INIT_CUMULATIVE_INCOMING_ARGS(CUM, FNTYPE, LIBNAME) \
+  d30v_init_cumulative_args (&CUM, FNTYPE, LIBNAME, FALSE, TRUE)
+
+/* A C statement (sans semicolon) to update the summarizer variable CUM to
+   advance past an argument in the argument list.  The values MODE, TYPE and
+   NAMED describe that argument.  Once this is done, the variable CUM is
+   suitable for analyzing the *following* argument with `FUNCTION_ARG', etc.
+
+   This macro need not do anything if the argument in question was passed on
+   the stack.  The compiler knows how to track the amount of stack space used
+   for arguments without any special help.  */
+
+#define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED) \
+  d30v_function_arg_advance (&CUM, (int) MODE, TYPE, NAMED)
+
+/* If defined, a C expression which determines whether, and in which direction,
+   to pad out an argument with extra space.  The value should be of type `enum
+   direction': either `upward' to pad above the argument, `downward' to pad
+   below, or `none' to inhibit padding.
+
+   The *amount* of padding is always just enough to reach the next multiple of
+   `FUNCTION_ARG_BOUNDARY'; this macro does not control it.
+
+   This macro has a default definition which is right for most systems.  For
+   little-endian machines, the default is to pad upward.  For big-endian
+   machines, the default is to pad downward for an argument of constant size
+   shorter than an `int', and upward otherwise.  */
+/* #define FUNCTION_ARG_PADDING(MODE, TYPE) */
+
+/* If defined, a C expression that gives the alignment boundary, in bits, of an
+   argument with the specified mode and type.  If it is not defined,
+   `PARM_BOUNDARY' is used for all arguments.  */
+
+#define FUNCTION_ARG_BOUNDARY(MODE, TYPE) \
+  d30v_function_arg_boundary ((int) MODE, TYPE)
+
+/* A C expression that is nonzero if REGNO is the number of a hard register in
+   which function arguments are sometimes passed.  This does *not* include
+   implicit arguments such as the static chain and the structure-value address.
+   On many machines, no registers can be used for this purpose since all
+   function arguments are pushed on the stack.  */
+
+#define FUNCTION_ARG_REGNO_P(REGNO) \
+  IN_RANGE_P (REGNO, GPR_ARG_FIRST, GPR_ARG_LAST)
+
+\f
+/* How Scalar Function Values are Returned */
+
+/* Define this macro if `-traditional' should not cause functions declared to
+   return `float' to convert the value to `double'.  */ /* #define
+   TRADITIONAL_RETURN_FLOAT */
+
+/* A C expression to create an RTX representing the place where a function
+   returns a value of data type VALTYPE.  VALTYPE is a tree node representing a
+   data type.  Write `TYPE_MODE (VALTYPE)' to get the machine mode used to
+   represent that type.  On many machines, only the mode is relevant.
+   (Actually, on most machines, scalar values are returned in the same place
+   regardless of mode).
+
+   If `PROMOTE_FUNCTION_RETURN' is defined, you must apply the same promotion
+   rules specified in `PROMOTE_MODE' if VALTYPE is a scalar type.
+
+   If the precise function being called is known, FUNC is a tree node
+   (`FUNCTION_DECL') for it; otherwise, FUNC is a null pointer.  This makes it
+   possible to use a different value-returning convention for specific
+   functions when all their calls are known.
+
+   `FUNCTION_VALUE' is not used for return vales with aggregate data types,
+   because these are returned in another way.  See `STRUCT_VALUE_REGNUM' and
+   related macros, below.  */
+
+#define FUNCTION_VALUE(VALTYPE, FUNC) \
+  gen_rtx (REG, TYPE_MODE (VALTYPE), GPR_RET_VALUE)
+
+/* Define this macro if the target machine has "register windows" so that the
+   register in which a function returns its value is not the same as the one in
+   which the caller sees the value.
+
+   For such machines, `FUNCTION_VALUE' computes the register in which the
+   caller will see the value.  `FUNCTION_OUTGOING_VALUE' should be defined in a
+   similar fashion to tell the function where to put the value.
+
+   If `FUNCTION_OUTGOING_VALUE' is not defined, `FUNCTION_VALUE' serves both
+   purposes.
+
+   `FUNCTION_OUTGOING_VALUE' is not used for return vales with aggregate data
+   types, because these are returned in another way.  See `STRUCT_VALUE_REGNUM'
+   and related macros, below.  */
+/* #define FUNCTION_OUTGOING_VALUE(VALTYPE, FUNC) */
+
+/* A C expression to create an RTX representing the place where a library
+   function returns a value of mode MODE.  If the precise function being called
+   is known, FUNC is a tree node (`FUNCTION_DECL') for it; otherwise, FUNC is a
+   null pointer.  This makes it possible to use a different value-returning
+   convention for specific functions when all their calls are known.
+
+   Note that "library function" in this context means a compiler support
+   routine, used to perform arithmetic, whose name is known specially by the
+   compiler and was not mentioned in the C code being compiled.
+
+   The definition of `LIBRARY_VALUE' need not be concerned aggregate data
+   types, because none of the library functions returns such types.  */
+
+#define LIBCALL_VALUE(MODE) gen_rtx (REG, MODE, GPR_RET_VALUE)
+
+/* A C expression that is nonzero if REGNO is the number of a hard register in
+   which the values of called function may come back.
+
+   A register whose use for returning values is limited to serving as the
+   second of a pair (for a value of type `double', say) need not be recognized
+   by this macro.  So for most machines, this definition suffices:
+
+        #define FUNCTION_VALUE_REGNO_P(N) ((N) == 0)
+
+   If the machine has register windows, so that the caller and the called
+   function use different registers for the return value, this macro should
+   recognize only the caller's register numbers.  */
+
+#define FUNCTION_VALUE_REGNO_P(REGNO) ((REGNO) == GPR_RET_VALUE)
+
+/* Define this macro if `untyped_call' and `untyped_return' need more space
+   than is implied by `FUNCTION_VALUE_REGNO_P' for saving and restoring an
+   arbitrary return value.  */
+/* #define APPLY_RESULT_SIZE */
+
+\f
+/* How Large Values are Returned */
+
+/* A C expression which can inhibit the returning of certain function values in
+   registers, based on the type of value.  A nonzero value says to return the
+   function value in memory, just as large structures are always returned.
+   Here TYPE will be a C expression of type `tree', representing the data type
+   of the value.
+
+   Note that values of mode `BLKmode' must be explicitly handled by this macro.
+   Also, the option `-fpcc-struct-return' takes effect regardless of this
+   macro.  On most systems, it is possible to leave the macro undefined; this
+   causes a default definition to be used, whose value is the constant 1 for
+   `BLKmode' values, and 0 otherwise.
+
+   Do not use this macro to indicate that structures and unions should always
+   be returned in memory.  You should instead use `DEFAULT_PCC_STRUCT_RETURN'
+   to indicate this.  */
+/* #define RETURN_IN_MEMORY(TYPE) */
+
+/* Define this macro to be 1 if all structure and union return values must be
+   in memory.  Since this results in slower code, this should be defined only
+   if needed for compatibility with other compilers or with an ABI.  If you
+   define this macro to be 0, then the conventions used for structure and union
+   return values are decided by the `RETURN_IN_MEMORY' macro.
+
+   If not defined, this defaults to the value 1.  */
+/* #define DEFAULT_PCC_STRUCT_RETURN */
+
+/* If the structure value address is passed in a register, then
+   `STRUCT_VALUE_REGNUM' should be the number of that register.  */
+
+#define STRUCT_VALUE_REGNUM GPR_ARG_FIRST
+
+/* If the structure value address is not passed in a register, define
+   `STRUCT_VALUE' as an expression returning an RTX for the place where the
+   address is passed.  If it returns 0, the address is passed as an "invisible"
+   first argument.  */
+
+#define STRUCT_VALUE 0
+
+/* On some architectures the place where the structure value address is found
+   by the called function is not the same place that the caller put it.  This
+   can be due to register windows, or it could be because the function prologue
+   moves it to a different place.
+
+   If the incoming location of the structure value address is in a register,
+   define this macro as the register number.  */
+/* #define STRUCT_VALUE_INCOMING_REGNUM */
+
+/* If the incoming location is not a register, then you should define
+   `STRUCT_VALUE_INCOMING' as an expression for an RTX for where the called
+   function should find the value.  If it should find the value on the stack,
+   define this to create a `mem' which refers to the frame pointer.  A
+   definition of 0 means that the address is passed as an "invisible" first
+   argument.  */
+/* #define STRUCT_VALUE_INCOMING */
+
+/* Define this macro if the usual system convention on the target machine for
+   returning structures and unions is for the called function to return the
+   address of a static variable containing the value.
+
+   Do not define this if the usual system convention is for the caller to pass
+   an address to the subroutine.
+
+   This macro has effect in `-fpcc-struct-return' mode, but it does nothing
+   when you use `-freg-struct-return' mode.  */
+/* #define PCC_STATIC_STRUCT_RETURN */
+
+\f
+/* Caller-Saves Register Allocation */
+
+/* Define this macro if function calls on the target machine do not preserve
+   any registers; in other words, if `CALL_USED_REGISTERS' has 1 for all
+   registers.  This macro enables `-fcaller-saves' by default.  Eventually that
+   option will be enabled by default on all machines and both the option and
+   this macro will be eliminated.  */
+/* #define DEFAULT_CALLER_SAVES */
+
+/* A C expression to determine whether it is worthwhile to consider placing a
+   pseudo-register in a call-clobbered hard register and saving and restoring
+   it around each function call.  The expression should be 1 when this is worth
+   doing, and 0 otherwise.
+
+   If you don't define this macro, a default is used which is good on most
+   machines: `4 * CALLS < REFS'.  */
+/* #define CALLER_SAVE_PROFITABLE(REFS, CALLS) */
+
+\f
+/* Function Entry and Exit */
+
+/* A C compound statement that outputs the assembler code for entry to a
+   function.  The prologue is responsible for setting up the stack frame,
+   initializing the frame pointer register, saving registers that must be
+   saved, and allocating SIZE additional bytes of storage for the local
+   variables.  SIZE is an integer.  FILE is a stdio stream to which the
+   assembler code should be output.
+
+   The label for the beginning of the function need not be output by this
+   macro.  That has already been done when the macro is run.
+
+   To determine which registers to save, the macro can refer to the array
+   `regs_ever_live': element R is nonzero if hard register R is used anywhere
+   within the function.  This implies the function prologue should save
+   register R, provided it is not one of the call-used registers.
+   (`FUNCTION_EPILOGUE' must likewise use `regs_ever_live'.)
+
+   On machines that have "register windows", the function entry code does not
+   save on the stack the registers that are in the windows, even if they are
+   supposed to be preserved by function calls; instead it takes appropriate
+   steps to "push" the register stack, if any non-call-used registers are used
+   in the function.
+
+   On machines where functions may or may not have frame-pointers, the function
+   entry code must vary accordingly; it must set up the frame pointer if one is
+   wanted, and not otherwise.  To determine whether a frame pointer is in
+   wanted, the macro can refer to the variable `frame_pointer_needed'.  The
+   variable's value will be 1 at run time in a function that needs a frame
+   pointer.  *Note Elimination::.
+
+   The function entry code is responsible for allocating any stack space
+   required for the function.  This stack space consists of the regions listed
+   below.  In most cases, these regions are allocated in the order listed, with
+   the last listed region closest to the top of the stack (the lowest address
+   if `STACK_GROWS_DOWNWARD' is defined, and the highest address if it is not
+   defined).  You can use a different order for a machine if doing so is more
+   convenient or required for compatibility reasons.  Except in cases where
+   required by standard or by a debugger, there is no reason why the stack
+   layout used by GCC need agree with that used by other compilers for a
+   machine.
+
+      * A region of `current_function_pretend_args_size' bytes of
+        uninitialized space just underneath the first argument
+        arriving on the stack.  (This may not be at the very start of
+        the allocated stack region if the calling sequence has pushed
+        anything else since pushing the stack arguments.  But
+        usually, on such machines, nothing else has been pushed yet,
+        because the function prologue itself does all the pushing.)
+        This region is used on machines where an argument may be
+        passed partly in registers and partly in memory, and, in some
+        cases to support the features in `varargs.h' and `stdargs.h'.
+
+      * An area of memory used to save certain registers used by the
+        function.  The size of this area, which may also include
+        space for such things as the return address and pointers to
+        previous stack frames, is machine-specific and usually
+        depends on which registers have been used in the function.
+        Machines with register windows often do not require a save
+        area.
+
+      * A region of at least SIZE bytes, possibly rounded up to an
+        allocation boundary, to contain the local variables of the
+        function.  On some machines, this region and the save area
+        may occur in the opposite order, with the save area closer to
+        the top of the stack.
+
+      * Optionally, when `ACCUMULATE_OUTGOING_ARGS' is defined, a
+        region of `current_function_outgoing_args_size' bytes to be
+        used for outgoing argument lists of the function.  *Note
+        Stack Arguments::.
+
+   Normally, it is necessary for the macros `FUNCTION_PROLOGUE' and
+   `FUNCTION_EPILOGUE' to treat leaf functions specially.  The C variable
+   `leaf_function' is nonzero for such a function.  */
+
+#define FUNCTION_PROLOGUE(FILE, SIZE) d30v_function_prologue (FILE, SIZE)
+
+/* Define this macro as a C expression that is nonzero if the return
+   instruction or the function epilogue ignores the value of the stack pointer;
+   in other words, if it is safe to delete an instruction to adjust the stack
+   pointer before a return from the function.
+
+   Note that this macro's value is relevant only for functions for which frame
+   pointers are maintained.  It is never safe to delete a final stack
+   adjustment in a function that has no frame pointer, and the compiler knows
+   this regardless of `EXIT_IGNORE_STACK'.  */
+/* #define EXIT_IGNORE_STACK */
+
+/* Define this macro as a C expression that is nonzero for registers
+   are used by the epilogue or the `return' pattern.  The stack and
+   frame pointer registers are already be assumed to be used as
+   needed.  */
+#define EPILOGUE_USES(REGNO)  ((REGNO) == GPR_LINK)
+
+/* A C compound statement that outputs the assembler code for exit from a
+   function.  The epilogue is responsible for restoring the saved registers and
+   stack pointer to their values when the function was called, and returning
+   control to the caller.  This macro takes the same arguments as the macro
+   `FUNCTION_PROLOGUE', and the registers to restore are determined from
+   `regs_ever_live' and `CALL_USED_REGISTERS' in the same way.
+
+   On some machines, there is a single instruction that does all the work of
+   returning from the function.  On these machines, give that instruction the
+   name `return' and do not define the macro `FUNCTION_EPILOGUE' at all.
+
+   Do not define a pattern named `return' if you want the `FUNCTION_EPILOGUE'
+   to be used.  If you want the target switches to control whether return
+   instructions or epilogues are used, define a `return' pattern with a
+   validity condition that tests the target switches appropriately.  If the
+   `return' pattern's validity condition is false, epilogues will be used.
+
+   On machines where functions may or may not have frame-pointers, the function
+   exit code must vary accordingly.  Sometimes the code for these two cases is
+   completely different.  To determine whether a frame pointer is wanted, the
+   macro can refer to the variable `frame_pointer_needed'.  The variable's
+   value will be 1 when compiling a function that needs a frame pointer.
+
+   Normally, `FUNCTION_PROLOGUE' and `FUNCTION_EPILOGUE' must treat leaf
+   functions specially.  The C variable `leaf_function' is nonzero for such a
+   function.  *Note Leaf Functions::.
+
+   On some machines, some functions pop their arguments on exit while others
+   leave that for the caller to do.  For example, the 68020 when given `-mrtd'
+   pops arguments in functions that take a fixed number of arguments.
+
+   Your definition of the macro `RETURN_POPS_ARGS' decides which functions pop
+   their own arguments.  `FUNCTION_EPILOGUE' needs to know what was decided.
+   The variable that is called `current_function_pops_args' is the number of
+   bytes of its arguments that a function should pop.  *Note Scalar Return::.  */
+
+#define FUNCTION_EPILOGUE(FILE, SIZE) d30v_function_epilogue (FILE, SIZE)
+
+/* Define this macro if the function epilogue contains delay slots to which
+   instructions from the rest of the function can be "moved".  The definition
+   should be a C expression whose value is an integer representing the number
+   of delay slots there.  */
+/* #define DELAY_SLOTS_FOR_EPILOGUE */
+
+/* A C expression that returns 1 if INSN can be placed in delay slot number N
+   of the epilogue.
+
+   The argument N is an integer which identifies the delay slot now being
+   considered (since different slots may have different rules of eligibility).
+   It is never negative and is always less than the number of epilogue delay
+   slots (what `DELAY_SLOTS_FOR_EPILOGUE' returns).  If you reject a particular
+   insn for a given delay slot, in principle, it may be reconsidered for a
+   subsequent delay slot.  Also, other insns may (at least in principle) be
+   considered for the so far unfilled delay slot.
+
+   The insns accepted to fill the epilogue delay slots are put in an
+   RTL list made with `insn_list' objects, stored in the variable
+   `current_function_epilogue_delay_list'.  The insn for the first
+   delay slot comes first in the list.  Your definition of the macro
+   `FUNCTION_EPILOGUE' should fill the delay slots by outputting the
+   insns in this list, usually by calling `final_scan_insn'.
+
+   You need not define this macro if you did not define
+   `DELAY_SLOTS_FOR_EPILOGUE'.  */
+/* #define ELIGIBLE_FOR_EPILOGUE_DELAY(INSN, N) */
+
+/* A C compound statement that outputs the assembler code for a thunk function,
+   used to implement C++ virtual function calls with multiple inheritance.  The
+   thunk acts as a wrapper around a virtual function, adjusting the implicit
+   object parameter before handing control off to the real function.
+
+   First, emit code to add the integer DELTA to the location that contains the
+   incoming first argument.  Assume that this argument contains a pointer, and
+   is the one used to pass the `this' pointer in C++.  This is the incoming
+   argument *before* the function prologue, e.g. `%o0' on a sparc.  The
+   addition must preserve the values of all other incoming arguments.
+
+   After the addition, emit code to jump to FUNCTION, which is a
+   `FUNCTION_DECL'.  This is a direct pure jump, not a call, and does not touch
+   the return address.  Hence returning from FUNCTION will return to whoever
+   called the current `thunk'.
+
+   The effect must be as if FUNCTION had been called directly with the adjusted
+   first argument.  This macro is responsible for emitting all of the code for
+   a thunk function; `FUNCTION_PROLOGUE' and `FUNCTION_EPILOGUE' are not
+   invoked.
+
+   The THUNK_FNDECL is redundant.  (DELTA and FUNCTION have already been
+   extracted from it.)  It might possibly be useful on some targets, but
+   probably not.
+
+   If you do not define this macro, the target-independent code in the C++
+   frontend will generate a less efficient heavyweight thunk that calls
+   FUNCTION instead of jumping to it.  The generic approach does not support
+   varargs.  */
+/* #define ASM_OUTPUT_MI_THUNK(FILE, THUNK_FNDECL, DELTA, FUNCTION) */
+
+\f
+/* Generating Code for Profiling.  */
+
+/* A C statement or compound statement to output to FILE some assembler code to
+   call the profiling subroutine `mcount'.  Before calling, the assembler code
+   must load the address of a counter variable into a register where `mcount'
+   expects to find the address.  The name of this variable is `LP' followed by
+   the number LABELNO, so you would generate the name using `LP%d' in a
+   `fprintf'.
+
+   The details of how the address should be passed to `mcount' are determined
+   by your operating system environment, not by GNU CC.  To figure them out,
+   compile a small program for profiling using the system's installed C
+   compiler and look at the assembler code that results.  */
+
+#define FUNCTION_PROFILER(FILE, LABELNO) d30v_function_profiler (FILE, LABELNO)
+
+/* Define this macro if the code for function profiling should come before the
+   function prologue.  Normally, the profiling code comes after.  */
+/* #define PROFILE_BEFORE_PROLOGUE */
+
+/* A C statement or compound statement to output to FILE some assembler code to
+   initialize basic-block profiling for the current object module.  The global
+   compile flag `profile_block_flag' distingishes two profile modes.
+
+   profile_block_flag != 2'
+        Output code to call the subroutine `__bb_init_func' once per
+        object module, passing it as its sole argument the address of
+        a block allocated in the object module.
+
+        The name of the block is a local symbol made with this
+        statement:
+
+             ASM_GENERATE_INTERNAL_LABEL (BUFFER, "LPBX", 0);
+
+        Of course, since you are writing the definition of
+        `ASM_GENERATE_INTERNAL_LABEL' as well as that of this macro,
+        you can take a short cut in the definition of this macro and
+        use the name that you know will result.
+
+        The first word of this block is a flag which will be nonzero
+        if the object module has already been initialized.  So test
+        this word first, and do not call `__bb_init_func' if the flag
+        is nonzero.  BLOCK_OR_LABEL contains a unique number which
+        may be used to generate a label as a branch destination when
+        `__bb_init_func' will not be called.
+
+        Described in assembler language, the code to be output looks
+        like:
+
+               cmp (LPBX0),0
+               bne local_label
+               parameter1 <- LPBX0
+               call __bb_init_func
+             local_label:
+
+   profile_block_flag == 2'
+        Output code to call the subroutine `__bb_init_trace_func' and
+        pass two parameters to it.  The first parameter is the same as
+        for `__bb_init_func'.  The second parameter is the number of
+        the first basic block of the function as given by
+        BLOCK_OR_LABEL.  Note that `__bb_init_trace_func' has to be
+        called, even if the object module has been initialized
+        already.
+
+        Described in assembler language, the code to be output looks
+        like:
+             parameter1 <- LPBX0
+             parameter2 <- BLOCK_OR_LABEL
+             call __bb_init_trace_func  */
+/* #define FUNCTION_BLOCK_PROFILER (FILE, LABELNO) */
+
+/* A C statement or compound statement to output to FILE some assembler code to
+   increment the count associated with the basic block number BLOCKNO.  The
+   global compile flag `profile_block_flag' distingishes two profile modes.
+
+   profile_block_flag != 2'
+        Output code to increment the counter directly.  Basic blocks
+        are numbered separately from zero within each compilation.
+        The count associated with block number BLOCKNO is at index
+        BLOCKNO in a vector of words; the name of this array is a
+        local symbol made with this statement:
+
+             ASM_GENERATE_INTERNAL_LABEL (BUFFER, "LPBX", 2);
+
+        Of course, since you are writing the definition of
+        `ASM_GENERATE_INTERNAL_LABEL' as well as that of this macro,
+        you can take a short cut in the definition of this macro and
+        use the name that you know will result.
+
+        Described in assembler language, the code to be output looks
+        like:
+
+             inc (LPBX2+4*BLOCKNO)
+
+   profile_block_flag == 2'
+        Output code to initialize the global structure `__bb' and
+        call the function `__bb_trace_func', which will increment the
+        counter.
+
+        `__bb' consists of two words.  In the first word, the current
+        basic block number, as given by BLOCKNO, has to be stored.  In
+        the second word, the address of a block allocated in the
+        object module has to be stored.  The address is given by the
+        label created with this statement:
+
+             ASM_GENERATE_INTERNAL_LABEL (BUFFER, "LPBX", 0);
+
+        Described in assembler language, the code to be output looks
+        like:
+             move BLOCKNO -> (__bb)
+             move LPBX0 -> (__bb+4)
+             call __bb_trace_func  */
+/* #define BLOCK_PROFILER(FILE, BLOCKNO) */
+
+/* A C statement or compound statement to output to FILE assembler
+   code to call function `__bb_trace_ret'.  The assembler code should
+   only be output if the global compile flag `profile_block_flag' ==
+   2.  This macro has to be used at every place where code for
+   returning from a function is generated (e.g. `FUNCTION_EPILOGUE').
+   Although you have to write the definition of `FUNCTION_EPILOGUE'
+   as well, you have to define this macro to tell the compiler, that
+   the proper call to `__bb_trace_ret' is produced.  */
+/* #define FUNCTION_BLOCK_PROFILER_EXIT(FILE) */
+
+/* A C statement or compound statement to save all registers, which may be
+   clobbered by a function call, including condition codes.  The `asm'
+   statement will be mostly likely needed to handle this task.  Local labels in
+   the assembler code can be concatenated with the string ID, to obtain a
+   unique lable name.
+
+   Registers or condition codes clobbered by `FUNCTION_PROLOGUE' or
+   `FUNCTION_EPILOGUE' must be saved in the macros `FUNCTION_BLOCK_PROFILER',
+   `FUNCTION_BLOCK_PROFILER_EXIT' and `BLOCK_PROFILER' prior calling
+   `__bb_init_trace_func', `__bb_trace_ret' and `__bb_trace_func' respectively.  */
+/* #define MACHINE_STATE_SAVE(ID) */
+
+/* A C statement or compound statement to restore all registers, including
+   condition codes, saved by `MACHINE_STATE_SAVE'.
+
+   Registers or condition codes clobbered by `FUNCTION_PROLOGUE' or
+   `FUNCTION_EPILOGUE' must be restored in the macros
+   `FUNCTION_BLOCK_PROFILER', `FUNCTION_BLOCK_PROFILER_EXIT' and
+   `BLOCK_PROFILER' after calling `__bb_init_trace_func', `__bb_trace_ret' and
+   `__bb_trace_func' respectively.  */
+/* #define MACHINE_STATE_RESTORE(ID) */
+
+/* A C function or functions which are needed in the library to support block
+   profiling.  */
+/* #define BLOCK_PROFILER_CODE */
+
+\f
+/* Implementing the Varargs Macros.  */
+
+/* If defined, is a C expression that produces the machine-specific code for a
+   call to `__builtin_saveregs'.  This code will be moved to the very beginning
+   of the function, before any parameter access are made.  The return value of
+   this function should be an RTX that contains the value to use as the return
+   of `__builtin_saveregs'.
+
+   If this macro is not defined, the compiler will output an ordinary call to
+   the library function `__builtin_saveregs'.  */
+
+#define EXPAND_BUILTIN_SAVEREGS() d30v_expand_builtin_saveregs ()
+
+/* This macro offers an alternative to using `__builtin_saveregs' and defining
+   the macro `EXPAND_BUILTIN_SAVEREGS'.  Use it to store the anonymous register
+   arguments into the stack so that all the arguments appear to have been
+   passed consecutively on the stack.  Once this is done, you can use the
+   standard implementation of varargs that works for machines that pass all
+   their arguments on the stack.
+
+   The argument ARGS_SO_FAR is the `CUMULATIVE_ARGS' data structure, containing
+   the values that obtain after processing of the named arguments.  The
+   arguments MODE and TYPE describe the last named argument--its machine mode
+   and its data type as a tree node.
+
+   The macro implementation should do two things: first, push onto the stack
+   all the argument registers *not* used for the named arguments, and second,
+   store the size of the data thus pushed into the `int'-valued variable whose
+   name is supplied as the argument PRETEND_ARGS_SIZE.  The value that you
+   store here will serve as additional offset for setting up the stack frame.
+
+   Because you must generate code to push the anonymous arguments at compile
+   time without knowing their data types, `SETUP_INCOMING_VARARGS' is only
+   useful on machines that have just a single category of argument register and
+   use it uniformly for all data types.
+
+   If the argument SECOND_TIME is nonzero, it means that the arguments of the
+   function are being analyzed for the second time.  This happens for an inline
+   function, which is not actually compiled until the end of the source file.
+   The macro `SETUP_INCOMING_VARARGS' should not generate any instructions in
+   this case.  */
+
+#define SETUP_INCOMING_VARARGS(ARGS_SO_FAR, MODE, TYPE, PRETEND_ARGS_SIZE, SECOND_TIME) \
+  d30v_setup_incoming_varargs (&ARGS_SO_FAR, (int) MODE, TYPE,         \
+                              &PRETEND_ARGS_SIZE, SECOND_TIME)
+
+/* Define this macro if the location where a function argument is passed
+   depends on whether or not it is a named argument.
+
+   This macro controls how the NAMED argument to `FUNCTION_ARG' is set for
+   varargs and stdarg functions.  With this macro defined, the NAMED argument
+   is always true for named arguments, and false for unnamed arguments.  If
+   this is not defined, but `SETUP_INCOMING_VARARGS' is defined, then all
+   arguments are treated as named.  Otherwise, all named arguments except the
+   last are treated as named.  */
+/* #define STRICT_ARGUMENT_NAMING */
+
+/* Build up the stdarg/varargs va_list type tree, assinging it to NODE.  If not
+   defined, it is assumed that va_list is a void * pointer.  */
+
+#define BUILD_VA_LIST_TYPE(VALIST) \
+  (VALIST) = d30v_build_va_list ()
+
+
+/* Implement the stdarg/varargs va_start macro.  STDARG_P is non-zero if this
+   is stdarg.h instead of varargs.h.  VALIST is the tree of the va_list
+   variable to initialize.  NEXTARG is the machine independent notion of the
+   'next' argument after the variable arguments.  If not defined, a standard
+   implementation will be defined that works for arguments passed on the stack.  */
+
+#define EXPAND_BUILTIN_VA_START(STDARG_P, VALIST, NEXTARG)             \
+(d30v_expand_builtin_va_start(STDARG_P, VALIST, NEXTARG))
+
+/* Implement the stdarg/varargs va_arg macro.  VALIST is the variable of type
+   va_list as a tree, TYPE is the type passed to va_arg.  */
+
+#define EXPAND_BUILTIN_VA_ARG(VALIST, TYPE)                            \
+(d30v_expand_builtin_va_arg (VALIST, TYPE))
+
+/* Implement the stdarg/varargs va_end macro.
+   VALIST is the variable of type va_list as a tree.  */
+
+/* #define EXPAND_BUILTIN_VA_END(VALIST) */
+
+
+\f
+/* Trampolines for Nested Functions.  */
+
+/* A C statement to output, on the stream FILE, assembler code for a block of
+   data that contains the constant parts of a trampoline.  This code should not
+   include a label--the label is taken care of automatically.  */
+/* #define TRAMPOLINE_TEMPLATE(FILE) d30v_trampoline_template (FILE) */
+
+/* The name of a subroutine to switch to the section in which the trampoline
+   template is to be placed (*note Sections::.).  The default is a value of
+   `readonly_data_section', which places the trampoline in the section
+   containing read-only data.  */
+/* #define TRAMPOLINE_SECTION */
+
+/* A C expression for the size in bytes of the trampoline, as an integer.  */
+#define TRAMPOLINE_SIZE (d30v_trampoline_size ())
+
+/* Alignment required for trampolines, in bits.
+
+   If you don't define this macro, the value of `BIGGEST_ALIGNMENT' is used for
+   aligning trampolines.  */
+#define TRAMPOLINE_ALIGNMENT 64
+
+/* A C statement to initialize the variable parts of a trampoline.  ADDR is an
+   RTX for the address of the trampoline; FNADDR is an RTX for the address of
+   the nested function; STATIC_CHAIN is an RTX for the static chain value that
+   should be passed to the function when it is called.  */
+#define INITIALIZE_TRAMPOLINE(ADDR, FNADDR, STATIC_CHAIN) \
+  d30v_initialize_trampoline (ADDR, FNADDR, STATIC_CHAIN)
+
+/* A C expression to allocate run-time space for a trampoline.  The expression
+   value should be an RTX representing a memory reference to the space for the
+   trampoline.
+
+   If this macro is not defined, by default the trampoline is allocated as a
+   stack slot.  This default is right for most machines.  The exceptions are
+   machines where it is impossible to execute instructions in the stack area.
+   On such machines, you may have to implement a separate stack, using this
+   macro in conjunction with `FUNCTION_PROLOGUE' and `FUNCTION_EPILOGUE'.
+
+   FP points to a data structure, a `struct function', which describes the
+   compilation status of the immediate containing function of the function
+   which the trampoline is for.  Normally (when `ALLOCATE_TRAMPOLINE' is not
+   defined), the stack slot for the trampoline is in the stack frame of this
+   containing function.  Other allocation strategies probably must do something
+   analogous with this information.  */
+/* #define ALLOCATE_TRAMPOLINE(FP) */
+
+/* Implementing trampolines is difficult on many machines because they have
+   separate instruction and data caches.  Writing into a stack location fails
+   to clear the memory in the instruction cache, so when the program jumps to
+   that location, it executes the old contents.
+
+   Here are two possible solutions.  One is to clear the relevant parts of the
+   instruction cache whenever a trampoline is set up.  The other is to make all
+   trampolines identical, by having them jump to a standard subroutine.  The
+   former technique makes trampoline execution faster; the latter makes
+   initialization faster.
+
+   To clear the instruction cache when a trampoline is initialized, define the
+   following macros which describe the shape of the cache.  */
+
+/* The total size in bytes of the cache.  */
+/* #define INSN_CACHE_SIZE */
+
+/* The length in bytes of each cache line.  The cache is divided into cache
+   lines which are disjoint slots, each holding a contiguous chunk of data
+   fetched from memory.  Each time data is brought into the cache, an entire
+   line is read at once.  The data loaded into a cache line is always aligned
+   on a boundary equal to the line size.  */
+/* #define INSN_CACHE_LINE_WIDTH */
+
+/* The number of alternative cache lines that can hold any particular memory
+   location.  */
+/* #define INSN_CACHE_DEPTH */
+
+/* Alternatively, if the machine has system calls or instructions to clear the
+   instruction cache directly, you can define the following macro.  */
+
+/* If defined, expands to a C expression clearing the *instruction cache* in
+   the specified interval.  If it is not defined, and the macro INSN_CACHE_SIZE
+   is defined, some generic code is generated to clear the cache.  The
+   definition of this macro would typically be a series of `asm' statements.
+   Both BEG and END are both pointer expressions.  */
+/* #define CLEAR_INSN_CACHE (BEG, END) */
+
+/* To use a standard subroutine, define the following macro.  In addition, you
+   must make sure that the instructions in a trampoline fill an entire cache
+   line with identical instructions, or else ensure that the beginning of the
+   trampoline code is always aligned at the same point in its cache line.  Look
+   in `m68k.h' as a guide.  */
+
+/* Define this macro if trampolines need a special subroutine to do their work.
+   The macro should expand to a series of `asm' statements which will be
+   compiled with GNU CC.  They go in a library function named
+   `__transfer_from_trampoline'.
+
+   If you need to avoid executing the ordinary prologue code of a compiled C
+   function when you jump to the subroutine, you can do so by placing a special
+   label of your own in the assembler code.  Use one `asm' statement to
+   generate an assembler label, and another to make the label global.  Then
+   trampolines can use that label to jump directly to your special assembler
+   code.  */
+/* #define TRANSFER_FROM_TRAMPOLINE */
+
+\f
+/* Implicit Calls to Library Routines */
+
+/* A C string constant giving the name of the function to call for
+   multiplication of one signed full-word by another.  If you do not define
+   this macro, the default name is used, which is `__mulsi3', a function
+   defined in `libgcc.a'.  */
+/* #define MULSI3_LIBCALL */
+
+/* A C string constant giving the name of the function to call for division of
+   one signed full-word by another.  If you do not define this macro, the
+   default name is used, which is `__divsi3', a function defined in `libgcc.a'.  */
+/* #define DIVSI3_LIBCALL */
+
+/* A C string constant giving the name of the function to call for division of
+   one unsigned full-word by another.  If you do not define this macro, the
+   default name is used, which is `__udivsi3', a function defined in
+   `libgcc.a'.  */
+/* #define UDIVSI3_LIBCALL */
+
+/* A C string constant giving the name of the function to call for the
+   remainder in division of one signed full-word by another.  If you do not
+   define this macro, the default name is used, which is `__modsi3', a function
+   defined in `libgcc.a'.  */
+/* #define MODSI3_LIBCALL */
+
+/* A C string constant giving the name of the function to call for the
+   remainder in division of one unsigned full-word by another.  If you do not
+   define this macro, the default name is used, which is `__umodsi3', a
+   function defined in `libgcc.a'.  */
+/* #define UMODSI3_LIBCALL */
+
+/* A C string constant giving the name of the function to call for
+   multiplication of one signed double-word by another.  If you do not define
+   this macro, the default name is used, which is `__muldi3', a function
+   defined in `libgcc.a'.  */
+/* #define MULDI3_LIBCALL */
+
+/* A C string constant giving the name of the function to call for division of
+   one signed double-word by another.  If you do not define this macro, the
+   default name is used, which is `__divdi3', a function defined in `libgcc.a'.  */
+/* #define DIVDI3_LIBCALL */
+
+/* A C string constant giving the name of the function to call for division of
+   one unsigned full-word by another.  If you do not define this macro, the
+   default name is used, which is `__udivdi3', a function defined in
+   `libgcc.a'.  */
+/* #define UDIVDI3_LIBCALL */
+
+/* A C string constant giving the name of the function to call for the
+   remainder in division of one signed double-word by another.  If you do not
+   define this macro, the default name is used, which is `__moddi3', a function
+   defined in `libgcc.a'.  */
+/* #define MODDI3_LIBCALL */
+
+/* A C string constant giving the name of the function to call for the
+   remainder in division of one unsigned full-word by another.  If you do not
+   define this macro, the default name is used, which is `__umoddi3', a
+   function defined in `libgcc.a'.  */
+/* #define UMODDI3_LIBCALL */
+
+/* Define this macro as a C statement that declares additional library routines
+   renames existing ones. `init_optabs' calls this macro after initializing all
+   the normal library routines.  */
+/* #define INIT_TARGET_OPTABS */
+
+/* The value of `EDOM' on the target machine, as a C integer constant
+   expression.  If you don't define this macro, GNU CC does not attempt to
+   deposit the value of `EDOM' into `errno' directly.  Look in
+   `/usr/include/errno.h' to find the value of `EDOM' on your system.
+
+   If you do not define `TARGET_EDOM', then compiled code reports domain errors
+   by calling the library function and letting it report the error.  If
+   mathematical functions on your system use `matherr' when there is an error,
+   then you should leave `TARGET_EDOM' undefined so that `matherr' is used
+   normally.  */
+/* #define TARGET_EDOM */
+
+/* Define this macro as a C expression to create an rtl expression that refers
+   to the global "variable" `errno'.  (On certain systems, `errno' may not
+   actually be a variable.)  If you don't define this macro, a reasonable
+   default is used.  */
+/* #define GEN_ERRNO_RTX */
+
+/* Define this macro if GNU CC should generate calls to the System V (and ANSI
+   C) library functions `memcpy' and `memset' rather than the BSD functions
+   `bcopy' and `bzero'.
+
+   Defined in svr4.h.  */
+/* #define TARGET_MEM_FUNCTIONS */
+
+/* Define this macro if only `float' arguments cannot be passed to library
+   routines (so they must be converted to `double').  This macro affects both
+   how library calls are generated and how the library routines in `libgcc1.c'
+   accept their arguments.  It is useful on machines where floating and fixed
+   point arguments are passed differently, such as the i860.  */
+/* #define LIBGCC_NEEDS_DOUBLE */
+
+/* Define this macro to override the type used by the library routines to pick
+   up arguments of type `float'.  (By default, they use a union of `float' and
+   `int'.)
+
+   The obvious choice would be `float'--but that won't work with traditional C
+   compilers that expect all arguments declared as `float' to arrive as
+   `double'.  To avoid this conversion, the library routines ask for the value
+   as some other type and then treat it as a `float'.
+
+   On some systems, no other type will work for this.  For these systems, you
+   must use `LIBGCC_NEEDS_DOUBLE' instead, to force conversion of the values
+   `double' before they are passed.  */
+/* #define FLOAT_ARG_TYPE */
+
+/* Define this macro to override the way library routines redesignate a `float'
+   argument as a `float' instead of the type it was passed as.  The default is
+   an expression which takes the `float' field of the union.  */
+/* #define FLOATIFY(PASSED_VALUE) */
+
+/* Define this macro to override the type used by the library routines to
+   return values that ought to have type `float'.  (By default, they use
+   `int'.)
+
+   The obvious choice would be `float'--but that won't work with traditional C
+   compilers gratuitously convert values declared as `float' into `double'.  */
+/* #define FLOAT_VALUE_TYPE */
+
+/* Define this macro to override the way the value of a `float'-returning
+   library routine should be packaged in order to return it.  These functions
+   are actually declared to return type `FLOAT_VALUE_TYPE' (normally `int').
+
+   These values can't be returned as type `float' because traditional C
+   compilers would gratuitously convert the value to a `double'.
+
+   A local variable named `intify' is always available when the macro `INTIFY'
+   is used.  It is a union of a `float' field named `f' and a field named `i'
+   whose type is `FLOAT_VALUE_TYPE' or `int'.
+
+   If you don't define this macro, the default definition works by copying the
+   value through that union.  */
+/* #define INTIFY(FLOAT_VALUE) */
+
+/* Define this macro as the name of the data type corresponding to `SImode' in
+   the system's own C compiler.
+
+   You need not define this macro if that type is `long int', as it usually is.  */
+/* #define nongcc_SI_type */
+
+/* Define this macro as the name of the data type corresponding to the
+   word_mode in the system's own C compiler.
+
+   You need not define this macro if that type is `long int', as it usually is.  */
+/* #define nongcc_word_type */
+
+/* Define these macros to supply explicit C statements to carry out various
+   arithmetic operations on types `float' and `double' in the library routines
+   in `libgcc1.c'.  See that file for a full list of these macros and their
+   arguments.
+
+   On most machines, you don't need to define any of these macros, because the
+   C compiler that comes with the system takes care of doing them.  */
+/* #define perform_... */
+
+/* Define this macro to generate code for Objective C message sending using the
+   calling convention of the NeXT system.  This calling convention involves
+   passing the object, the selector and the method arguments all at once to the
+   method-lookup library function.
+
+   The default calling convention passes just the object and the selector to
+   the lookup function, which returns a pointer to the method.  */
+/* #define NEXT_OBJC_RUNTIME */
+
+\f
+/* Addressing Modes */
+
+/* Define this macro if the machine supports post-increment addressing.  */
+#define HAVE_POST_INCREMENT 1
+
+/* Similar for other kinds of addressing.  */
+/* #define HAVE_PRE_INCREMENT 0 */
+#define HAVE_POST_DECREMENT 1
+/* #define HAVE_PRE_DECREMENT 0 */
+
+/* A C expression that is 1 if the RTX X is a constant which is a valid
+   address.  On most machines, this can be defined as `CONSTANT_P (X)', but a
+   few machines are more restrictive in which constant addresses are supported.
+
+   `CONSTANT_P' accepts integer-values expressions whose values are not
+   explicitly known, such as `symbol_ref', `label_ref', and `high' expressions
+   and `const' arithmetic expressions, in addition to `const_int' and
+   `const_double' expressions.  */
+#define CONSTANT_ADDRESS_P(X) CONSTANT_P (X)
+
+/* A number, the maximum number of registers that can appear in a valid memory
+   address.  Note that it is up to you to specify a value equal to the maximum
+   number that `GO_IF_LEGITIMATE_ADDRESS' would ever accept.  */
+#define MAX_REGS_PER_ADDRESS 2
+
+/* A C compound statement with a conditional `goto LABEL;' executed if X (an
+   RTX) is a legitimate memory address on the target machine for a memory
+   operand of mode MODE.
+
+   It usually pays to define several simpler macros to serve as subroutines for
+   this one.  Otherwise it may be too complicated to understand.
+
+   This macro must exist in two variants: a strict variant and a non-strict
+   one.  The strict variant is used in the reload pass.  It must be defined so
+   that any pseudo-register that has not been allocated a hard register is
+   considered a memory reference.  In contexts where some kind of register is
+   required, a pseudo-register with no hard register must be rejected.
+
+   The non-strict variant is used in other passes.  It must be defined to
+   accept all pseudo-registers in every context where some kind of register is
+   required.
+
+   Compiler source files that want to use the strict variant of this macro
+   define the macro `REG_OK_STRICT'.  You should use an `#ifdef REG_OK_STRICT'
+   conditional to define the strict variant in that case and the non-strict
+   variant otherwise.
+
+   Subroutines to check for acceptable registers for various purposes (one for
+   base registers, one for index registers, and so on) are typically among the
+   subroutines used to define `GO_IF_LEGITIMATE_ADDRESS'.  Then only these
+   subroutine macros need have two variants; the higher levels of macros may be
+   the same whether strict or not.
+
+   Normally, constant addresses which are the sum of a `symbol_ref' and an
+   integer are stored inside a `const' RTX to mark them as constant.
+   Therefore, there is no need to recognize such sums specifically as
+   legitimate addresses.  Normally you would simply recognize any `const' as
+   legitimate.
+
+   Usually `PRINT_OPERAND_ADDRESS' is not prepared to handle constant sums that
+   are not marked with `const'.  It assumes that a naked `plus' indicates
+   indexing.  If so, then you *must* reject such naked constant sums as
+   illegitimate addresses, so that none of them will be given to
+   `PRINT_OPERAND_ADDRESS'.
+
+   On some machines, whether a symbolic address is legitimate depends on the
+   section that the address refers to.  On these machines, define the macro
+   `ENCODE_SECTION_INFO' to store the information into the `symbol_ref', and
+   then check for it here.  When you see a `const', you will have to look
+   inside it to find the `symbol_ref' in order to determine the section.  *Note
+   Assembler Format::.
+
+   The best way to modify the name string is by adding text to the beginning,
+   with suitable punctuation to prevent any ambiguity.  Allocate the new name
+   in `saveable_obstack'.  You will have to modify `ASM_OUTPUT_LABELREF' to
+   remove and decode the added text and output the name accordingly, and define
+   `STRIP_NAME_ENCODING' to access the original name string.
+
+   You can check the information stored here into the `symbol_ref' in the
+   definitions of the macros `GO_IF_LEGITIMATE_ADDRESS' and
+   `PRINT_OPERAND_ADDRESS'.  */
+
+#ifdef REG_OK_STRICT
+#define REG_OK_STRICT_P 1
+#else
+#define REG_OK_STRICT_P 0
+#endif
+
+#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR)                                \
+do {                                                                   \
+    if (d30v_legitimate_address_p ((int)MODE, X, REG_OK_STRICT_P))     \
+      goto ADDR;                                                       \
+} while (0)
+
+/* A C expression that is nonzero if X (assumed to be a `reg' RTX) is valid for
+   use as a base register.  For hard registers, it should always accept those
+   which the hardware permits and reject the others.  Whether the macro accepts
+   or rejects pseudo registers must be controlled by `REG_OK_STRICT' as
+   described above.  This usually requires two variant definitions, of which
+   `REG_OK_STRICT' controls the one actually used.  */
+
+#ifdef REG_OK_STRICT
+#define REG_OK_FOR_BASE_P(X) (GPR_P (REGNO (X)))
+#else
+#define REG_OK_FOR_BASE_P(X) (GPR_OR_PSEUDO_P (REGNO (X)))
+#endif
+
+/* A C expression that is nonzero if X (assumed to be a `reg' RTX) is valid for
+   use as an index register.
+
+   The difference between an index register and a base register is that the
+   index register may be scaled.  If an address involves the sum of two
+   registers, neither one of them scaled, then either one may be labeled the
+   "base" and the other the "index"; but whichever labeling is used must fit
+   the machine's constraints of which registers may serve in each capacity.
+   The compiler will try both labelings, looking for one that is valid, and
+   will reload one or both registers only if neither labeling works.  */
+
+#define REG_OK_FOR_INDEX_P(X) REG_OK_FOR_BASE_P (X)
+
+/* A C compound statement that attempts to replace X with a valid memory
+   address for an operand of mode MODE.  WIN will be a C statement label
+   elsewhere in the code; the macro definition may use
+
+        GO_IF_LEGITIMATE_ADDRESS (MODE, X, WIN);
+
+   to avoid further processing if the address has become legitimate.
+
+   X will always be the result of a call to `break_out_memory_refs', and OLDX
+   will be the operand that was given to that function to produce X.
+
+   The code generated by this macro should not alter the substructure of X.  If
+   it transforms X into a more legitimate form, it should assign X (which will
+   always be a C variable) a new value.
+
+   It is not necessary for this macro to come up with a legitimate address.
+   The compiler has standard ways of doing so in all cases.  In fact, it is
+   safe for this macro to do nothing.  But often a machine-dependent strategy
+   can generate better code.  */
+
+#define LEGITIMIZE_ADDRESS(X, OLDX, MODE, WIN)                         \
+do {                                                                   \
+  rtx y = d30v_legitimize_address (X, OLDX, (int)MODE, REG_OK_STRICT_P); \
+  if (y)                                                               \
+    {                                                                  \
+      X = y;                                                           \
+      GO_IF_LEGITIMATE_ADDRESS (MODE, X, WIN);                         \
+    }                                                                  \
+} while (0)
+
+/* A C statement or compound statement with a conditional `goto LABEL;'
+   executed if memory address X (an RTX) can have different meanings depending
+   on the machine mode of the memory reference it is used for or if the address
+   is valid for some modes but not others.
+
+   Autoincrement and autodecrement addresses typically have mode-dependent
+   effects because the amount of the increment or decrement is the size of the
+   operand being addressed.  Some machines have other mode-dependent addresses.
+   Many RISC machines have no mode-dependent addresses.
+
+   You may assume that ADDR is a valid address for the machine.  */
+
+#define GO_IF_MODE_DEPENDENT_ADDRESS(ADDR, LABEL)                      \
+do {                                                                   \
+  if (d30v_mode_dependent_address_p (ADDR))                            \
+    goto LABEL;                                                                \
+} while (0)                                                            \
+
+/* A C expression that is nonzero if X is a legitimate constant for an
+   immediate operand on the target machine.  You can assume that X satisfies
+   `CONSTANT_P', so you need not check this.  In fact, `1' is a suitable
+   definition for this macro on machines where anything `CONSTANT_P' is valid.  */
+#define LEGITIMATE_CONSTANT_P(X) 1
+
+\f
+/* Condition Code Status */
+
+/* C code for a data type which is used for declaring the `mdep' component of
+   `cc_status'.  It defaults to `int'.
+
+   This macro is not used on machines that do not use `cc0'.  */
+/* #define CC_STATUS_MDEP */
+
+/* A C expression to initialize the `mdep' field to "empty".  The default
+   definition does nothing, since most machines don't use the field anyway.  If
+   you want to use the field, you should probably define this macro to
+   initialize it.
+
+   This macro is not used on machines that do not use `cc0'.  */
+/* #define CC_STATUS_MDEP_INIT */
+
+/* A C compound statement to set the components of `cc_status' appropriately
+   for an insn INSN whose body is EXP.  It is this macro's responsibility to
+   recognize insns that set the condition code as a byproduct of other activity
+   as well as those that explicitly set `(cc0)'.
+
+   This macro is not used on machines that do not use `cc0'.
+
+   If there are insns that do not set the condition code but do alter other
+   machine registers, this macro must check to see whether they invalidate the
+   expressions that the condition code is recorded as reflecting.  For example,
+   on the 68000, insns that store in address registers do not set the condition
+   code, which means that usually `NOTICE_UPDATE_CC' can leave `cc_status'
+   unaltered for such insns.  But suppose that the previous insn set the
+   condition code based on location `a4@(102)' and the current insn stores a
+   new value in `a4'.  Although the condition code is not changed by this, it
+   will no longer be true that it reflects the contents of `a4@(102)'.
+   Therefore, `NOTICE_UPDATE_CC' must alter `cc_status' in this case to say
+   that nothing is known about the condition code value.
+
+   The definition of `NOTICE_UPDATE_CC' must be prepared to deal with the
+   results of peephole optimization: insns whose patterns are `parallel' RTXs
+   containing various `reg', `mem' or constants which are just the operands.
+   The RTL structure of these insns is not sufficient to indicate what the
+   insns actually do.  What `NOTICE_UPDATE_CC' should do when it sees one is
+   just to run `CC_STATUS_INIT'.
+
+   A possible definition of `NOTICE_UPDATE_CC' is to call a function that looks
+   at an attribute (*note Insn Attributes::.) named, for example, `cc'.  This
+   avoids having detailed information about patterns in two places, the `md'
+   file and in `NOTICE_UPDATE_CC'.  */
+/* #define NOTICE_UPDATE_CC(EXP, INSN) */
+
+/* A list of names to be used for additional modes for condition code values in
+   registers (*note Jump Patterns::.).  These names are added to `enum
+   machine_mode' and all have class `MODE_CC'.  By convention, they should
+   start with `CC' and end with `mode'.
+
+   You should only define this macro if your machine does not use `cc0' and
+   only if additional modes are required.  */
+/* #define EXTRA_CC_MODES */
+
+/* Returns a mode from class `MODE_CC' to be used when comparison operation
+   code OP is applied to rtx X and Y.  For example, on the Sparc,
+   `SELECT_CC_MODE' is defined as (see *note Jump Patterns::.  for a
+   description of the reason for this definition)
+
+        #define SELECT_CC_MODE(OP,X,Y) \
+          (GET_MODE_CLASS (GET_MODE (X)) == MODE_FLOAT          \
+           ? ((OP == EQ || OP == NE) ? CCFPmode : CCFPEmode)    \
+           : ((GET_CODE (X) == PLUS || GET_CODE (X) == MINUS    \
+               || GET_CODE (X) == NEG) \
+              ? CC_NOOVmode : CCmode))
+
+   You need not define this macro if `EXTRA_CC_MODES' is not defined.  */
+/* #define SELECT_CC_MODE(OP, X, Y) */
+
+/* One some machines not all possible comparisons are defined, but you can
+   convert an invalid comparison into a valid one.  For example, the Alpha does
+   not have a `GT' comparison, but you can use an `LT' comparison instead and
+   swap the order of the operands.
+
+   On such machines, define this macro to be a C statement to do any required
+   conversions.  CODE is the initial comparison code and OP0 and OP1 are the
+   left and right operands of the comparison, respectively.  You should modify
+   CODE, OP0, and OP1 as required.
+
+   GNU CC will not assume that the comparison resulting from this macro is
+   valid but will see if the resulting insn matches a pattern in the `md' file.
+
+   You need not define this macro if it would never change the comparison code
+   or operands.  */
+/* #define CANONICALIZE_COMPARISON(CODE, OP0, OP1) */
+
+/* A C expression whose value is one if it is always safe to reverse a
+   comparison whose mode is MODE.  If `SELECT_CC_MODE' can ever return MODE for
+   a floating-point inequality comparison, then `REVERSIBLE_CC_MODE (MODE)'
+   must be zero.
+
+   You need not define this macro if it would always returns zero or if the
+   floating-point format is anything other than `IEEE_FLOAT_FORMAT'.  For
+   example, here is the definition used on the Sparc, where floating-point
+   inequality comparisons are always given `CCFPEmode':
+
+        #define REVERSIBLE_CC_MODE(MODE)  ((MODE) != CCFPEmode)  */
+/* #define REVERSIBLE_CC_MODE(MODE) */
+
+\f
+/* Describing Relative Costs of Operations */
+
+/* A part of a C `switch' statement that describes the relative costs of
+   constant RTL expressions.  It must contain `case' labels for expression
+   codes `const_int', `const', `symbol_ref', `label_ref' and `const_double'.
+   Each case must ultimately reach a `return' statement to return the relative
+   cost of the use of that kind of constant value in an expression.  The cost
+   may depend on the precise value of the constant, which is available for
+   examination in X, and the rtx code of the expression in which it is
+   contained, found in OUTER_CODE.
+
+   CODE is the expression code--redundant, since it can be obtained with
+   `GET_CODE (X)'.  */
+
+/* On the d30v, consider operatnds that fit in a short instruction very
+   cheap.  However, at this time, it causes cse to generate incorrect
+   code, so disable it for now.  */
+#if 0
+#define CONST_COSTS(X, CODE, OUTER_CODE)                               \
+  case CONST_INT:                                                      \
+    if (IN_RANGE_P (INTVAL (X), 0, 31))                                        \
+      return 0;                                                                \
+    else if ((OUTER_CODE) == LEU && (OUTER_CODE) == LTU                        \
+            && (OUTER_CODE) == GEU && (OUTER_CODE) == GTU)             \
+      return IN_RANGE_P (INTVAL (X), 32, 63) ? 0 : COSTS_N_INSNS (2);  \
+    else                                                               \
+      return IN_RANGE_P (INTVAL (X), -31, -1) ? 0 : COSTS_N_INSNS (2); \
+  case SYMBOL_REF:                                                     \
+  case LABEL_REF:                                                      \
+  case CONST:                                                          \
+    return COSTS_N_INSNS (2);                                          \
+  case CONST_DOUBLE:                                                   \
+    return COSTS_N_INSNS ((GET_MODE (X) == SFmode) ? 2 : 4);
+#else
+#define CONST_COSTS(X, CODE, OUTER_CODE)
+#endif
+
+/* Like `CONST_COSTS' but applies to nonconstant RTL expressions.  This can be
+   used, for example, to indicate how costly a multiply instruction is.  In
+   writing this macro, you can use the construct `COSTS_N_INSNS (N)' to specify
+   a cost equal to N fast instructions.  OUTER_CODE is the code of the
+   expression in which X is contained.
+
+   This macro is optional; do not define it if the default cost assumptions are
+   adequate for the target machine.  */
+#define RTX_COSTS(X, CODE, OUTER_CODE)                                 \
+  case MULT:                                                           \
+    return COSTS_N_INSNS ((GET_CODE (XEXP (x, 1)) == CONST_INT         \
+                          && exact_log2 (INTVAL (XEXP (x, 1))) >= 0)   \
+                         ? 1 : 2);
+
+/* An expression giving the cost of an addressing mode that contains ADDRESS.
+   If not defined, the cost is computed from the ADDRESS expression and the
+   `CONST_COSTS' values.
+
+   For most CISC machines, the default cost is a good approximation of the true
+   cost of the addressing mode.  However, on RISC machines, all instructions
+   normally have the same length and execution time.  Hence all addresses will
+   have equal costs.
+
+   In cases where more than one form of an address is known, the form with the
+   lowest cost will be used.  If multiple forms have the same, lowest, cost,
+   the one that is the most complex will be used.
+
+   For example, suppose an address that is equal to the sum of a register and a
+   constant is used twice in the same basic block.  When this macro is not
+   defined, the address will be computed in a register and memory references
+   will be indirect through that register.  On machines where the cost of the
+   addressing mode containing the sum is no higher than that of a simple
+   indirect reference, this will produce an additional instruction and possibly
+   require an additional register.  Proper specification of this macro
+   eliminates this overhead for such machines.
+
+   Similar use of this macro is made in strength reduction of loops.
+
+   ADDRESS need not be valid as an address.  In such a case, the cost is not
+   relevant and can be any value; invalid addresses need not be assigned a
+   different cost.
+
+   On machines where an address involving more than one register is as cheap as
+   an address computation involving only one register, defining `ADDRESS_COST'
+   to reflect this can cause two registers to be live over a region of code
+   where only one would have been if `ADDRESS_COST' were not defined in that
+   manner.  This effect should be considered in the definition of this macro.
+   Equivalent costs should probably only be given to addresses with different
+   numbers of registers on machines with lots of registers.
+
+   This macro will normally either not be defined or be defined as a constant.  */
+#define ADDRESS_COST(ADDRESS) 0
+
+/* A C expression for the cost of moving data from a register in class FROM to
+   one in class TO.  The classes are expressed using the enumeration values
+   such as `GENERAL_REGS'.  A value of 4 is the default; other values are
+   interpreted relative to that.
+
+   It is not required that the cost always equal 2 when FROM is the same as TO;
+   on some machines it is expensive to move between registers if they are not
+   general registers.
+
+   If reload sees an insn consisting of a single `set' between two hard
+   registers, and if `REGISTER_MOVE_COST' applied to their classes returns a
+   value of 2, reload does not check to ensure that the constraints of the insn
+   are met.  Setting a cost of other than 2 will allow reload to verify that
+   the constraints are met.  You should do this if the `movM' pattern's
+   constraints do not allow such copying.  */
+
+#define REGISTER_MOVE_COST(FROM, TO)                                   \
+  (((FROM) != GPR_REGS && (FROM) != EVEN_REGS                          \
+   && (TO) != GPR_REGS && (TO) != EVEN_REGS) ? 4 : 2)
+
+/* A C expression for the cost of moving data of mode M between a register and
+   memory.  A value of 2 is the default; this cost is relative to those in
+   `REGISTER_MOVE_COST'.
+
+   If moving between registers and memory is more expensive than between two
+   registers, you should define this macro to express the relative cost.  */
+#define MEMORY_MOVE_COST(M,C,I) 4
+
+/* A C expression for the cost of a branch instruction.  A value of 1 is the
+   default; other values are interpreted relative to that.  */
+
+#define BRANCH_COST d30v_branch_cost
+
+#define D30V_DEFAULT_BRANCH_COST 2
+
+/* Values of the -mbranch-cost=n string.  */
+extern int d30v_branch_cost;
+extern const char *d30v_branch_cost_string;
+
+/* Here are additional macros which do not specify precise relative costs, but
+   only that certain actions are more expensive than GNU CC would ordinarily
+   expect.  */
+
+/* Define this macro as a C expression which is nonzero if accessing less than
+   a word of memory (i.e. a `char' or a `short') is no faster than accessing a
+   word of memory, i.e., if such access require more than one instruction or if
+   there is no difference in cost between byte and (aligned) word loads.
+
+   When this macro is not defined, the compiler will access a field by finding
+   the smallest containing object; when it is defined, a fullword load will be
+   used if alignment permits.  Unless bytes accesses are faster than word
+   accesses, using word accesses is preferable since it may eliminate
+   subsequent memory access if subsequent accesses occur to other fields in the
+   same word of the structure, but to different bytes.  */
+#define SLOW_BYTE_ACCESS 1
+
+/* Define this macro if zero-extension (of a `char' or `short' to an `int') can
+   be done faster if the destination is a register that is known to be zero.
+
+   If you define this macro, you must have instruction patterns that recognize
+   RTL structures like this:
+
+        (set (strict_low_part (subreg:QI (reg:SI ...) 0)) ...)
+
+   and likewise for `HImode'.  */
+#define SLOW_ZERO_EXTEND 0
+
+/* Define this macro to be the value 1 if unaligned accesses have a cost many
+   times greater than aligned accesses, for example if they are emulated in a
+   trap handler.
+
+   When this macro is non-zero, the compiler will act as if `STRICT_ALIGNMENT'
+   were non-zero when generating code for block moves.  This can cause
+   significantly more instructions to be produced.  Therefore, do not set this
+   macro non-zero if unaligned accesses only add a cycle or two to the time for
+   a memory access.
+
+   If the value of this macro is always zero, it need not be defined.  */
+/* #define SLOW_UNALIGNED_ACCESS */
+
+/* Define this macro to inhibit strength reduction of memory addresses.  (On
+   some machines, such strength reduction seems to do harm rather than good.)  */
+/* #define DONT_REDUCE_ADDR */
+
+/* The number of scalar move insns which should be generated instead of a
+   string move insn or a library call.  Increasing the value will always make
+   code faster, but eventually incurs high cost in increased code size.
+
+   If you don't define this, a reasonable default is used.  */
+/* #define MOVE_RATIO */
+
+/* Define this macro if it is as good or better to call a constant function
+   address than to call an address kept in a register.  */
+#define NO_FUNCTION_CSE
+
+/* Define this macro if it is as good or better for a function to call itself
+   with an explicit address than to call an address kept in a register.  */
+/* #define NO_RECURSIVE_FUNCTION_CSE */
+
+/* A C statement (sans semicolon) to update the integer variable COST based on
+   the relationship between INSN that is dependent on DEP_INSN through the
+   dependence LINK.  The default is to make no adjustment to COST.  This can be
+   used for example to specify to the scheduler that an output- or
+   anti-dependence does not incur the same cost as a data-dependence.  */
+
+#define ADJUST_COST(INSN,LINK,DEP_INSN,COST)                           \
+  (COST) = d30v_adjust_cost (INSN, LINK, DEP_INSN, COST)
+
+/* A C statement (sans semicolon) to update the integer scheduling
+   priority `INSN_PRIORITY(INSN)'.  Reduce the priority to execute
+   the INSN earlier, increase the priority to execute INSN later.
+   Do not define this macro if you do not need to adjust the
+   scheduling priorities of insns.  */
+/* #define ADJUST_PRIORITY (INSN) */
+
+/* Macro to determine whether the Haifa scheduler is used.  */
+#ifdef HAIFA
+#define HAIFA_P 1
+#else
+#define HAIFA_P 0
+#endif
+
+\f
+/* Dividing the output into sections.  */
+
+/* A C expression whose value is a string containing the assembler operation
+   that should precede instructions and read-only data.  Normally `".text"' is
+   right.  */
+#define TEXT_SECTION_ASM_OP ".text"
+
+/* A C expression whose value is a string containing the assembler operation to
+   identify the following data as writable initialized data.  Normally
+   `".data"' is right.  */
+#define DATA_SECTION_ASM_OP ".data"
+
+/* if defined, a C expression whose value is a string containing the assembler
+   operation to identify the following data as shared data.  If not defined,
+   `DATA_SECTION_ASM_OP' will be used.  */
+/* #define SHARED_SECTION_ASM_OP */
+
+/* If defined, a C expression whose value is a string containing the
+   assembler operation to identify the following data as
+   uninitialized global data.  If not defined, and neither
+   `ASM_OUTPUT_BSS' nor `ASM_OUTPUT_ALIGNED_BSS' are defined,
+   uninitialized global data will be output in the data section if
+   `-fno-common' is passed, otherwise `ASM_OUTPUT_COMMON' will be
+   used.  */
+#define BSS_SECTION_ASM_OP ".bss"
+
+/* If defined, a C expression whose value is a string containing the
+   assembler operation to identify the following data as
+   uninitialized global shared data.  If not defined, and
+   `BSS_SECTION_ASM_OP' is, the latter will be used.  */
+/* #define SHARED_BSS_SECTION_ASM_OP */
+
+/* A list of names for sections other than the standard two, which are
+   `in_text' and `in_data'.  You need not define this macro on a system with no
+   other sections (that GCC needs to use).
+
+   Defined in svr4.h.  */
+/* #define EXTRA_SECTIONS */
+
+/* One or more functions to be defined in `varasm.c'.  These functions should
+   do jobs analogous to those of `text_section' and `data_section', for your
+   additional sections.  Do not define this macro if you do not define
+   `EXTRA_SECTIONS'.
+
+   Defined in svr4.h.  */
+/* #define EXTRA_SECTION_FUNCTIONS */
+
+/* On most machines, read-only variables, constants, and jump tables are placed
+   in the text section.  If this is not the case on your machine, this macro
+   should be defined to be the name of a function (either `data_section' or a
+   function defined in `EXTRA_SECTIONS') that switches to the section to be
+   used for read-only items.
+
+   If these items should be placed in the text section, this macro should not
+   be defined.  */
+/* #define READONLY_DATA_SECTION */
+
+/* A C statement or statements to switch to the appropriate section for output
+   of EXP.  You can assume that EXP is either a `VAR_DECL' node or a constant
+   of some sort.  RELOC indicates whether the initial value of EXP requires
+   link-time relocations.  Select the section by calling `text_section' or one
+   of the alternatives for other sections.
+
+   Do not define this macro if you put all read-only variables and constants in
+   the read-only data section (usually the text section).
+
+   Defined in svr4.h.  */
+/* #define SELECT_SECTION(EXP, RELOC) */
+
+/* A C statement or statements to switch to the appropriate section for output
+   of RTX in mode MODE.  You can assume that RTX is some kind of constant in
+   RTL.  The argument MODE is redundant except in the case of a `const_int'
+   rtx.  Select the section by calling `text_section' or one of the
+   alternatives for other sections.
+
+   Do not define this macro if you put all constants in the read-only data
+   section.
+
+   Defined in svr4.h.  */
+/* #define SELECT_RTX_SECTION(MODE, RTX) */
+
+/* Define this macro if jump tables (for `tablejump' insns) should be output in
+   the text section, along with the assembler instructions.  Otherwise, the
+   readonly data section is used.
+
+   This macro is irrelevant if there is no separate readonly data section.  */
+/* #define JUMP_TABLES_IN_TEXT_SECTION */
+
+/* Define this macro if references to a symbol must be treated differently
+   depending on something about the variable or function named by the symbol
+   (such as what section it is in).
+
+   The macro definition, if any, is executed immediately after the rtl for DECL
+   has been created and stored in `DECL_RTL (DECL)'.  The value of the rtl will
+   be a `mem' whose address is a `symbol_ref'.
+
+   The usual thing for this macro to do is to record a flag in the `symbol_ref'
+   (such as `SYMBOL_REF_FLAG') or to store a modified name string in the
+   `symbol_ref' (if one bit is not enough information).  */
+/* #define ENCODE_SECTION_INFO(DECL) */
+
+/* Decode SYM_NAME and store the real name part in VAR, sans the characters
+   that encode section info.  Define this macro if `ENCODE_SECTION_INFO' alters
+   the symbol's name string.  */
+/* #define STRIP_NAME_ENCODING(VAR, SYM_NAME) */
+
+/* A C expression which evaluates to true if DECL should be placed
+   into a unique section for some target-specific reason.  If you do
+   not define this macro, the default is `0'.  Note that the flag
+   `-ffunction-sections' will also cause functions to be placed into
+   unique sections.
+
+   Defined in svr4.h.  */
+/* #define UNIQUE_SECTION_P(DECL) */
+
+/* A C statement to build up a unique section name, expressed as a
+   STRING_CST node, and assign it to `DECL_SECTION_NAME (DECL)'.
+   RELOC indicates whether the initial value of EXP requires
+   link-time relocations.  If you do not define this macro, GNU CC
+   will use the symbol name prefixed by `.' as the section name.
+
+   Defined in svr4.h.  */
+/* #define UNIQUE_SECTION(DECL, RELOC) */
+
+\f
+/* Position Independent Code.  */
+
+/* The register number of the register used to address a table of static data
+   addresses in memory.  In some cases this register is defined by a
+   processor's "application binary interface" (ABI).  When this macro is
+   defined, RTL is generated for this register once, as with the stack pointer
+   and frame pointer registers.  If this macro is not defined, it is up to the
+   machine-dependent files to allocate such a register (if necessary).  */
+/* #define PIC_OFFSET_TABLE_REGNUM */
+
+/* Define this macro if the register defined by `PIC_OFFSET_TABLE_REGNUM' is
+   clobbered by calls.  Do not define this macro if `PIC_OFFSET_TABLE_REGNUM'
+   is not defined.  */
+/* #define PIC_OFFSET_TABLE_REG_CALL_CLOBBERED */
+
+/* By generating position-independent code, when two different programs (A and
+   B) share a common library (libC.a), the text of the library can be shared
+   whether or not the library is linked at the same address for both programs.
+   In some of these environments, position-independent code requires not only
+   the use of different addressing modes, but also special code to enable the
+   use of these addressing modes.
+
+   The `FINALIZE_PIC' macro serves as a hook to emit these special codes once
+   the function is being compiled into assembly code, but not before.  (It is
+   not done before, because in the case of compiling an inline function, it
+   would lead to multiple PIC prologues being included in functions which used
+   inline functions and were compiled to assembly language.)  */
+/* #define FINALIZE_PIC */
+
+/* A C expression that is nonzero if X is a legitimate immediate operand on the
+   target machine when generating position independent code.  You can assume
+   that X satisfies `CONSTANT_P', so you need not check this.  You can also
+   assume FLAG_PIC is true, so you need not check it either.  You need not
+   define this macro if all constants (including `SYMBOL_REF') can be immediate
+   operands when generating position independent code.  */
+/* #define LEGITIMATE_PIC_OPERAND_P(X) */
+
+\f
+/* The Overall Framework of an Assembler File.  */
+
+/* A C expression which outputs to the stdio stream STREAM some appropriate
+   text to go at the start of an assembler file.
+
+   Normally this macro is defined to output a line containing `#NO_APP', which
+   is a comment that has no effect on most assemblers but tells the GNU
+   assembler that it can save time by not checking for certain assembler
+   constructs.
+
+   On systems that use SDB, it is necessary to output certain commands; see
+   `attasm.h'.
+
+   Defined in svr4.h.  */
+
+/* #define ASM_FILE_START(STREAM) \
+  output_file_directive ((STREAM), main_input_filename) */
+
+/* A C expression which outputs to the stdio stream STREAM some appropriate
+   text to go at the end of an assembler file.
+
+   If this macro is not defined, the default is to output nothing special at
+   the end of the file.  Most systems don't require any definition.
+
+   On systems that use SDB, it is necessary to output certain commands; see
+   `attasm.h'.
+
+   Defined in svr4.h.  */
+/* #define ASM_FILE_END(STREAM) */
+
+/* A C statement to output assembler commands which will identify the object
+   file as having been compiled with GNU CC (or another GNU compiler).
+
+   If you don't define this macro, the string `gcc_compiled.:' is output.  This
+   string is calculated to define a symbol which, on BSD systems, will never be
+   defined for any other reason.  GDB checks for the presence of this symbol
+   when reading the symbol table of an executable.
+
+   On non-BSD systems, you must arrange communication with GDB in some other
+   fashion.  If GDB is not used on your system, you can define this macro with
+   an empty body.
+
+   Defined in svr4.h.  */
+/* #define ASM_IDENTIFY_GCC(FILE) */
+
+/* Like ASM_IDENTIFY_GCC, but used when dbx debugging is selected to emit
+   a stab the debugger uses to identify gcc as the compiler that is emitted
+   after the stabs for the filename, which makes it easier for GDB to parse.
+
+   Defined in svr4.h.  */
+/* #define ASM_IDENTIFY_GCC_AFTER_SOURCE(FILE) */
+
+/* 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 ";"
+
+/* A C string constant for text to be output before each `asm' statement or
+   group of consecutive ones.  Normally this is `"#APP"', which is a comment
+   that has no effect on most assemblers but tells the GNU assembler that it
+   must check the lines that follow for all valid assembler constructs.  */
+#define ASM_APP_ON "#APP\n"
+
+/* A C string constant for text to be output after each `asm' statement or
+   group of consecutive ones.  Normally this is `"#NO_APP"', which tells the
+   GNU assembler to resume making the time-saving assumptions that are valid
+   for ordinary compiler output.  */
+#define ASM_APP_OFF "#NO_APP\n"
+
+/* A C statement to output COFF information or DWARF debugging information
+   which indicates that filename NAME is the current source file to the stdio
+   stream STREAM.
+
+   This macro need not be defined if the standard form of output for the file
+   format in use is appropriate.  */
+/* #define ASM_OUTPUT_SOURCE_FILENAME(STREAM, NAME) */
+
+/* A C statement to output DBX or SDB debugging information before code for
+   line number LINE of the current source file to the stdio stream STREAM.
+
+   This macro need not be defined if the standard form of debugging information
+   for the debugger in use is appropriate.
+
+   Defined in svr4.h.  */
+/* #define ASM_OUTPUT_SOURCE_LINE(STREAM, LINE) */
+
+/* A C statement to output something to the assembler file to handle a `#ident'
+   directive containing the text STRING.  If this macro is not defined, nothing
+   is output for a `#ident' directive.
+
+   Defined in svr4.h.  */
+/* #define ASM_OUTPUT_IDENT(STREAM, STRING) */
+
+/* A C statement to output something to the assembler file to switch to section
+   NAME for object DECL which is either a `FUNCTION_DECL', a `VAR_DECL' or
+   `NULL_TREE'.  Some target formats do not support arbitrary sections.  Do not
+   define this macro in such cases.
+
+   At present this macro is only used to support section attributes.  When this
+   macro is undefined, section attributes are disabled.
+
+   Defined in svr4.h.  */
+/* #define ASM_OUTPUT_SECTION_NAME(STREAM, DECL, NAME) */
+
+/* A C statement to output any assembler statements which are required to
+   precede any Objective C object definitions or message sending.  The
+   statement is executed only when compiling an Objective C program.  */
+/* #define OBJC_PROLOGUE */
+
+\f
+/* Output of Data.  */
+
+/* A C statement to output to the stdio stream STREAM an assembler instruction
+   to assemble a floating-point constant of `TFmode', `DFmode', `SFmode',
+   `TQFmode', `HFmode', or `QFmode', respectively, whose value is VALUE.  VALUE
+   will be a C expression of type `REAL_VALUE_TYPE'.  Macros such as
+   `REAL_VALUE_TO_TARGET_DOUBLE' are useful for writing these definitions.  */
+
+/* #define ASM_OUTPUT_LONG_DOUBLE(STREAM, VALUE) */
+
+#define ASM_OUTPUT_DOUBLE(FILE, VALUE)                                 \
+  {                                                                    \
+    if (REAL_VALUE_ISINF (VALUE)                                       \
+        || REAL_VALUE_ISNAN (VALUE)                                    \
+       || REAL_VALUE_MINUS_ZERO (VALUE))                               \
+      {                                                                        \
+       long t[2];                                                      \
+       REAL_VALUE_TO_TARGET_DOUBLE ((VALUE), t);                       \
+       fprintf (FILE, "\t.long 0x%lx\n\t.long 0x%lx\n",                \
+               t[0] & 0xffffffff, t[1] & 0xffffffff);                  \
+      }                                                                        \
+    else                                                               \
+      {                                                                        \
+       char str[30];                                                   \
+       REAL_VALUE_TO_DECIMAL (VALUE, "%.20e", str);                    \
+       fprintf (FILE, "\t.double 0d%s\n", str);                        \
+      }                                                                        \
+  }
+
+#define ASM_OUTPUT_FLOAT(FILE, VALUE)                                  \
+  {                                                                    \
+    if (REAL_VALUE_ISINF (VALUE)                                       \
+        || REAL_VALUE_ISNAN (VALUE)                                    \
+       || REAL_VALUE_MINUS_ZERO (VALUE))                               \
+      {                                                                        \
+       long t;                                                         \
+       REAL_VALUE_TO_TARGET_SINGLE ((VALUE), t);                       \
+       fprintf (FILE, "\t.long 0x%lx\n", t & 0xffffffff);              \
+      }                                                                        \
+    else                                                               \
+      {                                                                        \
+       char str[30];                                                   \
+       REAL_VALUE_TO_DECIMAL ((VALUE), "%.20e", str);                  \
+       fprintf (FILE, "\t.float 0d%s\n", str);                         \
+      }                                                                        \
+  }
+
+/* #define ASM_OUTPUT_THREE_QUARTER_FLOAT(STREAM, VALUE) */
+/* #define ASM_OUTPUT_SHORT_FLOAT(STREAM, VALUE) */
+/* #define ASM_OUTPUT_BYTE_FLOAT(STREAM, VALUE) */
+
+/* A C statement to output to the stdio stream STREAM an assembler instruction
+   to assemble an integer of 16, 8, 4, 2 or 1 bytes, respectively, whose value
+   is VALUE.  The argument EXP will be an RTL expression which represents a
+   constant value.  Use `output_addr_const (STREAM, EXP)' to output this value
+   as an assembler expression.
+
+   For sizes larger than `UNITS_PER_WORD', if the action of a macro would be
+   identical to repeatedly calling the macro corresponding to a size of
+   `UNITS_PER_WORD', once for each word, you need not define the macro.  */
+
+/* #define ASM_OUTPUT_QUADRUPLE_INT(STREAM, EXP) */
+/* #define ASM_OUTPUT_DOUBLE_INT(STREAM, EXP) */
+
+#define ASM_OUTPUT_INT(STREAM, EXP)                                    \
+do {                                                                   \
+  fputs ("\t.word ", STREAM);                                          \
+  output_addr_const (STREAM, EXP);                                     \
+  putc ('\n', STREAM);                                                 \
+} while (0)
+
+#define ASM_OUTPUT_SHORT(STREAM, EXP)                                  \
+do {                                                                   \
+  fputs ("\t.hword ", STREAM);                                         \
+  output_addr_const (STREAM, EXP);                                     \
+  putc ('\n', STREAM);                                                 \
+} while (0)
+
+#define ASM_OUTPUT_CHAR(STREAM, EXP)                                   \
+do {                                                                   \
+  fputs ("\t.byte ", STREAM);                                          \
+  output_addr_const (STREAM, EXP);                                     \
+  putc ('\n', STREAM);                                                 \
+} while (0)
+
+/* A C statement to output to the stdio stream STREAM an assembler instruction
+   to assemble a single byte containing the number VALUE.  */
+
+#define ASM_OUTPUT_BYTE(STREAM, VALUE) \
+  fprintf (STREAM, "\t%s %d\n", ASM_BYTE_OP, (int)(VALUE))
+
+/* A C string constant giving the pseudo-op to use for a sequence of
+   single-byte constants.  If this macro is not defined, the default
+   is `"byte"'.
+
+   Defined in svr4.h.  */
+/* #define ASM_BYTE_OP */
+
+/* A C statement to output to the stdio stream STREAM an assembler instruction
+   to assemble a string constant containing the LEN bytes at PTR.  PTR will be
+   a C expression of type `char *' and LEN a C expression of type `int'.
+
+   If the assembler has a `.ascii' pseudo-op as found in the Berkeley Unix
+   assembler, do not define the macro `ASM_OUTPUT_ASCII'.
+
+   Defined in svr4.h.  */
+/* #define ASM_OUTPUT_ASCII(STREAM, PTR, LEN) */
+
+/* You may define this macro as a C expression.  You should define the
+   expression to have a non-zero value if GNU CC should output the
+   constant pool for a function before the code for the function, or
+   a zero value if GNU CC should output the constant pool after the
+   function.  If you do not define this macro, the usual case, GNU CC
+   will output the constant pool before the function.  */
+/* #define CONSTANT_POOL_BEFORE_FUNCTION */
+
+/* A C statement to output assembler commands to define the start of the
+   constant pool for a function.  FUNNAME is a string giving the name of the
+   function.  Should the return type of the function be required, it can be
+   obtained via FUNDECL.  SIZE is the size, in bytes, of the constant pool that
+   will be written immediately after this call.
+
+   If no constant-pool prefix is required, the usual case, this macro need not
+   be defined.  */
+/* #define ASM_OUTPUT_POOL_PROLOGUE(FILE FUNNAME FUNDECL SIZE) */
+
+/* A C statement (with or without semicolon) to output a constant in the
+   constant pool, if it needs special treatment.  (This macro need not do
+   anything for RTL expressions that can be output normally.)
+
+   The argument FILE is the standard I/O stream to output the assembler code
+   on.  X is the RTL expression for the constant to output, and MODE is the
+   machine mode (in case X is a `const_int').  ALIGN is the required alignment
+   for the value X; you should output an assembler directive to force this much
+   alignment.
+
+   The argument LABELNO is a number to use in an internal label for the address
+   of this pool entry.  The definition of this macro is responsible for
+   outputting the label definition at the proper place.  Here is how to do
+   this:
+
+        ASM_OUTPUT_INTERNAL_LABEL (FILE, "LC", LABELNO);
+
+   When you output a pool entry specially, you should end with a `goto' to the
+   label JUMPTO.  This will prevent the same pool entry from being output a
+   second time in the usual manner.
+
+   You need not define this macro if it would do nothing.  */
+/* #define ASM_OUTPUT_SPECIAL_POOL_ENTRY(FILE, X, MODE, ALIGN, LABELNO, JUMPTO) */
+
+/* Define this macro as a C expression which is nonzero if the constant EXP, of
+   type `tree', should be output after the code for a function.  The compiler
+   will normally output all constants before the function; you need not define
+   this macro if this is OK.  */
+/* #define CONSTANT_AFTER_FUNCTION_P(EXP) */
+
+/* A C statement to output assembler commands to at the end of the constant
+   pool for a function.  FUNNAME is a string giving the name of the function.
+   Should the return type of the function be required, you can obtain it via
+   FUNDECL.  SIZE is the size, in bytes, of the constant pool that GNU CC wrote
+   immediately before this call.
+
+   If no constant-pool epilogue is required, the usual case, you need not
+   define this macro.  */
+/* #define ASM_OUTPUT_POOL_EPILOGUE (FILE FUNNAME FUNDECL SIZE) */
+
+/* Define this macro as a C expression which is nonzero if C is used as a
+   logical line separator by the assembler.
+
+   If you do not define this macro, the default is that only the character `;'
+   is treated as a logical line separator.  */
+/* #define IS_ASM_LOGICAL_LINE_SEPARATOR(C) */
+
+/* These macros are defined as C string constant, describing the syntax in the
+   assembler for grouping arithmetic expressions.  The following definitions
+   are correct for most assemblers:
+
+        #define ASM_OPEN_PAREN "("
+        #define ASM_CLOSE_PAREN ")"  */
+#define ASM_OPEN_PAREN "("
+#define ASM_CLOSE_PAREN ")"
+
+/* These macros are provided by `real.h' for writing the definitions of
+   `ASM_OUTPUT_DOUBLE' and the like: */
+
+/* These translate X, of type `REAL_VALUE_TYPE', to the target's floating point
+   representation, and store its bit pattern in the array of `long int' whose
+   address is L.  The number of elements in the output array is determined by
+   the size of the desired target floating point data type: 32 bits of it go in
+   each `long int' array element.  Each array element holds 32 bits of the
+   result, even if `long int' is wider than 32 bits on the host machine.
+
+   The array element values are designed so that you can print them out using
+   `fprintf' in the order they should appear in the target machine's memory.  */
+/* #define REAL_VALUE_TO_TARGET_SINGLE(X, L) */
+/* #define REAL_VALUE_TO_TARGET_DOUBLE(X, L) */
+/* #define REAL_VALUE_TO_TARGET_LONG_DOUBLE(X, L) */
+
+/* This macro converts X, of type `REAL_VALUE_TYPE', to a decimal number and
+   stores it as a string into STRING.  You must pass, as STRING, the address of
+   a long enough block of space to hold the result.
+
+   The argument FORMAT is a `printf'-specification that serves as a suggestion
+   for how to format the output string.  */
+/* #define REAL_VALUE_TO_DECIMAL(X, FORMAT, STRING) */
+
+\f
+/* Output of Uninitialized Variables.  */
+
+/* A C statement (sans semicolon) to output to the stdio stream STREAM the
+   assembler definition of a common-label named NAME whose size is SIZE bytes.
+   The variable ROUNDED is the size rounded up to whatever alignment the caller
+   wants.
+
+   Use the expression `assemble_name (STREAM, NAME)' to output the name itself;
+   before and after that, output the additional assembler syntax for defining
+   the name, and a newline.
+
+   This macro controls how the assembler definitions of uninitialized global
+   variables are output.  */
+/* #define ASM_OUTPUT_COMMON(STREAM, NAME, SIZE, ROUNDED) */
+
+/* Like `ASM_OUTPUT_COMMON' except takes the required alignment as a separate,
+   explicit argument.  If you define this macro, it is used in place of
+   `ASM_OUTPUT_COMMON', and gives you more flexibility in handling the required
+   alignment of the variable.  The alignment is specified as the number of
+   bits.
+
+   Defined in svr4.h.  */
+/* #define ASM_OUTPUT_ALIGNED_COMMON(STREAM, NAME, SIZE, ALIGNMENT) */
+
+/* Like ASM_OUTPUT_ALIGNED_COMMON except that it takes an additional argument -
+   the DECL of the variable to be output, if there is one.  This macro can be
+   called with DECL == NULL_TREE.  If you define this macro, it is used in
+   place of both ASM_OUTPUT_COMMON and ASM_OUTPUT_ALIGNED_COMMON, and gives you
+   more flexibility in handling the destination of the variable.  */
+/* #define ASM_OUTPUT_DECL_COMMON (STREAM, DECL, NAME, SIZE, ALIGNMENT) */
+
+/* If defined, it is similar to `ASM_OUTPUT_COMMON', except that it is used
+   when NAME is shared.  If not defined, `ASM_OUTPUT_COMMON' will be used.  */
+/* #define ASM_OUTPUT_SHARED_COMMON(STREAM, NAME, SIZE, ROUNDED) */
+
+/* A C statement (sans semicolon) to output to the stdio stream STREAM the
+   assembler definition of uninitialized global DECL named NAME whose size is
+   SIZE bytes.  The variable ROUNDED is the size rounded up to whatever
+   alignment the caller wants.
+
+   Try to use function `asm_output_bss' defined in `varasm.c' when defining
+   this macro.  If unable, use the expression `assemble_name (STREAM, NAME)' to
+   output the name itself; before and after that, output the additional
+   assembler syntax for defining the name, and a newline.
+
+   This macro controls how the assembler definitions of uninitialized global
+   variables are output.  This macro exists to properly support languages like
+   `c++' which do not have `common' data.  However, this macro currently is not
+   defined for all targets.  If this macro and `ASM_OUTPUT_ALIGNED_BSS' are not
+   defined then `ASM_OUTPUT_COMMON' or `ASM_OUTPUT_ALIGNED_COMMON' or
+   `ASM_OUTPUT_DECL_COMMON' is used.  */
+/* #define ASM_OUTPUT_BSS(STREAM, DECL, NAME, SIZE, ROUNDED) */
+
+/* Like `ASM_OUTPUT_BSS' except takes the required alignment as a separate,
+   explicit argument.  If you define this macro, it is used in place of
+   `ASM_OUTPUT_BSS', and gives you more flexibility in handling the required
+   alignment of the variable.  The alignment is specified as the number of
+   bits.
+
+   Try to use function `asm_output_aligned_bss' defined in file `varasm.c' when
+   defining this macro.  */
+/* #define ASM_OUTPUT_ALIGNED_BSS(STREAM, DECL, NAME, SIZE, ALIGNMENT) */
+
+/* If defined, it is similar to `ASM_OUTPUT_BSS', except that it is used when
+   NAME is shared.  If not defined, `ASM_OUTPUT_BSS' will be used.  */
+/* #define ASM_OUTPUT_SHARED_BSS(STREAM, DECL, NAME, SIZE, ROUNDED) */
+
+/* A C statement (sans semicolon) to output to the stdio stream STREAM the
+   assembler definition of a local-common-label named NAME whose size is SIZE
+   bytes.  The variable ROUNDED is the size rounded up to whatever alignment
+   the caller wants.
+
+   Use the expression `assemble_name (STREAM, NAME)' to output the name itself;
+   before and after that, output the additional assembler syntax for defining
+   the name, and a newline.
+
+   This macro controls how the assembler definitions of uninitialized static
+   variables are output.  */
+/* #define ASM_OUTPUT_LOCAL(STREAM, NAME, SIZE, ROUNDED) */
+
+/* Like `ASM_OUTPUT_LOCAL' except takes the required alignment as a separate,
+   explicit argument.  If you define this macro, it is used in place of
+   `ASM_OUTPUT_LOCAL', and gives you more flexibility in handling the required
+   alignment of the variable.  The alignment is specified as the number of
+   bits.
+
+   Defined in svr4.h.  */
+/* #define ASM_OUTPUT_ALIGNED_LOCAL(STREAM, NAME, SIZE, ALIGNMENT) */
+
+/* Like `ASM_OUTPUT_ALIGNED_LOCAL' except that it takes an additional
+   parameter - the DECL of variable to be output, if there is one.
+   This macro can be called with DECL == NULL_TREE.  If you define
+   this macro, it is used in place of `ASM_OUTPUT_LOCAL' and
+   `ASM_OUTPUT_ALIGNED_LOCAL', and gives you more flexibility in
+   handling the destination of the variable.  */
+/* #define ASM_OUTPUT_DECL_LOCAL(STREAM, DECL, NAME, SIZE, ALIGNMENT) */
+
+/* If defined, it is similar to `ASM_OUTPUT_LOCAL', except that it is used when
+   NAME is shared.  If not defined, `ASM_OUTPUT_LOCAL' will be used.  */
+/* #define ASM_OUTPUT_SHARED_LOCAL (STREAM, NAME, SIZE, ROUNDED) */
+
+\f
+/* Output and Generation of Labels.  */
+
+/* A C statement (sans semicolon) to output to the stdio stream STREAM the
+   assembler definition of a label named NAME.  Use the expression
+   `assemble_name (STREAM, NAME)' to output the name itself; before and after
+   that, output the additional assembler syntax for defining the name, and a
+   newline.  */
+
+#define ASM_OUTPUT_LABEL(STREAM, NAME)                                 \
+do {                                                                   \
+  assemble_name (STREAM, NAME);                                                \
+  fputs (":\n", STREAM);                                               \
+} while (0)
+
+/* A C statement (sans semicolon) to output to the stdio stream STREAM any text
+   necessary for declaring the name NAME of a function which is being defined.
+   This macro is responsible for outputting the label definition (perhaps using
+   `ASM_OUTPUT_LABEL').  The argument DECL is the `FUNCTION_DECL' tree node
+   representing the function.
+
+   If this macro is not defined, then the function name is defined in the usual
+   manner as a label (by means of `ASM_OUTPUT_LABEL').
+
+   Defined in svr4.h.  */
+/* #define ASM_DECLARE_FUNCTION_NAME(STREAM, NAME, DECL) */
+
+/* A C statement (sans semicolon) to output to the stdio stream STREAM any text
+   necessary for declaring the size of a function which is being defined.  The
+   argument NAME is the name of the function.  The argument DECL is the
+   `FUNCTION_DECL' tree node representing the function.
+
+   If this macro is not defined, then the function size is not defined.
+
+   Defined in svr4.h.  */
+/* #define ASM_DECLARE_FUNCTION_SIZE(STREAM, NAME, DECL) */
+
+/* A C statement (sans semicolon) to output to the stdio stream STREAM any text
+   necessary for declaring the name NAME of an initialized variable which is
+   being defined.  This macro must output the label definition (perhaps using
+   `ASM_OUTPUT_LABEL').  The argument DECL is the `VAR_DECL' tree node
+   representing the variable.
+
+   If this macro is not defined, then the variable name is defined in the usual
+   manner as a label (by means of `ASM_OUTPUT_LABEL').
+
+   Defined in svr4.h.  */
+/* #define ASM_DECLARE_OBJECT_NAME(STREAM, NAME, DECL) */
+
+/* A C statement (sans semicolon) to finish up declaring a variable name once
+   the compiler has processed its initializer fully and thus has had a chance
+   to determine the size of an array when controlled by an initializer.  This
+   is used on systems where it's necessary to declare something about the size
+   of the object.
+
+   If you don't define this macro, that is equivalent to defining it to do
+   nothing.
+
+   Defined in svr4.h.  */
+/* #define ASM_FINISH_DECLARE_OBJECT(STREAM, DECL, TOPLEVEL, ATEND) */
+
+/* A C statement (sans semicolon) to output to the stdio stream STREAM some
+   commands that will make the label NAME global; that is, available for
+   reference from other files.  Use the expression `assemble_name (STREAM,
+   NAME)' to output the name itself; before and after that, output the
+   additional assembler syntax for making that name global, and a newline.  */
+
+#define ASM_GLOBALIZE_LABEL(STREAM,NAME)                               \
+do {                                                                   \
+  fputs ("\t.globl ", STREAM);                                         \
+  assemble_name (STREAM, NAME);                                                \
+  fputs ("\n", STREAM);                                                        \
+} while (0)
+
+/* A C statement (sans semicolon) to output to the stdio stream STREAM some
+   commands that will make the label NAME weak; that is, available for
+   reference from other files but only used if no other definition is
+   available.  Use the expression `assemble_name (STREAM, NAME)' to output the
+   name itself; before and after that, output the additional assembler syntax
+   for making that name weak, and a newline.
+
+   If you don't define this macro, GNU CC will not support weak symbols and you
+   should not define the `SUPPORTS_WEAK' macro.
+
+   Defined in svr4.h.  */
+/* #define ASM_WEAKEN_LABEL */
+
+/* A C expression which evaluates to true if the target supports weak symbols.
+
+   If you don't define this macro, `defaults.h' provides a default definition.
+   If `ASM_WEAKEN_LABEL' is defined, the default definition is `1'; otherwise,
+   it is `0'.  Define this macro if you want to control weak symbol support
+   with a compiler flag such as `-melf'.  */
+/* #define SUPPORTS_WEAK */
+
+/* A C statement (sans semicolon) to mark DECL to be emitted as a
+   public symbol such that extra copies in multiple translation units
+   will be discarded by the linker.  Define this macro if your object
+   file format provides support for this concept, such as the `COMDAT'
+   section flags in the Microsoft Windows PE/COFF format, and this
+   support requires changes to DECL, such as putting it in a separate
+   section.
+
+   Defined in svr4.h.  */
+/* #define MAKE_DECL_ONE_ONLY */
+
+/* A C expression which evaluates to true if the target supports one-only
+   semantics.
+
+   If you don't define this macro, `varasm.c' provides a default definition.
+   If `MAKE_DECL_ONE_ONLY' is defined, the default definition is `1';
+   otherwise, it is `0'.  Define this macro if you want to control one-only
+   symbol support with a compiler flag, or if setting the `DECL_ONE_ONLY' flag
+   is enough to mark a declaration to be emitted as one-only.  */
+/* #define SUPPORTS_ONE_ONLY */
+
+/* A C statement (sans semicolon) to output to the stdio stream STREAM any text
+   necessary for declaring the name of an external symbol named NAME which is
+   referenced in this compilation but not defined.  The value of DECL is the
+   tree node for the declaration.
+
+   This macro need not be defined if it does not need to output anything.  The
+   GNU assembler and most Unix assemblers don't require anything.  */
+/* #define ASM_OUTPUT_EXTERNAL(STREAM, DECL, NAME) */
+
+/* A C statement (sans semicolon) to output on STREAM an assembler pseudo-op to
+   declare a library function name external.  The name of the library function
+   is given by SYMREF, which has type `rtx' and is a `symbol_ref'.
+
+   This macro need not be defined if it does not need to output anything.  The
+   GNU assembler and most Unix assemblers don't require anything.
+
+   Defined in svr4.h.  */
+/* #define ASM_OUTPUT_EXTERNAL_LIBCALL(STREAM, SYMREF) */
+
+/* A C statement (sans semicolon) to output to the stdio stream STREAM a
+   reference in assembler syntax to a label named NAME.  This should add `_' to
+   the front of the name, if that is customary on your operating system, as it
+   is in most Berkeley Unix systems.  This macro is used in `assemble_name'.  */
+/* #define ASM_OUTPUT_LABELREF(STREAM, NAME) */
+
+/* A C statement to output to the stdio stream STREAM a label whose name is
+   made from the string PREFIX and the number NUM.
+
+   It is absolutely essential that these labels be distinct from the labels
+   used for user-level functions and variables.  Otherwise, certain programs
+   will have name conflicts with internal labels.
+
+   It is desirable to exclude internal labels from the symbol table of the
+   object file.  Most assemblers have a naming convention for labels that
+   should be excluded; on many systems, the letter `L' at the beginning of a
+   label has this effect.  You should find out what convention your system
+   uses, and follow it.
+
+   The usual definition of this macro is as follows:
+
+        fprintf (STREAM, "L%s%d:\n", PREFIX, NUM)
+
+   Defined in svr4.h.  */
+/* #define ASM_OUTPUT_INTERNAL_LABEL(STREAM, PREFIX, NUM) */
+
+/* A C statement to store into the string STRING a label whose name is made
+   from the string PREFIX and the number NUM.
+
+   This string, when output subsequently by `assemble_name', should produce the
+   output that `ASM_OUTPUT_INTERNAL_LABEL' would produce with the same PREFIX
+   and NUM.
+
+   If the string begins with `*', then `assemble_name' will output the rest of
+   the string unchanged.  It is often convenient for
+   `ASM_GENERATE_INTERNAL_LABEL' to use `*' in this way.  If the string doesn't
+   start with `*', then `ASM_OUTPUT_LABELREF' gets to output the string, and
+   may change it.  (Of course, `ASM_OUTPUT_LABELREF' is also part of your
+   machine description, so you should know what it does on your machine.)
+
+   Defined in svr4.h.  */
+
+/*
+#define ASM_GENERATE_INTERNAL_LABEL(LABEL, PREFIX, NUM)                        \
+do {                                                                   \
+  sprintf (LABEL, "*.%s%d", PREFIX, NUM);                              \
+} while (0)
+*/
+
+/* A C expression to assign to OUTVAR (which is a variable of type `char *') a
+   newly allocated string made from the string NAME and the number NUMBER, with
+   some suitable punctuation added.  Use `alloca' to get space for the string.
+
+   The string will be used as an argument to `ASM_OUTPUT_LABELREF' to produce
+   an assembler label for an internal static variable whose name is NAME.
+   Therefore, the string must be such as to result in valid assembler code.
+   The argument NUMBER is different each time this macro is executed; it
+   prevents conflicts between similarly-named internal static variables in
+   different scopes.
+
+   Ideally this string should not be a valid C identifier, to prevent any
+   conflict with the user's own symbols.  Most assemblers allow periods or
+   percent signs in assembler symbols; putting at least one of these between
+   the name and the number will suffice.  */
+
+#define ASM_FORMAT_PRIVATE_NAME(OUTVAR, NAME, NUMBER)                  \
+do {                                                                   \
+  (OUTVAR) = (char *) alloca (strlen ((NAME)) + 12);                   \
+  sprintf ((OUTVAR), "%s.%ld", (NAME), (long)(NUMBER));                        \
+} while (0)
+
+/* A C statement to output to the stdio stream STREAM assembler code which
+   defines (equates) the symbol NAME to have the value VALUE.
+
+   If SET_ASM_OP is defined, a default definition is provided which is correct
+   for most systems.
+
+   Defined in svr4.h.  */
+/* #define ASM_OUTPUT_DEF(STREAM, NAME, VALUE) */
+
+/* A C statement to output to the stdio stream STREAM assembler code which
+   defines (equates) the weak symbol NAME to have the value VALUE.
+
+   Define this macro if the target only supports weak aliases; define
+   ASM_OUTPUT_DEF instead if possible.  */
+/* #define ASM_OUTPUT_WEAK_ALIAS (STREAM, NAME, VALUE) */
+
+/* Define this macro to override the default assembler names used for Objective
+   C methods.
+
+   The default name is a unique method number followed by the name of the class
+   (e.g. `_1_Foo').  For methods in categories, the name of the category is
+   also included in the assembler name (e.g.  `_1_Foo_Bar').
+
+   These names are safe on most systems, but make debugging difficult since the
+   method's selector is not present in the name.  Therefore, particular systems
+   define other ways of computing names.
+
+   BUF is an expression of type `char *' which gives you a buffer in which to
+   store the name; its length is as long as CLASS_NAME, CAT_NAME and SEL_NAME
+   put together, plus 50 characters extra.
+
+   The argument IS_INST specifies whether the method is an instance method or a
+   class method; CLASS_NAME is the name of the class; CAT_NAME is the name of
+   the category (or NULL if the method is not in a category); and SEL_NAME is
+   the name of the selector.
+
+   On systems where the assembler can handle quoted names, you can use this
+   macro to provide more human-readable names.  */
+/* #define OBJC_GEN_METHOD_LABEL(BUF, IS_INST, CLASS_NAME, CAT_NAME, SEL_NAME) */
+
+\f
+/* Macros Controlling Initialization Routines.  */
+
+/* If defined, a C string constant for the assembler operation to identify the
+   following data as initialization code.  If not defined, GNU CC will assume
+   such a section does not exist.  When you are using special sections for
+   initialization and termination functions, this macro also controls how
+   `crtstuff.c' and `libgcc2.c' arrange to run the initialization functions.
+
+   Defined in svr4.h.  */
+/* #define INIT_SECTION_ASM_OP */
+#undef INIT_SECTION_ASM_OP
+
+/* If defined, `main' will not call `__main' as described above.  This macro
+   should be defined for systems that control the contents of the init section
+   on a symbol-by-symbol basis, such as OSF/1, and should not be defined
+   explicitly for systems that support `INIT_SECTION_ASM_OP'.  */
+/* #define HAS_INIT_SECTION */
+
+/* If defined, a C string constant for a switch that tells the linker that the
+   following symbol is an initialization routine.  */
+/* #define LD_INIT_SWITCH */
+
+/* If defined, a C string constant for a switch that tells the linker that the
+   following symbol is a finalization routine.  */
+/* #define LD_FINI_SWITCH */
+
+/* If defined, `main' will call `__main' despite the presence of
+   `INIT_SECTION_ASM_OP'.  This macro should be defined for systems where the
+   init section is not actually run automatically, but is still useful for
+   collecting the lists of constructors and destructors.  */
+#define INVOKE__main
+
+/* Define this macro as a C statement to output on the stream STREAM the
+   assembler code to arrange to call the function named NAME at initialization
+   time.
+
+   Assume that NAME is the name of a C function generated automatically by the
+   compiler.  This function takes no arguments.  Use the function
+   `assemble_name' to output the name NAME; this performs any system-specific
+   syntactic transformations such as adding an underscore.
+
+   If you don't define this macro, nothing special is output to arrange to call
+   the function.  This is correct when the function will be called in some
+   other manner--for example, by means of the `collect2' program, which looks
+   through the symbol table to find these functions by their names.
+
+   Defined in svr4.h.  */
+/* #define ASM_OUTPUT_CONSTRUCTOR(STREAM, NAME) */
+
+/* This is like `ASM_OUTPUT_CONSTRUCTOR' but used for termination functions
+   rather than initialization functions.
+
+   Defined in svr4.h.  */
+/* #define ASM_OUTPUT_DESTRUCTOR(STREAM, NAME) */
+
+/* If your system uses `collect2' as the means of processing constructors, then
+   that program normally uses `nm' to scan an object file for constructor
+   functions to be called.  On certain kinds of systems, you can define these
+   macros to make `collect2' work faster (and, in some cases, make it work at
+   all): */
+
+/* Define this macro if the system uses COFF (Common Object File Format) object
+   files, so that `collect2' can assume this format and scan object files
+   directly for dynamic constructor/destructor functions.  */
+/* #define OBJECT_FORMAT_COFF */
+
+/* Define this macro if the system uses ROSE format object files, so that
+   `collect2' can assume this format and scan object files directly for dynamic
+   constructor/destructor functions.
+
+   These macros are effective only in a native compiler; `collect2' as
+   part of a cross compiler always uses `nm' for the target machine.  */
+/* #define OBJECT_FORMAT_ROSE */
+
+/* Define this macro if the system uses ELF format object files.
+
+   Defined in svr4.h.  */
+/* #define OBJECT_FORMAT_ELF */
+
+/* Define this macro as a C string constant containing the file name to use to
+   execute `nm'.  The default is to search the path normally for `nm'.
+
+   If your system supports shared libraries and has a program to list the
+   dynamic dependencies of a given library or executable, you can define these
+   macros to enable support for running initialization and termination
+   functions in shared libraries: */
+/* #define REAL_NM_FILE_NAME */
+
+/* Define this macro to a C string constant containing the name of the program
+   which lists dynamic dependencies, like `"ldd"' under SunOS 4.  */
+/* #define LDD_SUFFIX */
+
+/* Define this macro to be C code that extracts filenames from the output of
+   the program denoted by `LDD_SUFFIX'.  PTR is a variable of type `char *'
+   that points to the beginning of a line of output from `LDD_SUFFIX'.  If the
+   line lists a dynamic dependency, the code must advance PTR to the beginning
+   of the filename on that line.  Otherwise, it must set PTR to `NULL'.  */
+/* #define PARSE_LDD_OUTPUT (PTR) */
+
+\f
+/* Output of Assembler Instructions.  */
+
+/* A C initializer containing the assembler's names for the machine registers,
+   each one as a C string constant.  This is what translates register numbers
+   in the compiler into assembler language.  */
+#define REGISTER_NAMES                                                 \
+{                                                                      \
+  "r0",                "r1",           "r2",           "r3",                   \
+  "r4",                "r5",           "r6",           "r7",                   \
+  "r8",                "r9",           "r10",          "r11",                  \
+  "r12",       "r13",          "r14",          "r15",                  \
+  "r16",       "r17",          "r18",          "r19",                  \
+  "r20",       "r21",          "r22",          "r23",                  \
+  "r24",       "r25",          "r26",          "r27",                  \
+  "r28",       "r29",          "r30",          "r31",                  \
+  "r32",       "r33",          "r34",          "r35",                  \
+  "r36",       "r37",          "r38",          "r39",                  \
+  "r40",       "r41",          "r42",          "r43",                  \
+  "r44",       "r45",          "r46",          "r47",                  \
+  "r48",       "r49",          "r50",          "r51",                  \
+  "r52",       "r53",          "r54",          "r55",                  \
+  "r56",       "r57",          "r58",          "r59",                  \
+  "r60",       "r61",          "link",         "sp",                   \
+  "ap",                                                                        \
+  "f0",                "f1",           "f2",           "f3",                   \
+  "s",         "v",            "va",           "c",                    \
+  "a0",                "a1",                                                   \
+  "psw",       "bpsw",         "pc",           "bpc",                  \
+  "dpsw",      "dpc",          "rpt_c",        "rpt_s",                \
+  "rpt_e",     "mod_s",        "mod_e",        "iba",                  \
+  "eit_vb",    "int_s",        "int_m",                                \
+}
+
+/* If defined, a C initializer for an array of structures containing a name and
+   a register number.  This macro defines additional names for hard registers,
+   thus allowing the `asm' option in declarations to refer to registers using
+   alternate names.  */
+#define ADDITIONAL_REGISTER_NAMES              \
+{                                              \
+  {"r62",      GPR_LINK},                      \
+  {"r63",      GPR_SP},                        \
+  {"f4",       FLAG_SAT},                      \
+  {"f5",       FLAG_OVERFLOW},                 \
+  {"f6",       FLAG_ACC_OVER},                 \
+  {"f7",       FLAG_CARRY},                    \
+  {"carry",    FLAG_CARRY},                    \
+  {"borrow",   FLAG_BORROW},                   \
+  {"b",                FLAG_BORROW},                   \
+  {"cr0",      CR_PSW},                        \
+  {"cr1",      CR_BPSW},                       \
+  {"cr2",      CR_PC},                         \
+  {"cr3",      CR_BPC},                        \
+  {"cr4",      CR_DPSW},                       \
+  {"cr5",      CR_DPC},                        \
+  {"cr7",      CR_RPT_C},                      \
+  {"cr8",      CR_RPT_S},                      \
+  {"cr9",      CR_RPT_E},                      \
+  {"cr10",     CR_MOD_S},                      \
+  {"cr11",     CR_MOD_E},                      \
+  {"cr14",     CR_IBA},                        \
+  {"cr15",     CR_EIT_VB},                     \
+  {"cr16",     CR_INT_S},                      \
+  {"cr17",     CR_INT_M}                       \
+}
+
+/* Define this macro if you are using an unusual assembler that requires
+   different names for the machine instructions.
+
+   The definition is a C statement or statements which output an assembler
+   instruction opcode to the stdio stream STREAM.  The macro-operand PTR is a
+   variable of type `char *' which points to the opcode name in its "internal"
+   form--the form that is written in the machine description.  The definition
+   should output the opcode name to STREAM, performing any translation you
+   desire, and increment the variable PTR to point at the end of the opcode so
+   that it will not be output twice.
+
+   In fact, your macro definition may process less than the entire opcode name,
+   or more than the opcode name; but if you want to process text that includes
+   `%'-sequences to substitute operands, you must take care of the substitution
+   yourself.  Just be sure to increment PTR over whatever text should not be
+   output normally.
+
+   If you need to look at the operand values, they can be found as the elements
+   of `recog_data.operand'.
+
+   If the macro definition does nothing, the instruction is output in the usual
+   way.  */
+/* #define ASM_OUTPUT_OPCODE(STREAM, PTR) */
+
+/* If defined, a C statement to be executed just prior to the output of
+   assembler code for INSN, to modify the extracted operands so they will be
+   output differently.
+
+   Here the argument OPVEC is the vector containing the operands extracted from
+   INSN, and NOPERANDS is the number of elements of the vector which contain
+   meaningful data for this insn.  The contents of this vector are what will be
+   used to convert the insn template into assembler code, so you can change the
+   assembler output by changing the contents of the vector.
+
+   This macro is useful when various assembler syntaxes share a single file of
+   instruction patterns; by defining this macro differently, you can cause a
+   large class of instructions to be output differently (such as with
+   rearranged operands).  Naturally, variations in assembler syntax affecting
+   individual insn patterns ought to be handled by writing conditional output
+   routines in those patterns.
+
+   If this macro is not defined, it is equivalent to a null statement.  */
+/* #define FINAL_PRESCAN_INSN(INSN, OPVEC, NOPERANDS) */
+
+/* If defined, `FINAL_PRESCAN_INSN' will be called on each
+   `CODE_LABEL'.  In that case, OPVEC will be a null pointer and
+   NOPERANDS will be zero.  */
+/* #define FINAL_PRESCAN_LABEL */
+
+/* A C compound statement to output to stdio stream STREAM the assembler syntax
+   for an instruction operand X.  X is an RTL expression.
+
+   CODE is a value that can be used to specify one of several ways of printing
+   the operand.  It is used when identical operands must be printed differently
+   depending on the context.  CODE comes from the `%' specification that was
+   used to request printing of the operand.  If the specification was just
+   `%DIGIT' then CODE is 0; if the specification was `%LTR DIGIT' then CODE is
+   the ASCII code for LTR.
+
+   If X is a register, this macro should print the register's name.  The names
+   can be found in an array `reg_names' whose type is `char *[]'.  `reg_names'
+   is initialized from `REGISTER_NAMES'.
+
+   When the machine description has a specification `%PUNCT' (a `%' followed by
+   a punctuation character), this macro is called with a null pointer for X and
+   the punctuation character for CODE.
+
+   Standard operand flags that are handled elsewhere:
+       `='  Output a number unique to each instruction in the compilation.
+       `a'  Substitute an operand as if it were a memory reference.
+       `c'  Omit the syntax that indicates an immediate operand.
+       `l'  Substitute a LABEL_REF into a jump instruction.
+       `n'  Like %cDIGIT, except negate the value before printing.
+
+   The d30v specific operand flags are:
+       `.'  Print r0.
+       `f'  Print a SF constant as an int.
+       `s'  Subtract 32 and negate.
+       `A'  Print accumulator number without an `a' in front of it.
+       `B'  Print bit offset for BSET, etc. instructions.
+       `E'  Print u if this is zero extend, nothing if this is sign extend.
+       `F'  Emit /{f,t,x}{f,t,x} for executing a false condition.
+       `L'  Print the lower half of a 64 bit item.
+       `M'  Print a memory reference for ld/st instructions.
+       `R'  Return appropriate cmp instruction for relational test.
+       `S'  Subtract 32.
+       `T'  Emit /{f,t,x}{f,t,x} for executing a true condition.
+       `U'  Print the upper half of a 64 bit item.  */
+
+#define PRINT_OPERAND(STREAM, X, CODE) d30v_print_operand (STREAM, X, CODE)
+
+/* A C expression which evaluates to true if CODE is a valid punctuation
+   character for use in the `PRINT_OPERAND' macro.  If
+   `PRINT_OPERAND_PUNCT_VALID_P' is not defined, it means that no punctuation
+   characters (except for the standard one, `%') are used in this way.  */
+
+#define PRINT_OPERAND_PUNCT_VALID_P(CODE) ((CODE) == '.')
+
+/* A C compound statement to output to stdio stream STREAM the assembler syntax
+   for an instruction operand that is a memory reference whose address is X.  X
+   is an RTL expression.
+
+   On some machines, the syntax for a symbolic address depends on the section
+   that the address refers to.  On these machines, define the macro
+   `ENCODE_SECTION_INFO' to store the information into the `symbol_ref', and
+   then check for it here.  *Note Assembler Format::.  */
+
+#define PRINT_OPERAND_ADDRESS(STREAM, X) d30v_print_operand_address (STREAM, X)
+
+/* A C statement, to be executed after all slot-filler instructions have been
+   output.  If necessary, call `dbr_sequence_length' to determine the number of
+   slots filled in a sequence (zero if not currently outputting a sequence), to
+   decide how many no-ops to output, or whatever.
+
+   Don't define this macro if it has nothing to do, but it is helpful in
+   reading assembly output if the extent of the delay sequence is made explicit
+   (e.g. with white space).
+
+   Note that output routines for instructions with delay slots must be prepared
+   to deal with not being output as part of a sequence (i.e.  when the
+   scheduling pass is not run, or when no slot fillers could be found.)  The
+   variable `final_sequence' is null when not processing a sequence, otherwise
+   it contains the `sequence' rtx being output.  */
+/* #define DBR_OUTPUT_SEQEND(FILE) */
+
+/* If defined, C string expressions to be used for the `%R', `%L', `%U', and
+   `%I' options of `asm_fprintf' (see `final.c').  These are useful when a
+   single `md' file must support multiple assembler formats.  In that case, the
+   various `tm.h' files can define these macros differently.
+
+   USER_LABEL_PREFIX is defined in svr4.h.  */
+
+#define REGISTER_PREFIX "%"
+#define LOCAL_LABEL_PREFIX "."
+#define USER_LABEL_PREFIX ""
+#define IMMEDIATE_PREFIX ""
+
+/* If your target supports multiple dialects of assembler language (such as
+   different opcodes), define this macro as a C expression that gives the
+   numeric index of the assembler language dialect to use, with zero as the
+   first variant.
+
+   If this macro is defined, you may use `{option0|option1|option2...}'
+   constructs in the output templates of patterns (*note Output Template::.) or
+   in the first argument of `asm_fprintf'.  This construct outputs `option0',
+   `option1' or `option2', etc., if the value of `ASSEMBLER_DIALECT' is zero,
+   one or two, etc.  Any special characters within these strings retain their
+   usual meaning.
+
+   If you do not define this macro, the characters `{', `|' and `}' do not have
+   any special meaning when used in templates or operands to `asm_fprintf'.
+
+   Define the macros `REGISTER_PREFIX', `LOCAL_LABEL_PREFIX',
+   `USER_LABEL_PREFIX' and `IMMEDIATE_PREFIX' if you can express the variations
+   in assemble language syntax with that mechanism.  Define `ASSEMBLER_DIALECT'
+   and use the `{option0|option1}' syntax if the syntax variant are larger and
+   involve such things as different opcodes or operand order.  */
+/* #define ASSEMBLER_DIALECT */
+
+/* A C expression to output to STREAM some assembler code which will push hard
+   register number REGNO onto the stack.  The code need not be optimal, since
+   this macro is used only when profiling.  */
+/* #define ASM_OUTPUT_REG_PUSH (STREAM, REGNO) */
+
+/* A C expression to output to STREAM some assembler code which will pop hard
+   register number REGNO off of the stack.  The code need not be optimal, since
+   this macro is used only when profiling.  */
+/* #define ASM_OUTPUT_REG_POP (STREAM, REGNO) */
+
+\f
+/* Output of dispatch tables.  */
+
+/* This macro should be provided on machines where the addresses in a dispatch
+   table are relative to the table's own address.
+
+   The definition should be a C statement to output to the stdio stream STREAM
+   an assembler pseudo-instruction to generate a difference between two labels.
+   VALUE and REL are the numbers of two internal labels.  The definitions of
+   these labels are output using `ASM_OUTPUT_INTERNAL_LABEL', and they must be
+   printed in the same way here.  For example,
+
+        fprintf (STREAM, "\t.word L%d-L%d\n", VALUE, REL)  */
+
+#define ASM_OUTPUT_ADDR_DIFF_ELT(STREAM, BODY, VALUE, REL) \
+fprintf (STREAM, "\t.word .L%d-.L%d\n", VALUE, REL)
+
+/* This macro should be provided on machines where the addresses in a dispatch
+   table are absolute.
+
+   The definition should be a C statement to output to the stdio stream STREAM
+   an assembler pseudo-instruction to generate a reference to a label.  VALUE
+   is the number of an internal label whose definition is output using
+   `ASM_OUTPUT_INTERNAL_LABEL'.  For example,
+
+        fprintf (STREAM, "\t.word L%d\n", VALUE)  */
+
+#define ASM_OUTPUT_ADDR_VEC_ELT(STREAM, VALUE) \
+fprintf (STREAM, "\t.word .L%d\n", VALUE)
+
+/* Define this if the label before a jump-table needs to be output specially.
+   The first three arguments are the same as for `ASM_OUTPUT_INTERNAL_LABEL';
+   the fourth argument is the jump-table which follows (a `jump_insn'
+   containing an `addr_vec' or `addr_diff_vec').
+
+   This feature is used on system V to output a `swbeg' statement for the
+   table.
+
+   If this macro is not defined, these labels are output with
+   `ASM_OUTPUT_INTERNAL_LABEL'.
+
+   Defined in svr4.h.  */
+/* #define ASM_OUTPUT_CASE_LABEL(STREAM, PREFIX, NUM, TABLE) */
+
+/* Define this if something special must be output at the end of a jump-table.
+   The definition should be a C statement to be executed after the assembler
+   code for the table is written.  It should write the appropriate code to
+   stdio stream STREAM.  The argument TABLE is the jump-table insn, and NUM is
+   the label-number of the preceding label.
+
+   If this macro is not defined, nothing special is output at the end of the
+   jump-table.  */
+/* #define ASM_OUTPUT_CASE_END(STREAM, NUM, TABLE) */
+
+\f
+/* Assembler Commands for Exception Regions.  */
+
+/* A C expression to output text to mark the start of an exception region.
+
+   This macro need not be defined on most platforms.  */
+/* #define ASM_OUTPUT_EH_REGION_BEG() */
+
+/* A C expression to output text to mark the end of an exception region.
+
+   This macro need not be defined on most platforms.  */
+/* #define ASM_OUTPUT_EH_REGION_END() */
+
+/* A C expression to switch to the section in which the main exception table is
+   to be placed (*note Sections::.).  The default is a section named
+   `.gcc_except_table' on machines that support named sections via
+   `ASM_OUTPUT_SECTION_NAME', otherwise if `-fpic' or `-fPIC' is in effect, the
+   `data_section', otherwise the `readonly_data_section'.  */
+/* #define EXCEPTION_SECTION() */
+
+/* If defined, a C string constant for the assembler operation to switch to the
+   section for exception handling frame unwind information.  If not defined,
+   GNU CC will provide a default definition if the target supports named
+   sections.  `crtstuff.c' uses this macro to switch to the appropriate
+   section.
+
+   You should define this symbol if your target supports DWARF 2 frame unwind
+   information and the default definition does not work.  */
+/* #define EH_FRAME_SECTION_ASM_OP */
+
+/* A C expression that is nonzero if the normal exception table output should
+   be omitted.
+
+   This macro need not be defined on most platforms.  */
+/* #define OMIT_EH_TABLE() */
+
+/* Alternate runtime support for looking up an exception at runtime and finding
+   the associated handler, if the default method won't work.
+
+   This macro need not be defined on most platforms.  */
+/* #define EH_TABLE_LOOKUP() */
+
+/* A C expression that decides whether or not the current function needs to
+   have a function unwinder generated for it.  See the file `except.c' for
+   details on when to define this, and how.  */
+/* #define DOESNT_NEED_UNWINDER */
+
+/* An rtx used to mask the return address found via RETURN_ADDR_RTX, so that it
+   does not contain any extraneous set bits in it.  */
+/* #define MASK_RETURN_ADDR */
+
+/* Define this macro to 0 if your target supports DWARF 2 frame unwind
+   information, but it does not yet work with exception handling.  Otherwise,
+   if your target supports this information (if it defines
+   `INCOMING_RETURN_ADDR_RTX' and either `UNALIGNED_INT_ASM_OP' or
+   `OBJECT_FORMAT_ELF'), GCC will provide a default definition of 1.
+
+   If this macro is defined to 1, the DWARF 2 unwinder will be the default
+   exception handling mechanism; otherwise, setjmp/longjmp will be used by
+   default.
+
+   If this macro is defined to anything, the DWARF 2 unwinder will be used
+   instead of inline unwinders and __unwind_function in the non-setjmp case.  */
+/* #define DWARF2_UNWIND_INFO */
+
+\f
+/* Assembler Commands for Alignment.  */
+
+/* The alignment (log base 2) to put in front of LABEL, which follows
+   a BARRIER.
+
+   This macro need not be defined if you don't want any special alignment to be
+   done at such a time.  Most machine descriptions do not currently define the
+   macro.  */
+/* #define LABEL_ALIGN_AFTER_BARRIER(LABEL) */
+
+/* The desired alignment for the location counter at the beginning
+   of a loop.
+
+   This macro need not be defined if you don't want any special alignment to be
+   done at such a time.  Most machine descriptions do not currently define the
+   macro.  */
+/* #define LOOP_ALIGN(LABEL) */
+
+/* A C statement to output to the stdio stream STREAM an assembler instruction
+   to advance the location counter by NBYTES bytes.  Those bytes should be zero
+   when loaded.  NBYTES will be a C expression of type `int'.
+
+   Defined in svr4.h.  */
+/* #define ASM_OUTPUT_SKIP(STREAM, NBYTES) \
+  fprintf (STREAM, "\t.zero\t%u\n", (NBYTES)) */
+
+/* Define this macro if `ASM_OUTPUT_SKIP' should not be used in the text
+   section because it fails put zeros in the bytes that are skipped.  This is
+   true on many Unix systems, where the pseudo-op to skip bytes produces no-op
+   instructions rather than zeros when used in the text section.  */
+/* #define ASM_NO_SKIP_IN_TEXT */
+
+/* A C statement to output to the stdio stream STREAM an assembler command to
+   advance the location counter to a multiple of 2 to the POWER bytes.  POWER
+   will be a C expression of type `int'.  */
+#define ASM_OUTPUT_ALIGN(STREAM, POWER) \
+  fprintf ((STREAM), "\t.p2align %d\n", (POWER))
+
+\f
+/* Macros Affecting all Debug Formats.  */
+
+/* A C expression that returns the DBX register number for the compiler
+   register number REGNO.  In simple cases, the value of this expression may be
+   REGNO itself.  But sometimes there are some registers that the compiler
+   knows about and DBX does not, or vice versa.  In such cases, some register
+   may need to have one number in the compiler and another for DBX.
+
+   If two registers have consecutive numbers inside GNU CC, and they can be
+   used as a pair to hold a multiword value, then they *must* have consecutive
+   numbers after renumbering with `DBX_REGISTER_NUMBER'.  Otherwise, debuggers
+   will be unable to access such a pair, because they expect register pairs to
+   be consecutive in their own numbering scheme.
+
+   If you find yourself defining `DBX_REGISTER_NUMBER' in way that does not
+   preserve register pairs, then what you must do instead is redefine the
+   actual register numbering scheme.  */
+#define DBX_REGISTER_NUMBER(REGNO)                                     \
+(GPR_P (REGNO)                  ? ((REGNO) - GPR_FIRST)                \
+ : ACCUM_P (REGNO)              ? ((REGNO) - ACCUM_FIRST + 84)         \
+ : FLAG_P (REGNO)               ? 66 /* return psw for all flags */    \
+ : (REGNO) == ARG_POINTER_REGNUM ? (GPR_SP - GPR_FIRST)                        \
+ : (REGNO) == CR_PSW            ? (66 + 0)                             \
+ : (REGNO) == CR_BPSW           ? (66 + 1)                             \
+ : (REGNO) == CR_PC             ? (66 + 2)                             \
+ : (REGNO) == CR_BPC            ? (66 + 3)                             \
+ : (REGNO) == CR_DPSW           ? (66 + 4)                             \
+ : (REGNO) == CR_DPC            ? (66 + 5)                             \
+ : (REGNO) == CR_RPT_C          ? (66 + 7)                             \
+ : (REGNO) == CR_RPT_S          ? (66 + 8)                             \
+ : (REGNO) == CR_RPT_E          ? (66 + 9)                             \
+ : (REGNO) == CR_MOD_S          ? (66 + 10)                            \
+ : (REGNO) == CR_MOD_E          ? (66 + 11)                            \
+ : (REGNO) == CR_IBA            ? (66 + 14)                            \
+ : (REGNO) == CR_EIT_VB                 ? (66 + 15)                            \
+ : (REGNO) == CR_INT_S          ? (66 + 16)                            \
+ : (REGNO) == CR_INT_M          ? (66 + 17)                            \
+ :                                -1)
+
+/* A C expression that returns the integer offset value for an automatic
+   variable having address X (an RTL expression).  The default computation
+   assumes that X is based on the frame-pointer and gives the offset from the
+   frame-pointer.  This is required for targets that produce debugging output
+   for DBX or COFF-style debugging output for SDB and allow the frame-pointer
+   to be eliminated when the `-g' options is used.  */
+/* #define DEBUGGER_AUTO_OFFSET(X) */
+
+/* A C expression that returns the integer offset value for an argument having
+   address X (an RTL expression).  The nominal offset is OFFSET.  */
+/* #define DEBUGGER_ARG_OFFSET(OFFSET, X) */
+
+/* A C expression that returns the type of debugging output GNU CC produces
+   when the user specifies `-g' or `-ggdb'.  Define this if you have arranged
+   for GNU CC to support more than one format of debugging output.  Currently,
+   the allowable values are `DBX_DEBUG', `SDB_DEBUG', `DWARF_DEBUG',
+   `DWARF2_DEBUG', and `XCOFF_DEBUG'.
+
+   The value of this macro only affects the default debugging output; the user
+   can always get a specific type of output by using `-gstabs', `-gcoff',
+   `-gdwarf-1', `-gdwarf-2', or `-gxcoff'.
+
+   Defined in svr4.h.  */
+
+#undef PREFERRED_DEBUGGING_TYPE
+#define        PREFERRED_DEBUGGING_TYPE DBX_DEBUG
+
+\f
+/* Specific Options for DBX Output.  */
+
+/* Define this macro if GNU CC should produce debugging output for DBX in
+   response to the `-g' option.
+
+   Defined in svr4.h.  */
+/* #define DBX_DEBUGGING_INFO */
+
+/* Define this macro if GNU CC should produce XCOFF format debugging output in
+   response to the `-g' option.  This is a variant of DBX format.  */
+/* #define XCOFF_DEBUGGING_INFO */
+
+/* Define this macro to control whether GNU CC should by default generate GDB's
+   extended version of DBX debugging information (assuming DBX-format debugging
+   information is enabled at all).  If you don't define the macro, the default
+   is 1: always generate the extended information if there is any occasion to.  */
+/* #define DEFAULT_GDB_EXTENSIONS */
+
+/* Define this macro if all `.stabs' commands should be output while in the
+   text section.  */
+/* #define DEBUG_SYMS_TEXT */
+
+/* A C string constant naming the assembler pseudo op to use instead of
+   `.stabs' to define an ordinary debugging symbol.  If you don't define this
+   macro, `.stabs' is used.  This macro applies only to DBX debugging
+   information format.  */
+/* #define ASM_STABS_OP */
+
+/* A C string constant naming the assembler pseudo op to use instead of
+   `.stabd' to define a debugging symbol whose value is the current location.
+   If you don't define this macro, `.stabd' is used.  This macro applies only
+   to DBX debugging information format.  */
+/* #define ASM_STABD_OP */
+
+/* A C string constant naming the assembler pseudo op to use instead of
+   `.stabn' to define a debugging symbol with no name.  If you don't define
+   this macro, `.stabn' is used.  This macro applies only to DBX debugging
+   information format.  */
+/* #define ASM_STABN_OP */
+
+/* Define this macro if DBX on your system does not support the construct
+   `xsTAGNAME'.  On some systems, this construct is used to describe a forward
+   reference to a structure named TAGNAME.  On other systems, this construct is
+   not supported at all.  */
+/* #define DBX_NO_XREFS */
+
+/* A symbol name in DBX-format debugging information is normally continued
+   (split into two separate `.stabs' directives) when it exceeds a certain
+   length (by default, 80 characters).  On some operating systems, DBX requires
+   this splitting; on others, splitting must not be done.  You can inhibit
+   splitting by defining this macro with the value zero.  You can override the
+   default splitting-length by defining this macro as an expression for the
+   length you desire.  */
+/* #define DBX_CONTIN_LENGTH */
+
+/* Normally continuation is indicated by adding a `\' character to the end of a
+   `.stabs' string when a continuation follows.  To use a different character
+   instead, define this macro as a character constant for the character you
+   want to use.  Do not define this macro if backslash is correct for your
+   system.  */
+/* #define DBX_CONTIN_CHAR */
+
+/* Define this macro if it is necessary to go to the data section before
+   outputting the `.stabs' pseudo-op for a non-global static variable.  */
+/* #define DBX_STATIC_STAB_DATA_SECTION */
+
+/* The value to use in the "code" field of the `.stabs' directive for a
+   typedef.  The default is `N_LSYM'.  */
+/* #define DBX_TYPE_DECL_STABS_CODE */
+
+/* The value to use in the "code" field of the `.stabs' directive for a static
+   variable located in the text section.  DBX format does not provide any
+   "right" way to do this.  The default is `N_FUN'.  */
+/* #define DBX_STATIC_CONST_VAR_CODE */
+
+/* The value to use in the "code" field of the `.stabs' directive for a
+   parameter passed in registers.  DBX format does not provide any "right" way
+   to do this.  The default is `N_RSYM'.  */
+/* #define DBX_REGPARM_STABS_CODE */
+
+/* The letter to use in DBX symbol data to identify a symbol as a parameter
+   passed in registers.  DBX format does not customarily provide any way to do
+   this.  The default is `'P''.  */
+/* #define DBX_REGPARM_STABS_LETTER */
+
+/* The letter to use in DBX symbol data to identify a symbol as a stack
+   parameter.  The default is `'p''.  */
+/* #define DBX_MEMPARM_STABS_LETTER */
+
+/* Define this macro if the DBX information for a function and its arguments
+   should precede the assembler code for the function.  Normally, in DBX
+   format, the debugging information entirely follows the assembler code.
+
+   Defined in svr4.h.  */
+/* #define DBX_FUNCTION_FIRST */
+
+/* Define this macro if the `N_LBRAC' symbol for a block should precede the
+   debugging information for variables and functions defined in that block.
+   Normally, in DBX format, the `N_LBRAC' symbol comes first.  */
+/* #define DBX_LBRAC_FIRST */
+
+/* Define this macro if the value of a symbol describing the scope of a block
+   (`N_LBRAC' or `N_RBRAC') should be relative to the start of the enclosing
+   function.  Normally, GNU C uses an absolute address.
+
+   Defined in svr4.h.  */
+/* #define DBX_BLOCKS_FUNCTION_RELATIVE */
+
+/* Define this macro if GNU C should generate `N_BINCL' and `N_EINCL'
+   stabs for included header files, as on Sun systems.  This macro
+   also directs GNU C to output a type number as a pair of a file
+   number and a type number within the file.  Normally, GNU C does not
+   generate `N_BINCL' or `N_EINCL' stabs, and it outputs a single
+   number for a type number.  */
+/* #define DBX_USE_BINCL */
+
+\f
+/* Open ended Hooks for DBX Output.  */
+
+/* Define this macro to say how to output to STREAM the debugging information
+   for the start of a scope level for variable names.  The argument NAME is the
+   name of an assembler symbol (for use with `assemble_name') whose value is
+   the address where the scope begins.  */
+/* #define DBX_OUTPUT_LBRAC(STREAM, NAME) */
+
+/* Like `DBX_OUTPUT_LBRAC', but for the end of a scope level.  */
+/* #define DBX_OUTPUT_RBRAC(STREAM, NAME) */
+
+/* Define this macro if the target machine requires special handling to output
+   an enumeration type.  The definition should be a C statement (sans
+   semicolon) to output the appropriate information to STREAM for the type
+   TYPE.  */
+/* #define DBX_OUTPUT_ENUM(STREAM, TYPE) */
+
+/* Define this macro if the target machine requires special output at the end
+   of the debugging information for a function.  The definition should be a C
+   statement (sans semicolon) to output the appropriate information to STREAM.
+   FUNCTION is the `FUNCTION_DECL' node for the function.  */
+/* #define DBX_OUTPUT_FUNCTION_END(STREAM, FUNCTION) */
+
+/* Define this macro if you need to control the order of output of the standard
+   data types at the beginning of compilation.  The argument SYMS is a `tree'
+   which is a chain of all the predefined global symbols, including names of
+   data types.
+
+   Normally, DBX output starts with definitions of the types for integers and
+   characters, followed by all the other predefined types of the particular
+   language in no particular order.
+
+   On some machines, it is necessary to output different particular types
+   first.  To do this, define `DBX_OUTPUT_STANDARD_TYPES' to output those
+   symbols in the necessary order.  Any predefined types that you don't
+   explicitly output will be output afterward in no particular order.
+
+   Be careful not to define this macro so that it works only for C.  There are
+   no global variables to access most of the built-in types, because another
+   language may have another set of types.  The way to output a particular type
+   is to look through SYMS to see if you can find it.  Here is an example:
+
+        {
+          tree decl;
+          for (decl = syms; decl; decl = TREE_CHAIN (decl))
+            if (!strcmp (IDENTIFIER_POINTER (DECL_NAME (decl)),
+                         "long int"))
+              dbxout_symbol (decl);
+          ...
+        }
+
+   This does nothing if the expected type does not exist.
+
+   See the function `init_decl_processing' in `c-decl.c' to find the names to
+   use for all the built-in C types. */
+/* #define DBX_OUTPUT_STANDARD_TYPES(SYMS) */
+
+/* Some stabs encapsulation formats (in particular ECOFF), cannot
+   handle the `.stabs "",N_FUN,,0,0,Lscope-function-1' gdb dbx
+   extention construct.  On those machines, define this macro to turn
+   this feature off without disturbing the rest of the gdb extensions.  */
+/* #define NO_DBX_FUNCTION_END */
+
+\f
+/* File names in DBX format.  */
+
+/* Define this if DBX wants to have the current directory recorded in each
+   object file.
+
+   Note that the working directory is always recorded if GDB extensions are
+   enabled.  */
+/* #define DBX_WORKING_DIRECTORY */
+
+/* A C statement to output DBX debugging information to the stdio stream STREAM
+   which indicates that file NAME is the main source file--the file specified
+   as the input file for compilation.  This macro is called only once, at the
+   beginning of compilation.
+
+   This macro need not be defined if the standard form of output for DBX
+   debugging information is appropriate.
+
+   Defined in svr4.h.  */
+/* #define DBX_OUTPUT_MAIN_SOURCE_FILENAME(STREAM, NAME) */
+
+/* A C statement to output DBX debugging information to the stdio stream STREAM
+   which indicates that the current directory during compilation is named NAME.
+
+   This macro need not be defined if the standard form of output for DBX
+   debugging information is appropriate.  */
+/* #define DBX_OUTPUT_MAIN_SOURCE_DIRECTORY(STREAM, NAME) */
+
+/* A C statement to output DBX debugging information at the end of compilation
+   of the main source file NAME.
+
+   If you don't define this macro, nothing special is output at the end of
+   compilation, which is correct for most machines.  */
+/* #define DBX_OUTPUT_MAIN_SOURCE_FILE_END(STREAM, NAME) */
+
+/* A C statement to output DBX debugging information to the stdio stream STREAM
+   which indicates that file NAME is the current source file.  This output is
+   generated each time input shifts to a different source file as a result of
+   `#include', the end of an included file, or a `#line' command.
+
+   This macro need not be defined if the standard form of output for DBX
+   debugging information is appropriate.  */
+/* #define DBX_OUTPUT_SOURCE_FILENAME(STREAM, NAME) */
+
+\f
+/* Macros for SDB and Dwarf Output.  */
+
+/* Define this macro if GNU CC should produce COFF-style debugging output for
+   SDB in response to the `-g' option.  */
+/* #define SDB_DEBUGGING_INFO */
+
+/* Define this macro if GNU CC should produce dwarf format debugging output in
+   response to the `-g' option.
+
+   Defined in svr4.h.  */
+/* #define DWARF_DEBUGGING_INFO */
+
+/* Define this macro if GNU CC should produce dwarf version 2 format debugging
+   output in response to the `-g' option.
+
+   To support optional call frame debugging information, you must also define
+   `INCOMING_RETURN_ADDR_RTX' and either set `RTX_FRAME_RELATED_P' on the
+   prologue insns if you use RTL for the prologue, or call `dwarf2out_def_cfa'
+   and `dwarf2out_reg_save' as appropriate from `FUNCTION_PROLOGUE' if you
+   don't.
+
+   Defined in svr4.h.  */
+/* #define DWARF2_DEBUGGING_INFO */
+
+/* Define these macros to override the assembler syntax for the special SDB
+   assembler directives.  See `sdbout.c' for a list of these macros and their
+   arguments.  If the standard syntax is used, you need not define them
+   yourself.  */
+/* #define PUT_SDB_... */
+
+/* Some assemblers do not support a semicolon as a delimiter, even between SDB
+   assembler directives.  In that case, define this macro to be the delimiter
+   to use (usually `\n').  It is not necessary to define a new set of
+   `PUT_SDB_OP' macros if this is the only change required.  */
+/* #define SDB_DELIM */
+
+/* Define this macro to override the usual method of constructing a dummy name
+   for anonymous structure and union types.  See `sdbout.c' for more
+   information.  */
+/* #define SDB_GENERATE_FAKE */
+
+/* Define this macro to allow references to unknown structure, union, or
+   enumeration tags to be emitted.  Standard COFF does not allow handling of
+   unknown references, MIPS ECOFF has support for it.  */
+/* #define SDB_ALLOW_UNKNOWN_REFERENCES */
+
+/* Define this macro to allow references to structure, union, or enumeration
+   tags that have not yet been seen to be handled.  Some assemblers choke if
+   forward tags are used, while some require it.  */
+/* #define SDB_ALLOW_FORWARD_REFERENCES */
+
+\f
+/* Cross Compilation and Floating Point.  */
+
+/* While all modern machines use 2's complement representation for integers,
+   there are a variety of representations for floating point numbers.  This
+   means that in a cross-compiler the representation of floating point numbers
+   in the compiled program may be different from that used in the machine doing
+   the compilation.
+
+   Because different representation systems may offer different amounts of
+   range and precision, the cross compiler cannot safely use the host machine's
+   floating point arithmetic.  Therefore, floating point constants must be
+   represented in the target machine's format.  This means that the cross
+   compiler cannot use `atof' to parse a floating point constant; it must have
+   its own special routine to use instead.  Also, constant folding must emulate
+   the target machine's arithmetic (or must not be done at all).
+
+   The macros in the following table should be defined only if you are cross
+   compiling between different floating point formats.
+
+   Otherwise, don't define them.  Then default definitions will be set up which
+   use `double' as the data type, `==' to test for equality, etc.
+
+   You don't need to worry about how many times you use an operand of any of
+   these macros.  The compiler never uses operands which have side effects.  */
+
+/* A macro for the C data type to be used to hold a floating point value in the
+   target machine's format.  Typically this would be a `struct' containing an
+   array of `int'.  */
+/* #define REAL_VALUE_TYPE */
+
+/* A macro for a C expression which compares for equality the two values, X and
+   Y, both of type `REAL_VALUE_TYPE'.  */
+/* #define REAL_VALUES_EQUAL(X, Y) */
+
+/* A macro for a C expression which tests whether X is less than Y, both values
+   being of type `REAL_VALUE_TYPE' and interpreted as floating point numbers in
+   the target machine's representation.  */
+/* #define REAL_VALUES_LESS(X, Y) */
+
+/* A macro for a C expression which performs the standard library function
+   `ldexp', but using the target machine's floating point representation.  Both
+   X and the value of the expression have type `REAL_VALUE_TYPE'.  The second
+   argument, SCALE, is an integer.  */
+/* #define REAL_VALUE_LDEXP(X, SCALE) */
+
+/* A macro whose definition is a C expression to convert the target-machine
+   floating point value X to a signed integer.  X has type `REAL_VALUE_TYPE'.  */
+/* #define REAL_VALUE_FIX(X) */
+
+/* A macro whose definition is a C expression to convert the target-machine
+   floating point value X to an unsigned integer.  X has type
+   `REAL_VALUE_TYPE'.  */
+/* #define REAL_VALUE_UNSIGNED_FIX(X) */
+
+/* A macro whose definition is a C expression to round the target-machine
+   floating point value X towards zero to an integer value (but still as a
+   floating point number).  X has type `REAL_VALUE_TYPE', and so does the
+   value.  */
+/* #define REAL_VALUE_RNDZINT(X) */
+
+/* A macro whose definition is a C expression to round the target-machine
+   floating point value X towards zero to an unsigned integer value (but still
+   represented as a floating point number).  X has type `REAL_VALUE_TYPE', and
+   so does the value.  */
+/* #define REAL_VALUE_UNSIGNED_RNDZINT(X) */
+
+/* A macro for a C expression which converts STRING, an expression of type
+   `char *', into a floating point number in the target machine's
+   representation for mode MODE.  The value has type `REAL_VALUE_TYPE'.  */
+/* #define REAL_VALUE_ATOF(STRING, MODE) */
+
+/* Define this macro if infinity is a possible floating point value, and
+   therefore division by 0 is legitimate.  */
+/* #define REAL_INFINITY */
+
+/* A macro for a C expression which determines whether X, a floating point
+   value, is infinity.  The value has type `int'.  By default, this is defined
+   to call `isinf'.  */
+/* #define REAL_VALUE_ISINF(X) */
+
+/* A macro for a C expression which determines whether X, a floating point
+   value, is a "nan" (not-a-number).  The value has type `int'.  By default,
+   this is defined to call `isnan'.  */
+/* #define REAL_VALUE_ISNAN(X) */
+
+/* Define the following additional macros if you want to make floating point
+   constant folding work while cross compiling.  If you don't define them,
+   cross compilation is still possible, but constant folding will not happen
+   for floating point values.  */
+
+/* A macro for a C statement which calculates an arithmetic operation of the
+   two floating point values X and Y, both of type `REAL_VALUE_TYPE' in the
+   target machine's representation, to produce a result of the same type and
+   representation which is stored in OUTPUT (which will be a variable).
+
+   The operation to be performed is specified by CODE, a tree code which will
+   always be one of the following: `PLUS_EXPR', `MINUS_EXPR', `MULT_EXPR',
+   `RDIV_EXPR', `MAX_EXPR', `MIN_EXPR'.
+
+   The expansion of this macro is responsible for checking for overflow.  If
+   overflow happens, the macro expansion should execute the statement `return
+   0;', which indicates the inability to perform the arithmetic operation
+   requested.  */
+/* #define REAL_ARITHMETIC(OUTPUT, CODE, X, Y) */
+
+/* The real.h file actually defines REAL_ARITHMETIC appropriately if it was
+   defined at all before entering into the code, by using #undef first.  */
+#define REAL_ARITHMETIC
+
+/* A macro for a C expression which returns the negative of the floating point
+   value X.  Both X and the value of the expression have type `REAL_VALUE_TYPE'
+   and are in the target machine's floating point representation.
+
+   There is no way for this macro to report overflow, since overflow can't
+   happen in the negation operation.  */
+/* #define REAL_VALUE_NEGATE(X) */
+
+/* A macro for a C expression which converts the floating point value X to mode
+   MODE.
+
+   Both X and the value of the expression are in the target machine's floating
+   point representation and have type `REAL_VALUE_TYPE'.  However, the value
+   should have an appropriate bit pattern to be output properly as a floating
+   constant whose precision accords with mode MODE.
+
+   There is no way for this macro to report overflow.  */
+/* #define REAL_VALUE_TRUNCATE(MODE, X) */
+
+/* A macro for a C expression which converts a floating point value X into a
+   double-precision integer which is then stored into LOW and HIGH, two
+   variables of type INT.  */
+/* #define REAL_VALUE_TO_INT(LOW, HIGH, X) */
+
+/* A macro for a C expression which converts a double-precision integer found
+   in LOW and HIGH, two variables of type INT, into a floating point value
+   which is then stored into X.  */
+/* #define REAL_VALUE_FROM_INT(X, LOW, HIGH) */
+
+\f
+/* Miscellaneous Parameters.  */
+
+/* Define this if you have defined special-purpose predicates in the file
+   `MACHINE.c'.  This macro is called within an initializer of an array of
+   structures.  The first field in the structure is the name of a predicate and
+   the second field is an array of rtl codes.  For each predicate, list all rtl
+   codes that can be in expressions matched by the predicate.  The list should
+   have a trailing comma.  Here is an example of two entries in the list for a
+   typical RISC machine:
+
+        #define PREDICATE_CODES \
+          {"gen_reg_rtx_operand", {SUBREG, REG}},  \
+          {"reg_or_short_cint_operand", {SUBREG, REG, CONST_INT}},
+
+   Defining this macro does not affect the generated code (however, incorrect
+   definitions that omit an rtl code that may be matched by the predicate can
+   cause the compiler to malfunction).  Instead, it allows the table built by
+   `genrecog' to be more compact and efficient, thus speeding up the compiler.
+   The most important predicates to include in the list specified by this macro
+   are thoses used in the most insn patterns.  */
+
+#define PREDICATE_CODES                                                        \
+  { "short_memory_operand",            { MEM }},                       \
+  { "long_memory_operand",             { MEM }},                       \
+  { "d30v_memory_operand",             { MEM }},                       \
+  { "single_reg_memory_operand",       { MEM }},                       \
+  { "const_addr_memory_operand",       { MEM }},                       \
+  { "call_operand",                    { MEM }},                       \
+  { "gpr_operand",                     { REG, SUBREG }},               \
+  { "accum_operand",                   { REG, SUBREG }},               \
+  { "gpr_or_accum_operand",            { REG, SUBREG }},               \
+  { "cr_operand",                      { REG, SUBREG }},               \
+  { "repeat_operand",                  { REG, SUBREG }},               \
+  { "flag_operand",                    { REG, SUBREG }},               \
+  { "br_flag_operand",                 { REG, SUBREG }},               \
+  { "br_flag_or_constant_operand",     { REG, SUBREG, CONST_INT }},    \
+  { "gpr_or_br_flag_operand",          { REG, SUBREG }},               \
+  { "f0_operand",                      { REG, SUBREG }},               \
+  { "f1_operand",                      { REG, SUBREG }},               \
+  { "carry_operand",                   { REG, SUBREG }},               \
+  { "reg_or_0_operand",                        { REG, SUBREG, CONST_INT,       \
+                                         CONST_DOUBLE }},              \
+  { "gpr_or_signed6_operand",          { REG, SUBREG, CONST_INT }},    \
+  { "gpr_or_unsigned5_operand",                { REG, SUBREG, CONST_INT }},    \
+  { "gpr_or_unsigned6_operand",                { REG, SUBREG, CONST_INT }},    \
+  { "gpr_or_constant_operand",         { REG, SUBREG, CONST_INT,       \
+                                         CONST, SYMBOL_REF,            \
+                                         LABEL_REF }},                 \
+  { "gpr_or_dbl_const_operand",                { REG, SUBREG, CONST_INT,       \
+                                         CONST, SYMBOL_REF,            \
+                                         LABEL_REF, CONST_DOUBLE }},   \
+  { "gpr_or_memory_operand",           { REG, SUBREG, MEM }},          \
+  { "move_input_operand",              { REG, SUBREG, MEM, CONST_INT,  \
+                                         CONST, SYMBOL_REF,            \
+                                         LABEL_REF, CONST_DOUBLE }},   \
+  { "move_output_operand",             { REG, SUBREG, MEM }},          \
+  { "signed6_operand",                 { CONST_INT }},                 \
+  { "unsigned5_operand",               { CONST_INT }},                 \
+  { "unsigned6_operand",               { CONST_INT }},                 \
+  { "bitset_operand",                  { CONST_INT }},                 \
+  { "condexec_test_operator",          { EQ, NE }},                    \
+  { "condexec_branch_operator",                { EQ, NE }},                    \
+  { "condexec_unary_operator",         { ABS, NEG, NOT, ZERO_EXTEND }}, \
+  { "condexec_addsub_operator",                { PLUS, MINUS }},               \
+  { "condexec_binary_operator",                { MULT, AND, IOR, XOR,          \
+                                         ASHIFT, ASHIFTRT, LSHIFTRT,   \
+                                         ROTATE, ROTATERT }},          \
+  { "condexec_shiftl_operator",                { ASHIFT, ROTATE }},            \
+  { "condexec_extend_operator",                { SIGN_EXTEND, ZERO_EXTEND }},  \
+  { "branch_zero_operator",            { EQ, NE }},                    \
+  { "cond_move_dest_operand",          { REG, SUBREG, MEM }},          \
+  { "cond_move_operand",               { REG, SUBREG, CONST_INT,       \
+                                         CONST, SYMBOL_REF,            \
+                                         LABEL_REF, MEM }},            \
+  { "cond_exec_operand",               { REG, SUBREG, CONST_INT,       \
+                                         CONST, SYMBOL_REF,            \
+                                         LABEL_REF, MEM }},            \
+  { "srelational_si_operator",         { EQ, NE, LT, LE, GT, GE }},    \
+  { "urelational_si_operator",         { LTU, LEU, GTU, GEU }},        \
+  { "relational_di_operator",          { EQ, NE, LT, LE, GT, GE,       \
+                                         LTU, LEU, GTU, GEU }},
+
+/* An alias for a machine mode name.  This is the machine mode that elements of
+   a jump-table should have.  */
+#define CASE_VECTOR_MODE SImode
+
+/* Define as C expression which evaluates to nonzero if the tablejump
+   instruction expects the table to contain offsets from the address of the
+   table.
+   Do not define this if the table should contain absolute addresses. */
+/* #define CASE_VECTOR_PC_RELATIVE 1 */
+
+/* Define this if control falls through a `case' insn when the index value is
+   out of range.  This means the specified default-label is actually ignored by
+   the `case' insn proper.  */
+/* #define CASE_DROPS_THROUGH */
+
+/* Define this to be the smallest number of different values for which it is
+   best to use a jump-table instead of a tree of conditional branches.  The
+   default is four for machines with a `casesi' instruction and five otherwise.
+   This is best for most machines.  */
+/* #define CASE_VALUES_THRESHOLD */
+
+/* Define this macro if operations between registers with integral mode smaller
+   than a word are always performed on the entire register.  Most RISC machines
+   have this property and most CISC machines do not.  */
+#define WORD_REGISTER_OPERATIONS 1
+
+/* Define this macro to be a C expression indicating when insns that read
+   memory in MODE, an integral mode narrower than a word, set the bits outside
+   of MODE to be either the sign-extension or the zero-extension of the data
+   read.  Return `SIGN_EXTEND' for values of MODE for which the insn
+   sign-extends, `ZERO_EXTEND' for which it zero-extends, and `NIL' for other
+   modes.
+
+   This macro is not called with MODE non-integral or with a width greater than
+   or equal to `BITS_PER_WORD', so you may return any value in this case.  Do
+   not define this macro if it would always return `NIL'.  On machines where
+   this macro is defined, you will normally define it as the constant
+   `SIGN_EXTEND' or `ZERO_EXTEND'.  */
+
+#define LOAD_EXTEND_OP(MODE) SIGN_EXTEND
+
+/* Define if loading short immediate values into registers sign extends.  */
+#define SHORT_IMMEDIATES_SIGN_EXTEND
+
+/* An alias for a tree code that should be used by default for conversion of
+   floating point values to fixed point.  Normally, `FIX_ROUND_EXPR' is used.  */
+#define IMPLICIT_FIX_EXPR FIX_ROUND_EXPR
+
+/* Define this macro if the same instructions that convert a floating point
+   number to a signed fixed point number also convert validly to an unsigned
+   one.  */
+/* #define FIXUNS_TRUNC_LIKE_FIX_TRUNC */
+
+/* An alias for a tree code that is the easiest kind of division to compile
+   code for in the general case.  It may be `TRUNC_DIV_EXPR', `FLOOR_DIV_EXPR',
+   `CEIL_DIV_EXPR' or `ROUND_DIV_EXPR'.  These four division operators differ
+   in how they round the result to an integer.  `EASY_DIV_EXPR' is used when it
+   is permissible to use any of those kinds of division and the choice should
+   be made on the basis of efficiency.  */
+#define EASY_DIV_EXPR TRUNC_DIV_EXPR
+
+/* The maximum number of bytes that a single instruction can move quickly from
+   memory to memory.  */
+#define MOVE_MAX 8
+
+/* The maximum number of bytes that a single instruction can move quickly from
+   memory to memory.  If this is undefined, the default is `MOVE_MAX'.
+   Otherwise, it is the constant value that is the largest value that
+   `MOVE_MAX' can have at run-time.  */
+/* #define MAX_MOVE_MAX */
+
+/* A C expression that is nonzero if on this machine the number of bits
+   actually used for the count of a shift operation is equal to the number of
+   bits needed to represent the size of the object being shifted.  When this
+   macro is non-zero, the compiler will assume that it is safe to omit a
+   sign-extend, zero-extend, and certain bitwise `and' instructions that
+   truncates the count of a shift operation.  On machines that have
+   instructions that act on bitfields at variable positions, which may include
+   `bit test' instructions, a nonzero `SHIFT_COUNT_TRUNCATED' also enables
+   deletion of truncations of the values that serve as arguments to bitfield
+   instructions.
+
+   If both types of instructions truncate the count (for shifts) and position
+   (for bitfield operations), or if no variable-position bitfield instructions
+   exist, you should define this macro.
+
+   However, on some machines, such as the 80386 and the 680x0, truncation only
+   applies to shift operations and not the (real or pretended) bitfield
+   operations.  Define `SHIFT_COUNT_TRUNCATED' to be zero on such machines.
+   Instead, add patterns to the `md' file that include the implied truncation
+   of the shift instructions.
+
+   You need not define this macro if it would always have the value of zero.  */
+/* #define SHIFT_COUNT_TRUNCATED */
+
+/* A C expression which is nonzero if on this machine it is safe to "convert"
+   an integer of INPREC bits to one of OUTPREC bits (where OUTPREC is smaller
+   than INPREC) by merely operating on it as if it had only OUTPREC bits.
+
+   On many machines, this expression can be 1.
+
+   When `TRULY_NOOP_TRUNCATION' returns 1 for a pair of sizes for modes for
+   which `MODES_TIEABLE_P' is 0, suboptimal code can result.  If this is the
+   case, making `TRULY_NOOP_TRUNCATION' return 0 in such cases may improve
+   things.  */
+#define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1
+
+/* A C expression describing the value returned by a comparison operator with
+   an integral mode and stored by a store-flag instruction (`sCOND') when the
+   condition is true.  This description must apply to *all* the `sCOND'
+   patterns and all the comparison operators whose results have a `MODE_INT'
+   mode.
+
+   A value of 1 or -1 means that the instruction implementing the comparison
+   operator returns exactly 1 or -1 when the comparison is true and 0 when the
+   comparison is false.  Otherwise, the value indicates which bits of the
+   result are guaranteed to be 1 when the comparison is true.  This value is
+   interpreted in the mode of the comparison operation, which is given by the
+   mode of the first operand in the `sCOND' pattern.  Either the low bit or the
+   sign bit of `STORE_FLAG_VALUE' be on.  Presently, only those bits are used
+   by the compiler.
+
+   If `STORE_FLAG_VALUE' is neither 1 or -1, the compiler will generate code
+   that depends only on the specified bits.  It can also replace comparison
+   operators with equivalent operations if they cause the required bits to be
+   set, even if the remaining bits are undefined.  For example, on a machine
+   whose comparison operators return an `SImode' value and where
+   `STORE_FLAG_VALUE' is defined as `0x80000000', saying that just the sign bit
+   is relevant, the expression
+
+        (ne:SI (and:SI X (const_int POWER-OF-2)) (const_int 0))
+
+   can be converted to
+
+        (ashift:SI X (const_int N))
+
+   where N is the appropriate shift count to move the bit being tested into the
+   sign bit.
+
+   There is no way to describe a machine that always sets the low-order bit for
+   a true value, but does not guarantee the value of any other bits, but we do
+   not know of any machine that has such an instruction.  If you are trying to
+   port GNU CC to such a machine, include an instruction to perform a
+   logical-and of the result with 1 in the pattern for the comparison operators
+   and let us know (*note How to Report Bugs: Bug Reporting.).
+
+   Often, a machine will have multiple instructions that obtain a value from a
+   comparison (or the condition codes).  Here are rules to guide the choice of
+   value for `STORE_FLAG_VALUE', and hence the instructions to be used:
+
+      * Use the shortest sequence that yields a valid definition for
+        `STORE_FLAG_VALUE'.  It is more efficient for the compiler to
+        "normalize" the value (convert it to, e.g., 1 or 0) than for
+        the comparison operators to do so because there may be
+        opportunities to combine the normalization with other
+        operations.
+
+      * For equal-length sequences, use a value of 1 or -1, with -1
+        being slightly preferred on machines with expensive jumps and
+        1 preferred on other machines.
+
+      * As a second choice, choose a value of `0x80000001' if
+        instructions exist that set both the sign and low-order bits
+        but do not define the others.
+
+      * Otherwise, use a value of `0x80000000'.
+
+   Many machines can produce both the value chosen for `STORE_FLAG_VALUE' and
+   its negation in the same number of instructions.  On those machines, you
+   should also define a pattern for those cases, e.g., one matching
+
+        (set A (neg:M (ne:M B C)))
+
+   Some machines can also perform `and' or `plus' operations on condition code
+   values with less instructions than the corresponding `sCOND' insn followed
+   by `and' or `plus'.  On those machines, define the appropriate patterns.
+   Use the names `incscc' and `decscc', respectively, for the the patterns
+   which perform `plus' or `minus' operations on condition code values.  See
+   `rs6000.md' for some examples.  The GNU Superoptizer can be used to find
+   such instruction sequences on other machines.
+
+   You need not define `STORE_FLAG_VALUE' if the machine has no store-flag
+   instructions.  */
+/* #define STORE_FLAG_VALUE */
+
+/* A C expression that gives a non-zero floating point value that is returned
+   when comparison operators with floating-point results are true.  Define this
+   macro on machine that have comparison operations that return floating-point
+   values.  If there are no such operations, do not define this macro.  */
+/* #define FLOAT_STORE_FLAG_VALUE */
+
+/* An alias for the machine mode for pointers.  On most machines, define this
+   to be the integer mode corresponding to the width of a hardware pointer;
+   `SImode' on 32-bit machine or `DImode' on 64-bit machines.  On some machines
+   you must define this to be one of the partial integer modes, such as
+   `PSImode'.
+
+   The width of `Pmode' must be at least as large as the value of
+   `POINTER_SIZE'.  If it is not equal, you must define the macro
+   `POINTERS_EXTEND_UNSIGNED' to specify how pointers are extended to `Pmode'.  */
+#define Pmode SImode
+
+/* An alias for the machine mode used for memory references to functions being
+   called, in `call' RTL expressions.  On most machines this should be
+   `QImode'.  */
+#define FUNCTION_MODE QImode
+
+/* A C expression for the maximum number of instructions above which the
+   function DECL should not be inlined.  DECL is a `FUNCTION_DECL' node.
+
+   The default definition of this macro is 64 plus 8 times the number of
+   arguments that the function accepts.  Some people think a larger threshold
+   should be used on RISC machines.  */
+/* #define INTEGRATE_THRESHOLD(DECL) */
+
+/* Define this if the preprocessor should ignore `#sccs' directives and print
+   no error message.
+
+   Defined in svr4.h.  */
+/* #define SCCS_DIRECTIVE */
+
+/* Define this macro if the system header files support C++ as well as C.  This
+   macro inhibits the usual method of using system header files in C++, which
+   is to pretend that the file's contents are enclosed in `extern "C" {...}'.  */
+/* #define NO_IMPLICIT_EXTERN_C */
+
+/* Define this macro if you want to implement any pragmas.  If defined, it
+   should be a C statement to be executed when `#pragma' is seen.  The argument
+   STREAM is the stdio input stream from which the source text can be read.
+
+   It is generally a bad idea to implement new uses of `#pragma'.  The only
+   reason to define this macro is for compatibility with other compilers that
+   do support `#pragma' for the sake of any user programs which already use it.  */
+/* #define HANDLE_PRAGMA(STREAM) */
+
+/* Define this macro to handle System V style pragmas (particularly #pack).
+
+   Defined in svr4.h.  */
+#define HANDLE_SYSV_PRAGMA
+
+/* Define this macro if you want to handle #pragma weak (HANDLE_SYSV_PRAGMA
+   must also be defined).  */
+/* #define HANDLE_WEAK_PRAGMA */
+
+/* If defined, a C expression whose value is nonzero if IDENTIFIER with
+   arguments ARGS is a valid machine specific attribute for DECL.  The
+   attributes in ATTRIBUTES have previously been assigned to DECL.  */
+/* #define VALID_MACHINE_DECL_ATTRIBUTE(DECL, ATTRIBUTES, IDENTIFIER, ARGS) */
+
+/* If defined, a C expression whose value is nonzero if IDENTIFIER with
+   arguments ARGS is a valid machine specific attribute for TYPE.  The
+   attributes in ATTRIBUTES have previously been assigned to TYPE.  */
+/* #define VALID_MACHINE_TYPE_ATTRIBUTE(TYPE, ATTRIBUTES, IDENTIFIER, ARGS) */
+
+/* If defined, a C expression whose value is zero if the attributes on TYPE1
+   and TYPE2 are incompatible, one if they are compatible, and two if they are
+   nearly compatible (which causes a warning to be generated).  */
+/* #define COMP_TYPE_ATTRIBUTES(TYPE1, TYPE2) */
+
+/* If defined, a C statement that assigns default attributes to newly defined
+   TYPE.  */
+/* #define SET_DEFAULT_TYPE_ATTRIBUTES(TYPE) */
+
+/* Define this macro to control use of the character `$' in identifier names.
+   The value should be 0, 1, or 2.  0 means `$' is not allowed by default; 1
+   means it is allowed by default if `-traditional' is used; 2 means it is
+   allowed by default provided `-ansi' is not used.  1 is the default; there is
+   no need to define this macro in that case.  */
+/* #define DOLLARS_IN_IDENTIFIERS */
+
+/* Define this macro if the assembler does not accept the character `$' in
+   label names.  By default constructors and destructors in G++ have `$' in the
+   identifiers.  If this macro is defined, `.' is used instead.
+
+   Defined in svr4.h.  */
+/* #define NO_DOLLAR_IN_LABEL */
+
+/* Define this macro if the assembler does not accept the character `.' in
+   label names.  By default constructors and destructors in G++ have names that
+   use `.'.  If this macro is defined, these names are rewritten to avoid `.'.  */
+/* #define NO_DOT_IN_LABEL */
+
+/* Define this macro if the target system expects every program's `main'
+   function to return a standard "success" value by default (if no other value
+   is explicitly returned).
+
+   The definition should be a C statement (sans semicolon) to generate the
+   appropriate rtl instructions.  It is used only when compiling the end of
+   `main'.  */
+/* #define DEFAULT_MAIN_RETURN */
+
+/* Define this if the target system supports the function `atexit' from the
+   ANSI C standard.  If this is not defined, and `INIT_SECTION_ASM_OP' is not
+   defined, a default `exit' function will be provided to support C++.
+
+   Defined by svr4.h */
+/* #define HAVE_ATEXIT */
+
+/* Define this if your `exit' function needs to do something besides calling an
+   external function `_cleanup' before terminating with `_exit'.  The
+   `EXIT_BODY' macro is only needed if netiher `HAVE_ATEXIT' nor
+   `INIT_SECTION_ASM_OP' are defined.  */
+/* #define EXIT_BODY */
+
+/* Define this macro as a C expression that is nonzero if it is safe for the
+   delay slot scheduler to place instructions in the delay slot of INSN, even
+   if they appear to use a resource set or clobbered in INSN.  INSN is always a
+   `jump_insn' or an `insn'; GNU CC knows that every `call_insn' has this
+   behavior.  On machines where some `insn' or `jump_insn' is really a function
+   call and hence has this behavior, you should define this macro.
+
+   You need not define this macro if it would always return zero.  */
+/* #define INSN_SETS_ARE_DELAYED(INSN) */
+
+/* Define this macro as a C expression that is nonzero if it is safe for the
+   delay slot scheduler to place instructions in the delay slot of INSN, even
+   if they appear to set or clobber a resource referenced in INSN.  INSN is
+   always a `jump_insn' or an `insn'.  On machines where some `insn' or
+   `jump_insn' is really a function call and its operands are registers whose
+   use is actually in the subroutine it calls, you should define this macro.
+   Doing so allows the delay slot scheduler to move instructions which copy
+   arguments into the argument registers into the delay slot of INSN.
+
+   You need not define this macro if it would always return zero.  */
+/* #define INSN_REFERENCES_ARE_DELAYED(INSN) */
+
+/* In rare cases, correct code generation requires extra machine dependent
+   processing between the second jump optimization pass and delayed branch
+   scheduling.  On those machines, define this macro as a C statement to act on
+   the code starting at INSN.  */
+#define MACHINE_DEPENDENT_REORG(INSN) d30v_machine_dependent_reorg (INSN)
+
+/* Define this macro if in some cases global symbols from one translation unit
+   may not be bound to undefined symbols in another translation unit without
+   user intervention.  For instance, under Microsoft Windows symbols must be
+   explicitly imported from shared libraries (DLLs).  */
+/* #define MULTIPLE_SYMBOL_SPACES */
+
+/* A C expression for the maximum number of instructions to execute via
+   conditional execution instructions instead of a branch.  A value of
+   BRANCH_COST+1 is the default if the machine does not use cc0, and 1 if it
+   does use cc0. */
+#define MAX_CONDITIONAL_EXECUTE d30v_cond_exec
+
+#define D30V_DEFAULT_MAX_CONDITIONAL_EXECUTE 4
+
+/* Values of the -mcond-exec=n string.  */
+extern int d30v_cond_exec;
+extern const char *d30v_cond_exec_string;
+
+/* Indicate how many instructions can be issued at the same time.  */
+#define ISSUE_RATE 2
diff --git a/gcc/config/d30v/d30v.md b/gcc/config/d30v/d30v.md
new file mode 100644 (file)
index 0000000..0e1d156
--- /dev/null
@@ -0,0 +1,3785 @@
+;; Mitsubishi D30V Machine description template
+;; Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
+;; Contributed by Cygnus Solutions.
+;;
+;; This file is part of GNU CC.
+;;
+;; GNU CC 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)
+;; any later version.
+;;
+;; GNU CC 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.
+
+;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
+
+\f
+;; ::::::::::::::::::::
+;; ::
+;; :: Constraints
+;; ::
+;; ::::::::::::::::::::
+
+;; Standard Constraints
+;;
+;; `m' A memory operand is allowed, with any kind of address that the
+;;     machine supports in general.
+;;
+;; `o' A memory operand is allowed, but only if the address is
+;;     "offsettable".  This means that adding a small integer (actually, the
+;;     width in bytes of the operand, as determined by its machine mode) may be
+;;     added to the address and the result is also a valid memory address.
+;;
+;; `V' A memory operand that is not offsettable.  In other words,
+;;     anything that would fit the `m' constraint but not the `o' constraint.
+;;
+;; `<' A memory operand with autodecrement addressing (either
+;;     predecrement or postdecrement) is allowed.
+;;
+;; `>' A memory operand with autoincrement addressing (either
+;;     preincrement or postincrement) is allowed.
+;;
+;; `r' A register operand is allowed provided that it is in a general
+;;     register.
+;;
+;; `d', `a', `f', ...
+;;     Other letters can be defined in machine-dependent fashion to stand for
+;;     particular classes of registers.  `d', `a' and `f' are defined on the
+;;     68000/68020 to stand for data, address and floating point registers.
+;;
+;; `i' An immediate integer operand (one with constant value) is allowed.
+;;     This includes symbolic constants whose values will be known only at
+;;     assembly time.
+;;
+;; `n' An immediate integer operand with a known numeric value is allowed.
+;;     Many systems cannot support assembly-time constants for operands less
+;;     than a word wide.  Constraints for these operands should use `n' rather
+;;     than `i'.
+;;
+;; 'I' First machine-dependent integer constant.
+;; 'J' Second machine-dependent integer constant.
+;; 'K' Third machine-dependent integer constant.
+;; 'L' Fourth machine-dependent integer constant.
+;; 'M' Fifth machine-dependent integer constant.
+;; 'N' Sixth machine-dependent integer constant.
+;; 'O' Seventh machine-dependent integer constant.
+;; 'P' Eighth machine-dependent integer constant.
+;;
+;;     Other letters in the range `I' through `P' may be defined in a
+;;     machine-dependent fashion to permit immediate integer operands with
+;;     explicit integer values in specified ranges.  For example, on the 68000,
+;;     `I' is defined to stand for the range of values 1 to 8.  This is the
+;;     range permitted as a shift count in the shift instructions.
+;;
+;; `E' An immediate floating operand (expression code `const_double') is
+;;     allowed, but only if the target floating point format is the same as
+;;     that of the host machine (on which the compiler is running).
+;;
+;; `F' An immediate floating operand (expression code `const_double') is
+;;     allowed.
+;;
+;; 'G' First machine-dependent const_double.
+;; 'H' Second machine-dependent const_double.
+;;
+;; `s' An immediate integer operand whose value is not an explicit
+;;     integer is allowed.
+;;
+;;     This might appear strange; if an insn allows a constant operand with a
+;;     value not known at compile time, it certainly must allow any known
+;;     value.  So why use `s' instead of `i'?  Sometimes it allows better code
+;;     to be generated.
+;;
+;;     For example, on the 68000 in a fullword instruction it is possible to
+;;     use an immediate operand; but if the immediate value is between -128 and
+;;     127, better code results from loading the value into a register and
+;;     using the register.  This is because the load into the register can be
+;;     done with a `moveq' instruction.  We arrange for this to happen by
+;;     defining the letter `K' to mean "any integer outside the range -128 to
+;;     127", and then specifying `Ks' in the operand constraints.
+;;
+;; `g' Any register, memory or immediate integer operand is allowed,
+;;     except for registers that are not general registers.
+;;
+;; `X' Any operand whatsoever is allowed, even if it does not satisfy
+;;     `general_operand'.  This is normally used in the constraint of a
+;;     `match_scratch' when certain alternatives will not actually require a
+;;     scratch register.
+;;
+;; `0' Match operand 0.
+;; `1' Match operand 1.
+;; `2' Match operand 2.
+;; `3' Match operand 3.
+;; `4' Match operand 4.
+;; `5' Match operand 5.
+;; `6' Match operand 6.
+;; `7' Match operand 7.
+;; `8' Match operand 8.
+;; `9' Match operand 9.
+;;
+;;     An operand that matches the specified operand number is allowed.  If a
+;;     digit is used together with letters within the same alternative, the
+;;     digit should come last.
+;;
+;;     This is called a "matching constraint" and what it really means is that
+;;     the assembler has only a single operand that fills two roles considered
+;;     separate in the RTL insn.  For example, an add insn has two input
+;;     operands and one output operand in the RTL, but on most CISC machines an
+;;     add instruction really has only two operands, one of them an
+;;     input-output operand:
+;;
+;;          addl #35,r12
+;;
+;;     Matching constraints are used in these circumstances.  More precisely,
+;;     the two operands that match must include one input-only operand and one
+;;     output-only operand.  Moreover, the digit must be a smaller number than
+;;     the number of the operand that uses it in the constraint.
+;;
+;;     For operands to match in a particular case usually means that they are
+;;     identical-looking RTL expressions.  But in a few special cases specific
+;;     kinds of dissimilarity are allowed.  For example, `*x' as an input
+;;     operand will match `*x++' as an output operand.  For proper results in
+;;     such cases, the output template should always use the output-operand's
+;;     number when printing the operand.
+;;
+;; `p' An operand that is a valid memory address is allowed.  This is for
+;;     "load address" and "push address" instructions.
+;;
+;;     `p' in the constraint must be accompanied by `address_operand' as the
+;;     predicate in the `match_operand'.  This predicate interprets the mode
+;;     specified in the `match_operand' as the mode of the memory reference for
+;;     which the address would be valid.
+;;
+;; `Q` First non constant, non register machine-dependent insns
+;; `R` Second non constant, non register machine-dependent insns
+;; `S` Third non constant, non register machine-dependent insns
+;; `T` Fourth non constant, non register machine-dependent insns
+;; `U` Fifth non constant, non register machine-dependent insns
+;;
+;;     Letters in the range `Q' through `U' may be defined in a
+;;     machine-dependent fashion to stand for arbitrary operand types.  The
+;;     machine description macro `EXTRA_CONSTRAINT' is passed the operand as
+;;     its first argument and the constraint letter as its second operand.
+;;
+;;     A typical use for this would be to distinguish certain types of memory
+;;     references that affect other insn operands.
+;;
+;;     Do not define these constraint letters to accept register references
+;;     (`reg'); the reload pass does not expect this and would not handle it
+;;     properly.
+
+;; Multiple Alternative Constraints
+;; `?' Disparage slightly the alternative that the `?' appears in, as a
+;;     choice when no alternative applies exactly.  The compiler regards this
+;;     alternative as one unit more costly for each `?' that appears in it.
+;;
+;; `!' Disparage severely the alternative that the `!' appears in.  This
+;;     alternative can still be used if it fits without reloading, but if
+;;     reloading is needed, some other alternative will be used.
+
+;; Constraint modifiers
+;; `=' Means that this operand is write-only for this instruction: the
+;;     previous value is discarded and replaced by output data.
+;;
+;; `+' Means that this operand is both read and written by the
+;;     instruction.
+;;
+;;     When the compiler fixes up the operands to satisfy the constraints, it
+;;     needs to know which operands are inputs to the instruction and which are
+;;     outputs from it.  `=' identifies an output; `+' identifies an operand
+;;     that is both input and output; all other operands are assumed to be
+;;     input only.
+;;
+;; `&' Means (in a particular alternative) that this operand is written
+;;     before the instruction is finished using the input operands.  Therefore,
+;;     this operand may not lie in a register that is used as an input operand
+;;     or as part of any memory address.
+;;
+;;     `&' applies only to the alternative in which it is written.  In
+;;     constraints with multiple alternatives, sometimes one alternative
+;;     requires `&' while others do not.
+;;
+;;     `&' does not obviate the need to write `='.
+;;
+;; `%' Declares the instruction to be commutative for this operand and the
+;;     following operand.  This means that the compiler may interchange the two
+;;     operands if that is the cheapest way to make all operands fit the
+;;     constraints.  This is often used in patterns for addition instructions
+;;     that really have only two operands: the result must go in one of the
+;;     arguments.
+;;
+;; `#' Says that all following characters, up to the next comma, are to be
+;;     ignored as a constraint.  They are significant only for choosing
+;;     register preferences.
+;;
+;; `*' Says that the following character should be ignored when choosing
+;;     register preferences.  `*' has no effect on the meaning of the
+;;     constraint as a constraint, and no effect on reloading.
+
+;; ::::::::::::::::::::
+;; ::
+;; :: D30V register classes
+;; ::
+;; ::::::::::::::::::::
+
+;; `a' Accumulator registers (a0, a1)
+;; `b' Flag registers for speculative execution (f0, f1)
+;; `c' CR registers
+;; `d' GPR registers
+;; `e' Even GPR registers
+;; `f' Any flag registers (f0, f1, ..., c)
+;; `l' CR7, the repeat count
+;; `x' F0
+;; `y' F1
+;; `z' Flag registers other than F0 and F1.
+
+;; ::::::::::::::::::::
+;; ::
+;; :: D30V special constraints
+;; ::
+;; ::::::::::::::::::::
+
+;; `G' Const double with 0 in both low & high part.
+;; `H' Unused.
+;; `I' Signed 6 bit integer constant (>= -32 && <= 31).
+;; `J' Unsigned 5 bit integer constant (>= 0 && <= 31).
+;; `K' Integer constant with 1 bit set (for bset).
+;; `L' Integer constant with 1 bit clear (for bclr).
+;; `M' Integer constant 32.
+;; `N' Integer constant 1.
+;; `O' Integer constant 0.
+;; `P' Integer constant >= 32 && <= 63.
+;; `Q' Short memory operand (can be done in small insn).
+;; `R' Memory operand using a single register for address.
+;; `S' Memory operand to constant address.
+;; `T' Unused.
+;; `U' Unused.
+
+;; ::::::::::::::::::::
+;; ::
+;; :: Standard operand flags
+;; ::
+;; ::::::::::::::::::::
+
+;; `='  Output a number unique to each instruction in the compilation.
+;; `a'  Substitute an operand as if it were a memory reference.
+;; `c'  Omit the syntax that indicates an immediate operand.
+;; `l'  Substitute a LABEL_REF into a jump instruction.
+;; `n'  Like %cDIGIT, except negate the value before printing.
+
+;; ::::::::::::::::::::
+;; ::
+;; :: D30V print_operand flags
+;; ::
+;; ::::::::::::::::::::
+
+;; `.' Print r0
+;; `f'  Print a SF constant as an int.
+;; `s'  Subtract 32 and negate.
+;; `A'  Print accumulator number without an `a' in front of it.
+;; `B'  Print bit offset for BSET, etc. instructions.
+;; `E'  Print u if this is zero extend, nothing if this is sign extend.
+;; `F'  Emit /{f,t,x}{f,t,x} for executing a false condition.
+;; `L'  Print the lower half of a 64 bit item.
+;; `M'  Print a memory reference for ld/st instructions.
+;; `R'  Return appropriate cmp instruction for relational test.
+;; `S'  Subtract 32.
+;; `T'  Emit /{f,t,x}{f,t,x} for executing a true condition.
+;; `U'  Print the upper half of a 64 bit item.
+
+\f
+;; ::::::::::::::::::::
+;; ::
+;; :: Attributes
+;; ::
+;; ::::::::::::::::::::
+
+;; The `define_attr' expression is used to define each attribute required by
+;; the target machine.  It looks like:
+;;
+;; (define_attr NAME LIST-OF-VALUES DEFAULT)
+
+;; NAME is a string specifying the name of the attribute being defined.
+
+;; LIST-OF-VALUES is either a string that specifies a comma-separated list of
+;; values that can be assigned to the attribute, or a null string to indicate
+;; that the attribute takes numeric values.
+
+;; DEFAULT is an attribute expression that gives the value of this attribute
+;; for insns that match patterns whose definition does not include an explicit
+;; value for this attribute.
+
+;; For each defined attribute, a number of definitions are written to the
+;; `insn-attr.h' file.  For cases where an explicit set of values is specified
+;; for an attribute, the following are defined:
+
+;; * A `#define' is written for the symbol `HAVE_ATTR_NAME'.
+;;
+;; * An enumeral class is defined for `attr_NAME' with elements of the
+;;   form `UPPER-NAME_UPPER-VALUE' where the attribute name and value are first
+;;   converted to upper case.
+;;
+;; * A function `get_attr_NAME' is defined that is passed an insn and
+;;   returns the attribute value for that insn.
+
+;; For example, if the following is present in the `md' file:
+;;
+;; (define_attr "type" "branch,fp,load,store,arith" ...)
+;;
+;; the following lines will be written to the file `insn-attr.h'.
+;;
+;; #define HAVE_ATTR_type
+;; enum attr_type {TYPE_BRANCH, TYPE_FP, TYPE_LOAD, TYPE_STORE, TYPE_ARITH};
+;; extern enum attr_type get_attr_type ();
+
+;; If the attribute takes numeric values, no `enum' type will be defined and
+;; the function to obtain the attribute's value will return `int'.
+
+;; Note, we lie a little bit here to make it simpler to optimize.  We pretend there
+;; is a separate long functional unit for long instructions that uses both the IU & MU.
+
+(define_attr "type" "iu,mu,br,br2,either,scarry,lcarry,scmp,lcmp,sload,lload,mul,long,multi,unknown"
+  (const_string "unknown"))
+
+;; Length in word units
+(define_attr "length" ""
+  (cond [(eq_attr "type" "iu,mu,either,scmp,sload,mul,scarry,")
+                                               (const_int 4)
+        (eq_attr "type" "long,lcmp,lload,lcarry")
+                                               (const_int 8)
+        (eq_attr "type" "multi,unknown")       (const_int 64)  ;; set higher to give a fudge factor
+        (eq_attr "type" "br")                  (if_then_else (and (ge (minus (pc) (match_dup 0))
+                                                                      (const_int -1048576))
+                                                                  (lt (minus (pc) (match_dup 0))
+                                                                      (const_int 1048575)))
+                                                             (const_int 4)
+                                                             (const_int 8))
+        (eq_attr "type" "br2")                 (if_then_else (and (ge (minus (pc) (match_dup 0))
+                                                                      (const_int -16384))
+                                                                  (lt (minus (pc) (match_dup 0))
+                                                                      (const_int 16383)))
+                                                             (const_int 4)
+                                                             (const_int 8))]
+       (const_int 8)))
+
+\f
+;; ::::::::::::::::::::
+;; ::
+;; :: Function Units
+;; ::
+;; ::::::::::::::::::::
+
+;; On most RISC machines, there are instructions whose results are not
+;; available for a specific number of cycles.  Common cases are instructions
+;; that load data from memory.  On many machines, a pipeline stall will result
+;; if the data is referenced too soon after the load instruction.
+
+;; In addition, many newer microprocessors have multiple function units,
+;; usually one for integer and one for floating point, and often will incur
+;; pipeline stalls when a result that is needed is not yet ready.
+
+;; The descriptions in this section allow the specification of how much time
+;; must elapse between the execution of an instruction and the time when its
+;; result is used.  It also allows specification of when the execution of an
+;; instruction will delay execution of similar instructions due to function
+;; unit conflicts.
+
+;; For the purposes of the specifications in this section, a machine is divided
+;; into "function units", each of which execute a specific class of
+;; instructions in first-in-first-out order.  Function units that accept one
+;; instruction each cycle and allow a result to be used in the succeeding
+;; instruction (usually via forwarding) need not be specified.  Classic RISC
+;; microprocessors will normally have a single function unit, which we can call
+;; `memory'.  The newer "superscalar" processors will often have function units
+;; for floating point operations, usually at least a floating point adder and
+;; multiplier.
+
+;; Each usage of a function units by a class of insns is specified with a
+;; `define_function_unit' expression, which looks like this:
+
+;; (define_function_unit NAME MULTIPLICITY SIMULTANEITY TEST READY-DELAY
+;;   ISSUE-DELAY [CONFLICT-LIST])
+
+;; NAME is a string giving the name of the function unit.
+
+;; MULTIPLICITY is an integer specifying the number of identical units in the
+;; processor.  If more than one unit is specified, they will be scheduled
+;; independently.  Only truly independent units should be counted; a pipelined
+;; unit should be specified as a single unit.  (The only common example of a
+;; machine that has multiple function units for a single instruction class that
+;; are truly independent and not pipelined are the two multiply and two
+;; increment units of the CDC 6600.)
+
+;; SIMULTANEITY specifies the maximum number of insns that can be executing in
+;; each instance of the function unit simultaneously or zero if the unit is
+;; pipelined and has no limit.
+
+;; All `define_function_unit' definitions referring to function unit NAME must
+;; have the same name and values for MULTIPLICITY and SIMULTANEITY.
+
+;; TEST is an attribute test that selects the insns we are describing in this
+;; definition.  Note that an insn may use more than one function unit and a
+;; function unit may be specified in more than one `define_function_unit'.
+
+;; READY-DELAY is an integer that specifies the number of cycles after which
+;; the result of the instruction can be used without introducing any stalls.
+
+;; ISSUE-DELAY is an integer that specifies the number of cycles after the
+;; instruction matching the TEST expression begins using this unit until a
+;; subsequent instruction can begin.  A cost of N indicates an N-1 cycle delay.
+;; A subsequent instruction may also be delayed if an earlier instruction has a
+;; longer READY-DELAY value.  This blocking effect is computed using the
+;; SIMULTANEITY, READY-DELAY, ISSUE-DELAY, and CONFLICT-LIST terms.  For a
+;; normal non-pipelined function unit, SIMULTANEITY is one, the unit is taken
+;; to block for the READY-DELAY cycles of the executing insn, and smaller
+;; values of ISSUE-DELAY are ignored.
+
+;; CONFLICT-LIST is an optional list giving detailed conflict costs for this
+;; unit.  If specified, it is a list of condition test expressions to be
+;; applied to insns chosen to execute in NAME following the particular insn
+;; matching TEST that is already executing in NAME.  For each insn in the list,
+;; ISSUE-DELAY specifies the conflict cost; for insns not in the list, the cost
+;; is zero.  If not specified, CONFLICT-LIST defaults to all instructions that
+;; use the function unit.
+
+;; Typical uses of this vector are where a floating point function unit can
+;; pipeline either single- or double-precision operations, but not both, or
+;; where a memory unit can pipeline loads, but not stores, etc.
+
+;; As an example, consider a classic RISC machine where the result of a load
+;; instruction is not available for two cycles (a single "delay" instruction is
+;; required) and where only one load instruction can be executed
+;; simultaneously.  This would be specified as:
+
+;; (define_function_unit "memory" 1 1 (eq_attr "type" "load") 2 0)
+
+;; For the case of a floating point function unit that can pipeline
+;; either single or double precision, but not both, the following could be
+;; specified:
+;;
+;; (define_function_unit "fp" 1 0
+;;   (eq_attr "type" "sp_fp") 4 4
+;;   [(eq_attr "type" "dp_fp")])
+;;
+;; (define_function_unit "fp" 1 0
+;;   (eq_attr "type" "dp_fp") 4 4
+;;   [(eq_attr "type" "sp_fp")])
+
+;; Note: The scheduler attempts to avoid function unit conflicts and uses all
+;; the specifications in the `define_function_unit' expression.  It has
+;; recently come to our attention that these specifications may not allow
+;; modeling of some of the newer "superscalar" processors that have insns using
+;; multiple pipelined units.  These insns will cause a potential conflict for
+;; the second unit used during their execution and there is no way of
+;; representing that conflict.  We welcome any examples of how function unit
+;; conflicts work in such processors and suggestions for their representation.
+
+(define_function_unit "iu" 1 0
+  (eq_attr "type" "iu,either")
+  1 1
+  [(eq_attr "type" "long,lcmp,lload,multi,unknown")])
+
+(define_function_unit "iu" 1 0
+  (eq_attr "type" "scmp,mul,scarry")
+  2 1
+  [(eq_attr "type" "long,lcmp,lload,multi,unknown")])
+
+(define_function_unit "mu" 1 0
+  (eq_attr "type" "mu,br,br2,either")
+  1 1
+  [(eq_attr "type" "long,lcmp,lload,multi,unknown")])
+
+(define_function_unit "mu" 1 0
+  (eq_attr "type" "scarry,scmp,sload")
+  2 1
+  [(eq_attr "type" "long,lcmp,lload,multi,unknown")])
+
+(define_function_unit "long" 1 0
+  (eq_attr "type" "long,multi,unknown")
+  1 1
+  [(eq_attr "type" "iu,mu,scarry,scmp,sload,mul,br,br2,either")])
+
+(define_function_unit "long" 1 0
+  (eq_attr "type" "lcmp,lload,lcarry")
+  2 1
+  [(eq_attr "type" "iu,mu,scarry,scmp,sload,mul,br,br2,either")])
+
+\f
+;; ::::::::::::::::::::
+;; ::
+;; :: Delay Slots
+;; ::
+;; ::::::::::::::::::::
+
+;; The insn attribute mechanism can be used to specify the requirements for
+;; delay slots, if any, on a target machine.  An instruction is said to require
+;; a "delay slot" if some instructions that are physically after the
+;; instruction are executed as if they were located before it.  Classic
+;; examples are branch and call instructions, which often execute the following
+;; instruction before the branch or call is performed.
+
+;; On some machines, conditional branch instructions can optionally "annul"
+;; instructions in the delay slot.  This means that the instruction will not be
+;; executed for certain branch outcomes.  Both instructions that annul if the
+;; branch is true and instructions that annul if the branch is false are
+;; supported.
+
+;; Delay slot scheduling differs from instruction scheduling in that
+;; determining whether an instruction needs a delay slot is dependent only
+;; on the type of instruction being generated, not on data flow between the
+;; instructions.  See the next section for a discussion of data-dependent
+;; instruction scheduling.
+
+;; The requirement of an insn needing one or more delay slots is indicated via
+;; the `define_delay' expression.  It has the following form:
+;;
+;; (define_delay TEST
+;;   [DELAY-1 ANNUL-TRUE-1 ANNUL-FALSE-1
+;;    DELAY-2 ANNUL-TRUE-2 ANNUL-FALSE-2
+;;    ...])
+
+;; TEST is an attribute test that indicates whether this `define_delay' applies
+;; to a particular insn.  If so, the number of required delay slots is
+;; determined by the length of the vector specified as the second argument.  An
+;; insn placed in delay slot N must satisfy attribute test DELAY-N.
+;; ANNUL-TRUE-N is an attribute test that specifies which insns may be annulled
+;; if the branch is true.  Similarly, ANNUL-FALSE-N specifies which insns in
+;; the delay slot may be annulled if the branch is false.  If annulling is not
+;; supported for that delay slot, `(nil)' should be coded.
+
+;; For example, in the common case where branch and call insns require a single
+;; delay slot, which may contain any insn other than a branch or call, the
+;; following would be placed in the `md' file:
+
+;; (define_delay (eq_attr "type" "branch,call")
+;;              [(eq_attr "type" "!branch,call") (nil) (nil)])
+
+;; Multiple `define_delay' expressions may be specified.  In this case, each
+;; such expression specifies different delay slot requirements and there must
+;; be no insn for which tests in two `define_delay' expressions are both true.
+
+;; For example, if we have a machine that requires one delay slot for branches
+;; but two for calls, no delay slot can contain a branch or call insn, and any
+;; valid insn in the delay slot for the branch can be annulled if the branch is
+;; true, we might represent this as follows:
+
+;; (define_delay (eq_attr "type" "branch")
+;;   [(eq_attr "type" "!branch,call")
+;;    (eq_attr "type" "!branch,call")
+;;    (nil)])
+;;
+;; (define_delay (eq_attr "type" "call")
+;;   [(eq_attr "type" "!branch,call") (nil) (nil)
+;;    (eq_attr "type" "!branch,call") (nil) (nil)])
+
+\f
+;; ::::::::::::::::::::
+;; ::
+;; :: Moves
+;; ::
+;; ::::::::::::::::::::
+
+;; Wrap moves in define_expand to prevent memory->memory moves from being
+;; generated at the RTL level, which generates better code for most machines
+;; which can't do mem->mem moves.
+
+;; If operand 0 is a `subreg' with mode M of a register whose own mode is wider
+;; than M, the effect of this instruction is to store the specified value in
+;; the part of the register that corresponds to mode M.  The effect on the rest
+;; of the register is undefined.
+
+;; This class of patterns is special in several ways.  First of all, each of
+;; these names *must* be defined, because there is no other way to copy a datum
+;; from one place to another.
+
+;; Second, these patterns are not used solely in the RTL generation pass.  Even
+;; the reload pass can generate move insns to copy values from stack slots into
+;; temporary registers.  When it does so, one of the operands is a hard
+;; register and the other is an operand that can need to be reloaded into a
+;; register.
+
+;; Therefore, when given such a pair of operands, the pattern must
+;; generate RTL which needs no reloading and needs no temporary
+;; registers--no registers other than the operands.  For example, if
+;; you support the pattern with a `define_expand', then in such a
+;; case the `define_expand' mustn't call `force_reg' or any other such
+;; function which might generate new pseudo registers.
+
+;; This requirement exists even for subword modes on a RISC machine
+;; where fetching those modes from memory normally requires several
+;; insns and some temporary registers.  Look in `spur.md' to see how
+;; the requirement can be satisfied.
+
+;; During reload a memory reference with an invalid address may be passed as an
+;; operand.  Such an address will be replaced with a valid address later in the
+;; reload pass.  In this case, nothing may be done with the address except to
+;; use it as it stands.  If it is copied, it will not be replaced with a valid
+;; address.  No attempt should be made to make such an address into a valid
+;; address and no routine (such as `change_address') that will do so may be
+;; called.  Note that `general_operand' will fail when applied to such an
+;; address.
+;;
+;; The global variable `reload_in_progress' (which must be explicitly declared
+;; if required) can be used to determine whether such special handling is
+;; required.
+;;
+;; The variety of operands that have reloads depends on the rest of
+;; the machine description, but typically on a RISC machine these can
+;; only be pseudo registers that did not get hard registers, while on
+;; other machines explicit memory references will get optional
+;; reloads.
+;;
+;; If a scratch register is required to move an object to or from memory, it
+;; can be allocated using `gen_reg_rtx' prior to reload.  But this is
+;; impossible during and after reload.  If there are cases needing scratch
+;; registers after reload, you must define `SECONDARY_INPUT_RELOAD_CLASS' and
+;; perhaps also `SECONDARY_OUTPUT_RELOAD_CLASS' to detect them, and provide
+;; patterns `reload_inM' or `reload_outM' to handle them.  *Note Register
+;; Classes::.
+
+;; The constraints on a `moveM' must permit moving any hard register to any
+;; other hard register provided that `HARD_REGNO_MODE_OK' permits mode M in
+;; both registers and `REGISTER_MOVE_COST' applied to their classes returns a
+;; value of 2.
+
+;; It is obligatory to support floating point `moveM' instructions
+;; into and out of any registers that can hold fixed point values,
+;; because unions and structures (which have modes `SImode' or
+;; `DImode') can be in those registers and they may have floating
+;; point members.
+
+;; There may also be a need to support fixed point `moveM' instructions in and
+;; out of floating point registers.  Unfortunately, I have forgotten why this
+;; was so, and I don't know whether it is still true.  If `HARD_REGNO_MODE_OK'
+;; rejects fixed point values in floating point registers, then the constraints
+;; of the fixed point `moveM' instructions must be designed to avoid ever
+;; trying to reload into a floating point register.
+
+(define_expand "movqi"
+  [(set (match_operand:QI 0 "general_operand" "")
+       (match_operand:QI 1 "general_operand" ""))]
+  ""
+  "
+{
+  if (!reload_in_progress && !reload_completed
+      && !register_operand (operands[0], QImode)
+      && !reg_or_0_operand (operands[1], QImode))
+    operands[1] = copy_to_mode_reg (QImode, operands[1]);
+}")
+
+(define_insn "*movqi_internal"
+  [(set (match_operand:QI 0 "move_output_operand" "=d,d,d,d,Q,m,Q,m,d,c")
+       (match_operand:QI 1 "move_input_operand" "dI,i,Q,m,d,d,O,O,c,d"))]
+  "register_operand (operands[0], QImode) || reg_or_0_operand (operands[1], QImode)"
+  "@
+    or %0,%.,%1
+    or %0,%.,%1
+    ldb %0,%M1
+    ldb %0,%M1
+    stb %1,%M0
+    stb %1,%M0
+    stb %.,%M0
+    stb %.,%M0
+    mvfsys %0,%1
+    mvtsys %0,%1"
+  [(set_attr "length" "4,8,4,8,4,8,4,8,4,4")
+   (set_attr "type" "either,long,sload,lload,mu,long,mu,long,mu,mu")])
+
+(define_expand "movhi"
+  [(set (match_operand:HI 0 "general_operand" "")
+       (match_operand:HI 1 "general_operand" ""))]
+  ""
+  "
+{
+  if (!reload_in_progress && !reload_completed
+      && !register_operand (operands[0], HImode)
+      && !reg_or_0_operand (operands[1], HImode))
+    operands[1] = copy_to_mode_reg (HImode, operands[1]);
+}")
+
+(define_insn "*movhi_internal"
+  [(set (match_operand:HI 0 "move_output_operand" "=d,d,d,d,Q,m,Q,m,d,c")
+       (match_operand:HI 1 "move_input_operand" "dI,i,Q,m,d,d,O,O,c,d"))]
+  "register_operand (operands[0], HImode) || reg_or_0_operand (operands[1], HImode)"
+  "@
+    or %0,%.,%1
+    or %0,%.,%1
+    ldh %0,%M1
+    ldh %0,%M1
+    sth %1,%M0
+    sth %1,%M0
+    sth %.,%M0
+    sth %.,%M0
+    mvfsys %0,%1
+    mvtsys %0,%1"
+  [(set_attr "length" "4,8,4,8,4,8,4,8,4,4")
+   (set_attr "type" "either,long,sload,lload,mu,long,mu,long,mu,mu")])
+
+(define_expand "movsi"
+  [(set (match_operand:SI 0 "general_operand" "")
+       (match_operand:SI 1 "general_operand" ""))]
+  ""
+  "
+{
+  if (!reload_in_progress && !reload_completed
+      && !register_operand (operands[0], SImode)
+      && !reg_or_0_operand (operands[1], SImode))
+    operands[1] = copy_to_mode_reg (SImode, operands[1]);
+
+  /* Convert addressing modes into the appropriate add/sub with the clobbers
+     needed.  This is generated by builtin_setjmp in the exception handling. */
+  if (GET_CODE (operands[1]) == PLUS)
+    {
+      emit_insn (gen_addsi3 (operands[0], XEXP (operands[1], 0),
+                            XEXP (operands[1], 1)));
+      DONE;
+    }
+
+  else if (GET_CODE (operands[1]) == MINUS)
+    {
+      emit_insn (gen_subsi3 (operands[0], XEXP (operands[1], 0),
+                            XEXP (operands[1], 1)));
+      DONE;
+    }
+}")
+
+(define_insn "*movsi_internal"
+  [(set (match_operand:SI 0 "move_output_operand" "=d,d,d,d,d,Q,m,Q,m,d,c")
+       (match_operand:SI 1 "move_input_operand" "dI,F,i,Q,m,d,d,O,O,c,d"))]
+  "register_operand (operands[0], SImode) || reg_or_0_operand (operands[1], SImode)"
+  "@
+    or %0,%.,%1
+    or %0,%.,%L1
+    or %0,%.,%1
+    ldw %0,%M1
+    ldw %0,%M1
+    stw %1,%M0
+    stw %1,%M0
+    stw %.,%M0
+    stw %.,%M0
+    mvfsys %0,%1
+    mvtsys %0,%1"
+  [(set_attr "length" "4,8,8,4,8,4,8,4,8,4,4")
+   (set_attr "type" "either,long,long,sload,lload,mu,long,mu,long,mu,mu")])
+
+(define_expand "movdi"
+  [(set (match_operand:DI 0 "general_operand" "")
+       (match_operand:DI 1 "general_operand" ""))]
+  ""
+  "
+{
+  if (!reload_in_progress && !reload_completed
+      && !register_operand (operands[0], DImode)
+      && !register_operand (operands[1], DImode))
+    operands[1] = copy_to_mode_reg (DImode, operands[1]);
+}")
+
+(define_insn "*movdi_internal"
+  [(set (match_operand:DI 0 "move_output_operand" "=e,e,e,e,Q,m,e,a,a")
+       (match_operand:DI 1 "move_input_operand" "eI,iF,Q,m,e,e,a,e,O"))]
+  "register_operand (operands[0], DImode) || register_operand (operands[1], DImode)"
+  "* return d30v_move_2words (operands, insn);"
+  [(set_attr "length" "8,16,4,8,4,8,8,4,4")
+   (set_attr "type" "multi,multi,sload,lload,mu,long,multi,iu,iu")])
+
+(define_split
+  [(set (match_operand:DI 0 "gpr_operand" "")
+       (match_operand:DI 1 "gpr_or_dbl_const_operand" ""))]
+  "reload_completed"
+  [(set (match_dup 2) (match_dup 3))
+   (set (match_dup 4) (match_dup 5))]
+  "
+{
+  d30v_split_double (operands[0], &operands[2], &operands[4]);
+  d30v_split_double (operands[1], &operands[3], &operands[5]);
+}")
+
+(define_expand "movsf"
+  [(set (match_operand:SF 0 "general_operand" "")
+       (match_operand:SF 1 "general_operand" ""))]
+  ""
+  "
+{
+  if (!reload_in_progress && !reload_completed
+      && !register_operand (operands[0], SFmode)
+      && !reg_or_0_operand (operands[1], SFmode))
+    operands[1] = copy_to_mode_reg (SFmode, operands[1]);
+}")
+
+(define_insn "*movsf_internal"
+  [(set (match_operand:SF 0 "move_output_operand" "=d,d,d,d,d,Q,m,Q,m")
+       (match_operand:SF 1 "move_input_operand" "d,G,F,Q,m,d,d,G,G"))]
+  "register_operand (operands[0], SFmode) || reg_or_0_operand (operands[1], SFmode)"
+  "@
+    or %0,%.,%1
+    or %0,%.,0
+    or %0,%.,%f1
+    ldw %0,%M1
+    ldw %0,%M1
+    stw %1,%M0
+    stw %1,%M0
+    stw %.,%M0
+    stw %.,%M0"
+  [(set_attr "length" "4,4,8,4,8,4,8,4,8")
+   (set_attr "type" "either,either,long,sload,lload,mu,long,mu,long")])
+
+(define_expand "movdf"
+  [(set (match_operand:DF 0 "general_operand" "")
+       (match_operand:DF 1 "general_operand" ""))]
+  ""
+  "
+{
+  if (!reload_in_progress && !reload_completed
+      && !register_operand (operands[0], DFmode)
+      && !register_operand (operands[1], DFmode))
+    operands[1] = copy_to_mode_reg (DFmode, operands[1]);
+}")
+
+(define_insn "*movdf_internal"
+  [(set (match_operand:DF 0 "move_output_operand" "=e,e,e,e,Q,m,!*e,!*a")
+       (match_operand:DF 1 "move_input_operand" "eG,F,Q,m,e,e,!*a,!*e"))]
+  "register_operand (operands[0], DFmode) || register_operand (operands[1], DFmode)"
+  "* return d30v_move_2words (operands, insn);"
+  [(set_attr "length" "8,16,4,8,4,8,8,4")
+   (set_attr "type" "multi,multi,sload,lload,mu,long,multi,iu")])
+
+(define_split
+  [(set (match_operand:DF 0 "gpr_operand" "")
+       (match_operand:DF 1 "gpr_or_dbl_const_operand" ""))]
+  "reload_completed"
+  [(set (match_dup 2) (match_dup 3))
+   (set (match_dup 4) (match_dup 5))]
+  "
+{
+  d30v_split_double (operands[0], &operands[2], &operands[4]);
+  d30v_split_double (operands[1], &operands[3], &operands[5]);
+}")
+
+(define_expand "movcc"
+  [(set (match_operand:CC 0 "general_operand" "")
+       (match_operand:CC 1 "general_operand" ""))]
+  ""
+  "
+{
+  if (!reload_in_progress && !reload_completed
+      && GET_CODE (operands[0]) == MEM
+      && GET_CODE (operands[1]) == MEM)
+    operands[1] = copy_to_mode_reg (CCmode, operands[1]);
+}")
+
+(define_insn "*movcc_internal"
+  [(set (match_operand:CC 0 "move_output_operand" "=f,f,f,d,?d,f,d,*d,*d,*Q,*m")
+       (match_operand:CC 1 "move_input_operand" "f,O,N,b,f,d,dON,*Q,*m,*d,*d"))]
+  "!memory_operand (operands[0], CCmode) || !memory_operand (operands[1], CCmode)"
+  "@
+    orfg %0,%1,%1
+    andfg %0,%0,0
+    orfg %0,%0,1
+    #
+    mvfsys %0,%1
+    cmpne %0,%1,0
+    or %0,%.,%1
+    ldb %0,%M1
+    ldb %0,%M1
+    stb %1,%M0
+    stb %1,%M0"
+  [(set_attr "length" "4,4,4,8,4,4,4,4,8,4,8")
+   (set_attr "type" "either,either,either,multi,mu,mu,either,sload,lload,mu,long")])
+
+(define_split
+  [(set (match_operand:CC 0 "gpr_operand" "")
+       (match_operand:CC 1 "br_flag_operand" ""))]
+  "reload_completed"
+  [(set (match_dup 2)
+       (const_int 0))
+   (set (match_dup 2)
+       (if_then_else:SI (ne:CC (match_dup 1)
+                               (const_int 0))
+                        (const_int 1)
+                        (match_dup 2)))]
+  "
+{
+  operands[2] = gen_lowpart (SImode, operands[0]);
+}")
+
+\f
+;; ::::::::::::::::::::
+;; ::
+;; :: Conversions
+;; ::
+;; ::::::::::::::::::::
+
+;; Signed conversions from a smaller integer to a larger integer
+(define_insn "extendqihi2"
+  [(set (match_operand:HI 0 "gpr_operand" "=d,d,d")
+       (sign_extend:HI (match_operand:QI 1 "gpr_or_memory_operand" "d,Q,m")))]
+  ""
+  "@
+    #
+    ldb %0,%M1
+    ldb %0,%M1"
+  [(set_attr "type" "multi,sload,lload")
+   (set_attr "length" "16,4,8")])
+
+(define_split
+  [(set (match_operand:HI 0 "gpr_operand" "")
+       (sign_extend:HI (match_operand:QI 1 "gpr_operand" "")))]
+  "reload_completed"
+  [(match_dup 2)
+   (match_dup 3)]
+  "
+{
+  rtx op0   = gen_lowpart (SImode, operands[0]);
+  rtx op1   = gen_lowpart (SImode, operands[1]);
+  rtx shift = gen_rtx (CONST_INT, VOIDmode, 24);
+
+  operands[2] = gen_ashlsi3 (op0, op1, shift);
+  operands[3] = gen_ashrsi3 (op0, op0, shift);
+}")
+
+(define_insn "extendqisi2"
+  [(set (match_operand:SI 0 "gpr_operand" "=d,d,d")
+       (sign_extend:SI (match_operand:QI 1 "gpr_or_memory_operand" "d,Q,m")))]
+  ""
+  "@
+    #
+    ldb %0,%M1
+    ldb %0,%M1"
+  [(set_attr "type" "multi,sload,lload")
+   (set_attr "length" "16,4,8")])
+
+(define_split
+  [(set (match_operand:SI 0 "gpr_operand" "")
+       (sign_extend:SI (match_operand:QI 1 "gpr_operand" "")))]
+  "reload_completed"
+  [(match_dup 2)
+   (match_dup 3)]
+  "
+{
+  rtx op0   = gen_lowpart (SImode, operands[0]);
+  rtx op1   = gen_lowpart (SImode, operands[1]);
+  rtx shift = gen_rtx (CONST_INT, VOIDmode, 24);
+
+  operands[2] = gen_ashlsi3 (op0, op1, shift);
+  operands[3] = gen_ashrsi3 (op0, op0, shift);
+}")
+
+(define_insn "extendhisi2"
+  [(set (match_operand:SI 0 "gpr_operand" "=d,d,d")
+       (sign_extend:SI (match_operand:HI 1 "gpr_or_memory_operand" "d,Q,m")))]
+  ""
+  "@
+    #
+    ldh %0,%M1
+    ldh %0,%M1"
+  [(set_attr "type" "multi,sload,lload")
+   (set_attr "length" "16,4,8")])
+
+(define_split
+  [(set (match_operand:SI 0 "gpr_operand" "")
+       (sign_extend:SI (match_operand:HI 1 "gpr_operand" "")))]
+  "reload_completed"
+  [(match_dup 2)
+   (match_dup 3)]
+  "
+{
+  rtx op0   = gen_lowpart (SImode, operands[0]);
+  rtx op1   = gen_lowpart (SImode, operands[1]);
+  rtx shift = gen_rtx (CONST_INT, VOIDmode, 16);
+
+  operands[2] = gen_ashlsi3 (op0, op1, shift);
+  operands[3] = gen_ashrsi3 (op0, op0, shift);
+}")
+
+(define_insn "extendqidi2"
+  [(set (match_operand:DI 0 "gpr_operand" "=e,e,e")
+       (sign_extend:DI (match_operand:QI 1 "gpr_or_memory_operand" "d,Q,m")))]
+  ""
+  "#"
+  [(set_attr "length" "12,8,12")
+   (set_attr "type" "multi")])
+
+(define_split
+  [(set (match_operand:DI 0 "gpr_operand" "")
+       (sign_extend:DI (match_operand:QI 1 "gpr_or_memory_operand" "")))]
+  "reload_completed"
+  [(set (match_dup 2) (sign_extend:SI (match_dup 1)))
+   (set (match_dup 3) (ashiftrt:SI (match_dup 2) (const_int 31)))]
+  "
+{
+  d30v_split_double (operands[0], &operands[3], &operands[2]);
+}")
+
+(define_insn "extendhidi2"
+  [(set (match_operand:DI 0 "gpr_operand" "=e,e,e")
+       (sign_extend:DI (match_operand:HI 1 "gpr_or_memory_operand" "d,Q,m")))]
+  ""
+  "#"
+  [(set_attr "length" "12,8,12")
+   (set_attr "type" "multi")])
+
+(define_split
+  [(set (match_operand:DI 0 "gpr_operand" "")
+       (sign_extend:DI (match_operand:HI 1 "gpr_or_memory_operand" "")))]
+  "reload_completed"
+  [(set (match_dup 2) (sign_extend:SI (match_dup 1)))
+   (set (match_dup 3) (ashiftrt:SI (match_dup 2) (const_int 31)))]
+  "
+{
+  d30v_split_double (operands[0], &operands[3], &operands[2]);
+}")
+
+(define_insn "extendsidi2"
+  [(set (match_operand:DI 0 "gpr_operand" "=e,e,e")
+       (sign_extend:DI (match_operand:SI 1 "gpr_or_memory_operand" "d,Q,m")))]
+  ""
+  "#"
+  [(set_attr "length" "8,8,12")
+   (set_attr "type" "multi")])
+
+(define_split
+  [(set (match_operand:DI 0 "gpr_operand" "")
+       (sign_extend:DI (match_operand:SI 1 "gpr_or_memory_operand" "")))]
+  "reload_completed"
+  [(set (match_dup 2) (match_dup 1))
+   (set (match_dup 3) (ashiftrt:SI (match_dup 2) (const_int 31)))]
+  "
+{
+  d30v_split_double (operands[0], &operands[3], &operands[2]);
+}")
+       
+;; Unsigned conversions from a smaller integer to a larger integer
+
+(define_insn "zero_extendqihi2"
+  [(set (match_operand:HI 0 "gpr_operand" "=d,d,d")
+       (zero_extend:HI (match_operand:QI 1 "gpr_or_memory_operand" "d,Q,m")))]
+  ""
+  "@
+    and %0,%1,0xff
+    ldbu %0,%M1
+    ldbu %0,%M1"
+  [(set_attr "length" "8,4,8")
+   (set_attr "type" "long,sload,lload")])
+
+(define_insn "zero_extendqisi2"
+  [(set (match_operand:SI 0 "gpr_operand" "=d,d,d")
+       (zero_extend:SI (match_operand:QI 1 "gpr_or_memory_operand" "d,Q,m")))]
+  ""
+  "@
+    and %0,%1,0xff
+    ldbu %0,%M1
+    ldbu %0,%M1"
+  [(set_attr "length" "8,4,8")
+   (set_attr "type" "long,sload,lload")])
+
+(define_insn "zero_extendhisi2"
+  [(set (match_operand:SI 0 "gpr_operand" "=d,d,d")
+       (zero_extend:SI (match_operand:HI 1 "gpr_or_memory_operand" "d,Q,m")))]
+  ""
+  "@
+    and %0,%1,0xffff
+    ldhu %0,%M1
+    ldhu %0,%M1"
+  [(set_attr "length" "8,4,8")
+   (set_attr "type" "long,sload,lload")])
+
+(define_insn "zero_extendqidi2"
+  [(set (match_operand:DI 0 "gpr_operand" "=e,e,e")
+       (zero_extend:DI (match_operand:QI 1 "gpr_or_memory_operand" "d,Q,m")))]
+  ""
+  "#"
+  [(set_attr "length" "12,8,12")
+   (set_attr "type" "multi")])
+
+(define_split
+  [(set (match_operand:DI 0 "gpr_operand" "")
+       (zero_extend:DI (match_operand:QI 1 "gpr_or_memory_operand" "")))]
+  "reload_completed"
+  [(set (match_dup 2) (zero_extend:SI (match_dup 1)))
+   (set (match_dup 3) (const_int 0))]
+  "
+{
+  d30v_split_double (operands[0], &operands[3], &operands[2]);
+}")
+
+(define_insn "zero_extendhidi2"
+  [(set (match_operand:DI 0 "gpr_operand" "=e,e,e")
+       (zero_extend:DI (match_operand:HI 1 "gpr_or_memory_operand" "d,Q,m")))]
+  ""
+  "#"
+  [(set_attr "length" "8,8,12")
+   (set_attr "type" "multi")])
+
+(define_split
+  [(set (match_operand:DI 0 "gpr_operand" "")
+       (zero_extend:DI (match_operand:HI 1 "gpr_or_memory_operand" "")))]
+  "reload_completed"
+  [(set (match_dup 2) (zero_extend:SI (match_dup 1)))
+   (set (match_dup 3) (const_int 0))]
+  "
+{
+  d30v_split_double (operands[0], &operands[3], &operands[2]);
+}")
+
+(define_insn "zero_extendsidi2"
+  [(set (match_operand:DI 0 "gpr_operand" "=e,e,e")
+       (zero_extend:DI (match_operand:SI 1 "gpr_or_memory_operand" "d,Q,m")))]
+  ""
+  "#"
+  [(set_attr "length" "8,8,12")
+   (set_attr "type" "multi")])
+
+(define_split
+  [(set (match_operand:DI 0 "gpr_operand" "")
+       (zero_extend:DI (match_operand:SI 1 "gpr_or_memory_operand" "")))]
+  "reload_completed"
+  [(set (match_dup 2) (match_dup 1))
+   (set (match_dup 3) (const_int 0))]
+  "
+{
+  d30v_split_double (operands[0], &operands[3], &operands[2]);
+}")
+
+\f
+;; ::::::::::::::::::::
+;; ::
+;; :: 32 bit Integer arithmetic
+;; ::
+;; ::::::::::::::::::::
+
+;; Addition
+(define_expand "addsi3"
+  [(parallel [(set (match_operand:SI 0 "gpr_operand" "")
+                  (plus:SI (match_operand:SI 1 "gpr_operand" "")
+                           (match_operand:SI 2 "gpr_or_constant_operand" "")))
+             (clobber (match_dup 3))
+             (clobber (match_dup 4))
+             (clobber (match_dup 5))])]
+  ""
+  "
+{
+  operands[3] = gen_rtx (REG, CCmode, FLAG_CARRY);
+  operands[4] = gen_rtx (REG, CCmode, FLAG_OVERFLOW);
+  operands[5] = gen_rtx (REG, CCmode, FLAG_ACC_OVER);
+}")
+
+(define_insn "*addsi3_internal"
+  [(set (match_operand:SI 0 "gpr_operand" "=d,d")
+       (plus:SI (match_operand:SI 1 "gpr_operand" "%d,d")
+                (match_operand:SI 2 "gpr_or_constant_operand" "dI,i")))
+   (clobber (match_operand:CC 3 "flag_operand" "=f,f"))
+   (clobber (match_operand:CC 4 "flag_operand" "=f,f"))
+   (clobber (match_operand:CC 5 "flag_operand" "=f,f"))]
+  ""
+  "add %0,%1,%2"
+  [(set_attr "length" "4,8")
+   (set_attr "type" "either,long")])
+
+;; Subtraction
+(define_expand "subsi3"
+  [(parallel [(set (match_operand:SI 0 "gpr_operand" "")
+                  (minus:SI (match_operand:SI 1 "reg_or_0_operand" "")
+                            (match_operand:SI 2 "gpr_or_constant_operand" "")))
+             (clobber (match_dup 3))
+             (clobber (match_dup 4))
+             (clobber (match_dup 5))])]
+  ""
+  "
+{
+  operands[3] = gen_rtx (REG, CCmode, FLAG_CARRY);
+  operands[4] = gen_rtx (REG, CCmode, FLAG_OVERFLOW);
+  operands[5] = gen_rtx (REG, CCmode, FLAG_ACC_OVER);
+}")
+
+(define_insn "*subsi3_internal"
+  [(set (match_operand:SI 0 "gpr_operand" "=d,d,d,d")
+       (minus:SI (match_operand:SI 1 "reg_or_0_operand" "d,d,O,O")
+                 (match_operand:SI 2 "gpr_or_constant_operand" "dI,i,dI,i")))
+   (clobber (match_operand:CC 3 "flag_operand" "=f,f,f,f"))
+   (clobber (match_operand:CC 4 "flag_operand" "=f,f,f,f"))
+   (clobber (match_operand:CC 5 "flag_operand" "=f,f,f,f"))]
+  ""
+  "@
+    sub %0,%1,%2
+    sub %0,%1,%2
+    sub %0,%.,%2
+    sub %0,%.,%2"
+  [(set_attr "length" "4,8,4,8")
+   (set_attr "type" "either,long,either,long")])
+
+;; Multiplication (same size)
+(define_insn "mulsi3"
+  [(set (match_operand:SI 0 "gpr_operand" "=d")
+       (mult:SI (match_operand:SI 1 "gpr_operand" "%d")
+                (match_operand:SI 2 "gpr_or_signed6_operand" "dI")))]
+  ""
+  "mul %0,%1,%2"
+  [(set_attr "length" "4")
+   (set_attr "type" "mul")])
+
+;; Signed multiplication producing 64 bit results from 32 bit inputs
+(define_insn "mulsidi3"
+  [(set (match_operand:DI 0 "accum_operand" "=a")
+       (mult:DI (sign_extend:DI (match_operand:SI 1 "gpr_operand" "d"))
+                (sign_extend:DI (match_operand:SI 2 "gpr_operand" "d"))))]
+  ""
+  "mulx %0,%1,%2"
+  [(set_attr "length" "4")
+   (set_attr "type" "mul")])
+
+(define_insn "*mulsidi3_const"
+  [(set (match_operand:DI 0 "accum_operand" "=a")
+       (mult:DI (sign_extend:DI (match_operand:SI 1 "gpr_operand" "%d"))
+                (match_operand:DI 2 "signed6_operand" "I")))]
+  ""
+  "mulx %0,%1,%2"
+  [(set_attr "length" "4")
+   (set_attr "type" "mul")])
+
+;; Signed multiplication producing just the upper 32 bits from a 32x32->64
+;; bit multiply.  We specifically allow any integer constant here so
+;; allow division by constants to be done by multiplying by a large constant.
+
+(define_expand "smulsi3_highpart"
+  [(set (match_dup 3)
+       (mult:DI (sign_extend:DI (match_operand:SI 1 "gpr_operand" ""))
+                (match_operand:SI 2 "gpr_or_constant_operand" "")))
+   (set (match_operand:SI 0 "gpr_operand" "")
+       (truncate:SI (lshiftrt:DI (match_dup 3)
+                                 (const_int 32))))]
+  ""
+  "
+{
+  operands[3] = gen_reg_rtx (DImode);
+
+  if (GET_CODE (operands[2]) == CONST_INT &&
+      !IN_RANGE_P (INTVAL (operands[2]), -32, 31))
+    operands[2] = force_reg (SImode, operands[2]);
+
+  if (GET_CODE (operands[2]) == REG || GET_CODE (operands[2]) == SUBREG)
+    operands[2] = gen_rtx (SIGN_EXTEND, DImode, operands[2]);
+}")
+
+(define_insn "*di_highpart"
+  [(set (match_operand:SI 0 "gpr_operand" "=d,d")
+       (truncate:SI (lshiftrt:DI (match_operand:DI 1 "gpr_or_accum_operand" "e,a")
+                     (const_int 32))))]
+  ""
+  "@
+    or %0,%.,%U1
+    mvfacc %0,%1,32"
+  [(set_attr "length" "4")
+   (set_attr "type" "either,iu")])
+
+;; Negation
+(define_expand "negsi2"
+  [(parallel [(set (match_operand:SI 0 "gpr_operand" "")
+                  (neg:SI (match_operand:SI 1 "gpr_operand" "")))
+             (clobber (match_dup 2))
+             (clobber (match_dup 3))
+             (clobber (match_dup 4))])]
+  ""
+  "
+{
+  operands[2] = gen_rtx (REG, CCmode, FLAG_CARRY);
+  operands[3] = gen_rtx (REG, CCmode, FLAG_OVERFLOW);
+  operands[4] = gen_rtx (REG, CCmode, FLAG_ACC_OVER);
+}")
+
+(define_insn "*negsi2_internal"
+  [(set (match_operand:SI 0 "gpr_operand" "=d")
+       (neg:SI (match_operand:SI 1 "gpr_operand" "d")))
+   (clobber (match_operand:CC 2 "flag_operand" "=f"))
+   (clobber (match_operand:CC 3 "flag_operand" "=f"))
+   (clobber (match_operand:CC 4 "flag_operand" "=f"))]
+  ""
+  "sub %0,%.,%1"
+  [(set_attr "length" "4")
+   (set_attr "type" "either")])
+
+;; Absolute value
+(define_insn "abssi2"
+  [(set (match_operand:SI 0 "gpr_operand" "=d")
+       (abs:SI (match_operand:SI 1 "gpr_operand" "d")))]
+  ""
+  "abs %0,%1"
+  [(set_attr "length" "4")
+   (set_attr "type" "either")])
+
+\f
+;; ::::::::::::::::::::
+;; ::
+;; :: 64 bit Integer arithmetic
+;; ::
+;; ::::::::::::::::::::
+
+;; Addition
+(define_expand "adddi3"
+  [(parallel [(set (match_operand:DI 0 "gpr_operand" "")
+                  (plus:DI (match_operand:DI 1 "gpr_operand" "")
+                           (match_operand:DI 2 "gpr_or_constant_operand" "")))
+             (clobber (match_dup 3))
+             (clobber (match_dup 4))
+             (clobber (match_dup 5))])]
+  ""
+  "
+{
+  operands[3] = gen_rtx (REG, CCmode, FLAG_CARRY);
+  operands[4] = gen_rtx (REG, CCmode, FLAG_OVERFLOW);
+  operands[5] = gen_rtx (REG, CCmode, FLAG_ACC_OVER);
+}")
+
+(define_insn "*adddi3_internal"
+  [(set (match_operand:DI 0 "gpr_operand" "=e,e,e,e")
+       (plus:DI (match_operand:DI 1 "gpr_operand" "%e,e,e,e")
+                (match_operand:DI 2 "gpr_or_constant_operand" "I,i,e,F")))
+   (clobber (match_operand:CC 3 "flag_operand" "=f,f,f,f"))
+   (clobber (match_operand:CC 4 "flag_operand" "=f,f,f,f"))
+   (clobber (match_operand:CC 5 "flag_operand" "=f,f,f,f"))]
+  ""
+  "#"
+  [(set_attr "length" "8,12,8,16")
+   (set_attr "type" "multi")])
+
+(define_insn "addsi3_set_carry"
+  [(set (match_operand:SI 0 "gpr_operand" "=d,d")
+       (plus:SI (match_operand:SI 1 "gpr_operand" "%d,d")
+                (match_operand:SI 2 "gpr_or_constant_operand" "dI,i")))
+   (set (match_operand:CC 3 "carry_operand" "=f,f")
+       (unspec:CC [(match_dup 1)
+                (match_dup 2)] 1))
+   (clobber (match_operand:CC 4 "flag_operand" "=f,f"))
+   (clobber (match_operand:CC 5 "flag_operand" "=f,f"))]
+  ""
+  "add %0,%1,%2"
+  [(set_attr "length" "4,8")
+   (set_attr "type" "scarry,lcarry")])
+
+(define_insn "addsi3_use_carry"
+  [(set (match_operand:SI 0 "gpr_operand" "=d,d")
+       (unspec:SI [(match_operand:SI 1 "gpr_operand" "%d,d")
+                (match_operand:SI 2 "gpr_or_constant_operand" "dI,i")
+                (match_operand:CC 3 "carry_operand" "+f,f")] 2))
+   (clobber (match_operand:CC 4 "flag_operand" "=f,f"))
+   (clobber (match_operand:CC 5 "flag_operand" "=f,f"))]
+  ""
+  "addc %0,%1,%2"
+  [(set_attr "length" "4,8")
+   (set_attr "type" "scarry,lcarry")])
+
+(define_split
+  [(set (match_operand:DI 0 "gpr_operand" "")
+       (plus:DI (match_operand:DI 1 "gpr_operand" "")
+                (match_operand:DI 2 "gpr_or_constant_operand" "")))
+   (clobber (match_operand:CC 3 "flag_operand" ""))
+   (clobber (match_operand:CC 4 "flag_operand" ""))
+   (clobber (match_operand:CC 5 "flag_operand" ""))]
+  "reload_completed"
+  [(match_dup 6)
+   (match_dup 7)]
+  "
+{
+  rtx high[3];
+  rtx low[3];
+
+  d30v_split_double (operands[0], &high[0], &low[0]);
+  d30v_split_double (operands[1], &high[1], &low[1]);
+  d30v_split_double (operands[2], &high[2], &low[2]);
+
+  operands[6] = gen_addsi3_set_carry (low[0], low[1], low[2], operands[3],
+                                     operands[4], operands[5]);
+
+  operands[7] = gen_addsi3_use_carry (high[0], high[1], high[2], operands[3],
+                                     operands[4], operands[5]);
+}")
+
+;; Subtraction
+(define_expand "subdi3"
+  [(parallel [(set (match_operand:DI 0 "gpr_operand" "")
+                  (minus:DI (match_operand:DI 1 "gpr_operand" "")
+                            (match_operand:DI 2 "gpr_or_constant_operand" "")))
+             (clobber (match_dup 3))
+             (clobber (match_dup 4))
+             (clobber (match_dup 5))])]
+  ""
+  "
+{
+  operands[3] = gen_rtx (REG, CCmode, FLAG_CARRY);
+  operands[4] = gen_rtx (REG, CCmode, FLAG_OVERFLOW);
+  operands[5] = gen_rtx (REG, CCmode, FLAG_ACC_OVER);
+}")
+
+(define_insn "*subdi3_internal"
+  [(set (match_operand:DI 0 "gpr_operand" "=e,e,e,e")
+       (minus:DI (match_operand:DI 1 "gpr_operand" "e,e,e,e")
+                 (match_operand:DI 2 "gpr_or_constant_operand" "I,i,e,F")))
+   (clobber (match_operand:CC 3 "flag_operand" "=f,f,f,f"))
+   (clobber (match_operand:CC 4 "flag_operand" "=f,f,f,f"))
+   (clobber (match_operand:CC 5 "flag_operand" "=f,f,f,f"))]
+  ""
+  "#"
+  [(set_attr "length" "8,12,8,16")
+   (set_attr "type" "multi")])
+
+(define_insn "subsi3_set_carry"
+  [(set (match_operand:SI 0 "gpr_operand" "=d,d,d,d")
+       (minus:SI (match_operand:SI 1 "reg_or_0_operand" "d,d,O,O")
+                 (match_operand:SI 2 "gpr_or_constant_operand" "dI,i,dI,i")))
+   (set (match_operand:CC 3 "carry_operand" "=f,f,f,f")
+       (unspec:CC [(match_dup 1)
+                   (match_dup 2)] 3))
+   (clobber (match_operand:CC 4 "flag_operand" "=f,f,f,f"))
+   (clobber (match_operand:CC 5 "flag_operand" "=f,f,f,f"))]
+  ""
+  "@
+    sub %0,%1,%2
+    sub %0,%1,%2
+    sub %0,%.,%2
+    sub %0,%.,%2"
+  [(set_attr "length" "4,8,4,8")
+   (set_attr "type" "scarry,lcarry,scarry,lcarry")])
+
+(define_insn "subsi3_use_carry"
+  [(set (match_operand:SI 0 "gpr_operand" "=d,d,d,d")
+       (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "d,d,O,O")
+                   (match_operand:SI 2 "gpr_operand" "dI,i,dI,i")
+                   (match_operand:CC 3 "carry_operand" "+f,f,f,f")] 4))
+   (clobber (match_operand:CC 4 "flag_operand" "=f,f,f,f"))
+   (clobber (match_operand:CC 5 "flag_operand" "=f,f,f,f"))]
+  ""
+  "@
+    subb %0,%1,%2
+    subb %0,%1,%2
+    subb %0,%.,%2
+    subb %0,%.,%2"
+  [(set_attr "length" "4,8,4,8")
+   (set_attr "type" "scarry,lcarry,scarry,lcarry")])
+
+(define_split
+  [(set (match_operand:DI 0 "gpr_operand" "")
+       (minus:DI (match_operand:DI 1 "gpr_operand" "")
+                 (match_operand:DI 2 "gpr_or_constant_operand" "")))
+   (clobber (match_operand:CC 3 "flag_operand" ""))
+   (clobber (match_operand:CC 4 "flag_operand" ""))
+   (clobber (match_operand:CC 5 "flag_operand" ""))]
+  "reload_completed"
+  [(match_dup 6)
+   (match_dup 7)]
+  "
+{
+  rtx high[3];
+  rtx low[3];
+
+  d30v_split_double (operands[0], &high[0], &low[0]);
+  d30v_split_double (operands[1], &high[1], &low[1]);
+  d30v_split_double (operands[2], &high[2], &low[2]);
+
+  operands[6] = gen_subsi3_set_carry (low[0], low[1], low[2], operands[3],
+                                     operands[4], operands[5]);
+
+  operands[7] = gen_subsi3_use_carry (high[0], high[1], high[2], operands[3],
+                                     operands[4], operands[5]);
+}")
+
+;; Negation
+(define_expand "negdi2"
+  [(parallel [(set (match_operand:DI 0 "gpr_operand" "")
+                  (neg:DI (match_operand:DI 1 "gpr_operand" "")))
+             (clobber (match_dup 2))
+             (clobber (match_dup 3))
+             (clobber (match_dup 4))])]
+  ""
+  "
+{
+  operands[2] = gen_rtx (REG, CCmode, FLAG_CARRY);
+  operands[3] = gen_rtx (REG, CCmode, FLAG_OVERFLOW);
+  operands[4] = gen_rtx (REG, CCmode, FLAG_ACC_OVER);
+}")
+
+(define_insn "*negdi2_internal"
+  [(set (match_operand:DI 0 "gpr_operand" "=e")
+       (neg:DI (match_operand:DI 1 "gpr_operand" "e")))
+   (clobber (match_operand:CC 2 "flag_operand" "=f"))
+   (clobber (match_operand:CC 3 "flag_operand" "=f"))
+   (clobber (match_operand:CC 4 "flag_operand" "=f"))]
+  ""
+  "#"
+  [(set_attr "length" "8")
+   (set_attr "type" "multi")])
+
+(define_split
+  [(set (match_operand:DI 0 "gpr_operand" "=e")
+       (neg:DI (match_operand:DI 1 "gpr_operand" "e")))
+   (clobber (match_operand:CC 2 "flag_operand" "=f"))
+   (clobber (match_operand:CC 3 "flag_operand" "=f"))
+   (clobber (match_operand:CC 4 "flag_operand" "=f"))]
+  "reload_completed"
+  [(match_dup 5)
+   (match_dup 6)]
+  "
+{
+  rtx high[2];
+  rtx low[2];
+  rtx r0 = const0_rtx;
+
+  d30v_split_double (operands[0], &high[0], &low[0]);
+  d30v_split_double (operands[1], &high[1], &low[1]);
+
+  operands[5] = gen_subsi3_set_carry (low[0], r0, low[1], operands[2],
+                                     operands[3], operands[4]);
+
+  operands[6] = gen_subsi3_use_carry (high[0], r0, high[1], operands[2],
+                                     operands[3], operands[4]);
+}")
+
+\f
+;; ::::::::::::::::::::
+;; ::
+;; :: 32 bit Integer Shifts and Rotates
+;; ::
+;; ::::::::::::::::::::
+
+;; Arithmetic Shift Left (negate the shift value and use shift right)
+(define_expand "ashlsi3"
+  [(set (match_operand:SI 0 "gpr_operand" "")
+       (ashift:SI (match_operand:SI 1 "gpr_operand" "")
+                  (match_operand:SI 2 "gpr_or_unsigned5_operand" "")))]
+  ""
+  "
+{
+  if (GET_CODE (operands[2]) != CONST_INT)
+    operands[2] = gen_rtx (NEG, SImode, negate_rtx (SImode, operands[2]));
+}")
+
+(define_insn "*ashlsi3_constant"
+  [(set (match_operand:SI 0 "gpr_operand" "=d")
+       (ashift:SI (match_operand:SI 1 "gpr_operand" "d")
+                  (match_operand:SI 2 "unsigned5_operand" "J")))]
+  ""
+  "sra %0,%1,%n2"
+  [(set_attr "length" "4")
+   (set_attr "type" "either")])
+
+(define_insn "*ashlsi3_register"
+  [(set (match_operand:SI 0 "gpr_operand" "=d")
+       (ashift:SI (match_operand:SI 1 "gpr_operand" "d")
+                  (neg:SI (match_operand:SI 2 "gpr_operand" "d"))))]
+  ""
+  "sra %0,%1,%2"
+  [(set_attr "length" "4")
+   (set_attr "type" "either")])
+
+;; Arithmetic Shift Right
+(define_insn "ashrsi3"
+  [(set (match_operand:SI 0 "gpr_operand" "=d")
+       (ashiftrt:SI (match_operand:SI 1 "gpr_operand" "d")
+                    (match_operand:SI 2 "gpr_or_unsigned5_operand" "dJ")))]
+  ""
+  "sra %0,%1,%2"
+  [(set_attr "length" "4")])
+
+;; Logical Shift Right
+(define_insn "lshrsi3"
+  [(set (match_operand:SI 0 "gpr_operand" "=d")
+       (lshiftrt:SI (match_operand:SI 1 "gpr_operand" "d")
+                    (match_operand:SI 2 "gpr_or_unsigned5_operand" "dJ")))]
+  ""
+  "srl %0,%1,%2"
+  [(set_attr "length" "4")
+   (set_attr "type" "either")])
+
+;; Rotate Left (negate the shift value and use rotate right)
+(define_expand "rotlsi3"
+  [(set (match_operand:SI 0 "gpr_operand" "")
+       (rotate:SI (match_operand:SI 1 "gpr_operand" "")
+                  (match_operand:SI 2 "gpr_or_unsigned5_operand" "")))]
+  ""
+  "
+{
+  if (GET_CODE (operands[2]) != CONST_INT)
+    operands[2] = gen_rtx (NEG, SImode, negate_rtx (SImode, operands[2]));
+}")
+
+(define_insn "*rotlsi3_constant"
+  [(set (match_operand:SI 0 "gpr_operand" "=d")
+       (rotate:SI (match_operand:SI 1 "gpr_operand" "d")
+                  (match_operand:SI 2 "unsigned5_operand" "J")))]
+  ""
+  "rot %0,%1,%n2"
+  [(set_attr "length" "4")
+   (set_attr "type" "either")])
+
+(define_insn "*rotlsi3_register"
+  [(set (match_operand:SI 0 "gpr_operand" "=d")
+       (rotate:SI (match_operand:SI 1 "gpr_operand" "d")
+                  (neg:SI (match_operand:SI 2 "gpr_operand" "d"))))]
+  ""
+  "rot %0,%1,%2"
+  [(set_attr "length" "4")
+   (set_attr "type" "either")])
+
+;; Rotate Right
+(define_insn "rotrsi3"
+  [(set (match_operand:SI 0 "gpr_operand" "=d")
+       (rotatert:SI (match_operand:SI 1 "gpr_operand" "d")
+                    (match_operand:SI 2 "gpr_or_unsigned5_operand" "dJ")))]
+  ""
+  "rot %0,%1,%2"
+  [(set_attr "length" "4")
+   (set_attr "type" "either")])
+
+\f
+;; ::::::::::::::::::::
+;; ::
+;; :: 64 bit Integer Shifts and Rotates
+;; ::
+;; ::::::::::::::::::::
+
+;; Arithmetic Shift Left
+(define_expand "ashldi3"
+  [(parallel [(set (match_operand:DI 0 "gpr_operand" "")
+                  (ashift:DI (match_operand:DI 1 "gpr_operand" "")
+                             (match_operand:SI 2 "gpr_or_unsigned6_operand" "")))
+             (clobber (match_scratch:CC 3 ""))])]
+  ""
+  "
+{
+  if (GET_CODE (operands[2]) == CONST_INT)
+    {
+      if (IN_RANGE_P (INTVAL (operands[2]), 0, 63))
+       {
+         emit_insn (gen_ashldi3_constant (operands[0], operands[1], operands[2]));
+         DONE;
+       }
+      else
+       operands[2] = copy_to_mode_reg (SImode, operands[2]);
+    }
+
+  operands[2] = gen_rtx (NEG, SImode, negate_rtx (SImode, operands[2]));
+}")
+
+(define_insn "ashldi3_constant"
+  [(set (match_operand:DI 0 "gpr_operand" "=e,e")
+       (ashift:DI (match_operand:DI 1 "gpr_operand" "0,e")
+                  (match_operand:SI 2 "unsigned6_operand" "J,P")))]
+  ""
+  "@
+    src %U0,%L0,%n2\;sra %L0,%L0,%n2
+    sra %U0,%L1,%s2\;or %L0,%.,0"
+  [(set_attr "length" "8")
+   (set_attr "type" "multi")])
+
+(define_insn "*ashldi3_register"
+  [(set (match_operand:DI 0 "gpr_operand" "=e")
+       (ashift:DI (match_operand:DI 1 "gpr_operand" "0")
+                  (neg:SI (match_operand:SI 2 "gpr_operand" "d"))))
+   (clobber (match_scratch:CC 3 "=b"))]
+  ""
+  "cmpge %3,%2,-31\;src%T3 %U0,%L0,%2\;sra%T3 %L0,%L0,%2\;sub%F3 %U0,%2,-32\;sra%F3 %U0,%L0,%U0\;or%F3 %L0,%.,0"
+  [(set_attr "length" "32")
+   (set_attr "type" "multi")])
+
+;; Arithmetic Shift Right
+(define_insn "ashrdi3"
+  [(set (match_operand:DI 0 "gpr_operand" "=e,e,e")
+       (ashiftrt:DI (match_operand:DI 1 "gpr_operand" "0,e,0")
+                    (match_operand:SI 2 "gpr_or_unsigned6_operand" "J,P,d")))
+   (clobber (match_scratch:CC 3 "=X,X,b"))]
+  ""
+  "@
+    src %L0,%U0,%2\;sra %U0,%U0,%2
+    sra %L0,%U1,%S2\;sra %U0,%L0,31
+    cmple %3,%2,31\;src%T3 %L0,%U0,%2\;sra%T3 %U0,%U0,%2\;add%F3 %L0,%2,-32\;sra%F3 %L0,%U0,%L0\;sra%F3 %U0,%U0,31"
+  [(set_attr "length" "8,8,28")
+   (set_attr "type" "multi")])
+
+;; Logical Shift Right
+
+(define_insn "lshrdi3"
+  [(set (match_operand:DI 0 "gpr_operand" "=e,e,e")
+       (lshiftrt:DI (match_operand:DI 1 "gpr_operand" "0,e,0")
+                    (match_operand:SI 2 "gpr_or_unsigned6_operand" "J,P,d")))
+   (clobber (match_scratch:CC 3 "=X,X,b"))]
+  ""
+  "@
+    src %L0,%U0,%2\;srl %U0,%U0,%2
+    srl %L0,%U1,%S2\;or %U0,%.,0
+    cmple %3,%2,31\;src%T3 %L0,%U0,%2\;srl%T3 %U0,%U0,%2\;add%F3 %L0,%2,-32\;srl%F3 %L0,%U0,%L0\;or%F3 %U0,%.,0"
+  [(set_attr "length" "8,8,28")
+   (set_attr "type" "multi")])
+
+\f
+;; ::::::::::::::::::::
+;; ::
+;; :: 32 Bit Integer Logical operations
+;; ::
+;; ::::::::::::::::::::
+
+;; Logical AND, 32 bit integers
+(define_expand "andsi3"
+  [(set (match_operand:SI 0 "gpr_operand" "")
+       (and:SI (match_operand:SI 1 "gpr_operand" "")
+               (match_operand:SI 2 "gpr_or_constant_operand" "")))]
+  ""
+  "")
+
+(define_insn "*andsi3_register"
+  [(set (match_operand:SI 0 "gpr_operand" "=d")
+       (and:SI (match_operand:SI 1 "gpr_operand" "%d")
+               (match_operand:SI 2 "gpr_operand" "d")))]
+  ""
+  "and %0,%1,%2"
+  [(set_attr "length" "4")
+   (set_attr "type" "either")])
+
+(define_insn "*andsi3_move"
+  [(set (match_operand:SI 0 "gpr_operand" "=d,d")
+       (and:SI (match_operand:SI 1 "gpr_operand" "%0,d")
+               (match_operand:SI 2 "const_int_operand" "n,n")))]
+  "((INTVAL (operands[2]) & 0xffffffff) == 0xffffffff)"
+  "@
+    ; and 0xffffffff to same register
+    and %0,%1,-1"
+  [(set_attr "length" "0,4")
+   (set_attr "type" "either")])
+
+(define_insn "*andsi3_constant"
+  [(set (match_operand:SI 0 "gpr_operand" "=d,d,d,d")
+       (and:SI (match_operand:SI 1 "gpr_operand" "%d,d,d,d")
+               (match_operand:SI 2 "const_int_operand" "L,O,I,i")))]
+  ""
+  "@
+    bclr %0,%1,%B2
+    or %0,%.,0
+    and %0,%1,%2
+    and %0,%1,%2"
+  [(set_attr "length" "4,4,4,8")
+   (set_attr "type" "either,either,either,long")])
+
+;; Inclusive OR, 32 bit integers
+(define_expand "iorsi3"
+  [(set (match_operand:SI 0 "gpr_operand" "")
+       (ior:SI (match_operand:SI 1 "gpr_operand" "")
+               (match_operand:SI 2 "gpr_or_constant_operand" "")))]
+  ""
+  "")
+
+(define_insn "*iorsi3_register"
+  [(set (match_operand:SI 0 "gpr_operand" "=d")
+       (ior:SI (match_operand:SI 1 "gpr_operand" "%d")
+               (match_operand:SI 2 "gpr_operand" "d")))]
+  ""
+  "or %0,%1,%2"
+  [(set_attr "length" "4")
+   (set_attr "type" "either")])
+
+(define_insn "*iorsi3_constant"
+  [(set (match_operand:SI 0 "gpr_operand" "=d,d,d,d")
+       (ior:SI (match_operand:SI 1 "gpr_operand" "%d,0,d,d")
+               (match_operand:SI 2 "const_int_operand" "K,O,I,i")))]
+  ""
+  "@
+    bset %0,%1,%B2
+    ; or 0 to same register (%0)
+    or %0,%1,%2
+    or %0,%1,%2"
+  [(set_attr "length" "4,0,4,8")
+   (set_attr "type" "either,either,either,long")])
+
+;; Exclusive OR, 32 bit integers
+(define_expand "xorsi3"
+  [(set (match_operand:SI 0 "gpr_operand" "")
+       (xor:SI (match_operand:SI 1 "gpr_operand" "")
+               (match_operand:SI 2 "gpr_or_constant_operand" "")))]
+  ""
+  "")
+
+(define_insn "*xorsi3_register"
+  [(set (match_operand:SI 0 "gpr_operand" "=d")
+       (xor:SI (match_operand:SI 1 "gpr_operand" "%d")
+               (match_operand:SI 2 "gpr_operand" "d")))]
+  ""
+  "xor %0,%1,%2"
+  [(set_attr "length" "4")
+   (set_attr "type" "either")])
+
+(define_insn "*xorsi3_constant"
+  [(set (match_operand:SI 0 "gpr_operand" "=d,d,d,d")
+       (xor:SI (match_operand:SI 1 "gpr_operand" "%d,0,d,d")
+               (match_operand:SI 2 "const_int_operand" "K,O,I,i")))]
+  ""
+  "@
+    bnot %0,%1,%B2
+    ; xor 0 to same register (%0)
+    xor %0,%1,%2
+    xor %0,%1,%2"
+  [(set_attr "length" "4,0,4,8")
+   (set_attr "type" "either,either,either,long")])
+
+;; One's complement, 32 bit integers
+(define_insn "one_cmplsi2"
+  [(set (match_operand:SI 0 "gpr_operand" "=d")
+       (not:SI (match_operand:SI 1 "gpr_operand" "d")))]
+  ""
+  "not %0,%1"
+  [(set_attr "length" "4")
+   (set_attr "type" "either")])
+
+\f
+;; ::::::::::::::::::::
+;; ::
+;; :: 64 Bit Integer Logical operations
+;; ::
+;; ::::::::::::::::::::
+
+;; Logical AND, 64 bit integers
+(define_insn "anddi3"
+  [(set (match_operand:DI 0 "gpr_operand" "=e,e,&e,e,e,e")
+       (and:DI (match_operand:DI 1 "gpr_operand" "%e,0,e,e,e,e")
+               (match_operand:DI 2 "gpr_or_dbl_const_operand" "0,e,e,I,i,F")))]
+  ""
+  "#"
+  [(set_attr "length" "8,8,8,8,12,16")
+   (set_attr "type" "multi")])
+
+(define_split
+  [(set (match_operand:DI 0 "gpr_operand" "")
+       (and:DI (match_operand:DI 1 "gpr_operand" "")
+               (match_operand:DI 2 "gpr_or_dbl_const_operand" "")))]
+  "reload_completed"
+  [(set (match_dup 3) (and:SI (match_dup 4) (match_dup 5)))
+   (set (match_dup 6) (and:SI (match_dup 7) (match_dup 8)))]
+  "
+{
+  d30v_split_double (operands[0], &operands[3], &operands[6]);
+  d30v_split_double (operands[1], &operands[4], &operands[7]);
+  d30v_split_double (operands[2], &operands[5], &operands[8]);
+}")
+
+;; Includive OR, 64 bit integers
+(define_insn "iordi3"
+  [(set (match_operand:DI 0 "gpr_operand" "=e,e,&e,e,e,e")
+       (ior:DI (match_operand:DI 1 "gpr_operand" "%e,0,e,e,e,e")
+               (match_operand:DI 2 "gpr_or_dbl_const_operand" "0,e,e,I,i,F")))]
+  ""
+  "#"
+  [(set_attr "length" "8,8,8,8,12,16")
+   (set_attr "type" "multi")])
+
+(define_split
+  [(set (match_operand:DI 0 "gpr_operand" "")
+       (ior:DI (match_operand:DI 1 "gpr_operand" "")
+               (match_operand:DI 2 "gpr_or_dbl_const_operand" "")))]
+  "reload_completed"
+  [(set (match_dup 3) (ior:SI (match_dup 4) (match_dup 5)))
+   (set (match_dup 6) (ior:SI (match_dup 7) (match_dup 8)))]
+  "
+{
+  d30v_split_double (operands[0], &operands[3], &operands[6]);
+  d30v_split_double (operands[1], &operands[4], &operands[7]);
+  d30v_split_double (operands[2], &operands[5], &operands[8]);
+}")
+
+;; Excludive OR, 64 bit integers
+(define_insn "xordi3"
+  [(set (match_operand:DI 0 "gpr_operand" "=e,e,&e,e,e,e")
+       (xor:DI (match_operand:DI 1 "gpr_operand" "%e,0,e,e,e,e")
+               (match_operand:DI 2 "gpr_or_dbl_const_operand" "0,e,e,I,i,F")))]
+  ""
+  "#"
+  [(set_attr "length" "8,8,8,8,12,16")
+   (set_attr "type" "multi")])
+
+(define_split
+  [(set (match_operand:DI 0 "gpr_operand" "")
+       (xor:DI (match_operand:DI 1 "gpr_operand" "")
+               (match_operand:DI 2 "gpr_or_dbl_const_operand" "")))]
+  "reload_completed"
+  [(set (match_dup 3) (xor:SI (match_dup 4) (match_dup 5)))
+   (set (match_dup 6) (xor:SI (match_dup 7) (match_dup 8)))]
+  "
+{
+  d30v_split_double (operands[0], &operands[3], &operands[6]);
+  d30v_split_double (operands[1], &operands[4], &operands[7]);
+  d30v_split_double (operands[2], &operands[5], &operands[8]);
+}")
+
+;; One's complement, 64 bit integers
+(define_insn "one_cmpldi2"
+  [(set (match_operand:DI 0 "gpr_operand" "=e,&e")
+       (not:DI (match_operand:DI 1 "gpr_operand" "0,e")))]
+  ""
+  "#"
+  [(set_attr "length" "8")
+   (set_attr "type" "multi")])
+
+(define_split
+  [(set (match_operand:DI 0 "gpr_operand" "")
+       (not:DI (match_operand:DI 1 "gpr_operand" "")))]
+  "reload_completed"
+  [(set (match_dup 3) (not:SI (match_dup 4)))
+   (set (match_dup 5) (not:SI (match_dup 6)))]
+  "
+{
+  d30v_split_double (operands[0], &operands[3], &operands[5]);
+  d30v_split_double (operands[1], &operands[4], &operands[6]);
+}")
+
+\f
+;; ::::::::::::::::::::
+;; ::
+;; :: Multiply and accumulate instructions
+;; ::
+;; ::::::::::::::::::::
+
+(define_insn "*mac_reg"
+  [(set (match_operand:DI 0 "accum_operand" "+a")
+       (plus:DI (match_dup 0)
+                (mult:DI (sign_extend:DI (match_operand:SI 1 "gpr_operand" "%d"))
+                         (sign_extend:DI (match_operand:SI 2 "gpr_operand" "d")))))]
+  ""
+  "mac%A0 %.,%1,%2"
+  [(set_attr "length" "4")
+   (set_attr "type" "mul")])
+
+(define_insn "*mac_const"
+  [(set (match_operand:DI 0 "accum_operand" "+a")
+       (plus:DI (match_dup 0)
+                (mult:DI (sign_extend:DI (match_operand:SI 1 "gpr_operand" "%d"))
+                         (match_operand:DI 2 "signed6_operand" "I"))))]
+  ""
+  "mac%A0 %.,%1,%2"
+  [(set_attr "length" "4")
+   (set_attr "type" "mul")])
+
+(define_insn "*macs_reg"
+  [(set (match_operand:DI 0 "accum_operand" "+a")
+       (plus:DI (match_dup 0)
+                (ashift:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "gpr_operand" "%d"))
+                                    (sign_extend:DI (match_operand:SI 2 "gpr_operand" "d")))
+                           (const_int 1))))]
+  ""
+  "macs%A0 %.,%1,%2"
+  [(set_attr "length" "4")
+   (set_attr "type" "mul")])
+
+(define_insn "*macs_const"
+  [(set (match_operand:DI 0 "accum_operand" "+a")
+       (plus:DI (match_dup 0)
+                (ashift:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "gpr_operand" "%d"))
+                                    (match_operand:DI 2 "signed6_operand" "I"))
+                           (const_int 1))))]
+  ""
+  "macs%A0 %.,%1,%2"
+  [(set_attr "length" "4")
+   (set_attr "type" "mul")])
+
+(define_insn "*msub_reg"
+  [(set (match_operand:DI 0 "accum_operand" "+a")
+       (minus:DI (match_dup 0)
+                 (mult:DI (sign_extend:DI (match_operand:SI 1 "gpr_operand" "d"))
+                          (sign_extend:DI (match_operand:SI 2 "gpr_operand" "d")))))]
+  ""
+  "msub%A0 %.,%1,%2"
+  [(set_attr "length" "4")
+   (set_attr "type" "mul")])
+
+(define_insn "*msub_const"
+  [(set (match_operand:DI 0 "accum_operand" "+a")
+       (minus:DI (match_dup 0)
+                 (mult:DI (sign_extend:DI (match_operand:SI 1 "gpr_operand" "d"))
+                          (match_operand:DI 2 "signed6_operand" "I"))))]
+  ""
+  "msub%A0 %.,%1,%2"
+  [(set_attr "length" "4")
+   (set_attr "type" "mul")])
+
+(define_insn "*msubs_reg"
+  [(set (match_operand:DI 0 "accum_operand" "+a")
+       (minus:DI (match_dup 0)
+                 (ashift:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "gpr_operand" "d"))
+                                     (sign_extend:DI (match_operand:SI 2 "gpr_operand" "d")))
+                            (const_int 1))))]
+  ""
+  "msubs%A0 %.,%1,%2"
+  [(set_attr "length" "4")
+   (set_attr "type" "mul")])
+
+(define_insn "*msubs_const"
+  [(set (match_operand:DI 0 "accum_operand" "+a")
+       (minus:DI (match_dup 0)
+                 (ashift:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "gpr_operand" "d"))
+                                     (match_operand:DI 2 "signed6_operand" "I"))
+                            (const_int 1))))]
+  ""
+  "msubs%A0 %.,%1,%2"
+  [(set_attr "length" "4")
+   (set_attr "type" "mul")])
+
+\f
+;; ::::::::::::::::::::
+;; ::
+;; :: Comparisons
+;; ::
+;; ::::::::::::::::::::
+
+;; Note, we store the operands in the comparison insns, and use them later
+;; when generating the branch or scc operation.
+
+;; First the routines called by the machine independent part of the compiler
+(define_expand "cmpsi"
+  [(set (cc0)
+        (compare (match_operand:SI 0 "gpr_operand" "")
+                (match_operand:SI 1 "gpr_or_constant_operand" "")))]
+  ""
+  "
+{
+  d30v_compare_op0 = operands[0];
+  d30v_compare_op1 = operands[1];
+  DONE;
+}")
+
+(define_expand "cmpdi"
+  [(set (cc0)
+        (compare (match_operand:DI 0 "gpr_operand" "")
+                (match_operand:DI 1 "nonmemory_operand" "")))]
+  ""
+  "
+{
+  d30v_compare_op0 = operands[0];
+  d30v_compare_op1 = operands[1];
+  DONE;
+}")
+
+;; Now, the actual comparisons, generated by the branch and/or scc operations
+
+;; 32 bit integer tests
+(define_insn "*srelational"
+  [(set (match_operand:CC 0 "flag_operand" "=f,f")
+       (match_operator:CC 1 "srelational_si_operator"
+                          [(match_operand:SI 2 "gpr_operand" "d,d")
+                           (match_operand:SI 3 "gpr_or_constant_operand" "dI,i")]))]
+  ""
+  "%R1 %0,%2,%3"
+  [(set_attr "length" "4,8")
+   (set_attr "type" "scmp,lcmp")])
+
+(define_insn "*urelational"
+  [(set (match_operand:CC 0 "flag_operand" "=f,f")
+       (match_operator:CC 1 "urelational_si_operator"
+                          [(match_operand:SI 2 "gpr_operand" "d,d")
+                           (match_operand:SI 3 "gpr_or_constant_operand" "dJP,i")]))]
+  ""
+  "%R1 %0,%2,%3"
+  [(set_attr "length" "4,8")
+   (set_attr "type" "scmp,lcmp")])
+
+;; Code used after splitting DI compares
+
+(define_insn "*movcccc_signed_true"
+  [(set (match_operand:CC 0 "flag_operand" "=f,f")
+       (if_then_else:CC (match_operand:CC 1 "br_flag_operand" "f,f")
+                        (match_operator:CC 3 "srelational_si_operator"
+                                           [(match_operand:SI 4 "gpr_operand" "d,d")
+                                            (match_operand:SI 5 "gpr_or_constant_operand" "dI,i")])
+                        (match_dup 0)))]
+  ""
+  "%R3%T1 %0,%4,%5"
+  [(set_attr "length" "4,8")
+   (set_attr "type" "scmp,lcmp")])
+
+(define_insn "*movcccc_signed_false"
+  [(set (match_operand:CC 0 "flag_operand" "=f,f")
+       (if_then_else:CC (match_operand:CC 1 "br_flag_operand" "f,f")
+                        (match_dup 0)
+                        (match_operator:CC 3 "srelational_si_operator"
+                                           [(match_operand:SI 4 "gpr_operand" "d,d")
+                                            (match_operand:SI 5 "gpr_or_constant_operand" "dI,i")])))]
+  ""
+  "%R3%F1 %0,%4,%5"
+  [(set_attr "length" "4,8")
+   (set_attr "type" "scmp,lcmp")])
+
+(define_insn "*movcccc_unsigned_true"
+  [(set (match_operand:CC 0 "flag_operand" "=f,f")
+       (if_then_else:CC (match_operand:CC 1 "br_flag_operand" "f,f")
+                        (match_operator:CC 3 "urelational_si_operator"
+                                           [(match_operand:SI 4 "gpr_operand" "d,d")
+                                            (match_operand:SI 5 "gpr_or_constant_operand" "dJP,i")])
+                        (match_dup 0)))]
+  ""
+  "%R3%T1 %0,%4,%5"
+  [(set_attr "length" "4,8")
+   (set_attr "type" "scmp,lcmp")])
+
+(define_insn "*movcccc_unsigned_false"
+  [(set (match_operand:CC 0 "flag_operand" "=f,f")
+       (if_then_else:CC (match_operand:CC 1 "br_flag_operand" "f,f")
+                        (match_dup 0)
+                        (match_operator:CC 3 "urelational_si_operator"
+                                           [(match_operand:SI 4 "gpr_operand" "d,d")
+                                            (match_operand:SI 5 "gpr_or_constant_operand" "dJP,i")])))]
+  ""
+  "%R3%F1 %0,%4,%5"
+  [(set_attr "length" "4,8")
+   (set_attr "type" "scmp,lcmp")])
+
+;; 64 bit integer tests
+(define_insn "*eqdi_internal"
+  [(set (match_operand:CC 0 "br_flag_operand" "=b,b,b")
+       (eq:CC (match_operand:DI 1 "gpr_operand" "e,e,e")
+              (match_operand:DI 2 "gpr_or_dbl_const_operand" "eI,i,F")))]
+  ""
+  "#"
+  [(set_attr "length" "8,12,16")
+   (set_attr "type" "multi")])
+
+(define_split
+  [(set (match_operand:CC 0 "br_flag_operand" "")
+       (eq:CC (match_operand:DI 1 "gpr_operand" "")
+              (match_operand:DI 2 "gpr_or_dbl_const_operand" "")))]
+  "reload_completed"
+  [(set (match_dup 0)
+       (eq:CC (match_dup 3)
+              (match_dup 4)))
+   (set (match_dup 0)
+       (if_then_else:CC (match_dup 0)
+                        (eq:CC (match_dup 5)
+                               (match_dup 6))
+                        (match_dup 0)))]
+  "
+{
+  d30v_split_double (operands[1], &operands[3], &operands[5]);
+  d30v_split_double (operands[2], &operands[4], &operands[6]);
+}")
+
+(define_insn "*nedi_internal"
+  [(set (match_operand:CC 0 "br_flag_operand" "=b,b,b")
+       (ne:CC (match_operand:DI 1 "gpr_operand" "e,e,e")
+              (match_operand:DI 2 "gpr_or_dbl_const_operand" "eI,i,F")))]
+  ""
+  "#"
+  [(set_attr "length" "8,12,16")
+   (set_attr "type" "multi")])
+
+(define_split
+  [(set (match_operand:CC 0 "br_flag_operand" "")
+       (ne:CC (match_operand:DI 1 "gpr_operand" "")
+              (match_operand:DI 2 "gpr_or_dbl_const_operand" "")))]
+  "reload_completed"
+  [(set (match_dup 0)
+       (ne:CC (match_dup 3)
+              (match_dup 4)))
+   (set (match_dup 0)
+       (if_then_else:CC (match_dup 0)
+                        (match_dup 0)
+                        (ne:CC (match_dup 5)
+                               (match_dup 6))))]
+  "
+{
+  d30v_split_double (operands[1], &operands[3], &operands[5]);
+  d30v_split_double (operands[2], &operands[4], &operands[6]);
+}")
+
+(define_insn "*ltdi_zero"
+  [(set (match_operand:CC 0 "flag_operand" "=f")
+       (lt:CC (match_operand:DI 1 "gpr_operand" "e")
+              (const_int 0)))]
+  ""
+  "cmplt %0,%U1,0"
+  [(set_attr "length" "4")
+   (set_attr "type" "scmp")])
+
+(define_insn "*ltdi_internal"
+  [(set (match_operand:CC 0 "flag_operand" "=&f,&f,&f")
+       (lt:CC (match_operand:DI 1 "gpr_operand" "e,e,e")
+              (match_operand:DI 2 "gpr_or_dbl_const_operand" "eJP,i,F")))
+   (clobber (match_operand:CC 3 "br_flag_operand" "=&b,&b,&b"))]
+  ""
+  "#"
+  [(set_attr "length" "12,16,24")
+   (set_attr "type" "multi")])
+
+(define_insn "*ledi_internal"
+  [(set (match_operand:CC 0 "flag_operand" "=&f,&f,&f")
+       (le:CC (match_operand:DI 1 "gpr_operand" "e,e,e")
+              (match_operand:DI 2 "gpr_or_dbl_const_operand" "eJP,i,F")))
+   (clobber (match_operand:CC 3 "br_flag_operand" "=&b,&b,&b"))]
+  ""
+  "#"
+  [(set_attr "length" "12,16,24")
+   (set_attr "type" "multi")])
+
+(define_insn "*gtdi_internal"
+  [(set (match_operand:CC 0 "flag_operand" "=&f,&f,&f")
+       (gt:CC (match_operand:DI 1 "gpr_operand" "e,e,e")
+              (match_operand:DI 2 "gpr_or_dbl_const_operand" "eJP,i,F")))
+   (clobber (match_operand:CC 3 "br_flag_operand" "=&b,&b,&b"))]
+  ""
+  "#"
+  [(set_attr "length" "12,16,24")
+   (set_attr "type" "multi")])
+
+(define_insn "*gedi_zero"
+  [(set (match_operand:CC 0 "flag_operand" "=f")
+       (ge:CC (match_operand:DI 1 "gpr_operand" "e")
+              (const_int 0)))]
+  ""
+  "cmpge %0,%U1,0"
+  [(set_attr "length" "4")
+   (set_attr "type" "scmp")])
+
+(define_insn "*gedi_internal"
+  [(set (match_operand:CC 0 "flag_operand" "=&f,&f,&f")
+       (ge:CC (match_operand:DI 1 "gpr_operand" "e,e,e")
+              (match_operand:DI 2 "gpr_or_dbl_const_operand" "eJP,i,F")))
+   (clobber (match_operand:CC 3 "br_flag_operand" "=&b,&b,&b"))]
+  ""
+  "#"
+  [(set_attr "length" "12,16,24")
+   (set_attr "type" "multi")])
+
+(define_insn "*ltudi_internal"
+  [(set (match_operand:CC 0 "flag_operand" "=&f,&f,&f")
+       (ltu:CC (match_operand:DI 1 "gpr_operand" "e,e,e")
+               (match_operand:DI 2 "gpr_or_dbl_const_operand" "eJP,i,F")))
+   (clobber (match_operand:CC 3 "br_flag_operand" "=&b,&b,&b"))]
+  ""
+  "#"
+  [(set_attr "length" "12,16,24")
+   (set_attr "type" "multi")])
+
+(define_insn "*leudi_internal"
+  [(set (match_operand:CC 0 "flag_operand" "=&f,&f,&f")
+       (leu:CC (match_operand:DI 1 "gpr_operand" "e,e,e")
+               (match_operand:DI 2 "gpr_or_dbl_const_operand" "eJP,i,F")))
+   (clobber (match_operand:CC 3 "br_flag_operand" "=&b,&b,&b"))]
+  ""
+  "#"
+  [(set_attr "length" "12,16,24")
+   (set_attr "type" "multi")])
+
+(define_insn "*gtudi_internal"
+  [(set (match_operand:CC 0 "flag_operand" "=&f,&f,&f")
+       (gtu:CC (match_operand:DI 1 "gpr_operand" "e,e,e")
+               (match_operand:DI 2 "gpr_or_dbl_const_operand" "eJP,i,F")))
+   (clobber (match_operand:CC 3 "br_flag_operand" "=&b,&b,&b"))]
+  ""
+  "#"
+  [(set_attr "length" "12,16,24")
+   (set_attr "type" "multi")])
+
+(define_insn "*geudi_internal"
+  [(set (match_operand:CC 0 "flag_operand" "=&f,&f,&f")
+       (geu:CC (match_operand:DI 1 "gpr_operand" "e,e,e")
+               (match_operand:DI 2 "gpr_or_dbl_const_operand" "eJP,i,F")))
+   (clobber (match_operand:CC 3 "br_flag_operand" "=&b,&b,&b"))]
+  ""
+  "#"
+  [(set_attr "length" "12,16,24")
+   (set_attr "type" "multi")])
+
+(define_split
+  [(set (match_operand:CC 0 "flag_operand" "")
+       (match_operator:CC 1 "relational_di_operator"
+                          [(match_operand:DI 2 "gpr_operand" "")
+                           (match_operand:DI 3 "gpr_or_dbl_const_operand" "")]))
+   (clobber (match_operand:CC 4 "br_flag_operand" ""))]
+  "reload_completed"
+  [(match_dup 5)
+   (match_dup 6)
+   (match_dup 7)]
+  "
+{
+  enum rtx_code cond = GET_CODE (operands[1]);
+  enum rtx_code ucond = unsigned_condition (cond);
+  rtx tmpflag = operands[4];
+  rtx outflag = operands[0];
+  rtx high[2];
+  rtx low[2];
+
+  d30v_split_double (operands[2], &high[0], &low[0]);
+  d30v_split_double (operands[3], &high[1], &low[1]);
+
+  operands[5] = gen_rtx (SET, VOIDmode,
+                        tmpflag,
+                        gen_rtx (EQ, CCmode, high[0], high[1]));
+
+  operands[6] = gen_rtx (SET, VOIDmode,
+                        outflag,
+                        gen_rtx (IF_THEN_ELSE, CCmode,
+                                 tmpflag,
+                                 outflag,
+                                 gen_rtx (cond, CCmode, high[0], high[1])));
+
+  operands[7] = gen_rtx (SET, VOIDmode,
+                        outflag,
+                        gen_rtx (IF_THEN_ELSE, CCmode,
+                                 tmpflag,
+                                 gen_rtx (ucond, CCmode, low[0], low[1]),
+                                 outflag));
+}")
+
+\f
+;; ::::::::::::::::::::
+;; ::
+;; :: Branches
+;; ::
+;; ::::::::::::::::::::
+
+;; Define_expands called by the machine independent part of the compiler
+;; to allocate a new comparison register
+
+(define_expand "beq"
+  [(match_dup 2)
+   (set (pc)
+       (if_then_else (ne:CC (match_dup 1)
+                            (const_int 0))
+                     (label_ref (match_operand 0 "" ""))
+                     (pc)))]
+  ""
+  "
+{
+  operands[1] = gen_reg_rtx (CCmode);
+  operands[2] = d30v_emit_comparison (EQ, operands[1],
+                                     d30v_compare_op0,
+                                     d30v_compare_op1);
+}")
+
+(define_expand "bne"
+  [(match_dup 2)
+   (set (pc)
+       (if_then_else (ne:CC (match_dup 1)
+                            (const_int 0))
+                     (label_ref (match_operand 0 "" ""))
+                     (pc)))]
+  ""
+  "
+{
+  operands[1] = gen_reg_rtx (CCmode);
+  operands[2] = d30v_emit_comparison (NE, operands[1],
+                                     d30v_compare_op0,
+                                     d30v_compare_op1);
+}")
+
+(define_expand "bgt"
+  [(match_dup 2)
+   (set (pc)
+       (if_then_else (ne:CC (match_dup 1)
+                            (const_int 0))
+                     (label_ref (match_operand 0 "" ""))
+                     (pc)))]
+  ""
+  "
+{
+  operands[1] = gen_reg_rtx (CCmode);
+  operands[2] = d30v_emit_comparison (GT, operands[1],
+                                     d30v_compare_op0,
+                                     d30v_compare_op1);
+}")
+
+(define_expand "bge"
+  [(match_dup 2)
+   (set (pc)
+       (if_then_else (ne:CC (match_dup 1)
+                            (const_int 0))
+                     (label_ref (match_operand 0 "" ""))
+                     (pc)))]
+  ""
+  "
+{
+  operands[1] = gen_reg_rtx (CCmode);
+  operands[2] = d30v_emit_comparison (GE, operands[1],
+                                     d30v_compare_op0,
+                                     d30v_compare_op1);
+}")
+
+(define_expand "blt"
+  [(match_dup 2)
+   (set (pc)
+       (if_then_else (ne:CC (match_dup 1)
+                            (const_int 0))
+                     (label_ref (match_operand 0 "" ""))
+                     (pc)))]
+  ""
+  "
+{
+  operands[1] = gen_reg_rtx (CCmode);
+  operands[2] = d30v_emit_comparison (LT, operands[1],
+                                     d30v_compare_op0,
+                                     d30v_compare_op1);
+}")
+
+(define_expand "ble"
+  [(match_dup 2)
+   (set (pc)
+       (if_then_else (ne:CC (match_dup 1)
+                            (const_int 0))
+                     (label_ref (match_operand 0 "" ""))
+                     (pc)))]
+  ""
+  "
+{
+  operands[1] = gen_reg_rtx (CCmode);
+  operands[2] = d30v_emit_comparison (LE, operands[1],
+                                     d30v_compare_op0,
+                                     d30v_compare_op1);
+}")
+
+(define_expand "bgtu"
+  [(match_dup 2)
+   (set (pc)
+       (if_then_else (ne:CC (match_dup 1)
+                            (const_int 0))
+                     (label_ref (match_operand 0 "" ""))
+                     (pc)))]
+  ""
+  "
+{
+  operands[1] = gen_reg_rtx (CCmode);
+  operands[2] = d30v_emit_comparison (GTU, operands[1],
+                                     d30v_compare_op0,
+                                     d30v_compare_op1);
+}")
+
+(define_expand "bgeu"
+  [(match_dup 2)
+   (set (pc)
+       (if_then_else (ne:CC (match_dup 1)
+                            (const_int 0))
+                     (label_ref (match_operand 0 "" ""))
+                     (pc)))]
+  ""
+  "
+{
+  operands[1] = gen_reg_rtx (CCmode);
+  operands[2] = d30v_emit_comparison (GEU, operands[1],
+                                     d30v_compare_op0,
+                                     d30v_compare_op1);
+}")
+
+(define_expand "bltu"
+  [(match_dup 2)
+   (set (pc)
+       (if_then_else (ne:CC (match_dup 1)
+                            (const_int 0))
+                     (label_ref (match_operand 0 "" ""))
+                     (pc)))]
+  ""
+  "
+{
+  operands[1] = gen_reg_rtx (CCmode);
+  operands[2] = d30v_emit_comparison (LTU, operands[1],
+                                     d30v_compare_op0,
+                                     d30v_compare_op1);
+}")
+
+(define_expand "bleu"
+  [(match_dup 2)
+   (set (pc)
+       (if_then_else (ne:CC (match_dup 1)
+                            (const_int 0))
+                     (label_ref (match_operand 0 "" ""))
+                     (pc)))]
+  ""
+  "
+{
+  operands[1] = gen_reg_rtx (CCmode);
+  operands[2] = d30v_emit_comparison (LEU, operands[1],
+                                     d30v_compare_op0,
+                                     d30v_compare_op1);
+}")
+
+;; Actual branches.  We must allow for the (label_ref) and the (pc) to be
+;; swapped.  If they are swapped, it reverses the sense of the branch.
+;; Also handle changing the ne to eq.
+;; In order for the length calculations to be correct, the label must be
+;; operand 0.
+
+;; We used to handle branches against 0 to be folded directly into
+;; bratnz/bratzr instruction, but this dimisses the possibility of doing
+;; conditional execution.  Instead handle these via peepholes.
+
+;; Branches based off of the flag bits
+(define_insn "*bra_true"
+  [(set (pc)
+       (if_then_else (match_operator:CC 1 "condexec_branch_operator"
+                                        [(match_operand:CC 2 "br_flag_or_constant_operand" "b,I,N")
+                                         (const_int 0)])
+                     (label_ref (match_operand 0 "" ""))
+                     (pc)))]
+  ""
+  "*
+{
+  if (GET_CODE (operands[2]) == REG || GET_CODE (operands[2]) == SUBREG)
+    return \"bra%F1 %l0\";
+
+  if (GET_CODE (operands[2]) != CONST_INT)
+    fatal_insn (\"bad jump\", insn);
+
+  if ((GET_CODE (operands[1]) == EQ && INTVAL (operands[2]) == 0)
+      || (GET_CODE (operands[1]) == NE && INTVAL (operands[2]) != 0))
+    return \"bra %l0\";
+
+  return \"; jump to %l0 optimized away\";
+}"
+  [(set_attr "type" "br")])
+
+(define_insn "*bra_false"
+  [(set (pc)
+       (if_then_else (match_operator:CC 1 "condexec_branch_operator"
+                                        [(match_operand:CC 2 "br_flag_or_constant_operand" "b,I,N")
+                                         (const_int 0)])
+                     (pc)
+                     (label_ref (match_operand 0 "" ""))))]
+  ""
+  "*
+{
+  if (GET_CODE (operands[2]) == REG || GET_CODE (operands[2]) == SUBREG)
+    return \"bra%T1 %l0\";
+
+  if (GET_CODE (operands[2]) != CONST_INT)
+    fatal_insn (\"bad jump\", insn);
+
+  if ((GET_CODE (operands[1]) == EQ && INTVAL (operands[2]) != 0)
+      || (GET_CODE (operands[1]) == NE && INTVAL (operands[2]) == 0))
+    return \"bra %l0\";
+
+  return \"; jump to %l0 optimized away\";
+}"
+  [(set_attr "type" "br")])
+
+;; Peephole to turn set flag, cond. jumps into branch if register ==/!= 0.
+
+(define_peephole2
+  [(set (match_operand:CC 0 "br_flag_operand" "=b")
+       (match_operator:CC 1 "branch_zero_operator"
+                          [(match_operand:SI 2 "gpr_operand" "d")
+                           (const_int 0)]))
+   (set (pc)
+       (if_then_else (match_operator:CC 3 "condexec_test_operator"
+                                        [(match_dup 0)
+                                         (const_int 0)])
+                     (match_operand 4 "" "")
+                     (match_operand 5 "" "")))]
+  "reg_dead_p (last_insn, operands[0])"
+  [(set (pc)
+       (if_then_else (match_dup 6)
+                     (match_dup 4)
+                     (match_dup 5)))]
+  "
+{
+  int true_false = 1;
+  if (GET_CODE (operands[1]) == EQ)
+    true_false = !true_false;
+  if (GET_CODE (operands[3]) == EQ)
+    true_false = !true_false;
+  operands[6] = gen_rtx_fmt_ee ((true_false ? NE : EQ), CCmode,
+                               operands[2], const0_rtx);
+}")
+
+(define_insn "*bra_reg_true"
+  [(set (pc) (if_then_else (match_operator:CC 1 "branch_zero_operator"
+                            [(match_operand:SI 2 "gpr_operand" "d")
+                             (const_int 0)])
+                          (label_ref (match_operand 0 "" ""))
+                          (pc)))]
+  "reload_completed"
+  "*
+{
+  return GET_CODE (operands[1]) == NE ? \"bratnz %2,%l0\" : \"bratzr %2,%l0\";
+}"
+  [(set_attr "type" "br2")])
+
+(define_insn "*bra_reg_false"
+  [(set (pc) (if_then_else (match_operator:CC 1 "branch_zero_operator"
+                            [(match_operand:SI 2 "gpr_operand" "d")
+                             (const_int 0)])
+                          (pc)
+                          (label_ref (match_operand 0 "" ""))))]
+  "reload_completed"
+  "*
+{
+  return GET_CODE (operands[1]) == EQ ? \"bratnz %2,%l0\" : \"bratzr %2,%l0\";
+}"
+  [(set_attr "type" "br2")])
+\f
+;; ::::::::::::::::::::
+;; ::
+;; :: Set flag operations
+;; ::
+;; ::::::::::::::::::::
+
+;; Define_expands called by the machine independent part of the compiler
+;; to allocate a new comparison register
+
+;; ??? These patterns should all probably use (ne:SI ... (const_int 0)) instead
+;; of (eq:SI ... (const_int 1)), because the former is the canonical form.
+;; The non-canonical form was used here because I was just trying to get the
+;; port working again after it broke, and the non-canonical form was the
+;; safer faster way to fix this.
+
+
+(define_expand "seq"
+  [(match_dup 2)
+   (set (match_operand:SI 0 "gpr_operand" "")
+       (ne:SI (match_dup 1) (const_int 0)))]
+  ""
+  "
+{
+  operands[1] = gen_reg_rtx (CCmode);
+  operands[2] = d30v_emit_comparison (EQ, operands[1],
+                                     d30v_compare_op0,
+                                     d30v_compare_op1);
+}")
+
+(define_expand "sne"
+  [(match_dup 2)
+   (set (match_operand:SI 0 "gpr_operand" "")
+       (ne:SI (match_dup 1) (const_int 0)))]
+  ""
+  "
+{
+  operands[1] = gen_reg_rtx (CCmode);
+  operands[2] = d30v_emit_comparison (NE, operands[1],
+                                     d30v_compare_op0,
+                                     d30v_compare_op1);
+}")
+
+(define_expand "sgt"
+  [(match_dup 2)
+   (set (match_operand:SI 0 "gpr_operand" "")
+       (ne:SI (match_dup 1) (const_int 0)))]
+  ""
+  "
+{
+  operands[1] = gen_reg_rtx (CCmode);
+  operands[2] = d30v_emit_comparison (GT, operands[1],
+                                     d30v_compare_op0,
+                                     d30v_compare_op1);
+}")
+
+(define_expand "sge"
+  [(match_dup 2)
+   (set (match_operand:SI 0 "gpr_operand" "")
+       (ne:SI (match_dup 1) (const_int 0)))]
+  ""
+  "
+{
+  operands[1] = gen_reg_rtx (CCmode);
+  operands[2] = d30v_emit_comparison (GE, operands[1],
+                                     d30v_compare_op0,
+                                     d30v_compare_op1);
+}")
+
+(define_expand "slt"
+  [(match_dup 2)
+   (set (match_operand:SI 0 "gpr_operand" "")
+       (ne:SI (match_dup 1) (const_int 0)))]
+  ""
+  "
+{
+  operands[1] = gen_reg_rtx (CCmode);
+  operands[2] = d30v_emit_comparison (LT, operands[1],
+                                     d30v_compare_op0,
+                                     d30v_compare_op1);
+}")
+
+(define_expand "sle"
+  [(match_dup 2)
+   (set (match_operand:SI 0 "gpr_operand" "")
+       (ne:SI (match_dup 1) (const_int 0)))]
+  ""
+  "
+{
+  operands[1] = gen_reg_rtx (CCmode);
+  operands[2] = d30v_emit_comparison (LE, operands[1],
+                                     d30v_compare_op0,
+                                     d30v_compare_op1);
+}")
+
+(define_expand "sgtu"
+  [(match_dup 2)
+   (set (match_operand:SI 0 "gpr_operand" "")
+       (ne:SI (match_dup 1) (const_int 0)))]
+  ""
+  "
+{
+  operands[1] = gen_reg_rtx (CCmode);
+  operands[2] = d30v_emit_comparison (GTU, operands[1],
+                                     d30v_compare_op0,
+                                     d30v_compare_op1);
+}")
+
+(define_expand "sgeu"
+  [(match_dup 2)
+   (set (match_operand:SI 0 "gpr_operand" "")
+       (ne:SI (match_dup 1) (const_int 0)))]
+  ""
+  "
+{
+  operands[1] = gen_reg_rtx (CCmode);
+  operands[2] = d30v_emit_comparison (GEU, operands[1],
+                                     d30v_compare_op0,
+                                     d30v_compare_op1);
+}")
+
+(define_expand "sltu"
+  [(match_dup 2)
+   (set (match_operand:SI 0 "gpr_operand" "")
+       (ne:SI (match_dup 1) (const_int 0)))]
+  ""
+  "
+{
+  operands[1] = gen_reg_rtx (CCmode);
+  operands[2] = d30v_emit_comparison (LTU, operands[1],
+                                     d30v_compare_op0,
+                                     d30v_compare_op1);
+}")
+
+(define_expand "sleu"
+  [(match_dup 2)
+   (set (match_operand:SI 0 "gpr_operand" "")
+       (ne:SI (match_dup 1) (const_int 0)))]
+  ""
+  "
+{
+  operands[1] = gen_reg_rtx (CCmode);
+  operands[2] = d30v_emit_comparison (LEU, operands[1],
+                                     d30v_compare_op0,
+                                     d30v_compare_op1);
+}")
+
+;; Set flag operations.  We prefer to use conditional execution instead of
+;; mvfsys, since it is faster, but allow the use of mvfsys to offload some
+;; register pressure.
+(define_insn "*setcc_internal"
+  [(set (match_operand:SI 0 "gpr_operand" "=d,?d,?*d")
+       (ne:SI (match_operand:CC 1 "flag_operand" "b,z,*d")
+              (const_int 0)))]
+  ""
+  "@
+    #
+    mvfsys %0,%1
+    or %0,%.,%1"
+  [(set_attr "length" "8,4,4")
+   (set_attr "type" "multi,either,either")])
+
+(define_split
+  [(set (match_operand:SI 0 "gpr_operand" "")
+       (ne:SI (match_operand:CC 1 "br_flag_operand" "")
+              (const_int 0)))]
+  "reload_completed"
+  [(set (match_dup 0)
+       (const_int 0))
+   (set (match_dup 0)
+       (if_then_else:SI (ne:CC (match_dup 1)
+                               (const_int 0))
+                        (const_int 1)
+                        (match_dup 0)))]
+  "")
+
+\f
+;; ::::::::::::::::::::
+;; ::
+;; :: Operations on flags
+;; ::
+;; ::::::::::::::::::::
+
+(define_insn "andcc3"
+  [(set (match_operand:CC 0 "flag_operand" "=f")
+       (and:CC (match_operand:CC 1 "flag_operand" "f")
+               (match_operand:CC 2 "flag_operand" "f")))]
+  ""
+  "andfg %0,%1,%2"
+  [(set_attr "length" "4")
+   (set_attr "type" "either")])
+
+(define_insn "iorcc3"
+  [(set (match_operand:CC 0 "flag_operand" "=f")
+       (ior:CC (match_operand:CC 1 "flag_operand" "f")
+               (match_operand:CC 2 "flag_operand" "f")))]
+  ""
+  "orfg %0,%1,%2"
+  [(set_attr "length" "4")
+   (set_attr "type" "either")])
+
+(define_insn "xorcc3"
+  [(set (match_operand:CC 0 "flag_operand" "=f")
+       (xor:CC (match_operand:CC 1 "flag_operand" "f")
+               (match_operand:CC 2 "flag_operand" "f")))]
+  ""
+  "xorfg %0,%1,%2"
+  [(set_attr "length" "4")
+   (set_attr "type" "either")])
+
+;; This is the canonical form produced by combine.
+
+(define_insn "incscc"
+  [(set (match_operand:SI 0 "gpr_operand" "=d")
+        (plus:SI (eq:SI (match_operand:CC 1 "br_flag_operand" "b")
+                       (const_int 1))
+                (match_operand:SI 2 "gpr_operand" "0")))]
+  ""
+  "add%T1 %0,%2,1"
+[(set_attr "length" "4")
+ (set_attr "type" "either")])
+
+(define_insn "decscc"
+  [(set (match_operand:SI 0 "gpr_operand" "=d")
+        (minus:SI (match_operand:SI 1 "gpr_operand" "0")
+                 (eq:SI (match_operand:CC 2 "br_flag_operand" "b")
+                        (const_int 1))))]
+  ""
+  "sub%T2 %0,%1,1"
+[(set_attr "length" "4")
+ (set_attr "type" "either")])
+\f
+;; ::::::::::::::::::::
+;; ::
+;; :: Call and branch instructions
+;; ::
+;; ::::::::::::::::::::
+
+;; Subroutine call instruction returning no value.  Operand 0 is the function
+;; to call; operand 1 is the number of bytes of arguments pushed (in mode
+;; `SImode', except it is normally a `const_int'); operand 2 is the number of
+;; registers used as operands.
+
+;; On most machines, operand 2 is not actually stored into the RTL pattern.  It
+;; is supplied for the sake of some RISC machines which need to put this
+;; information into the assembler code; they can put it in the RTL instead of
+;; operand 1.
+
+(define_expand "call"
+  [(parallel [(call (match_operand 0 "call_operand" "")
+                   (match_operand 1 "" ""))
+             (use (match_operand 2 "" ""))
+             (clobber (match_dup 3))])]
+  ""
+  "
+{
+  if (GET_CODE (XEXP (operands[0], 0)) == SUBREG)
+    XEXP (operands[0], 0) = copy_addr_to_reg (XEXP (operands[0], 0));
+
+  if (!operands[2])
+    operands[2] = const0_rtx;
+
+  operands[3] = gen_rtx (REG, Pmode, GPR_LINK);
+}")
+
+(define_insn "*call_internal"
+  [(call (match_operand:QI 0 "call_operand" "R,S")
+        (match_operand 1 "" ""))
+   (use (match_operand 2 "" ""))
+   (clobber (match_operand 3 "" "=d,d"))]
+  ""
+  "@
+    jsr %0
+    bsr %0"
+  [(set_attr "length" "4,8")
+   (set_attr "type" "mu,long")])
+
+;; Subroutine call instruction returning a value.  Operand 0 is the hard
+;; register in which the value is returned.  There are three more operands, the
+;; same as the three operands of the `call' instruction (but with numbers
+;; increased by one).
+
+;; Subroutines that return `BLKmode' objects use the `call' insn.
+
+(define_expand "call_value"
+  [(parallel [(set (match_operand 0 "gpr_operand" "")
+                  (call (match_operand 1 "call_operand" "")
+                        (match_operand 2 "" "")))
+            (use (match_operand 3 "" ""))
+            (clobber (match_dup 4))])]
+  ""
+  "
+{
+  if (GET_CODE (XEXP (operands[1], 0)) == SUBREG)
+    XEXP (operands[1], 0) = copy_addr_to_reg (XEXP (operands[1], 0));
+
+  if (!operands[3])
+    operands[3] = const0_rtx;
+
+  operands[4] = gen_rtx (REG, Pmode, GPR_LINK);
+}")
+
+(define_insn "*call_value_internal"
+  [(set (match_operand 0 "gpr_operand" "=d,d")
+       (call (match_operand:QI 1 "call_operand" "R,S")
+             (match_operand 2 "" "")))
+       (use (match_operand 3 "" ""))
+       (clobber (match_operand 4 "" "=d,d"))]
+  ""
+  "@
+    jsr %1
+    bsr %1"
+  [(set_attr "length" "4,8")
+   (set_attr "type" "mu,long")])
+
+;; Subroutine return
+(define_expand "return"
+  [(return)]
+  "direct_return ()"
+  "")
+
+(define_insn "*return_internal"
+  [(return)]
+  "reload_completed"
+  "jmp link"
+  [(set_attr "length" "4")
+   (set_attr "type" "mu")])
+
+(define_insn "*cond_return_true"
+  [(set (pc)
+       (if_then_else (match_operator:CC 0 "condexec_branch_operator"
+                       [(match_operand:CC 1 "br_flag_operand" "b")
+                        (const_int 0)])
+         (return)
+         (pc)))]
+  "reload_completed"
+  "jmp%F0 link"
+  [(set_attr "length" "4")
+   (set_attr "type" "mu")])
+
+(define_insn "*cond_return_false"
+  [(set (pc)
+       (if_then_else (match_operator:CC 0 "condexec_branch_operator"
+                       [(match_operand:CC 1 "br_flag_operand" "b")
+                        (const_int 0)])
+         (pc)
+         (return)))]
+  "reload_completed"
+  "jmp%T0 link"
+  [(set_attr "length" "4")
+   (set_attr "type" "mu")])
+
+;; Normal unconditional jump
+(define_insn "jump"
+  [(set (pc) (label_ref (match_operand 0 "" "")))]
+  ""
+  "bra %l0"
+  [(set_attr "type" "br")])
+
+;; Indirect jump through a register
+(define_insn "indirect_jump"
+  [(set (pc) (match_operand:SI 0 "gpr_operand" "d"))]
+  ""
+  "jmp %0"
+  [(set_attr "length" "4")
+   (set_attr "type" "mu")])
+
+;; Instruction to jump to a variable address.  This is a low-level capability
+;; which can be used to implement a dispatch table when there is no `casesi'
+;; pattern.
+
+;; This pattern requires two operands: the address or offset, and a label which
+;; should immediately precede the jump table.  If the macro
+;; `CASE_VECTOR_PC_RELATIVE' is defined then the first operand is an offset
+;; which counts from the address of the table; otherwise, it is an absolute
+;; address to jump to.  In either case, the first operand has mode `Pmode'.
+
+;; The `tablejump' insn is always the last insn before the jump table it uses.
+;; Its assembler code normally has no need to use the second operand, but you
+;; should incorporate it in the RTL pattern so that the jump optimizer will not
+;; delete the table as unreachable code.
+
+(define_insn "tablejump"
+  [(set (pc) (match_operand:SI 0 "gpr_operand" "d"))
+   (use (label_ref (match_operand 1 "" "")))]
+  ""
+  "jmp %0"
+  [(set_attr "length" "4")
+   (set_attr "type" "mu")])
+
+\f
+
+;; ::::::::::::::::::::
+;; ::
+;; :: Prologue and Epilogue instructions
+;; ::
+;; ::::::::::::::::::::
+
+;; Called after register allocation to add any instructions needed for the
+;; prologue.  Using a prologue insn is favored compared to putting all of the
+;; instructions in the FUNCTION_PROLOGUE macro, since it allows the scheduler
+;; to intermix instructions with the saves of the caller saved registers.  In
+;; some cases, it might be necessary to emit a barrier instruction as the last
+;; insn to prevent such scheduling.
+
+(define_expand "prologue"
+  [(const_int 1)]
+  ""
+  "
+{
+  d30v_expand_prologue ();
+  DONE;
+}")
+
+;; Called after register allocation to add any instructions needed for the
+;; epilogue.  Using a epilogue insn is favored compared to putting all of the
+;; instructions in the FUNCTION_PROLOGUE macro, since it allows the scheduler
+;; to intermix instructions with the saves of the caller saved registers.  In
+;; some cases, it might be necessary to emit a barrier instruction as the last
+;; insn to prevent such scheduling.
+
+(define_expand "epilogue"
+  [(const_int 2)]
+  ""
+  "
+{
+  d30v_expand_epilogue ();
+  DONE;
+}")
+
+(define_expand "eh_epilogue"
+  [(use (match_operand:DI 0 "register_operand" "r"))
+   (use (match_operand:DI 1 "register_operand" "r"))
+   (use (match_operand:DI 2 "register_operand" "r"))]
+  ""
+  "
+{
+  d30v_eh_epilogue_sp_ofs = operands[1];
+  if (GET_CODE (operands[2]) != REG || REGNO (operands[2]) != GPR_LINK)
+    {
+      rtx ra = gen_rtx_REG (Pmode, GPR_LINK);
+      emit_move_insn (ra, operands[2]);
+      operands[2] = ra;
+    }
+}")
+
+\f
+;; ::::::::::::::::::::
+;; ::
+;; :: Conditional move instructions
+;; ::
+;; ::::::::::::::::::::
+
+;; Conditionally move operand 2 or operand 3 into operand 0 according to the
+;; comparison in operand 1.  If the comparison is true, operand 2 is moved into
+;; operand 0, otherwise operand 3 is moved.
+
+;; The mode of the operands being compared need not be the same as the operands
+;; being moved.  Some machines, sparc64 for example, have instructions that
+;; conditionally move an integer value based on the floating point condition
+;; codes and vice versa.
+
+;; If the machine does not have conditional move instructions, do not
+;; define these patterns.
+
+;; Note we don't allow the general form of conditional store to be generated --
+;; we always generate two separate if_then_elses's
+(define_expand "movqicc"
+  [(set (match_operand:QI 0 "move_output_operand" "")
+       (if_then_else:QI (match_operand 1 "" "")
+                        (match_operand:QI 2 "move_input_operand" "")
+                        (match_operand:QI 3 "move_input_operand" "")))]
+  "TARGET_COND_MOVE"
+  "
+{
+  if (!d30v_emit_cond_move (operands[0], operands[1], operands[2], operands[3]))
+    FAIL;
+
+  DONE;
+}")
+
+(define_insn "*movqicc_internal"
+  [(set (match_operand:QI 0 "gpr_operand" "=d,d,d,d,d,c,d,d,d,d,d,c,?&d")
+       (if_then_else:QI (match_operator:CC 1 "condexec_test_operator"
+                                           [(match_operand:CC 2 "br_flag_operand" "b,b,b,b,b,b,b,b,b,b,b,b,b")
+                                            (const_int 0)])
+                        (match_operand:QI 3 "move_input_operand" "dI,i,Q,m,c,d,0,0,0,0,0,0,dim")
+                        (match_operand:QI 4 "move_input_operand" "0,0,0,0,0,0,dI,i,Q,m,c,d,dim")))]
+  ""
+  "#"
+  [(set_attr "length" "4,8,4,8,4,4,4,8,4,8,4,4,16")
+   (set_attr "type" "either,long,sload,lload,mu,mu,either,long,sload,lload,mu,mu,multi")])
+
+;; If we have: a = (test) ? a : b, or a = (test) ? b : a, we can split it
+;; before reload to allow combine to substitute in early.
+;; ??? Not until we teach reload how to do conditional spills, we can't.
+(define_split
+  [(set (match_operand:QI 0 "move_output_operand" "")
+       (if_then_else:QI (match_operator:CC 1 "condexec_test_operator"
+                          [(match_operand:CC 2 "br_flag_operand" "")
+                           (const_int 0)])
+                        (match_operand:QI 3 "move_input_operand" "")
+                        (match_dup 0)))]
+  "reload_completed"
+  [(cond_exec (match_dup 1) 
+     (set (match_dup 0) (match_dup 3)))]
+  "")
+
+(define_split
+  [(set (match_operand:QI 0 "move_output_operand" "")
+       (if_then_else:QI (match_operator:CC 1 "condexec_test_operator"
+                          [(match_operand:CC 2 "br_flag_operand" "")
+                           (const_int 0)])
+                        (match_dup 0)
+                        (match_operand:QI 3 "move_input_operand" "")))]
+  "reload_completed"
+  [(cond_exec (match_dup 4)
+     (set (match_dup 0) (match_dup 3)))]
+  "
+{
+  if (GET_CODE (operands[1]) == EQ)
+    operands[4] = gen_rtx_NE (CCmode, operands[2], const0_rtx);
+  else
+    operands[4] = gen_rtx_EQ (CCmode, operands[2], const0_rtx);
+}")
+
+(define_split
+  [(set (match_operand:QI 0 "move_output_operand" "")
+       (if_then_else:QI (match_operator:CC 1 "condexec_test_operator"
+                          [(match_operand:CC 2 "br_flag_operand" "")
+                           (const_int 0)])
+                        (match_operand:QI 3 "move_input_operand" "")
+                        (match_operand:QI 4 "move_input_operand" "")))]
+  "reload_completed"
+  [(cond_exec (match_dup 1)
+     (set (match_dup 0) (match_dup 3)))
+   (cond_exec (match_dup 5)
+     (set (match_dup 0) (match_dup 4)))]
+  "
+{
+  if (GET_CODE (operands[1]) == EQ)
+    operands[5] = gen_rtx_NE (CCmode, operands[2], const0_rtx);
+  else
+    operands[5] = gen_rtx_EQ (CCmode, operands[2], const0_rtx);
+}")
+
+(define_expand "movhicc"
+  [(set (match_operand:HI 0 "move_output_operand" "")
+       (if_then_else:HI (match_operand 1 "" "")
+                        (match_operand:HI 2 "move_input_operand" "")
+                        (match_operand:HI 3 "move_input_operand" "")))]
+  "TARGET_COND_MOVE"
+  "
+{
+  if (!d30v_emit_cond_move (operands[0], operands[1], operands[2], operands[3]))
+    FAIL;
+
+  DONE;
+}")
+
+(define_insn "*movhicc_internal"
+  [(set (match_operand:HI 0 "gpr_operand" "=d,d,d,d,d,c,d,d,d,d,d,c,?&d")
+       (if_then_else:HI
+         (match_operator:CC 1 "condexec_test_operator"
+           [(match_operand:CC 2 "br_flag_operand" "b,b,b,b,b,b,b,b,b,b,b,b,b")
+            (const_int 0)])
+         (match_operand:HI 3 "move_input_operand" "dI,i,Q,m,c,d,0,0,0,0,0,0,dim")
+         (match_operand:HI 4 "move_input_operand" "0,0,0,0,0,0,dI,i,Q,m,c,d,dim")))]
+  ""
+  "#"
+  [(set_attr "length" "4,8,4,8,4,4,4,8,4,8,4,4,16")
+   (set_attr "type" "either,long,sload,lload,mu,mu,either,long,sload,lload,mu,mu,multi")])
+
+;; If we have: a = (test) ? a : b, or a = (test) ? b : a, we can split it
+;; before reload to allow combine to substitute in early.
+;; ??? Not until we teach reload how to do conditional spills, we can't.
+(define_split
+  [(set (match_operand:HI 0 "move_output_operand" "")
+       (if_then_else:HI (match_operator:CC 1 "condexec_test_operator"
+                          [(match_operand:CC 2 "br_flag_operand" "")
+                           (const_int 0)])
+                        (match_operand:HI 3 "move_input_operand" "")
+                        (match_dup 0)))]
+  "reload_completed"
+  [(cond_exec (match_dup 1)
+     (set (match_dup 0) (match_dup 3)))]
+  "")
+
+(define_split
+  [(set (match_operand:HI 0 "move_output_operand" "")
+       (if_then_else:HI (match_operator:CC 1 "condexec_test_operator"
+                          [(match_operand:CC 2 "br_flag_operand" "")
+                           (const_int 0)])
+                        (match_dup 0)
+                        (match_operand:HI 3 "move_input_operand" "")))]
+  "reload_completed"
+  [(cond_exec (match_dup 4)
+     (set (match_dup 0) (match_dup 3)))]
+  "
+{
+  if (GET_CODE (operands[1]) == EQ)
+    operands[4] = gen_rtx_NE (CCmode, operands[2], const0_rtx);
+  else
+    operands[4] = gen_rtx_EQ (CCmode, operands[2], const0_rtx);
+}")
+
+(define_split
+  [(set (match_operand:HI 0 "move_output_operand" "")
+       (if_then_else:HI (match_operator:CC 1 "condexec_test_operator"
+                          [(match_operand:CC 2 "br_flag_operand" "")
+                           (const_int 0)])
+                        (match_operand:HI 3 "move_input_operand" "")
+                        (match_operand:HI 4 "move_input_operand" "")))]
+  "reload_completed"
+  [(cond_exec (match_dup 1)
+     (set (match_dup 0) (match_dup 3)))
+   (cond_exec (match_dup 5)
+     (set (match_dup 0) (match_dup 4)))]
+  "
+{
+  if (GET_CODE (operands[1]) == EQ)
+    operands[5] = gen_rtx_NE (CCmode, operands[2], const0_rtx);
+  else
+    operands[5] = gen_rtx_EQ (CCmode, operands[2], const0_rtx);
+}")
+
+(define_expand "movsicc"
+  [(set (match_operand:SI 0 "move_output_operand" "")
+       (if_then_else:SI (match_operand 1 "" "")
+                        (match_operand:SI 2 "move_input_operand" "")
+                        (match_operand:SI 3 "move_input_operand" "")))]
+  "TARGET_COND_MOVE"
+  "
+{
+  if (!d30v_emit_cond_move (operands[0], operands[1], operands[2], operands[3]))
+    FAIL;
+
+  DONE;
+}")
+
+(define_insn "*movsicc_internal"
+  [(set (match_operand:SI 0 "move_output_operand" "=d,d,d,d,d,c,d,d,d,d,d,c,?&d")
+       (if_then_else:SI
+         (match_operator:CC 1 "condexec_test_operator"
+           [(match_operand:CC 2 "br_flag_operand" "b,b,b,b,b,b,b,b,b,b,b,b,b")
+            (const_int 0)])
+         (match_operand:SI 3 "move_input_operand" "dI,i,Q,m,c,d,0,0,0,0,0,0,dim")
+         (match_operand:SI 4 "move_input_operand" "0,0,0,0,0,0,dI,i,Q,m,c,d,dim")))]
+  ""
+  "#"
+  [(set_attr "length" "4,8,4,8,4,4,4,8,4,8,4,4,16")
+   (set_attr "type" "either,long,sload,lload,mu,mu,either,long,sload,lload,mu,mu,multi")])
+
+;; If we have: a = (test) ? a : b, or a = (test) ? b : a, we can split it
+;; before reload to allow combine to substitute in early.
+;; ??? Not until we teach reload how to do conditional spills, we can't.
+(define_split
+  [(set (match_operand:SI 0 "move_output_operand" "")
+       (if_then_else:SI (match_operator:CC 1 "condexec_test_operator"
+                          [(match_operand:CC 2 "br_flag_operand" "")
+                           (const_int 0)])
+                        (match_operand:SI 3 "move_input_operand" "")
+                        (match_dup 0)))]
+  "reload_completed"
+  [(cond_exec (match_dup 1)
+     (set (match_dup 0) (match_dup 3)))]
+  "")
+
+(define_split
+  [(set (match_operand:SI 0 "move_output_operand" "")
+       (if_then_else:SI (match_operator:CC 1 "condexec_test_operator"
+                          [(match_operand:CC 2 "br_flag_operand" "")
+                           (const_int 0)])
+                        (match_dup 0)
+                        (match_operand:SI 3 "move_input_operand" "")))]
+  "reload_completed"
+  [(cond_exec (match_dup 4)
+     (set (match_dup 0) (match_dup 3)))]
+  "
+{
+  if (GET_CODE (operands[1]) == EQ)
+    operands[4] = gen_rtx_NE (CCmode, operands[2], const0_rtx);
+  else
+    operands[4] = gen_rtx_EQ (CCmode, operands[2], const0_rtx);
+}")
+
+(define_split
+  [(set (match_operand:SI 0 "move_output_operand" "")
+       (if_then_else:SI (match_operator:CC 1 "condexec_test_operator"
+                          [(match_operand:CC 2 "br_flag_operand" "")
+                           (const_int 0)])
+                        (match_operand:SI 3 "move_input_operand" "")
+                        (match_operand:SI 4 "move_input_operand" "")))]
+  "reload_completed"
+  [(cond_exec (match_dup 1)
+     (set (match_dup 0) (match_dup 3)))
+   (cond_exec (match_dup 5)
+     (set (match_dup 0) (match_dup 4)))]
+  "
+{
+  if (GET_CODE (operands[1]) == EQ)
+    operands[5] = gen_rtx_NE (CCmode, operands[2], const0_rtx);
+  else
+    operands[5] = gen_rtx_EQ (CCmode, operands[2], const0_rtx);
+}")
+
+(define_expand "movsfcc"
+  [(set (match_operand:SF 0 "move_output_operand" "")
+       (if_then_else:SF (match_operand 1 "" "")
+                        (match_operand:SF 2 "move_input_operand" "")
+                        (match_operand:SF 3 "move_input_operand" "")))]
+  "TARGET_COND_MOVE"
+  "
+{
+  if (!d30v_emit_cond_move (operands[0], operands[1], operands[2], operands[3]))
+    FAIL;
+
+  DONE;
+}")
+
+(define_insn "*movsfcc_internal"
+  [(set (match_operand:SF 0 "gpr_operand" "=d,d,d,d,d,d,d,d,?&d")
+       (if_then_else:SF
+         (match_operator:CC 1 "condexec_test_operator"
+           [(match_operand:CC 2 "br_flag_operand" "b,b,b,b,b,b,b,b,b")
+            (const_int 0)])
+         (match_operand:SF 3 "move_input_operand" "dG,F,Q,m,0,0,0,0,dim")
+         (match_operand:SF 4 "move_input_operand" "0,0,0,0,dG,F,Q,m,dim")))]
+  ""
+  "#"
+  [(set_attr "length" "4,8,4,8,4,8,4,8,16")
+   (set_attr "type" "either,long,sload,lload,either,long,sload,lload,multi")])
+
+(define_split
+  [(set (match_operand:SF 0 "move_output_operand" "")
+       (if_then_else:SF (match_operator:CC 1 "condexec_test_operator"
+                          [(match_operand:CC 2 "br_flag_operand" "")
+                           (const_int 0)])
+                        (match_operand:SF 3 "move_input_operand" "")
+                        (match_dup 0)))]
+  "reload_completed"
+  [(cond_exec (match_dup 1)
+     (set (match_dup 0) (match_dup 3)))]
+  "")
+
+(define_split
+  [(set (match_operand:SF 0 "move_output_operand" "")
+       (if_then_else:SF (match_operator:CC 1 "condexec_test_operator"
+                          [(match_operand:CC 2 "br_flag_operand" "")
+                           (const_int 0)])
+                        (match_dup 0)
+                        (match_operand:SF 3 "move_input_operand" "")))]
+  "reload_completed"
+  [(cond_exec (match_dup 4)
+     (set (match_dup 0) (match_dup 3)))]
+  "
+{
+  if (GET_CODE (operands[1]) == EQ)
+    operands[4] = gen_rtx_NE (CCmode, operands[2], const0_rtx);
+  else
+    operands[4] = gen_rtx_EQ (CCmode, operands[2], const0_rtx);
+}")
+
+(define_split
+  [(set (match_operand:SF 0 "move_output_operand" "")
+       (if_then_else:SF (match_operator:CC 1 "condexec_test_operator"
+                          [(match_operand:CC 2 "br_flag_operand" "")
+                           (const_int 0)])
+                        (match_operand:SF 3 "move_input_operand" "")
+                        (match_operand:SF 4 "move_input_operand" "")))]
+  "reload_completed"
+  [(cond_exec (match_dup 1)
+     (set (match_dup 0) (match_dup 3)))
+   (cond_exec (match_dup 5)
+     (set (match_dup 0) (match_dup 4)))]
+  "
+{
+  if (GET_CODE (operands[1]) == EQ)
+    operands[5] = gen_rtx_NE (CCmode, operands[2], const0_rtx);
+  else
+    operands[5] = gen_rtx_EQ (CCmode, operands[2], const0_rtx);
+}")
+
+\f
+;; ::::::::::::::::::::
+;; ::
+;; :: Conditional execution
+;; ::
+;; ::::::::::::::::::::
+
+(define_insn "*cond_exec_movqi"
+  [(cond_exec
+     (match_operator:CC 2 "condexec_test_operator"
+       [(match_operand:CC 3 "br_flag_operand" "b,b,b,b,b,b,b,b,b,b")
+       (const_int 0)])
+     (set (match_operand:QI 0 "move_output_operand" "=d,d,d,d,Q,m,Q,m,d,c")
+         (match_operand:QI 1 "move_input_operand" "dI,i,Q,m,d,d,O,O,c,d")))]
+  "register_operand (operands[0], QImode)
+   || reg_or_0_operand (operands[1], QImode)"
+  "@
+    or%F2 %0,%.,%1
+    or%F2 %0,%.,%1
+    ldb%F2 %0,%M1
+    ldb%F2 %0,%M1
+    stb%F2 %1,%M0
+    stb%F2 %1,%M0
+    stb%F2 %.,%M0
+    stb%F2 %.,%M0
+    mvfsys%F2 %0,%1
+    mvtsys%F2 %0,%1"
+  [(set_attr "length" "4,8,4,8,4,8,4,8,4,4")
+   (set_attr "type" "either,long,sload,lload,mu,long,mu,long,mu,mu")])
+
+(define_insn "*cond_exec_movhi"
+  [(cond_exec
+     (match_operator:CC 2 "condexec_test_operator"
+       [(match_operand:CC 3 "br_flag_operand" "b,b,b,b,b,b,b,b,b,b")
+       (const_int 0)])
+     (set (match_operand:HI 0 "move_output_operand" "=d,d,d,d,Q,m,Q,m,d,c")
+         (match_operand:HI 1 "move_input_operand" "dI,i,Q,m,d,d,O,O,c,d")))]
+  "register_operand (operands[0], HImode)
+   || reg_or_0_operand (operands[1], HImode)"
+  "@
+    or%F2 %0,%.,%1
+    or%F2 %0,%.,%1
+    ldh%F2 %0,%M1
+    ldh%F2 %0,%M1
+    sth%F2 %1,%M0
+    sth%F2 %1,%M0
+    sth%F2 %.,%M0
+    sth%F2 %.,%M0
+    mvfsys%F2 %0,%1
+    mvtsys%F2 %0,%1"
+  [(set_attr "length" "4,8,4,8,4,8,4,8,4,4")
+   (set_attr "type" "either,long,sload,lload,mu,long,mu,long,mu,mu")])
+
+(define_insn "*cond_exec_movsi"
+  [(cond_exec
+     (match_operator:CC 2 "condexec_test_operator"
+       [(match_operand:CC 3 "br_flag_operand" "b,b,b,b,b,b,b,b,b,b,b")
+       (const_int 0)])
+     (set (match_operand:SI 0 "move_output_operand" "=d,d,d,d,d,Q,m,Q,m,d,c")
+         (match_operand:SI 1 "move_input_operand" "dI,F,i,Q,m,d,d,O,O,c,d")))]
+  "register_operand (operands[0], SImode)
+   || reg_or_0_operand (operands[1], SImode)"
+  "@
+    or%F2 %0,%.,%1
+    or%F2 %0,%.,%L1
+    or%F2 %0,%.,%1
+    ldw%F2 %0,%M1
+    ldw%F2 %0,%M1
+    stw%F2 %1,%M0
+    stw%F2 %1,%M0
+    stw%F2 %.,%M0
+    stw%F2 %.,%M0
+    mvfsys%F2 %0,%1
+    mvtsys%F2 %0,%1"
+  [(set_attr "length" "4,8,8,4,8,4,8,4,8,4,4")
+   (set_attr "type" "either,long,long,sload,lload,mu,long,mu,long,mu,mu")])
+
+(define_insn "*cond_exec_movsf"
+  [(cond_exec
+     (match_operator:CC 2 "condexec_test_operator"
+       [(match_operand:CC 3 "br_flag_operand" "b,b,b,b,b,b,b,b,b")
+       (const_int 0)])
+     (set (match_operand:SF 0 "move_output_operand" "=d,d,d,d,d,Q,m,Q,m")
+         (match_operand:SF 1 "move_input_operand" "d,G,F,Q,m,d,d,G,G")))]
+  "register_operand (operands[0], SFmode)
+   || reg_or_0_operand (operands[1], SFmode)"
+  "@
+    or%F2 %0,%.,%1
+    or%F2 %0,%.,0
+    or%F2 %0,%.,%f1
+    ldw%F2 %0,%M1
+    ldw%F2 %0,%M1
+    stw%F2 %1,%M0
+    stw%F2 %1,%M0
+    stw%F2 %.,%M0
+    stw%F2 %.,%M0"
+  [(set_attr "length" "4,4,8,4,8,4,8,4,8")
+   (set_attr "type" "either,either,long,sload,lload,mu,long,mu,long")])
+
+(define_insn "*cond_exec_zero_extendqisi"
+  [(cond_exec
+     (match_operator 2 "condexec_test_operator"
+       [(match_operand:CC 3 "br_flag_operand" "b,b,b")
+        (const_int 0)])
+     (set (match_operand:SI 0 "gpr_operand" "=d,d,d")
+         (zero_extend:SI
+           (match_operand:QI 1 "gpr_or_memory_operand" "d,Q,m"))))]
+  ""
+  "@
+    and%F2 %0,%1,0xff
+    ldbu%F2 %0,%M1
+    ldbu%F2 %0,%M1"
+  [(set_attr "length" "8,4,8")
+   (set_attr "type" "long,sload,lload")])
+
+(define_insn "*cond_exec_sign_extendqisi"
+  [(cond_exec
+     (match_operator 2 "condexec_test_operator"
+       [(match_operand:CC 3 "br_flag_operand" "b,b,b")
+        (const_int 0)])
+     (set (match_operand:SI 0 "gpr_operand" "=d,d,d")
+         (sign_extend:SI
+           (match_operand:QI 1 "gpr_or_memory_operand" "d,Q,m"))))]
+  ""
+  "@
+    #
+    ldbu%F2 %0,%M1
+    ldbu%F2 %0,%M1"
+  [(set_attr "length" "8,4,8")
+   (set_attr "type" "multi,sload,lload")])
+
+(define_split
+  [(cond_exec
+     (match_operator 1 "condexec_test_operator"
+       [(match_operand:CC 2 "br_flag_operand" "")
+        (const_int 0)])
+     (set (match_operand:SI 0 "gpr_operand" "")
+         (sign_extend:SI (match_operand:QI 3 "gpr_operand" ""))))]
+   "reload_completed"
+   [(cond_exec (match_dup 1)
+      (set (match_dup 5) (ashift:SI (match_dup 6) (const_int 24))))
+    (cond_exec (match_dup 1)
+      (set (match_dup 5) (ashiftrt:SI (match_dup 5) (const_int 24))))]
+   "
+{
+  operands[5] = gen_lowpart (SImode, operands[0]);
+  operands[6] = gen_lowpart (SImode, operands[1]);
+}")
+
+(define_insn "*cond_exec_zero_extendhisi"
+  [(cond_exec
+     (match_operator 2 "condexec_test_operator"
+       [(match_operand:CC 3 "br_flag_operand" "b,b,b")
+        (const_int 0)])
+     (set (match_operand:SI 0 "gpr_operand" "=d,d,d")
+         (zero_extend:SI
+           (match_operand:HI 1 "gpr_or_memory_operand" "d,Q,m"))))]
+  ""
+  "@
+    and%F2 %0,%1,0xffff
+    ldbu%F2 %0,%M1
+    ldbu%F2 %0,%M1"
+  [(set_attr "length" "8,4,8")
+   (set_attr "type" "long,sload,lload")])
+
+(define_insn "*cond_exec_sign_extendhisi"
+  [(cond_exec
+     (match_operator 2 "condexec_test_operator"
+       [(match_operand:CC 3 "br_flag_operand" "b,b,b")
+        (const_int 0)])
+     (set (match_operand:SI 0 "gpr_operand" "=d,d,d")
+         (sign_extend:SI
+           (match_operand:HI 1 "gpr_or_memory_operand" "d,Q,m"))))]
+  ""
+  "@
+    #
+    ldbu%F2 %0,%M1
+    ldbu%F2 %0,%M1"
+  [(set_attr "length" "8,4,8")
+   (set_attr "type" "multi,sload,lload")])
+
+(define_split
+  [(cond_exec
+     (match_operator 2 "condexec_test_operator"
+       [(match_operand:CC 3 "br_flag_operand" "")
+        (const_int 0)])
+     (set (match_operand:SI 0 "gpr_operand" "")
+         (sign_extend:SI (match_operand:HI 1 "gpr_operand" ""))))]
+   "reload_completed"
+   [(cond_exec (match_dup 1)
+      (set (match_dup 5) (ashift:SI (match_dup 6) (const_int 16))))
+    (cond_exec (match_dup 1)
+      (set (match_dup 5) (ashiftrt:SI (match_dup 5) (const_int 16))))]
+   "
+{
+  operands[5] = gen_lowpart (SImode, operands[0]);
+  operands[6] = gen_lowpart (SImode, operands[3]);
+}")
+
+(define_insn "*cond_exec_si_unary"
+  [(cond_exec
+     (match_operator 3 "condexec_test_operator"
+       [(match_operand:CC 4 "br_flag_operand" "b")
+        (const_int 0)])
+     (set (match_operand:SI 0 "gpr_operand" "=d")
+         (match_operator:SI 1 "condexec_unary_operator"
+           [(match_operand:SI 2 "gpr_operand" "d")])))]
+  ""
+  "*
+{
+  switch (GET_CODE (operands[1]))
+    {
+    default:
+      fatal_insn (\"cond_exec_si_unary:\", insn);
+
+    case ABS: return \"abs%F3 %0,%2\";
+    case NOT: return \"not%F3 %0,%2\";
+    }
+}"
+  [(set_attr "length" "4")
+   (set_attr "type" "either")])
+
+(define_insn "*cond_exec_si_neg"
+  [(cond_exec
+     (match_operator 2 "condexec_test_operator"
+       [(match_operand:CC 3 "br_flag_operand" "b")
+        (const_int 0)])
+     (parallel [
+       (set (match_operand:SI 0 "gpr_operand" "=d")
+           (neg:SI (match_operand:SI 1 "gpr_operand" "d")))
+       (clobber (match_operand:CC 4 "flag_operand" ""))
+       (clobber (match_operand:CC 5 "flag_operand" ""))
+       (clobber (match_operand:CC 6 "flag_operand" ""))]))]
+  ""
+  "sub%F2 %0,%.,%1"
+  [(set_attr "length" "4")
+   (set_attr "type" "either")])
+
+(define_insn "*cond_exec_si_addsub"
+  [(cond_exec
+     (match_operator 4 "condexec_test_operator"
+       [(match_operand:CC 5 "br_flag_operand" "b,b")
+        (const_int 0)])
+     (parallel [
+       (set (match_operand:SI 0 "gpr_operand" "=d,d")
+           (match_operator:SI 1 "condexec_addsub_operator"
+             [(match_operand:SI 2 "gpr_operand" "d,d")
+              (match_operand:SI 3 "gpr_or_constant_operand" "dI,i")]))
+       (clobber (match_operand:CC 6 "flag_operand" ""))
+       (clobber (match_operand:CC 7 "flag_operand" ""))
+       (clobber (match_operand:CC 8 "flag_operand" ""))]))]
+  ""
+  "*
+{
+  switch (GET_CODE (operands[1]))
+    {
+    default:
+      fatal_insn (\"cond_exec_si_addsub_true:\", insn);
+
+    case PLUS:  return \"add%F4 %0,%2,%3\";
+    case MINUS: return \"sub%F4 %0,%2,%3\";
+    }
+}"
+  [(set_attr "length" "4,8")
+   (set_attr "type" "either,long")])
+
+(define_insn "*cond_exec_si_binary"
+  [(cond_exec
+     (match_operator 4 "condexec_test_operator"
+       [(match_operand:CC 5 "br_flag_operand" "b,b")
+        (const_int 0)])
+     (set (match_operand:SI 0 "gpr_operand" "=d,d")
+          (match_operator:SI 1 "condexec_binary_operator"
+           [(match_operand:SI 2 "gpr_operand" "d,d")
+            (match_operand:SI 3 "gpr_or_constant_operand" "dI,i")])))]
+  ""
+  "*
+{
+  switch (GET_CODE (operands[1]))
+    {
+    default:
+      fatal_insn (\"cond_exec_si_binary_true:\", insn);
+
+    case AND:      return \"and%F4 %0,%2,%3\";
+    case IOR:      return \"or%F4 %0,%2,%3\";
+    case XOR:      return \"xor%F4 %0,%2,%3\";
+    case ASHIFT:   return \"sra%F4 %0,%2,%n3\";
+    case ASHIFTRT: return \"sra%F4 %0,%2,%3\";
+    case LSHIFTRT: return \"srl%F4 %0,%2,%3\";
+    case ROTATE:   return \"rot%F4 %0,%2,%n3\";
+    case ROTATERT: return \"rot%F4 %0,%2,%3\";
+    }
+}"
+  [(set_attr "length" "4,8")
+   (set_attr "type" "either,long")])
+
+(define_insn "*cond_exec_si_shiftl"
+  [(cond_exec
+     (match_operator 4 "condexec_test_operator"
+       [(match_operand:CC 5 "br_flag_operand" "b")
+        (const_int 0)])
+     (set (match_operand:SI 0 "gpr_operand" "=d")
+         (match_operator:SI 1 "condexec_shiftl_operator"
+           [(match_operand:SI 2 "gpr_operand" "d")
+            (neg:SI (match_operand:SI 3 "gpr_operand" "d"))])))]
+  ""
+  "*
+{
+  switch (GET_CODE (operands[1]))
+    {
+    default:
+      fatal_insn (\"cond_exec_si_shiftl_true:\", insn);
+
+    case ASHIFT:   return \"sra%F4 %0,%2,%3\";
+    case ROTATE:   return \"rot%F4 %0,%2,%3\";
+    }
+}"
+  [(set_attr "length" "4")
+   (set_attr "type" "either")])
+
+(define_insn "*cond_exec_si_mul"
+  [(cond_exec
+     (match_operator 4 "condexec_test_operator"
+       [(match_operand:CC 5 "br_flag_operand" "b")
+        (const_int 0)])
+     (set (match_operand:SI 0 "gpr_operand" "=d")
+         (mult:SI (match_operand:SI 1 "gpr_operand" "%d")
+                  (match_operand:SI 2 "gpr_or_signed6_operand" "dI"))))]
+  ""
+  "mul%F4 %0,%1,%2"
+  [(set_attr "length" "4")
+   (set_attr "type" "iu")])
+
+(define_insn "*cond_exec_call_internal"
+  [(cond_exec
+     (match_operator 4 "condexec_test_operator"
+       [(match_operand:CC 5 "br_flag_operand" "b,b")
+        (const_int 0)])
+     (parallel [
+       (call (match_operand:QI 0 "call_operand" "R,S")
+            (match_operand 1 "" ""))
+       (use (match_operand 2 "" ""))
+       (clobber (match_operand 3 "" "=d,d"))]))]
+  ""
+  "@
+    jsr%F4 %0
+    bsr%F4 %0"
+  [(set_attr "length" "4,8")
+   (set_attr "type" "mu,long")])
+
+(define_insn "*cond_exec_call_value_internal"
+  [(cond_exec
+     (match_operator 5 "condexec_test_operator"
+       [(match_operand:CC 6 "br_flag_operand" "b,b")
+        (const_int 0)])
+     (parallel [
+       (set (match_operand 0 "gpr_operand" "=d,d")
+           (call (match_operand:QI 1 "call_operand" "R,S")
+                 (match_operand 2 "" "")))
+       (use (match_operand 3 "" ""))
+       (clobber (match_operand 4 "" "=d,d"))]))]
+  ""
+  "@
+    jsr%F5 %1
+    bsr%F5 %1"
+  [(set_attr "length" "4,8")
+   (set_attr "type" "mu,long")])
+\f
+;; ::::::::::::::::::::
+;; ::
+;; :: Miscellaneous instructions
+;; ::
+;; ::::::::::::::::::::
+
+;; No operation, needed in case the user uses -g but not -O.
+(define_insn "nop"
+  [(const_int 0)]
+  ""
+  "nop || nop"
+  [(set_attr "length" "8")
+   (set_attr "type" "long")])
+
+;; Pseudo instruction that prevents the scheduler from moving code above this
+;; point.
+(define_insn "blockage"
+  [(unspec_volatile [(const_int 0)] 0)]
+  ""
+  ""
+  [(set_attr "length" "0")
+   (set_attr "type" "unknown")])
diff --git a/gcc/config/d30v/libgcc1.asm b/gcc/config/d30v/libgcc1.asm
new file mode 100644 (file)
index 0000000..daf674a
--- /dev/null
@@ -0,0 +1,191 @@
+/* Assembly support functions for libgcc1.
+ *
+ *   Copyright (C) 1997 Free Software Foundation, Inc.
+ *   Contributed by Cygnus Support
+ * 
+ * This file 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) any
+ * later version.
+ * 
+ * In addition to the permissions in the GNU General Public License, the
+ * Free Software Foundation gives you unlimited permission to link the
+ * compiled version of this file with other programs, and to distribute
+ * those programs without any restriction coming from the use of this
+ * file.  (The General Public License restrictions do apply in other
+ * respects; for example, they cover modification of the file, and
+ * distribution when not linked into another program.)
+ * 
+ * This file 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 this program; see the file COPYING.  If not, write to
+ * the Free Software Foundation, 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ * 
+ *    As a special exception, if you link this library with files
+ *    compiled with GCC to produce an executable, this does not cause
+ *    the resulting executable to be covered by the GNU General Public License.
+ *    This exception does not however invalidate any other reasons why
+ *    the executable file might be covered by the GNU General Public License.
+ */
+
+\f
+#ifdef L_udivsi3
+
+/* For division, we use the following algorithm:
+ *
+ *     unsigned
+ *     __divsi3 (unsigned a, unsigned b)
+ *     {
+ *       unsigned al = a;
+ *       unsigned ah = 0;
+ *       unsigned tmpf;
+ *       int i;
+ *
+ *       for (i = 32; i > 0; i--)
+ *         {
+ *           ah = (ah << 1) | (al >> 31);
+ *           tmpf = (ah >= b) ? 1 : 0;
+ *           ah -= ((tmpf) ? b : 0);
+ *           al = (al << 1) | tmpf;
+ *         }
+ *
+ *       return al;    // for __udivsi3
+ *       return ah;    // for __umodsi3
+ *     }
+ */
+
+       .file   "_udivsi3"
+       .text
+       .globl  __umodsi3
+       .globl  __udivsi3
+       .type   __umodsi3,@function
+       .type   __udivsi3,@function
+       .stabs  "libgcc1.asm",100,0,0,__umodsi3
+       .stabs  "int:t(0,1)=r(0,1);-2147483648;2147483647;",128,0,0,0
+       .stabs  "__umodsi3:F(0,1)",36,0,1,__umodsi3
+       .stabs  "a:P(0,1)",64,0,1,2
+       .stabs  "b:P(0,1)",64,0,1,3
+
+__umodsi3:
+       bra.s .Lmerge           || orfg f1,f1,1         ; indicate this is __umodsi3
+.Lumod:
+       .size   __umodsi3,.Lumod-__umodsi3
+       .stabs  "",36,0,0,.Lumod-__umodsi3
+
+       .stabs  "__udivsi3:F(0,1)",36,0,1,__udivsi3
+       .stabs  "a:P(0,1)",64,0,1,2
+       .stabs  "b:P(0,1)",64,0,1,3
+__udivsi3:
+       andfg   f1,f1,0         || nop                  ; indicate this is __udivsi3
+
+.Lmerge:
+       ; r2 = al
+       ; r3 = b
+       ; r4 = ah
+       ; r5 = loop counter
+       ; f0 = tmpf
+       ; f1 = 1 if this is mod, 0 if this is div
+       or       r4,r0,0        || sub   r5,r0,-32      ; ah = 0, loop = 32
+
+.Lloop:
+       src      r4,r2,-1       || sub   r5,r5,1        ; ah = (ah << 1) | (al >> 31); decrement loop count
+       cmpuge   f0,r4,r3       || sra   r2,r2,-1       ; f0 = (ah >= b); al <<= 1
+       sub/tx   r4,r4,r3       || or/tx r2,r2,1        ; ah -= (tmpf) ? b : 0; al |= tmpf
+       bratnz.s r5,.Lloop      || nop                  ; loop back if not done
+       jmp      link           || or/xt r2,r0,r4       ; if mod, update register, then return to user
+.Ludiv:
+       .size    __udivsi3,.Ludiv-__udivsi3
+       .stabs  "",36,0,0,.Ludiv-__udivsi3
+
+#endif /* L_udivsi3 */
+
+\f
+#ifdef L_divsi3
+
+/* For division, we use the following algorithm:
+ *
+ *     unsigned
+ *     __divsi3 (unsigned a, unsigned b)
+ *     {
+ *       unsigned al = __builtin_abs (a);
+ *       unsigned b2 = __builtin_abs (b);
+ *       unsigned ah = 0;
+ *       unsigned tmpf;
+ *       int i;
+ *
+ *       for (i = 32; i > 0; i--)
+ *         {
+ *           ah = (ah << 1) | (al >> 31);
+ *           tmpf = (ah >= b2) ? 1 : 0;
+ *           ah -= ((tmpf) ? b2 : 0);
+ *           al = (al << 1) | tmpf;
+ *         }
+ *
+ *       if (a < 0)
+ *         ah = -ah, al = -al;
+ *
+ *       if (b < 0)
+ *         al = -al;
+ *
+ *       return al;    // for __divsi3
+ *       return ah;    // for __modsi3
+ *     }
+ */
+
+       .file   "_divsi3"
+       .text
+       .globl  __modsi3
+       .globl  __divsi3
+       .type   __modsi3,@function
+       .type   __divsi3,@function
+       .stabs  "libgcc1.asm",100,0,0,__modsi3
+       .stabs  "int:t(0,1)=r(0,1);-2147483648;2147483647;",128,0,0,0
+       .stabs  "__modsi3:F(0,1)",36,0,1,__modsi3
+       .stabs  "a:P(0,1)",64,0,1,2
+       .stabs  "b:P(0,1)",64,0,1,3
+
+__modsi3:
+       bra.s .Lmerge           || orfg f1,f1,1         ; indicate this is __modsi3
+.Lmod:
+       .size   __modsi3,.Lmod-__modsi3
+       .stabs  "",36,0,0,.Lmod-__modsi3
+
+       .stabs  "__divsi3:F(0,1)",36,0,1,__divsi3
+       .stabs  "a:P(0,1)",64,0,1,2
+       .stabs  "b:P(0,1)",64,0,1,3
+__divsi3:
+       andfg   f1,f1,0         || nop                  ; indicate this is __divsi3
+
+.Lmerge:
+       ; r2 = al
+       ; r3 = b2
+       ; r4 = ah
+       ; r5 = loop counter
+       ; r6 = a
+       ; r7 = b
+       ; f0 = tmpf
+       ; f1 = 1 if this is mod, 0 if this is div
+       or       r6,r0,r2       || or     r7,r0,r3      ; copy original inputs
+       abs      r2,r2          || abs    r3,r3         ; make both postive
+       or       r4,r0,0        || sub   r5,r0,-32      ; ah = 0, loop = 32
+
+.Lloop:
+       src      r4,r2,-1       || sub    r5,r5,1       ; ah = (ah << 1) | (al >> 31); decrement loop count
+       cmpuge   f0,r4,r3       || sra    r2,r2,-1      ; f0 = (ah >= b); al <<= 1
+       sub/tx   r4,r4,r3       || or/tx  r2,r2,1       ; ah -= (tmpf) ? b : 0; al |= tmpf
+       bratnz.s r5,.Lloop      || nop                  ; loop back if not done
+       cmplt    f0,r6,0        || nop                  ; f0 = (a < 0)
+
+       sub/tx   r2,r0,r2       || sub/tx r4,r0,r4      ; negate both al, ah if (a < 0)
+       cmplt    f0,r7,0        -> sub/tx r2,r0,r2      ; negate al if (b < 0)
+       jmp      link           || or/xt  r2,r0,r4      ; update result if mod; return to user
+.Ldiv:
+       .size    __divsi3,.Ldiv-__divsi3
+       .stabs  "",36,0,0,.Ldiv-__divsi3
+
+#endif /* L_divsi3 */
diff --git a/gcc/config/d30v/t-d30v b/gcc/config/d30v/t-d30v
new file mode 100644 (file)
index 0000000..52ce088
--- /dev/null
@@ -0,0 +1,35 @@
+# Build libgcc1 from assembler sources
+LIBGCC1 = libgcc1-asm.a
+CROSS_LIBGCC1 = libgcc1-asm.a
+LIB1ASMSRC = d30v/libgcc1.asm
+LIB1ASMFUNCS = _udivsi3 _divsi3
+
+# Turn on full debug for libgcc.a.
+LIBGCC2_DEBUG_CFLAGS = -g
+
+# We want fine grained libraries, so use the new code to build the
+# floating point emulation libraries.
+FPBIT = fp-bit.c
+DPBIT = dp-bit.c
+
+dp-bit.c: $(srcdir)/config/fp-bit.c config.status
+       cat $(srcdir)/config/fp-bit.c > dp-bit.c
+
+fp-bit.c: $(srcdir)/config/fp-bit.c config.status
+       echo '#define FLOAT' > fp-bit.c
+       echo '#define _fpadd_parts _fpadd_parts_sf' >> fp-bit.c
+       cat $(srcdir)/config/fp-bit.c >> fp-bit.c
+
+# For svr4 we build crtbegin.o and crtend.o which serve to add begin and
+# end labels to the .ctors and .dtors section when we link using gcc.
+
+EXTRA_PARTS=crtbegin.o crtend.o
+
+# We need to use -fPIC when we are using gcc to compile the routines in
+# crtstuff.c.  This is only really needed when we are going to use gcc/g++
+# to produce a shared library, but since we don't know ahead of time when
+# we will be doing that, we just always use -fPIC when compiling the
+# routines in crtstuff.c.
+
+# Right now, disable, since we don't support shared libraries on d30v yet.
+#CRTSTUFF_T_CFLAGS = -fPIC
diff --git a/gcc/config/d30v/xm-d30v.h b/gcc/config/d30v/xm-d30v.h
new file mode 100644 (file)
index 0000000..9d14d13
--- /dev/null
@@ -0,0 +1,196 @@
+/* Configuration for GNU C-compiler for Mitsubishi D30V.
+   Copyright (C) 1997, 2000 Free Software Foundation, Inc.
+   Contributed by Cygnus Solutions.
+
+   This file is part of GNU CC.
+
+   GNU CC 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)
+   any later version.
+
+   GNU CC 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.  */
+
+/* #defines that need visibility everywhere.  */
+#define        FALSE   0
+#define        TRUE    1
+
+/* Define this macro if the host system is System V.  */
+/* #define USG */
+
+/* Define this macro if the host system is VMS.  */
+/* #define VMS */
+
+/* A C expression for the status code to be returned when the compiler exits
+   after serious errors.  */
+#define FATAL_EXIT_CODE 33
+
+/* A C expression for the status code to be returned when the compiler exits
+   without serious errors.  */
+#define SUCCESS_EXIT_CODE 0
+
+/* Defined if the host machine stores words of multi-word values in big-endian
+   order.  (GNU CC does not depend on the host byte ordering within a word.)  */
+#define HOST_WORDS_BIG_ENDIAN
+
+/* Define this macro to be 1 if the host machine stores `DFmode', `XFmode' or
+   `TFmode' floating point numbers in memory with the word containing the sign
+   bit at the lowest address; otherwise, define it to be zero.
+
+   This macro need not be defined if the ordering is the same as for multi-word
+   integers.  */
+/* #define HOST_FLOAT_WORDS_BIG_ENDIAN */
+
+/* A numeric code distinguishing the floating point format for the host
+   machine.  See `TARGET_FLOAT_FORMAT' in *Note Storage Layout:: for the
+   alternatives and default.  */
+/* #define HOST_FLOAT_FORMAT */
+
+/* A C expression for the number of bits in `char' on the host machine.  */
+#define HOST_BITS_PER_CHAR 8
+
+/* A C expression for the number of bits in `short' on the host machine.  */
+#define HOST_BITS_PER_SHORT 16
+
+/* A C expression for the number of bits in `int' on the host machine.  */
+#define HOST_BITS_PER_INT 32
+
+/* A C expression for the number of bits in `long' on the host machine.  */
+#define HOST_BITS_PER_LONG 32
+
+/* Define this macro to indicate that the host compiler only supports `int' bit
+   fields, rather than other integral types, including `enum', as do most C
+   compilers.  */
+/* #define ONLY_INT_FIELDS */
+
+/* A C expression for the size of ordinary obstack chunks.  If you don't define
+   this, a usually-reasonable default is used.  */
+/* #define OBSTACK_CHUNK_SIZE */
+
+/* The function used to allocate obstack chunks.  If you don't define this,
+   `xmalloc' is used.  */
+/* #define OBSTACK_CHUNK_ALLOC */
+
+/* The function used to free obstack chunks.  If you don't define this, `free'
+   is used.  */
+/* #define OBSTACK_CHUNK_FREE */
+
+/* Define this macro to indicate that the compiler is running with the `alloca'
+   implemented in C.  This version of `alloca' can be found in the file
+   `alloca.c'; to use it, you must also alter the `Makefile' variable `ALLOCA'.
+   (This is done automatically for the systems on which we know it is needed.)
+
+   If you do define this macro, you should probably do it as follows:
+
+        #ifndef __GNUC__
+        #define USE_C_ALLOCA
+        #else
+        #define alloca __builtin_alloca
+        #endif
+
+   so that when the compiler is compiled with GNU CC it uses the more efficient
+   built-in `alloca' function.  */
+
+#ifndef __GNUC__
+#define USE_C_ALLOCA
+#else
+#define alloca __builtin_alloca
+#endif
+
+/* Define this macro to indicate that the host compiler does not properly
+   handle converting a function value to a pointer-to-function when it is used
+   in an expression.  */
+/* #define FUNCTION_CONVERSION_BUG */
+
+/* Define this if the library function `vprintf' is available on your system.  */
+/* #define HAVE_VPRINTF */
+
+/* Define this macro to enable support for multibyte characters in the input to
+   GNU CC.  This requires that the host system support the ANSI C library
+   functions for converting multibyte characters to wide characters.  */
+/* #define MULTIBYTE_CHARS */
+
+/* Define this if the library function `putenv' is available on your system.  */
+/* #define HAVE_PUTENV */
+
+/* Define this if your system is POSIX.1 compliant.  */
+/* #define POSIX */
+
+/* Define this if your system *does not* provide the variable `sys_siglist'.  */
+/* #define NO_SYS_SIGLIST */
+
+/* Define this if your system has the variable `sys_siglist', and there is
+   already a declaration of it in the system header files.  */
+/* #define DONT_DECLARE_SYS_SIGLIST */
+
+/* Define this to be 1 if you know that the host compiler supports prototypes,
+   even if it doesn't define __STDC__, or define it to be 0 if you do not want
+   any prototypes used in compiling GNU CC.  If `USE_PROTOTYPES' is not
+   defined, it will be determined automatically whether your compiler supports
+   prototypes by checking if `__STDC__' is defined.  */
+/* #define USE_PROTOTYPES */
+
+/* Define this if you wish suppression of prototypes generated from the machine
+   description file, but to use other prototypes within GNU CC.  If
+   `USE_PROTOTYPES' is defined to be 0, or the host compiler does not support
+   prototypes, this macro has no effect.  */
+/* #define NO_MD_PROTOTYPES */
+
+/* Define this if you wish to generate prototypes for the `gen_call' or
+   `gen_call_value' functions generated from the machine description file.  If
+   `USE_PROTOTYPES' is defined to be 0, or the host compiler does not support
+   prototypes, or `NO_MD_PROTOTYPES' is defined, this macro has no effect.  As
+   soon as all of the machine descriptions are modified to have the appropriate
+   number of arguments, this macro will be removed.
+
+   Some systems do provide this variable, but with a different name such as
+   `_sys_siglist'.  On these systems, you can define `sys_siglist' as a macro
+   which expands into the name actually provided.  */
+/* #define MD_CALL_PROTOTYPES */
+
+/* Define this macro to be a C character constant representing the character
+   used to separate components in paths.  The default value is.  the colon
+   character */
+/* #define PATH_SEPARATOR */
+
+/* If your system uses some character other than slash to separate directory
+   names within a file specification, define this macro to be a C character
+   constant specifying that character.  When GNU CC displays file names, the
+   character you specify will be used.  GNU CC will test for both slash and the
+   character you specify when parsing filenames.  */
+/* #define DIR_SEPARATOR */
+
+/* Define this macro to be a C string representing the suffix for object files
+   on your machine.  If you do not define this macro, GNU CC will use `.o' as
+   the suffix for object files.  */
+/* #define OBJECT_SUFFIX */
+
+/* Define this macro to be a C string representing the suffix for executable
+   files on your machine.  If you do not define this macro, GNU CC will use the
+   null string as the suffix for object files.  */
+/* #define EXECUTABLE_SUFFIX */
+
+/* If defined, `collect2' will scan the individual object files specified on
+   its command line and create an export list for the linker.  Define this
+   macro for systems like AIX, where the linker discards object files that are
+   not referenced from `main' and uses export lists.  */
+/* #define COLLECT_EXPORT_LIST */
+
+/* In addition, configuration files for system V define `bcopy', `bzero' and
+   `bcmp' as aliases.  Some files define `alloca' as a macro when compiled with
+   GNU CC, in order to take advantage of the benefit of GNU CC's built-in
+   `alloca'.  */
+
+/* target machine dependencies.
+   tm.h is a symbolic link to the actual target specific file.   */
+#include "tm.h"
+
+/* end of xm-generic.h */
index d310103..b7f282f 100755 (executable)
@@ -3671,6 +3671,9 @@ for machine in $build $host $target; do
                extra_parts="crtbegin.o crtend.o"
                install_headers_dir=install-headers-cpio
                ;;
                extra_parts="crtbegin.o crtend.o"
                install_headers_dir=install-headers-cpio
                ;;
+       d30v-*)
+               float_format=i64
+               ;;
        dsp16xx-*)
                ;;
        elxsi-elxsi-*)
        dsp16xx-*)
                ;;
        elxsi-elxsi-*)
@@ -6648,7 +6651,7 @@ fi
 
 
         echo $ac_n "checking for strerror in -lcposix""... $ac_c" 1>&6
 
 
         echo $ac_n "checking for strerror in -lcposix""... $ac_c" 1>&6
-echo "configure:6652: checking for strerror in -lcposix" >&5
+echo "configure:6655: checking for strerror in -lcposix" >&5
 ac_lib_var=`echo cposix'_'strerror | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 ac_lib_var=`echo cposix'_'strerror | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -6656,7 +6659,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-lcposix  $LIBS"
 cat > conftest.$ac_ext <<EOF
   ac_save_LIBS="$LIBS"
 LIBS="-lcposix  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 6660 "configure"
+#line 6663 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -6667,7 +6670,7 @@ int main() {
 strerror()
 ; return 0; }
 EOF
 strerror()
 ; return 0; }
 EOF
-if { (eval echo configure:6671: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:6674: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -6690,12 +6693,12 @@ fi
   
 
 echo $ac_n "checking for working const""... $ac_c" 1>&6
   
 
 echo $ac_n "checking for working const""... $ac_c" 1>&6
-echo "configure:6694: checking for working const" >&5
+echo "configure:6697: checking for working const" >&5
 if eval "test \"`echo '$''{'ac_cv_c_const'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
 if eval "test \"`echo '$''{'ac_cv_c_const'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 6699 "configure"
+#line 6702 "configure"
 #include "confdefs.h"
 
 int main() {
 #include "confdefs.h"
 
 int main() {
@@ -6744,7 +6747,7 @@ ccp = (char const *const *) p;
 
 ; return 0; }
 EOF
 
 ; return 0; }
 EOF
-if { (eval echo configure:6748: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:6751: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_c_const=yes
 else
   rm -rf conftest*
   ac_cv_c_const=yes
 else
@@ -6765,21 +6768,21 @@ EOF
 fi
 
 echo $ac_n "checking for inline""... $ac_c" 1>&6
 fi
 
 echo $ac_n "checking for inline""... $ac_c" 1>&6
-echo "configure:6769: checking for inline" >&5
+echo "configure:6772: checking for inline" >&5
 if eval "test \"`echo '$''{'ac_cv_c_inline'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   ac_cv_c_inline=no
 for ac_kw in inline __inline__ __inline; do
   cat > conftest.$ac_ext <<EOF
 if eval "test \"`echo '$''{'ac_cv_c_inline'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   ac_cv_c_inline=no
 for ac_kw in inline __inline__ __inline; do
   cat > conftest.$ac_ext <<EOF
-#line 6776 "configure"
+#line 6779 "configure"
 #include "confdefs.h"
 
 int main() {
 } $ac_kw foo() {
 ; return 0; }
 EOF
 #include "confdefs.h"
 
 int main() {
 } $ac_kw foo() {
 ; return 0; }
 EOF
-if { (eval echo configure:6783: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:6786: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_c_inline=$ac_kw; break
 else
   rm -rf conftest*
   ac_cv_c_inline=$ac_kw; break
 else
@@ -6805,12 +6808,12 @@ EOF
 esac
 
 echo $ac_n "checking for off_t""... $ac_c" 1>&6
 esac
 
 echo $ac_n "checking for off_t""... $ac_c" 1>&6
-echo "configure:6809: checking for off_t" >&5
+echo "configure:6812: checking for off_t" >&5
 if eval "test \"`echo '$''{'ac_cv_type_off_t'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
 if eval "test \"`echo '$''{'ac_cv_type_off_t'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 6814 "configure"
+#line 6817 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #if STDC_HEADERS
 #include "confdefs.h"
 #include <sys/types.h>
 #if STDC_HEADERS
@@ -6838,12 +6841,12 @@ EOF
 fi
 
 echo $ac_n "checking for size_t""... $ac_c" 1>&6
 fi
 
 echo $ac_n "checking for size_t""... $ac_c" 1>&6
-echo "configure:6842: checking for size_t" >&5
+echo "configure:6845: checking for size_t" >&5
 if eval "test \"`echo '$''{'ac_cv_type_size_t'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
 if eval "test \"`echo '$''{'ac_cv_type_size_t'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 6847 "configure"
+#line 6850 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #if STDC_HEADERS
 #include "confdefs.h"
 #include <sys/types.h>
 #if STDC_HEADERS
@@ -6873,19 +6876,19 @@ fi
 # The Ultrix 4.2 mips builtin alloca declared by alloca.h only works
 # for constant arguments.  Useless!
 echo $ac_n "checking for working alloca.h""... $ac_c" 1>&6
 # The Ultrix 4.2 mips builtin alloca declared by alloca.h only works
 # for constant arguments.  Useless!
 echo $ac_n "checking for working alloca.h""... $ac_c" 1>&6
-echo "configure:6877: checking for working alloca.h" >&5
+echo "configure:6880: checking for working alloca.h" >&5
 if eval "test \"`echo '$''{'ac_cv_header_alloca_h'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
 if eval "test \"`echo '$''{'ac_cv_header_alloca_h'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 6882 "configure"
+#line 6885 "configure"
 #include "confdefs.h"
 #include <alloca.h>
 int main() {
 char *p = alloca(2 * sizeof(int));
 ; return 0; }
 EOF
 #include "confdefs.h"
 #include <alloca.h>
 int main() {
 char *p = alloca(2 * sizeof(int));
 ; return 0; }
 EOF
-if { (eval echo configure:6889: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:6892: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   ac_cv_header_alloca_h=yes
 else
   rm -rf conftest*
   ac_cv_header_alloca_h=yes
 else
@@ -6906,12 +6909,12 @@ EOF
 fi
 
 echo $ac_n "checking for alloca""... $ac_c" 1>&6
 fi
 
 echo $ac_n "checking for alloca""... $ac_c" 1>&6
-echo "configure:6910: checking for alloca" >&5
+echo "configure:6913: checking for alloca" >&5
 if eval "test \"`echo '$''{'ac_cv_func_alloca_works'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
 if eval "test \"`echo '$''{'ac_cv_func_alloca_works'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 6915 "configure"
+#line 6918 "configure"
 #include "confdefs.h"
 
 #ifdef __GNUC__
 #include "confdefs.h"
 
 #ifdef __GNUC__
@@ -6939,7 +6942,7 @@ int main() {
 char *p = (char *) alloca(1);
 ; return 0; }
 EOF
 char *p = (char *) alloca(1);
 ; return 0; }
 EOF
-if { (eval echo configure:6943: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:6946: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   ac_cv_func_alloca_works=yes
 else
   rm -rf conftest*
   ac_cv_func_alloca_works=yes
 else
@@ -6971,12 +6974,12 @@ EOF
 
 
 echo $ac_n "checking whether alloca needs Cray hooks""... $ac_c" 1>&6
 
 
 echo $ac_n "checking whether alloca needs Cray hooks""... $ac_c" 1>&6
-echo "configure:6975: checking whether alloca needs Cray hooks" >&5
+echo "configure:6978: checking whether alloca needs Cray hooks" >&5
 if eval "test \"`echo '$''{'ac_cv_os_cray'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
 if eval "test \"`echo '$''{'ac_cv_os_cray'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 6980 "configure"
+#line 6983 "configure"
 #include "confdefs.h"
 #if defined(CRAY) && ! defined(CRAY2)
 webecray
 #include "confdefs.h"
 #if defined(CRAY) && ! defined(CRAY2)
 webecray
@@ -7001,12 +7004,12 @@ echo "$ac_t""$ac_cv_os_cray" 1>&6
 if test $ac_cv_os_cray = yes; then
 for ac_func in _getb67 GETB67 getb67; do
   echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
 if test $ac_cv_os_cray = yes; then
 for ac_func in _getb67 GETB67 getb67; do
   echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:7005: checking for $ac_func" >&5
+echo "configure:7008: checking for $ac_func" >&5
 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 7010 "configure"
+#line 7013 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -7029,7 +7032,7 @@ $ac_func();
 
 ; return 0; }
 EOF
 
 ; return 0; }
 EOF
-if { (eval echo configure:7033: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:7036: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
@@ -7056,7 +7059,7 @@ done
 fi
 
 echo $ac_n "checking stack direction for C alloca""... $ac_c" 1>&6
 fi
 
 echo $ac_n "checking stack direction for C alloca""... $ac_c" 1>&6
-echo "configure:7060: checking stack direction for C alloca" >&5
+echo "configure:7063: checking stack direction for C alloca" >&5
 if eval "test \"`echo '$''{'ac_cv_c_stack_direction'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
 if eval "test \"`echo '$''{'ac_cv_c_stack_direction'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -7064,7 +7067,7 @@ else
   ac_cv_c_stack_direction=0
 else
   cat > conftest.$ac_ext <<EOF
   ac_cv_c_stack_direction=0
 else
   cat > conftest.$ac_ext <<EOF
-#line 7068 "configure"
+#line 7071 "configure"
 #include "confdefs.h"
 find_stack_direction ()
 {
 #include "confdefs.h"
 find_stack_direction ()
 {
@@ -7083,7 +7086,7 @@ main ()
   exit (find_stack_direction() < 0);
 }
 EOF
   exit (find_stack_direction() < 0);
 }
 EOF
-if { (eval echo configure:7087: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:7090: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   ac_cv_c_stack_direction=1
 else
 then
   ac_cv_c_stack_direction=1
 else
@@ -7110,17 +7113,17 @@ unistd.h sys/param.h
 do
 ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
 do
 ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:7114: checking for $ac_hdr" >&5
+echo "configure:7117: checking for $ac_hdr" >&5
 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 7119 "configure"
+#line 7122 "configure"
 #include "confdefs.h"
 #include <$ac_hdr>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
 #include "confdefs.h"
 #include <$ac_hdr>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:7124: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:7127: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   rm -rf conftest*
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -7150,12 +7153,12 @@ done
 strdup __argz_count __argz_stringify __argz_next
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
 strdup __argz_count __argz_stringify __argz_next
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:7154: checking for $ac_func" >&5
+echo "configure:7157: checking for $ac_func" >&5
 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 7159 "configure"
+#line 7162 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -7178,7 +7181,7 @@ $ac_func();
 
 ; return 0; }
 EOF
 
 ; return 0; }
 EOF
-if { (eval echo configure:7182: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:7185: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
@@ -7207,12 +7210,12 @@ done
      for ac_func in stpcpy
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
      for ac_func in stpcpy
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:7211: checking for $ac_func" >&5
+echo "configure:7214: checking for $ac_func" >&5
 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 7216 "configure"
+#line 7219 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -7235,7 +7238,7 @@ $ac_func();
 
 ; return 0; }
 EOF
 
 ; return 0; }
 EOF
-if { (eval echo configure:7239: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:7242: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
@@ -7269,19 +7272,19 @@ EOF
 
    if test $ac_cv_header_locale_h = yes; then
     echo $ac_n "checking for LC_MESSAGES""... $ac_c" 1>&6
 
    if test $ac_cv_header_locale_h = yes; then
     echo $ac_n "checking for LC_MESSAGES""... $ac_c" 1>&6
-echo "configure:7273: checking for LC_MESSAGES" >&5
+echo "configure:7276: checking for LC_MESSAGES" >&5
 if eval "test \"`echo '$''{'am_cv_val_LC_MESSAGES'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
 if eval "test \"`echo '$''{'am_cv_val_LC_MESSAGES'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 7278 "configure"
+#line 7281 "configure"
 #include "confdefs.h"
 #include <locale.h>
 int main() {
 return LC_MESSAGES
 ; return 0; }
 EOF
 #include "confdefs.h"
 #include <locale.h>
 int main() {
 return LC_MESSAGES
 ; return 0; }
 EOF
-if { (eval echo configure:7285: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:7288: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   am_cv_val_LC_MESSAGES=yes
 else
   rm -rf conftest*
   am_cv_val_LC_MESSAGES=yes
 else
@@ -7302,7 +7305,7 @@ EOF
     fi
   fi
    echo $ac_n "checking whether NLS is requested""... $ac_c" 1>&6
     fi
   fi
    echo $ac_n "checking whether NLS is requested""... $ac_c" 1>&6
-echo "configure:7306: checking whether NLS is requested" >&5
+echo "configure:7309: checking whether NLS is requested" >&5
         # Check whether --enable-nls or --disable-nls was given.
 if test "${enable_nls+set}" = set; then
   enableval="$enable_nls"
         # Check whether --enable-nls or --disable-nls was given.
 if test "${enable_nls+set}" = set; then
   enableval="$enable_nls"
@@ -7322,7 +7325,7 @@ fi
 EOF
 
       echo $ac_n "checking whether included gettext is requested""... $ac_c" 1>&6
 EOF
 
       echo $ac_n "checking whether included gettext is requested""... $ac_c" 1>&6
-echo "configure:7326: checking whether included gettext is requested" >&5
+echo "configure:7329: checking whether included gettext is requested" >&5
       # Check whether --with-included-gettext or --without-included-gettext was given.
 if test "${with_included_gettext+set}" = set; then
   withval="$with_included_gettext"
       # Check whether --with-included-gettext or --without-included-gettext was given.
 if test "${with_included_gettext+set}" = set; then
   withval="$with_included_gettext"
@@ -7341,17 +7344,17 @@ fi
 
        ac_safe=`echo "libintl.h" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for libintl.h""... $ac_c" 1>&6
 
        ac_safe=`echo "libintl.h" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for libintl.h""... $ac_c" 1>&6
-echo "configure:7345: checking for libintl.h" >&5
+echo "configure:7348: checking for libintl.h" >&5
 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 7350 "configure"
+#line 7353 "configure"
 #include "confdefs.h"
 #include <libintl.h>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
 #include "confdefs.h"
 #include <libintl.h>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:7355: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:7358: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   rm -rf conftest*
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -7368,19 +7371,19 @@ fi
 if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
   echo "$ac_t""yes" 1>&6
   echo $ac_n "checking for gettext in libc""... $ac_c" 1>&6
 if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
   echo "$ac_t""yes" 1>&6
   echo $ac_n "checking for gettext in libc""... $ac_c" 1>&6
-echo "configure:7372: checking for gettext in libc" >&5
+echo "configure:7375: checking for gettext in libc" >&5
 if eval "test \"`echo '$''{'gt_cv_func_gettext_libc'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
 if eval "test \"`echo '$''{'gt_cv_func_gettext_libc'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 7377 "configure"
+#line 7380 "configure"
 #include "confdefs.h"
 #include <libintl.h>
 int main() {
 return (int) gettext ("")
 ; return 0; }
 EOF
 #include "confdefs.h"
 #include <libintl.h>
 int main() {
 return (int) gettext ("")
 ; return 0; }
 EOF
-if { (eval echo configure:7384: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:7387: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   gt_cv_func_gettext_libc=yes
 else
   rm -rf conftest*
   gt_cv_func_gettext_libc=yes
 else
@@ -7396,7 +7399,7 @@ echo "$ac_t""$gt_cv_func_gettext_libc" 1>&6
 
           if test "$gt_cv_func_gettext_libc" != "yes"; then
             echo $ac_n "checking for bindtextdomain in -lintl""... $ac_c" 1>&6
 
           if test "$gt_cv_func_gettext_libc" != "yes"; then
             echo $ac_n "checking for bindtextdomain in -lintl""... $ac_c" 1>&6
-echo "configure:7400: checking for bindtextdomain in -lintl" >&5
+echo "configure:7403: checking for bindtextdomain in -lintl" >&5
 ac_lib_var=`echo intl'_'bindtextdomain | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 ac_lib_var=`echo intl'_'bindtextdomain | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -7404,7 +7407,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-lintl  $LIBS"
 cat > conftest.$ac_ext <<EOF
   ac_save_LIBS="$LIBS"
 LIBS="-lintl  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 7408 "configure"
+#line 7411 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -7415,7 +7418,7 @@ int main() {
 bindtextdomain()
 ; return 0; }
 EOF
 bindtextdomain()
 ; return 0; }
 EOF
-if { (eval echo configure:7419: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:7422: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -7431,12 +7434,12 @@ fi
 if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
   echo "$ac_t""yes" 1>&6
   echo $ac_n "checking for gettext in libintl""... $ac_c" 1>&6
 if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
   echo "$ac_t""yes" 1>&6
   echo $ac_n "checking for gettext in libintl""... $ac_c" 1>&6
-echo "configure:7435: checking for gettext in libintl" >&5
+echo "configure:7438: checking for gettext in libintl" >&5
 if eval "test \"`echo '$''{'gt_cv_func_gettext_libintl'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   echo $ac_n "checking for gettext in -lintl""... $ac_c" 1>&6
 if eval "test \"`echo '$''{'gt_cv_func_gettext_libintl'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   echo $ac_n "checking for gettext in -lintl""... $ac_c" 1>&6
-echo "configure:7440: checking for gettext in -lintl" >&5
+echo "configure:7443: checking for gettext in -lintl" >&5
 ac_lib_var=`echo intl'_'gettext | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 ac_lib_var=`echo intl'_'gettext | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -7444,7 +7447,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-lintl  $LIBS"
 cat > conftest.$ac_ext <<EOF
   ac_save_LIBS="$LIBS"
 LIBS="-lintl  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 7448 "configure"
+#line 7451 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -7455,7 +7458,7 @@ int main() {
 gettext()
 ; return 0; }
 EOF
 gettext()
 ; return 0; }
 EOF
-if { (eval echo configure:7459: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:7462: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -7494,7 +7497,7 @@ EOF
              # Extract the first word of "msgfmt", so it can be a program name with args.
 set dummy msgfmt; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
              # Extract the first word of "msgfmt", so it can be a program name with args.
 set dummy msgfmt; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:7498: checking for $ac_word" >&5
+echo "configure:7501: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_path_MSGFMT'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
 if eval "test \"`echo '$''{'ac_cv_path_MSGFMT'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -7528,12 +7531,12 @@ fi
                for ac_func in dcgettext
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
                for ac_func in dcgettext
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:7532: checking for $ac_func" >&5
+echo "configure:7535: checking for $ac_func" >&5
 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 7537 "configure"
+#line 7540 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -7556,7 +7559,7 @@ $ac_func();
 
 ; return 0; }
 EOF
 
 ; return 0; }
 EOF
-if { (eval echo configure:7560: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:7563: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
@@ -7583,7 +7586,7 @@ done
                # Extract the first word of "gmsgfmt", so it can be a program name with args.
 set dummy gmsgfmt; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
                # Extract the first word of "gmsgfmt", so it can be a program name with args.
 set dummy gmsgfmt; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:7587: checking for $ac_word" >&5
+echo "configure:7590: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_path_GMSGFMT'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
 if eval "test \"`echo '$''{'ac_cv_path_GMSGFMT'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -7619,7 +7622,7 @@ fi
                # Extract the first word of "xgettext", so it can be a program name with args.
 set dummy xgettext; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
                # Extract the first word of "xgettext", so it can be a program name with args.
 set dummy xgettext; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:7623: checking for $ac_word" >&5
+echo "configure:7626: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_path_XGETTEXT'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
 if eval "test \"`echo '$''{'ac_cv_path_XGETTEXT'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -7651,7 +7654,7 @@ else
 fi
 
                cat > conftest.$ac_ext <<EOF
 fi
 
                cat > conftest.$ac_ext <<EOF
-#line 7655 "configure"
+#line 7658 "configure"
 #include "confdefs.h"
 
 int main() {
 #include "confdefs.h"
 
 int main() {
@@ -7659,7 +7662,7 @@ extern int _nl_msg_cat_cntr;
                               return _nl_msg_cat_cntr
 ; return 0; }
 EOF
                               return _nl_msg_cat_cntr
 ; return 0; }
 EOF
-if { (eval echo configure:7663: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:7666: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   CATOBJEXT=.gmo
                   DATADIRNAME=share
   rm -rf conftest*
   CATOBJEXT=.gmo
                   DATADIRNAME=share
@@ -7682,7 +7685,7 @@ fi
 
         if test "$CATOBJEXT" = "NONE"; then
          echo $ac_n "checking whether catgets can be used""... $ac_c" 1>&6
 
         if test "$CATOBJEXT" = "NONE"; then
          echo $ac_n "checking whether catgets can be used""... $ac_c" 1>&6
-echo "configure:7686: checking whether catgets can be used" >&5
+echo "configure:7689: checking whether catgets can be used" >&5
          # Check whether --with-catgets or --without-catgets was given.
 if test "${with_catgets+set}" = set; then
   withval="$with_catgets"
          # Check whether --with-catgets or --without-catgets was given.
 if test "${with_catgets+set}" = set; then
   withval="$with_catgets"
@@ -7695,7 +7698,7 @@ fi
 
          if test "$nls_cv_use_catgets" = "yes"; then
                    echo $ac_n "checking for main in -li""... $ac_c" 1>&6
 
          if test "$nls_cv_use_catgets" = "yes"; then
                    echo $ac_n "checking for main in -li""... $ac_c" 1>&6
-echo "configure:7699: checking for main in -li" >&5
+echo "configure:7702: checking for main in -li" >&5
 ac_lib_var=`echo i'_'main | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 ac_lib_var=`echo i'_'main | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -7703,14 +7706,14 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-li  $LIBS"
 cat > conftest.$ac_ext <<EOF
   ac_save_LIBS="$LIBS"
 LIBS="-li  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 7707 "configure"
+#line 7710 "configure"
 #include "confdefs.h"
 
 int main() {
 main()
 ; return 0; }
 EOF
 #include "confdefs.h"
 
 int main() {
 main()
 ; return 0; }
 EOF
-if { (eval echo configure:7714: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:7717: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -7738,12 +7741,12 @@ else
 fi
 
            echo $ac_n "checking for catgets""... $ac_c" 1>&6
 fi
 
            echo $ac_n "checking for catgets""... $ac_c" 1>&6
-echo "configure:7742: checking for catgets" >&5
+echo "configure:7745: checking for catgets" >&5
 if eval "test \"`echo '$''{'ac_cv_func_catgets'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
 if eval "test \"`echo '$''{'ac_cv_func_catgets'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 7747 "configure"
+#line 7750 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char catgets(); below.  */
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char catgets(); below.  */
@@ -7766,7 +7769,7 @@ catgets();
 
 ; return 0; }
 EOF
 
 ; return 0; }
 EOF
-if { (eval echo configure:7770: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:7773: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_func_catgets=yes"
 else
   rm -rf conftest*
   eval "ac_cv_func_catgets=yes"
 else
@@ -7788,7 +7791,7 @@ EOF
               # Extract the first word of "gencat", so it can be a program name with args.
 set dummy gencat; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
               # Extract the first word of "gencat", so it can be a program name with args.
 set dummy gencat; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:7792: checking for $ac_word" >&5
+echo "configure:7795: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_path_GENCAT'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
 if eval "test \"`echo '$''{'ac_cv_path_GENCAT'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -7824,7 +7827,7 @@ fi
                 # Extract the first word of "gmsgfmt", so it can be a program name with args.
 set dummy gmsgfmt; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
                 # Extract the first word of "gmsgfmt", so it can be a program name with args.
 set dummy gmsgfmt; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:7828: checking for $ac_word" >&5
+echo "configure:7831: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_path_GMSGFMT'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
 if eval "test \"`echo '$''{'ac_cv_path_GMSGFMT'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -7861,7 +7864,7 @@ fi
                   # Extract the first word of "msgfmt", so it can be a program name with args.
 set dummy msgfmt; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
                   # Extract the first word of "msgfmt", so it can be a program name with args.
 set dummy msgfmt; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:7865: checking for $ac_word" >&5
+echo "configure:7868: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_path_GMSGFMT'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
 if eval "test \"`echo '$''{'ac_cv_path_GMSGFMT'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -7896,7 +7899,7 @@ fi
                 # Extract the first word of "xgettext", so it can be a program name with args.
 set dummy xgettext; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
                 # Extract the first word of "xgettext", so it can be a program name with args.
 set dummy xgettext; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:7900: checking for $ac_word" >&5
+echo "configure:7903: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_path_XGETTEXT'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
 if eval "test \"`echo '$''{'ac_cv_path_XGETTEXT'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -7954,7 +7957,7 @@ fi
         # Extract the first word of "msgfmt", so it can be a program name with args.
 set dummy msgfmt; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
         # Extract the first word of "msgfmt", so it can be a program name with args.
 set dummy msgfmt; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:7958: checking for $ac_word" >&5
+echo "configure:7961: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_path_MSGFMT'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
 if eval "test \"`echo '$''{'ac_cv_path_MSGFMT'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -7988,7 +7991,7 @@ fi
         # Extract the first word of "gmsgfmt", so it can be a program name with args.
 set dummy gmsgfmt; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
         # Extract the first word of "gmsgfmt", so it can be a program name with args.
 set dummy gmsgfmt; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:7992: checking for $ac_word" >&5
+echo "configure:7995: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_path_GMSGFMT'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
 if eval "test \"`echo '$''{'ac_cv_path_GMSGFMT'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -8024,7 +8027,7 @@ fi
         # Extract the first word of "xgettext", so it can be a program name with args.
 set dummy xgettext; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
         # Extract the first word of "xgettext", so it can be a program name with args.
 set dummy xgettext; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:8028: checking for $ac_word" >&5
+echo "configure:8031: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_path_XGETTEXT'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
 if eval "test \"`echo '$''{'ac_cv_path_XGETTEXT'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -8117,7 +8120,7 @@ fi
        LINGUAS=
      else
        echo $ac_n "checking for catalogs to be installed""... $ac_c" 1>&6
        LINGUAS=
      else
        echo $ac_n "checking for catalogs to be installed""... $ac_c" 1>&6
-echo "configure:8121: checking for catalogs to be installed" >&5
+echo "configure:8124: checking for catalogs to be installed" >&5
        NEW_LINGUAS=
        for lang in ${LINGUAS=$ALL_LINGUAS}; do
          case "$ALL_LINGUAS" in
        NEW_LINGUAS=
        for lang in ${LINGUAS=$ALL_LINGUAS}; do
          case "$ALL_LINGUAS" in
@@ -8145,17 +8148,17 @@ echo "configure:8121: checking for catalogs to be installed" >&5
    if test "$CATOBJEXT" = ".cat"; then
      ac_safe=`echo "linux/version.h" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for linux/version.h""... $ac_c" 1>&6
    if test "$CATOBJEXT" = ".cat"; then
      ac_safe=`echo "linux/version.h" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for linux/version.h""... $ac_c" 1>&6
-echo "configure:8149: checking for linux/version.h" >&5
+echo "configure:8152: checking for linux/version.h" >&5
 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 8154 "configure"
+#line 8157 "configure"
 #include "confdefs.h"
 #include <linux/version.h>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
 #include "confdefs.h"
 #include <linux/version.h>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:8159: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:8162: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   rm -rf conftest*
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -8230,7 +8233,7 @@ fi
 
 
 echo $ac_n "checking whether windows registry support is requested""... $ac_c" 1>&6
 
 
 echo $ac_n "checking whether windows registry support is requested""... $ac_c" 1>&6
-echo "configure:8234: checking whether windows registry support is requested" >&5
+echo "configure:8237: checking whether windows registry support is requested" >&5
 if test x$enable_win32_registry != xno; then
   cat >> confdefs.h <<\EOF
 #define ENABLE_WIN32_REGISTRY 1
 if test x$enable_win32_registry != xno; then
   cat >> confdefs.h <<\EOF
 #define ENABLE_WIN32_REGISTRY 1
@@ -8259,7 +8262,7 @@ esac
 
 if test x$enable_win32_registry != xno; then
   echo $ac_n "checking registry key on windows hosts""... $ac_c" 1>&6
 
 if test x$enable_win32_registry != xno; then
   echo $ac_n "checking registry key on windows hosts""... $ac_c" 1>&6
-echo "configure:8263: checking registry key on windows hosts" >&5
+echo "configure:8266: checking registry key on windows hosts" >&5
   cat >> confdefs.h <<EOF
 #define WIN32_REGISTRY_KEY "$gcc_cv_win32_registry_key"
 EOF
   cat >> confdefs.h <<EOF
 #define WIN32_REGISTRY_KEY "$gcc_cv_win32_registry_key"
 EOF
@@ -8435,7 +8438,7 @@ fi
 
 # Figure out what assembler alignment features are present.
 echo $ac_n "checking assembler alignment features""... $ac_c" 1>&6
 
 # Figure out what assembler alignment features are present.
 echo $ac_n "checking assembler alignment features""... $ac_c" 1>&6
-echo "configure:8439: checking assembler alignment features" >&5
+echo "configure:8442: checking assembler alignment features" >&5
 gcc_cv_as=
 gcc_cv_as_alignment_features=
 gcc_cv_as_gas_srcdir=`echo $srcdir | sed -e 's,/gcc$,,'`/gas
 gcc_cv_as=
 gcc_cv_as_alignment_features=
 gcc_cv_as_gas_srcdir=`echo $srcdir | sed -e 's,/gcc$,,'`/gas
@@ -8556,7 +8559,7 @@ fi
 echo "$ac_t""$gcc_cv_as_alignment_features" 1>&6
 
 echo $ac_n "checking assembler subsection support""... $ac_c" 1>&6
 echo "$ac_t""$gcc_cv_as_alignment_features" 1>&6
 
 echo $ac_n "checking assembler subsection support""... $ac_c" 1>&6
-echo "configure:8560: checking assembler subsection support" >&5
+echo "configure:8563: checking assembler subsection support" >&5
 gcc_cv_as_subsections=
 if test x$gcc_cv_as != x; then
        # Check if we have .subsection
 gcc_cv_as_subsections=
 if test x$gcc_cv_as != x; then
        # Check if we have .subsection
@@ -8596,7 +8599,7 @@ fi
 echo "$ac_t""$gcc_cv_as_subsections" 1>&6
 
 echo $ac_n "checking assembler weak support""... $ac_c" 1>&6
 echo "$ac_t""$gcc_cv_as_subsections" 1>&6
 
 echo $ac_n "checking assembler weak support""... $ac_c" 1>&6
-echo "configure:8600: checking assembler weak support" >&5
+echo "configure:8603: checking assembler weak support" >&5
 gcc_cv_as_weak=
 if test x$gcc_cv_as != x; then
        # Check if we have .weak
 gcc_cv_as_weak=
 if test x$gcc_cv_as != x; then
        # Check if we have .weak
@@ -8613,7 +8616,7 @@ fi
 echo "$ac_t""$gcc_cv_as_weak" 1>&6
 
 echo $ac_n "checking assembler hidden support""... $ac_c" 1>&6
 echo "$ac_t""$gcc_cv_as_weak" 1>&6
 
 echo $ac_n "checking assembler hidden support""... $ac_c" 1>&6
-echo "configure:8617: checking assembler hidden support" >&5
+echo "configure:8620: checking assembler hidden support" >&5
 gcc_cv_as_hidden=
 if test x$gcc_cv_as != x; then
        # Check if we have .hidden
 gcc_cv_as_hidden=
 if test x$gcc_cv_as != x; then
        # Check if we have .hidden
@@ -8633,7 +8636,7 @@ echo "$ac_t""$gcc_cv_as_hidden" 1>&6
 case "$target" in 
   sparc*-*-*)
     echo $ac_n "checking assembler .register pseudo-op support""... $ac_c" 1>&6
 case "$target" in 
   sparc*-*-*)
     echo $ac_n "checking assembler .register pseudo-op support""... $ac_c" 1>&6
-echo "configure:8637: checking assembler .register pseudo-op support" >&5
+echo "configure:8640: checking assembler .register pseudo-op support" >&5
 if eval "test \"`echo '$''{'gcc_cv_as_register_pseudo_op'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
 if eval "test \"`echo '$''{'gcc_cv_as_register_pseudo_op'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -8663,7 +8666,7 @@ EOF
     case "$tm_file" in
     *64*)
        echo $ac_n "checking for 64 bit support in assembler ($gcc_cv_as)""... $ac_c" 1>&6
     case "$tm_file" in
     *64*)
        echo $ac_n "checking for 64 bit support in assembler ($gcc_cv_as)""... $ac_c" 1>&6
-echo "configure:8667: checking for 64 bit support in assembler ($gcc_cv_as)" >&5
+echo "configure:8670: checking for 64 bit support in assembler ($gcc_cv_as)" >&5
 if eval "test \"`echo '$''{'gcc_cv_as_flags64'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
 if eval "test \"`echo '$''{'gcc_cv_as_flags64'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -8708,7 +8711,7 @@ EOF
 
     if test "x$gcc_cv_as_flags64" != xno; then
        echo $ac_n "checking for assembler offsetable %lo() support""... $ac_c" 1>&6
 
     if test "x$gcc_cv_as_flags64" != xno; then
        echo $ac_n "checking for assembler offsetable %lo() support""... $ac_c" 1>&6
-echo "configure:8712: checking for assembler offsetable %lo() support" >&5
+echo "configure:8715: checking for assembler offsetable %lo() support" >&5
 if eval "test \"`echo '$''{'gcc_cv_as_offsetable_lo10'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
 if eval "test \"`echo '$''{'gcc_cv_as_offsetable_lo10'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -8747,7 +8750,7 @@ EOF
 
   i[34567]86-*-*)
     echo $ac_n "checking assembler instructions""... $ac_c" 1>&6
 
   i[34567]86-*-*)
     echo $ac_n "checking assembler instructions""... $ac_c" 1>&6
-echo "configure:8751: checking assembler instructions" >&5
+echo "configure:8754: checking assembler instructions" >&5
     gcc_cv_as_instructions=
     if test x$gcc_cv_as != x; then
        set "filds fists" "filds mem; fists mem"
     gcc_cv_as_instructions=
     if test x$gcc_cv_as != x; then
        set "filds fists" "filds mem; fists mem"
@@ -8873,7 +8876,7 @@ fi
 
 # Build a new-libstdc++ system (ie libstdc++-v3)
 echo $ac_n "checking for libstdc++ to install""... $ac_c" 1>&6
 
 # Build a new-libstdc++ system (ie libstdc++-v3)
 echo $ac_n "checking for libstdc++ to install""... $ac_c" 1>&6
-echo "configure:8877: checking for libstdc++ to install" >&5
+echo "configure:8880: checking for libstdc++ to install" >&5
 # Check whether --enable-libstdcxx-v3 or --disable-libstdcxx-v3 was given.
 if test "${enable_libstdcxx_v3+set}" = set; then
   enableval="$enable_libstdcxx_v3"
 # Check whether --enable-libstdcxx-v3 or --disable-libstdcxx-v3 was given.
 if test "${enable_libstdcxx_v3+set}" = set; then
   enableval="$enable_libstdcxx_v3"
index f3863b9..07b16ba 100644 (file)
@@ -921,6 +921,9 @@ changequote([,])dnl
                extra_parts="crtbegin.o crtend.o"
                install_headers_dir=install-headers-cpio
                ;;
                extra_parts="crtbegin.o crtend.o"
                install_headers_dir=install-headers-cpio
                ;;
+       d30v-*)
+               float_format=i64
+               ;;
        dsp16xx-*)
                ;;
        elxsi-elxsi-*)
        dsp16xx-*)
                ;;
        elxsi-elxsi-*)