]> oss.titaniummirror.com Git - msp430-gcc.git/blobdiff - gcc/config/ns32k/ns32k.c
Imported gcc-4.4.3
[msp430-gcc.git] / gcc / config / ns32k / ns32k.c
diff --git a/gcc/config/ns32k/ns32k.c b/gcc/config/ns32k/ns32k.c
deleted file mode 100644 (file)
index 7c3afe2..0000000
+++ /dev/null
@@ -1,1558 +0,0 @@
-/* Subroutines for assembler code output on the NS32000.
-   Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
-   Free Software Foundation, Inc.
-
-This file is part of GNU CC.
-
-GNU CC is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
-any later version.
-
-GNU CC is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with GNU CC; see the file COPYING.  If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA.  */
-
-#include "config.h"
-#include "system.h"
-#include "rtl.h"
-#include "regs.h"
-#include "hard-reg-set.h"
-#include "real.h"
-#include "insn-config.h"
-#include "conditions.h"
-#include "output.h"
-#include "insn-attr.h"
-#include "tree.h"
-#include "function.h"
-#include "expr.h"
-#include "flags.h"
-#include "recog.h"
-#include "tm_p.h"
-#include "target.h"
-#include "target-def.h"
-#include "toplev.h"
-
-#ifdef OSF_OS
-int ns32k_num_files = 0;
-#endif
-
-/* This duplicates reg_class_contents in reg_class.c, but maybe that isn't
-   initialized in time. Also this is more convenient as an array of ints.
-   We know that HARD_REG_SET fits in an unsigned int */
-
-unsigned int ns32k_reg_class_contents[N_REG_CLASSES][1] = REG_CLASS_CONTENTS;
-
-enum reg_class regclass_map[FIRST_PSEUDO_REGISTER] =
-{
-  GENERAL_REGS, GENERAL_REGS, GENERAL_REGS, GENERAL_REGS,
-  GENERAL_REGS, GENERAL_REGS, GENERAL_REGS, GENERAL_REGS,
-  FLOAT_REG0, LONG_FLOAT_REG0, FLOAT_REGS, FLOAT_REGS,
-  FLOAT_REGS, FLOAT_REGS, FLOAT_REGS, FLOAT_REGS,
-  FP_REGS, FP_REGS, FP_REGS, FP_REGS,
-  FP_REGS, FP_REGS, FP_REGS, FP_REGS,
-  FRAME_POINTER_REG, STACK_POINTER_REG
-};
-
-static const char *const ns32k_out_reg_names[] = OUTPUT_REGISTER_NAMES;
-
-static rtx gen_indexed_expr PARAMS ((rtx, rtx, rtx));
-static const char *singlemove_string PARAMS ((rtx *));
-static void move_tail PARAMS ((rtx[], int, int));
-static tree ns32k_handle_fntype_attribute PARAMS ((tree *, tree, tree, int, bool *));
-const struct attribute_spec ns32k_attribute_table[];
-static void ns32k_output_function_prologue PARAMS ((FILE *, HOST_WIDE_INT));
-static void ns32k_output_function_epilogue PARAMS ((FILE *, HOST_WIDE_INT));
-\f
-/* Initialize the GCC target structure.  */
-#undef TARGET_ATTRIBUTE_TABLE
-#define TARGET_ATTRIBUTE_TABLE ns32k_attribute_table
-
-#undef TARGET_ASM_ALIGNED_HI_OP
-#define TARGET_ASM_ALIGNED_HI_OP "\t.word\t"
-
-#ifdef ENCORE_ASM
-#undef TARGET_ASM_ALIGNED_SI_OP
-#define TARGET_ASM_ALIGNED_SI_OP "\t.double\t"
-#endif
-
-#undef TARGET_ASM_FUNCTION_PROLOGUE
-#define TARGET_ASM_FUNCTION_PROLOGUE ns32k_output_function_prologue
-#undef TARGET_ASM_FUNCTION_EPILOGUE
-#define TARGET_ASM_FUNCTION_EPILOGUE ns32k_output_function_epilogue
-
-struct gcc_target targetm = TARGET_INITIALIZER;
-\f
-/* Generate the assembly code for function entry.  FILE is a stdio
-   stream to output the code to.  SIZE is an int: how many units of
-   temporary storage to allocate.
-
-   Refer to the array `regs_ever_live' to determine which registers to
-   save; `regs_ever_live[I]' is nonzero if register number I is ever
-   used in the function.  This function is responsible for knowing
-   which registers should not be saved even if used.  */
-
-/*
- * The function prologue for the ns32k is fairly simple.
- * If a frame pointer is needed (decided in reload.c ?) then
- * we need assembler of the form
- *
- *  # Save the oldframe pointer, set the new frame pointer, make space
- *  # on the stack and save any general purpose registers necessary
- *
- *  enter [<general purpose regs to save>], <local stack space>
- *
- *  movf  fn, tos    # Save any floating point registers necessary
- *  .
- *  .
- *
- * If a frame pointer is not needed we need assembler of the form
- *
- *  # Make space on the stack
- *
- *  adjspd <local stack space + 4>
- *
- *  # Save any general purpose registers necessary
- *
- *  save [<general purpose regs to save>]
- *
- *  movf  fn, tos    # Save any floating point registers necessary
- *  .
- *  .
- */
-
-#if !defined (MERLIN_TARGET) && !defined (UTEK_ASM)
-
-#if defined(IMMEDIATE_PREFIX) && IMMEDIATE_PREFIX
-#define ADJSP(FILE, N) \
-        fprintf (FILE, "\tadjspd %c%d\n", IMMEDIATE_PREFIX, (N))
-#else
-#define ADJSP(FILE, N) \
-        fprintf (FILE, "\tadjspd %d\n", (N))
-#endif
-
-static void
-ns32k_output_function_prologue (file, size)
-     FILE *file;
-     HOST_WIDE_INT size;
-{
-  register int regno, g_regs_used = 0;
-  int used_regs_buf[8], *bufp = used_regs_buf;
-  int used_fregs_buf[17], *fbufp = used_fregs_buf;
-
-  for (regno = R0_REGNUM; regno < F0_REGNUM; regno++)
-    if (regs_ever_live[regno]
-       && ! call_used_regs[regno])
-      {
-        *bufp++ = regno; g_regs_used++;
-      }
-  *bufp = -1;
-
-  for (; regno < FRAME_POINTER_REGNUM; regno++)
-    if (regs_ever_live[regno] && !call_used_regs[regno])
-      {
-        *fbufp++ = regno;
-      }
-  *fbufp = -1;
-
-  bufp = used_regs_buf;
-  if (frame_pointer_needed)
-    fprintf (file, "\tenter [");
-  else
-    {
-      if (size)
-        ADJSP (file, size + 4);
-      if (g_regs_used && g_regs_used > 4)
-        fprintf (file, "\tsave [");
-      else
-       {
-         while (*bufp >= 0)
-            fprintf (file, "\tmovd r%d,tos\n", *bufp++);
-         g_regs_used = 0;
-       }
-    }
-
-  while (*bufp >= 0)
-    {
-      fprintf (file, "r%d", *bufp++);
-      if (*bufp >= 0)
-       fputc (',', file);
-    }
-
-  if (frame_pointer_needed)
-    fprintf (file, "],%d\n", size);
-  else if (g_regs_used)
-    fprintf (file, "]\n");
-
-  fbufp = used_fregs_buf;
-  while (*fbufp >= 0)
-    {
-      if ((*fbufp & 1) || (fbufp[0] != fbufp[1] - 1))
-       fprintf (file, "\tmovf %s,tos\n", ns32k_out_reg_names[*fbufp++]);
-      else
-       {
-         fprintf (file, "\tmovl %s,tos\n",
-                  ns32k_out_reg_names[fbufp[0]]);
-         fbufp += 2;
-       }
-    }
-
-  if (flag_pic && current_function_uses_pic_offset_table)
-    {
-      fprintf (file, "\tsprd sb,tos\n");
-      if (TARGET_REGPARM)
-       {
-         fprintf (file, "\taddr __GLOBAL_OFFSET_TABLE_(pc),tos\n");
-         fprintf (file, "\tlprd sb,tos\n");
-       }
-      else
-       {
-         fprintf (file, "\taddr __GLOBAL_OFFSET_TABLE_(pc),r0\n");
-         fprintf (file, "\tlprd sb,r0\n");
-       }
-    }
-}
-
-#else /* MERLIN_TARGET || UTEK_ASM  */
-
-/* This differs from the standard one above in printing a bitmask
-   rather than a register list in the enter or save instruction.  */
-
-static void
-ns32k_output_function_prologue (file, size)
-     FILE *file;
-     HOST_WIDE_INT size;
-{
-  register int regno, g_regs_used = 0;
-  int used_regs_buf[8], *bufp = used_regs_buf;
-  int used_fregs_buf[8], *fbufp = used_fregs_buf;
-
-  for (regno = 0; regno < 8; regno++)
-    if (regs_ever_live[regno]
-       && ! call_used_regs[regno])
-      {
-       *bufp++ = regno; g_regs_used++;
-      }
-  *bufp = -1;
-
-  for (; regno < 16; regno++)
-    if (regs_ever_live[regno] && !call_used_regs[regno]) {
-      *fbufp++ = regno;
-    }
-  *fbufp = -1;
-
-  bufp = used_regs_buf;
-  if (frame_pointer_needed)
-    fprintf (file, "\tenter ");
-  else if (g_regs_used)
-    fprintf (file, "\tsave ");
-
-  if (frame_pointer_needed || g_regs_used)
-    {
-      char mask = 0;
-      while (*bufp >= 0)
-       mask |= 1 << *bufp++;
-      fprintf (file, "$0x%x", (int) mask & 0xff);
-    }
-
-  if (frame_pointer_needed)
-#ifdef UTEK_ASM
-    fprintf (file, ",$%d\n", size);
-#else
-    fprintf (file, ",%d\n", size);
-#endif
-  else if (g_regs_used)
-    fprintf (file, "\n");
-
-  fbufp = used_fregs_buf;
-  while (*fbufp >= 0)
-    {
-      if ((*fbufp & 1) || (fbufp[0] != fbufp[1] - 1))
-       fprintf (file, "\tmovf f%d,tos\n", *fbufp++ - 8);
-      else
-       {
-         fprintf (file, "\tmovl f%d,tos\n", fbufp[0] - 8);
-         fbufp += 2;
-       }
-    }
-}
-
-#endif /* MERLIN_TARGET || UTEK_ASM  */
-
-/* This function generates the assembly code for function exit,
-   on machines that need it.
-
-   The function epilogue should not depend on the current stack pointer,
-   if EXIT_IGNORE_STACK is nonzero.  That doesn't apply here.
-
-   If a frame pointer is needed (decided in reload.c ?) then
-   we need assembler of the form
-
-    movf  tos, fn      # Restore any saved floating point registers
-    .
-    .
-
-    # Restore any saved general purpose registers, restore the stack
-    # pointer from the frame pointer, restore the old frame pointer.
-    exit [<general purpose regs to save>]
-
-   If a frame pointer is not needed we need assembler of the form
-    # Restore any general purpose registers saved
-
-    movf  tos, fn      # Restore any saved floating point registers
-    .
-    .
-    .
-    restore [<general purpose regs to save>]
-
-    # reclaim space allocated on stack
-
-    adjspd <-(local stack space + 4)> */
-
-#if !defined (MERLIN_TARGET) && !defined (UTEK_ASM)
-
-static void
-ns32k_output_function_epilogue (file, size)
-     FILE *file;
-     HOST_WIDE_INT size;
-{
-  register int regno, g_regs_used = 0, f_regs_used = 0;
-  int used_regs_buf[8], *bufp = used_regs_buf;
-  int used_fregs_buf[17], *fbufp = used_fregs_buf;
-
-  if (flag_pic && current_function_uses_pic_offset_table)
-    fprintf (file, "\tlprd sb,tos\n");
-
-  *fbufp++ = -2;
-  for (regno = F0_REGNUM; regno < FRAME_POINTER_REGNUM; regno++)
-    if (regs_ever_live[regno] && !call_used_regs[regno])
-      {
-       *fbufp++ = regno; f_regs_used++;
-      }
-  fbufp--;
-
-  for (regno = 0; regno < F0_REGNUM; regno++)
-    if (regs_ever_live[regno]
-       && ! call_used_regs[regno])
-      {
-        *bufp++ = regno; g_regs_used++;
-      }
-
-  while (fbufp > used_fregs_buf)
-    {
-      if ((*fbufp & 1) && fbufp[0] == fbufp[-1] + 1)
-       {
-         fprintf (file, "\tmovl tos,%s\n",
-                  ns32k_out_reg_names[fbufp[-1]]);
-         fbufp -= 2;
-       }
-      else fprintf (file, "\tmovf tos,%s\n", ns32k_out_reg_names[*fbufp--]);
-    }
-
-  if (frame_pointer_needed)
-    fprintf (file, "\texit [");
-  else
-    {
-      if (g_regs_used && g_regs_used > 4)
-        fprintf (file, "\trestore [");
-      else
-        {
-         while (bufp > used_regs_buf)
-            fprintf (file, "\tmovd tos,r%d\n", *--bufp);
-         g_regs_used = 0;
-        }
-    }
-
-  while (bufp > used_regs_buf)
-    {
-      fprintf (file, "r%d", *--bufp);
-      if (bufp > used_regs_buf)
-       fputc (',', file);
-    }
-
-  if (g_regs_used || frame_pointer_needed)
-    fprintf (file, "]\n");
-
-  if (size && !frame_pointer_needed)
-    ADJSP (file, -(size + 4));
-
-  if (current_function_pops_args)
-    fprintf (file, "\tret %d\n", current_function_pops_args);
-  else
-    fprintf (file, "\tret 0\n");
-}
-
-#else /* MERLIN_TARGET || UTEK_ASM  */
-
-/* This differs from the standard one above in printing a bitmask
-   rather than a register list in the exit or restore instruction.  */
-
-static void
-ns32k_output_function_epilogue (file, size)
-     FILE *file;
-     HOST_WIDE_INT size ATTRIBUTE_UNUSED;
-{
-  register int regno, g_regs_used = 0, f_regs_used = 0;
-  int used_regs_buf[8], *bufp = used_regs_buf;
-  int used_fregs_buf[8], *fbufp = used_fregs_buf;
-
-  *fbufp++ = -2;
-  for (regno = 8; regno < 16; regno++)
-    if (regs_ever_live[regno] && !call_used_regs[regno]) {
-      *fbufp++ = regno; f_regs_used++;
-    }
-  fbufp--;
-
-  for (regno = 0; regno < 8; regno++)
-    if (regs_ever_live[regno]
-       && ! call_used_regs[regno])
-      {
-       *bufp++ = regno; g_regs_used++;
-      }
-
-  while (fbufp > used_fregs_buf)
-    {
-      if ((*fbufp & 1) && fbufp[0] == fbufp[-1] + 1)
-       {
-         fprintf (file, "\tmovl tos,f%d\n", fbufp[-1] - 8);
-         fbufp -= 2;
-       }
-      else fprintf (file, "\tmovf tos,f%d\n", *fbufp-- - 8);
-    }
-
-  if (frame_pointer_needed)
-    fprintf (file, "\texit ");
-  else if (g_regs_used)
-    fprintf (file, "\trestore ");
-
-  if (g_regs_used || frame_pointer_needed)
-    {
-      char mask = 0;
-
-      while (bufp > used_regs_buf)
-       {
-         /* Utek assembler takes care of reversing this */
-         mask |= 1 << *--bufp;
-       }
-      fprintf (file, "$0x%x\n", (int) mask & 0xff);
-    }
-
-#ifdef UTEK_ASM
-  if (current_function_pops_args)
-    fprintf (file, "\tret $%d\n", current_function_pops_args);
-  else
-    fprintf (file, "\tret $0\n");
-#else
-  if (current_function_pops_args)
-    fprintf (file, "\tret %d\n", current_function_pops_args);
-  else
-    fprintf (file, "\tret 0\n");
-#endif
-}
-
-#endif /* MERLIN_TARGET || UTEK_ASM  */
-
-/* Value is 1 if hard register REGNO can hold a value of machine-mode MODE. */ 
-int
-hard_regno_mode_ok (regno, mode)
-     int regno;
-     enum machine_mode mode;
-{
-  int size = GET_MODE_UNIT_SIZE (mode);
-
-  if (FLOAT_MODE_P (mode))
-    {
-      if (size == UNITS_PER_WORD && regno < L1_REGNUM)
-       return 1;
-      if (size == UNITS_PER_WORD * 2
-         && (((regno & 1) == 0 && regno < FRAME_POINTER_REGNUM)))
-       return 1;
-      return 0;
-    }
-  if (size == UNITS_PER_WORD * 2
-      && (regno & 1) == 0 && regno < F0_REGNUM)
-    return 1;
-  if (size <= UNITS_PER_WORD
-      && (regno < F0_REGNUM || regno == FRAME_POINTER_REGNUM
-         || regno == STACK_POINTER_REGNUM))
-    return 1;
-  return 0;
-}
-
-int register_move_cost (CLASS1, CLASS2)
-     enum reg_class CLASS1;
-     enum reg_class CLASS2;
-{
-  if (CLASS1 == NO_REGS || CLASS2 == NO_REGS)
-    return 2;
-  if ((SUBSET_P (CLASS1, FP_REGS) && !SUBSET_P (CLASS2, FP_REGS))
-   || (!SUBSET_P (CLASS1, FP_REGS) && SUBSET_P (CLASS2, FP_REGS)))
-    return 8;
-  if (((CLASS1) == STACK_POINTER_REG && !SUBSET_P (CLASS2,GENERAL_REGS))
-      || ((CLASS2) == STACK_POINTER_REG && !SUBSET_P (CLASS1,GENERAL_REGS)))
-    return 6;
-  if (((CLASS1) == FRAME_POINTER_REG && !SUBSET_P (CLASS2,GENERAL_REGS))
-      || ((CLASS2) == FRAME_POINTER_REG && !SUBSET_P (CLASS1,GENERAL_REGS)))
-    return 6;
-  return 2;
-}
-
-#if 0
-/* We made the insn definitions copy from floating point to general
-  registers via the stack. */
-int secondary_memory_needed (CLASS1, CLASS2, M)
-     enum reg_class CLASS1;
-     enum reg_class CLASS2;
-     enum machine_mode M;
-{
-  int ret = ((SUBSET_P (CLASS1, FP_REGS) && !SUBSET_P (CLASS2, FP_REGS))
-   || (!SUBSET_P (CLASS1, FP_REGS) && SUBSET_P (CLASS2, FP_REGS)));
-  return ret;
-}
-#endif
-    
-
-/* ADDRESS_COST calls this.  This function is not optimal
-   for the 32032 & 32332, but it probably is better than
-   the default. */
-
-int
-calc_address_cost (operand)
-     rtx operand;
-{
-  int i;
-  int cost = 0;
-  if (GET_CODE (operand) == MEM)
-    cost += 3;
-  if (GET_CODE (operand) == MULT)
-    cost += 2;
-  switch (GET_CODE (operand))
-    {
-    case REG:
-      cost += 1;
-      break;
-    case POST_DEC:
-    case PRE_DEC:
-      break;
-    case CONST_INT:
-      if (INTVAL (operand) <= 7 && INTVAL (operand) >= -8)
-       break;
-      if (INTVAL (operand) < 0x2000 && INTVAL (operand) >= -0x2000)
-       {
-         cost +=1;
-         break;
-       }
-    case CONST:
-    case LABEL_REF:
-    case SYMBOL_REF:
-      cost +=3;
-      break;
-    case CONST_DOUBLE:
-      cost += 5;
-      break;
-    case MEM:
-      cost += calc_address_cost (XEXP (operand, 0));
-      break;
-    case MULT:
-    case PLUS:
-      for (i = 0; i < GET_RTX_LENGTH (GET_CODE (operand)); i++)
-       {
-         cost += calc_address_cost (XEXP (operand, i));
-       }
-    default:
-      break;
-    }
-  return cost;
-}
-
-/* Return the register class of a scratch register needed to copy IN into
-   or out of a register in CLASS in MODE.  If it can be done directly,
-   NO_REGS is returned.  */
-
-enum reg_class
-secondary_reload_class (class, mode, in)
-     enum reg_class class;
-     enum machine_mode mode ATTRIBUTE_UNUSED;
-     rtx in;
-{
-  int regno = true_regnum (in);
-
-  if (regno >= FIRST_PSEUDO_REGISTER)
-    regno = -1;
-
-  if ((class == FRAME_POINTER_REG && regno == STACK_POINTER_REGNUM)
-      || ( class == STACK_POINTER_REG && regno == FRAME_POINTER_REGNUM))
-    return GENERAL_REGS;
-  else
-    return NO_REGS;
-}
-
-/* Generate the rtx that comes from an address expression in the md file */
-/* The expression to be build is BASE[INDEX:SCALE].  To recognize this,
-   scale must be converted from an exponent (from ASHIFT) to a
-   multiplier (for MULT). */
-
-static rtx
-gen_indexed_expr (base, index, scale)
-     rtx base, index, scale;
-{
-  rtx addr;
-
-  /* This generates an invalid addressing mode, if BASE is
-     fp or sp.  This is handled by PRINT_OPERAND_ADDRESS.  */
-  if (GET_CODE (base) != REG && GET_CODE (base) != CONST_INT)
-    base = gen_rtx_MEM (SImode, base);
-  addr = gen_rtx_MULT (SImode, index,
-                      GEN_INT (1 << INTVAL (scale)));
-  addr = gen_rtx_PLUS (SImode, base, addr);
-  return addr;
-}
-
-\f
-/* Split one or more DImode RTL references into pairs of SImode
-   references.  The RTL can be REG, offsettable MEM, integer constant, or
-   CONST_DOUBLE.  "operands" is a pointer to an array of DImode RTL to
-   split and "num" is its length.  lo_half and hi_half are output arrays
-   that parallel "operands". */
-
-void
-split_di (operands, num, lo_half, hi_half)
-     rtx operands[];
-     int num;
-     rtx lo_half[], hi_half[];
-{
-  while (num--)
-    {
-      if (GET_CODE (operands[num]) == REG)
-       {
-         lo_half[num] = gen_rtx_REG (SImode, REGNO (operands[num]));
-         hi_half[num] = gen_rtx_REG (SImode, REGNO (operands[num]) + 1);
-       }
-      else if (CONSTANT_P (operands[num]))
-       {
-         split_double (operands[num], &lo_half[num], &hi_half[num]);
-       }
-      else if (offsettable_memref_p (operands[num]))
-       {
-         lo_half[num] = operands[num];
-         hi_half[num] = adjust_address (operands[num], SImode, 4);
-       }
-      else
-       abort ();
-    }
-}
-\f
-/* Return the best assembler insn template
-   for moving operands[1] into operands[0] as a fullword.  */
-
-static const char *
-singlemove_string (operands)
-     rtx *operands;
-{
-  if (GET_CODE (operands[1]) == CONST_INT
-      && INTVAL (operands[1]) <= 7
-      && INTVAL (operands[1]) >= -8)
-    return "movqd %1,%0";
-  return "movd %1,%0";
-}
-
-const char *
-output_move_double (operands)
-     rtx *operands;
-{
-  enum anon1 { REGOP, OFFSOP, PUSHOP, CNSTOP, RNDOP } optype0, optype1;
-  rtx latehalf[2];
-
-  /* First classify both operands.  */
-
-  if (REG_P (operands[0]))
-    optype0 = REGOP;
-  else if (offsettable_memref_p (operands[0]))
-    optype0 = OFFSOP;
-  else if (GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
-    optype0 = PUSHOP;
-  else
-    optype0 = RNDOP;
-
-  if (REG_P (operands[1]))
-    optype1 = REGOP;
-  else if (CONSTANT_P (operands[1])
-          || GET_CODE (operands[1]) == CONST_DOUBLE)
-    optype1 = CNSTOP;
-  else if (offsettable_memref_p (operands[1]))
-    optype1 = OFFSOP;
-  else if (GET_CODE (XEXP (operands[1], 0)) == PRE_DEC)
-    optype1 = PUSHOP;
-  else
-    optype1 = RNDOP;
-
-  /* Check for the cases that the operand constraints are not
-     supposed to allow to happen.  Abort if we get one,
-     because generating code for these cases is painful.  */
-
-  if (optype0 == RNDOP || optype1 == RNDOP)
-    abort ();
-
-  /* Ok, we can do one word at a time.
-     Normally we do the low-numbered word first,
-     but if either operand is autodecrementing then we
-     do the high-numbered word first.
-
-     In either case, set up in LATEHALF the operands to use
-     for the high-numbered word and in some cases alter the
-     operands in OPERANDS to be suitable for the low-numbered word.  */
-
-  if (optype0 == REGOP)
-    latehalf[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
-  else if (optype0 == OFFSOP)
-    latehalf[0] = adjust_address (operands[0], SImode, 4);
-  else
-    latehalf[0] = operands[0];
-
-  if (optype1 == REGOP)
-    latehalf[1] = gen_rtx_REG (SImode, REGNO (operands[1]) + 1);
-  else if (optype1 == OFFSOP)
-    latehalf[1] = adjust_address (operands[1], SImode, 4);
-  else if (optype1 == CNSTOP)
-    split_double (operands[1], &operands[1], &latehalf[1]);
-  else
-    latehalf[1] = operands[1];
-
-  /* If insn is effectively movd N(sp),tos then we will do the
-     high word first.  We should use the adjusted operand 1 (which is N+4(sp))
-     for the low word as well, to compensate for the first decrement of sp.
-     Given this, it doesn't matter which half we do "first".  */
-  if (optype0 == PUSHOP
-      && REGNO (XEXP (XEXP (operands[0], 0), 0)) == STACK_POINTER_REGNUM
-      && reg_overlap_mentioned_p (stack_pointer_rtx, operands[1]))
-    operands[1] = latehalf[1];
-
-  /* If one or both operands autodecrementing,
-     do the two words, high-numbered first.  */
-  else if (optype0 == PUSHOP || optype1 == PUSHOP)
-    {
-      output_asm_insn (singlemove_string (latehalf), latehalf);
-      return singlemove_string (operands);
-    }
-
-  /* If the first move would clobber the source of the second one,
-     do them in the other order.  */
-
-  /* Overlapping registers.  */
-  if (optype0 == REGOP && optype1 == REGOP
-      && REGNO (operands[0]) == REGNO (latehalf[1]))
-    {
-      /* Do that word.  */
-      output_asm_insn (singlemove_string (latehalf), latehalf);
-      /* Do low-numbered word.  */
-      return singlemove_string (operands);
-    }
-  /* Loading into a register which overlaps a register used in the address.  */
-  else if (optype0 == REGOP && optype1 != REGOP
-          && reg_overlap_mentioned_p (operands[0], operands[1]))
-    {
-      if (reg_mentioned_p (operands[0], XEXP (operands[1], 0))
-         && reg_mentioned_p (latehalf[0], XEXP (operands[1], 0)))
-       {
-         /* If both halves of dest are used in the src memory address,
-            load the destination address into the low reg (operands[0]).
-            Then it works to load latehalf first.  */
-         rtx xops[2];
-         xops[0] = XEXP (operands[1], 0);
-         xops[1] = operands[0];
-         output_asm_insn ("addr %a0,%1", xops);
-         operands[1] = gen_rtx_MEM (DImode, operands[0]);
-         latehalf[1] = adjust_address (operands[1], SImode, 4);
-         /* The first half has the overlap, Do the late half first.  */
-         output_asm_insn (singlemove_string (latehalf), latehalf);
-         /* Then clobber.  */
-         return singlemove_string (operands);
-       }
-      if (reg_mentioned_p (operands[0], XEXP (operands[1], 0)))
-       {
-         /* The first half has the overlap, Do the late half first.  */
-         output_asm_insn (singlemove_string (latehalf), latehalf);
-         /* Then clobber.  */
-         return singlemove_string (operands);
-       }
-    }
-
-  /* Normal case.  Do the two words, low-numbered first.  */
-
-  output_asm_insn (singlemove_string (operands), operands);
-
-  operands[0] = latehalf[0];
-  operands[1] = latehalf[1];
-  return singlemove_string (operands);
-}
-
-\f
-#define MAX_UNALIGNED_COPY (32)
-/* Expand string/block move operations.
-
-   operands[0] is the pointer to the destination.
-   operands[1] is the pointer to the source.
-   operands[2] is the number of bytes to move.
-   operands[3] is the alignment.  */
-
-static void
-move_tail (operands, bytes, offset)
-     rtx operands[];
-     int bytes;
-     int offset;
-{
-  if (bytes & 2)
-    {
-      emit_move_insn (adjust_address (operands[0], HImode, offset),
-                     adjust_address (operands[1], HImode, offset));
-      offset += 2;
-    }
-  if (bytes & 1)
-    emit_move_insn (adjust_address (operands[0], QImode, offset),
-                   adjust_address (operands[1], QImode, offset));
-}
-
-void
-expand_block_move (operands)
-     rtx operands[];
-{
-  rtx bytes_rtx        = operands[2];
-  rtx align_rtx = operands[3];
-  int constp   = (GET_CODE (bytes_rtx) == CONST_INT);
-  int bytes    = (constp ? INTVAL (bytes_rtx) : 0);
-  int align    = INTVAL (align_rtx);
-  rtx src_reg = gen_rtx_REG (Pmode, 1);
-  rtx dest_reg = gen_rtx_REG (Pmode, 2);
-  rtx count_reg = gen_rtx_REG (SImode, 0);
-
-  if (constp && bytes <= 0)
-    return;
-
-  if (constp && bytes < 20)
-    {
-      int words = bytes >> 2;
-
-      if (words)
-       {
-         if (words < 3 || flag_unroll_loops)
-           {
-             int offset = 0;
-
-             for (; words; words--, offset += 4)
-               emit_move_insn (adjust_address (operands[0], SImode, offset),
-                               adjust_address (operands[1], SImode, offset));
-           }
-         else
-           {
-             /* Use movmd. It is slower than multiple movd's but more
-                compact. It is also slower than movsd for large copies
-                but causes less registers reloading so is better than movsd
-                for small copies. */
-             rtx src, dest;
-             dest = copy_addr_to_reg (XEXP (operands[0], 0));
-             src = copy_addr_to_reg (XEXP (operands[1], 0));
-           
-             emit_insn (gen_movstrsi2(dest, src, GEN_INT (words)));
-           }
-       }
-      move_tail (operands, bytes & 3, bytes & ~3);
-      return;
-    }
-
-  if (align > UNITS_PER_WORD)
-    align = UNITS_PER_WORD;
-
-  /* Move the address into scratch registers.  */
-  emit_insn (gen_rtx_CLOBBER (VOIDmode, dest_reg));
-  emit_move_insn (dest_reg, XEXP (operands[0], 0));
-  operands[0] = gen_rtx_MEM (SImode, dest_reg);
-  emit_insn (gen_rtx_CLOBBER (VOIDmode, src_reg));
-  emit_move_insn (src_reg, XEXP (operands[1], 0));
-  operands[1] = gen_rtx_MEM (SImode, src_reg);
-  emit_insn (gen_rtx_CLOBBER (VOIDmode, count_reg));
-
-  if (constp && (align == UNITS_PER_WORD || bytes < MAX_UNALIGNED_COPY))
-    {
-      /* constant no of bytes and aligned or small enough copy to not bother
-       * aligning. Emit insns to copy by words.
-       */
-      if (bytes >> 2)
-       {
-         emit_move_insn (count_reg, GEN_INT (bytes >> 2));
-         emit_insn (gen_movstrsi1 (GEN_INT (4)));
-       }
-      /* insns to copy rest */
-      move_tail (operands, bytes & 3, 0);
-    }
-  else if (align == UNITS_PER_WORD)
-    {
-      /* insns to copy by words */
-      emit_insn (gen_lshrsi3 (count_reg, bytes_rtx, GEN_INT (2)));
-      emit_insn (gen_movstrsi1 (GEN_INT (4)));
-      if (constp)
-       {
-         move_tail (operands, bytes & 3, 0);
-       }
-      else
-       {
-         /* insns to copy rest */
-         emit_insn (gen_andsi3 (count_reg, bytes_rtx, GEN_INT (3)));
-         emit_insn (gen_movstrsi1 (const1_rtx));
-       }
-    }
-  else
-    {
-      /* Not aligned and we may have a lot to copy so it is worth
-       * aligning.
-       */
-      rtx aligned_label = gen_label_rtx ();
-      rtx bytes_reg;
-
-      bytes_reg = copy_to_mode_reg (SImode, bytes_rtx);
-      if (!constp)
-       {
-         /* Emit insns to test and skip over the alignment if it is
-          * not worth it. This doubles as a test to ensure that the alignment
-          * operation can't copy too many bytes
-          */
-         emit_insn (gen_cmpsi (bytes_reg, GEN_INT (MAX_UNALIGNED_COPY)));
-         emit_jump_insn (gen_blt (aligned_label));
-       }
-
-      /* Emit insns to do alignment at run time */
-      emit_insn (gen_negsi2 (count_reg, src_reg));
-      emit_insn (gen_andsi3 (count_reg, count_reg, GEN_INT (3)));
-      emit_insn (gen_subsi3 (bytes_reg, bytes_reg, count_reg));
-      emit_insn (gen_movstrsi1 (const1_rtx));
-      if (!constp)
-       emit_label (aligned_label);
-
-      /* insns to copy by words */
-      emit_insn (gen_lshrsi3 (count_reg, bytes_reg, GEN_INT (2)));
-      emit_insn (gen_movstrsi1 (GEN_INT (4)));
-
-      /* insns to copy rest */
-      emit_insn (gen_andsi3 (count_reg, bytes_reg, GEN_INT (3)));
-      emit_insn (gen_movstrsi1 (const1_rtx));
-    }
-}
-\f
-
-/* Returns 1 if OP contains a global symbol reference */
-
-int
-global_symbolic_reference_mentioned_p (op, f)
-     rtx op;
-     int f;
-{
-  register const char *fmt;
-  register int i;
-
-  if (GET_CODE (op) == SYMBOL_REF)
-    {
-      if (! SYMBOL_REF_FLAG (op))
-       return 1;
-      else
-        return 0;
-    }
-  else if (f && GET_CODE (op) != CONST)
-    return 0;
-
-  fmt = GET_RTX_FORMAT (GET_CODE (op));
-  for (i = GET_RTX_LENGTH (GET_CODE (op)) - 1; i >= 0; i--)
-    {
-      if (fmt[i] == 'E')
-       {
-         register int j;
-
-         for (j = XVECLEN (op, i) - 1; j >= 0; j--)
-           if (global_symbolic_reference_mentioned_p (XVECEXP (op, i, j), 0))
-             return 1;
-       }
-      else if (fmt[i] == 'e' 
-              && global_symbolic_reference_mentioned_p (XEXP (op, i), 0))
-       return 1;
-    }
-
-  return 0;
-}
-
-\f
-/* Returns 1 if OP contains a symbol reference */
-
-int
-symbolic_reference_mentioned_p (op)
-     rtx op;
-{
-  register const char *fmt;
-  register int i;
-
-  if (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == LABEL_REF)
-    return 1;
-
-  fmt = GET_RTX_FORMAT (GET_CODE (op));
-  for (i = GET_RTX_LENGTH (GET_CODE (op)) - 1; i >= 0; i--)
-    {
-      if (fmt[i] == 'E')
-       {
-         register int j;
-
-         for (j = XVECLEN (op, i) - 1; j >= 0; j--)
-           if (symbolic_reference_mentioned_p (XVECEXP (op, i, j)))
-             return 1;
-       }
-      else if (fmt[i] == 'e' && symbolic_reference_mentioned_p (XEXP (op, i)))
-       return 1;
-    }
-
-  return 0;
-}
-\f
-/* Table of machine-specific attributes.  */
-
-const struct attribute_spec ns32k_attribute_table[] =
-{
-  /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
-  /* Stdcall attribute says callee is responsible for popping arguments
-     if they are not variable.  */
-  { "stdcall", 0, 0, false, true,  true,  ns32k_handle_fntype_attribute },
-  /* Cdecl attribute says the callee is a normal C declaration */
-  { "cdecl",   0, 0, false, true,  true,  ns32k_handle_fntype_attribute },
-  { NULL,      0, 0, false, false, false, NULL }
-};
-
-/* Handle an attribute requiring a FUNCTION_TYPE, FIELD_DECL or TYPE_DECL;
-   arguments as in struct attribute_spec.handler.  */
-static tree
-ns32k_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
-      && TREE_CODE (*node) != FIELD_DECL
-      && TREE_CODE (*node) != TYPE_DECL)
-    {
-      warning ("`%s' attribute only applies to functions",
-              IDENTIFIER_POINTER (name));
-      *no_add_attrs = true;
-    }
-
-  return NULL_TREE;
-}
-
-\f
-/* Value is the number of bytes of arguments automatically
-   popped when returning from a subroutine call.
-   FUNDECL is the declaration node of the function (as a tree),
-   FUNTYPE is the data type of the function (as a tree),
-   or for a library call it is an identifier node for the subroutine name.
-   SIZE is the number of bytes of arguments passed on the stack.
-
-   On the ns32k, the RET insn may be used to pop them if the number
-     of args is fixed, but if the number is variable then the caller
-     must pop them all.  RET can't be used for library calls now
-     because the library is compiled with the Unix compiler.
-   Use of RET is a selectable option, since it is incompatible with
-   standard Unix calling sequences.  If the option is not selected,
-   the caller must always pop the args.
-
-   The attribute stdcall is equivalent to RET on a per module basis.  */
-
-int
-ns32k_return_pops_args (fundecl, funtype, size)
-     tree fundecl ATTRIBUTE_UNUSED;
-     tree funtype;
-     int size;
-{
-  int rtd = TARGET_RTD;
-
-  if (TREE_CODE (funtype) == IDENTIFIER_NODE)
-    return rtd ? size : 0;
-
-  /* Cdecl functions override -mrtd, and never pop the stack */
-  if (lookup_attribute ("cdecl", TYPE_ATTRIBUTES (funtype)))
-    return 0;
-
-  /* Stdcall functions will pop the stack if not variable args */
-  if (lookup_attribute ("stdcall", TYPE_ATTRIBUTES (funtype)))
-    rtd = 1;
-
-  if (rtd)
-    {
-      if (TYPE_ARG_TYPES (funtype) == NULL_TREE
-         || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (funtype))) == void_type_node))
-       return size;
-    }
-
-  return 0;
-}
-\f
-/* PRINT_OPERAND is defined to call this function,
-   which is easier to debug than putting all the code in
-   a macro definition in ns32k.h.  */
-
-/* XXX time 12% of cpu time is in fprintf for non optimizing */
-void
-print_operand (file, x, code)
-     FILE *file;
-     rtx x;
-     int code;
-{
-  if (code == '$')
-    PUT_IMMEDIATE_PREFIX (file);
-  else if (code == '?')
-    PUT_EXTERNAL_PREFIX (file);
-  else if (GET_CODE (x) == REG)
-    fprintf (file, "%s", ns32k_out_reg_names[REGNO (x)]);
-  else if (GET_CODE (x) == MEM)
-    {
-      output_address (XEXP (x, 0));
-    }
-  else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) != VOIDmode)
-    {
-      if (GET_MODE (x) == DFmode)
-       { 
-         union { double d; int i[2]; } u;
-         u.i[0] = CONST_DOUBLE_LOW (x); u.i[1] = CONST_DOUBLE_HIGH (x);
-         PUT_IMMEDIATE_PREFIX (file);
-#ifdef SEQUENT_ASM
-         /* Sequent likes its floating point constants as integers */
-         fprintf (file, "0Dx%08x%08x", u.i[1], u.i[0]);
-#else
-#ifdef ENCORE_ASM
-         fprintf (file, "0f%.20e", u.d); 
-#else
-         fprintf (file, "0d%.20e", u.d); 
-#endif
-#endif
-       }
-      else
-       { 
-         union { double d; int i[2]; } u;
-         u.i[0] = CONST_DOUBLE_LOW (x); u.i[1] = CONST_DOUBLE_HIGH (x);
-         PUT_IMMEDIATE_PREFIX (file);
-#ifdef SEQUENT_ASM
-         /* We have no way of winning if we can't get the bits
-            for a sequent floating point number.  */
-#if HOST_FLOAT_FORMAT != TARGET_FLOAT_FORMAT
-         abort ();
-#endif
-         {
-           union { float f; long l; } uu;
-           uu.f = u.d;
-           fprintf (file, "0Fx%08lx", uu.l);
-         }
-#else
-         fprintf (file, "0f%.20e", u.d); 
-#endif
-       }
-    }
-  else
-    {
-      if (flag_pic
-          && GET_CODE (x) == CONST
-          && symbolic_reference_mentioned_p (x))
-        {
-         fprintf (stderr, "illegal constant for pic-mode: \n");
-         print_rtl (stderr, x);
-          fprintf (stderr, "\nGET_CODE (x) == %d, CONST == %d, symbolic_reference_mentioned_p (x) == %d\n",
-                 GET_CODE (x), CONST, symbolic_reference_mentioned_p (x));
-         abort ();
-       }
-      else if (flag_pic
-               && (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == LABEL_REF))
-       {
-         output_addr_const (file, x);
-         fprintf (file, "(sb)");
-       }
-      else
-        {
-#ifdef NO_IMMEDIATE_PREFIX_IF_SYMBOLIC
-          if (GET_CODE (x) == CONST_INT)
-#endif
-           PUT_IMMEDIATE_PREFIX (file);
-          output_addr_const (file, x);
-       }
-    }
-}
-\f
-/* PRINT_OPERAND_ADDRESS is defined to call this function,
-   which is easier to debug than putting all the code in
-   a macro definition in ns32k.h .  */
-
-/* Completely rewritten to get this to work with Gas for PC532 Mach.
-   This function didn't work and I just wasn't able (nor very willing) to
-   figure out how it worked.
-   90-11-25 Tatu Yl|nen <ylo@cs.hut.fi> */
-
-void
-print_operand_address (file, addr)
-     register FILE *file;
-     register rtx addr;
-{
-  static const char scales[] = { 'b', 'w', 'd', 0, 'q', };
-  rtx offset, base, indexexp, tmp;
-  int scale;
-  extern int flag_pic;
-
-  if (GET_CODE (addr) == PRE_DEC || GET_CODE (addr) == POST_DEC)
-    {
-      fprintf (file, "tos");
-      return;
-    }
-
-  offset = NULL;
-  base = NULL;
-  indexexp = NULL;
-  while (addr != NULL)
-    {
-      if (GET_CODE (addr) == PLUS)
-       {
-         if (GET_CODE (XEXP (addr, 0)) == PLUS)
-           {
-             tmp = XEXP (addr, 1);
-             addr = XEXP (addr, 0);
-           }
-         else
-           {
-             tmp = XEXP (addr,0);
-             addr = XEXP (addr,1);
-           }
-       }
-      else
-       {
-         tmp = addr;
-         addr = NULL;
-       }
-      switch (GET_CODE (tmp))
-       {
-       case PLUS:
-         abort ();
-       case MEM:
-         if (base)
-           {
-             indexexp = base;
-             base = tmp;
-           }
-         else
-           base = tmp;
-         break;
-       case REG:
-         if (REGNO (tmp) < F0_REGNUM)
-           if (base)
-             {
-               indexexp = tmp;
-             }
-           else
-             base = tmp;
-         else
-           if (base)
-             {
-               indexexp = base;
-               base = tmp;
-             }
-           else
-             base = tmp;
-         break;
-       case MULT:
-         indexexp = tmp;
-         break;
-       case SYMBOL_REF:
-         if (flag_pic && ! CONSTANT_POOL_ADDRESS_P (tmp)
-             && ! SYMBOL_REF_FLAG (tmp))
-           {
-             if (base)
-               {
-                 if (indexexp)
-                   abort ();
-                 indexexp = base;
-               }
-             base = tmp;
-             break;
-           }
-       case CONST:
-         if (flag_pic && GET_CODE (tmp) == CONST)
-           {
-             rtx sym, off, tmp1;
-             tmp1 = XEXP (tmp,0);
-             if (GET_CODE (tmp1)  != PLUS)
-               abort ();
-
-             sym = XEXP (tmp1,0);
-             if (GET_CODE (sym) != SYMBOL_REF)
-               {
-                 off = sym;
-                 sym = XEXP (tmp1,1);
-               }
-             else
-               off = XEXP (tmp1,1);
-             if (GET_CODE (sym) == SYMBOL_REF)
-               {
-                 if (GET_CODE (off) != CONST_INT)
-                   abort ();
-
-                 if (CONSTANT_POOL_ADDRESS_P (sym)
-                     || SYMBOL_REF_FLAG (sym))
-                   {
-                     SYMBOL_REF_FLAG (tmp) = 1;
-                   }
-                 else
-                   {
-                     if (base)
-                       {
-                         if (indexexp)
-                           abort ();
-
-                         indexexp = base;
-                       }
-
-                     if (offset != 0)
-                       abort ();
-
-                     base = sym;
-                     offset = off;
-                     break;
-                   }
-               }
-           }
-       case CONST_INT:
-       case LABEL_REF:
-         if (offset)
-           offset = gen_rtx_PLUS (SImode, tmp, offset);
-         else
-           offset = tmp;
-         break;
-       default:
-         abort ();
-       }
-    }
-  if (! offset)
-    offset = const0_rtx;
-
-  if (base
-#ifndef INDEX_RATHER_THAN_BASE
-      && (flag_pic || TARGET_HIMEM)
-      && GET_CODE (base) != SYMBOL_REF 
-      && GET_CODE (offset) != CONST_INT
-#else
-  /* This is a re-implementation of the SEQUENT_ADDRESS_BUG fix.  */
-#endif
-      && !indexexp && GET_CODE (base) == REG
-      && REG_OK_FOR_INDEX_P (base))
-    {
-      indexexp = base;
-      base = NULL;
-    }
-
-  /* now, offset, base and indexexp are set */
-#ifndef BASE_REG_NEEDED
-  if (! base)
-    {
-#if defined (PC_RELATIVE) || defined (NO_ABSOLUTE_PREFIX_IF_SYMBOLIC)
-      if (GET_CODE (offset) == CONST_INT)
-#endif
-       PUT_ABSOLUTE_PREFIX (file);
-    }
-#endif
-
-  output_addr_const (file, offset);
-  if (base) /* base can be (REG ...) or (MEM ...) */
-    switch (GET_CODE (base))
-      {
-       /* now we must output base.  Possible alternatives are:
-          (rN)       (REG ...)
-          (sp)       (REG ...)
-          (fp)       (REG ...)
-          (pc)       (REG ...)  used for SYMBOL_REF and LABEL_REF, output
-          (disp(fp)) (MEM ...)       just before possible [rX:y]
-          (disp(sp)) (MEM ...)
-          (disp(sb)) (MEM ...)
-          */
-      case REG:
-       fprintf (file, "(%s)", ns32k_out_reg_names[REGNO (base)]);
-       break;
-      case SYMBOL_REF:
-       if (! flag_pic)
-         abort ();
-
-        fprintf (file, "(");
-       output_addr_const (file, base);
-       fprintf (file, "(sb))");
-        break;
-      case MEM:
-       addr = XEXP (base,0);
-       base = NULL;
-       offset = NULL;
-       while (addr != NULL)
-         {
-           if (GET_CODE (addr) == PLUS)
-             {
-               if (GET_CODE (XEXP (addr, 0)) == PLUS)
-                 {
-                   tmp = XEXP (addr, 1);
-                   addr = XEXP (addr, 0);
-                 }
-               else
-                 {
-                   tmp = XEXP (addr, 0);
-                   addr = XEXP (addr, 1);
-                 }
-             }
-           else
-             {
-               tmp = addr;
-               addr = NULL;
-             }
-           switch (GET_CODE (tmp))
-             {
-             case REG:
-               base = tmp;
-               break;
-             case CONST:
-             case CONST_INT:
-             case SYMBOL_REF:
-             case LABEL_REF:
-               if (offset)
-                 offset = gen_rtx_PLUS (SImode, tmp, offset);
-               else
-                 offset = tmp;
-               break;
-             default:
-               abort ();
-             }
-         }
-       if (! offset)
-         offset = const0_rtx;
-       fprintf (file, "(");
-       output_addr_const (file, offset);
-       if (base)
-         fprintf (file, "(%s)", ns32k_out_reg_names[REGNO (base)]);
-       else if (TARGET_SB)
-         fprintf (file, "(sb)");
-       else
-         abort ();
-       fprintf (file, ")");
-       break;
-      default:
-       abort ();
-      }
-#ifdef PC_RELATIVE
-  else if (GET_CODE (offset) != CONST_INT)
-    fprintf (file, "(pc)");
-#ifdef BASE_REG_NEEDED
-  else if (TARGET_SB)
-    fprintf (file, "(sb)");
-  else
-    abort ();
-#endif
-#endif /* PC_RELATIVE */
-
-  /* now print index if we have one */
-  if (indexexp)
-    {
-      if (GET_CODE (indexexp) == MULT)
-       {
-         scale = INTVAL (XEXP (indexexp, 1)) >> 1;
-         indexexp = XEXP (indexexp, 0);
-       }
-      else
-       scale = 0;
-      if (GET_CODE (indexexp) != REG || REGNO (indexexp) >= F0_REGNUM)
-       abort ();
-
-#ifdef UTEK_ASM
-      fprintf (file, "[%c`%s]",
-              scales[scale],
-              ns32k_out_reg_names[REGNO (indexexp)]);
-#else
-      fprintf (file, "[%s:%c]",
-              ns32k_out_reg_names[REGNO (indexexp)],
-              scales[scale]);
-#endif
-    }
-}
-\f
-/* National 32032 shifting is so bad that we can get
-   better performance in many common cases by using other
-   techniques.  */
-const char *
-output_shift_insn (operands)
-     rtx *operands;
-{
-  if (GET_CODE (operands[2]) == CONST_INT
-      && INTVAL (operands[2]) > 0
-      && INTVAL (operands[2]) <= 3)
-    {
-      if (GET_CODE (operands[0]) == REG)
-       {
-         if (GET_CODE (operands[1]) == REG)
-           {
-             if (REGNO (operands[0]) == REGNO (operands[1]))
-               {
-                 if (operands[2] == const1_rtx)
-                   return "addd %0,%0";
-                 else if (INTVAL (operands[2]) == 2)
-                   return "addd %0,%0\n\taddd %0,%0";
-               }
-             if (operands[2] == const1_rtx)
-               return "movd %1,%0\n\taddd %0,%0";
-           
-             operands[1] = gen_indexed_expr (const0_rtx, operands[1], operands[2]);
-             return "addr %a1,%0";
-           }
-         if (operands[2] == const1_rtx)
-           return "movd %1,%0\n\taddd %0,%0";
-       }
-      else if (GET_CODE (operands[1]) == REG)
-       {
-         operands[1] = gen_indexed_expr (const0_rtx, operands[1], operands[2]);
-         return "addr %a1,%0";
-       }
-      else if (INTVAL (operands[2]) == 1
-              && GET_CODE (operands[1]) == MEM
-              && rtx_equal_p (operands [0], operands[1]))
-       {
-         rtx temp = XEXP (operands[1], 0);
-       
-         if (GET_CODE (temp) == REG
-             || (GET_CODE (temp) == PLUS
-                 && GET_CODE (XEXP (temp, 0)) == REG
-                 && GET_CODE (XEXP (temp, 1)) == CONST_INT))
-           return "addd %0,%0";
-       }
-      else return "ashd %2,%0";
-    }
-  return "ashd %2,%0";
-}
-
-const char *
-output_move_dconst (n, s)
-       int n;
-       const char *s;
-{
-  static char r[32];
-
-  if (n > -9 && n < 8)
-    strcpy (r, "movqd ");
-  else if (n > 0 && n < 256)
-    strcpy (r, "movzbd ");
-  else if (n > 0 && n < 65536)
-    strcpy (r, "movzwd ");
-  else if (n < 0 && n > -129)
-    strcpy (r, "movxbd ");
-  else if (n < 0 && n > -32769)
-    strcpy (r, "movxwd ");
-  else
-    strcpy (r, "movd ");
-  strcat (r, s);
-  return r;
-}