]> oss.titaniummirror.com Git - msp430-gcc.git/blobdiff - gcc/config/d30v/d30v.c
Imported gcc-4.4.3
[msp430-gcc.git] / gcc / config / d30v / d30v.c
diff --git a/gcc/config/d30v/d30v.c b/gcc/config/d30v/d30v.c
deleted file mode 100644 (file)
index 4bfd4bb..0000000
+++ /dev/null
@@ -1,3609 +0,0 @@
-/* Definitions of target machine for Mitsubishi D30V.
-   Copyright (C) 1997, 1998, 1999, 2000, 2001 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 "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 "integrate.h"
-#include "ggc.h"
-#include "target.h"
-#include "target-def.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));
-static void d30v_init_machine_status PARAMS ((struct function *));
-static void d30v_mark_machine_status PARAMS ((struct function *));
-static void d30v_free_machine_status PARAMS ((struct function *));
-static void d30v_output_function_prologue PARAMS ((FILE *, HOST_WIDE_INT));
-static void d30v_output_function_epilogue PARAMS ((FILE *, HOST_WIDE_INT));
-static int d30v_adjust_cost PARAMS ((rtx, rtx, rtx, int));
-static int d30v_issue_rate 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;
-
-/* Cached value of d30v_stack_info */
-static d30v_stack_t *d30v_stack_cache = (d30v_stack_t *)0;
-
-/* 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
-/* Initialize the GCC target structure.  */
-#undef TARGET_ASM_ALIGNED_HI_OP
-#define TARGET_ASM_ALIGNED_HI_OP "\t.hword\t"
-#undef TARGET_ASM_ALIGNED_SI_OP
-#define TARGET_ASM_ALIGNED_SI_OP "\t.word\t"
-
-#undef TARGET_ASM_FUNCTION_PROLOGUE
-#define TARGET_ASM_FUNCTION_PROLOGUE d30v_output_function_prologue
-#undef TARGET_ASM_FUNCTION_EPILOGUE
-#define TARGET_ASM_FUNCTION_EPILOGUE d30v_output_function_epilogue
-#undef TARGET_SCHED_ADJUST_COST
-#define TARGET_SCHED_ADJUST_COST d30v_adjust_cost
-#undef TARGET_SCHED_ISSUE_RATE
-#define TARGET_SCHED_ISSUE_RATE d30v_issue_rate
-
-struct gcc_target targetm = TARGET_INITIALIZER;
-\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 const char *const 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 (current_function_profile)
-    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)
-             : (int) 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)
-             : (int) 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)
-              : (int) 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)
-              : (int) 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,
-                              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
-/* Generate the assembly code for function entry.  FILE is a stdio
-   stream to output the code to.  SIZE is an int: how many units of
-   temporary storage to allocate.
-
-   Refer to the array `regs_ever_live' to determine which registers to
-   save; `regs_ever_live[I]' is nonzero if register number I is ever
-   used in the function.  This function is responsible for knowing
-   which registers should not be saved even if used.  */
-
-static void
-d30v_output_function_prologue (stream, size)
-     FILE *stream ATTRIBUTE_UNUSED;
-     HOST_WIDE_INT size ATTRIBUTE_UNUSED;
-{
-  /* For the d30v, move all of the prologue processing into separate
-     insns.  */
-}
-
-\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 output_function_prologue (), 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
-/* This function generates the assembly code for function exit.
-   Args are as for output_function_prologue ().
-
-   The function epilogue should not depend on the current stack
-   pointer!  It should use the frame pointer only.  This is mandatory
-   because of alloca; we also take advantage of it to omit stack
-   adjustments before returning.  */
-
-static void
-d30v_output_function_epilogue (stream, size)
-     FILE *stream ATTRIBUTE_UNUSED;
-     HOST_WIDE_INT size ATTRIBUTE_UNUSED;
-{
-  /* 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.  */
-  d30v_stack_cache = (d30v_stack_t *)0;        /* reset stack cache */
-}
-
-\f
-
-/* Called after register allocation to add any instructions needed for
-   the epilogue.  Using an epilogue insn is favored compared to putting
-   all of the instructions in output_function_prologue(), 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 (cfun->machine->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 (cfun->machine->eh_epilogue_sp_ofs)
-       emit_insn (gen_addsi3 (cfun->machine->eh_epilogue_sp_ofs,
-                              cfun->machine->eh_epilogue_sp_ofs,
-                              GEN_INT (extra_stack)));
-      else
-        emit_insn (gen_addsi3 (sp, sp, GEN_INT (extra_stack)));
-    }
-  if (cfun->machine->eh_epilogue_sp_ofs)
-    emit_insn (gen_addsi3 (sp, sp, cfun->machine->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:
-      if (GET_CODE (SUBREG_REG (value)) != REG)
-       abort ();
-      offset = subreg_regno_offset (REGNO (SUBREG_REG (value)),
-                                   GET_MODE (SUBREG_REG (value)),
-                                   SUBREG_BYTE (value),
-                                   GET_MODE (value));
-      value = SUBREG_REG (value);
-
-      /* 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
-    {
-      const char *suffix = "";
-      int offset0  = 0;
-
-      if (GET_CODE (x0) == SUBREG)
-       {
-         offset0 = subreg_regno_offset (REGNO (SUBREG_REG (x0)),
-                                        GET_MODE (SUBREG_REG (x0)),
-                                        SUBREG_BYTE (x0),
-                                        GET_MODE (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_regno_offset (REGNO (SUBREG_REG (x1)),
-                                        GET_MODE (SUBREG_REG (x1)),
-                                        SUBREG_BYTE (x1),
-                                        GET_MODE (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 ':':   /* Output the condition for the current insn.  */
-      x = current_insn_predicate;
-      if (x == NULL_RTX)
-       break;
-      letter = 'T';
-      /* FALLTHRU */
-
-    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.  */
-
-const 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.  */
-
-static 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 + 2;
-       }
-    }
-
-  return cost;
-}
-
-/* Function which returns the number of insns that can be
-   scheduled in the same machine cycle.  This must be constant
-   over an entire compilation.  The default is 1.  */
-static int
-d30v_issue_rate ()
-{
-  return 2;
-}
-
-\f
-/* Routine to allocate, mark and free a per-function,
-   machine specific structure.  */
-
-static void
-d30v_init_machine_status (p)
-     struct function *p;
-{
-  p->machine =
-    (machine_function *) xcalloc (1, sizeof (machine_function));
-}
-
-static void
-d30v_mark_machine_status (p)
-     struct function * p;
-{
-  if (p->machine == NULL)
-    return;
-  
-  ggc_mark_rtx (p->machine->eh_epilogue_sp_ofs);
-}
-
-static void
-d30v_free_machine_status (p)
-     struct function *p;
-{
-  struct machine_function *machine = p->machine;
-
-  if (machine == NULL)
-    return;
-
-  free (machine);
-  p->machine = NULL;
-}
-
-/* Do anything needed before RTL is emitted for each function.  */
-
-void
-d30v_init_expanders ()
-{
-  /* Arrange to save and restore machine status around nested functions.  */
-  init_machine_status = d30v_init_machine_status;
-  mark_machine_status = d30v_mark_machine_status;
-  free_machine_status = d30v_free_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 ()
-{
-  return get_hard_reg_initial_val (Pmode, GPR_LINK);
-}
-
-/* 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);
-}