]> oss.titaniummirror.com Git - msp430-gcc.git/blobdiff - gcc/config/c4x/c4x.c
Imported gcc-4.4.3
[msp430-gcc.git] / gcc / config / c4x / c4x.c
diff --git a/gcc/config/c4x/c4x.c b/gcc/config/c4x/c4x.c
deleted file mode 100644 (file)
index ee878dd..0000000
+++ /dev/null
@@ -1,5060 +0,0 @@
-/* Subroutines for assembler code output on the TMS320C[34]x
-   Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
-   Free Software Foundation, Inc.
-
-   Contributed by Michael Hayes (m.hayes@elec.canterbury.ac.nz)
-              and Herman Ten Brugge (Haj.Ten.Brugge@net.HCC.nl).
-
-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.  */
-
-/* Some output-actions in c4x.md need these.  */
-#include "config.h"
-#include "system.h"
-#include "rtl.h"
-#include "tree.h"
-#include "regs.h"
-#include "hard-reg-set.h"
-#include "basic-block.h"
-#include "real.h"
-#include "insn-config.h"
-#include "insn-attr.h"
-#include "conditions.h"
-#include "output.h"
-#include "function.h"
-#include "expr.h"
-#include "optabs.h"
-#include "libfuncs.h"
-#include "flags.h"
-#include "loop.h"
-#include "recog.h"
-#include "c-tree.h"
-#include "ggc.h"
-#include "cpplib.h"
-#include "toplev.h"
-#include "c4x-protos.h"
-#include "target.h"
-#include "target-def.h"
-
-rtx smulhi3_libfunc;
-rtx umulhi3_libfunc;
-rtx fix_truncqfhi2_libfunc;
-rtx fixuns_truncqfhi2_libfunc;
-rtx fix_trunchfhi2_libfunc;
-rtx fixuns_trunchfhi2_libfunc;
-rtx floathiqf2_libfunc;
-rtx floatunshiqf2_libfunc;
-rtx floathihf2_libfunc;
-rtx floatunshihf2_libfunc;
-
-static int c4x_leaf_function;
-
-static const char *const float_reg_names[] = FLOAT_REGISTER_NAMES;
-
-/* Array of the smallest class containing reg number REGNO, indexed by
-   REGNO.  Used by REGNO_REG_CLASS in c4x.h.  We assume that all these
-   registers are available and set the class to NO_REGS for registers 
-   that the target switches say are unavailable.  */
-
-enum reg_class c4x_regclass_map[FIRST_PSEUDO_REGISTER] =
-{
-                                /* Reg          Modes           Saved.  */
-  R0R1_REGS,                   /* R0           QI, QF, HF      No.  */
-  R0R1_REGS,                   /* R1           QI, QF, HF      No.  */
-  R2R3_REGS,                   /* R2           QI, QF, HF      No.  */
-  R2R3_REGS,                   /* R3           QI, QF, HF      No.  */
-  EXT_LOW_REGS,                        /* R4           QI, QF, HF      QI.  */
-  EXT_LOW_REGS,                        /* R5           QI, QF, HF      QI.  */
-  EXT_LOW_REGS,                        /* R6           QI, QF, HF      QF.  */
-  EXT_LOW_REGS,                        /* R7           QI, QF, HF      QF.  */
-  ADDR_REGS,                   /* AR0          QI              No.  */
-  ADDR_REGS,                   /* AR1          QI              No.  */
-  ADDR_REGS,                   /* AR2          QI              No.  */
-  ADDR_REGS,                   /* AR3          QI              QI.  */
-  ADDR_REGS,                   /* AR4          QI              QI.  */
-  ADDR_REGS,                   /* AR5          QI              QI.  */
-  ADDR_REGS,                   /* AR6          QI              QI.  */
-  ADDR_REGS,                   /* AR7          QI              QI.  */
-  DP_REG,                      /* DP           QI              No.  */
-  INDEX_REGS,                  /* IR0          QI              No.  */
-  INDEX_REGS,                  /* IR1          QI              No.  */
-  BK_REG,                      /* BK           QI              QI.  */
-  SP_REG,                      /* SP           QI              No.  */
-  ST_REG,                      /* ST           CC              No.  */
-  NO_REGS,                     /* DIE/IE                       No.  */
-  NO_REGS,                     /* IIE/IF                       No.  */
-  NO_REGS,                     /* IIF/IOF                      No.  */
-  INT_REGS,                    /* RS           QI              No.  */
-  INT_REGS,                    /* RE           QI              No.  */
-  RC_REG,                      /* RC           QI              No.  */
-  EXT_REGS,                    /* R8           QI, QF, HF      QI.  */
-  EXT_REGS,                    /* R9           QI, QF, HF      No.  */
-  EXT_REGS,                    /* R10          QI, QF, HF      No.  */
-  EXT_REGS,                    /* R11          QI, QF, HF      No.  */
-};
-
-enum machine_mode c4x_caller_save_map[FIRST_PSEUDO_REGISTER] =
-{
-                                /* Reg          Modes           Saved.  */
-  HFmode,                      /* R0           QI, QF, HF      No.  */
-  HFmode,                      /* R1           QI, QF, HF      No.  */
-  HFmode,                      /* R2           QI, QF, HF      No.  */
-  HFmode,                      /* R3           QI, QF, HF      No.  */
-  QFmode,                      /* R4           QI, QF, HF      QI.  */
-  QFmode,                      /* R5           QI, QF, HF      QI.  */
-  QImode,                      /* R6           QI, QF, HF      QF.  */
-  QImode,                      /* R7           QI, QF, HF      QF.  */
-  QImode,                      /* AR0          QI              No.  */
-  QImode,                      /* AR1          QI              No.  */
-  QImode,                      /* AR2          QI              No.  */
-  QImode,                      /* AR3          QI              QI.  */
-  QImode,                      /* AR4          QI              QI.  */
-  QImode,                      /* AR5          QI              QI.  */
-  QImode,                      /* AR6          QI              QI.  */
-  QImode,                      /* AR7          QI              QI.  */
-  VOIDmode,                    /* DP           QI              No.  */
-  QImode,                      /* IR0          QI              No.  */
-  QImode,                      /* IR1          QI              No.  */
-  QImode,                      /* BK           QI              QI.  */
-  VOIDmode,                    /* SP           QI              No.  */
-  VOIDmode,                    /* ST           CC              No.  */
-  VOIDmode,                    /* DIE/IE                       No.  */
-  VOIDmode,                    /* IIE/IF                       No.  */
-  VOIDmode,                    /* IIF/IOF                      No.  */
-  QImode,                      /* RS           QI              No.  */
-  QImode,                      /* RE           QI              No.  */
-  VOIDmode,                    /* RC           QI              No.  */
-  QFmode,                      /* R8           QI, QF, HF      QI.  */
-  HFmode,                      /* R9           QI, QF, HF      No.  */
-  HFmode,                      /* R10          QI, QF, HF      No.  */
-  HFmode,                      /* R11          QI, QF, HF      No.  */
-};
-
-
-/* Test and compare insns in c4x.md store the information needed to
-   generate branch and scc insns here.  */
-
-struct rtx_def *c4x_compare_op0 = NULL_RTX;
-struct rtx_def *c4x_compare_op1 = NULL_RTX;
-
-const char *c4x_rpts_cycles_string;
-int c4x_rpts_cycles = 0;       /* Max. cycles for RPTS.  */
-const char *c4x_cpu_version_string;
-int c4x_cpu_version = 40;      /* CPU version C30/31/32/33/40/44.  */
-
-/* Pragma definitions.  */
-
-tree code_tree = NULL_TREE;
-tree data_tree = NULL_TREE;
-tree pure_tree = NULL_TREE;
-tree noreturn_tree = NULL_TREE;
-tree interrupt_tree = NULL_TREE;
-
-/* Forward declarations */
-static void c4x_add_gc_roots PARAMS ((void));
-static int c4x_isr_reg_used_p PARAMS ((unsigned int));
-static int c4x_leaf_function_p PARAMS ((void));
-static int c4x_assembler_function_p PARAMS ((void));
-static int c4x_immed_float_p PARAMS ((rtx));
-static int c4x_a_register PARAMS ((rtx));
-static int c4x_x_register PARAMS ((rtx));
-static int c4x_immed_int_constant PARAMS ((rtx));
-static int c4x_immed_float_constant PARAMS ((rtx));
-static int c4x_K_constant PARAMS ((rtx));
-static int c4x_N_constant PARAMS ((rtx));
-static int c4x_O_constant PARAMS ((rtx));
-static int c4x_R_indirect PARAMS ((rtx));
-static int c4x_S_indirect PARAMS ((rtx));
-static void c4x_S_address_parse PARAMS ((rtx , int *, int *, int *, int *));
-static int c4x_valid_operands PARAMS ((enum rtx_code, rtx *,
-                                      enum machine_mode, int));
-static int c4x_arn_reg_operand PARAMS ((rtx, enum machine_mode, unsigned int));
-static int c4x_arn_mem_operand PARAMS ((rtx, enum machine_mode, unsigned int));
-static void c4x_check_attribute PARAMS ((const char *, tree, tree, tree *));
-static int c4x_r11_set_p PARAMS ((rtx));
-static int c4x_rptb_valid_p PARAMS ((rtx, rtx));
-static int c4x_label_ref_used_p PARAMS ((rtx, rtx));
-static tree c4x_handle_fntype_attribute PARAMS ((tree *, tree, tree, int, bool *));
-const struct attribute_spec c4x_attribute_table[];
-static void c4x_insert_attributes PARAMS ((tree, tree *));
-static void c4x_asm_named_section PARAMS ((const char *, unsigned int));
-static int c4x_adjust_cost PARAMS ((rtx, rtx, rtx, int));
-\f
-/* Initialize the GCC target structure.  */
-#undef TARGET_ASM_BYTE_OP
-#define TARGET_ASM_BYTE_OP "\t.word\t"
-#undef TARGET_ASM_ALIGNED_HI_OP
-#define TARGET_ASM_ALIGNED_HI_OP NULL
-#undef TARGET_ASM_ALIGNED_SI_OP
-#define TARGET_ASM_ALIGNED_SI_OP NULL
-
-#undef TARGET_ATTRIBUTE_TABLE
-#define TARGET_ATTRIBUTE_TABLE c4x_attribute_table
-
-#undef TARGET_INSERT_ATTRIBUTES
-#define TARGET_INSERT_ATTRIBUTES c4x_insert_attributes
-
-#undef TARGET_INIT_BUILTINS
-#define TARGET_INIT_BUILTINS c4x_init_builtins
-
-#undef TARGET_EXPAND_BUILTIN
-#define TARGET_EXPAND_BUILTIN c4x_expand_builtin
-
-#undef TARGET_SCHED_ADJUST_COST
-#define TARGET_SCHED_ADJUST_COST c4x_adjust_cost
-
-struct gcc_target targetm = TARGET_INITIALIZER;
-\f
-/* Called to register all of our global variables with the garbage
-   collector.  */
-
-static void
-c4x_add_gc_roots ()
-{
-  ggc_add_rtx_root (&c4x_compare_op0, 1);
-  ggc_add_rtx_root (&c4x_compare_op1, 1);
-  ggc_add_tree_root (&code_tree, 1);
-  ggc_add_tree_root (&data_tree, 1);
-  ggc_add_tree_root (&pure_tree, 1);
-  ggc_add_tree_root (&noreturn_tree, 1);
-  ggc_add_tree_root (&interrupt_tree, 1);
-  ggc_add_rtx_root (&smulhi3_libfunc, 1);
-  ggc_add_rtx_root (&umulhi3_libfunc, 1);
-  ggc_add_rtx_root (&fix_truncqfhi2_libfunc, 1);
-  ggc_add_rtx_root (&fixuns_truncqfhi2_libfunc, 1);
-  ggc_add_rtx_root (&fix_trunchfhi2_libfunc, 1);
-  ggc_add_rtx_root (&fixuns_trunchfhi2_libfunc, 1);
-  ggc_add_rtx_root (&floathiqf2_libfunc, 1);
-  ggc_add_rtx_root (&floatunshiqf2_libfunc, 1);
-  ggc_add_rtx_root (&floathihf2_libfunc, 1);
-  ggc_add_rtx_root (&floatunshihf2_libfunc, 1);
-}
-
-
-/* Override command line options.
-   Called once after all options have been parsed.
-   Mostly we process the processor
-   type and sometimes adjust other TARGET_ options.  */
-
-void
-c4x_override_options ()
-{
-  if (c4x_rpts_cycles_string)
-    c4x_rpts_cycles = atoi (c4x_rpts_cycles_string);
-  else
-    c4x_rpts_cycles = 0;
-
-  if (TARGET_C30)
-    c4x_cpu_version = 30;
-  else if (TARGET_C31)
-    c4x_cpu_version = 31;
-  else if (TARGET_C32)
-    c4x_cpu_version = 32;
-  else if (TARGET_C33)
-    c4x_cpu_version = 33;
-  else if (TARGET_C40)
-    c4x_cpu_version = 40;
-  else if (TARGET_C44)
-    c4x_cpu_version = 44;
-  else
-    c4x_cpu_version = 40;             
-
-  /* -mcpu=xx overrides -m40 etc.  */
-  if (c4x_cpu_version_string)
-    {
-      const char *p = c4x_cpu_version_string;
-      
-      /* Also allow -mcpu=c30 etc.  */
-      if (*p == 'c' || *p == 'C')
-       p++;
-      c4x_cpu_version = atoi (p);
-    }
-
-  target_flags &= ~(C30_FLAG | C31_FLAG | C32_FLAG | C33_FLAG |
-                   C40_FLAG | C44_FLAG);
-
-  switch (c4x_cpu_version)
-    {
-    case 30: target_flags |= C30_FLAG; break;
-    case 31: target_flags |= C31_FLAG; break;
-    case 32: target_flags |= C32_FLAG; break;
-    case 33: target_flags |= C33_FLAG; break;
-    case 40: target_flags |= C40_FLAG; break;
-    case 44: target_flags |= C44_FLAG; break;
-    default:
-      warning ("unknown CPU version %d, using 40.\n", c4x_cpu_version);
-      c4x_cpu_version = 40;
-      target_flags |= C40_FLAG;
-    }
-
-  if (TARGET_C30 || TARGET_C31 || TARGET_C32 || TARGET_C33)
-    target_flags |= C3X_FLAG;
-  else
-    target_flags &= ~C3X_FLAG;
-
-  /* Convert foo / 8.0 into foo * 0.125, etc.  */
-  set_fast_math_flags();
-
-  /* We should phase out the following at some stage.
-     This provides compatibility with the old -mno-aliases option.  */
-  if (! TARGET_ALIASES && ! flag_argument_noalias)
-    flag_argument_noalias = 1;
-
-  /* Register global variables with the garbage collector.  */
-  c4x_add_gc_roots ();
-}
-
-
-/* This is called before c4x_override_options.  */
-
-void
-c4x_optimization_options (level, size)
-     int level ATTRIBUTE_UNUSED;
-     int size ATTRIBUTE_UNUSED;
-{
-  /* Scheduling before register allocation can screw up global
-     register allocation, especially for functions that use MPY||ADD
-     instructions.  The benefit we gain we get by scheduling before
-     register allocation is probably marginal anyhow.  */
-  flag_schedule_insns = 0;
-}
-
-
-/* Write an ASCII string.  */
-
-#define C4X_ASCII_LIMIT 40
-
-void
-c4x_output_ascii (stream, ptr, len)
-     FILE *stream;
-     const char *ptr;
-     int len;
-{
-  char sbuf[C4X_ASCII_LIMIT + 1];
-  int s, l, special, first = 1, onlys;
-
-  if (len)
-      fprintf (stream, "\t.byte\t");
-
-  for (s = l = 0; len > 0; --len, ++ptr)
-    {
-      onlys = 0;
-
-      /* Escape " and \ with a \".  */
-      special = *ptr == '\"' || *ptr == '\\';
-
-      /* If printable - add to buff.  */
-      if ((! TARGET_TI || ! special) && *ptr >= 0x20 && *ptr < 0x7f)
-       {
-         if (special)
-           sbuf[s++] = '\\';
-         sbuf[s++] = *ptr;
-         if (s < C4X_ASCII_LIMIT - 1)
-           continue;
-         onlys = 1;
-       }
-      if (s)
-       {
-         if (first)
-           first = 0;
-         else
-           {
-             fputc (',', stream);
-             l++;
-           }
-
-         sbuf[s] = 0;
-         fprintf (stream, "\"%s\"", sbuf);
-         l += s + 2;
-         if (TARGET_TI && l >= 80 && len > 1)
-           {
-             fprintf (stream, "\n\t.byte\t");
-             first = 1;
-             l = 0;
-           }
-       
-         s = 0;
-       }
-      if (onlys)
-       continue;
-
-      if (first)
-       first = 0;
-      else
-       {
-         fputc (',', stream);
-         l++;
-       }
-
-      fprintf (stream, "%d", *ptr);
-      l += 3;
-      if (TARGET_TI && l >= 80 && len > 1)
-       {
-         fprintf (stream, "\n\t.byte\t");
-         first = 1;
-         l = 0;
-       }
-    }
-  if (s)
-    {
-      if (! first)
-       fputc (',', stream);
-
-      sbuf[s] = 0;
-      fprintf (stream, "\"%s\"", sbuf);
-      s = 0;
-    }
-  fputc ('\n', stream);
-}
-
-
-int
-c4x_hard_regno_mode_ok (regno, mode)
-     unsigned int regno;
-     enum machine_mode mode;
-{
-  switch (mode)
-    {
-#if Pmode != QImode
-    case Pmode:                        /* Pointer (24/32 bits).  */
-#endif
-    case QImode:               /* Integer (32 bits).  */
-      return IS_INT_REGNO (regno);
-
-    case QFmode:               /* Float, Double (32 bits).  */
-    case HFmode:               /* Long Double (40 bits).  */
-      return IS_EXT_REGNO (regno);
-
-    case CCmode:               /* Condition Codes.  */
-    case CC_NOOVmode:          /* Condition Codes.  */
-      return IS_ST_REGNO (regno);
-
-    case HImode:               /* Long Long (64 bits).  */
-      /* We need two registers to store long longs.  Note that 
-        it is much easier to constrain the first register
-        to start on an even boundary.  */
-      return IS_INT_REGNO (regno)
-       && IS_INT_REGNO (regno + 1)
-       && (regno & 1) == 0;
-
-    default:
-      return 0;                        /* We don't support these modes.  */
-    }
-
-  return 0;
-}
-
-/* Return non-zero if REGNO1 can be renamed to REGNO2.  */
-int
-c4x_hard_regno_rename_ok (regno1, regno2)
-     unsigned int regno1;
-     unsigned int regno2;
-{
-  /* We can not copy call saved registers from mode QI into QF or from
-     mode QF into QI.  */
-  if (IS_FLOAT_CALL_SAVED_REGNO (regno1) && IS_INT_CALL_SAVED_REGNO (regno2))
-    return 0;
-  if (IS_INT_CALL_SAVED_REGNO (regno1) && IS_FLOAT_CALL_SAVED_REGNO (regno2))
-    return 0;
-  /* We cannot copy from an extended (40 bit) register to a standard
-     (32 bit) register because we only set the condition codes for
-     extended registers.  */
-  if (IS_EXT_REGNO (regno1) && ! IS_EXT_REGNO (regno2))
-    return 0;
-  if (IS_EXT_REGNO (regno2) && ! IS_EXT_REGNO (regno1))
-    return 0;
-  return 1;
-}
-
-/* The TI C3x C compiler register argument runtime model uses 6 registers,
-   AR2, R2, R3, RC, RS, RE.
-
-   The first two floating point arguments (float, double, long double)
-   that are found scanning from left to right are assigned to R2 and R3.
-
-   The remaining integer (char, short, int, long) or pointer arguments
-   are assigned to the remaining registers in the order AR2, R2, R3,
-   RC, RS, RE when scanning left to right, except for the last named
-   argument prior to an ellipsis denoting variable number of
-   arguments.  We don't have to worry about the latter condition since
-   function.c treats the last named argument as anonymous (unnamed).
-
-   All arguments that cannot be passed in registers are pushed onto
-   the stack in reverse order (right to left).  GCC handles that for us.
-
-   c4x_init_cumulative_args() is called at the start, so we can parse
-   the args to see how many floating point arguments and how many
-   integer (or pointer) arguments there are.  c4x_function_arg() is
-   then called (sometimes repeatedly) for each argument (parsed left
-   to right) to obtain the register to pass the argument in, or zero
-   if the argument is to be passed on the stack.  Once the compiler is
-   happy, c4x_function_arg_advance() is called.
-
-   Don't use R0 to pass arguments in, we use 0 to indicate a stack
-   argument.  */
-
-static const int c4x_int_reglist[3][6] =
-{
-  {AR2_REGNO, R2_REGNO, R3_REGNO, RC_REGNO, RS_REGNO, RE_REGNO},
-  {AR2_REGNO, R3_REGNO, RC_REGNO, RS_REGNO, RE_REGNO, 0},
-  {AR2_REGNO, RC_REGNO, RS_REGNO, RE_REGNO, 0, 0}
-};
-
-static int c4x_fp_reglist[2] = {R2_REGNO, R3_REGNO};
-
-
-/* Initialize a variable CUM of type CUMULATIVE_ARGS for a call to a
-   function whose data type is FNTYPE.
-   For a library call, FNTYPE is  0.  */
-
-void
-c4x_init_cumulative_args (cum, fntype, libname)
-     CUMULATIVE_ARGS *cum;     /* Argument info to initialize.  */
-     tree fntype;              /* Tree ptr for function decl.  */
-     rtx libname;              /* SYMBOL_REF of library name or 0.  */
-{
-  tree param, next_param;
-
-  cum->floats = cum->ints = 0;
-  cum->init = 0;
-  cum->var = 0;
-  cum->args = 0;
-
-  if (TARGET_DEBUG)
-    {
-      fprintf (stderr, "\nc4x_init_cumulative_args (");
-      if (fntype)
-       {
-         tree ret_type = TREE_TYPE (fntype);
-
-         fprintf (stderr, "fntype code = %s, ret code = %s",
-                  tree_code_name[(int) TREE_CODE (fntype)],
-                  tree_code_name[(int) TREE_CODE (ret_type)]);
-       }
-      else
-       fprintf (stderr, "no fntype");
-
-      if (libname)
-       fprintf (stderr, ", libname = %s", XSTR (libname, 0));
-    }
-
-  cum->prototype = (fntype && TYPE_ARG_TYPES (fntype));
-
-  for (param = fntype ? TYPE_ARG_TYPES (fntype) : 0;
-       param; param = next_param)
-    {
-      tree type;
-
-      next_param = TREE_CHAIN (param);
-
-      type = TREE_VALUE (param);
-      if (type && type != void_type_node)
-       {
-         enum machine_mode mode;
-
-         /* If the last arg doesn't have void type then we have
-            variable arguments.  */
-         if (! next_param)
-           cum->var = 1;
-
-         if ((mode = TYPE_MODE (type)))
-           {
-             if (! MUST_PASS_IN_STACK (mode, type))
-               {
-                 /* Look for float, double, or long double argument.  */
-                 if (mode == QFmode || mode == HFmode)
-                   cum->floats++;
-                 /* Look for integer, enumeral, boolean, char, or pointer
-                    argument.  */
-                 else if (mode == QImode || mode == Pmode)
-                   cum->ints++;
-               }
-           }
-         cum->args++;
-       }
-    }
-
-  if (TARGET_DEBUG)
-    fprintf (stderr, "%s%s, args = %d)\n",
-            cum->prototype ? ", prototype" : "",
-            cum->var ? ", variable args" : "",
-            cum->args);
-}
-
-
-/* Update the data in CUM to advance over an argument
-   of mode MODE and data type TYPE.
-   (TYPE is null for libcalls where that information may not be available.)  */
-
-void
-c4x_function_arg_advance (cum, mode, type, named)
-     CUMULATIVE_ARGS *cum;     /* Current arg information.  */
-     enum machine_mode mode;   /* Current arg mode.  */
-     tree type;                        /* Type of the arg or 0 if lib support.  */
-     int named;                        /* Whether or not the argument was named.  */
-{
-  if (TARGET_DEBUG)
-    fprintf (stderr, "c4x_function_adv(mode=%s, named=%d)\n\n",
-            GET_MODE_NAME (mode), named);
-  if (! TARGET_MEMPARM 
-      && named
-      && type
-      && ! MUST_PASS_IN_STACK (mode, type))
-    {
-      /* Look for float, double, or long double argument.  */
-      if (mode == QFmode || mode == HFmode)
-       cum->floats++;
-      /* Look for integer, enumeral, boolean, char, or pointer argument.  */
-      else if (mode == QImode || mode == Pmode)
-       cum->ints++;
-    }
-  else if (! TARGET_MEMPARM && ! type)
-    {
-      /* Handle libcall arguments.  */
-      if (mode == QFmode || mode == HFmode)
-       cum->floats++;
-      else if (mode == QImode || mode == Pmode)
-       cum->ints++;
-    }
-  return;
-}
-
-
-/* Define where to put the arguments to a function.  Value is zero to
-   push the argument on the stack, or a hard register in which to
-   store the argument.
-
-   MODE is the argument's machine mode.
-   TYPE is the data type of the argument (as a tree).
-   This is null for libcalls where that information may
-   not be available.
-   CUM is a variable of type CUMULATIVE_ARGS which gives info about
-   the preceding args and about the function being called.
-   NAMED is nonzero if this argument is a named parameter
-   (otherwise it is an extra parameter matching an ellipsis).  */
-
-struct rtx_def *
-c4x_function_arg (cum, mode, type, named)
-     CUMULATIVE_ARGS *cum;     /* Current arg information.  */
-     enum machine_mode mode;   /* Current arg mode.  */
-     tree type;                        /* Type of the arg or 0 if lib support.  */
-     int named;                        /* != 0 for normal args, == 0 for ... args.  */
-{
-  int reg = 0;                 /* Default to passing argument on stack.  */
-
-  if (! cum->init)
-    {
-      /* We can handle at most 2 floats in R2, R3.  */
-      cum->maxfloats = (cum->floats > 2) ? 2 : cum->floats;
-
-      /* We can handle at most 6 integers minus number of floats passed 
-        in registers.  */
-      cum->maxints = (cum->ints > 6 - cum->maxfloats) ? 
-       6 - cum->maxfloats : cum->ints;
-
-      /* If there is no prototype, assume all the arguments are integers.  */
-      if (! cum->prototype)
-       cum->maxints = 6;
-
-      cum->ints = cum->floats = 0;
-      cum->init = 1;
-    }
-
-  /* This marks the last argument.  We don't need to pass this through
-     to the call insn.  */
-  if (type == void_type_node)
-    return 0;
-
-  if (! TARGET_MEMPARM 
-      && named 
-      && type
-      && ! MUST_PASS_IN_STACK (mode, type))
-    {
-      /* Look for float, double, or long double argument.  */
-      if (mode == QFmode || mode == HFmode)
-       {
-         if (cum->floats < cum->maxfloats)
-           reg = c4x_fp_reglist[cum->floats];
-       }
-      /* Look for integer, enumeral, boolean, char, or pointer argument.  */
-      else if (mode == QImode || mode == Pmode)
-       {
-         if (cum->ints < cum->maxints)
-           reg = c4x_int_reglist[cum->maxfloats][cum->ints];
-       }
-    }
-  else if (! TARGET_MEMPARM && ! type)
-    {
-      /* We could use a different argument calling model for libcalls,
-         since we're only calling functions in libgcc.  Thus we could
-         pass arguments for long longs in registers rather than on the
-         stack.  In the meantime, use the odd TI format.  We make the
-         assumption that we won't have more than two floating point
-         args, six integer args, and that all the arguments are of the
-         same mode.  */
-      if (mode == QFmode || mode == HFmode)
-       reg = c4x_fp_reglist[cum->floats];
-      else if (mode == QImode || mode == Pmode)
-       reg = c4x_int_reglist[0][cum->ints];
-    }
-
-  if (TARGET_DEBUG)
-    {
-      fprintf (stderr, "c4x_function_arg(mode=%s, named=%d",
-              GET_MODE_NAME (mode), named);
-      if (reg)
-       fprintf (stderr, ", reg=%s", reg_names[reg]);
-      else
-       fprintf (stderr, ", stack");
-      fprintf (stderr, ")\n");
-    }
-  if (reg)
-    return gen_rtx_REG (mode, reg);
-  else
-    return NULL_RTX;
-}
-
-
-void
-c4x_va_start (stdarg_p, valist, nextarg)
-     int stdarg_p;
-     tree valist;
-     rtx nextarg;
-{
-  nextarg = plus_constant (nextarg, stdarg_p ? 0 : UNITS_PER_WORD * 2);
-
-  std_expand_builtin_va_start (stdarg_p, valist, nextarg);
-}
-
-
-/* C[34]x arguments grow in weird ways (downwards) that the standard
-   varargs stuff can't handle..  */
-rtx
-c4x_va_arg (valist, type)
-     tree valist, type;
-{
-  tree t;
-
-  t = build (PREDECREMENT_EXPR, TREE_TYPE (valist), valist,
-            build_int_2 (int_size_in_bytes (type), 0));
-  TREE_SIDE_EFFECTS (t) = 1;
-
-  return expand_expr (t, NULL_RTX, Pmode, EXPAND_NORMAL);
-}
-
-
-static int
-c4x_isr_reg_used_p (regno)
-     unsigned int regno;
-{
-  /* Don't save/restore FP or ST, we handle them separately.  */
-  if (regno == FRAME_POINTER_REGNUM
-      || IS_ST_REGNO (regno))
-    return 0;
-
-  /* We could be a little smarter abut saving/restoring DP.
-     We'll only save if for the big memory model or if
-     we're paranoid. ;-)  */
-  if (IS_DP_REGNO (regno))
-    return ! TARGET_SMALL || TARGET_PARANOID;
-
-  /* Only save/restore regs in leaf function that are used.  */
-  if (c4x_leaf_function)
-    return regs_ever_live[regno] && fixed_regs[regno] == 0;
-
-  /* Only save/restore regs that are used by the ISR and regs
-     that are likely to be used by functions the ISR calls
-     if they are not fixed.  */
-  return IS_EXT_REGNO (regno)
-    || ((regs_ever_live[regno] || call_used_regs[regno]) 
-       && fixed_regs[regno] == 0);
-}
-
-
-static int
-c4x_leaf_function_p ()
-{
-  /* A leaf function makes no calls, so we only need
-     to save/restore the registers we actually use.
-     For the global variable leaf_function to be set, we need
-     to define LEAF_REGISTERS and all that it entails.
-     Let's check ourselves...   */
-
-  if (lookup_attribute ("leaf_pretend",
-                       TYPE_ATTRIBUTES (TREE_TYPE (current_function_decl))))
-    return 1;
-
-  /* Use the leaf_pretend attribute at your own risk.  This is a hack
-     to speed up ISRs that call a function infrequently where the
-     overhead of saving and restoring the additional registers is not
-     warranted.  You must save and restore the additional registers
-     required by the called function.  Caveat emptor.  Here's enough
-     rope...  */
-
-  if (leaf_function_p ())
-    return 1;
-
-  return 0;
-}
-
-
-static int
-c4x_assembler_function_p ()
-{
-  tree type;
-
-  type = TREE_TYPE (current_function_decl);
-  return (lookup_attribute ("assembler", TYPE_ATTRIBUTES (type)) != NULL)
-    || (lookup_attribute ("naked", TYPE_ATTRIBUTES (type)) != NULL);
-}
-
-
-int
-c4x_interrupt_function_p ()
-{
-  if (lookup_attribute ("interrupt",
-                       TYPE_ATTRIBUTES (TREE_TYPE (current_function_decl))))
-    return 1;
-
-  /* Look for TI style c_intnn.  */
-  return current_function_name[0] == 'c'
-    && current_function_name[1] == '_'
-    && current_function_name[2] == 'i'
-    && current_function_name[3] == 'n' 
-    && current_function_name[4] == 't'
-    && ISDIGIT (current_function_name[5])
-    && ISDIGIT (current_function_name[6]);
-}
-
-void
-c4x_expand_prologue ()
-{
-  unsigned int regno;
-  int size = get_frame_size ();
-  rtx insn;
-
-  /* In functions where ar3 is not used but frame pointers are still
-     specified, frame pointers are not adjusted (if >= -O2) and this
-     is used so it won't needlessly push the frame pointer.  */
-  int dont_push_ar3;
-
-  /* For __assembler__ function don't build a prologue.  */
-  if (c4x_assembler_function_p ())
-    {
-      return;
-    }
-  
-  /* For __interrupt__ function build specific prologue.  */
-  if (c4x_interrupt_function_p ())
-    {
-      c4x_leaf_function = c4x_leaf_function_p ();
-      
-      insn = emit_insn (gen_push_st ());
-      RTX_FRAME_RELATED_P (insn) = 1;
-      if (size)
-       {
-          insn = emit_insn (gen_pushqi ( gen_rtx_REG (QImode, AR3_REGNO)));
-          RTX_FRAME_RELATED_P (insn) = 1;
-         insn = emit_insn (gen_movqi (gen_rtx_REG (QImode, AR3_REGNO),
-                                      gen_rtx_REG (QImode, SP_REGNO)));
-          RTX_FRAME_RELATED_P (insn) = 1;
-         /* We require that an ISR uses fewer than 32768 words of
-            local variables, otherwise we have to go to lots of
-            effort to save a register, load it with the desired size,
-            adjust the stack pointer, and then restore the modified
-            register.  Frankly, I think it is a poor ISR that
-            requires more than 32767 words of local temporary
-            storage!  */
-         if (size > 32767)
-           error ("ISR %s requires %d words of local vars, max is 32767",
-                  current_function_name, size);
-
-         insn = emit_insn (gen_addqi3 (gen_rtx_REG (QImode, SP_REGNO),
-                                       gen_rtx_REG (QImode, SP_REGNO),
-                                       GEN_INT (size)));
-          RTX_FRAME_RELATED_P (insn) = 1;
-       }
-      for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
-       {
-         if (c4x_isr_reg_used_p (regno))
-           {
-             if (regno == DP_REGNO)
-               {
-                 insn = emit_insn (gen_push_dp ());
-                  RTX_FRAME_RELATED_P (insn) = 1;
-               }
-             else
-               {
-                  insn = emit_insn (gen_pushqi (gen_rtx_REG (QImode, regno)));
-                  RTX_FRAME_RELATED_P (insn) = 1;
-                 if (IS_EXT_REGNO (regno))
-                   {
-                      insn = emit_insn (gen_pushqf
-                                       (gen_rtx_REG (QFmode, regno)));
-                      RTX_FRAME_RELATED_P (insn) = 1;
-                   }
-               }
-           }
-       }
-      /* We need to clear the repeat mode flag if the ISR is
-         going to use a RPTB instruction or uses the RC, RS, or RE
-         registers.  */
-      if (regs_ever_live[RC_REGNO] 
-         || regs_ever_live[RS_REGNO] 
-         || regs_ever_live[RE_REGNO])
-       {
-          insn = emit_insn (gen_andn_st (GEN_INT(~0x100)));
-          RTX_FRAME_RELATED_P (insn) = 1;
-       }
-
-      /* Reload DP reg if we are paranoid about some turkey
-         violating small memory model rules.  */
-      if (TARGET_SMALL && TARGET_PARANOID)
-       {
-          insn = emit_insn (gen_set_ldp_prologue
-                           (gen_rtx_REG (QImode, DP_REGNO),
-                            gen_rtx_SYMBOL_REF (QImode, "data_sec")));
-          RTX_FRAME_RELATED_P (insn) = 1;
-       }
-    }
-  else
-    {
-      if (frame_pointer_needed)
-       {
-         if ((size != 0)
-             || (current_function_args_size != 0)
-             || (optimize < 2))
-           {
-              insn = emit_insn (gen_pushqi ( gen_rtx_REG (QImode, AR3_REGNO)));
-              RTX_FRAME_RELATED_P (insn) = 1;
-             insn = emit_insn (gen_movqi (gen_rtx_REG (QImode, AR3_REGNO),
-                                          gen_rtx_REG (QImode, SP_REGNO)));
-              RTX_FRAME_RELATED_P (insn) = 1;
-             dont_push_ar3 = 1;
-           }
-         else
-           {
-             /* Since ar3 is not used, we don't need to push it.  */
-             dont_push_ar3 = 1;
-           }
-       }
-      else
-       {
-         /* If we use ar3, we need to push it.   */
-         dont_push_ar3 = 0;
-         if ((size != 0) || (current_function_args_size != 0))
-           {
-             /* If we are omitting the frame pointer, we still have
-                to make space for it so the offsets are correct
-                unless we don't use anything on the stack at all.  */
-             size += 1;
-           }
-       }
-      
-      if (size > 32767)
-       {
-         /* Local vars are too big, it will take multiple operations
-            to increment SP.  */
-         if (TARGET_C3X)
-           {
-             insn = emit_insn (gen_movqi (gen_rtx_REG (QImode, R1_REGNO),
-                                          GEN_INT(size >> 16)));
-              RTX_FRAME_RELATED_P (insn) = 1;
-             insn = emit_insn (gen_lshrqi3 (gen_rtx_REG (QImode, R1_REGNO),
-                                            gen_rtx_REG (QImode, R1_REGNO),
-                                            GEN_INT(-16)));
-              RTX_FRAME_RELATED_P (insn) = 1;
-           }
-         else
-           {
-             insn = emit_insn (gen_movqi (gen_rtx_REG (QImode, R1_REGNO),
-                                          GEN_INT(size & ~0xffff)));
-              RTX_FRAME_RELATED_P (insn) = 1;
-           }
-         insn = emit_insn (gen_iorqi3 (gen_rtx_REG (QImode, R1_REGNO),
-                                       gen_rtx_REG (QImode, R1_REGNO),
-                                       GEN_INT(size & 0xffff)));
-          RTX_FRAME_RELATED_P (insn) = 1;
-         insn = emit_insn (gen_addqi3 (gen_rtx_REG (QImode, SP_REGNO),
-                                       gen_rtx_REG (QImode, SP_REGNO),
-                                       gen_rtx_REG (QImode, R1_REGNO)));
-          RTX_FRAME_RELATED_P (insn) = 1;
-       }
-      else if (size != 0)
-       {
-         /* Local vars take up less than 32767 words, so we can directly
-            add the number.  */
-         insn = emit_insn (gen_addqi3 (gen_rtx_REG (QImode, SP_REGNO),
-                                       gen_rtx_REG (QImode, SP_REGNO),
-                                       GEN_INT (size)));
-          RTX_FRAME_RELATED_P (insn) = 1;
-       }
-      
-      for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
-       {
-         if (regs_ever_live[regno] && ! call_used_regs[regno])
-           {
-             if (IS_FLOAT_CALL_SAVED_REGNO (regno))
-               {
-                 if (TARGET_PRESERVE_FLOAT)
-                   {
-                      insn = emit_insn (gen_pushqi
-                                       (gen_rtx_REG (QImode, regno)));
-                     RTX_FRAME_RELATED_P (insn) = 1;
-                   }
-                  insn = emit_insn (gen_pushqf (gen_rtx_REG (QFmode, regno)));
-                 RTX_FRAME_RELATED_P (insn) = 1;
-               }
-             else if ((! dont_push_ar3) || (regno != AR3_REGNO))
-               {
-                  insn = emit_insn (gen_pushqi ( gen_rtx_REG (QImode, regno)));
-                 RTX_FRAME_RELATED_P (insn) = 1;
-               }
-           }
-       }
-    }
-}
-
-
-void
-c4x_expand_epilogue()
-{
-  int regno;
-  int jump = 0;
-  int dont_pop_ar3;
-  rtx insn;
-  int size = get_frame_size ();
-  
-  /* For __assembler__ function build no epilogue.  */
-  if (c4x_assembler_function_p ())
-    {
-      insn = emit_jump_insn (gen_return_from_epilogue ());
-      RTX_FRAME_RELATED_P (insn) = 1;
-      return;
-    }
-
-  /* For __interrupt__ function build specific epilogue.  */
-  if (c4x_interrupt_function_p ())
-    {
-      for (regno = FIRST_PSEUDO_REGISTER - 1; regno >= 0; --regno)
-       {
-         if (! c4x_isr_reg_used_p (regno))
-           continue;
-         if (regno == DP_REGNO)
-           {
-             insn = emit_insn (gen_pop_dp ());
-             RTX_FRAME_RELATED_P (insn) = 1;
-           }
-         else
-           {
-             /* We have to use unspec because the compiler will delete insns
-                that are not call-saved.  */
-             if (IS_EXT_REGNO (regno))
-               {
-                  insn = emit_insn (gen_popqf_unspec
-                                   (gen_rtx_REG (QFmode, regno)));
-                 RTX_FRAME_RELATED_P (insn) = 1;
-               }
-             insn = emit_insn (gen_popqi_unspec (gen_rtx_REG (QImode, regno)));
-             RTX_FRAME_RELATED_P (insn) = 1;
-           }
-       }
-      if (size)
-       {
-         insn = emit_insn (gen_subqi3 (gen_rtx_REG (QImode, SP_REGNO),
-                                       gen_rtx_REG (QImode, SP_REGNO),
-                                       GEN_INT(size)));
-          RTX_FRAME_RELATED_P (insn) = 1;
-         insn = emit_insn (gen_popqi
-                           (gen_rtx_REG (QImode, AR3_REGNO)));
-          RTX_FRAME_RELATED_P (insn) = 1;
-       }
-      insn = emit_insn (gen_pop_st ());
-      RTX_FRAME_RELATED_P (insn) = 1;
-      insn = emit_jump_insn (gen_return_from_interrupt_epilogue ());
-      RTX_FRAME_RELATED_P (insn) = 1;
-    }
-  else
-    {
-      if (frame_pointer_needed)
-       {
-         if ((size != 0) 
-             || (current_function_args_size != 0) 
-             || (optimize < 2))
-           {
-             insn = emit_insn
-               (gen_movqi (gen_rtx_REG (QImode, R2_REGNO),
-                           gen_rtx_MEM (QImode,
-                                        gen_rtx_PLUS 
-                                        (QImode, gen_rtx_REG (QImode,
-                                                              AR3_REGNO),
-                                         GEN_INT(-1)))));
-             RTX_FRAME_RELATED_P (insn) = 1;
-             
-             /* We already have the return value and the fp,
-                so we need to add those to the stack.  */
-             size += 2;
-             jump = 1;
-             dont_pop_ar3 = 1;
-           }
-         else
-           {
-             /* Since ar3 is not used for anything, we don't need to
-                pop it.  */
-             dont_pop_ar3 = 1;
-           }
-       }
-      else
-       {
-         dont_pop_ar3 = 0;     /* If we use ar3, we need to pop it.  */
-         if (size || current_function_args_size)
-           {
-             /* If we are ommitting the frame pointer, we still have
-                to make space for it so the offsets are correct
-                unless we don't use anything on the stack at all.  */
-             size += 1;
-           }
-       }
-      
-      /* Now restore the saved registers, putting in the delayed branch
-         where required.  */
-      for (regno = FIRST_PSEUDO_REGISTER - 1; regno >= 0; regno--)
-       {
-         if (regs_ever_live[regno] && ! call_used_regs[regno])
-           {
-             if (regno == AR3_REGNO && dont_pop_ar3)
-               continue;
-             
-             if (IS_FLOAT_CALL_SAVED_REGNO (regno))
-               {
-                 insn = emit_insn (gen_popqf_unspec
-                                   (gen_rtx_REG (QFmode, regno)));
-                 RTX_FRAME_RELATED_P (insn) = 1;
-                 if (TARGET_PRESERVE_FLOAT)
-                   {
-                      insn = emit_insn (gen_popqi_unspec
-                                       (gen_rtx_REG (QImode, regno)));
-                     RTX_FRAME_RELATED_P (insn) = 1;
-                   }
-               }
-             else
-               {
-                 insn = emit_insn (gen_popqi (gen_rtx_REG (QImode, regno)));
-                 RTX_FRAME_RELATED_P (insn) = 1;
-               }
-           }
-       }
-      
-      if (frame_pointer_needed)
-       {
-         if ((size != 0)
-             || (current_function_args_size != 0)
-             || (optimize < 2))
-           {
-             /* Restore the old FP.  */
-             insn = emit_insn 
-               (gen_movqi 
-                (gen_rtx_REG (QImode, AR3_REGNO),
-                 gen_rtx_MEM (QImode, gen_rtx_REG (QImode, AR3_REGNO))));
-             
-             RTX_FRAME_RELATED_P (insn) = 1;
-           }
-       }
-      
-      if (size > 32767)
-       {
-         /* Local vars are too big, it will take multiple operations
-            to decrement SP.  */
-         if (TARGET_C3X)
-           {
-             insn = emit_insn (gen_movqi (gen_rtx_REG (QImode, R3_REGNO),
-                                          GEN_INT(size >> 16)));
-              RTX_FRAME_RELATED_P (insn) = 1;
-             insn = emit_insn (gen_lshrqi3 (gen_rtx_REG (QImode, R3_REGNO),
-                                            gen_rtx_REG (QImode, R3_REGNO),
-                                            GEN_INT(-16)));
-              RTX_FRAME_RELATED_P (insn) = 1;
-           }
-         else
-           {
-             insn = emit_insn (gen_movqi (gen_rtx_REG (QImode, R3_REGNO),
-                                          GEN_INT(size & ~0xffff)));
-              RTX_FRAME_RELATED_P (insn) = 1;
-           }
-         insn = emit_insn (gen_iorqi3 (gen_rtx_REG (QImode, R3_REGNO),
-                                       gen_rtx_REG (QImode, R3_REGNO),
-                                       GEN_INT(size & 0xffff)));
-          RTX_FRAME_RELATED_P (insn) = 1;
-         insn = emit_insn (gen_subqi3 (gen_rtx_REG (QImode, SP_REGNO),
-                                       gen_rtx_REG (QImode, SP_REGNO),
-                                       gen_rtx_REG (QImode, R3_REGNO)));
-          RTX_FRAME_RELATED_P (insn) = 1;
-       }
-      else if (size != 0)
-       {
-         /* Local vars take up less than 32768 words, so we can directly
-            subtract the number.  */
-         insn = emit_insn (gen_subqi3 (gen_rtx_REG (QImode, SP_REGNO),
-                                       gen_rtx_REG (QImode, SP_REGNO),
-                                       GEN_INT(size)));
-          RTX_FRAME_RELATED_P (insn) = 1;
-       }
-      
-      if (jump)
-       {
-         insn = emit_jump_insn (gen_return_indirect_internal
-                                (gen_rtx_REG (QImode, R2_REGNO)));
-          RTX_FRAME_RELATED_P (insn) = 1;
-       }
-      else
-       {
-          insn = emit_jump_insn (gen_return_from_epilogue ());
-          RTX_FRAME_RELATED_P (insn) = 1;
-       }
-    }
-}
-
-
-int
-c4x_null_epilogue_p ()
-{
-  int regno;
-
-  if (reload_completed
-      && ! c4x_assembler_function_p ()
-      && ! c4x_interrupt_function_p ()
-      && ! current_function_calls_alloca
-      && ! current_function_args_size
-      && ! (optimize < 2)
-      && ! get_frame_size ())
-    {
-      for (regno = FIRST_PSEUDO_REGISTER - 1; regno >= 0; regno--)
-       if (regs_ever_live[regno] && ! call_used_regs[regno]
-           && (regno != AR3_REGNO))
-         return 0;
-      return 1;
-    }
-  return 0;
-}
-
-
-int
-c4x_emit_move_sequence (operands, mode)
-     rtx *operands;
-     enum machine_mode mode;     
-{
-  rtx op0 = operands[0];
-  rtx op1 = operands[1];
-
-  if (! reload_in_progress
-      && ! REG_P (op0) 
-      && ! REG_P (op1)
-      && ! (stik_const_operand (op1, mode) && ! push_operand (op0, mode)))
-    op1 = force_reg (mode, op1);
-
-  if (GET_CODE (op1) == LO_SUM
-      && GET_MODE (op1) == Pmode
-      && dp_reg_operand (XEXP (op1, 0), mode))
-    {
-      /* expand_increment will sometimes create a LO_SUM immediate
-        address.  */
-      op1 = XEXP (op1, 1);
-    }
-  else if (symbolic_address_operand (op1, mode))
-    {
-      if (TARGET_LOAD_ADDRESS)
-       {
-         /* Alias analysis seems to do a better job if we force
-            constant addresses to memory after reload.  */
-         emit_insn (gen_load_immed_address (op0, op1));
-         return 1;
-       }
-      else
-       {
-         /* Stick symbol or label address into the constant pool.  */
-         op1 = force_const_mem (Pmode, op1);
-       }
-    }
-  else if (mode == HFmode && CONSTANT_P (op1) && ! LEGITIMATE_CONSTANT_P (op1))
-    {
-      /* We could be a lot smarter about loading some of these
-        constants...  */
-      op1 = force_const_mem (mode, op1);
-    }
-
-  /* Convert (MEM (SYMREF)) to a (MEM (LO_SUM (REG) (SYMREF)))
-     and emit associated (HIGH (SYMREF)) if large memory model.  
-     c4x_legitimize_address could be used to do this,
-     perhaps by calling validize_address.  */
-  if (TARGET_EXPOSE_LDP
-      && ! (reload_in_progress || reload_completed)
-      && GET_CODE (op1) == MEM
-      && symbolic_address_operand (XEXP (op1, 0), Pmode))
-    {
-      rtx dp_reg = gen_rtx_REG (Pmode, DP_REGNO);
-      if (! TARGET_SMALL)
-       emit_insn (gen_set_ldp (dp_reg, XEXP (op1, 0)));
-      op1 = change_address (op1, mode,
-                           gen_rtx_LO_SUM (Pmode, dp_reg, XEXP (op1, 0)));
-    }
-
-  if (TARGET_EXPOSE_LDP
-      && ! (reload_in_progress || reload_completed)
-      && GET_CODE (op0) == MEM 
-      && symbolic_address_operand (XEXP (op0, 0), Pmode))
-    {
-      rtx dp_reg = gen_rtx_REG (Pmode, DP_REGNO);
-      if (! TARGET_SMALL)
-       emit_insn (gen_set_ldp (dp_reg, XEXP (op0, 0)));
-      op0 = change_address (op0, mode,
-                           gen_rtx_LO_SUM (Pmode, dp_reg, XEXP (op0, 0)));
-    }
-
-  if (GET_CODE (op0) == SUBREG
-      && mixed_subreg_operand (op0, mode))
-    {
-      /* We should only generate these mixed mode patterns
-        during RTL generation.  If we need do it later on
-        then we'll have to emit patterns that won't clobber CC.  */
-      if (reload_in_progress || reload_completed)
-       abort ();
-      if (GET_MODE (SUBREG_REG (op0)) == QImode)
-       op0 = SUBREG_REG (op0);
-      else if (GET_MODE (SUBREG_REG (op0)) == HImode)
-       {
-         op0 = copy_rtx (op0);
-         PUT_MODE (op0, QImode);
-       }
-      else
-       abort ();
-
-      if (mode == QFmode)
-       emit_insn (gen_storeqf_int_clobber (op0, op1));
-      else
-       abort ();
-      return 1;
-    }
-
-  if (GET_CODE (op1) == SUBREG
-      && mixed_subreg_operand (op1, mode))
-    {
-      /* We should only generate these mixed mode patterns
-        during RTL generation.  If we need do it later on
-        then we'll have to emit patterns that won't clobber CC.  */
-      if (reload_in_progress || reload_completed)
-       abort ();
-      if (GET_MODE (SUBREG_REG (op1)) == QImode)
-       op1 = SUBREG_REG (op1);
-      else if (GET_MODE (SUBREG_REG (op1)) == HImode)
-       {
-         op1 = copy_rtx (op1);
-         PUT_MODE (op1, QImode);
-       }
-      else
-       abort ();
-
-      if (mode == QFmode)
-       emit_insn (gen_loadqf_int_clobber (op0, op1));
-      else
-       abort ();
-      return 1;
-    }
-
-  if (mode == QImode
-      && reg_operand (op0, mode)
-      && const_int_operand (op1, mode)
-      && ! IS_INT16_CONST (INTVAL (op1))
-      && ! IS_HIGH_CONST (INTVAL (op1)))
-    {
-      emit_insn (gen_loadqi_big_constant (op0, op1));
-      return 1;
-    }
-
-  if (mode == HImode
-      && reg_operand (op0, mode)
-      && const_int_operand (op1, mode))
-    {
-      emit_insn (gen_loadhi_big_constant (op0, op1));
-      return 1;
-    }
-
-  /* Adjust operands in case we have modified them.  */
-  operands[0] = op0;
-  operands[1] = op1;
-
-  /* Emit normal pattern.  */
-  return 0;
-}
-
-
-void
-c4x_emit_libcall (libcall, code, dmode, smode, noperands, operands)
-     rtx libcall;
-     enum rtx_code code;
-     enum machine_mode dmode;
-     enum machine_mode smode;
-     int noperands;
-     rtx *operands;
-{
-  rtx ret;
-  rtx insns;
-  rtx equiv;
-
-  start_sequence ();
-  switch (noperands)
-    {
-    case 2:
-      ret = emit_library_call_value (libcall, NULL_RTX, 1, dmode, 1,
-                                    operands[1], smode);
-      equiv = gen_rtx (code, dmode, operands[1]);
-      break;
-
-    case 3:
-      ret = emit_library_call_value (libcall, NULL_RTX, 1, dmode, 2,
-                                    operands[1], smode, operands[2], smode);
-      equiv = gen_rtx (code, dmode, operands[1], operands[2]);
-      break;
-
-    default:
-      abort ();
-    }
-
-  insns = get_insns ();
-  end_sequence ();
-  emit_libcall_block (insns, operands[0], ret, equiv);
-}
-
-
-void
-c4x_emit_libcall3 (libcall, code, mode, operands)
-     rtx libcall;
-     enum rtx_code code;
-     enum machine_mode mode;
-     rtx *operands;
-{
-  c4x_emit_libcall (libcall, code, mode, mode, 3, operands);
-}
-
-
-void
-c4x_emit_libcall_mulhi (libcall, code, mode, operands)
-     rtx libcall;
-     enum rtx_code code;
-     enum machine_mode mode;
-     rtx *operands;
-{
-  rtx ret;
-  rtx insns;
-  rtx equiv;
-
-  start_sequence ();
-  ret = emit_library_call_value (libcall, NULL_RTX, 1, mode, 2,
-                                 operands[1], mode, operands[2], mode);
-  equiv = gen_rtx_TRUNCATE (mode,
-                   gen_rtx_LSHIFTRT (HImode,
-                            gen_rtx_MULT (HImode,
-                                     gen_rtx (code, HImode, operands[1]),
-                                     gen_rtx (code, HImode, operands[2])),
-                                     GEN_INT (32)));
-  insns = get_insns ();
-  end_sequence ();
-  emit_libcall_block (insns, operands[0], ret, equiv);
-}
-
-
-/* Set the SYMBOL_REF_FLAG for a function decl.  However, wo do not
-   yet use this info.  */
-void
-c4x_encode_section_info (decl)
-  tree decl;
-{
-#if 0
-  if (TREE_CODE (TREE_TYPE (decl)) == FUNCTION_TYPE)   
-    SYMBOL_REF_FLAG (XEXP (DECL_RTL (decl), 0)) = 1;
-#else
-  if (TREE_CODE (decl) == FUNCTION_DECL)   
-    SYMBOL_REF_FLAG (XEXP (DECL_RTL (decl), 0)) = 1;
-#endif
-}
-
-
-int
-c4x_check_legit_addr (mode, addr, strict)
-     enum machine_mode mode;
-     rtx addr;
-     int strict;
-{
-  rtx base = NULL_RTX;         /* Base register (AR0-AR7).  */
-  rtx indx = NULL_RTX;         /* Index register (IR0,IR1).  */
-  rtx disp = NULL_RTX;         /* Displacement.  */
-  enum rtx_code code;
-
-  code = GET_CODE (addr);
-  switch (code)
-    {
-      /* Register indirect with auto increment/decrement.  We don't
-        allow SP here---push_operand should recognise an operand
-        being pushed on the stack.  */
-
-    case PRE_DEC:
-    case PRE_INC:
-    case POST_DEC:
-      if (mode != QImode && mode != QFmode)
-       return 0;
-
-    case POST_INC:
-      base = XEXP (addr, 0);
-      if (! REG_P (base))
-       return 0;
-      break;
-
-    case PRE_MODIFY:
-    case POST_MODIFY:
-      {
-       rtx op0 = XEXP (addr, 0);
-       rtx op1 = XEXP (addr, 1);
-
-       if (mode != QImode && mode != QFmode)
-         return 0;
-
-       if (! REG_P (op0) 
-           || (GET_CODE (op1) != PLUS && GET_CODE (op1) != MINUS))
-         return 0;
-       base = XEXP (op1, 0);
-       if (base != op0)
-         return 0;
-       if (REG_P (XEXP (op1, 1)))
-         indx = XEXP (op1, 1);
-       else
-         disp = XEXP (op1, 1);
-      }
-      break;
-       
-      /* Register indirect.  */
-    case REG:
-      base = addr;
-      break;
-
-      /* Register indirect with displacement or index.  */
-    case PLUS:
-      {
-       rtx op0 = XEXP (addr, 0);
-       rtx op1 = XEXP (addr, 1);
-       enum rtx_code code0 = GET_CODE (op0);
-
-       switch (code0)
-         {
-         case REG:
-           if (REG_P (op1))
-             {
-               base = op0;     /* Base + index.  */
-               indx = op1;
-               if (IS_INDEX_REG (base) || IS_ADDR_REG (indx))
-                 {
-                   base = op1;
-                   indx = op0;
-                 }
-             }
-           else
-             {
-               base = op0;     /* Base + displacement.  */
-               disp = op1;
-             }
-           break;
-
-         default:
-           return 0;
-         }
-      }
-      break;
-
-      /* Direct addressing with DP register.  */
-    case LO_SUM:
-      {
-       rtx op0 = XEXP (addr, 0);
-       rtx op1 = XEXP (addr, 1);
-
-       /* HImode and HFmode direct memory references aren't truly
-          offsettable (consider case at end of data page).  We
-          probably get better code by loading a pointer and using an
-          indirect memory reference.  */
-       if (mode == HImode || mode == HFmode)
-         return 0;
-
-       if (!REG_P (op0) || REGNO (op0) != DP_REGNO)
-         return 0;
-
-       if ((GET_CODE (op1) == SYMBOL_REF || GET_CODE (op1) == LABEL_REF))
-         return 1;
-
-       if (GET_CODE (op1) == CONST)
-         return 1;
-       return 0;
-      }
-      break;
-
-      /* Direct addressing with some work for the assembler...  */
-    case CONST:
-      /* Direct addressing.  */
-    case LABEL_REF:
-    case SYMBOL_REF:
-      if (! TARGET_EXPOSE_LDP && ! strict && mode != HFmode && mode != HImode)
-       return 1;
-      /* These need to be converted to a LO_SUM (...). 
-        LEGITIMIZE_RELOAD_ADDRESS will do this during reload.  */
-      return 0;
-
-      /* Do not allow direct memory access to absolute addresses.
-         This is more pain than it's worth, especially for the
-         small memory model where we can't guarantee that
-         this address is within the data page---we don't want
-         to modify the DP register in the small memory model,
-         even temporarily, since an interrupt can sneak in....  */
-    case CONST_INT:
-      return 0;
-
-      /* Indirect indirect addressing.  */
-    case MEM:
-      return 0;
-
-    case CONST_DOUBLE:
-      fatal_insn ("using CONST_DOUBLE for address", addr);
-
-    default:
-      return 0;
-    }
-
-  /* Validate the base register.  */
-  if (base)
-    {
-      /* Check that the address is offsettable for HImode and HFmode.  */
-      if (indx && (mode == HImode || mode == HFmode))
-       return 0;
-
-      /* Handle DP based stuff.  */
-      if (REGNO (base) == DP_REGNO)
-       return 1;
-      if (strict && ! REGNO_OK_FOR_BASE_P (REGNO (base)))
-       return 0;
-      else if (! strict && ! IS_ADDR_OR_PSEUDO_REG (base))
-       return 0;
-    }
-
-  /* Now validate the index register.  */
-  if (indx)
-    {
-      if (GET_CODE (indx) != REG)
-       return 0;
-      if (strict && ! REGNO_OK_FOR_INDEX_P (REGNO (indx)))
-       return 0;
-      else if (! strict && ! IS_INDEX_OR_PSEUDO_REG (indx))
-       return 0;
-    }
-
-  /* Validate displacement.  */
-  if (disp)
-    {
-      if (GET_CODE (disp) != CONST_INT)
-       return 0;
-      if (mode == HImode || mode == HFmode)
-       {
-         /* The offset displacement must be legitimate.  */
-         if (! IS_DISP8_OFF_CONST (INTVAL (disp)))
-           return 0;
-       }
-      else
-       {
-         if (! IS_DISP8_CONST (INTVAL (disp)))
-           return 0;
-       }
-      /* Can't add an index with a disp.  */
-      if (indx)
-       return 0;               
-    }
-  return 1;
-}
-
-
-rtx
-c4x_legitimize_address (orig, mode)
-     rtx orig ATTRIBUTE_UNUSED;
-     enum machine_mode mode ATTRIBUTE_UNUSED;
-{
-  if (GET_CODE (orig) == SYMBOL_REF
-      || GET_CODE (orig) == LABEL_REF)
-    {
-      if (mode == HImode || mode == HFmode)
-       {
-         /* We need to force the address into
-            a register so that it is offsettable.  */
-         rtx addr_reg = gen_reg_rtx (Pmode);
-         emit_move_insn (addr_reg, orig);
-         return addr_reg;
-       }
-      else
-       {
-         rtx dp_reg = gen_rtx_REG (Pmode, DP_REGNO);
-         
-         if (! TARGET_SMALL)
-           emit_insn (gen_set_ldp (dp_reg, orig));
-         
-         return gen_rtx_LO_SUM (Pmode, dp_reg, orig);
-       }
-    }
-
-  return NULL_RTX;
-}
-
-
-/* Provide the costs of an addressing mode that contains ADDR.
-   If ADDR is not a valid address, its cost is irrelevant.  
-   This is used in cse and loop optimisation to determine
-   if it is worthwhile storing a common address into a register. 
-   Unfortunately, the C4x address cost depends on other operands.  */
-
-int 
-c4x_address_cost (addr)
-     rtx addr;
-{
-  switch (GET_CODE (addr))
-    {
-    case REG:
-      return 1;
-
-    case POST_INC:
-    case POST_DEC:
-    case PRE_INC:
-    case PRE_DEC:
-      return 1;
-      
-      /* These shouldn't be directly generated.  */
-    case SYMBOL_REF:
-    case LABEL_REF:
-    case CONST:
-      return 10;
-
-    case LO_SUM:
-      {
-       rtx op1 = XEXP (addr, 1);
-
-       if (GET_CODE (op1) == LABEL_REF || GET_CODE (op1) == SYMBOL_REF)
-         return TARGET_SMALL ? 3 : 4;
-       
-       if (GET_CODE (op1) == CONST)
-         {
-           rtx offset = const0_rtx;
-           
-           op1 = eliminate_constant_term (op1, &offset);
-           
-           /* ??? These costs need rethinking...  */
-           if (GET_CODE (op1) == LABEL_REF)
-             return 3;
-           
-           if (GET_CODE (op1) != SYMBOL_REF)
-             return 4;
-           
-           if (INTVAL (offset) == 0)
-             return 3;
-
-           return 4;
-         }
-       fatal_insn ("c4x_address_cost: Invalid addressing mode", addr);
-      }
-      break;
-      
-    case PLUS:
-      {
-       register rtx op0 = XEXP (addr, 0);
-       register rtx op1 = XEXP (addr, 1);
-       
-       if (GET_CODE (op0) != REG)
-         break;
-       
-       switch (GET_CODE (op1))
-         {
-         default:
-           break;
-
-         case REG:
-           /* This cost for REG+REG must be greater than the cost
-              for REG if we want autoincrement addressing modes.  */
-           return 2;
-
-         case CONST_INT:
-           /* The following tries to improve GIV combination
-              in strength reduce but appears not to help.  */
-           if (TARGET_DEVEL && IS_UINT5_CONST (INTVAL (op1)))
-             return 1;
-
-           if (IS_DISP1_CONST (INTVAL (op1)))
-             return 1;
-
-           if (! TARGET_C3X && IS_UINT5_CONST (INTVAL (op1)))
-             return 2;
-
-           return 3;
-         }
-      }
-    default:
-      break;
-    }
-  
-  return 4;
-}
-
-
-rtx
-c4x_gen_compare_reg (code, x, y)
-     enum rtx_code code;
-     rtx x, y;
-{
-  enum machine_mode mode = SELECT_CC_MODE (code, x, y);
-  rtx cc_reg;
-
-  if (mode == CC_NOOVmode
-      && (code == LE || code == GE || code == LT || code == GT))
-    return NULL_RTX;
-
-  cc_reg = gen_rtx_REG (mode, ST_REGNO);
-  emit_insn (gen_rtx_SET (VOIDmode, cc_reg,
-                         gen_rtx_COMPARE (mode, x, y)));
-  return cc_reg;
-}
-
-char *
-c4x_output_cbranch (form, seq)
-     const char *form;
-     rtx seq;
-{
-  int delayed = 0;
-  int annultrue = 0;
-  int annulfalse = 0;
-  rtx delay;
-  char *cp;
-  static char str[100];
-  
-  if (final_sequence)
-    {
-      delay = XVECEXP (final_sequence, 0, 1);
-      delayed = ! INSN_ANNULLED_BRANCH_P (seq);
-      annultrue = INSN_ANNULLED_BRANCH_P (seq) && ! INSN_FROM_TARGET_P (delay);
-      annulfalse = INSN_ANNULLED_BRANCH_P (seq) && INSN_FROM_TARGET_P (delay);
-    }
-  strcpy (str, form);
-  cp = &str [strlen (str)];
-  if (delayed)
-    {
-      *cp++ = '%';
-      *cp++ = '#';
-    }
-  if (annultrue)
-    {
-      *cp++ = 'a';
-      *cp++ = 't';
-    }
-  if (annulfalse)
-    {
-      *cp++ = 'a'; 
-      *cp++ = 'f';
-    }
-  *cp++ = '\t';
-  *cp++ = '%'; 
-  *cp++ = 'l';
-  *cp++ = '1';
-  *cp = 0;
-  return str;
-}
-
-void
-c4x_print_operand (file, op, letter)
-     FILE *file;               /* File to write to.  */
-     rtx op;                   /* Operand to print.  */
-     int letter;               /* %<letter> or 0.  */
-{
-  rtx op1;
-  enum rtx_code code;
-
-  switch (letter)
-    {
-    case '#':                  /* Delayed.  */
-      if (final_sequence)
-       asm_fprintf (file, "d");
-      return;
-    }
-
-  code = GET_CODE (op);
-  switch (letter)
-    {
-    case 'A':                  /* Direct address.  */
-      if (code == CONST_INT || code == SYMBOL_REF || code == CONST)
-       asm_fprintf (file, "@");
-      break;
-
-    case 'H':                  /* Sethi.  */
-      output_addr_const (file, op);
-      return;
-
-    case 'I':                  /* Reversed condition.  */
-      code = reverse_condition (code);
-      break;
-
-    case 'L':                  /* Log 2 of constant.  */
-      if (code != CONST_INT)
-       fatal_insn ("c4x_print_operand: %%L inconsistency", op);
-      fprintf (file, "%d", exact_log2 (INTVAL (op)));
-      return;
-
-    case 'N':                  /* Ones complement of small constant.  */
-      if (code != CONST_INT)
-       fatal_insn ("c4x_print_operand: %%N inconsistency", op);
-      fprintf (file, "%d", ~INTVAL (op));
-      return;
-
-    case 'K':                  /* Generate ldp(k) if direct address.  */
-      if (! TARGET_SMALL
-         && code == MEM
-         && GET_CODE (XEXP (op, 0)) == LO_SUM
-         && GET_CODE (XEXP (XEXP (op, 0), 0)) == REG
-         && REGNO (XEXP (XEXP (op, 0), 0)) == DP_REGNO)
-       {
-         op1 = XEXP (XEXP (op, 0), 1);
-          if (GET_CODE(op1) == CONST_INT || GET_CODE(op1) == SYMBOL_REF)
-           {
-             asm_fprintf (file, "\t%s\t@", TARGET_C3X ? "ldp" : "ldpk");
-             output_address (XEXP (adjust_address (op, VOIDmode, 1), 0));
-             asm_fprintf (file, "\n");
-           }
-       }
-      return;
-
-    case 'M':                  /* Generate ldp(k) if direct address.  */
-      if (! TARGET_SMALL       /* Only used in asm statements.  */
-         && code == MEM
-         && (GET_CODE (XEXP (op, 0)) == CONST
-             || GET_CODE (XEXP (op, 0)) == SYMBOL_REF))
-       {
-         asm_fprintf (file, "%s\t@", TARGET_C3X ? "ldp" : "ldpk");
-          output_address (XEXP (op, 0));
-         asm_fprintf (file, "\n\t");
-       }
-      return;
-
-    case 'O':                  /* Offset address.  */
-      if (code == MEM && c4x_autoinc_operand (op, Pmode))
-       break;
-      else if (code == MEM)
-       output_address (XEXP (adjust_address (op, VOIDmode, 1), 0));
-      else if (code == REG)
-       fprintf (file, "%s", reg_names[REGNO (op) + 1]);
-      else
-       fatal_insn ("c4x_print_operand: %%O inconsistency", op);
-      return;
-
-    case 'C':                  /* Call.  */
-      break;
-
-    case 'U':                  /* Call/callu.  */
-      if (code != SYMBOL_REF)
-       asm_fprintf (file, "u");
-      return;
-
-    default:
-      break;
-    }
-  
-  switch (code)
-    {
-    case REG:
-      if (GET_MODE_CLASS (GET_MODE (op)) == MODE_FLOAT
-         && ! TARGET_TI)
-       fprintf (file, "%s", float_reg_names[REGNO (op)]);
-      else
-       fprintf (file, "%s", reg_names[REGNO (op)]);
-      break;
-      
-    case MEM:
-      output_address (XEXP (op, 0));
-      break;
-      
-    case CONST_DOUBLE:
-      {
-       char str[30];
-       REAL_VALUE_TYPE r;
-       
-       REAL_VALUE_FROM_CONST_DOUBLE (r, op);
-       REAL_VALUE_TO_DECIMAL (r, "%20f", str);
-       fprintf (file, "%s", str);
-      }
-      break;
-      
-    case CONST_INT:
-      fprintf (file, "%d", INTVAL (op));
-      break;
-      
-    case NE:
-      asm_fprintf (file, "ne");
-      break;
-      
-    case EQ:
-      asm_fprintf (file, "eq");
-      break;
-      
-    case GE:
-      asm_fprintf (file, "ge");
-      break;
-
-    case GT:
-      asm_fprintf (file, "gt");
-      break;
-
-    case LE:
-      asm_fprintf (file, "le");
-      break;
-
-    case LT:
-      asm_fprintf (file, "lt");
-      break;
-
-    case GEU:
-      asm_fprintf (file, "hs");
-      break;
-
-    case GTU:
-      asm_fprintf (file, "hi");
-      break;
-
-    case LEU:
-      asm_fprintf (file, "ls");
-      break;
-
-    case LTU:
-      asm_fprintf (file, "lo");
-      break;
-
-    case SYMBOL_REF:
-      output_addr_const (file, op);
-      break;
-
-    case CONST:
-      output_addr_const (file, XEXP (op, 0));
-      break;
-
-    case CODE_LABEL:
-      break;
-
-    default:
-      fatal_insn ("c4x_print_operand: Bad operand case", op);
-      break;
-    }
-}
-
-
-void
-c4x_print_operand_address (file, addr)
-     FILE *file;
-     rtx addr;
-{
-  switch (GET_CODE (addr))
-    {
-    case REG:
-      fprintf (file, "*%s", reg_names[REGNO (addr)]);
-      break;
-
-    case PRE_DEC:
-      fprintf (file, "*--%s", reg_names[REGNO (XEXP (addr, 0))]);
-      break;
-
-    case POST_INC:
-      fprintf (file, "*%s++", reg_names[REGNO (XEXP (addr, 0))]);
-      break;
-
-    case POST_MODIFY:
-      {
-       rtx op0 = XEXP (XEXP (addr, 1), 0);
-       rtx op1 = XEXP (XEXP (addr, 1), 1);
-       
-       if (GET_CODE (XEXP (addr, 1)) == PLUS && REG_P (op1))
-         fprintf (file, "*%s++(%s)", reg_names[REGNO (op0)],
-                  reg_names[REGNO (op1)]);
-       else if (GET_CODE (XEXP (addr, 1)) == PLUS && INTVAL (op1) > 0)
-         fprintf (file, "*%s++(%d)", reg_names[REGNO (op0)],
-                  INTVAL (op1));
-       else if (GET_CODE (XEXP (addr, 1)) == PLUS && INTVAL (op1) < 0)
-         fprintf (file, "*%s--(%d)", reg_names[REGNO (op0)],
-                  -INTVAL (op1));
-       else if (GET_CODE (XEXP (addr, 1)) == MINUS && REG_P (op1))
-         fprintf (file, "*%s--(%s)", reg_names[REGNO (op0)],
-                  reg_names[REGNO (op1)]);
-       else
-         fatal_insn ("c4x_print_operand_address: Bad post_modify", addr);
-      }
-      break;
-      
-    case PRE_MODIFY:
-      {
-       rtx op0 = XEXP (XEXP (addr, 1), 0);
-       rtx op1 = XEXP (XEXP (addr, 1), 1);
-       
-       if (GET_CODE (XEXP (addr, 1)) == PLUS && REG_P (op1))
-         fprintf (file, "*++%s(%s)", reg_names[REGNO (op0)],
-                  reg_names[REGNO (op1)]);
-       else if (GET_CODE (XEXP (addr, 1)) == PLUS && INTVAL (op1) > 0)
-         fprintf (file, "*++%s(%d)", reg_names[REGNO (op0)],
-                  INTVAL (op1));
-       else if (GET_CODE (XEXP (addr, 1)) == PLUS && INTVAL (op1) < 0)
-         fprintf (file, "*--%s(%d)", reg_names[REGNO (op0)],
-                  -INTVAL (op1));
-       else if (GET_CODE (XEXP (addr, 1)) == MINUS && REG_P (op1))
-         fprintf (file, "*--%s(%s)", reg_names[REGNO (op0)],
-                  reg_names[REGNO (op1)]);
-       else
-         fatal_insn ("c4x_print_operand_address: Bad pre_modify", addr);
-      }
-      break;
-      
-    case PRE_INC:
-      fprintf (file, "*++%s", reg_names[REGNO (XEXP (addr, 0))]);
-      break;
-
-    case POST_DEC:
-      fprintf (file, "*%s--", reg_names[REGNO (XEXP (addr, 0))]);
-      break;
-
-    case PLUS:                 /* Indirect with displacement.  */
-      {
-       rtx op0 = XEXP (addr, 0);
-       rtx op1 = XEXP (addr, 1);
-
-       if (REG_P (op0))
-         {
-           if (REG_P (op1))
-             {
-               if (IS_INDEX_REG (op0))
-                 {
-                   fprintf (file, "*+%s(%s)",
-                            reg_names[REGNO (op1)],
-                            reg_names[REGNO (op0)]);   /* Index + base.  */
-                 }
-               else
-                 {
-                   fprintf (file, "*+%s(%s)",
-                            reg_names[REGNO (op0)],
-                            reg_names[REGNO (op1)]);   /* Base + index.  */
-                 }
-             }
-           else if (INTVAL (op1) < 0)
-             {
-               fprintf (file, "*-%s(%d)",
-                        reg_names[REGNO (op0)],
-                        -INTVAL (op1));        /* Base - displacement.  */
-             }
-           else
-             {
-               fprintf (file, "*+%s(%d)",
-                        reg_names[REGNO (op0)],
-                        INTVAL (op1)); /* Base + displacement.  */
-             }
-         }
-       else
-          fatal_insn ("c4x_print_operand_address: Bad operand case", addr);
-      }
-      break;
-
-    case LO_SUM:
-      {
-       rtx op0 = XEXP (addr, 0);
-       rtx op1 = XEXP (addr, 1);
-         
-       if (REG_P (op0) && REGNO (op0) == DP_REGNO)
-         c4x_print_operand_address (file, op1);
-       else
-          fatal_insn ("c4x_print_operand_address: Bad operand case", addr);
-      }
-      break;
-
-    case CONST:
-    case SYMBOL_REF:
-    case LABEL_REF:
-      fprintf (file, "@");
-      output_addr_const (file, addr);
-      break;
-
-      /* We shouldn't access CONST_INT addresses.  */
-    case CONST_INT:
-
-    default:
-      fatal_insn ("c4x_print_operand_address: Bad operand case", addr);
-      break;
-    }
-}
-
-
-/* Return nonzero if the floating point operand will fit
-   in the immediate field.  */
-
-static int
-c4x_immed_float_p (op)
-     rtx op;
-{
-  long convval[2];
-  int exponent;
-  REAL_VALUE_TYPE r;
-
-  REAL_VALUE_FROM_CONST_DOUBLE (r, op);
-  if (GET_MODE (op) == HFmode)
-    REAL_VALUE_TO_TARGET_DOUBLE (r, convval);
-  else
-    {
-      REAL_VALUE_TO_TARGET_SINGLE (r, convval[0]);
-      convval[1] = 0;
-    }
-
-  /* Sign extend exponent.  */
-  exponent = (((convval[0] >> 24) & 0xff) ^ 0x80) - 0x80;
-  if (exponent == -128)
-    return 1;                  /* 0.0  */
-  if ((convval[0] & 0x00000fff) != 0 || convval[1] != 0)
-    return 0;                  /* Precision doesn't fit.  */
-  return (exponent <= 7)       /* Positive exp.  */
-    && (exponent >= -7);       /* Negative exp.  */
-}
-
-
-/* The last instruction in a repeat block cannot be a Bcond, DBcound,
-   CALL, CALLCond, TRAPcond, RETIcond, RETScond, IDLE, RPTB or RPTS.
-
-   None of the last four instructions from the bottom of the block can
-   be a BcondD, BRD, DBcondD, RPTBD, LAJ, LAJcond, LATcond, BcondAF,
-   BcondAT or RETIcondD.
-
-   This routine scans the four previous insns for a jump insn, and if
-   one is found, returns 1 so that we bung in a nop instruction.
-   This simple minded strategy will add a nop, when it may not
-   be required.  Say when there is a JUMP_INSN near the end of the
-   block that doesn't get converted into a delayed branch.
-
-   Note that we cannot have a call insn, since we don't generate
-   repeat loops with calls in them (although I suppose we could, but
-   there's no benefit.)  
-
-   !!! FIXME.  The rptb_top insn may be sucked into a SEQUENCE.  */
-
-int
-c4x_rptb_nop_p (insn)
-     rtx insn;
-{
-  rtx start_label;
-  int i;
-
-  /* Extract the start label from the jump pattern (rptb_end).  */
-  start_label = XEXP (XEXP (SET_SRC (XVECEXP (PATTERN (insn), 0, 0)), 1), 0);
-
-  /* If there is a label at the end of the loop we must insert
-     a NOP.  */
-  do {
-    insn = previous_insn (insn);
-  } while (GET_CODE (insn) == NOTE
-          || GET_CODE (insn) == USE
-          || GET_CODE (insn) == CLOBBER);
-  if (GET_CODE (insn) == CODE_LABEL)
-    return 1;
-
-  for (i = 0; i < 4; i++)
-    {
-      /* Search back for prev non-note and non-label insn.  */
-      while (GET_CODE (insn) == NOTE || GET_CODE (insn) == CODE_LABEL
-            || GET_CODE (insn) == USE || GET_CODE (insn) == CLOBBER)
-       {
-         if (insn == start_label)
-           return i == 0;
-
-         insn = previous_insn (insn);
-       };
-
-      /* If we have a jump instruction we should insert a NOP. If we
-        hit repeat block top we should only insert a NOP if the loop
-        is empty.  */
-      if (GET_CODE (insn) == JUMP_INSN)
-       return 1;
-      insn = previous_insn (insn);
-    }
-  return 0;
-}
-
-
-/* The C4x looping instruction needs to be emitted at the top of the
-  loop.  Emitting the true RTL for a looping instruction at the top of
-  the loop can cause problems with flow analysis.  So instead, a dummy
-  doloop insn is emitted at the end of the loop.  This routine checks
-  for the presence of this doloop insn and then searches back to the
-  top of the loop, where it inserts the true looping insn (provided
-  there are no instructions in the loop which would cause problems).
-  Any additional labels can be emitted at this point.  In addition, if
-  the desired loop count register was not allocated, this routine does
-  nothing. 
-
-  Before we can create a repeat block looping instruction we have to
-  verify that there are no jumps outside the loop and no jumps outside
-  the loop go into this loop. This can happen in the basic blocks reorder
-  pass. The C4x cpu can not handle this.  */
-
-static int
-c4x_label_ref_used_p (x, code_label)
-     rtx x, code_label;
-{
-  enum rtx_code code;
-  int i, j;
-  const char *fmt;
-
-  if (x == 0)
-    return 0;
-
-  code = GET_CODE (x);
-  if (code == LABEL_REF)
-    return INSN_UID (XEXP (x,0)) == INSN_UID (code_label);
-
-  fmt = GET_RTX_FORMAT (code);
-  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
-    {
-      if (fmt[i] == 'e')
-       {
-          if (c4x_label_ref_used_p (XEXP (x, i), code_label))
-           return 1;
-       }
-      else if (fmt[i] == 'E')
-        for (j = XVECLEN (x, i) - 1; j >= 0; j--)
-          if (c4x_label_ref_used_p (XVECEXP (x, i, j), code_label))
-           return 1;
-    }
-  return 0;
-}
-
-
-static int
-c4x_rptb_valid_p (insn, start_label)
-     rtx insn, start_label;
-{
-  rtx end = insn;
-  rtx start;
-  rtx tmp;
-
-  /* Find the start label.  */
-  for (; insn; insn = PREV_INSN (insn))
-    if (insn == start_label)
-      break;
-
-  /* Note found then we can not use a rptb or rpts.  The label was
-     probably moved by the basic block reorder pass.  */
-  if (! insn)
-    return 0;
-
-  start = insn;
-  /* If any jump jumps inside this block then we must fail.  */
-  for (insn = PREV_INSN (start); insn; insn = PREV_INSN (insn))
-    {
-      if (GET_CODE (insn) == CODE_LABEL)
-       {
-         for (tmp = NEXT_INSN (start); tmp != end; tmp = NEXT_INSN(tmp))
-           if (GET_CODE (tmp) == JUMP_INSN
-                && c4x_label_ref_used_p (tmp, insn))
-             return 0;
-        }
-    }
-  for (insn = NEXT_INSN (end); insn; insn = NEXT_INSN (insn))
-    {
-      if (GET_CODE (insn) == CODE_LABEL)
-       {
-         for (tmp = NEXT_INSN (start); tmp != end; tmp = NEXT_INSN(tmp))
-           if (GET_CODE (tmp) == JUMP_INSN
-                && c4x_label_ref_used_p (tmp, insn))
-             return 0;
-        }
-    }
-  /* If any jump jumps outside this block then we must fail.  */
-  for (insn = NEXT_INSN (start); insn != end; insn = NEXT_INSN (insn))
-    {
-      if (GET_CODE (insn) == CODE_LABEL)
-       {
-         for (tmp = NEXT_INSN (end); tmp; tmp = NEXT_INSN(tmp))
-           if (GET_CODE (tmp) == JUMP_INSN
-                && c4x_label_ref_used_p (tmp, insn))
-             return 0;
-         for (tmp = PREV_INSN (start); tmp; tmp = PREV_INSN(tmp))
-           if (GET_CODE (tmp) == JUMP_INSN
-                && c4x_label_ref_used_p (tmp, insn))
-             return 0;
-        }
-    }
-
-  /* All checks OK.  */
-  return 1;
-}
-
-
-void
-c4x_rptb_insert (insn)
-     rtx insn;
-{
-  rtx end_label;
-  rtx start_label;
-  rtx new_start_label;
-  rtx count_reg;
-
-  /* If the count register has not been allocated to RC, say if
-     there is a movstr pattern in the loop, then do not insert a
-     RPTB instruction.  Instead we emit a decrement and branch
-     at the end of the loop.  */
-  count_reg = XEXP (XEXP (SET_SRC (XVECEXP (PATTERN (insn), 0, 0)), 0), 0);
-  if (REGNO (count_reg) != RC_REGNO)
-    return;
-
-  /* Extract the start label from the jump pattern (rptb_end).  */
-  start_label = XEXP (XEXP (SET_SRC (XVECEXP (PATTERN (insn), 0, 0)), 1), 0);
-  
-  if (! c4x_rptb_valid_p (insn, start_label))
-    {
-      /* We can not use the rptb insn.  Replace it so reorg can use
-         the delay slots of the jump insn.  */
-      emit_insn_before (gen_addqi3 (count_reg, count_reg, GEN_INT (-1)), insn);
-      emit_insn_before (gen_cmpqi (count_reg, GEN_INT (0)), insn);
-      emit_insn_before (gen_bge (start_label), insn);
-      LABEL_NUSES (start_label)++;
-      delete_insn (insn);
-      return;
-    }
-
-  end_label = gen_label_rtx ();
-  LABEL_NUSES (end_label)++;
-  emit_label_after (end_label, insn);
-
-  new_start_label = gen_label_rtx ();
-  LABEL_NUSES (new_start_label)++;
-
-  for (; insn; insn = PREV_INSN (insn))
-    {
-      if (insn == start_label)
-        break;
-      if (GET_CODE (insn) == JUMP_INSN &&
-         JUMP_LABEL (insn) == start_label)
-       redirect_jump (insn, new_start_label, 0);
-    }
-  if (! insn)
-    fatal_insn ("c4x_rptb_insert: Cannot find start label", start_label);
-
-  emit_label_after (new_start_label, insn);
-
-  if (TARGET_RPTS && c4x_rptb_rpts_p (PREV_INSN (insn), 0))
-    emit_insn_after (gen_rpts_top (new_start_label, end_label), insn);
-  else
-    emit_insn_after (gen_rptb_top (new_start_label, end_label), insn);
-  if (LABEL_NUSES (start_label) == 0)
-    delete_insn (start_label);
-}
-
-
-/* This function is a C4x special called immediately before delayed
-   branch scheduling.  We fix up RTPB style loops that didn't get RC
-   allocated as the loop counter.  */
-
-void
-c4x_process_after_reload (first)
-     rtx first;
-{
-  rtx insn;
-
-  for (insn = first; insn; insn = NEXT_INSN (insn))
-    {
-      /* Look for insn.  */
-      if (INSN_P (insn))
-       {
-         int insn_code_number;
-         rtx old;
-
-         insn_code_number = recog_memoized (insn);
-
-         if (insn_code_number < 0)
-           continue;
-
-         /* Insert the RTX for RPTB at the top of the loop
-            and a label at the end of the loop.  */
-         if (insn_code_number == CODE_FOR_rptb_end)
-           c4x_rptb_insert(insn);
-
-         /* We need to split the insn here. Otherwise the calls to
-            force_const_mem will not work for load_immed_address.  */
-         old = insn;
-
-         /* Don't split the insn if it has been deleted.  */
-         if (! INSN_DELETED_P (old))
-           insn = try_split (PATTERN(old), old, 1);
-
-         /* When not optimizing, the old insn will be still left around
-            with only the 'deleted' bit set.  Transform it into a note
-            to avoid confusion of subsequent processing.  */
-         if (INSN_DELETED_P (old))
-           {
-             PUT_CODE (old, NOTE);
-             NOTE_LINE_NUMBER (old) = NOTE_INSN_DELETED;
-             NOTE_SOURCE_FILE (old) = 0;
-           }
-       }
-    }
-}
-
-
-static int
-c4x_a_register (op)
-     rtx op;
-{
-  return REG_P (op) && IS_ADDR_OR_PSEUDO_REG (op);
-}
-
-
-static int
-c4x_x_register (op)
-     rtx op;
-{
-  return REG_P (op) && IS_INDEX_OR_PSEUDO_REG (op);
-}
-
-
-static int
-c4x_immed_int_constant (op)
-     rtx op;
-{
-  if (GET_CODE (op) != CONST_INT)
-    return 0;
-
-  return GET_MODE (op) == VOIDmode
-    || GET_MODE_CLASS (op) == MODE_INT
-    || GET_MODE_CLASS (op) == MODE_PARTIAL_INT;
-}
-
-
-static int
-c4x_immed_float_constant (op)
-     rtx op;
-{
-  if (GET_CODE (op) != CONST_DOUBLE)
-    return 0;
-
-  /* Do not check if the CONST_DOUBLE is in memory. If there is a MEM
-     present this only means that a MEM rtx has been generated. It does
-     not mean the rtx is really in memory.  */
-
-  return GET_MODE (op) == QFmode || GET_MODE (op) == HFmode;
-}
-
-
-int
-c4x_shiftable_constant (op)
-     rtx op;
-{
-  int i;
-  int mask;
-  int val = INTVAL (op);
-
-  for (i = 0; i < 16; i++)
-    {
-      if (val & (1 << i))
-       break;
-    }
-  mask = ((0xffff >> i) << 16) | 0xffff;
-  if (IS_INT16_CONST (val & (1 << 31) ? (val >> i) | ~mask
-                                     : (val >> i) & mask))
-    return i;
-  return -1;
-} 
-
-
-int
-c4x_H_constant (op)
-     rtx op;
-{
-  return c4x_immed_float_constant (op) && c4x_immed_float_p (op);
-}
-
-
-int
-c4x_I_constant (op)
-     rtx op;
-{
-  return c4x_immed_int_constant (op) && IS_INT16_CONST (INTVAL (op));
-}
-
-
-int
-c4x_J_constant (op)
-     rtx op;
-{
-  if (TARGET_C3X)
-    return 0;
-  return c4x_immed_int_constant (op) && IS_INT8_CONST (INTVAL (op));
-}
-
-
-static int
-c4x_K_constant (op)
-     rtx op;
-{
-  if (TARGET_C3X || ! c4x_immed_int_constant (op))
-    return 0;
-  return IS_INT5_CONST (INTVAL (op));
-}
-
-
-int
-c4x_L_constant (op)
-     rtx op;
-{
-  return c4x_immed_int_constant (op) && IS_UINT16_CONST (INTVAL (op));
-}
-
-
-static int
-c4x_N_constant (op)
-     rtx op;
-{
-  return c4x_immed_int_constant (op) && IS_NOT_UINT16_CONST (INTVAL (op));
-}
-
-
-static int
-c4x_O_constant (op)
-     rtx op;
-{
-  return c4x_immed_int_constant (op) && IS_HIGH_CONST (INTVAL (op));
-}
-
-
-/* The constraints do not have to check the register class,
-   except when needed to discriminate between the constraints.
-   The operand has been checked by the predicates to be valid.  */
-
-/* ARx + 9-bit signed const or IRn
-   *ARx, *+ARx(n), *-ARx(n), *+ARx(IRn), *-Arx(IRn) for -256 < n < 256
-   We don't include the pre/post inc/dec forms here since
-   they are handled by the <> constraints.  */
-
-int
-c4x_Q_constraint (op)
-     rtx op;
-{
-  enum machine_mode mode = GET_MODE (op);
-
-  if (GET_CODE (op) != MEM)
-    return 0;
-  op = XEXP (op, 0);
-  switch (GET_CODE (op))
-    {
-    case REG:
-      return 1;
-
-    case PLUS:
-      {
-       rtx op0 = XEXP (op, 0);
-       rtx op1 = XEXP (op, 1);
-
-       if (! REG_P (op0))
-         return 0;
-
-       if (REG_P (op1))
-         return 1;
-
-       if (GET_CODE (op1) != CONST_INT)
-         return 0;
-
-       /* HImode and HFmode must be offsettable.  */
-       if (mode == HImode || mode == HFmode)
-         return IS_DISP8_OFF_CONST (INTVAL (op1));
-       
-       return IS_DISP8_CONST (INTVAL (op1));
-      }
-      break;
-
-    default:
-      break;
-    }
-  return 0;
-}
-
-
-/* ARx + 5-bit unsigned const
-   *ARx, *+ARx(n) for n < 32.  */
-
-int
-c4x_R_constraint (op)
-     rtx op;
-{
-  enum machine_mode mode = GET_MODE (op);
-
-  if (TARGET_C3X)
-    return 0;
-  if (GET_CODE (op) != MEM)
-    return 0;
-  op = XEXP (op, 0);
-  switch (GET_CODE (op))
-    {
-    case REG:
-      return 1;
-
-    case PLUS:
-      {
-       rtx op0 = XEXP (op, 0);
-       rtx op1 = XEXP (op, 1);
-
-       if (! REG_P (op0))
-         return 0;
-
-       if (GET_CODE (op1) != CONST_INT)
-         return 0;
-
-       /* HImode and HFmode must be offsettable.  */
-       if (mode == HImode || mode == HFmode)
-         return IS_UINT5_CONST (INTVAL (op1) + 1);
-       
-       return IS_UINT5_CONST (INTVAL (op1));
-      }
-      break;
-
-    default:
-      break;
-    }
-  return 0;
-}
-
-
-static int
-c4x_R_indirect (op)
-     rtx op;
-{
-  enum machine_mode mode = GET_MODE (op);
-
-  if (TARGET_C3X || GET_CODE (op) != MEM)
-    return 0;
-
-  op = XEXP (op, 0);
-  switch (GET_CODE (op))
-    {
-    case REG:
-      return IS_ADDR_OR_PSEUDO_REG (op);
-
-    case PLUS:
-      {
-       rtx op0 = XEXP (op, 0);
-       rtx op1 = XEXP (op, 1);
-
-       /* HImode and HFmode must be offsettable.  */
-       if (mode == HImode || mode == HFmode)
-         return IS_ADDR_OR_PSEUDO_REG (op0)
-           && GET_CODE (op1) == CONST_INT 
-           && IS_UINT5_CONST (INTVAL (op1) + 1);
-
-       return REG_P (op0)
-         && IS_ADDR_OR_PSEUDO_REG (op0)
-         && GET_CODE (op1) == CONST_INT
-         && IS_UINT5_CONST (INTVAL (op1));
-      }
-      break;
-
-    default:
-      break;
-    }
-  return 0;
-}
-
-
-/* ARx + 1-bit unsigned const or IRn
-   *ARx, *+ARx(1), *-ARx(1), *+ARx(IRn), *-Arx(IRn)
-   We don't include the pre/post inc/dec forms here since
-   they are handled by the <> constraints.  */
-
-int
-c4x_S_constraint (op)
-     rtx op;
-{
-  enum machine_mode mode = GET_MODE (op);
-  if (GET_CODE (op) != MEM)
-    return 0;
-  op = XEXP (op, 0);
-  switch (GET_CODE (op))
-    {
-    case REG:
-      return 1;
-
-    case PRE_MODIFY:
-    case POST_MODIFY:
-      {
-       rtx op0 = XEXP (op, 0);
-       rtx op1 = XEXP (op, 1);
-       
-       if ((GET_CODE (op1) != PLUS && GET_CODE (op1) != MINUS)
-           || (op0 != XEXP (op1, 0)))
-         return 0;
-       
-       op0 = XEXP (op1, 0);
-       op1 = XEXP (op1, 1);
-       return REG_P (op0) && REG_P (op1);
-       /* Pre or post_modify with a displacement of 0 or 1 
-          should not be generated.  */
-      }
-      break;
-
-    case PLUS:
-      {
-       rtx op0 = XEXP (op, 0);
-       rtx op1 = XEXP (op, 1);
-
-       if (!REG_P (op0))
-         return 0;
-
-       if (REG_P (op1))
-         return 1;
-
-       if (GET_CODE (op1) != CONST_INT)
-         return 0;
-       
-       /* HImode and HFmode must be offsettable.  */
-       if (mode == HImode || mode == HFmode)
-         return IS_DISP1_OFF_CONST (INTVAL (op1));
-       
-       return IS_DISP1_CONST (INTVAL (op1));
-      }
-      break;
-
-    default:
-      break;
-    }
-  return 0;
-}
-
-
-static int
-c4x_S_indirect (op)
-     rtx op;
-{
-  enum machine_mode mode = GET_MODE (op);
-  if (GET_CODE (op) != MEM)
-    return 0;
-
-  op = XEXP (op, 0);
-  switch (GET_CODE (op))
-    {
-    case PRE_DEC:
-    case POST_DEC:
-      if (mode != QImode && mode != QFmode)
-       return 0;
-    case PRE_INC:
-    case POST_INC:
-      op = XEXP (op, 0);
-
-    case REG:
-      return IS_ADDR_OR_PSEUDO_REG (op);
-
-    case PRE_MODIFY:
-    case POST_MODIFY:
-      {
-       rtx op0 = XEXP (op, 0);
-       rtx op1 = XEXP (op, 1);
-       
-       if (mode != QImode && mode != QFmode)
-         return 0;
-
-       if ((GET_CODE (op1) != PLUS && GET_CODE (op1) != MINUS)
-           || (op0 != XEXP (op1, 0)))
-         return 0;
-       
-       op0 = XEXP (op1, 0);
-       op1 = XEXP (op1, 1);
-       return REG_P (op0) && IS_ADDR_OR_PSEUDO_REG (op0)
-         && REG_P (op1) && IS_INDEX_OR_PSEUDO_REG (op1);
-       /* Pre or post_modify with a displacement of 0 or 1 
-          should not be generated.  */
-      }
-
-    case PLUS:
-      {
-       rtx op0 = XEXP (op, 0);
-       rtx op1 = XEXP (op, 1);
-
-       if (REG_P (op0))
-         {
-           /* HImode and HFmode must be offsettable.  */
-           if (mode == HImode || mode == HFmode)
-             return IS_ADDR_OR_PSEUDO_REG (op0)
-               && GET_CODE (op1) == CONST_INT 
-               && IS_DISP1_OFF_CONST (INTVAL (op1));
-
-           if (REG_P (op1))
-             return (IS_INDEX_OR_PSEUDO_REG (op1)
-                     && IS_ADDR_OR_PSEUDO_REG (op0))
-               || (IS_ADDR_OR_PSEUDO_REG (op1)
-                   && IS_INDEX_OR_PSEUDO_REG (op0));
-           
-           return IS_ADDR_OR_PSEUDO_REG (op0)
-             && GET_CODE (op1) == CONST_INT 
-             && IS_DISP1_CONST (INTVAL (op1));
-         }
-      }
-      break;
-
-    default:
-      break;
-    }
-  return 0;
-}
-
-
-/* Direct memory operand.  */
-
-int
-c4x_T_constraint (op)
-     rtx op;
-{
-  if (GET_CODE (op) != MEM)
-    return 0;
-  op = XEXP (op, 0);
-
-  if (GET_CODE (op) != LO_SUM)
-    {
-      /* Allow call operands.  */
-      return GET_CODE (op) == SYMBOL_REF
-       && GET_MODE (op) == Pmode
-       && SYMBOL_REF_FLAG (op);
-    }
-
-  /* HImode and HFmode are not offsettable.  */
-  if (GET_MODE (op) == HImode || GET_CODE (op) == HFmode)
-    return 0;
-
-  if ((GET_CODE (XEXP (op, 0)) == REG)
-      && (REGNO (XEXP (op, 0)) == DP_REGNO))
-    return c4x_U_constraint (XEXP (op, 1));
-  
-  return 0;
-}
-
-
-/* Symbolic operand.  */
-
-int
-c4x_U_constraint (op)
-     rtx op;
-{
-  /* Don't allow direct addressing to an arbitrary constant.  */
-  return GET_CODE (op) == CONST
-        || GET_CODE (op) == SYMBOL_REF
-        || GET_CODE (op) == LABEL_REF;
-}
-
-
-int
-c4x_autoinc_operand (op, mode)
-     rtx op;
-     enum machine_mode mode ATTRIBUTE_UNUSED;
-{
-  if (GET_CODE (op) == MEM)
-    {
-      enum rtx_code code = GET_CODE (XEXP (op, 0));
-      
-      if (code == PRE_INC
-         || code == PRE_DEC
-         || code == POST_INC
-         || code == POST_DEC
-         || code == PRE_MODIFY
-         || code == POST_MODIFY
-         )
-       return 1;
-    }
-  return 0;
-}
-
-
-/* Match any operand.  */
-
-int
-any_operand (op, mode)
-     register rtx op ATTRIBUTE_UNUSED;
-     enum machine_mode mode ATTRIBUTE_UNUSED;
-{
-  return 1;
-}
-
-
-/* Nonzero if OP is a floating point value with value 0.0.  */
-
-int
-fp_zero_operand (op, mode)
-     rtx op;
-     enum machine_mode mode ATTRIBUTE_UNUSED;
-{
-  REAL_VALUE_TYPE r;
-
-  if (GET_CODE (op) != CONST_DOUBLE)
-    return 0;
-  REAL_VALUE_FROM_CONST_DOUBLE (r, op);
-  return REAL_VALUES_EQUAL (r, dconst0);
-}
-
-
-int
-const_operand (op, mode)
-     register rtx op;
-     register enum machine_mode mode;
-{
-  switch (mode)
-    {
-    case QFmode:
-    case HFmode:
-      if (GET_CODE (op) != CONST_DOUBLE
-         || GET_MODE (op) != mode
-         || GET_MODE_CLASS (mode) != MODE_FLOAT)
-       return 0;
-
-      return c4x_immed_float_p (op);
-
-#if Pmode != QImode
-    case Pmode:
-#endif
-    case QImode:
-      if (GET_CODE (op) == CONSTANT_P_RTX)
-       return 1;
-
-      if (GET_CODE (op) != CONST_INT
-         || (GET_MODE (op) != VOIDmode && GET_MODE (op) != mode)
-         || GET_MODE_CLASS (mode) != MODE_INT)
-       return 0;
-
-      return IS_HIGH_CONST (INTVAL (op)) || IS_INT16_CONST (INTVAL (op));
-
-    case HImode:
-      return 0;
-
-    default:
-      return 0;
-    }
-}
-
-
-int
-stik_const_operand (op, mode)
-     rtx op;
-     enum machine_mode mode ATTRIBUTE_UNUSED;
-{
-  return c4x_K_constant (op);
-}
-
-
-int
-not_const_operand (op, mode)
-     rtx op;
-     enum machine_mode mode ATTRIBUTE_UNUSED;
-{
-  return c4x_N_constant (op);
-}
-
-
-int
-reg_operand (op, mode)
-     rtx op;
-     enum machine_mode mode;
-{
-  if (GET_CODE (op) == SUBREG
-      && GET_MODE (op) == QFmode)
-    return 0;
-  return register_operand (op, mode);
-}
-
-
-int
-mixed_subreg_operand (op, mode)
-     rtx op;
-     enum machine_mode mode ATTRIBUTE_UNUSED;
-{
-  /* Allow (subreg:HF (reg:HI)) that be generated for a union of an
-     int and a long double.  */
-  if (GET_CODE (op) == SUBREG
-      && (GET_MODE (op) == QFmode)
-      && (GET_MODE (SUBREG_REG (op)) == QImode
-         || GET_MODE (SUBREG_REG (op)) == HImode))
-    return 1;
-  return 0;
-}
-
-
-int
-reg_imm_operand (op, mode)
-     rtx op;
-     enum machine_mode mode ATTRIBUTE_UNUSED;
-{
-  if (REG_P (op) || CONSTANT_P (op))
-    return 1;
-  return 0;
-}
-
-
-int
-not_modify_reg (op, mode)
-     rtx op;
-     enum machine_mode mode ATTRIBUTE_UNUSED;
-{
-  if (REG_P (op) || CONSTANT_P (op))
-    return 1;
-  if (GET_CODE (op) != MEM)
-    return 0;
-  op = XEXP (op, 0);
-  switch (GET_CODE (op))
-    {
-    case REG:
-      return 1;
-
-    case PLUS:
-      {
-       rtx op0 = XEXP (op, 0);
-       rtx op1 = XEXP (op, 1);
-
-       if (! REG_P (op0))
-         return 0;
-       
-       if (REG_P (op1) || GET_CODE (op1) == CONST_INT)
-         return 1;
-      }
-
-    case LO_SUM:
-      {
-       rtx op0 = XEXP (op, 0);
-         
-       if (REG_P (op0) && REGNO (op0) == DP_REGNO)
-         return 1;
-      }
-      break;
-     
-    case CONST:
-    case SYMBOL_REF:
-    case LABEL_REF:
-      return 1;
-
-    default:
-      break;
-    }
-  return 0;
-}
-
-
-int
-not_rc_reg (op, mode)
-     rtx op;
-     enum machine_mode mode ATTRIBUTE_UNUSED;
-{
-  if (REG_P (op) && REGNO (op) == RC_REGNO)
-    return 0;
-  return 1;
-}
-
-
-/* Extended precision register R0-R1.  */
-
-int
-r0r1_reg_operand (op, mode)
-     rtx op;
-     enum machine_mode mode;
-{
-  if (! reg_operand (op, mode))
-    return 0;
-  if (GET_CODE (op) == SUBREG)
-    op = SUBREG_REG (op);
-  return REG_P (op) && IS_R0R1_OR_PSEUDO_REG (op);
-}
-
-
-/* Extended precision register R2-R3.  */
-
-int
-r2r3_reg_operand (op, mode)
-     rtx op;
-     enum machine_mode mode;
-{
-  if (! reg_operand (op, mode))
-    return 0;
-  if (GET_CODE (op) == SUBREG)
-    op = SUBREG_REG (op);
-  return REG_P (op) && IS_R2R3_OR_PSEUDO_REG (op);
-}
-
-
-/* Low extended precision register R0-R7.  */
-
-int
-ext_low_reg_operand (op, mode)
-     rtx op;
-     enum machine_mode mode;
-{
-  if (! reg_operand (op, mode))
-    return 0;
-  if (GET_CODE (op) == SUBREG)
-    op = SUBREG_REG (op);
-  return REG_P (op) && IS_EXT_LOW_OR_PSEUDO_REG (op);
-}
-
-
-/* Extended precision register.  */
-
-int
-ext_reg_operand (op, mode)
-     rtx op;
-     enum machine_mode mode;
-{
-  if (! reg_operand (op, mode))
-    return 0;
-  if (GET_CODE (op) == SUBREG)
-    op = SUBREG_REG (op);
-  if (! REG_P (op))
-    return 0;
-  return IS_EXT_OR_PSEUDO_REG (op);
-}
-
-
-/* Standard precision register.  */
-
-int
-std_reg_operand (op, mode)
-     rtx op;
-     enum machine_mode mode;
-{
-  if (! reg_operand (op, mode))
-    return 0;
-  if (GET_CODE (op) == SUBREG)
-    op = SUBREG_REG (op);
-  return REG_P (op) && IS_STD_OR_PSEUDO_REG (op);
-}
-
-/* Standard precision or normal register.  */
-
-int
-std_or_reg_operand (op, mode)
-     rtx op;
-     enum machine_mode mode;
-{
-  if (reload_in_progress)
-    return std_reg_operand (op, mode);
-  return reg_operand (op, mode);
-}
-
-/* Address register.  */
-
-int
-addr_reg_operand (op, mode)
-     rtx op;
-     enum machine_mode mode;
-{
-  if (! reg_operand (op, mode))
-    return 0;
-  return c4x_a_register (op);
-}
-
-
-/* Index register.  */
-
-int
-index_reg_operand (op, mode)
-     rtx op;
-     enum machine_mode mode;
-{
-  if (! reg_operand (op, mode))
-    return 0;
-  if (GET_CODE (op) == SUBREG)
-    op = SUBREG_REG (op);
-  return c4x_x_register (op);
-}
-
-
-/* DP register.  */
-
-int
-dp_reg_operand (op, mode)
-     rtx op;
-     enum machine_mode mode ATTRIBUTE_UNUSED;
-{
-  return REG_P (op) && IS_DP_OR_PSEUDO_REG (op);
-}
-
-
-/* SP register.  */
-
-int
-sp_reg_operand (op, mode)
-     rtx op;
-     enum machine_mode mode ATTRIBUTE_UNUSED;
-{
-  return REG_P (op) && IS_SP_OR_PSEUDO_REG (op);
-}
-
-
-/* ST register.  */
-
-int
-st_reg_operand (op, mode)
-     register rtx op;
-     enum machine_mode mode ATTRIBUTE_UNUSED;
-{
-  return REG_P (op) && IS_ST_OR_PSEUDO_REG (op);
-}
-
-
-/* RC register.  */
-
-int
-rc_reg_operand (op, mode)
-     register rtx op;
-     enum machine_mode mode ATTRIBUTE_UNUSED;
-{
-  return REG_P (op) && IS_RC_OR_PSEUDO_REG (op);
-}
-
-
-int
-call_address_operand (op, mode)
-     rtx op;
-     enum machine_mode mode ATTRIBUTE_UNUSED;
-{
-  return (REG_P (op) || symbolic_address_operand (op, mode));
-}
-
-
-/* Symbolic address operand.  */
-
-int
-symbolic_address_operand (op, mode)
-     register rtx op;
-     enum machine_mode mode ATTRIBUTE_UNUSED;
-{
-  switch (GET_CODE (op))
-    {
-    case CONST:
-    case SYMBOL_REF:
-    case LABEL_REF:
-      return 1;
-    default:
-      return 0;
-    }
-}
-
-
-/* Check dst operand of a move instruction.  */
-
-int
-dst_operand (op, mode)
-     rtx op;
-     enum machine_mode mode;
-{
-  if (GET_CODE (op) == SUBREG
-      && mixed_subreg_operand (op, mode))
-    return 0;
-
-  if (REG_P (op))
-    return reg_operand (op, mode);
-
-  return nonimmediate_operand (op, mode);
-}
-
-
-/* Check src operand of two operand arithmetic instructions.  */
-
-int
-src_operand (op, mode)
-     rtx op;
-     enum machine_mode mode;
-{
-  if (GET_CODE (op) == SUBREG
-      && mixed_subreg_operand (op, mode))
-    return 0;
-
-  if (REG_P (op))
-    return reg_operand (op, mode);
-
-  if (mode == VOIDmode)
-    mode = GET_MODE (op);
-
-  if (GET_CODE (op) == CONST_INT)
-    return (mode == QImode || mode == Pmode || mode == HImode)
-      && c4x_I_constant (op);
-
-  /* We don't like CONST_DOUBLE integers.  */
-  if (GET_CODE (op) == CONST_DOUBLE)
-    return c4x_H_constant (op);
-
-  /* Disallow symbolic addresses.  Only the predicate
-     symbolic_address_operand will match these.  */
-  if (GET_CODE (op) == SYMBOL_REF
-      || GET_CODE (op) == LABEL_REF
-      || GET_CODE (op) == CONST)
-    return 0;
-
-  /* If TARGET_LOAD_DIRECT_MEMS is non-zero, disallow direct memory
-     access to symbolic addresses.  These operands will get forced
-     into a register and the movqi expander will generate a
-     HIGH/LO_SUM pair if TARGET_EXPOSE_LDP is non-zero.  */
-  if (GET_CODE (op) == MEM
-      && ((GET_CODE (XEXP (op, 0)) == SYMBOL_REF
-          || GET_CODE (XEXP (op, 0)) == LABEL_REF
-          || GET_CODE (XEXP (op, 0)) == CONST)))
-    return ! TARGET_LOAD_DIRECT_MEMS && GET_MODE (op) == mode;
-
-  return general_operand (op, mode);
-}
-
-
-int
-src_hi_operand (op, mode)
-     rtx op;
-     enum machine_mode mode;
-{
-  if (c4x_O_constant (op))
-    return 1;
-  return src_operand (op, mode);
-}
-
-
-/* Check src operand of two operand logical instructions.  */
-
-int
-lsrc_operand (op, mode)
-     rtx op;
-     enum machine_mode mode;
-{
-  if (mode == VOIDmode)
-    mode = GET_MODE (op);
-
-  if (mode != QImode && mode != Pmode)
-    fatal_insn ("mode not QImode", op);
-
-  if (GET_CODE (op) == CONST_INT)
-    return c4x_L_constant (op) || c4x_J_constant (op);
-
-  return src_operand (op, mode);
-}
-
-
-/* Check src operand of two operand tricky instructions.  */
-
-int
-tsrc_operand (op, mode)
-     rtx op;
-     enum machine_mode mode;
-{
-  if (mode == VOIDmode)
-    mode = GET_MODE (op);
-
-  if (mode != QImode && mode != Pmode)
-    fatal_insn ("mode not QImode", op);
-
-  if (GET_CODE (op) == CONST_INT)
-    return c4x_L_constant (op) || c4x_N_constant (op) || c4x_J_constant (op);
-
-  return src_operand (op, mode);
-}
-
-
-int
-reg_or_const_operand (op, mode)
-     rtx op;
-     enum machine_mode mode;
-{
-  return reg_operand (op, mode) || const_operand (op, mode);
-}
-
-
-/* Check for indirect operands allowable in parallel instruction.  */
-
-int
-par_ind_operand (op, mode)
-     rtx op;
-     enum machine_mode mode;
-{
-  if (mode != VOIDmode && mode != GET_MODE (op))
-    return 0;
-
-  return c4x_S_indirect (op);
-}
-
-
-/* Check for operands allowable in parallel instruction.  */
-
-int
-parallel_operand (op, mode)
-     rtx op;
-     enum machine_mode mode;
-{
-  return ext_low_reg_operand (op, mode) || par_ind_operand (op, mode);
-}
-
-
-static void 
-c4x_S_address_parse (op, base, incdec, index, disp)
-     rtx op;
-     int *base;
-     int *incdec;
-     int *index;
-     int *disp;
-{
-  *base = 0;
-  *incdec = 0;
-  *index = 0;
-  *disp = 0;
-       
-  if (GET_CODE (op) != MEM)
-    fatal_insn ("invalid indirect memory address", op);
-  
-  op = XEXP (op, 0);
-  switch (GET_CODE (op))
-    {
-    case PRE_DEC:
-      *base = REGNO (XEXP (op, 0));
-      *incdec = 1;
-      *disp = -1;
-      return;
-
-    case POST_DEC:
-      *base = REGNO (XEXP (op, 0));
-      *incdec = 1;
-      *disp = 0;
-      return;
-
-    case PRE_INC:
-      *base = REGNO (XEXP (op, 0));
-      *incdec = 1;
-      *disp = 1;
-      return;
-
-    case POST_INC:
-      *base = REGNO (XEXP (op, 0));
-      *incdec = 1;
-      *disp = 0;
-      return;
-
-    case POST_MODIFY:
-      *base = REGNO (XEXP (op, 0));
-      if (REG_P (XEXP (XEXP (op, 1), 1)))
-       {
-         *index = REGNO (XEXP (XEXP (op, 1), 1));
-         *disp = 0;            /* ??? */
-       }
-      else
-         *disp = INTVAL (XEXP (XEXP (op, 1), 1));
-      *incdec = 1;
-      return;
-
-    case PRE_MODIFY:
-      *base = REGNO (XEXP (op, 0));
-      if (REG_P (XEXP (XEXP (op, 1), 1)))
-       {
-         *index = REGNO (XEXP (XEXP (op, 1), 1));
-         *disp = 1;            /* ??? */
-       }
-      else
-         *disp = INTVAL (XEXP (XEXP (op, 1), 1));
-      *incdec = 1;
-
-      return;
-
-    case REG:
-      *base = REGNO (op);
-      return;
-
-    case PLUS:
-      {
-       rtx op0 = XEXP (op, 0);
-       rtx op1 = XEXP (op, 1);
-
-       if (c4x_a_register (op0))
-         {
-           if (c4x_x_register (op1))
-             {
-               *base = REGNO (op0);
-               *index = REGNO (op1);
-               return;
-             }
-           else if ((GET_CODE (op1) == CONST_INT 
-                     && IS_DISP1_CONST (INTVAL (op1))))
-             {
-               *base = REGNO (op0);
-               *disp = INTVAL (op1);
-               return;
-             }
-         }
-       else if (c4x_x_register (op0) && c4x_a_register (op1))
-         {
-           *base = REGNO (op1);
-           *index = REGNO (op0);
-           return;
-         }
-      }
-      /* Fallthrough.  */
-
-    default:
-      fatal_insn ("invalid indirect (S) memory address", op);
-    }
-}
-
-
-int
-c4x_address_conflict (op0, op1, store0, store1)
-     rtx op0;
-     rtx op1;
-     int store0;
-     int store1;
-{
-  int base0;
-  int base1;
-  int incdec0;
-  int incdec1;
-  int index0;
-  int index1;
-  int disp0;
-  int disp1;
-  
-  if (MEM_VOLATILE_P (op0) && MEM_VOLATILE_P (op1))
-    return 1;
-
-  c4x_S_address_parse (op0, &base0, &incdec0, &index0, &disp0);
-  c4x_S_address_parse (op1, &base1, &incdec1, &index1, &disp1);
-
-  if (store0 && store1)
-    {
-      /* If we have two stores in parallel to the same address, then
-        the C4x only executes one of the stores.  This is unlikely to
-        cause problems except when writing to a hardware device such
-        as a FIFO since the second write will be lost.  The user
-        should flag the hardware location as being volatile so that
-        we don't do this optimisation.  While it is unlikely that we
-        have an aliased address if both locations are not marked
-        volatile, it is probably safer to flag a potential conflict
-        if either location is volatile.  */
-      if (! flag_argument_noalias)
-       {
-         if (MEM_VOLATILE_P (op0) || MEM_VOLATILE_P (op1))
-           return 1;
-       }
-    }
-
-  /* If have a parallel load and a store to the same address, the load
-     is performed first, so there is no conflict.  Similarly, there is
-     no conflict if have parallel loads from the same address.  */
-
-  /* Cannot use auto increment or auto decrement twice for same
-     base register.  */
-  if (base0 == base1 && incdec0 && incdec0)
-    return 1;
-
-  /* It might be too confusing for GCC if we have use a base register
-     with a side effect and a memory reference using the same register
-     in parallel.  */
-  if (! TARGET_DEVEL && base0 == base1 && (incdec0 || incdec1))
-    return 1;
-
-  /* We can not optimize the case where op1 and op2 refer to the same
-     address.  */
-  if (base0 == base1 && disp0 == disp1 && index0 == index1)
-    return 1;
-
-  /* No conflict.  */
-  return 0;
-}
-
-
-/* Check for while loop inside a decrement and branch loop.  */
-
-int
-c4x_label_conflict (insn, jump, db)
-     rtx insn;
-     rtx jump;
-     rtx db;
-{
-  while (insn)
-    {
-      if (GET_CODE (insn) == CODE_LABEL)
-       {
-          if (CODE_LABEL_NUMBER (jump) == CODE_LABEL_NUMBER (insn))
-           return 1;
-          if (CODE_LABEL_NUMBER (db) == CODE_LABEL_NUMBER (insn))
-           return 0;
-       }
-      insn = PREV_INSN (insn);
-    }
-  return 1;
-}
-
-
-/* Validate combination of operands for parallel load/store instructions.  */
-
-int
-valid_parallel_load_store (operands, mode)
-     rtx *operands;
-     enum machine_mode mode ATTRIBUTE_UNUSED;
-{
-  rtx op0 = operands[0];
-  rtx op1 = operands[1];
-  rtx op2 = operands[2];
-  rtx op3 = operands[3];
-
-  if (GET_CODE (op0) == SUBREG)
-    op0 = SUBREG_REG (op0);
-  if (GET_CODE (op1) == SUBREG)
-    op1 = SUBREG_REG (op1);
-  if (GET_CODE (op2) == SUBREG)
-    op2 = SUBREG_REG (op2);
-  if (GET_CODE (op3) == SUBREG)
-    op3 = SUBREG_REG (op3);
-
-  /* The patterns should only allow ext_low_reg_operand() or
-     par_ind_operand() operands.  Thus of the 4 operands, only 2
-     should be REGs and the other 2 should be MEMs.  */
-
-  /* This test prevents the multipack pass from using this pattern if
-     op0 is used as an index or base register in op2 or op3, since
-     this combination will require reloading.  */
-  if (GET_CODE (op0) == REG
-      && ((GET_CODE (op2) == MEM && reg_mentioned_p (op0, XEXP (op2, 0)))
-         || (GET_CODE (op3) == MEM && reg_mentioned_p (op0, XEXP (op3, 0)))))
-    return 0;
-
-  /* LDI||LDI.  */
-  if (GET_CODE (op0) == REG && GET_CODE (op2) == REG)
-    return (REGNO (op0) != REGNO (op2))
-      && GET_CODE (op1) == MEM && GET_CODE (op3) == MEM
-      && ! c4x_address_conflict (op1, op3, 0, 0);
-
-  /* STI||STI.  */
-  if (GET_CODE (op1) == REG && GET_CODE (op3) == REG)
-    return GET_CODE (op0) == MEM && GET_CODE (op2) == MEM
-      && ! c4x_address_conflict (op0, op2, 1, 1);
-
-  /* LDI||STI.  */
-  if (GET_CODE (op0) == REG && GET_CODE (op3) == REG)
-    return GET_CODE (op1) == MEM && GET_CODE (op2) == MEM
-      && ! c4x_address_conflict (op1, op2, 0, 1);
-
-  /* STI||LDI.  */
-  if (GET_CODE (op1) == REG && GET_CODE (op2) == REG)
-    return GET_CODE (op0) == MEM && GET_CODE (op3) == MEM
-      && ! c4x_address_conflict (op0, op3, 1, 0);
-
-  return 0;
-}
-
-
-int
-valid_parallel_operands_4 (operands, mode)
-     rtx *operands;
-     enum machine_mode mode ATTRIBUTE_UNUSED;
-{
-  rtx op0 = operands[0];
-  rtx op2 = operands[2];
-
-  if (GET_CODE (op0) == SUBREG)
-    op0 = SUBREG_REG (op0);
-  if (GET_CODE (op2) == SUBREG)
-    op2 = SUBREG_REG (op2);
-
-  /* This test prevents the multipack pass from using this pattern if
-     op0 is used as an index or base register in op2, since this combination
-     will require reloading.  */
-  if (GET_CODE (op0) == REG
-      && GET_CODE (op2) == MEM
-      && reg_mentioned_p (op0, XEXP (op2, 0)))
-    return 0;
-
-  return 1;
-}
-
-
-int
-valid_parallel_operands_5 (operands, mode)
-     rtx *operands;
-     enum machine_mode mode ATTRIBUTE_UNUSED;
-{
-  int regs = 0;
-  rtx op0 = operands[0];
-  rtx op1 = operands[1];
-  rtx op2 = operands[2];
-  rtx op3 = operands[3];
-
-  if (GET_CODE (op0) == SUBREG)
-    op0 = SUBREG_REG (op0);
-  if (GET_CODE (op1) == SUBREG)
-    op1 = SUBREG_REG (op1);
-  if (GET_CODE (op2) == SUBREG)
-    op2 = SUBREG_REG (op2);
-
-  /* The patterns should only allow ext_low_reg_operand() or
-     par_ind_operand() operands.  Operands 1 and 2 may be commutative
-     but only one of them can be a register.  */
-  if (GET_CODE (op1) == REG)
-    regs++;
-  if (GET_CODE (op2) == REG)
-    regs++;
-
-  if (regs != 1)
-    return 0;
-
-  /* This test prevents the multipack pass from using this pattern if
-     op0 is used as an index or base register in op3, since this combination
-     will require reloading.  */
-  if (GET_CODE (op0) == REG
-      && GET_CODE (op3) == MEM
-      && reg_mentioned_p (op0, XEXP (op3, 0)))
-    return 0;
-
-  return 1;
-}
-
-
-int
-valid_parallel_operands_6 (operands, mode)
-     rtx *operands;
-     enum machine_mode mode ATTRIBUTE_UNUSED;
-{
-  int regs = 0;
-  rtx op0 = operands[0];
-  rtx op1 = operands[1];
-  rtx op2 = operands[2];
-  rtx op4 = operands[4];
-  rtx op5 = operands[5];
-
-  if (GET_CODE (op1) == SUBREG)
-    op1 = SUBREG_REG (op1);
-  if (GET_CODE (op2) == SUBREG)
-    op2 = SUBREG_REG (op2);
-  if (GET_CODE (op4) == SUBREG)
-    op4 = SUBREG_REG (op4);
-  if (GET_CODE (op5) == SUBREG)
-    op5 = SUBREG_REG (op5);
-
-  /* The patterns should only allow ext_low_reg_operand() or
-     par_ind_operand() operands.  Thus of the 4 input operands, only 2
-     should be REGs and the other 2 should be MEMs.  */
-
-  if (GET_CODE (op1) == REG)
-    regs++;
-  if (GET_CODE (op2) == REG)
-    regs++;
-  if (GET_CODE (op4) == REG)
-    regs++;
-  if (GET_CODE (op5) == REG)
-    regs++;
-
-  /* The new C30/C40 silicon dies allow 3 regs of the 4 input operands. 
-     Perhaps we should count the MEMs as well?  */
-  if (regs != 2)
-    return 0;
-
-  /* This test prevents the multipack pass from using this pattern if
-     op0 is used as an index or base register in op4 or op5, since
-     this combination will require reloading.  */
-  if (GET_CODE (op0) == REG
-      && ((GET_CODE (op4) == MEM && reg_mentioned_p (op0, XEXP (op4, 0)))
-         || (GET_CODE (op5) == MEM && reg_mentioned_p (op0, XEXP (op5, 0)))))
-    return 0;
-
-  return 1;
-}
-
-
-/* Validate combination of src operands.  Note that the operands have
-   been screened by the src_operand predicate.  We just have to check
-   that the combination of operands is valid.  If FORCE is set, ensure
-   that the destination regno is valid if we have a 2 operand insn.  */
-
-static int
-c4x_valid_operands (code, operands, mode, force)
-     enum rtx_code code;
-     rtx *operands;
-     enum machine_mode mode ATTRIBUTE_UNUSED;
-     int force;
-{
-  rtx op1;
-  rtx op2;
-  enum rtx_code code1;
-  enum rtx_code code2;
-
-  if (code == COMPARE)
-    {
-      op1 = operands[0];
-      op2 = operands[1];
-    }
-  else
-    {
-      op1 = operands[1];
-      op2 = operands[2];
-    }
-
-  if (GET_CODE (op1) == SUBREG)
-    op1 = SUBREG_REG (op1);
-  if (GET_CODE (op2) == SUBREG)
-    op2 = SUBREG_REG (op2);
-
-  code1 = GET_CODE (op1);
-  code2 = GET_CODE (op2);
-
-  if (code1 == REG && code2 == REG)
-    return 1;
-
-  if (code1 == MEM && code2 == MEM)
-    {
-      if (c4x_S_indirect (op1) && c4x_S_indirect (op2))
-       return 1;
-      return c4x_R_indirect (op1) && c4x_R_indirect (op2);
-    }
-
-  if (code1 == code2)
-    return 0;
-
-  if (code1 == REG)
-    {
-      switch (code2)
-       {
-       case CONST_INT:
-         if (c4x_J_constant (op2) && c4x_R_indirect (op1))
-           return 1;
-         break;
-         
-       case CONST_DOUBLE:
-         if (! c4x_H_constant (op2))
-           return 0;
-         break;
-
-         /* Any valid memory operand screened by src_operand is OK.  */
-       case MEM:
-         
-         /* After CSE, any remaining (ADDRESSOF:P reg) gets converted
-            into a stack slot memory address comprising a PLUS and a
-            constant.  */
-       case ADDRESSOF:
-         break;
-         
-       default:
-         fatal_insn ("c4x_valid_operands: Internal error", op2);
-         break;
-       }
-      
-      /* Check that we have a valid destination register for a two operand
-        instruction.  */
-      return ! force || code == COMPARE || REGNO (op1) == REGNO (operands[0]);
-    }
-
-  /* We assume MINUS is commutative since the subtract patterns
-     also support the reverse subtract instructions.  Since op1
-     is not a register, and op2 is a register, op1 can only
-     be a restricted memory operand for a shift instruction.  */
-  if (code == ASHIFTRT || code == LSHIFTRT
-      || code == ASHIFT || code == COMPARE)
-    return code2 == REG
-      && (c4x_S_indirect (op1) || c4x_R_indirect (op1));
-  
-  switch (code1)
-    {
-    case CONST_INT:
-      if (c4x_J_constant (op1) && c4x_R_indirect (op2))
-       return 1;
-      break;
-      
-    case CONST_DOUBLE:
-      if (! c4x_H_constant (op1))
-       return 0;
-      break;
-
-      /* Any valid memory operand screened by src_operand is OK.  */      
-    case MEM:
-#if 0
-      if (code2 != REG)
-       return 0;
-#endif
-      break;
-
-      /* After CSE, any remaining (ADDRESSOF:P reg) gets converted
-        into a stack slot memory address comprising a PLUS and a
-        constant.  */
-    case ADDRESSOF:
-      break;
-      
-    default:
-      abort ();
-      break;
-    }
-      
-  /* Check that we have a valid destination register for a two operand
-     instruction.  */
-  return ! force || REGNO (op1) == REGNO (operands[0]);
-}
-
-
-int valid_operands (code, operands, mode)
-     enum rtx_code code;
-     rtx *operands;
-     enum machine_mode mode;
-{
-
-  /* If we are not optimizing then we have to let anything go and let
-     reload fix things up.  instantiate_decl in function.c can produce
-     invalid insns by changing the offset of a memory operand from a
-     valid one into an invalid one, when the second operand is also a
-     memory operand.  The alternative is not to allow two memory
-     operands for an insn when not optimizing.  The problem only rarely
-     occurs, for example with the C-torture program DFcmp.c.  */
-
-  return ! optimize || c4x_valid_operands (code, operands, mode, 0);
-}
-
-
-int
-legitimize_operands (code, operands, mode)
-     enum rtx_code code;
-     rtx *operands;
-     enum machine_mode mode;
-{
-  /* Compare only has 2 operands.  */
-  if (code == COMPARE)
-    {
-      /* During RTL generation, force constants into pseudos so that
-        they can get hoisted out of loops.  This will tie up an extra
-        register but can save an extra cycle.  Only do this if loop
-        optimisation enabled.  (We cannot pull this trick for add and
-        sub instructions since the flow pass won't find
-        autoincrements etc.)  This allows us to generate compare
-        instructions like CMPI R0, *AR0++ where R0 = 42, say, instead
-        of LDI *AR0++, R0; CMPI 42, R0. 
-
-        Note that expand_binops will try to load an expensive constant
-        into a register if it is used within a loop.  Unfortunately,
-        the cost mechanism doesn't allow us to look at the other
-        operand to decide whether the constant is expensive.  */
-      
-      if (! reload_in_progress
-         && TARGET_HOIST
-         && optimize > 0
-         && GET_CODE (operands[1]) == CONST_INT 
-         && preserve_subexpressions_p ()
-         && rtx_cost (operands[1], code) > 1)
-       operands[1] = force_reg (mode, operands[1]);
-      
-      if (! reload_in_progress
-          && ! c4x_valid_operands (code, operands, mode, 0))
-       operands[0] = force_reg (mode, operands[0]);
-      return 1;
-    }
-  
-  /* We cannot do this for ADDI/SUBI insns since we will
-     defeat the flow pass from finding autoincrement addressing
-     opportunities.  */
-  if (! reload_in_progress
-      && ! ((code == PLUS || code == MINUS) && mode == Pmode)
-      && TARGET_HOIST
-      && optimize > 1
-      && GET_CODE (operands[2]) == CONST_INT
-      && preserve_subexpressions_p ()
-      && rtx_cost (operands[2], code) > 1)
-    operands[2] = force_reg (mode, operands[2]);
-
-  /* We can get better code on a C30 if we force constant shift counts
-     into a register.  This way they can get hoisted out of loops,
-     tying up a register, but saving an instruction.  The downside is
-     that they may get allocated to an address or index register, and
-     thus we will get a pipeline conflict if there is a nearby
-     indirect address using an address register. 
-
-     Note that expand_binops will not try to load an expensive constant
-     into a register if it is used within a loop for a shift insn.  */
-  
-  if (! reload_in_progress
-      && ! c4x_valid_operands (code, operands, mode, TARGET_FORCE))
-    {
-      /* If the operand combination is invalid, we force operand1 into a
-         register, preventing reload from having doing to do this at a
-         later stage.  */
-      operands[1] = force_reg (mode, operands[1]);
-      if (TARGET_FORCE)
-       {
-         emit_move_insn (operands[0], operands[1]);
-         operands[1] = copy_rtx (operands[0]);
-       }
-      else
-       {
-         /* Just in case...  */
-         if (! c4x_valid_operands (code, operands, mode, 0))
-           operands[2] = force_reg (mode, operands[2]);
-       }
-    }
-
-  /* Right shifts require a negative shift count, but GCC expects
-     a positive count, so we emit a NEG.  */
-  if ((code == ASHIFTRT || code == LSHIFTRT)
-      && (GET_CODE (operands[2]) != CONST_INT))
-    operands[2] = gen_rtx_NEG (mode, negate_rtx (mode, operands[2]));
-  
-  return 1;
-}
-
-
-/* The following predicates are used for instruction scheduling.  */
-
-int
-group1_reg_operand (op, mode)
-     rtx op;
-     enum machine_mode mode;
-{
-  if (mode != VOIDmode && mode != GET_MODE (op))
-    return 0;
-  if (GET_CODE (op) == SUBREG)
-    op = SUBREG_REG (op);
-  return REG_P (op) && (! reload_completed || IS_GROUP1_REG (op));
-}
-
-
-int
-group1_mem_operand (op, mode)
-     rtx op;
-     enum machine_mode mode;
-{
-  if (mode != VOIDmode && mode != GET_MODE (op))
-    return 0;
-
-  if (GET_CODE (op) == MEM)
-    {
-      op = XEXP (op, 0);
-      if (GET_CODE (op) == PLUS)
-       {
-         rtx op0 = XEXP (op, 0);
-         rtx op1 = XEXP (op, 1);
-
-         if ((REG_P (op0) && (! reload_completed || IS_GROUP1_REG (op0)))
-             || (REG_P (op1) && (! reload_completed || IS_GROUP1_REG (op1))))
-           return 1;
-       }
-      else if ((REG_P (op)) && (! reload_completed || IS_GROUP1_REG (op)))
-       return 1;
-    }
-
-  return 0;
-}
-
-
-/* Return true if any one of the address registers.  */
-
-int
-arx_reg_operand (op, mode)
-     rtx op;
-     enum machine_mode mode;
-{
-  if (mode != VOIDmode && mode != GET_MODE (op))
-    return 0;
-  if (GET_CODE (op) == SUBREG)
-    op = SUBREG_REG (op);
-  return REG_P (op) && (! reload_completed || IS_ADDR_REG (op));
-}
-
-
-static int
-c4x_arn_reg_operand (op, mode, regno)
-     rtx op;
-     enum machine_mode mode;
-     unsigned int regno;
-{
-  if (mode != VOIDmode && mode != GET_MODE (op))
-    return 0;
-  if (GET_CODE (op) == SUBREG)
-    op = SUBREG_REG (op);
-  return REG_P (op) && (! reload_completed || (REGNO (op) == regno));
-}
-
-
-static int
-c4x_arn_mem_operand (op, mode, regno)
-     rtx op;
-     enum machine_mode mode;
-     unsigned int regno;
-{
-  if (mode != VOIDmode && mode != GET_MODE (op))
-    return 0;
-
-  if (GET_CODE (op) == MEM)
-    {
-      op = XEXP (op, 0);
-      switch (GET_CODE (op))
-       {
-       case PRE_DEC:
-       case POST_DEC:
-       case PRE_INC:
-       case POST_INC:
-         op = XEXP (op, 0);
-
-       case REG:
-          return REG_P (op) && (! reload_completed || (REGNO (op) == regno));
-
-       case PRE_MODIFY:
-       case POST_MODIFY:
-          if (REG_P (XEXP (op, 0)) && (! reload_completed 
-                                      || (REGNO (XEXP (op, 0)) == regno)))
-           return 1;
-          if (REG_P (XEXP (XEXP (op, 1), 1))
-             && (! reload_completed
-                 || (REGNO (XEXP (XEXP (op, 1), 1)) == regno)))
-           return 1;
-         break;
-
-       case PLUS:
-         {
-           rtx op0 = XEXP (op, 0);
-           rtx op1 = XEXP (op, 1);
-
-           if ((REG_P (op0) && (! reload_completed
-                                || (REGNO (op0) == regno)))
-               || (REG_P (op1) && (! reload_completed
-                                   || (REGNO (op1) == regno))))
-             return 1;
-         }
-         break;
-
-       default:
-         break;
-       }
-    }
-  return 0;
-}
-
-
-int
-ar0_reg_operand (op, mode)
-     rtx op;
-     enum machine_mode mode;
-{
-  return c4x_arn_reg_operand (op, mode, AR0_REGNO);
-}
-
-
-int
-ar0_mem_operand (op, mode)
-     rtx op;
-     enum machine_mode mode;
-{
-  return c4x_arn_mem_operand (op, mode, AR0_REGNO);
-}
-
-
-int
-ar1_reg_operand (op, mode)
-     rtx op;
-     enum machine_mode mode;
-{
-  return c4x_arn_reg_operand (op, mode, AR1_REGNO);
-}
-
-
-int
-ar1_mem_operand (op, mode)
-     rtx op;
-     enum machine_mode mode;
-{
-  return c4x_arn_mem_operand (op, mode, AR1_REGNO);
-}
-
-
-int
-ar2_reg_operand (op, mode)
-     rtx op;
-     enum machine_mode mode;
-{
-  return c4x_arn_reg_operand (op, mode, AR2_REGNO);
-}
-
-
-int
-ar2_mem_operand (op, mode)
-     rtx op;
-     enum machine_mode mode;
-{
-  return c4x_arn_mem_operand (op, mode, AR2_REGNO);
-}
-
-
-int
-ar3_reg_operand (op, mode)
-     rtx op;
-     enum machine_mode mode;
-{
-  return c4x_arn_reg_operand (op, mode, AR3_REGNO);
-}
-
-
-int
-ar3_mem_operand (op, mode)
-     rtx op;
-     enum machine_mode mode;
-{
-  return c4x_arn_mem_operand (op, mode, AR3_REGNO);
-}
-
-
-int
-ar4_reg_operand (op, mode)
-     rtx op;
-     enum machine_mode mode;
-{
-  return c4x_arn_reg_operand (op, mode, AR4_REGNO);
-}
-
-
-int
-ar4_mem_operand (op, mode)
-     rtx op;
-     enum machine_mode mode;
-{
-  return c4x_arn_mem_operand (op, mode, AR4_REGNO);
-}
-
-
-int
-ar5_reg_operand (op, mode)
-     rtx op;
-     enum machine_mode mode;
-{
-  return c4x_arn_reg_operand (op, mode, AR5_REGNO);
-}
-
-
-int
-ar5_mem_operand (op, mode)
-     rtx op;
-     enum machine_mode mode;
-{
-  return c4x_arn_mem_operand (op, mode, AR5_REGNO);
-}
-
-
-int
-ar6_reg_operand (op, mode)
-     rtx op;
-     enum machine_mode mode;
-{
-  return c4x_arn_reg_operand (op, mode, AR6_REGNO);
-}
-
-
-int
-ar6_mem_operand (op, mode)
-     rtx op;
-     enum machine_mode mode;
-{
-  return c4x_arn_mem_operand (op, mode, AR6_REGNO);
-}
-
-
-int
-ar7_reg_operand (op, mode)
-     rtx op;
-     enum machine_mode mode;
-{
-  return c4x_arn_reg_operand (op, mode, AR7_REGNO);
-}
-
-
-int
-ar7_mem_operand (op, mode)
-     rtx op;
-     enum machine_mode mode;
-{
-  return c4x_arn_mem_operand (op, mode, AR7_REGNO);
-}
-
-
-int
-ir0_reg_operand (op, mode)
-     rtx op;
-     enum machine_mode mode;
-{
-  return c4x_arn_reg_operand (op, mode, IR0_REGNO);
-}
-
-
-int
-ir0_mem_operand (op, mode)
-     rtx op;
-     enum machine_mode mode;
-{
-  return c4x_arn_mem_operand (op, mode, IR0_REGNO);
-}
-
-
-int
-ir1_reg_operand (op, mode)
-     rtx op;
-     enum machine_mode mode;
-{
-  return c4x_arn_reg_operand (op, mode, IR1_REGNO);
-}
-
-
-int
-ir1_mem_operand (op, mode)
-     rtx op;
-     enum machine_mode mode;
-{
-  return c4x_arn_mem_operand (op, mode, IR1_REGNO);
-}
-
-
-/* This is similar to operand_subword but allows autoincrement
-   addressing.  */
-
-rtx
-c4x_operand_subword (op, i, validate_address, mode)
-     rtx op;
-     int i;
-     int validate_address;
-     enum machine_mode mode;
-{
-  if (mode != HImode && mode != HFmode)
-    fatal_insn ("c4x_operand_subword: invalid mode", op);
-
-  if (mode == HFmode && REG_P (op))
-    fatal_insn ("c4x_operand_subword: invalid operand", op);
-
-  if (GET_CODE (op) == MEM)
-    {
-      enum rtx_code code = GET_CODE (XEXP (op, 0));
-      enum machine_mode mode = GET_MODE (XEXP (op, 0));
-      enum machine_mode submode;
-
-      submode = mode;
-      if (mode == HImode)
-       submode = QImode;
-      else if (mode == HFmode)
-       submode = QFmode;
-
-      switch (code)
-       {
-       case POST_INC:
-       case PRE_INC:
-         return gen_rtx_MEM (submode, XEXP (op, 0));
-         
-       case POST_DEC:
-       case PRE_DEC:
-       case PRE_MODIFY:
-       case POST_MODIFY:
-         /* We could handle these with some difficulty.
-            e.g., *p-- => *(p-=2); *(p+1).  */
-         fatal_insn ("c4x_operand_subword: invalid autoincrement", op);
-
-       case SYMBOL_REF:
-       case LABEL_REF:
-       case CONST:
-       case CONST_INT:
-         fatal_insn ("c4x_operand_subword: invalid address", op);
-
-         /* Even though offsettable_address_p considers (MEM
-            (LO_SUM)) to be offsettable, it is not safe if the
-            address is at the end of the data page since we also have
-            to fix up the associated high PART.  In this case where
-            we are trying to split a HImode or HFmode memory
-            reference, we would have to emit another insn to reload a
-            new HIGH value.  It's easier to disable LO_SUM memory references
-            in HImode or HFmode and we probably get better code.  */
-       case LO_SUM:
-         fatal_insn ("c4x_operand_subword: address not offsettable", op);
-  
-       default:
-         break;
-       }
-    }
-  
-  return operand_subword (op, i, validate_address, mode);
-}
-
-struct name_list
-{
-  struct name_list *next;
-  const char *name;
-};
-
-static struct name_list *global_head;
-static struct name_list *extern_head;
-
-
-/* Add NAME to list of global symbols and remove from external list if
-   present on external list.  */
-
-void
-c4x_global_label (name)
-     const char *name;
-{
-  struct name_list *p, *last;
-
-  /* Do not insert duplicate names, so linearly search through list of
-     existing names.  */
-  p = global_head;
-  while (p)
-    {
-      if (strcmp (p->name, name) == 0)
-       return;
-      p = p->next;
-    }
-  p = (struct name_list *) permalloc (sizeof *p);
-  p->next = global_head;
-  p->name = name;
-  global_head = p;
-
-  /* Remove this name from ref list if present.  */
-  last = NULL;
-  p = extern_head;
-  while (p)
-    {
-      if (strcmp (p->name, name) == 0)
-       {
-         if (last)
-           last->next = p->next;
-         else
-           extern_head = p->next;
-         break;
-       }
-      last = p;
-      p = p->next;
-    }
-}
-
-
-/* Add NAME to list of external symbols.  */
-
-void
-c4x_external_ref (name)
-     const char *name;
-{
-  struct name_list *p;
-
-  /* Do not insert duplicate names.  */
-  p = extern_head;
-  while (p)
-    {
-      if (strcmp (p->name, name) == 0)
-       return;
-      p = p->next;
-    }
-  
-  /* Do not insert ref if global found.  */
-  p = global_head;
-  while (p)
-    {
-      if (strcmp (p->name, name) == 0)
-       return;
-      p = p->next;
-    }
-  p = (struct name_list *) permalloc (sizeof *p);
-  p->next = extern_head;
-  p->name = name;
-  extern_head = p;
-}
-
-
-void
-c4x_file_end (fp)
-     FILE *fp;
-{
-  struct name_list *p;
-  
-  /* Output all external names that are not global.  */
-  p = extern_head;
-  while (p)
-    {
-      fprintf (fp, "\t.ref\t");
-      assemble_name (fp, p->name);
-      fprintf (fp, "\n");
-      p = p->next;
-    }
-  fprintf (fp, "\t.end\n");
-}
-
-
-static void
-c4x_check_attribute (attrib, list, decl, attributes)
-     const char *attrib;
-     tree list, decl, *attributes;
-{
-  while (list != NULL_TREE
-         && IDENTIFIER_POINTER (TREE_PURPOSE (list))
-        != IDENTIFIER_POINTER (DECL_NAME (decl)))
-    list = TREE_CHAIN (list);
-  if (list)
-    *attributes = tree_cons (get_identifier (attrib), TREE_VALUE (list),
-                            *attributes);
-}
-
-
-static void
-c4x_insert_attributes (decl, attributes)
-     tree decl, *attributes;
-{
-  switch (TREE_CODE (decl))
-    {
-    case FUNCTION_DECL:
-      c4x_check_attribute ("section", code_tree, decl, attributes);
-      c4x_check_attribute ("const", pure_tree, decl, attributes);
-      c4x_check_attribute ("noreturn", noreturn_tree, decl, attributes);
-      c4x_check_attribute ("interrupt", interrupt_tree, decl, attributes);
-      break;
-
-    case VAR_DECL:
-      c4x_check_attribute ("section", data_tree, decl, attributes);
-      break;
-
-    default:
-      break;
-    }
-}
-
-/* Table of valid machine attributes.  */
-const struct attribute_spec c4x_attribute_table[] =
-{
-  /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
-  { "interrupt",    0, 0, false, true,  true,  c4x_handle_fntype_attribute },
-  /* FIXME: code elsewhere in this file treats "naked" as a synonym of
-     "interrupt"; should it be accepted here?  */
-  { "assembler",    0, 0, false, true,  true,  c4x_handle_fntype_attribute },
-  { "leaf_pretend", 0, 0, false, true,  true,  c4x_handle_fntype_attribute },
-  { NULL,           0, 0, false, false, false, NULL }
-};
-
-/* Handle an attribute requiring a FUNCTION_TYPE;
-   arguments as in struct attribute_spec.handler.  */
-static tree
-c4x_handle_fntype_attribute (node, name, args, flags, no_add_attrs)
-     tree *node;
-     tree name;
-     tree args ATTRIBUTE_UNUSED;
-     int flags ATTRIBUTE_UNUSED;
-     bool *no_add_attrs;
-{
-  if (TREE_CODE (*node) != FUNCTION_TYPE)
-    {
-      warning ("`%s' attribute only applies to functions",
-              IDENTIFIER_POINTER (name));
-      *no_add_attrs = true;
-    }
-
-  return NULL_TREE;
-}
-
-
-/* !!! FIXME to emit RPTS correctly.  */
-
-int
-c4x_rptb_rpts_p (insn, op)
-     rtx insn, op;
-{
-  /* The next insn should be our label marking where the
-     repeat block starts.  */
-  insn = NEXT_INSN (insn);
-  if (GET_CODE (insn) != CODE_LABEL)
-    {
-      /* Some insns may have been shifted between the RPTB insn
-         and the top label... They were probably destined to
-         be moved out of the loop.  For now, let's leave them
-         where they are and print a warning.  We should
-         probably move these insns before the repeat block insn.  */
-      if (TARGET_DEBUG)
-       fatal_insn("c4x_rptb_rpts_p: Repeat block top label moved\n",
-                  insn);
-      return 0;
-    }
-
-  /* Skip any notes.  */
-  insn = next_nonnote_insn (insn);
-
-  /* This should be our first insn in the loop.  */
-  if (! INSN_P (insn))
-    return 0;
-
-  /* Skip any notes.  */
-  insn = next_nonnote_insn (insn);
-
-  if (! INSN_P (insn))
-    return 0;
-
-  if (recog_memoized (insn) != CODE_FOR_rptb_end)
-    return 0;
-
-  if (TARGET_RPTS)
-    return 1;
-
-  return (GET_CODE (op) == CONST_INT) && TARGET_RPTS_CYCLES (INTVAL (op));
-}
-
-
-/* Check if register r11 is used as the destination of an insn.  */
-
-static int
-c4x_r11_set_p(x)
-    rtx x;
-{
-  rtx set;
-  int i, j;
-  const char *fmt;
-
-  if (x == 0)
-    return 0;
-
-  if (INSN_P (x) && GET_CODE (PATTERN (x)) == SEQUENCE)
-    x = XVECEXP (PATTERN (x), 0, XVECLEN (PATTERN (x), 0) - 1);
-
-  if (INSN_P (x) && (set = single_set (x)))
-    x = SET_DEST (set);
-
-  if (GET_CODE (x) == REG && REGNO (x) == R11_REGNO)
-    return 1;
-
-  fmt = GET_RTX_FORMAT (GET_CODE (x));
-  for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
-    {
-      if (fmt[i] == 'e')
-       {
-          if (c4x_r11_set_p (XEXP (x, i)))
-           return 1;
-       }
-      else if (fmt[i] == 'E')
-        for (j = XVECLEN (x, i) - 1; j >= 0; j--)
-          if (c4x_r11_set_p (XVECEXP (x, i, j)))
-           return 1;
-    }
-  return 0;
-}
-
-
-/* The c4x sometimes has a problem when the insn before the laj insn
-   sets the r11 register.  Check for this situation.  */
-
-int
-c4x_check_laj_p (insn)
-     rtx insn;
-{
-  insn = prev_nonnote_insn (insn);
-
-  /* If this is the start of the function no nop is needed.  */
-  if (insn == 0)
-    return 0;
-
-  /* If the previous insn is a code label we have to insert a nop. This
-     could be a jump or table jump. We can find the normal jumps by
-     scanning the function but this will not find table jumps.  */
-  if (GET_CODE (insn) == CODE_LABEL)
-    return 1;
-
-  /* If the previous insn sets register r11 we have to insert a nop.  */
-  if (c4x_r11_set_p (insn))
-    return 1;
-
-  /* No nop needed.  */
-  return 0;
-}
-
-
-/* Adjust the cost of a scheduling dependency.  Return the new cost of
-   a dependency LINK or INSN on DEP_INSN.  COST is the current cost. 
-   A set of an address register followed by a use occurs a 2 cycle
-   stall (reduced to a single cycle on the c40 using LDA), while
-   a read of an address register followed by a use occurs a single cycle.  */
-
-#define        SET_USE_COST    3
-#define        SETLDA_USE_COST 2
-#define        READ_USE_COST   2
-
-static int
-c4x_adjust_cost (insn, link, dep_insn, cost)
-     rtx insn;
-     rtx link;
-     rtx dep_insn;
-     int cost;
-{
-  /* Don't worry about this until we know what registers have been
-     assigned.  */
-  if (flag_schedule_insns == 0 && ! reload_completed)
-    return 0;
-
-  /* How do we handle dependencies where a read followed by another
-     read causes a pipeline stall?  For example, a read of ar0 followed
-     by the use of ar0 for a memory reference.  It looks like we
-     need to extend the scheduler to handle this case.  */
-
-  /* Reload sometimes generates a CLOBBER of a stack slot, e.g.,
-     (clobber (mem:QI (plus:QI (reg:QI 11 ar3) (const_int 261)))),
-     so only deal with insns we know about.  */
-  if (recog_memoized (dep_insn) < 0)
-    return 0;
-
-  if (REG_NOTE_KIND (link) == 0)
-    {
-      int max = 0;
-
-      /* Data dependency; DEP_INSN writes a register that INSN reads some
-        cycles later.  */
-      if (TARGET_C3X)
-       {
-         if (get_attr_setgroup1 (dep_insn) && get_attr_usegroup1 (insn))
-           max = SET_USE_COST > max ? SET_USE_COST : max;
-         if (get_attr_readarx (dep_insn) && get_attr_usegroup1 (insn))
-           max = READ_USE_COST > max ? READ_USE_COST : max;
-       }
-      else
-       {
-         /* This could be significantly optimized. We should look
-            to see if dep_insn sets ar0-ar7 or ir0-ir1 and if
-            insn uses ar0-ar7.  We then test if the same register
-            is used.  The tricky bit is that some operands will
-            use several registers...  */
-         if (get_attr_setar0 (dep_insn) && get_attr_usear0 (insn))
-           max = SET_USE_COST > max ? SET_USE_COST : max;
-         if (get_attr_setlda_ar0 (dep_insn) && get_attr_usear0 (insn))
-           max = SETLDA_USE_COST > max ? SETLDA_USE_COST : max;
-         if (get_attr_readar0 (dep_insn) && get_attr_usear0 (insn))
-           max = READ_USE_COST > max ? READ_USE_COST : max;
-
-         if (get_attr_setar1 (dep_insn) && get_attr_usear1 (insn))
-           max = SET_USE_COST > max ? SET_USE_COST : max;
-         if (get_attr_setlda_ar1 (dep_insn) && get_attr_usear1 (insn))
-           max = SETLDA_USE_COST > max ? SETLDA_USE_COST : max;
-         if (get_attr_readar1 (dep_insn) && get_attr_usear1 (insn))
-           max = READ_USE_COST > max ? READ_USE_COST : max;
-
-         if (get_attr_setar2 (dep_insn) && get_attr_usear2 (insn))
-           max = SET_USE_COST > max ? SET_USE_COST : max;
-         if (get_attr_setlda_ar2 (dep_insn) && get_attr_usear2 (insn))
-           max = SETLDA_USE_COST > max ? SETLDA_USE_COST : max;
-         if (get_attr_readar2 (dep_insn) && get_attr_usear2 (insn))
-           max = READ_USE_COST > max ? READ_USE_COST : max;
-
-         if (get_attr_setar3 (dep_insn) && get_attr_usear3 (insn))
-           max = SET_USE_COST > max ? SET_USE_COST : max;
-         if (get_attr_setlda_ar3 (dep_insn) && get_attr_usear3 (insn))
-           max = SETLDA_USE_COST > max ? SETLDA_USE_COST : max;
-         if (get_attr_readar3 (dep_insn) && get_attr_usear3 (insn))
-           max = READ_USE_COST > max ? READ_USE_COST : max;
-
-         if (get_attr_setar4 (dep_insn) && get_attr_usear4 (insn))
-           max = SET_USE_COST > max ? SET_USE_COST : max;
-         if (get_attr_setlda_ar4 (dep_insn) && get_attr_usear4 (insn))
-           max = SETLDA_USE_COST > max ? SETLDA_USE_COST : max;
-         if (get_attr_readar4 (dep_insn) && get_attr_usear4 (insn))
-           max = READ_USE_COST > max ? READ_USE_COST : max;
-
-         if (get_attr_setar5 (dep_insn) && get_attr_usear5 (insn))
-           max = SET_USE_COST > max ? SET_USE_COST : max;
-         if (get_attr_setlda_ar5 (dep_insn) && get_attr_usear5 (insn))
-           max = SETLDA_USE_COST > max ? SETLDA_USE_COST : max;
-         if (get_attr_readar5 (dep_insn) && get_attr_usear5 (insn))
-           max = READ_USE_COST > max ? READ_USE_COST : max;
-
-         if (get_attr_setar6 (dep_insn) && get_attr_usear6 (insn))
-           max = SET_USE_COST > max ? SET_USE_COST : max;
-         if (get_attr_setlda_ar6 (dep_insn) && get_attr_usear6 (insn))
-           max = SETLDA_USE_COST > max ? SETLDA_USE_COST : max;
-         if (get_attr_readar6 (dep_insn) && get_attr_usear6 (insn))
-           max = READ_USE_COST > max ? READ_USE_COST : max;
-
-         if (get_attr_setar7 (dep_insn) && get_attr_usear7 (insn))
-           max = SET_USE_COST > max ? SET_USE_COST : max;
-         if (get_attr_setlda_ar7 (dep_insn) && get_attr_usear7 (insn))
-           max = SETLDA_USE_COST > max ? SETLDA_USE_COST : max;
-         if (get_attr_readar7 (dep_insn) && get_attr_usear7 (insn))
-           max = READ_USE_COST > max ? READ_USE_COST : max;
-
-         if (get_attr_setir0 (dep_insn) && get_attr_useir0 (insn))
-           max = SET_USE_COST > max ? SET_USE_COST : max;
-         if (get_attr_setlda_ir0 (dep_insn) && get_attr_useir0 (insn))
-           max = SETLDA_USE_COST > max ? SETLDA_USE_COST : max;
-
-         if (get_attr_setir1 (dep_insn) && get_attr_useir1 (insn))
-           max = SET_USE_COST > max ? SET_USE_COST : max;
-         if (get_attr_setlda_ir1 (dep_insn) && get_attr_useir1 (insn))
-           max = SETLDA_USE_COST > max ? SETLDA_USE_COST : max;
-       }
-
-      if (max)
-       cost = max;
-
-      /* For other data dependencies, the default cost specified in the
-        md is correct.  */
-      return cost;
-    }
-  else if (REG_NOTE_KIND (link) == REG_DEP_ANTI)
-    {
-      /* Anti dependency; DEP_INSN reads a register that INSN writes some
-        cycles later.  */
-
-      /* For c4x anti dependencies, the cost is 0.  */
-      return 0;
-    }
-  else if (REG_NOTE_KIND (link) == REG_DEP_OUTPUT)
-    {
-      /* Output dependency; DEP_INSN writes a register that INSN writes some
-        cycles later.  */
-
-      /* For c4x output dependencies, the cost is 0.  */
-      return 0;
-    }
-  else
-    abort ();
-}
-
-void
-c4x_init_builtins ()
-{
-  tree endlink = void_list_node;
-
-  builtin_function ("fast_ftoi",
-                   build_function_type 
-                   (integer_type_node,
-                    tree_cons (NULL_TREE, double_type_node, endlink)),
-                   C4X_BUILTIN_FIX, BUILT_IN_MD, NULL);
-  builtin_function ("ansi_ftoi",
-                   build_function_type 
-                   (integer_type_node, 
-                    tree_cons (NULL_TREE, double_type_node, endlink)),
-                   C4X_BUILTIN_FIX_ANSI, BUILT_IN_MD, NULL);
-  if (TARGET_C3X)
-    builtin_function ("fast_imult",
-                     build_function_type
-                     (integer_type_node, 
-                      tree_cons (NULL_TREE, integer_type_node,
-                                 tree_cons (NULL_TREE,
-                                            integer_type_node, endlink))),
-                     C4X_BUILTIN_MPYI, BUILT_IN_MD, NULL);
-  else
-    {
-      builtin_function ("toieee",
-                       build_function_type 
-                       (double_type_node,
-                        tree_cons (NULL_TREE, double_type_node, endlink)),
-                       C4X_BUILTIN_TOIEEE, BUILT_IN_MD, NULL);
-      builtin_function ("frieee",
-                       build_function_type
-                       (double_type_node, 
-                        tree_cons (NULL_TREE, double_type_node, endlink)),
-                       C4X_BUILTIN_FRIEEE, BUILT_IN_MD, NULL);
-      builtin_function ("fast_invf",
-                       build_function_type 
-                       (double_type_node, 
-                        tree_cons (NULL_TREE, double_type_node, endlink)),
-                       C4X_BUILTIN_RCPF, BUILT_IN_MD, NULL);
-    }
-}
-
-
-rtx
-c4x_expand_builtin (exp, target, subtarget, mode, ignore)
-     tree exp;
-     rtx target;
-     rtx subtarget ATTRIBUTE_UNUSED;
-     enum machine_mode mode ATTRIBUTE_UNUSED;
-     int ignore ATTRIBUTE_UNUSED;
-{
-  tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
-  unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
-  tree arglist = TREE_OPERAND (exp, 1);
-  tree arg0, arg1;
-  rtx r0, r1;
-
-  switch (fcode)
-    {
-    case C4X_BUILTIN_FIX:
-      arg0 = TREE_VALUE (arglist);
-      r0 = expand_expr (arg0, NULL_RTX, QFmode, 0);
-      r0 = protect_from_queue (r0, 0);
-      if (! target || ! register_operand (target, QImode))
-       target = gen_reg_rtx (QImode);
-      emit_insn (gen_fixqfqi_clobber (target, r0));
-      return target;
-
-    case C4X_BUILTIN_FIX_ANSI:
-      arg0 = TREE_VALUE (arglist);
-      r0 = expand_expr (arg0, NULL_RTX, QFmode, 0);
-      r0 = protect_from_queue (r0, 0);
-      if (! target || ! register_operand (target, QImode))
-       target = gen_reg_rtx (QImode);
-      emit_insn (gen_fix_truncqfqi2 (target, r0));
-      return target;
-
-    case C4X_BUILTIN_MPYI:
-      if (! TARGET_C3X)
-       break;
-      arg0 = TREE_VALUE (arglist);
-      arg1 = TREE_VALUE (TREE_CHAIN (arglist));
-      r0 = expand_expr (arg0, NULL_RTX, QImode, 0);
-      r1 = expand_expr (arg1, NULL_RTX, QImode, 0);
-      r0 = protect_from_queue (r0, 0);
-      r1 = protect_from_queue (r1, 0);
-      if (! target || ! register_operand (target, QImode))
-       target = gen_reg_rtx (QImode);
-      emit_insn (gen_mulqi3_24_clobber (target, r0, r1));
-      return target;
-
-    case C4X_BUILTIN_TOIEEE:
-      if (TARGET_C3X)
-       break;
-      arg0 = TREE_VALUE (arglist);
-      r0 = expand_expr (arg0, NULL_RTX, QFmode, 0);
-      r0 = protect_from_queue (r0, 0);
-      if (! target || ! register_operand (target, QFmode))
-       target = gen_reg_rtx (QFmode);
-      emit_insn (gen_toieee (target, r0));
-      return target;
-
-    case C4X_BUILTIN_FRIEEE:
-      if (TARGET_C3X)
-       break;
-      arg0 = TREE_VALUE (arglist);
-      if (TREE_CODE (arg0) == VAR_DECL || TREE_CODE (arg0) == PARM_DECL)
-       put_var_into_stack (arg0);
-      r0 = expand_expr (arg0, NULL_RTX, QFmode, 0);
-      r0 = protect_from_queue (r0, 0);
-      if (register_operand (r0, QFmode))
-       {
-         r1 = assign_stack_local (QFmode, GET_MODE_SIZE (QFmode), 0);
-         emit_move_insn (r1, r0);
-         r0 = r1;
-       }
-      if (! target || ! register_operand (target, QFmode))
-       target = gen_reg_rtx (QFmode);
-      emit_insn (gen_frieee (target, r0));
-      return target;
-
-    case C4X_BUILTIN_RCPF:
-      if (TARGET_C3X)
-       break;
-      arg0 = TREE_VALUE (arglist);
-      r0 = expand_expr (arg0, NULL_RTX, QFmode, 0);
-      r0 = protect_from_queue (r0, 0);
-      if (! target || ! register_operand (target, QFmode))
-       target = gen_reg_rtx (QFmode);
-      emit_insn (gen_rcpfqf_clobber (target, r0));
-      return target;
-    }
-  return NULL_RTX;
-}
-
-static void
-c4x_asm_named_section (name, flags)
-     const char *name;
-     unsigned int flags ATTRIBUTE_UNUSED;
-{
-  fprintf (asm_out_file, "\t.sect\t\"%s\"\n", name);
-}