/* Output variables, constants and external declarations, for GNU compiler.
   Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997,
   1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.

This file is part of GCC.

GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 2, or (at your option) any later
version.

GCC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
for more details.

You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING.  If not, write to the Free
Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA.  */


/* This file handles generation of all the assembler code
   *except* the instructions of a function.
   This includes declarations of variables and their initial values.

   We also output the assembler code for constants stored in memory
   and are responsible for combining constants with the same value.  */

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "tm.h"
#include "rtl.h"
#include "tree.h"
#include "flags.h"
#include "function.h"
#include "expr.h"
#include "hard-reg-set.h"
#include "regs.h"
#include "real.h"
#include "output.h"
#include "toplev.h"
#include "hashtab.h"
#include "c-pragma.h"
#include "ggc.h"
#include "langhooks.h"
#include "tm_p.h"
#include "debug.h"
#include "target.h"
#include "cgraph.h"

#ifdef XCOFF_DEBUGGING_INFO
#include "xcoffout.h"		/* Needed for external data
				   declarations for e.g. AIX 4.x.  */
#endif

#ifndef TRAMPOLINE_ALIGNMENT
#define TRAMPOLINE_ALIGNMENT FUNCTION_BOUNDARY
#endif

#ifndef ASM_STABS_OP
#define ASM_STABS_OP "\t.stabs\t"
#endif

/* The (assembler) name of the first globally-visible object output.  */
const char *first_global_object_name;
const char *weak_global_object_name;

struct addr_const;
struct constant_descriptor_rtx;
struct rtx_const;
struct pool_constant;

#define MAX_RTX_HASH_TABLE 61

struct varasm_status GTY(())
{
  /* Hash facility for making memory-constants
     from constant rtl-expressions.  It is used on RISC machines
     where immediate integer arguments and constant addresses are restricted
     so that such constants must be stored in memory.

     This pool of constants is reinitialized for each function
     so each function gets its own constants-pool that comes right before
     it.  */
  struct constant_descriptor_rtx ** GTY ((length ("MAX_RTX_HASH_TABLE")))
    x_const_rtx_hash_table;
  struct pool_constant ** GTY ((length ("MAX_RTX_HASH_TABLE")))
    x_const_rtx_sym_hash_table;

  /* Pointers to first and last constant in pool.  */
  struct pool_constant *x_first_pool;
  struct pool_constant *x_last_pool;

  /* Current offset in constant pool (does not include any machine-specific
     header).  */
  HOST_WIDE_INT x_pool_offset;

  /* Number of tree-constants deferred during the expansion of this
     function.  */
  unsigned int deferred_constants;
};

#define const_rtx_hash_table (cfun->varasm->x_const_rtx_hash_table)
#define const_rtx_sym_hash_table (cfun->varasm->x_const_rtx_sym_hash_table)
#define first_pool (cfun->varasm->x_first_pool)
#define last_pool (cfun->varasm->x_last_pool)
#define pool_offset (cfun->varasm->x_pool_offset)
#define n_deferred_constants (cfun->varasm->deferred_constants)

/* Number for making the label on the next
   constant that is stored in memory.  */

static GTY(()) int const_labelno;

/* Carry information from ASM_DECLARE_OBJECT_NAME
   to ASM_FINISH_DECLARE_OBJECT.  */

int size_directive_output;

/* The last decl for which assemble_variable was called,
   if it did ASM_DECLARE_OBJECT_NAME.
   If the last call to assemble_variable didn't do that,
   this holds 0.  */

tree last_assemble_variable_decl;

/* RTX_UNCHANGING_P in a MEM can mean it is stored into, for initialization.
   So giving constant the alias set for the type will allow such
   initializations to appear to conflict with the load of the constant.  We
   avoid this by giving all constants an alias set for just constants.
   Since there will be no stores to that alias set, nothing will ever
   conflict with them.  */

static HOST_WIDE_INT const_alias_set;

static const char *strip_reg_name (const char *);
static int contains_pointers_p (tree);
#ifdef ASM_OUTPUT_EXTERNAL
static bool incorporeal_function_p (tree);
#endif
static void decode_addr_const (tree, struct addr_const *);
static hashval_t const_desc_hash (const void *);
static int const_desc_eq (const void *, const void *);
static hashval_t const_hash_1 (const tree);
static int compare_constant (const tree, const tree);
static tree copy_constant (tree);
static void output_constant_def_contents (rtx);
static void decode_rtx_const (enum machine_mode, rtx, struct rtx_const *);
static unsigned int const_hash_rtx (enum machine_mode, rtx);
static int compare_constant_rtx (enum machine_mode, rtx,
				 struct constant_descriptor_rtx *);
static struct constant_descriptor_rtx * record_constant_rtx
  (enum machine_mode, rtx);
static struct pool_constant *find_pool_constant (struct function *, rtx);
static void mark_constant_pool (void);
static void mark_constants (rtx);
static int mark_constant (rtx *current_rtx, void *data);
static void output_addressed_constants (tree);
static unsigned HOST_WIDE_INT array_size_for_constructor (tree);
static unsigned min_align (unsigned, unsigned);
static void output_constructor (tree, unsigned HOST_WIDE_INT, unsigned int);
static void globalize_decl (tree);
static void maybe_assemble_visibility (tree);
static int in_named_entry_eq (const void *, const void *);
static hashval_t in_named_entry_hash (const void *);
#ifdef ASM_OUTPUT_BSS
static void asm_output_bss (FILE *, tree, const char *,
			    unsigned HOST_WIDE_INT, unsigned HOST_WIDE_INT);
#endif
#ifdef BSS_SECTION_ASM_OP
#ifdef ASM_OUTPUT_ALIGNED_BSS
static void asm_output_aligned_bss (FILE *, tree, const char *,
				    unsigned HOST_WIDE_INT, int)
     ATTRIBUTE_UNUSED;
#endif
#endif /* BSS_SECTION_ASM_OP */
static bool asm_emit_uninitialised (tree, const char*,
				    unsigned HOST_WIDE_INT,
				    unsigned HOST_WIDE_INT);
static void mark_weak (tree);

enum in_section { no_section, in_text, in_data, in_named
#ifdef BSS_SECTION_ASM_OP
  , in_bss
#endif
#ifdef CTORS_SECTION_ASM_OP
  , in_ctors
#endif
#ifdef DTORS_SECTION_ASM_OP
  , in_dtors
#endif
#ifdef READONLY_DATA_SECTION_ASM_OP
  , in_readonly_data
#endif
#ifdef EXTRA_SECTIONS
  , EXTRA_SECTIONS
#endif
};
static GTY(()) enum in_section in_section = no_section;

/* Return a nonzero value if DECL has a section attribute.  */
#ifndef IN_NAMED_SECTION
#define IN_NAMED_SECTION(DECL) \
  ((TREE_CODE (DECL) == FUNCTION_DECL || TREE_CODE (DECL) == VAR_DECL) \
   && DECL_SECTION_NAME (DECL) != NULL_TREE)
#endif

/* Text of section name when in_section == in_named.  */
static GTY(()) const char *in_named_name;

/* Hash table of flags that have been used for a particular named section.  */

struct in_named_entry GTY(())
{
  const char *name;
  unsigned int flags;
  bool declared;
};

static GTY((param_is (struct in_named_entry))) htab_t in_named_htab;

/* Define functions like text_section for any extra sections.  */
#ifdef EXTRA_SECTION_FUNCTIONS
EXTRA_SECTION_FUNCTIONS
#endif

/* Tell assembler to switch to text section.  */

void
text_section (void)
{
  if (in_section != in_text)
    {
      in_section = in_text;
      fprintf (asm_out_file, "%s\n", TEXT_SECTION_ASM_OP);
    }
}

/* Tell assembler to switch to data section.  */

void
data_section (void)
{
  if (in_section != in_data)
    {
      in_section = in_data;
      if (flag_shared_data)
	{
#ifdef SHARED_SECTION_ASM_OP
	  fprintf (asm_out_file, "%s\n", SHARED_SECTION_ASM_OP);
#else
	  fprintf (asm_out_file, "%s\n", DATA_SECTION_ASM_OP);
#endif
	}
      else
	fprintf (asm_out_file, "%s\n", DATA_SECTION_ASM_OP);
    }
}

/* Tell assembler to switch to read-only data section.  This is normally
   the text section.  */

void
readonly_data_section (void)
{
#ifdef READONLY_DATA_SECTION
  READONLY_DATA_SECTION ();  /* Note this can call data_section.  */
#else
#ifdef READONLY_DATA_SECTION_ASM_OP
  if (in_section != in_readonly_data)
    {
      in_section = in_readonly_data;
      fputs (READONLY_DATA_SECTION_ASM_OP, asm_out_file);
      fputc ('\n', asm_out_file);
    }
#else
  text_section ();
#endif
#endif
}

/* Determine if we're in the text section.  */

int
in_text_section (void)
{
  return in_section == in_text;
}

/* Determine if we're in the data section.  */

int
in_data_section (void)
{
  return in_section == in_data;
}

/* Helper routines for maintaining in_named_htab.  */

static int
in_named_entry_eq (const void *p1, const void *p2)
{
  const struct in_named_entry *old = p1;
  const char *new = p2;

  return strcmp (old->name, new) == 0;
}

static hashval_t
in_named_entry_hash (const void *p)
{
  const struct in_named_entry *old = p;
  return htab_hash_string (old->name);
}

/* If SECTION has been seen before as a named section, return the flags
   that were used.  Otherwise, return 0.  Note, that 0 is a perfectly valid
   set of flags for a section to have, so 0 does not mean that the section
   has not been seen.  */

unsigned int
get_named_section_flags (const char *section)
{
  struct in_named_entry **slot;

  slot = (struct in_named_entry **)
    htab_find_slot_with_hash (in_named_htab, section,
			      htab_hash_string (section), NO_INSERT);

  return slot ? (*slot)->flags : 0;
}

/* Returns true if the section has been declared before.   Sets internal
   flag on this section in in_named_hash so subsequent calls on this
   section will return false.  */

bool
named_section_first_declaration (const char *name)
{
  struct in_named_entry **slot;

  slot = (struct in_named_entry **)
    htab_find_slot_with_hash (in_named_htab, name,
			      htab_hash_string (name), NO_INSERT);
  if (! (*slot)->declared)
    {
      (*slot)->declared = true;
      return true;
    }
  else
    {
      return false;
    }
}


/* Record FLAGS for SECTION.  If SECTION was previously recorded with a
   different set of flags, return false.  */

bool
set_named_section_flags (const char *section, unsigned int flags)
{
  struct in_named_entry **slot, *entry;

  slot = (struct in_named_entry **)
    htab_find_slot_with_hash (in_named_htab, section,
			      htab_hash_string (section), INSERT);
  entry = *slot;

  if (!entry)
    {
      entry = ggc_alloc (sizeof (*entry));
      *slot = entry;
      entry->name = ggc_strdup (section);
      entry->flags = flags;
      entry->declared = false;
    }
  else if (entry->flags != flags)
    return false;

  return true;
}

/* Tell assembler to change to section NAME with attributes FLAGS.  */

void
named_section_flags (const char *name, unsigned int flags)
{
  if (in_section != in_named || strcmp (name, in_named_name) != 0)
    {
      if (! set_named_section_flags (name, flags))
	abort ();

      (*targetm.asm_out.named_section) (name, flags);

      if (flags & SECTION_FORGET)
	in_section = no_section;
      else
	{
	  in_named_name = ggc_strdup (name);
	  in_section = in_named;
	}
    }
}

/* Tell assembler to change to section NAME for DECL.
   If DECL is NULL, just switch to section NAME.
   If NAME is NULL, get the name from DECL.
   If RELOC is 1, the initializer for DECL contains relocs.  */

void
named_section (tree decl, const char *name, int reloc)
{
  unsigned int flags;

  if (decl != NULL_TREE && !DECL_P (decl))
    abort ();
  if (name == NULL)
    name = TREE_STRING_POINTER (DECL_SECTION_NAME (decl));

  flags = (* targetm.section_type_flags) (decl, name, reloc);

  /* Sanity check user variables for flag changes.  Non-user
     section flag changes will abort in named_section_flags.
     However, don't complain if SECTION_OVERRIDE is set.
     We trust that the setter knows that it is safe to ignore
     the default flags for this decl.  */
  if (decl && ! set_named_section_flags (name, flags))
    {
      flags = get_named_section_flags (name);
      if ((flags & SECTION_OVERRIDE) == 0)
	error ("%J%D causes a section type conflict", decl, decl);
    }

  named_section_flags (name, flags);
}

/* If required, set DECL_SECTION_NAME to a unique name.  */

void
resolve_unique_section (tree decl, int reloc ATTRIBUTE_UNUSED,
			int flag_function_or_data_sections)
{
  if (DECL_SECTION_NAME (decl) == NULL_TREE
      && targetm.have_named_sections
      && (flag_function_or_data_sections
	  || DECL_ONE_ONLY (decl)))
    (*targetm.asm_out.unique_section) (decl, reloc);
}

#ifdef BSS_SECTION_ASM_OP

/* Tell the assembler to switch to the bss section.  */

void
bss_section (void)
{
  if (in_section != in_bss)
    {
      fprintf (asm_out_file, "%s\n", BSS_SECTION_ASM_OP);
      in_section = in_bss;
    }
}

#ifdef ASM_OUTPUT_BSS

/* Utility function for ASM_OUTPUT_BSS for targets to use if
   they don't support alignments in .bss.
   ??? It is believed that this function will work in most cases so such
   support is localized here.  */

static void
asm_output_bss (FILE *file, tree decl ATTRIBUTE_UNUSED,
		const char *name,
		unsigned HOST_WIDE_INT size ATTRIBUTE_UNUSED,
		unsigned HOST_WIDE_INT rounded)
{
  (*targetm.asm_out.globalize_label) (file, name);
  bss_section ();
#ifdef ASM_DECLARE_OBJECT_NAME
  last_assemble_variable_decl = decl;
  ASM_DECLARE_OBJECT_NAME (file, name, decl);
#else
  /* Standard thing is just output label for the object.  */
  ASM_OUTPUT_LABEL (file, name);
#endif /* ASM_DECLARE_OBJECT_NAME */
  ASM_OUTPUT_SKIP (file, rounded ? rounded : 1);
}

#endif

#ifdef ASM_OUTPUT_ALIGNED_BSS

/* Utility function for targets to use in implementing
   ASM_OUTPUT_ALIGNED_BSS.
   ??? It is believed that this function will work in most cases so such
   support is localized here.  */

static void
asm_output_aligned_bss (FILE *file, tree decl ATTRIBUTE_UNUSED,
			const char *name, unsigned HOST_WIDE_INT size,
			int align)
{
  bss_section ();
  ASM_OUTPUT_ALIGN (file, floor_log2 (align / BITS_PER_UNIT));
#ifdef ASM_DECLARE_OBJECT_NAME
  last_assemble_variable_decl = decl;
  ASM_DECLARE_OBJECT_NAME (file, name, decl);
#else
  /* Standard thing is just output label for the object.  */
  ASM_OUTPUT_LABEL (file, name);
#endif /* ASM_DECLARE_OBJECT_NAME */
  ASM_OUTPUT_SKIP (file, size ? size : 1);
}

#endif

#endif /* BSS_SECTION_ASM_OP */

/* Switch to the section for function DECL.

   If DECL is NULL_TREE, switch to the text section.
   ??? It's not clear that we will ever be passed NULL_TREE, but it's
   safer to handle it.  */

void
function_section (tree decl)
{
  if (decl != NULL_TREE
      && DECL_SECTION_NAME (decl) != NULL_TREE)
    named_section (decl, (char *) 0, 0);
  else
    text_section ();
}

/* Switch to section for variable DECL.  RELOC is the same as the
   argument to SELECT_SECTION.  */

void
variable_section (tree decl, int reloc)
{
  if (IN_NAMED_SECTION (decl))
    named_section (decl, NULL, reloc);
  else
    (*targetm.asm_out.select_section) (decl, reloc, DECL_ALIGN (decl));
}

/* Tell assembler to switch to the section for string merging.  */

void
mergeable_string_section (tree decl ATTRIBUTE_UNUSED,
			  unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED,
			  unsigned int flags ATTRIBUTE_UNUSED)
{
  if (HAVE_GAS_SHF_MERGE && flag_merge_constants
      && TREE_CODE (decl) == STRING_CST
      && TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE
      && align <= 256
      && TREE_STRING_LENGTH (decl) >= int_size_in_bytes (TREE_TYPE (decl)))
    {
      enum machine_mode mode;
      unsigned int modesize;
      const char *str;
      int i, j, len, unit;
      char name[30];

      mode = TYPE_MODE (TREE_TYPE (TREE_TYPE (decl)));
      modesize = GET_MODE_BITSIZE (mode);
      if (modesize >= 8 && modesize <= 256
	  && (modesize & (modesize - 1)) == 0)
	{
	  if (align < modesize)
	    align = modesize;

	  str = TREE_STRING_POINTER (decl);
	  len = TREE_STRING_LENGTH (decl);
	  unit = GET_MODE_SIZE (mode);

	  /* Check for embedded NUL characters.  */
	  for (i = 0; i < len; i += unit)
	    {
	      for (j = 0; j < unit; j++)
		if (str[i + j] != '\0')
		  break;
	      if (j == unit)
		break;
	    }
	  if (i == len - unit)
	    {
	      sprintf (name, ".rodata.str%d.%d", modesize / 8,
		       (int) (align / 8));
	      flags |= (modesize / 8) | SECTION_MERGE | SECTION_STRINGS;
	      if (!i && modesize < align)
		{
		  /* A "" string with requested alignment greater than
		     character size might cause a problem:
		     if some other string required even bigger
		     alignment than "", then linker might think the
		     "" is just part of padding after some other string
		     and not put it into the hash table initially.
		     But this means "" could have smaller alignment
		     than requested.  */
#ifdef ASM_OUTPUT_SECTION_START
		  named_section_flags (name, flags);
		  ASM_OUTPUT_SECTION_START (asm_out_file);
#else
		  readonly_data_section ();
#endif
		  return;
		}

	      named_section_flags (name, flags);
	      return;
	    }
	}
    }

  readonly_data_section ();
}

/* Tell assembler to switch to the section for constant merging.  */

void
mergeable_constant_section (enum machine_mode mode ATTRIBUTE_UNUSED,
			    unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED,
			    unsigned int flags ATTRIBUTE_UNUSED)
{
  unsigned int modesize = GET_MODE_BITSIZE (mode);

  if (HAVE_GAS_SHF_MERGE && flag_merge_constants
      && mode != VOIDmode
      && mode != BLKmode
      && modesize <= align
      && align >= 8
      && align <= 256
      && (align & (align - 1)) == 0)
    {
      char name[24];

      sprintf (name, ".rodata.cst%d", (int) (align / 8));
      flags |= (align / 8) | SECTION_MERGE;
      named_section_flags (name, flags);
      return;
    }

  readonly_data_section ();
}

/* Given NAME, a putative register name, discard any customary prefixes.  */

static const char *
strip_reg_name (const char *name)
{
#ifdef REGISTER_PREFIX
  if (!strncmp (name, REGISTER_PREFIX, strlen (REGISTER_PREFIX)))
    name += strlen (REGISTER_PREFIX);
#endif
  if (name[0] == '%' || name[0] == '#')
    name++;
  return name;
}

/* Decode an `asm' spec for a declaration as a register name.
   Return the register number, or -1 if nothing specified,
   or -2 if the ASMSPEC is not `cc' or `memory' and is not recognized,
   or -3 if ASMSPEC is `cc' and is not recognized,
   or -4 if ASMSPEC is `memory' and is not recognized.
   Accept an exact spelling or a decimal number.
   Prefixes such as % are optional.  */

int
decode_reg_name (const char *asmspec)
{
  if (asmspec != 0)
    {
      int i;

      /* Get rid of confusing prefixes.  */
      asmspec = strip_reg_name (asmspec);

      /* Allow a decimal number as a "register name".  */
      for (i = strlen (asmspec) - 1; i >= 0; i--)
	if (! ISDIGIT (asmspec[i]))
	  break;
      if (asmspec[0] != 0 && i < 0)
	{
	  i = atoi (asmspec);
	  if (i < FIRST_PSEUDO_REGISTER && i >= 0)
	    return i;
	  else
	    return -2;
	}

      for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
	if (reg_names[i][0]
	    && ! strcmp (asmspec, strip_reg_name (reg_names[i])))
	  return i;

#ifdef ADDITIONAL_REGISTER_NAMES
      {
	static const struct { const char *const name; const int number; } table[]
	  = ADDITIONAL_REGISTER_NAMES;

	for (i = 0; i < (int) ARRAY_SIZE (table); i++)
	  if (! strcmp (asmspec, table[i].name))
	    return table[i].number;
      }
#endif /* ADDITIONAL_REGISTER_NAMES */

      if (!strcmp (asmspec, "memory"))
	return -4;

      if (!strcmp (asmspec, "cc"))
	return -3;

      return -2;
    }

  return -1;
}

/* Create the DECL_RTL for a VAR_DECL or FUNCTION_DECL.  DECL should
   have static storage duration.  In other words, it should not be an
   automatic variable, including PARM_DECLs.

   There is, however, one exception: this function handles variables
   explicitly placed in a particular register by the user.

   ASMSPEC, if not 0, is the string which the user specified as the
   assembler symbol name.

   This is never called for PARM_DECL nodes.  */

void
make_decl_rtl (tree decl, const char *asmspec)
{
  const char *name = 0;
  int reg_number;
  rtx x;

  /* Check that we are not being given an automatic variable.  */
  /* A weak alias has TREE_PUBLIC set but not the other bits.  */
  if (TREE_CODE (decl) == PARM_DECL
      || TREE_CODE (decl) == RESULT_DECL
      || (TREE_CODE (decl) == VAR_DECL
	  && !TREE_STATIC (decl)
	  && !TREE_PUBLIC (decl)
	  && !DECL_EXTERNAL (decl)
	  && !DECL_REGISTER (decl)))
    abort ();
  /* And that we were not given a type or a label.  */
  else if (TREE_CODE (decl) == TYPE_DECL
	   || TREE_CODE (decl) == LABEL_DECL)
    abort ();

  /* For a duplicate declaration, we can be called twice on the
     same DECL node.  Don't discard the RTL already made.  */
  if (DECL_RTL_SET_P (decl))
    {
      /* If the old RTL had the wrong mode, fix the mode.  */
      if (GET_MODE (DECL_RTL (decl)) != DECL_MODE (decl))
	SET_DECL_RTL (decl, adjust_address_nv (DECL_RTL (decl),
					       DECL_MODE (decl), 0));

      /* ??? Another way to do this would be to maintain a hashed
	 table of such critters.  Instead of adding stuff to a DECL
	 to give certain attributes to it, we could use an external
	 hash map from DECL to set of attributes.  */

      /* Let the target reassign the RTL if it wants.
	 This is necessary, for example, when one machine specific
	 decl attribute overrides another.  */
      (* targetm.encode_section_info) (decl, DECL_RTL (decl), false);
      return;
    }

  reg_number = decode_reg_name (asmspec);
  if (reg_number == -2)
    {
      /* ASMSPEC is given, and not the name of a register.  Mark the
	 name with a star so assemble_name won't munge it.  */
      char *starred = alloca (strlen (asmspec) + 2);
      starred[0] = '*';
      strcpy (starred + 1, asmspec);
      change_decl_assembler_name (decl, get_identifier (starred));
    }

  name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));

  if (TREE_CODE (decl) != FUNCTION_DECL && DECL_REGISTER (decl))
    {
      /* First detect errors in declaring global registers.  */
      if (reg_number == -1)
	error ("%Jregister name not specified for '%D'", decl, decl);
      else if (reg_number < 0)
	error ("%Jinvalid register name for '%D'", decl, decl);
      else if (TYPE_MODE (TREE_TYPE (decl)) == BLKmode)
	error ("%Jdata type of '%D' isn't suitable for a register",
	       decl, decl);
      else if (! HARD_REGNO_MODE_OK (reg_number, TYPE_MODE (TREE_TYPE (decl))))
	error ("%Jregister specified for '%D' isn't suitable for data type",
               decl, decl);
      /* Now handle properly declared static register variables.  */
      else
	{
	  int nregs;

	  if (DECL_INITIAL (decl) != 0 && TREE_STATIC (decl))
	    {
	      DECL_INITIAL (decl) = 0;
	      error ("global register variable has initial value");
	    }
	  if (TREE_THIS_VOLATILE (decl))
	    warning ("volatile register variables don't work as you might wish");

	  /* If the user specified one of the eliminables registers here,
	     e.g., FRAME_POINTER_REGNUM, we don't want to get this variable
	     confused with that register and be eliminated.  This usage is
	     somewhat suspect...  */

	  SET_DECL_RTL (decl, gen_rtx_raw_REG (DECL_MODE (decl), reg_number));
	  ORIGINAL_REGNO (DECL_RTL (decl)) = reg_number;
	  REG_USERVAR_P (DECL_RTL (decl)) = 1;

	  if (TREE_STATIC (decl))
	    {
	      /* Make this register global, so not usable for anything
		 else.  */
#ifdef ASM_DECLARE_REGISTER_GLOBAL
	      ASM_DECLARE_REGISTER_GLOBAL (asm_out_file, decl, reg_number, name);
#endif
	      nregs = HARD_REGNO_NREGS (reg_number, DECL_MODE (decl));
	      while (nregs > 0)
		globalize_reg (reg_number + --nregs);
	    }

	  /* As a register variable, it has no section.  */
	  return;
	}
    }

  /* Now handle ordinary static variables and functions (in memory).
     Also handle vars declared register invalidly.  */

  if (reg_number >= 0 || reg_number == -3)
    error ("%Jregister name given for non-register variable '%D'", decl, decl);

  /* Specifying a section attribute on a variable forces it into a
     non-.bss section, and thus it cannot be common.  */
  if (TREE_CODE (decl) == VAR_DECL
      && DECL_SECTION_NAME (decl) != NULL_TREE
      && DECL_INITIAL (decl) == NULL_TREE
      && DECL_COMMON (decl))
    DECL_COMMON (decl) = 0;

  /* Variables can't be both common and weak.  */
  if (TREE_CODE (decl) == VAR_DECL && DECL_WEAK (decl))
    DECL_COMMON (decl) = 0;

  x = gen_rtx_SYMBOL_REF (Pmode, name);
  SYMBOL_REF_WEAK (x) = DECL_WEAK (decl);
  SYMBOL_REF_DECL (x) = decl;

  x = gen_rtx_MEM (DECL_MODE (decl), x);
  if (TREE_CODE (decl) != FUNCTION_DECL)
    set_mem_attributes (x, decl, 1);
  SET_DECL_RTL (decl, x);

  /* Optionally set flags or add text to the name to record information
     such as that it is a function name.
     If the name is changed, the macro ASM_OUTPUT_LABELREF
     will have to know how to strip this information.  */
  (* targetm.encode_section_info) (decl, DECL_RTL (decl), true);
}

/* Make the rtl for variable VAR be volatile.
   Use this only for static variables.  */

void
make_var_volatile (tree var)
{
  if (GET_CODE (DECL_RTL (var)) != MEM)
    abort ();

  MEM_VOLATILE_P (DECL_RTL (var)) = 1;
}

/* Output a string of literal assembler code
   for an `asm' keyword used between functions.  */

void
assemble_asm (tree string)
{
  app_enable ();

  if (TREE_CODE (string) == ADDR_EXPR)
    string = TREE_OPERAND (string, 0);

  fprintf (asm_out_file, "\t%s\n", TREE_STRING_POINTER (string));
}

/* Record an element in the table of global destructors.  SYMBOL is
   a SYMBOL_REF of the function to be called; PRIORITY is a number
   between 0 and MAX_INIT_PRIORITY.  */

void
default_stabs_asm_out_destructor (rtx symbol, int priority ATTRIBUTE_UNUSED)
{
  /* Tell GNU LD that this is part of the static destructor set.
     This will work for any system that uses stabs, most usefully
     aout systems.  */
  fprintf (asm_out_file, "%s\"___DTOR_LIST__\",22,0,0,", ASM_STABS_OP);
  assemble_name (asm_out_file, XSTR (symbol, 0));
  fputc ('\n', asm_out_file);
}

void
default_named_section_asm_out_destructor (rtx symbol, int priority)
{
  const char *section = ".dtors";
  char buf[16];

  /* ??? This only works reliably with the GNU linker.  */
  if (priority != DEFAULT_INIT_PRIORITY)
    {
      sprintf (buf, ".dtors.%.5u",
	       /* Invert the numbering so the linker puts us in the proper
		  order; constructors are run from right to left, and the
		  linker sorts in increasing order.  */
	       MAX_INIT_PRIORITY - priority);
      section = buf;
    }

  named_section_flags (section, SECTION_WRITE);
  assemble_align (POINTER_SIZE);
  assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
}

#ifdef DTORS_SECTION_ASM_OP
void
dtors_section (void)
{
  if (in_section != in_dtors)
    {
      in_section = in_dtors;
      fputs (DTORS_SECTION_ASM_OP, asm_out_file);
      fputc ('\n', asm_out_file);
    }
}

void
default_dtor_section_asm_out_destructor (rtx symbol,
					 int priority ATTRIBUTE_UNUSED)
{
  dtors_section ();
  assemble_align (POINTER_SIZE);
  assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
}
#endif

/* Likewise for global constructors.  */

void
default_stabs_asm_out_constructor (rtx symbol, int priority ATTRIBUTE_UNUSED)
{
  /* Tell GNU LD that this is part of the static destructor set.
     This will work for any system that uses stabs, most usefully
     aout systems.  */
  fprintf (asm_out_file, "%s\"___CTOR_LIST__\",22,0,0,", ASM_STABS_OP);
  assemble_name (asm_out_file, XSTR (symbol, 0));
  fputc ('\n', asm_out_file);
}

void
default_named_section_asm_out_constructor (rtx symbol, int priority)
{
  const char *section = ".ctors";
  char buf[16];

  /* ??? This only works reliably with the GNU linker.  */
  if (priority != DEFAULT_INIT_PRIORITY)
    {
      sprintf (buf, ".ctors.%.5u",
	       /* Invert the numbering so the linker puts us in the proper
		  order; constructors are run from right to left, and the
		  linker sorts in increasing order.  */
	       MAX_INIT_PRIORITY - priority);
      section = buf;
    }

  named_section_flags (section, SECTION_WRITE);
  assemble_align (POINTER_SIZE);
  assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
}

#ifdef CTORS_SECTION_ASM_OP
void
ctors_section (void)
{
  if (in_section != in_ctors)
    {
      in_section = in_ctors;
      fputs (CTORS_SECTION_ASM_OP, asm_out_file);
      fputc ('\n', asm_out_file);
    }
}

void
default_ctor_section_asm_out_constructor (rtx symbol,
					  int priority ATTRIBUTE_UNUSED)
{
  ctors_section ();
  assemble_align (POINTER_SIZE);
  assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
}
#endif

/* CONSTANT_POOL_BEFORE_FUNCTION may be defined as an expression with
   a nonzero value if the constant pool should be output before the
   start of the function, or a zero value if the pool should output
   after the end of the function.  The default is to put it before the
   start.  */

#ifndef CONSTANT_POOL_BEFORE_FUNCTION
#define CONSTANT_POOL_BEFORE_FUNCTION 1
#endif

/* DECL is an object (either VAR_DECL or FUNCTION_DECL) which is going
   to be output to assembler.
   Set first_global_object_name and weak_global_object_name as appropriate.  */

void
notice_global_symbol (tree decl)
{
  const char **type = &first_global_object_name;

  if (first_global_object_name
      || !TREE_PUBLIC (decl) || DECL_EXTERNAL (decl)
      || !DECL_NAME (decl)
      || (TREE_CODE (decl) != FUNCTION_DECL
	  && (TREE_CODE (decl) != VAR_DECL
	      || (DECL_COMMON (decl)
		  && (DECL_INITIAL (decl) == 0
		      || DECL_INITIAL (decl) == error_mark_node))))
      || GET_CODE (DECL_RTL (decl)) != MEM)
    return;

  /* We win when global object is found, but it is usefull to know about weak
     symbol as well so we can produce nicer unique names.  */
  if (DECL_WEAK (decl) || DECL_ONE_ONLY (decl))
    type = &weak_global_object_name;

  if (!*type)
    {
      const char *p;
      char *name;
      rtx decl_rtl = DECL_RTL (decl);

      p = (* targetm.strip_name_encoding) (XSTR (XEXP (decl_rtl, 0), 0));
      name = xstrdup (p);

      *type = name;
    }
}

/* Output assembler code for the constant pool of a function and associated
   with defining the name of the function.  DECL describes the function.
   NAME is the function's name.  For the constant pool, we use the current
   constant pool data.  */

void
assemble_start_function (tree decl, const char *fnname)
{
  int align;

  /* The following code does not need preprocessing in the assembler.  */

  app_disable ();

  if (CONSTANT_POOL_BEFORE_FUNCTION)
    output_constant_pool (fnname, decl);

  resolve_unique_section (decl, 0, flag_function_sections);
  function_section (decl);

  /* Tell assembler to move to target machine's alignment for functions.  */
  align = floor_log2 (FUNCTION_BOUNDARY / BITS_PER_UNIT);
  if (align < force_align_functions_log)
    align = force_align_functions_log;
  if (align > 0)
    {
      ASM_OUTPUT_ALIGN (asm_out_file, align);
    }

  /* Handle a user-specified function alignment.
     Note that we still need to align to FUNCTION_BOUNDARY, as above,
     because ASM_OUTPUT_MAX_SKIP_ALIGN might not do any alignment at all.  */
  if (align_functions_log > align
      && cfun->function_frequency != FUNCTION_FREQUENCY_UNLIKELY_EXECUTED)
    {
#ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
      ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file,
				 align_functions_log, align_functions - 1);
#else
      ASM_OUTPUT_ALIGN (asm_out_file, align_functions_log);
#endif
    }

#ifdef ASM_OUTPUT_FUNCTION_PREFIX
  ASM_OUTPUT_FUNCTION_PREFIX (asm_out_file, fnname);
#endif

  (*debug_hooks->begin_function) (decl);

  /* Make function name accessible from other files, if appropriate.  */

  if (TREE_PUBLIC (decl))
    {
      notice_global_symbol (decl);

      globalize_decl (decl);

      maybe_assemble_visibility (decl);
    }

  /* Do any machine/system dependent processing of the function name.  */
#ifdef ASM_DECLARE_FUNCTION_NAME
  ASM_DECLARE_FUNCTION_NAME (asm_out_file, fnname, current_function_decl);
#else
  /* Standard thing is just output label for the function.  */
  ASM_OUTPUT_LABEL (asm_out_file, fnname);
#endif /* ASM_DECLARE_FUNCTION_NAME */
}

/* Output assembler code associated with defining the size of the
   function.  DECL describes the function.  NAME is the function's name.  */

void
assemble_end_function (tree decl, const char *fnname)
{
#ifdef ASM_DECLARE_FUNCTION_SIZE
  ASM_DECLARE_FUNCTION_SIZE (asm_out_file, fnname, decl);
#endif
  if (! CONSTANT_POOL_BEFORE_FUNCTION)
    {
      output_constant_pool (fnname, decl);
      function_section (decl);	/* need to switch back */
    }
}

/* Assemble code to leave SIZE bytes of zeros.  */

void
assemble_zeros (unsigned HOST_WIDE_INT size)
{
  /* Do no output if -fsyntax-only.  */
  if (flag_syntax_only)
    return;

#ifdef ASM_NO_SKIP_IN_TEXT
  /* The `space' pseudo in the text section outputs nop insns rather than 0s,
     so we must output 0s explicitly in the text section.  */
  if (ASM_NO_SKIP_IN_TEXT && in_text_section ())
    {
      unsigned HOST_WIDE_INT i;
      for (i = 0; i < size; i++)
	assemble_integer (const0_rtx, 1, BITS_PER_UNIT, 1);
    }
  else
#endif
    if (size > 0)
      ASM_OUTPUT_SKIP (asm_out_file, size);
}

/* Assemble an alignment pseudo op for an ALIGN-bit boundary.  */

void
assemble_align (int align)
{
  if (align > BITS_PER_UNIT)
    {
      ASM_OUTPUT_ALIGN (asm_out_file, floor_log2 (align / BITS_PER_UNIT));
    }
}

/* Assemble a string constant with the specified C string as contents.  */

void
assemble_string (const char *p, int size)
{
  int pos = 0;
  int maximum = 2000;

  /* If the string is very long, split it up.  */

  while (pos < size)
    {
      int thissize = size - pos;
      if (thissize > maximum)
	thissize = maximum;

      ASM_OUTPUT_ASCII (asm_out_file, p, thissize);

      pos += thissize;
      p += thissize;
    }
}


#if defined  ASM_OUTPUT_ALIGNED_DECL_LOCAL
#define ASM_EMIT_LOCAL(decl, name, size, rounded) \
  ASM_OUTPUT_ALIGNED_DECL_LOCAL (asm_out_file, decl, name, size, DECL_ALIGN (decl))
#else
#if defined  ASM_OUTPUT_ALIGNED_LOCAL
#define ASM_EMIT_LOCAL(decl, name, size, rounded) \
  ASM_OUTPUT_ALIGNED_LOCAL (asm_out_file, name, size, DECL_ALIGN (decl))
#else
#define ASM_EMIT_LOCAL(decl, name, size, rounded) \
  ASM_OUTPUT_LOCAL (asm_out_file, name, size, rounded)
#endif
#endif

#if defined ASM_OUTPUT_ALIGNED_BSS
#define ASM_EMIT_BSS(decl, name, size, rounded) \
  ASM_OUTPUT_ALIGNED_BSS (asm_out_file, decl, name, size, DECL_ALIGN (decl))
#else
#if defined ASM_OUTPUT_BSS
#define ASM_EMIT_BSS(decl, name, size, rounded) \
  ASM_OUTPUT_BSS (asm_out_file, decl, name, size, rounded)
#else
#undef  ASM_EMIT_BSS
#endif
#endif

#if defined ASM_OUTPUT_ALIGNED_DECL_COMMON
#define ASM_EMIT_COMMON(decl, name, size, rounded) \
  ASM_OUTPUT_ALIGNED_DECL_COMMON (asm_out_file, decl, name, size, DECL_ALIGN (decl))
#else
#if defined ASM_OUTPUT_ALIGNED_COMMON
#define ASM_EMIT_COMMON(decl, name, size, rounded) \
  ASM_OUTPUT_ALIGNED_COMMON (asm_out_file, name, size, DECL_ALIGN (decl))
#else
#define ASM_EMIT_COMMON(decl, name, size, rounded) \
  ASM_OUTPUT_COMMON (asm_out_file, name, size, rounded)
#endif
#endif

static bool
asm_emit_uninitialised (tree decl, const char *name,
			unsigned HOST_WIDE_INT size ATTRIBUTE_UNUSED,
			unsigned HOST_WIDE_INT rounded ATTRIBUTE_UNUSED)
{
  enum
  {
    asm_dest_common,
    asm_dest_bss,
    asm_dest_local
  }
  destination = asm_dest_local;

  /* ??? We should handle .bss via select_section mechanisms rather than
     via special target hooks.  That would eliminate this special case.  */
  if (TREE_PUBLIC (decl))
    {
      if (!DECL_COMMON (decl))
#ifdef ASM_EMIT_BSS
	destination = asm_dest_bss;
#else
	return false;
#endif
      else
	destination = asm_dest_common;
    }

  if (destination == asm_dest_bss)
    globalize_decl (decl);
  resolve_unique_section (decl, 0, flag_data_sections);

  if (flag_shared_data)
    {
      switch (destination)
	{
#ifdef ASM_OUTPUT_SHARED_BSS
	case asm_dest_bss:
	  ASM_OUTPUT_SHARED_BSS (asm_out_file, decl, name, size, rounded);
	  return;
#endif
#ifdef ASM_OUTPUT_SHARED_COMMON
	case asm_dest_common:
	  ASM_OUTPUT_SHARED_COMMON (asm_out_file, name, size, rounded);
	  return;
#endif
#ifdef ASM_OUTPUT_SHARED_LOCAL
	case asm_dest_local:
	  ASM_OUTPUT_SHARED_LOCAL (asm_out_file, name, size, rounded);
	  return;
#endif
	default:
	  break;
	}
    }

  switch (destination)
    {
#ifdef ASM_EMIT_BSS
    case asm_dest_bss:
      ASM_EMIT_BSS (decl, name, size, rounded);
      break;
#endif
    case asm_dest_common:
      ASM_EMIT_COMMON (decl, name, size, rounded);
      break;
    case asm_dest_local:
      ASM_EMIT_LOCAL (decl, name, size, rounded);
      break;
    default:
      abort ();
    }

  return true;
}

/* Assemble everything that is needed for a variable or function declaration.
   Not used for automatic variables, and not used for function definitions.
   Should not be called for variables of incomplete structure type.

   TOP_LEVEL is nonzero if this variable has file scope.
   AT_END is nonzero if this is the special handling, at end of compilation,
   to define things that have had only tentative definitions.
   DONT_OUTPUT_DATA if nonzero means don't actually output the
   initial value (that will be done by the caller).  */

void
assemble_variable (tree decl, int top_level ATTRIBUTE_UNUSED,
		   int at_end ATTRIBUTE_UNUSED, int dont_output_data)
{
  const char *name;
  unsigned int align;
  int reloc = 0;
  rtx decl_rtl;

  if (lang_hooks.decls.prepare_assemble_variable)
    (*lang_hooks.decls.prepare_assemble_variable) (decl);

  last_assemble_variable_decl = 0;

  /* Normally no need to say anything here for external references,
     since assemble_external is called by the language-specific code
     when a declaration is first seen.  */

  if (DECL_EXTERNAL (decl))
    return;

  /* Output no assembler code for a function declaration.
     Only definitions of functions output anything.  */

  if (TREE_CODE (decl) == FUNCTION_DECL)
    return;

  /* Do nothing for global register variables.  */
  if (DECL_RTL_SET_P (decl) && GET_CODE (DECL_RTL (decl)) == REG)
    {
      TREE_ASM_WRITTEN (decl) = 1;
      return;
    }

  /* If type was incomplete when the variable was declared,
     see if it is complete now.  */

  if (DECL_SIZE (decl) == 0)
    layout_decl (decl, 0);

  /* Still incomplete => don't allocate it; treat the tentative defn
     (which is what it must have been) as an `extern' reference.  */

  if (!dont_output_data && DECL_SIZE (decl) == 0)
    {
      error ("%Jstorage size of `%D' isn't known", decl, decl);
      TREE_ASM_WRITTEN (decl) = 1;
      return;
    }

  /* The first declaration of a variable that comes through this function
     decides whether it is global (in C, has external linkage)
     or local (in C, has internal linkage).  So do nothing more
     if this function has already run.  */

  if (TREE_ASM_WRITTEN (decl))
    return;

  /* Make sure targetm.encode_section_info is invoked before we set
     ASM_WRITTEN.  */
  decl_rtl = DECL_RTL (decl);

  TREE_ASM_WRITTEN (decl) = 1;

  /* Do no output if -fsyntax-only.  */
  if (flag_syntax_only)
    return;

  app_disable ();

  if (! dont_output_data
      && ! host_integerp (DECL_SIZE_UNIT (decl), 1))
    {
      error ("%Jsize of variable '%D' is too large", decl, decl);
      return;
    }

  name = XSTR (XEXP (decl_rtl, 0), 0);
  if (TREE_PUBLIC (decl) && DECL_NAME (decl))
    notice_global_symbol (decl);

  /* Compute the alignment of this data.  */

  align = DECL_ALIGN (decl);

  /* In the case for initialing an array whose length isn't specified,
     where we have not yet been able to do the layout,
     figure out the proper alignment now.  */
  if (dont_output_data && DECL_SIZE (decl) == 0
      && TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE)
    align = MAX (align, TYPE_ALIGN (TREE_TYPE (TREE_TYPE (decl))));

  /* Some object file formats have a maximum alignment which they support.
     In particular, a.out format supports a maximum alignment of 4.  */
#ifndef MAX_OFILE_ALIGNMENT
#define MAX_OFILE_ALIGNMENT BIGGEST_ALIGNMENT
#endif
  if (align > MAX_OFILE_ALIGNMENT)
    {
      warning ("%Jalignment of '%D' is greater than maximum object "
               "file alignment.  Using %d", decl, decl,
	       MAX_OFILE_ALIGNMENT/BITS_PER_UNIT);
      align = MAX_OFILE_ALIGNMENT;
    }

  /* On some machines, it is good to increase alignment sometimes.  */
  if (! DECL_USER_ALIGN (decl))
    {
#ifdef DATA_ALIGNMENT
      align = DATA_ALIGNMENT (TREE_TYPE (decl), align);
#endif
#ifdef CONSTANT_ALIGNMENT
      if (DECL_INITIAL (decl) != 0 && DECL_INITIAL (decl) != error_mark_node)
	align = CONSTANT_ALIGNMENT (DECL_INITIAL (decl), align);
#endif
    }

  /* Reset the alignment in case we have made it tighter, so we can benefit
     from it in get_pointer_alignment.  */
  DECL_ALIGN (decl) = align;
  set_mem_align (decl_rtl, align);

  if (TREE_PUBLIC (decl))
    maybe_assemble_visibility (decl);

  /* Output any data that we will need to use the address of.  */
  if (DECL_INITIAL (decl) == error_mark_node)
    reloc = contains_pointers_p (TREE_TYPE (decl)) ? 3 : 0;
  else if (DECL_INITIAL (decl))
    {
      reloc = compute_reloc_for_constant (DECL_INITIAL (decl));
      output_addressed_constants (DECL_INITIAL (decl));
    }
  resolve_unique_section (decl, reloc, flag_data_sections);

  /* Handle uninitialized definitions.  */

  /* If the decl has been given an explicit section name, then it
     isn't common, and shouldn't be handled as such.  */
  if (DECL_SECTION_NAME (decl) || dont_output_data)
    ;
  /* We don't implement common thread-local data at present.  */
  else if (DECL_THREAD_LOCAL (decl))
    {
      if (DECL_COMMON (decl))
	sorry ("thread-local COMMON data not implemented");
    }
  else if (DECL_INITIAL (decl) == 0
	   || DECL_INITIAL (decl) == error_mark_node
	   || (flag_zero_initialized_in_bss
	       /* Leave constant zeroes in .rodata so they can be shared.  */
	       && !TREE_READONLY (decl)
	       && initializer_zerop (DECL_INITIAL (decl))))
    {
      unsigned HOST_WIDE_INT size = tree_low_cst (DECL_SIZE_UNIT (decl), 1);
      unsigned HOST_WIDE_INT rounded = size;

      /* Don't allocate zero bytes of common,
	 since that means "undefined external" in the linker.  */
      if (size == 0)
	rounded = 1;

      /* Round size up to multiple of BIGGEST_ALIGNMENT bits
	 so that each uninitialized object starts on such a boundary.  */
      rounded += (BIGGEST_ALIGNMENT / BITS_PER_UNIT) - 1;
      rounded = (rounded / (BIGGEST_ALIGNMENT / BITS_PER_UNIT)
		 * (BIGGEST_ALIGNMENT / BITS_PER_UNIT));

#if !defined(ASM_OUTPUT_ALIGNED_COMMON) && !defined(ASM_OUTPUT_ALIGNED_DECL_COMMON) && !defined(ASM_OUTPUT_ALIGNED_BSS)
      if ((unsigned HOST_WIDE_INT) DECL_ALIGN (decl) / BITS_PER_UNIT > rounded)
	warning ("%Jrequested alignment for '%D' is greater than "
                 "implemented alignment of %d", decl, decl, rounded);
#endif

      /* If the target cannot output uninitialized but not common global data
	 in .bss, then we have to use .data, so fall through.  */
      if (asm_emit_uninitialised (decl, name, size, rounded))
	return;
    }

  /* Handle initialized definitions.
     Also handle uninitialized global definitions if -fno-common and the
     target doesn't support ASM_OUTPUT_BSS.  */

  /* First make the assembler name(s) global if appropriate.  */
  if (TREE_PUBLIC (decl) && DECL_NAME (decl))
    globalize_decl (decl);

  /* Switch to the appropriate section.  */
  variable_section (decl, reloc);

  /* dbxout.c needs to know this.  */
  if (in_text_section ())
    DECL_IN_TEXT_SECTION (decl) = 1;

  /* Output the alignment of this data.  */
  if (align > BITS_PER_UNIT)
    {
      ASM_OUTPUT_ALIGN (asm_out_file,
			floor_log2 (DECL_ALIGN (decl) / BITS_PER_UNIT));
    }

  /* Do any machine/system dependent processing of the object.  */
#ifdef ASM_DECLARE_OBJECT_NAME
  last_assemble_variable_decl = decl;
  ASM_DECLARE_OBJECT_NAME (asm_out_file, name, decl);
#else
  /* Standard thing is just output label for the object.  */
  ASM_OUTPUT_LABEL (asm_out_file, name);
#endif /* ASM_DECLARE_OBJECT_NAME */

  if (!dont_output_data)
    {
      if (DECL_INITIAL (decl) && DECL_INITIAL (decl) != error_mark_node)
	/* Output the actual data.  */
	output_constant (DECL_INITIAL (decl),
			 tree_low_cst (DECL_SIZE_UNIT (decl), 1),
			 align);
      else
	/* Leave space for it.  */
	assemble_zeros (tree_low_cst (DECL_SIZE_UNIT (decl), 1));
    }
}

/* Return 1 if type TYPE contains any pointers.  */

static int
contains_pointers_p (tree type)
{
  switch (TREE_CODE (type))
    {
    case POINTER_TYPE:
    case REFERENCE_TYPE:
      /* I'm not sure whether OFFSET_TYPE needs this treatment,
	 so I'll play safe and return 1.  */
    case OFFSET_TYPE:
      return 1;

    case RECORD_TYPE:
    case UNION_TYPE:
    case QUAL_UNION_TYPE:
      {
	tree fields;
	/* For a type that has fields, see if the fields have pointers.  */
	for (fields = TYPE_FIELDS (type); fields; fields = TREE_CHAIN (fields))
	  if (TREE_CODE (fields) == FIELD_DECL
	      && contains_pointers_p (TREE_TYPE (fields)))
	    return 1;
	return 0;
      }

    case ARRAY_TYPE:
      /* An array type contains pointers if its element type does.  */
      return contains_pointers_p (TREE_TYPE (type));

    default:
      return 0;
    }
}

#ifdef ASM_OUTPUT_EXTERNAL
/* True if DECL is a function decl for which no out-of-line copy exists.
   It is assumed that DECL's assembler name has been set.  */

static bool
incorporeal_function_p (tree decl)
{
  if (TREE_CODE (decl) == FUNCTION_DECL && DECL_BUILT_IN (decl))
    {
      const char *name;

      if (DECL_BUILT_IN_CLASS (decl) == BUILT_IN_NORMAL
	  && DECL_FUNCTION_CODE (decl) == BUILT_IN_ALLOCA)
	return true;

      name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
      if (strncmp (name, "__builtin_", strlen ("__builtin_")) == 0)
	return true;
    }
  return false;
}
#endif

/* Output something to declare an external symbol to the assembler.
   (Most assemblers don't need this, so we normally output nothing.)
   Do nothing if DECL is not external.  */

void
assemble_external (tree decl ATTRIBUTE_UNUSED)
{
  /* Because most platforms do not define ASM_OUTPUT_EXTERNAL, the
     main body of this code is only rarely exercised.  To provide some
     testing, on all platforms, we make sure that the ASM_OUT_FILE is
     open.  If it's not, we should not be calling this function.  */
  if (!asm_out_file)
    abort ();

#ifdef ASM_OUTPUT_EXTERNAL
  if (DECL_P (decl) && DECL_EXTERNAL (decl) && TREE_PUBLIC (decl))
    {
      rtx rtl = DECL_RTL (decl);

      if (GET_CODE (rtl) == MEM && GET_CODE (XEXP (rtl, 0)) == SYMBOL_REF
	  && !SYMBOL_REF_USED (XEXP (rtl, 0))
	  && !incorporeal_function_p (decl))
	{
	  /* Some systems do require some output.  */
	  SYMBOL_REF_USED (XEXP (rtl, 0)) = 1;
	  ASM_OUTPUT_EXTERNAL (asm_out_file, decl, XSTR (XEXP (rtl, 0), 0));
	}
    }
#endif
}

/* Similar, for calling a library function FUN.  */

void
assemble_external_libcall (rtx fun)
{
  /* Declare library function name external when first used, if nec.  */
  if (! SYMBOL_REF_USED (fun))
    {
      SYMBOL_REF_USED (fun) = 1;
      (*targetm.asm_out.external_libcall) (fun);
    }
}

/* Assemble a label named NAME.  */

void
assemble_label (const char *name)
{
  ASM_OUTPUT_LABEL (asm_out_file, name);
}

/* Set the symbol_referenced flag for ID and notify callgraph code.  */
void
mark_referenced (tree id)
{
  if (!TREE_SYMBOL_REFERENCED (id))
    {
      struct cgraph_node *node;
      struct cgraph_varpool_node *vnode;

      if (!cgraph_global_info_ready)
	{
	  node = cgraph_node_for_identifier (id);
	  if (node)
	    cgraph_mark_needed_node (node);
	}

      vnode = cgraph_varpool_node_for_identifier (id);
      if (vnode)
	cgraph_varpool_mark_needed_node (vnode);
    }
  TREE_SYMBOL_REFERENCED (id) = 1;
}

/* Output to FILE a reference to the assembler name of a C-level name NAME.
   If NAME starts with a *, the rest of NAME is output verbatim.
   Otherwise NAME is transformed in an implementation-defined way
   (usually by the addition of an underscore).
   Many macros in the tm file are defined to call this function.  */

void
assemble_name (FILE *file, const char *name)
{
  const char *real_name;
  tree id;

  real_name = (* targetm.strip_name_encoding) (name);

  id = maybe_get_identifier (real_name);
  if (id)
    mark_referenced (id);

  if (name[0] == '*')
    fputs (&name[1], file);
  else
    ASM_OUTPUT_LABELREF (file, name);
}

/* Allocate SIZE bytes writable static space with a gensym name
   and return an RTX to refer to its address.  */

rtx
assemble_static_space (unsigned HOST_WIDE_INT size)
{
  char name[12];
  const char *namestring;
  rtx x;

#if 0
  if (flag_shared_data)
    data_section ();
#endif

  ASM_GENERATE_INTERNAL_LABEL (name, "LF", const_labelno);
  ++const_labelno;
  namestring = ggc_strdup (name);

  x = gen_rtx_SYMBOL_REF (Pmode, namestring);
  SYMBOL_REF_FLAGS (x) = SYMBOL_FLAG_LOCAL;

#ifdef ASM_OUTPUT_ALIGNED_DECL_LOCAL
  ASM_OUTPUT_ALIGNED_DECL_LOCAL (asm_out_file, NULL_TREE, name, size,
				 BIGGEST_ALIGNMENT);
#else
#ifdef ASM_OUTPUT_ALIGNED_LOCAL
  ASM_OUTPUT_ALIGNED_LOCAL (asm_out_file, name, size, BIGGEST_ALIGNMENT);
#else
  {
    /* Round size up to multiple of BIGGEST_ALIGNMENT bits
       so that each uninitialized object starts on such a boundary.  */
    /* Variable `rounded' might or might not be used in ASM_OUTPUT_LOCAL.  */
    unsigned HOST_WIDE_INT rounded ATTRIBUTE_UNUSED
      = ((size + (BIGGEST_ALIGNMENT / BITS_PER_UNIT) - 1)
	 / (BIGGEST_ALIGNMENT / BITS_PER_UNIT)
	 * (BIGGEST_ALIGNMENT / BITS_PER_UNIT));
    ASM_OUTPUT_LOCAL (asm_out_file, name, size, rounded);
  }
#endif
#endif
  return x;
}

/* Assemble the static constant template for function entry trampolines.
   This is done at most once per compilation.
   Returns an RTX for the address of the template.  */

#ifdef TRAMPOLINE_TEMPLATE
rtx
assemble_trampoline_template (void)
{
  char label[256];
  const char *name;
  int align;
  rtx symbol;

  /* By default, put trampoline templates in read-only data section.  */

#ifdef TRAMPOLINE_SECTION
  TRAMPOLINE_SECTION ();
#else
  readonly_data_section ();
#endif

  /* Write the assembler code to define one.  */
  align = floor_log2 (TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT);
  if (align > 0)
    {
      ASM_OUTPUT_ALIGN (asm_out_file, align);
    }

  (*targetm.asm_out.internal_label) (asm_out_file, "LTRAMP", 0);
  TRAMPOLINE_TEMPLATE (asm_out_file);

  /* Record the rtl to refer to it.  */
  ASM_GENERATE_INTERNAL_LABEL (label, "LTRAMP", 0);
  name = ggc_strdup (label);
  symbol = gen_rtx_SYMBOL_REF (Pmode, name);
  SYMBOL_REF_FLAGS (symbol) = SYMBOL_FLAG_LOCAL;

  return symbol;
}
#endif

/* A and B are either alignments or offsets.  Return the minimum alignment
   that may be assumed after adding the two together.  */

static inline unsigned
min_align (unsigned int a, unsigned int b)
{
  return (a | b) & -(a | b);
}

/* Return the assembler directive for creating a given kind of integer
   object.  SIZE is the number of bytes in the object and ALIGNED_P
   indicates whether it is known to be aligned.  Return NULL if the
   assembly dialect has no such directive.

   The returned string should be printed at the start of a new line and
   be followed immediately by the object's initial value.  */

const char *
integer_asm_op (int size, int aligned_p)
{
  struct asm_int_op *ops;

  if (aligned_p)
    ops = &targetm.asm_out.aligned_op;
  else
    ops = &targetm.asm_out.unaligned_op;

  switch (size)
    {
    case 1:
      return targetm.asm_out.byte_op;
    case 2:
      return ops->hi;
    case 4:
      return ops->si;
    case 8:
      return ops->di;
    case 16:
      return ops->ti;
    default:
      return NULL;
    }
}

/* Use directive OP to assemble an integer object X.  Print OP at the
   start of the line, followed immediately by the value of X.  */

void
assemble_integer_with_op (const char *op, rtx x)
{
  fputs (op, asm_out_file);
  output_addr_const (asm_out_file, x);
  fputc ('\n', asm_out_file);
}

/* The default implementation of the asm_out.integer target hook.  */

bool
default_assemble_integer (rtx x ATTRIBUTE_UNUSED,
			  unsigned int size ATTRIBUTE_UNUSED,
			  int aligned_p ATTRIBUTE_UNUSED)
{
  const char *op = integer_asm_op (size, aligned_p);
  return op && (assemble_integer_with_op (op, x), true);
}

/* Assemble the integer constant X into an object of SIZE bytes.  ALIGN is
   the alignment of the integer in bits.  Return 1 if we were able to output
   the constant, otherwise 0.  If FORCE is nonzero, abort if we can't output
   the constant.  */

bool
assemble_integer (rtx x, unsigned int size, unsigned int align, int force)
{
  int aligned_p;

  aligned_p = (align >= MIN (size * BITS_PER_UNIT, BIGGEST_ALIGNMENT));

  /* See if the target hook can handle this kind of object.  */
  if ((*targetm.asm_out.integer) (x, size, aligned_p))
    return true;

  /* If the object is a multi-byte one, try splitting it up.  Split
     it into words it if is multi-word, otherwise split it into bytes.  */
  if (size > 1)
    {
      enum machine_mode omode, imode;
      unsigned int subalign;
      unsigned int subsize, i;

      subsize = size > UNITS_PER_WORD? UNITS_PER_WORD : 1;
      subalign = MIN (align, subsize * BITS_PER_UNIT);
      omode = mode_for_size (subsize * BITS_PER_UNIT, MODE_INT, 0);
      imode = mode_for_size (size * BITS_PER_UNIT, MODE_INT, 0);

      for (i = 0; i < size; i += subsize)
	{
	  rtx partial = simplify_subreg (omode, x, imode, i);
	  if (!partial || !assemble_integer (partial, subsize, subalign, 0))
	    break;
	}
      if (i == size)
	return true;

      /* If we've printed some of it, but not all of it, there's no going
	 back now.  */
      if (i > 0)
	abort ();
    }

  if (force)
    abort ();

  return false;
}

void
assemble_real (REAL_VALUE_TYPE d, enum machine_mode mode, unsigned int align)
{
  long data[4];
  int i;
  int bitsize, nelts, nunits, units_per;

  /* This is hairy.  We have a quantity of known size.  real_to_target
     will put it into an array of *host* longs, 32 bits per element
     (even if long is more than 32 bits).  We need to determine the
     number of array elements that are occupied (nelts) and the number
     of *target* min-addressable units that will be occupied in the
     object file (nunits).  We cannot assume that 32 divides the
     mode's bitsize (size * BITS_PER_UNIT) evenly.

     size * BITS_PER_UNIT is used here to make sure that padding bits
     (which might appear at either end of the value; real_to_target
     will include the padding bits in its output array) are included.  */

  nunits = GET_MODE_SIZE (mode);
  bitsize = nunits * BITS_PER_UNIT;
  nelts = CEIL (bitsize, 32);
  units_per = 32 / BITS_PER_UNIT;

  real_to_target (data, &d, mode);

  /* Put out the first word with the specified alignment.  */
  assemble_integer (GEN_INT (data[0]), MIN (nunits, units_per), align, 1);
  nunits -= units_per;

  /* Subsequent words need only 32-bit alignment.  */
  align = min_align (align, 32);

  for (i = 1; i < nelts; i++)
    {
      assemble_integer (GEN_INT (data[i]), MIN (nunits, units_per), align, 1);
      nunits -= units_per;
    }
}

/* Given an expression EXP with a constant value,
   reduce it to the sum of an assembler symbol and an integer.
   Store them both in the structure *VALUE.
   Abort if EXP does not reduce.  */

struct addr_const GTY(())
{
  rtx base;
  HOST_WIDE_INT offset;
};

static void
decode_addr_const (tree exp, struct addr_const *value)
{
  tree target = TREE_OPERAND (exp, 0);
  int offset = 0;
  rtx x;

  while (1)
    {
      if (TREE_CODE (target) == COMPONENT_REF
	  && host_integerp (byte_position (TREE_OPERAND (target, 1)), 0))

	{
	  offset += int_byte_position (TREE_OPERAND (target, 1));
	  target = TREE_OPERAND (target, 0);
	}
      else if (TREE_CODE (target) == ARRAY_REF
	       || TREE_CODE (target) == ARRAY_RANGE_REF)
	{
	  offset += (tree_low_cst (TYPE_SIZE_UNIT (TREE_TYPE (target)), 1)
		     * tree_low_cst (TREE_OPERAND (target, 1), 0));
	  target = TREE_OPERAND (target, 0);
	}
      else
	break;
    }

  switch (TREE_CODE (target))
    {
    case VAR_DECL:
    case FUNCTION_DECL:
      x = DECL_RTL (target);
      break;

    case LABEL_DECL:
      x = gen_rtx_MEM (FUNCTION_MODE,
		       gen_rtx_LABEL_REF (VOIDmode, force_label_rtx (target)));
      break;

    case REAL_CST:
    case STRING_CST:
    case COMPLEX_CST:
    case CONSTRUCTOR:
    case INTEGER_CST:
      x = output_constant_def (target, 1);
      break;

    default:
      abort ();
    }

  if (GET_CODE (x) != MEM)
    abort ();
  x = XEXP (x, 0);

  value->base = x;
  value->offset = offset;
}

/* We do RTX_UNSPEC + XINT (blah), so nothing can go after RTX_UNSPEC.  */
enum kind { RTX_UNKNOWN, RTX_DOUBLE, RTX_VECTOR, RTX_INT, RTX_UNSPEC };
struct rtx_const GTY(())
{
  ENUM_BITFIELD(kind) kind : 16;
  ENUM_BITFIELD(machine_mode) mode : 16;
  union rtx_const_un {
    REAL_VALUE_TYPE GTY ((tag ("4"))) du;
    struct rtx_const_u_addr {
      rtx base;
      const char *symbol;
      HOST_WIDE_INT offset;
    } GTY ((tag ("1"))) addr;
    struct rtx_const_u_di {
      HOST_WIDE_INT high;
      HOST_WIDE_INT low;
    } GTY ((tag ("0"))) di;

    /* The max vector size we have is 16 wide; two variants for
       integral and floating point vectors.  */
    struct rtx_const_int_vec {
      HOST_WIDE_INT high;
      HOST_WIDE_INT low;
    } GTY ((tag ("2"))) int_vec[16];

    REAL_VALUE_TYPE GTY ((tag ("3"))) fp_vec[8];

  } GTY ((desc ("%1.kind >= RTX_INT"), descbits ("1"))) un;
};

/* Uniquize all constants that appear in memory.
   Each constant in memory thus far output is recorded
   in `const_desc_table'.  */

struct constant_descriptor_tree GTY(())
{
  /* A MEM for the constant.  */
  rtx rtl;

  /* The value of the constant.  */
  tree value;
};

static GTY((param_is (struct constant_descriptor_tree)))
     htab_t const_desc_htab;

static struct constant_descriptor_tree * build_constant_desc (tree);
static void maybe_output_constant_def_contents (struct constant_descriptor_tree *, int);

/* Compute a hash code for a constant expression.  */

static hashval_t
const_desc_hash (const void *ptr)
{
  return const_hash_1 (((struct constant_descriptor_tree *)ptr)->value);
}

static hashval_t
const_hash_1 (const tree exp)
{
  const char *p;
  hashval_t hi;
  int len, i;
  enum tree_code code = TREE_CODE (exp);

  /* Either set P and LEN to the address and len of something to hash and
     exit the switch or return a value.  */

  switch (code)
    {
    case INTEGER_CST:
      p = (char *) &TREE_INT_CST (exp);
      len = sizeof TREE_INT_CST (exp);
      break;

    case REAL_CST:
      return real_hash (TREE_REAL_CST_PTR (exp));

    case STRING_CST:
      if (flag_writable_strings)
	{
	  p = (char *) &exp;
	  len = sizeof exp;
	}
      else
	{
	  p = TREE_STRING_POINTER (exp);
	  len = TREE_STRING_LENGTH (exp);
	}
      break;

    case COMPLEX_CST:
      return (const_hash_1 (TREE_REALPART (exp)) * 5
	      + const_hash_1 (TREE_IMAGPART (exp)));

    case CONSTRUCTOR:
      if (TREE_CODE (TREE_TYPE (exp)) == SET_TYPE)
	{
	  char *tmp;

	  len = int_size_in_bytes (TREE_TYPE (exp));
	  tmp = alloca (len);
	  get_set_constructor_bytes (exp, (unsigned char *) tmp, len);
	  p = tmp;
	  break;
	}
      else
	{
	  tree link;

	  hi = 5 + int_size_in_bytes (TREE_TYPE (exp));

	  for (link = CONSTRUCTOR_ELTS (exp); link; link = TREE_CHAIN (link))
	    if (TREE_VALUE (link))
	      hi = hi * 603 + const_hash_1 (TREE_VALUE (link));

	  return hi;
	}

    case ADDR_EXPR:
    case FDESC_EXPR:
      {
	struct addr_const value;

	decode_addr_const (exp, &value);
	if (GET_CODE (value.base) == SYMBOL_REF)
	  {
	    /* Don't hash the address of the SYMBOL_REF;
	       only use the offset and the symbol name.  */
	    hi = value.offset;
	    p = XSTR (value.base, 0);
	    for (i = 0; p[i] != 0; i++)
	      hi = ((hi * 613) + (unsigned) (p[i]));
	  }
	else if (GET_CODE (value.base) == LABEL_REF)
	  hi = value.offset + CODE_LABEL_NUMBER (XEXP (value.base, 0)) * 13;
	else
	  abort ();
      }
      return hi;

    case PLUS_EXPR:
    case MINUS_EXPR:
      return (const_hash_1 (TREE_OPERAND (exp, 0)) * 9
	      + const_hash_1 (TREE_OPERAND (exp, 1)));

    case NOP_EXPR:
    case CONVERT_EXPR:
    case NON_LVALUE_EXPR:
      return const_hash_1 (TREE_OPERAND (exp, 0)) * 7 + 2;

    default:
      /* A language specific constant. Just hash the code.  */
      return code;
    }

  /* Compute hashing function.  */
  hi = len;
  for (i = 0; i < len; i++)
    hi = ((hi * 613) + (unsigned) (p[i]));

  return hi;
}

/* Wrapper of compare_constant, for the htab interface.  */
static int
const_desc_eq (const void *p1, const void *p2)
{
  return compare_constant (((struct constant_descriptor_tree *)p1)->value,
			   ((struct constant_descriptor_tree *)p2)->value);
}

/* Compare t1 and t2, and return 1 only if they are known to result in
   the same bit pattern on output.  */

static int
compare_constant (const tree t1, const tree t2)
{
  enum tree_code typecode;

  if (t1 == NULL_TREE)
    return t2 == NULL_TREE;
  if (t2 == NULL_TREE)
    return 0;

  if (TREE_CODE (t1) != TREE_CODE (t2))
    return 0;

  switch (TREE_CODE (t1))
    {
    case INTEGER_CST:
      /* Integer constants are the same only if the same width of type.  */
      if (TYPE_PRECISION (TREE_TYPE (t1)) != TYPE_PRECISION (TREE_TYPE (t2)))
	return 0;
      return tree_int_cst_equal (t1, t2);

    case REAL_CST:
      /* Real constants are the same only if the same width of type.  */
      if (TYPE_PRECISION (TREE_TYPE (t1)) != TYPE_PRECISION (TREE_TYPE (t2)))
	return 0;

      return REAL_VALUES_IDENTICAL (TREE_REAL_CST (t1), TREE_REAL_CST (t2));

    case STRING_CST:
      if (flag_writable_strings)
	return t1 == t2;

      if (TYPE_MODE (TREE_TYPE (t1)) != TYPE_MODE (TREE_TYPE (t2)))
	return 0;

      return (TREE_STRING_LENGTH (t1) == TREE_STRING_LENGTH (t2)
	      && ! memcmp (TREE_STRING_POINTER (t1), TREE_STRING_POINTER (t2),
			 TREE_STRING_LENGTH (t1)));

    case COMPLEX_CST:
      return (compare_constant (TREE_REALPART (t1), TREE_REALPART (t2))
	      && compare_constant (TREE_IMAGPART (t1), TREE_IMAGPART (t2)));

    case CONSTRUCTOR:
      typecode = TREE_CODE (TREE_TYPE (t1));
      if (typecode != TREE_CODE (TREE_TYPE (t2)))
	return 0;

      if (typecode == SET_TYPE)
	{
	  int len = int_size_in_bytes (TREE_TYPE (t2));
	  unsigned char *tmp1, *tmp2;

	  if (int_size_in_bytes (TREE_TYPE (t1)) != len)
	    return 0;

	  tmp1 = alloca (len);
	  tmp2 = alloca (len);

	  if (get_set_constructor_bytes (t1, tmp1, len) != NULL_TREE)
	    return 0;
	  if (get_set_constructor_bytes (t2, tmp2, len) != NULL_TREE)
	    return 0;

	  return memcmp (tmp1, tmp2, len) == 0;
	}
      else
	{
	  tree l1, l2;

	  if (typecode == ARRAY_TYPE)
	    {
	      HOST_WIDE_INT size_1 = int_size_in_bytes (TREE_TYPE (t1));
	      /* For arrays, check that the sizes all match.  */
	      if (TYPE_MODE (TREE_TYPE (t1)) != TYPE_MODE (TREE_TYPE (t2))
		  || size_1 == -1
		  || size_1 != int_size_in_bytes (TREE_TYPE (t2)))
		return 0;
	    }
	  else
	    {
	      /* For record and union constructors, require exact type
                 equality.  */
	      if (TREE_TYPE (t1) != TREE_TYPE (t2))
		return 0;
	    }

	  for (l1 = CONSTRUCTOR_ELTS (t1), l2 = CONSTRUCTOR_ELTS (t2);
	       l1 && l2;
	       l1 = TREE_CHAIN (l1), l2 = TREE_CHAIN (l2))
	    {
	      /* Check that each value is the same...  */
	      if (! compare_constant (TREE_VALUE (l1), TREE_VALUE (l2)))
		return 0;
	      /* ... and that they apply to the same fields!  */
	      if (typecode == ARRAY_TYPE)
		{
		  if (! compare_constant (TREE_PURPOSE (l1),
					  TREE_PURPOSE (l2)))
		    return 0;
		}
	      else
		{
		  if (TREE_PURPOSE (l1) != TREE_PURPOSE (l2))
		    return 0;
		}
	    }

	  return l1 == NULL_TREE && l2 == NULL_TREE;
	}

    case ADDR_EXPR:
    case FDESC_EXPR:
      {
	struct addr_const value1, value2;

	decode_addr_const (t1, &value1);
	decode_addr_const (t2, &value2);
	return (value1.offset == value2.offset
		&& strcmp (XSTR (value1.base, 0), XSTR (value2.base, 0)) == 0);
      }

    case PLUS_EXPR:
    case MINUS_EXPR:
    case RANGE_EXPR:
      return (compare_constant (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0))
	      && compare_constant(TREE_OPERAND (t1, 1), TREE_OPERAND (t2, 1)));

    case NOP_EXPR:
    case CONVERT_EXPR:
    case NON_LVALUE_EXPR:
      return compare_constant (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0));

    default:
      {
	tree nt1, nt2;
	nt1 = (*lang_hooks.expand_constant) (t1);
	nt2 = (*lang_hooks.expand_constant) (t2);
	if (nt1 != t1 || nt2 != t2)
	  return compare_constant (nt1, nt2);
	else
	  return 0;
      }
    }

  /* Should not get here.  */
  abort ();
}

/* Make a copy of the whole tree structure for a constant.  This
   handles the same types of nodes that compare_constant handles.
   Writable string constants are never copied.  */

static tree
copy_constant (tree exp)
{
  switch (TREE_CODE (exp))
    {
    case ADDR_EXPR:
      /* For ADDR_EXPR, we do not want to copy the decl whose address
	 is requested.  We do want to copy constants though.  */
      if (TREE_CODE_CLASS (TREE_CODE (TREE_OPERAND (exp, 0))) == 'c')
	return build1 (TREE_CODE (exp), TREE_TYPE (exp),
		       copy_constant (TREE_OPERAND (exp, 0)));
      else
	return copy_node (exp);

    case STRING_CST:
      if (flag_writable_strings)
	return exp;
      /* FALLTHROUGH */
    case INTEGER_CST:
    case REAL_CST:
      return copy_node (exp);

    case COMPLEX_CST:
      return build_complex (TREE_TYPE (exp),
			    copy_constant (TREE_REALPART (exp)),
			    copy_constant (TREE_IMAGPART (exp)));

    case PLUS_EXPR:
    case MINUS_EXPR:
      return build (TREE_CODE (exp), TREE_TYPE (exp),
		    copy_constant (TREE_OPERAND (exp, 0)),
		    copy_constant (TREE_OPERAND (exp, 1)));

    case NOP_EXPR:
    case CONVERT_EXPR:
    case NON_LVALUE_EXPR:
    case VIEW_CONVERT_EXPR:
      return build1 (TREE_CODE (exp), TREE_TYPE (exp),
		     copy_constant (TREE_OPERAND (exp, 0)));

    case CONSTRUCTOR:
      {
	tree copy = copy_node (exp);
	tree list = copy_list (CONSTRUCTOR_ELTS (exp));
	tree tail;

	CONSTRUCTOR_ELTS (copy) = list;
	for (tail = list; tail; tail = TREE_CHAIN (tail))
	  TREE_VALUE (tail) = copy_constant (TREE_VALUE (tail));
	if (TREE_CODE (TREE_TYPE (exp)) == SET_TYPE)
	  for (tail = list; tail; tail = TREE_CHAIN (tail))
	    TREE_PURPOSE (tail) = copy_constant (TREE_PURPOSE (tail));

	return copy;
      }

    default:
      {
	tree t;
	t = (*lang_hooks.expand_constant) (exp);
	if (t != exp)
	  return copy_constant (t);
	else
	  abort ();
      }
    }
}

/* Subroutine of output_constant_def:
   No constant equal to EXP is known to have been output.
   Make a constant descriptor to enter EXP in the hash table.
   Assign the label number and construct RTL to refer to the
   constant's location in memory.
   Caller is responsible for updating the hash table.  */

static struct constant_descriptor_tree *
build_constant_desc (tree exp)
{
  rtx symbol;
  rtx rtl;
  char label[256];
  int labelno;
  struct constant_descriptor_tree *desc;

  desc = ggc_alloc (sizeof (*desc));
  desc->value = copy_constant (exp);

  /* Create a string containing the label name, in LABEL.  */
  labelno = const_labelno++;
  ASM_GENERATE_INTERNAL_LABEL (label, "LC", labelno);

  /* We have a symbol name; construct the SYMBOL_REF and the MEM.  */
  symbol = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (label));
  SYMBOL_REF_FLAGS (symbol) = SYMBOL_FLAG_LOCAL;
  SYMBOL_REF_DECL (symbol) = desc->value;
  TREE_CONSTANT_POOL_ADDRESS_P (symbol) = 1;

  rtl = gen_rtx_MEM (TYPE_MODE (TREE_TYPE (exp)), symbol);
  set_mem_attributes (rtl, exp, 1);
  set_mem_alias_set (rtl, 0);
  set_mem_alias_set (rtl, const_alias_set);

  /* Set flags or add text to the name to record information, such as
     that it is a local symbol.  If the name is changed, the macro
     ASM_OUTPUT_LABELREF will have to know how to strip this
     information.  This call might invalidate our local variable
     SYMBOL; we can't use it afterward.  */

  (*targetm.encode_section_info) (exp, rtl, true);

  desc->rtl = rtl;

  return desc;
}

/* Return an rtx representing a reference to constant data in memory
   for the constant expression EXP.

   If assembler code for such a constant has already been output,
   return an rtx to refer to it.
   Otherwise, output such a constant in memory
   and generate an rtx for it.

   If DEFER is nonzero, this constant can be deferred and output only
   if referenced in the function after all optimizations.

   `const_desc_table' records which constants already have label strings.  */

rtx
output_constant_def (tree exp, int defer)
{
  struct constant_descriptor_tree *desc;
  struct constant_descriptor_tree key;
  void **loc;

  /* Look up EXP in the table of constant descriptors.  If we didn't find
     it, create a new one.  */
  key.value = exp;
  loc = htab_find_slot (const_desc_htab, &key, INSERT);

  desc = *loc;
  if (desc == 0)
    {
      desc = build_constant_desc (exp);
      *loc = desc;
    }

  maybe_output_constant_def_contents (desc, defer);
  return desc->rtl;
}

/* Subroutine of output_constant_def: Decide whether or not we need to
   output the constant DESC now, and if so, do it.  */
static void
maybe_output_constant_def_contents (struct constant_descriptor_tree *desc,
				    int defer)
{
  rtx symbol = XEXP (desc->rtl, 0);
  tree exp = desc->value;

  if (flag_syntax_only)
    return;

  if (TREE_ASM_WRITTEN (exp))
    /* Already output; don't do it again.  */
    return;

  /* The only constants that cannot safely be deferred, assuming the
     context allows it, are strings under flag_writable_strings.  */
  if (defer && (TREE_CODE (exp) != STRING_CST || !flag_writable_strings))
    {
      /* Increment n_deferred_constants if it exists.  It needs to be at
	 least as large as the number of constants actually referred to
	 by the function.  If it's too small we'll stop looking too early
	 and fail to emit constants; if it's too large we'll only look
	 through the entire function when we could have stopped earlier.  */
      if (cfun)
	n_deferred_constants++;
      return;
    }

  output_constant_def_contents (symbol);
}

/* We must output the constant data referred to by SYMBOL; do so.  */

static void
output_constant_def_contents (rtx symbol)
{
  tree exp = SYMBOL_REF_DECL (symbol);
  const char *label = XSTR (symbol, 0);
  HOST_WIDE_INT size;

  /* Make sure any other constants whose addresses appear in EXP
     are assigned label numbers.  */
  int reloc = compute_reloc_for_constant (exp);

  /* Align the location counter as required by EXP's data type.  */
  int align = TYPE_ALIGN (TREE_TYPE (exp));
#ifdef CONSTANT_ALIGNMENT
  align = CONSTANT_ALIGNMENT (exp, align);
#endif

  output_addressed_constants (exp);

  /* We are no longer deferring this constant.  */
  TREE_ASM_WRITTEN (exp) = 1;

  if (IN_NAMED_SECTION (exp))
    named_section (exp, NULL, reloc);
  else
    (*targetm.asm_out.select_section) (exp, reloc, align);

  if (align > BITS_PER_UNIT)
    {
      ASM_OUTPUT_ALIGN (asm_out_file, floor_log2 (align / BITS_PER_UNIT));
    }

  size = int_size_in_bytes (TREE_TYPE (exp));
  if (TREE_CODE (exp) == STRING_CST)
    size = MAX (TREE_STRING_LENGTH (exp), size);

  /* Do any machine/system dependent processing of the constant.  */
#ifdef ASM_DECLARE_CONSTANT_NAME
  ASM_DECLARE_CONSTANT_NAME (asm_out_file, label, exp, size);
#else
  /* Standard thing is just output label for the constant.  */
  ASM_OUTPUT_LABEL (asm_out_file, label);
#endif /* ASM_DECLARE_CONSTANT_NAME */

  /* Output the value of EXP.  */
  output_constant (exp, size, align);
}

/* A constant which was deferred in its original location has been
   inserted by the RTL inliner into a different function.  The
   current function's deferred constant count must be incremented.  */
void
notice_rtl_inlining_of_deferred_constant (void)
{
  n_deferred_constants++;
}

/* Look up EXP in the table of constant descriptors.  Return the rtl
   if it has been emitted, else null.  */

rtx
lookup_constant_def (tree exp)
{
  struct constant_descriptor_tree *desc;
  struct constant_descriptor_tree key;

  key.value = exp;
  desc = htab_find (const_desc_htab, &key);

  return (desc ? desc->rtl : NULL_RTX);
}

/* Used in the hash tables to avoid outputting the same constant
   twice.  Unlike 'struct constant_descriptor_tree', RTX constants
   are output once per function, not once per file; there seems
   to be no reason for the difference.  */

struct constant_descriptor_rtx GTY(())
{
  /* More constant_descriptors with the same hash code.  */
  struct constant_descriptor_rtx *next;

  /* A MEM for the constant.  */
  rtx rtl;

  /* The value of the constant.  */
  struct rtx_const value;
};

/* Structure to represent sufficient information about a constant so that
   it can be output when the constant pool is output, so that function
   integration can be done, and to simplify handling on machines that reference
   constant pool as base+displacement.  */

struct pool_constant GTY(())
{
  struct constant_descriptor_rtx *desc;
  struct pool_constant *next;
  struct pool_constant *next_sym;
  rtx constant;
  enum machine_mode mode;
  int labelno;
  unsigned int align;
  HOST_WIDE_INT offset;
  int mark;
};

/* Hash code for a SYMBOL_REF with CONSTANT_POOL_ADDRESS_P true.
   The argument is XSTR (... , 0)  */

#define SYMHASH(LABEL)	(((unsigned long) (LABEL)) % MAX_RTX_HASH_TABLE)

/* Initialize constant pool hashing for a new function.  */

void
init_varasm_status (struct function *f)
{
  struct varasm_status *p;
  p = ggc_alloc (sizeof (struct varasm_status));
  f->varasm = p;
  p->x_const_rtx_hash_table
    = ggc_alloc_cleared (MAX_RTX_HASH_TABLE
			 * sizeof (struct constant_descriptor_rtx *));
  p->x_const_rtx_sym_hash_table
    = ggc_alloc_cleared (MAX_RTX_HASH_TABLE
			 * sizeof (struct pool_constant *));

  p->x_first_pool = p->x_last_pool = 0;
  p->x_pool_offset = 0;
  p->deferred_constants = 0;
}


/* Express an rtx for a constant integer (perhaps symbolic)
   as the sum of a symbol or label plus an explicit integer.
   They are stored into VALUE.  */

static void
decode_rtx_const (enum machine_mode mode, rtx x, struct rtx_const *value)
{
  /* Clear the whole structure, including any gaps.  */
  memset (value, 0, sizeof (struct rtx_const));

  value->kind = RTX_INT;	/* Most usual kind.  */
  value->mode = mode;

  switch (GET_CODE (x))
    {
    case CONST_DOUBLE:
      value->kind = RTX_DOUBLE;
      if (GET_MODE (x) != VOIDmode)
	{
	  const REAL_VALUE_TYPE *r = CONST_DOUBLE_REAL_VALUE (x);

	  value->mode = GET_MODE (x);

	  /* Copy the REAL_VALUE_TYPE by members so that we don't
	     copy garbage from the original structure into our
	     carefully cleaned hashing structure.  */
	  value->un.du.class = r->class;
	  value->un.du.sign = r->sign;
	  switch (r->class)
	    {
	    case rvc_zero:
	    case rvc_inf:
	      break;
	    case rvc_normal:
	      value->un.du.exp = r->exp;
	      /* Fall through.  */
	    case rvc_nan:
	      memcpy (value->un.du.sig, r->sig, sizeof (r->sig));
	      break;
	    default:
	      abort ();
	    }
	}
      else
	{
	  value->un.di.low = CONST_DOUBLE_LOW (x);
	  value->un.di.high = CONST_DOUBLE_HIGH (x);
	}
      break;

    case CONST_VECTOR:
      {
	int units, i;

	units = CONST_VECTOR_NUNITS (x);
	value->kind = RTX_VECTOR;
	value->mode = mode;

	if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
	  {
	    for (i = 0; i < units; ++i)
	      {
	        rtx elt = CONST_VECTOR_ELT (x, i);
	        if (GET_CODE (elt) == CONST_INT)
	          {
		    value->un.int_vec[i].low = INTVAL (elt);
		    value->un.int_vec[i].high = 0;
	          }
		else
	          {
		    value->un.int_vec[i].low = CONST_DOUBLE_LOW (elt);
		    value->un.int_vec[i].high = CONST_DOUBLE_HIGH (elt);
		  }
	      }
	  }
	else if (GET_MODE_CLASS (mode) == MODE_VECTOR_FLOAT)
	  {
	    for (i = 0; i < units; ++i)
	      {
		const REAL_VALUE_TYPE *r
		  = CONST_DOUBLE_REAL_VALUE (CONST_VECTOR_ELT (x, i));
		REAL_VALUE_TYPE *d = &value->un.fp_vec[i];

	        /* Copy the REAL_VALUE_TYPE by members so that we don't
	           copy garbage from the original structure into our
	           carefully cleaned hashing structure.  */
	        d->class = r->class;
	        d->sign = r->sign;
	        switch (r->class)
	          {
	          case rvc_zero:
	          case rvc_inf:
	            break;
	          case rvc_normal:
	            d->exp = r->exp;
	            /* Fall through.  */
	          case rvc_nan:
	            memcpy (d->sig, r->sig, sizeof (r->sig));
	            break;
	          default:
	            abort ();
	          }
	      }
	  }
	else
	  abort ();
      }
      break;

    case CONST_INT:
      value->un.addr.offset = INTVAL (x);
      break;

    case SYMBOL_REF:
    case LABEL_REF:
    case PC:
      value->un.addr.base = x;
      break;

    case CONST:
      x = XEXP (x, 0);
      if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == CONST_INT)
	{
	  value->un.addr.base = XEXP (x, 0);
	  value->un.addr.offset = INTVAL (XEXP (x, 1));
	}
      else if (GET_CODE (x) == MINUS && GET_CODE (XEXP (x, 1)) == CONST_INT)
	{
	  value->un.addr.base = XEXP (x, 0);
	  value->un.addr.offset = - INTVAL (XEXP (x, 1));
	}
      else
	{
	  value->un.addr.base = x;
	  value->un.addr.offset = 0;
	}
      break;

    default:
      value->kind = RTX_UNKNOWN;
      break;
    }

  if (value->kind == RTX_INT && value->un.addr.base != 0
      && GET_CODE (value->un.addr.base) == UNSPEC)
    {
      /* For a simple UNSPEC, the base is set to the
	 operand, the kind field is set to the index of
	 the unspec expression.
	 Together with the code below, in case that
	 the operand is a SYMBOL_REF or LABEL_REF,
	 the address of the string or the code_label
	 is taken as base.  */
      if (XVECLEN (value->un.addr.base, 0) == 1)
	{
	  value->kind = RTX_UNSPEC + XINT (value->un.addr.base, 1);
	  value->un.addr.base = XVECEXP (value->un.addr.base, 0, 0);
	}
    }

  if (value->kind >= RTX_INT && value->un.addr.base != 0)
    switch (GET_CODE (value->un.addr.base))
      {
      case SYMBOL_REF:
	/* Use the string's address, not the SYMBOL_REF's address,
	   for the sake of addresses of library routines.  */
	value->un.addr.symbol = XSTR (value->un.addr.base, 0);
	value->un.addr.base = NULL_RTX;
	break;

      case LABEL_REF:
	/* For a LABEL_REF, compare labels.  */
	value->un.addr.base = XEXP (value->un.addr.base, 0);

      default:
	break;
      }
}

/* Given a MINUS expression, simplify it if both sides
   include the same symbol.  */

rtx
simplify_subtraction (rtx x)
{
  struct rtx_const val0, val1;

  decode_rtx_const (GET_MODE (x), XEXP (x, 0), &val0);
  decode_rtx_const (GET_MODE (x), XEXP (x, 1), &val1);

  if (val0.kind >= RTX_INT
      && val0.kind == val1.kind
      && val0.un.addr.base == val1.un.addr.base
      && val0.un.addr.symbol == val1.un.addr.symbol)
    return GEN_INT (val0.un.addr.offset - val1.un.addr.offset);

  return x;
}

/* Compute a hash code for a constant RTL expression.  */

static unsigned int
const_hash_rtx (enum machine_mode mode, rtx x)
{
  union {
    struct rtx_const value;
    unsigned int data[sizeof(struct rtx_const) / sizeof (unsigned int)];
  } u;

  unsigned int hi;
  size_t i;

  decode_rtx_const (mode, x, &u.value);

  /* Compute hashing function.  */
  hi = 0;
  for (i = 0; i < ARRAY_SIZE (u.data); i++)
    hi = hi * 613 + u.data[i];

  return hi % MAX_RTX_HASH_TABLE;
}

/* Compare a constant rtl object X with a constant-descriptor DESC.
   Return 1 if DESC describes a constant with the same value as X.  */

static int
compare_constant_rtx (enum machine_mode mode, rtx x,
		      struct constant_descriptor_rtx *desc)
{
  struct rtx_const value;

  decode_rtx_const (mode, x, &value);

  /* Compare constant contents.  */
  return memcmp (&value, &desc->value, sizeof (struct rtx_const)) == 0;
}

/* Construct a constant descriptor for the rtl-expression X.
   It is up to the caller to enter the descriptor in the hash table.  */

static struct constant_descriptor_rtx *
record_constant_rtx (enum machine_mode mode, rtx x)
{
  struct constant_descriptor_rtx *ptr;

  ptr = ggc_alloc (sizeof (*ptr));
  decode_rtx_const (mode, x, &ptr->value);

  return ptr;
}

/* Given a constant rtx X, make (or find) a memory constant for its value
   and return a MEM rtx to refer to it in memory.  */

rtx
force_const_mem (enum machine_mode mode, rtx x)
{
  int hash;
  struct constant_descriptor_rtx *desc;
  char label[256];
  rtx def, symbol;
  struct pool_constant *pool;
  unsigned int align;

  /* If we're not allowed to drop X into the constant pool, don't.  */
  if ((*targetm.cannot_force_const_mem) (x))
    return NULL_RTX;

  /* Compute hash code of X.  Search the descriptors for that hash code
     to see if any of them describes X.  If yes, we have an rtx to use.  */
  hash = const_hash_rtx (mode, x);
  for (desc = const_rtx_hash_table[hash]; desc; desc = desc->next)
    if (compare_constant_rtx (mode, x, desc))
      return copy_rtx (desc->rtl);

  /* No constant equal to X is known to have been output.
     Make a constant descriptor to enter X in the hash table
     and make a MEM for it.  */
  desc = record_constant_rtx (mode, x);
  desc->next = const_rtx_hash_table[hash];
  const_rtx_hash_table[hash] = desc;

  /* Align the location counter as required by EXP's data type.  */
  align = GET_MODE_ALIGNMENT (mode == VOIDmode ? word_mode : mode);
#ifdef CONSTANT_ALIGNMENT
  {
    tree type = (*lang_hooks.types.type_for_mode) (mode, 0);
    if (type != NULL_TREE)
      align = CONSTANT_ALIGNMENT (make_tree (type, x), align);
  }
#endif

  pool_offset += (align / BITS_PER_UNIT) - 1;
  pool_offset &= ~ ((align / BITS_PER_UNIT) - 1);

  if (GET_CODE (x) == LABEL_REF)
    LABEL_PRESERVE_P (XEXP (x, 0)) = 1;

  /* Allocate a pool constant descriptor, fill it in, and chain it in.  */
  pool = ggc_alloc (sizeof (struct pool_constant));
  pool->desc = desc;
  pool->constant = x;
  pool->mode = mode;
  pool->labelno = const_labelno;
  pool->align = align;
  pool->offset = pool_offset;
  pool->mark = 1;
  pool->next = 0;

  if (last_pool == 0)
    first_pool = pool;
  else
    last_pool->next = pool;

  last_pool = pool;
  pool_offset += GET_MODE_SIZE (mode);

  /* Create a string containing the label name, in LABEL.  */
  ASM_GENERATE_INTERNAL_LABEL (label, "LC", const_labelno);

  ++const_labelno;

  /* Construct the SYMBOL_REF and the MEM.  */

  symbol = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (label));
  SYMBOL_REF_FLAGS (symbol) = SYMBOL_FLAG_LOCAL;

  pool->desc->rtl = def = gen_rtx_MEM (mode, symbol);
  set_mem_attributes (def, (*lang_hooks.types.type_for_mode) (mode, 0), 1);
  RTX_UNCHANGING_P (def) = 1;

  /* Add label to symbol hash table.  */
  hash = SYMHASH (XSTR (symbol, 0));
  pool->next_sym = const_rtx_sym_hash_table[hash];
  const_rtx_sym_hash_table[hash] = pool;

  /* Mark the symbol_ref as belonging to this constants pool.  */
  CONSTANT_POOL_ADDRESS_P (symbol) = 1;
  SYMBOL_REF_FLAGS (symbol) = SYMBOL_FLAG_LOCAL;
  current_function_uses_const_pool = 1;

  return copy_rtx (def);
}

/* Given a SYMBOL_REF with CONSTANT_POOL_ADDRESS_P true, return a pointer to
   the corresponding pool_constant structure.  */

static struct pool_constant *
find_pool_constant (struct function *f, rtx addr)
{
  struct pool_constant *pool;
  const char *label = XSTR (addr, 0);

  for (pool = f->varasm->x_const_rtx_sym_hash_table[SYMHASH (label)]; pool;
       pool = pool->next_sym)
    if (XSTR (XEXP (pool->desc->rtl, 0), 0) == label)
      return pool;

  abort ();
}

/* Given a constant pool SYMBOL_REF, return the corresponding constant.  */

rtx
get_pool_constant (rtx addr)
{
  return (find_pool_constant (cfun, addr))->constant;
}

/* Given a constant pool SYMBOL_REF, return the corresponding constant
   and whether it has been output or not.  */

rtx
get_pool_constant_mark (rtx addr, bool *pmarked)
{
  struct pool_constant *pool = find_pool_constant (cfun, addr);
  *pmarked = (pool->mark != 0);
  return pool->constant;
}

/* Likewise, but for the constant pool of a specific function.  */

rtx
get_pool_constant_for_function (struct function *f, rtx addr)
{
  return (find_pool_constant (f, addr))->constant;
}

/* Similar, return the mode.  */

enum machine_mode
get_pool_mode (rtx addr)
{
  return (find_pool_constant (cfun, addr))->mode;
}

enum machine_mode
get_pool_mode_for_function (struct function *f, rtx addr)
{
  return (find_pool_constant (f, addr))->mode;
}

/* Similar, return the offset in the constant pool.  */

int
get_pool_offset (rtx addr)
{
  return (find_pool_constant (cfun, addr))->offset;
}

/* Return the size of the constant pool.  */

int
get_pool_size (void)
{
  return pool_offset;
}

/* Write all the constants in the constant pool.  */

void
output_constant_pool (const char *fnname ATTRIBUTE_UNUSED,
		      tree fndecl ATTRIBUTE_UNUSED)
{
  struct pool_constant *pool;
  rtx x;
  REAL_VALUE_TYPE r;

  /* It is possible for gcc to call force_const_mem and then to later
     discard the instructions which refer to the constant.  In such a
     case we do not need to output the constant.  */
  mark_constant_pool ();

#ifdef ASM_OUTPUT_POOL_PROLOGUE
  ASM_OUTPUT_POOL_PROLOGUE (asm_out_file, fnname, fndecl, pool_offset);
#endif

  for (pool = first_pool; pool; pool = pool->next)
    {
      rtx tmp;

      x = pool->constant;

      if (! pool->mark)
	continue;

      /* See if X is a LABEL_REF (or a CONST referring to a LABEL_REF)
	 whose CODE_LABEL has been deleted.  This can occur if a jump table
	 is eliminated by optimization.  If so, write a constant of zero
	 instead.  Note that this can also happen by turning the
	 CODE_LABEL into a NOTE.  */
      /* ??? This seems completely and utterly wrong.  Certainly it's
	 not true for NOTE_INSN_DELETED_LABEL, but I disbelieve proper
	 functioning even with INSN_DELETED_P and friends.  */

      tmp = x;
      switch (GET_CODE (x))
	{
	case CONST:
	  if (GET_CODE (XEXP (x, 0)) != PLUS
	      || GET_CODE (XEXP (XEXP (x, 0), 0)) != LABEL_REF)
	    break;
	  tmp = XEXP (XEXP (x, 0), 0);
	  /* Fall through.  */

	case LABEL_REF:
	  tmp = XEXP (x, 0);
	  if (INSN_DELETED_P (tmp)
	      || (GET_CODE (tmp) == NOTE
		  && NOTE_LINE_NUMBER (tmp) == NOTE_INSN_DELETED))
	    {
	      abort ();
	      x = const0_rtx;
	    }
	  break;

	default:
	  break;
	}

      /* First switch to correct section.  */
      (*targetm.asm_out.select_rtx_section) (pool->mode, x, pool->align);

#ifdef ASM_OUTPUT_SPECIAL_POOL_ENTRY
      ASM_OUTPUT_SPECIAL_POOL_ENTRY (asm_out_file, x, pool->mode,
				     pool->align, pool->labelno, done);
#endif

      assemble_align (pool->align);

      /* Output the label.  */
      (*targetm.asm_out.internal_label) (asm_out_file, "LC", pool->labelno);

      /* Output the value of the constant itself.  */
      switch (GET_MODE_CLASS (pool->mode))
	{
	case MODE_FLOAT:
	  if (GET_CODE (x) != CONST_DOUBLE)
	    abort ();

	  REAL_VALUE_FROM_CONST_DOUBLE (r, x);
	  assemble_real (r, pool->mode, pool->align);
	  break;

	case MODE_INT:
	case MODE_PARTIAL_INT:
	  assemble_integer (x, GET_MODE_SIZE (pool->mode), pool->align, 1);
	  break;

	case MODE_VECTOR_FLOAT:
	  {
	    int i, units;
	    rtx elt;

	    if (GET_CODE (x) != CONST_VECTOR)
	      abort ();

	    units = CONST_VECTOR_NUNITS (x);

	    for (i = 0; i < units; i++)
	      {
		elt = CONST_VECTOR_ELT (x, i);
		REAL_VALUE_FROM_CONST_DOUBLE (r, elt);
		assemble_real (r, GET_MODE_INNER (pool->mode), pool->align);
	      }
	  }
	  break;

	case MODE_VECTOR_INT:
	  {
	    int i, units;
	    rtx elt;

	    if (GET_CODE (x) != CONST_VECTOR)
	      abort ();

	    units = CONST_VECTOR_NUNITS (x);

	    for (i = 0; i < units; i++)
	      {
		elt = CONST_VECTOR_ELT (x, i);
		assemble_integer (elt, GET_MODE_UNIT_SIZE (pool->mode),
				  pool->align, 1);
	      }
	  }
	  break;

	default:
	  abort ();
	}

      /* Make sure all constants in SECTION_MERGE and not SECTION_STRINGS
	 sections have proper size.  */
      if (pool->align > GET_MODE_BITSIZE (pool->mode)
	  && in_section == in_named
	  && get_named_section_flags (in_named_name) & SECTION_MERGE)
	assemble_align (pool->align);

#ifdef ASM_OUTPUT_SPECIAL_POOL_ENTRY
    done: ;
#endif
    }

#ifdef ASM_OUTPUT_POOL_EPILOGUE
  ASM_OUTPUT_POOL_EPILOGUE (asm_out_file, fnname, fndecl, pool_offset);
#endif

  /* Done with this pool.  */
  first_pool = last_pool = 0;
}

/* Look through the instructions for this function, and mark all the
   entries in the constant pool which are actually being used.  Emit
   deferred constants which have indeed been used.  */

static void
mark_constant_pool (void)
{
  rtx insn;
  rtx link;
  struct pool_constant *pool;

  if (first_pool == 0 && n_deferred_constants == 0)
    return;

  for (pool = first_pool; pool; pool = pool->next)
    pool->mark = 0;

  for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
    if (INSN_P (insn))
      mark_constants (PATTERN (insn));

  for (link = current_function_epilogue_delay_list;
       link;
       link = XEXP (link, 1))
    {
      insn = XEXP (link, 0);

      if (INSN_P (insn))
	mark_constants (PATTERN (insn));
    }
}

/* Look through appropriate parts of X, marking all entries in the
   constant pool which are actually being used.  Entries that are only
   referenced by other constants are also marked as used.  Emit
   deferred strings that are used.  */

static void
mark_constants (rtx x)
{
  int i;
  const char *format_ptr;

  if (x == 0)
    return;

  if (GET_CODE (x) == SYMBOL_REF)
    {
      mark_constant (&x, NULL);
      return;
    }

  /* Insns may appear inside a SEQUENCE.  Only check the patterns of
     insns, not any notes that may be attached.  We don't want to mark
     a constant just because it happens to appear in a REG_EQUIV note.  */
  if (INSN_P (x))
    {
      mark_constants (PATTERN (x));
      return;
    }

  format_ptr = GET_RTX_FORMAT (GET_CODE (x));

  for (i = 0; i < GET_RTX_LENGTH (GET_CODE (x)); i++)
    {
      switch (*format_ptr++)
	{
	case 'e':
	  mark_constants (XEXP (x, i));
	  break;

	case 'E':
	  if (XVEC (x, i) != 0)
	    {
	      int j;

	      for (j = 0; j < XVECLEN (x, i); j++)
		mark_constants (XVECEXP (x, i, j));
	    }
	  break;

	case 'S':
	case 's':
	case '0':
	case 'i':
	case 'w':
	case 'n':
	case 'u':
	case 'B':
	  break;

	default:
	  abort ();
	}
    }
}

/* Given a SYMBOL_REF CURRENT_RTX, mark it and all constants it refers
   to as used.  Emit referenced deferred strings.  This function can
   be used with for_each_rtx to mark all SYMBOL_REFs in an rtx.  */

static int
mark_constant (rtx *current_rtx, void *data ATTRIBUTE_UNUSED)
{
  rtx x = *current_rtx;

  if (x == NULL_RTX)
    return 0;

  else if (GET_CODE (x) == SYMBOL_REF)
    {
      if (CONSTANT_POOL_ADDRESS_P (x))
	{
	  struct pool_constant *pool = find_pool_constant (cfun, x);
	  if (pool->mark == 0)
	    {
	      pool->mark = 1;
	      for_each_rtx (&(pool->constant), &mark_constant, NULL);
	    }
	  else
	    return -1;
	}
      else if (TREE_CONSTANT_POOL_ADDRESS_P (x))
	{
	  tree exp = SYMBOL_REF_DECL (x);
	  if (!TREE_ASM_WRITTEN (exp))
	    {
	      n_deferred_constants--;
	      output_constant_def_contents (x);
	    }
	}
    }
  return 0;
}

/* Determine what kind of relocations EXP may need.  */

int
compute_reloc_for_constant (tree exp)
{
  int reloc = 0, reloc2;
  tree tem;

  /* Give the front-end a chance to convert VALUE to something that
     looks more like a constant to the back-end.  */
  exp = (*lang_hooks.expand_constant) (exp);

  switch (TREE_CODE (exp))
    {
    case ADDR_EXPR:
    case FDESC_EXPR:
      /* Go inside any operations that get_inner_reference can handle and see
	 if what's inside is a constant: no need to do anything here for
	 addresses of variables or functions.  */
      for (tem = TREE_OPERAND (exp, 0); handled_component_p (tem);
	   tem = TREE_OPERAND (tem, 0))
	;

      if (TREE_PUBLIC (tem))
	reloc |= 2;
      else
	reloc |= 1;
      break;

    case PLUS_EXPR:
      reloc = compute_reloc_for_constant (TREE_OPERAND (exp, 0));
      reloc |= compute_reloc_for_constant (TREE_OPERAND (exp, 1));
      break;

    case MINUS_EXPR:
      reloc = compute_reloc_for_constant (TREE_OPERAND (exp, 0));
      reloc2 = compute_reloc_for_constant (TREE_OPERAND (exp, 1));
      /* The difference of two local labels is computable at link time.  */
      if (reloc == 1 && reloc2 == 1)
	reloc = 0;
      else
	reloc |= reloc2;
      break;

    case NOP_EXPR:
    case CONVERT_EXPR:
    case NON_LVALUE_EXPR:
      reloc = compute_reloc_for_constant (TREE_OPERAND (exp, 0));
      break;

    case CONSTRUCTOR:
      for (tem = CONSTRUCTOR_ELTS (exp); tem; tem = TREE_CHAIN (tem))
	if (TREE_VALUE (tem) != 0)
	  reloc |= compute_reloc_for_constant (TREE_VALUE (tem));

      break;

    default:
      break;
    }
  return reloc;
}

/* Find all the constants whose addresses are referenced inside of EXP,
   and make sure assembler code with a label has been output for each one.
   Indicate whether an ADDR_EXPR has been encountered.  */

static void
output_addressed_constants (tree exp)
{
  tree tem;

  /* Give the front-end a chance to convert VALUE to something that
     looks more like a constant to the back-end.  */
  exp = (*lang_hooks.expand_constant) (exp);

  switch (TREE_CODE (exp))
    {
    case ADDR_EXPR:
    case FDESC_EXPR:
      /* Go inside any operations that get_inner_reference can handle and see
	 if what's inside is a constant: no need to do anything here for
	 addresses of variables or functions.  */
      for (tem = TREE_OPERAND (exp, 0); handled_component_p (tem);
	   tem = TREE_OPERAND (tem, 0))
	;

      if (TREE_CODE_CLASS (TREE_CODE (tem)) == 'c'
	  || TREE_CODE (tem) == CONSTRUCTOR)
	output_constant_def (tem, 0);
      break;

    case PLUS_EXPR:
    case MINUS_EXPR:
      output_addressed_constants (TREE_OPERAND (exp, 1));
      /* Fall through.  */

    case NOP_EXPR:
    case CONVERT_EXPR:
    case NON_LVALUE_EXPR:
      output_addressed_constants (TREE_OPERAND (exp, 0));
      break;

    case CONSTRUCTOR:
      for (tem = CONSTRUCTOR_ELTS (exp); tem; tem = TREE_CHAIN (tem))
	if (TREE_VALUE (tem) != 0)
	  output_addressed_constants (TREE_VALUE (tem));

      break;

    default:
      break;
    }
}

/* Return nonzero if VALUE is a valid constant-valued expression
   for use in initializing a static variable; one that can be an
   element of a "constant" initializer.

   Return null_pointer_node if the value is absolute;
   if it is relocatable, return the variable that determines the relocation.
   We assume that VALUE has been folded as much as possible;
   therefore, we do not need to check for such things as
   arithmetic-combinations of integers.  */

tree
initializer_constant_valid_p (tree value, tree endtype)
{
  /* Give the front-end a chance to convert VALUE to something that
     looks more like a constant to the back-end.  */
  value = (*lang_hooks.expand_constant) (value);

  switch (TREE_CODE (value))
    {
    case CONSTRUCTOR:
      if ((TREE_CODE (TREE_TYPE (value)) == UNION_TYPE
	   || TREE_CODE (TREE_TYPE (value)) == RECORD_TYPE)
	  && TREE_CONSTANT (value)
	  && CONSTRUCTOR_ELTS (value))
	{
	  tree elt;
	  bool absolute = true;

	  for (elt = CONSTRUCTOR_ELTS (value); elt; elt = TREE_CHAIN (elt))
	    {
	      tree reloc;
	      value = TREE_VALUE (elt);
	      reloc = initializer_constant_valid_p (value, TREE_TYPE (value));
	      if (!reloc)
		return NULL_TREE;
	      if (reloc != null_pointer_node)
		absolute = false;
	    }
	  /* For a non-absolute relocation, there is no single
	     variable that can be "the variable that determines the
	     relocation."  */
	  return absolute ? null_pointer_node : error_mark_node;
	}

      return TREE_STATIC (value) ? null_pointer_node : NULL_TREE;

    case INTEGER_CST:
    case VECTOR_CST:
    case REAL_CST:
    case STRING_CST:
    case COMPLEX_CST:
      return null_pointer_node;

    case ADDR_EXPR:
    case FDESC_EXPR:
      return staticp (TREE_OPERAND (value, 0)) ? TREE_OPERAND (value, 0) : 0;

    case VIEW_CONVERT_EXPR:
    case NON_LVALUE_EXPR:
      return initializer_constant_valid_p (TREE_OPERAND (value, 0), endtype);

    case CONVERT_EXPR:
    case NOP_EXPR:
      {
	tree src;
	tree src_type;
	tree dest_type;

	src = TREE_OPERAND (value, 0);
	src_type = TREE_TYPE (src);
	dest_type = TREE_TYPE (value);

	/* Allow conversions between pointer types, floating-point
	   types, and offset types.  */
	if ((POINTER_TYPE_P (dest_type) && POINTER_TYPE_P (src_type))
	    || (FLOAT_TYPE_P (dest_type) && FLOAT_TYPE_P (src_type))
	    || (TREE_CODE (dest_type) == OFFSET_TYPE
		&& TREE_CODE (src_type) == OFFSET_TYPE))
	  return initializer_constant_valid_p (src, endtype);

	/* Allow length-preserving conversions between integer types.  */
	if (INTEGRAL_TYPE_P (dest_type) && INTEGRAL_TYPE_P (src_type)
	    && (TYPE_PRECISION (dest_type) == TYPE_PRECISION (src_type)))
	  return initializer_constant_valid_p (src, endtype);

	/* Allow conversions between other integer types only if
	   explicit value.  */
	if (INTEGRAL_TYPE_P (dest_type) && INTEGRAL_TYPE_P (src_type))
	  {
	    tree inner = initializer_constant_valid_p (src, endtype);
	    if (inner == null_pointer_node)
	      return null_pointer_node;
	    break;
	  }

	/* Allow (int) &foo provided int is as wide as a pointer.  */
	if (INTEGRAL_TYPE_P (dest_type) && POINTER_TYPE_P (src_type)
	    && (TYPE_PRECISION (dest_type) >= TYPE_PRECISION (src_type)))
	  return initializer_constant_valid_p (src, endtype);

	/* Likewise conversions from int to pointers, but also allow
	   conversions from 0.  */
	if ((POINTER_TYPE_P (dest_type)
	     || TREE_CODE (dest_type) == OFFSET_TYPE)
	    && INTEGRAL_TYPE_P (src_type))
	  {
	    if (integer_zerop (src))
	      return null_pointer_node;
	    else if (TYPE_PRECISION (dest_type) <= TYPE_PRECISION (src_type))
	      return initializer_constant_valid_p (src, endtype);
	  }

	/* Allow conversions to struct or union types if the value
	   inside is okay.  */
	if (TREE_CODE (dest_type) == RECORD_TYPE
	    || TREE_CODE (dest_type) == UNION_TYPE)
	  return initializer_constant_valid_p (src, endtype);
      }
      break;

    case PLUS_EXPR:
      if (! INTEGRAL_TYPE_P (endtype)
	  || TYPE_PRECISION (endtype) >= POINTER_SIZE)
	{
	  tree valid0 = initializer_constant_valid_p (TREE_OPERAND (value, 0),
						      endtype);
	  tree valid1 = initializer_constant_valid_p (TREE_OPERAND (value, 1),
						      endtype);
	  /* If either term is absolute, use the other terms relocation.  */
	  if (valid0 == null_pointer_node)
	    return valid1;
	  if (valid1 == null_pointer_node)
	    return valid0;
	}
      break;

    case MINUS_EXPR:
      if (! INTEGRAL_TYPE_P (endtype)
	  || TYPE_PRECISION (endtype) >= POINTER_SIZE)
	{
	  tree valid0 = initializer_constant_valid_p (TREE_OPERAND (value, 0),
						      endtype);
	  tree valid1 = initializer_constant_valid_p (TREE_OPERAND (value, 1),
						      endtype);
	  /* Win if second argument is absolute.  */
	  if (valid1 == null_pointer_node)
	    return valid0;
	  /* Win if both arguments have the same relocation.
	     Then the value is absolute.  */
	  if (valid0 == valid1 && valid0 != 0)
	    return null_pointer_node;

	  /* Since GCC guarantees that string constants are unique in the
	     generated code, a subtraction between two copies of the same
	     constant string is absolute.  */
	  if (valid0 && TREE_CODE (valid0) == STRING_CST &&
	      valid1 && TREE_CODE (valid1) == STRING_CST &&
	      TREE_STRING_POINTER (valid0) == TREE_STRING_POINTER (valid1))
	    return null_pointer_node;
	}

      /* Support differences between labels.  */
      if (INTEGRAL_TYPE_P (endtype))
	{
	  tree op0, op1;
	  op0 = TREE_OPERAND (value, 0);
	  op1 = TREE_OPERAND (value, 1);

	  /* Like STRIP_NOPS except allow the operand mode to widen.
	     This works around a feature of fold that simplifies
	     (int)(p1 - p2) to ((int)p1 - (int)p2) under the theory
	     that the narrower operation is cheaper.  */

	  while (TREE_CODE (op0) == NOP_EXPR
		 || TREE_CODE (op0) == CONVERT_EXPR
		 || TREE_CODE (op0) == NON_LVALUE_EXPR)
	    {
	      tree inner = TREE_OPERAND (op0, 0);
	      if (inner == error_mark_node
	          || ! INTEGRAL_MODE_P (TYPE_MODE (TREE_TYPE (inner)))
		  || (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (op0)))
		      > GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (inner)))))
		break;
	      op0 = inner;
	    }

	  while (TREE_CODE (op1) == NOP_EXPR
		 || TREE_CODE (op1) == CONVERT_EXPR
		 || TREE_CODE (op1) == NON_LVALUE_EXPR)
	    {
	      tree inner = TREE_OPERAND (op1, 0);
	      if (inner == error_mark_node
	          || ! INTEGRAL_MODE_P (TYPE_MODE (TREE_TYPE (inner)))
		  || (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (op1)))
		      > GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (inner)))))
		break;
	      op1 = inner;
	    }

	  if (TREE_CODE (op0) == ADDR_EXPR
	      && TREE_CODE (TREE_OPERAND (op0, 0)) == LABEL_DECL
	      && TREE_CODE (op1) == ADDR_EXPR
	      && TREE_CODE (TREE_OPERAND (op1, 0)) == LABEL_DECL)
	    return null_pointer_node;
	}
      break;

    default:
      break;
    }

  return 0;
}

/* Output assembler code for constant EXP to FILE, with no label.
   This includes the pseudo-op such as ".int" or ".byte", and a newline.
   Assumes output_addressed_constants has been done on EXP already.

   Generate exactly SIZE bytes of assembler data, padding at the end
   with zeros if necessary.  SIZE must always be specified.

   SIZE is important for structure constructors,
   since trailing members may have been omitted from the constructor.
   It is also important for initialization of arrays from string constants
   since the full length of the string constant might not be wanted.
   It is also needed for initialization of unions, where the initializer's
   type is just one member, and that may not be as long as the union.

   There a case in which we would fail to output exactly SIZE bytes:
   for a structure constructor that wants to produce more than SIZE bytes.
   But such constructors will never be generated for any possible input.

   ALIGN is the alignment of the data in bits.  */

void
output_constant (tree exp, unsigned HOST_WIDE_INT size, unsigned int align)
{
  enum tree_code code;
  unsigned HOST_WIDE_INT thissize;

  /* Some front-ends use constants other than the standard language-independent
     varieties, but which may still be output directly.  Give the front-end a
     chance to convert EXP to a language-independent representation.  */
  exp = (*lang_hooks.expand_constant) (exp);

  if (size == 0 || flag_syntax_only)
    return;

  /* Eliminate any conversions since we'll be outputting the underlying
     constant.  */
  while (TREE_CODE (exp) == NOP_EXPR || TREE_CODE (exp) == CONVERT_EXPR
	 || TREE_CODE (exp) == NON_LVALUE_EXPR
	 || TREE_CODE (exp) == VIEW_CONVERT_EXPR)
    exp = TREE_OPERAND (exp, 0);

  code = TREE_CODE (TREE_TYPE (exp));
  thissize = int_size_in_bytes (TREE_TYPE (exp));

  /* Allow a constructor with no elements for any data type.
     This means to fill the space with zeros.  */
  if (TREE_CODE (exp) == CONSTRUCTOR && CONSTRUCTOR_ELTS (exp) == 0)
    {
      assemble_zeros (size);
      return;
    }

  if (TREE_CODE (exp) == FDESC_EXPR)
    {
#ifdef ASM_OUTPUT_FDESC
      HOST_WIDE_INT part = tree_low_cst (TREE_OPERAND (exp, 1), 0);
      tree decl = TREE_OPERAND (exp, 0);
      ASM_OUTPUT_FDESC (asm_out_file, decl, part);
#else
      abort ();
#endif
      return;
    }

  /* Now output the underlying data.  If we've handling the padding, return.
     Otherwise, break and ensure THISSIZE is the size written.  */
  switch (code)
    {
    case CHAR_TYPE:
    case BOOLEAN_TYPE:
    case INTEGER_TYPE:
    case ENUMERAL_TYPE:
    case POINTER_TYPE:
    case REFERENCE_TYPE:
    case OFFSET_TYPE:
      if (! assemble_integer (expand_expr (exp, NULL_RTX, VOIDmode,
					   EXPAND_INITIALIZER),
			      size, align, 0))
	error ("initializer for integer value is too complicated");
      break;

    case REAL_TYPE:
      if (TREE_CODE (exp) != REAL_CST)
	error ("initializer for floating value is not a floating constant");

      assemble_real (TREE_REAL_CST (exp), TYPE_MODE (TREE_TYPE (exp)), align);
      break;

    case COMPLEX_TYPE:
      output_constant (TREE_REALPART (exp), thissize / 2, align);
      output_constant (TREE_IMAGPART (exp), thissize / 2,
		       min_align (align, BITS_PER_UNIT * (thissize / 2)));
      break;

    case ARRAY_TYPE:
    case VECTOR_TYPE:
      if (TREE_CODE (exp) == CONSTRUCTOR)
	{
	  output_constructor (exp, size, align);
	  return;
	}
      else if (TREE_CODE (exp) == STRING_CST)
	{
	  thissize = MIN ((unsigned HOST_WIDE_INT)TREE_STRING_LENGTH (exp),
			  size);
	  assemble_string (TREE_STRING_POINTER (exp), thissize);
	}
      else if (TREE_CODE (exp) == VECTOR_CST)
	{
	  int elt_size;
	  tree link;
	  unsigned int nalign;
	  enum machine_mode inner;

	  inner = GET_MODE_INNER (TYPE_MODE (TREE_TYPE (exp)));
	  nalign = MIN (align, GET_MODE_ALIGNMENT (inner));

	  elt_size = GET_MODE_UNIT_SIZE (TYPE_MODE (TREE_TYPE (exp)));

	  link = TREE_VECTOR_CST_ELTS (exp);
	  output_constant (TREE_VALUE (link), elt_size, align);
	  while ((link = TREE_CHAIN (link)) != NULL)
	    output_constant (TREE_VALUE (link), elt_size, nalign);
	}
      else
	abort ();
      break;

    case RECORD_TYPE:
    case UNION_TYPE:
      if (TREE_CODE (exp) == CONSTRUCTOR)
	output_constructor (exp, size, align);
      else
	abort ();
      return;

    case SET_TYPE:
      if (TREE_CODE (exp) == INTEGER_CST)
	assemble_integer (expand_expr (exp, NULL_RTX,
				       VOIDmode, EXPAND_INITIALIZER),
			  thissize, align, 1);
      else if (TREE_CODE (exp) == CONSTRUCTOR)
	{
	  unsigned char *buffer = alloca (thissize);
	  if (get_set_constructor_bytes (exp, buffer, thissize))
	    abort ();
	  assemble_string ((char *) buffer, thissize);
	}
      else
	error ("unknown set constructor type");
      return;

    case ERROR_MARK:
      return;

    default:
      abort ();
    }

  if (size > thissize)
    assemble_zeros (size - thissize);
}


/* Subroutine of output_constructor, used for computing the size of
   arrays of unspecified length.  VAL must be a CONSTRUCTOR of an array
   type with an unspecified upper bound.  */

static unsigned HOST_WIDE_INT
array_size_for_constructor (tree val)
{
  tree max_index, i;

  /* This code used to attempt to handle string constants that are not
     arrays of single-bytes, but nothing else does, so there's no point in
     doing it here.  */
  if (TREE_CODE (val) == STRING_CST)
    return TREE_STRING_LENGTH (val);

  max_index = NULL_TREE;
  for (i = CONSTRUCTOR_ELTS (val); i; i = TREE_CHAIN (i))
    {
      tree index = TREE_PURPOSE (i);

      if (TREE_CODE (index) == RANGE_EXPR)
	index = TREE_OPERAND (index, 1);
      if (max_index == NULL_TREE || tree_int_cst_lt (max_index, index))
	max_index = index;
    }

  if (max_index == NULL_TREE)
    return 0;

  /* Compute the total number of array elements.  */
  i = size_binop (MINUS_EXPR, convert (sizetype, max_index),
		  convert (sizetype,
			   TYPE_MIN_VALUE (TYPE_DOMAIN (TREE_TYPE (val)))));
  i = size_binop (PLUS_EXPR, i, convert (sizetype, integer_one_node));

  /* Multiply by the array element unit size to find number of bytes.  */
  i = size_binop (MULT_EXPR, i, TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (val))));

  return tree_low_cst (i, 1);
}

/* Subroutine of output_constant, used for CONSTRUCTORs (aggregate constants).
   Generate at least SIZE bytes, padding if necessary.  */

static void
output_constructor (tree exp, unsigned HOST_WIDE_INT size,
		    unsigned int align)
{
  tree type = TREE_TYPE (exp);
  tree link, field = 0;
  tree min_index = 0;
  /* Number of bytes output or skipped so far.
     In other words, current position within the constructor.  */
  HOST_WIDE_INT total_bytes = 0;
  /* Nonzero means BYTE contains part of a byte, to be output.  */
  int byte_buffer_in_use = 0;
  int byte = 0;

  if (HOST_BITS_PER_WIDE_INT < BITS_PER_UNIT)
    abort ();

  if (TREE_CODE (type) == RECORD_TYPE)
    field = TYPE_FIELDS (type);

  if (TREE_CODE (type) == ARRAY_TYPE
      && TYPE_DOMAIN (type) != 0)
    min_index = TYPE_MIN_VALUE (TYPE_DOMAIN (type));

  /* As LINK goes through the elements of the constant,
     FIELD goes through the structure fields, if the constant is a structure.
     if the constant is a union, then we override this,
     by getting the field from the TREE_LIST element.
     But the constant could also be an array.  Then FIELD is zero.

     There is always a maximum of one element in the chain LINK for unions
     (even if the initializer in a source program incorrectly contains
     more one).  */
  for (link = CONSTRUCTOR_ELTS (exp);
       link;
       link = TREE_CHAIN (link),
       field = field ? TREE_CHAIN (field) : 0)
    {
      tree val = TREE_VALUE (link);
      tree index = 0;

      /* The element in a union constructor specifies the proper field
	 or index.  */
      if ((TREE_CODE (type) == RECORD_TYPE || TREE_CODE (type) == UNION_TYPE
	   || TREE_CODE (type) == QUAL_UNION_TYPE)
	  && TREE_PURPOSE (link) != 0)
	field = TREE_PURPOSE (link);

      else if (TREE_CODE (type) == ARRAY_TYPE)
	index = TREE_PURPOSE (link);

#ifdef ASM_COMMENT_START
      if (field && flag_verbose_asm)
	fprintf (asm_out_file, "%s %s:\n",
		 ASM_COMMENT_START, 
		 DECL_NAME (field) 
		 ? IDENTIFIER_POINTER (DECL_NAME (field))
		 : "<anonymous>");
#endif

      /* Eliminate the marker that makes a cast not be an lvalue.  */
      if (val != 0)
	STRIP_NOPS (val);

      if (index && TREE_CODE (index) == RANGE_EXPR)
	{
	  unsigned HOST_WIDE_INT fieldsize
	    = int_size_in_bytes (TREE_TYPE (type));
	  HOST_WIDE_INT lo_index = tree_low_cst (TREE_OPERAND (index, 0), 0);
	  HOST_WIDE_INT hi_index = tree_low_cst (TREE_OPERAND (index, 1), 0);
	  HOST_WIDE_INT index;
	  unsigned int align2 = min_align (align, fieldsize * BITS_PER_UNIT);

	  for (index = lo_index; index <= hi_index; index++)
	    {
	      /* Output the element's initial value.  */
	      if (val == 0)
		assemble_zeros (fieldsize);
	      else
		output_constant (val, fieldsize, align2);

	      /* Count its size.  */
	      total_bytes += fieldsize;
	    }
	}
      else if (field == 0 || !DECL_BIT_FIELD (field))
	{
	  /* An element that is not a bit-field.  */

	  unsigned HOST_WIDE_INT fieldsize;
	  /* Since this structure is static,
	     we know the positions are constant.  */
	  HOST_WIDE_INT pos = field ? int_byte_position (field) : 0;
	  unsigned int align2;

	  if (index != 0)
	    pos = (tree_low_cst (TYPE_SIZE_UNIT (TREE_TYPE (val)), 1)
		   * (tree_low_cst (index, 0) - tree_low_cst (min_index, 0)));

	  /* Output any buffered-up bit-fields preceding this element.  */
	  if (byte_buffer_in_use)
	    {
	      assemble_integer (GEN_INT (byte), 1, BITS_PER_UNIT, 1);
	      total_bytes++;
	      byte_buffer_in_use = 0;
	    }

	  /* Advance to offset of this element.
	     Note no alignment needed in an array, since that is guaranteed
	     if each element has the proper size.  */
	  if ((field != 0 || index != 0) && pos != total_bytes)
	    {
	      assemble_zeros (pos - total_bytes);
	      total_bytes = pos;
	    }

	  /* Find the alignment of this element.  */
	  align2 = min_align (align, BITS_PER_UNIT * pos);

	  /* Determine size this element should occupy.  */
	  if (field)
	    {
	      fieldsize = 0;

	      /* If this is an array with an unspecified upper bound,
		 the initializer determines the size.  */
	      /* ??? This ought to only checked if DECL_SIZE_UNIT is NULL,
		 but we cannot do this until the deprecated support for
		 initializing zero-length array members is removed.  */
	      if (TREE_CODE (TREE_TYPE (field)) == ARRAY_TYPE
		  && TYPE_DOMAIN (TREE_TYPE (field))
		  && ! TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (field))))
		{
		  fieldsize = array_size_for_constructor (val);
		  /* Given a non-empty initialization, this field had
		     better be last.  */
		  if (fieldsize != 0 && TREE_CHAIN (field) != NULL_TREE)
		    abort ();
		}
	      else if (DECL_SIZE_UNIT (field))
		{
		  /* ??? This can't be right.  If the decl size overflows
		     a host integer we will silently emit no data.  */
		  if (host_integerp (DECL_SIZE_UNIT (field), 1))
		    fieldsize = tree_low_cst (DECL_SIZE_UNIT (field), 1);
		}
	    }
	  else
	    fieldsize = int_size_in_bytes (TREE_TYPE (type));

	  /* Output the element's initial value.  */
	  if (val == 0)
	    assemble_zeros (fieldsize);
	  else
	    output_constant (val, fieldsize, align2);

	  /* Count its size.  */
	  total_bytes += fieldsize;
	}
      else if (val != 0 && TREE_CODE (val) != INTEGER_CST)
	error ("invalid initial value for member `%s'",
	       IDENTIFIER_POINTER (DECL_NAME (field)));
      else
	{
	  /* Element that is a bit-field.  */

	  HOST_WIDE_INT next_offset = int_bit_position (field);
	  HOST_WIDE_INT end_offset
	    = (next_offset + tree_low_cst (DECL_SIZE (field), 1));

	  if (val == 0)
	    val = integer_zero_node;

	  /* If this field does not start in this (or, next) byte,
	     skip some bytes.  */
	  if (next_offset / BITS_PER_UNIT != total_bytes)
	    {
	      /* Output remnant of any bit field in previous bytes.  */
	      if (byte_buffer_in_use)
		{
		  assemble_integer (GEN_INT (byte), 1, BITS_PER_UNIT, 1);
		  total_bytes++;
		  byte_buffer_in_use = 0;
		}

	      /* If still not at proper byte, advance to there.  */
	      if (next_offset / BITS_PER_UNIT != total_bytes)
		{
		  assemble_zeros (next_offset / BITS_PER_UNIT - total_bytes);
		  total_bytes = next_offset / BITS_PER_UNIT;
		}
	    }

	  if (! byte_buffer_in_use)
	    byte = 0;

	  /* We must split the element into pieces that fall within
	     separate bytes, and combine each byte with previous or
	     following bit-fields.  */

	  /* next_offset is the offset n fbits from the beginning of
	     the structure to the next bit of this element to be processed.
	     end_offset is the offset of the first bit past the end of
	     this element.  */
	  while (next_offset < end_offset)
	    {
	      int this_time;
	      int shift;
	      HOST_WIDE_INT value;
	      HOST_WIDE_INT next_byte = next_offset / BITS_PER_UNIT;
	      HOST_WIDE_INT next_bit = next_offset % BITS_PER_UNIT;

	      /* Advance from byte to byte
		 within this element when necessary.  */
	      while (next_byte != total_bytes)
		{
		  assemble_integer (GEN_INT (byte), 1, BITS_PER_UNIT, 1);
		  total_bytes++;
		  byte = 0;
		}

	      /* Number of bits we can process at once
		 (all part of the same byte).  */
	      this_time = MIN (end_offset - next_offset,
			       BITS_PER_UNIT - next_bit);
	      if (BYTES_BIG_ENDIAN)
		{
		  /* On big-endian machine, take the most significant bits
		     first (of the bits that are significant)
		     and put them into bytes from the most significant end.  */
		  shift = end_offset - next_offset - this_time;

		  /* Don't try to take a bunch of bits that cross
		     the word boundary in the INTEGER_CST. We can
		     only select bits from the LOW or HIGH part
		     not from both.  */
		  if (shift < HOST_BITS_PER_WIDE_INT
		      && shift + this_time > HOST_BITS_PER_WIDE_INT)
		    {
		      this_time = shift + this_time - HOST_BITS_PER_WIDE_INT;
		      shift = HOST_BITS_PER_WIDE_INT;
		    }

		  /* Now get the bits from the appropriate constant word.  */
		  if (shift < HOST_BITS_PER_WIDE_INT)
		    value = TREE_INT_CST_LOW (val);
		  else if (shift < 2 * HOST_BITS_PER_WIDE_INT)
		    {
		      value = TREE_INT_CST_HIGH (val);
		      shift -= HOST_BITS_PER_WIDE_INT;
		    }
		  else
		    abort ();

		  /* Get the result. This works only when:
		     1 <= this_time <= HOST_BITS_PER_WIDE_INT.  */
		  byte |= (((value >> shift)
			    & (((HOST_WIDE_INT) 2 << (this_time - 1)) - 1))
			   << (BITS_PER_UNIT - this_time - next_bit));
		}
	      else
		{
		  /* On little-endian machines,
		     take first the least significant bits of the value
		     and pack them starting at the least significant
		     bits of the bytes.  */
		  shift = next_offset - int_bit_position (field);

		  /* Don't try to take a bunch of bits that cross
		     the word boundary in the INTEGER_CST. We can
		     only select bits from the LOW or HIGH part
		     not from both.  */
		  if (shift < HOST_BITS_PER_WIDE_INT
		      && shift + this_time > HOST_BITS_PER_WIDE_INT)
		    this_time = (HOST_BITS_PER_WIDE_INT - shift);

		  /* Now get the bits from the appropriate constant word.  */
		  if (shift < HOST_BITS_PER_WIDE_INT)
		    value = TREE_INT_CST_LOW (val);
		  else if (shift < 2 * HOST_BITS_PER_WIDE_INT)
		    {
		      value = TREE_INT_CST_HIGH (val);
		      shift -= HOST_BITS_PER_WIDE_INT;
		    }
		  else
		    abort ();

		  /* Get the result. This works only when:
		     1 <= this_time <= HOST_BITS_PER_WIDE_INT.  */
		  byte |= (((value >> shift)
			    & (((HOST_WIDE_INT) 2 << (this_time - 1)) - 1))
			   << next_bit);
		}

	      next_offset += this_time;
	      byte_buffer_in_use = 1;
	    }
	}
    }

  if (byte_buffer_in_use)
    {
      assemble_integer (GEN_INT (byte), 1, BITS_PER_UNIT, 1);
      total_bytes++;
    }

  if ((unsigned HOST_WIDE_INT)total_bytes < size)
    assemble_zeros (size - total_bytes);
}

/* This TREE_LIST contains any weak symbol declarations waiting
   to be emitted.  */
static GTY(()) tree weak_decls;

/* Mark DECL as weak.  */

static void
mark_weak (tree decl)
{
  DECL_WEAK (decl) = 1;

  if (DECL_RTL_SET_P (decl)
      && GET_CODE (DECL_RTL (decl)) == MEM
      && XEXP (DECL_RTL (decl), 0)
      && GET_CODE (XEXP (DECL_RTL (decl), 0)) == SYMBOL_REF)
    SYMBOL_REF_WEAK (XEXP (DECL_RTL (decl), 0)) = 1;
}

/* Merge weak status between NEWDECL and OLDDECL.  */

void
merge_weak (tree newdecl, tree olddecl)
{
  if (DECL_WEAK (newdecl) == DECL_WEAK (olddecl))
    return;

  if (DECL_WEAK (newdecl))
    {
      tree wd;

      /* NEWDECL is weak, but OLDDECL is not.  */

      /* If we already output the OLDDECL, we're in trouble; we can't
	 go back and make it weak.  This error cannot caught in
	 declare_weak because the NEWDECL and OLDDECL was not yet
	 been merged; therefore, TREE_ASM_WRITTEN was not set.  */
      if (TREE_ASM_WRITTEN (olddecl))
	error ("%Jweak declaration of '%D' must precede definition",
	       newdecl, newdecl);

      /* If we've already generated rtl referencing OLDDECL, we may
	 have done so in a way that will not function properly with
	 a weak symbol.  */
      else if (TREE_USED (olddecl)
	       && TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (olddecl)))
	warning ("%Jweak declaration of '%D' after first use results "
                 "in unspecified behavior", newdecl, newdecl);

      if (SUPPORTS_WEAK)
	{
	  /* We put the NEWDECL on the weak_decls list at some point.
	     Replace it with the OLDDECL.  */
	  for (wd = weak_decls; wd; wd = TREE_CHAIN (wd))
	    if (TREE_VALUE (wd) == newdecl)
	      {
		TREE_VALUE (wd) = olddecl;
		break;
	      }
	  /* We may not find the entry on the list.  If NEWDECL is a
	     weak alias, then we will have already called
	     globalize_decl to remove the entry; in that case, we do
	     not need to do anything.  */
	}

      /* Make the OLDDECL weak; it's OLDDECL that we'll be keeping.  */
      mark_weak (olddecl);
    }
  else
    /* OLDDECL was weak, but NEWDECL was not explicitly marked as
       weak.  Just update NEWDECL to indicate that it's weak too.  */
    mark_weak (newdecl);
}

/* Declare DECL to be a weak symbol.  */

void
declare_weak (tree decl)
{
  if (! TREE_PUBLIC (decl))
    error ("%Jweak declaration of '%D' must be public", decl, decl);
  else if (TREE_CODE (decl) == FUNCTION_DECL && TREE_ASM_WRITTEN (decl))
    error ("%Jweak declaration of '%D' must precede definition", decl, decl);
  else if (SUPPORTS_WEAK)
    {
      if (! DECL_WEAK (decl))
	weak_decls = tree_cons (NULL, decl, weak_decls);
    }
  else
    warning ("%Jweak declaration of '%D' not supported", decl, decl);

  mark_weak (decl);
}

/* Emit any pending weak declarations.  */

void
weak_finish (void)
{
  tree t;

  for (t = weak_decls; t; t = TREE_CHAIN (t))
    {
      tree decl = TREE_VALUE (t);
#if defined (ASM_WEAKEN_DECL) || defined (ASM_WEAKEN_LABEL)
      const char *const name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
#endif

      if (! TREE_USED (decl))
	continue;

#ifdef ASM_WEAKEN_DECL
      ASM_WEAKEN_DECL (asm_out_file, decl, name, NULL);
#else
#ifdef ASM_WEAKEN_LABEL
      ASM_WEAKEN_LABEL (asm_out_file, name);
#else
#ifdef ASM_OUTPUT_WEAK_ALIAS
      warning ("only weak aliases are supported in this configuration");
      return;
#endif
#endif
#endif
    }
}

/* Emit the assembly bits to indicate that DECL is globally visible.  */

static void
globalize_decl (tree decl)
{
  const char *name = XSTR (XEXP (DECL_RTL (decl), 0), 0);

#if defined (ASM_WEAKEN_LABEL) || defined (ASM_WEAKEN_DECL)
  if (DECL_WEAK (decl))
    {
      tree *p, t;

#ifdef ASM_WEAKEN_DECL
      ASM_WEAKEN_DECL (asm_out_file, decl, name, 0);
#else
      ASM_WEAKEN_LABEL (asm_out_file, name);
#endif

      /* Remove this function from the pending weak list so that
	 we do not emit multiple .weak directives for it.  */
      for (p = &weak_decls; (t = *p) ; )
	{
	  if (DECL_ASSEMBLER_NAME (decl) == DECL_ASSEMBLER_NAME (TREE_VALUE (t)))
	    *p = TREE_CHAIN (t);
	  else
	    p = &TREE_CHAIN (t);
	}
      return;
    }
#endif

  (*targetm.asm_out.globalize_label) (asm_out_file, name);
}

/* Some targets do not allow a forward or undefined reference in a
   ASM_OUTPUT_DEF.  Thus, a mechanism is needed to defer the output
   of this assembler code.  The output_def_pair struct holds the
   declaration and target for a deferred output define.  */
struct output_def_pair GTY(())
{
  tree decl;
  tree target;
};
typedef struct output_def_pair *output_def_pair;

/* Variable array of deferred output defines.  */
static GTY ((param_is (struct output_def_pair))) varray_type output_defs;

#ifdef ASM_OUTPUT_DEF
/* Output the assembler code for a define (equate) using ASM_OUTPUT_DEF
   or ASM_OUTPUT_DEF_FROM_DECLS.  The function defines the symbol whose
   tree node is DECL to have the value of the tree node TARGET.  */

static void
assemble_output_def (tree decl ATTRIBUTE_UNUSED, tree target ATTRIBUTE_UNUSED)
{
#ifdef ASM_OUTPUT_DEF_FROM_DECLS
  ASM_OUTPUT_DEF_FROM_DECLS (asm_out_file, decl, target);
#else
  ASM_OUTPUT_DEF (asm_out_file,
		  IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)),
		  IDENTIFIER_POINTER (target));
#endif
}
#endif

/* Process the varray of pending assembler defines.  */

void
process_pending_assemble_output_defs (void)
{
#ifdef ASM_OUTPUT_DEF
  size_t i;
  output_def_pair p;

  if (!output_defs)
    return;

  for (i = 0; i < VARRAY_ACTIVE_SIZE (output_defs); i++)
    {
      p = VARRAY_GENERIC_PTR (output_defs, i);
      assemble_output_def (p->decl, p->target);
    }

  output_defs = NULL;
#endif
}

/* Emit an assembler directive to make the symbol for DECL an alias to
   the symbol for TARGET.  */

void
assemble_alias (tree decl, tree target ATTRIBUTE_UNUSED)
{
  /* We must force creation of DECL_RTL for debug info generation, even though
     we don't use it here.  */
  make_decl_rtl (decl, NULL);

#ifdef ASM_OUTPUT_DEF
  /* Make name accessible from other files, if appropriate.  */

  if (TREE_PUBLIC (decl))
    {
      globalize_decl (decl);
      maybe_assemble_visibility (decl);
    }

  if (TARGET_DEFERRED_OUTPUT_DEFS (decl, target))
    {
      output_def_pair p;

      if (!output_defs)
	VARRAY_GENERIC_PTR_INIT (output_defs, 10, "output defs");
	
      p = ggc_alloc (sizeof (struct output_def_pair));
      p->decl = decl;
      p->target = target;
      VARRAY_PUSH_GENERIC_PTR (output_defs, p);
    }
  else
    assemble_output_def (decl, target);
#else /* !ASM_OUTPUT_DEF */
#if defined (ASM_OUTPUT_WEAK_ALIAS) || defined (ASM_WEAKEN_DECL)
  if (DECL_WEAK (decl))
    {
      const char *name;
      tree *p, t;

      name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
#ifdef ASM_WEAKEN_DECL
      ASM_WEAKEN_DECL (asm_out_file, decl, name, IDENTIFIER_POINTER (target));
#else
      ASM_OUTPUT_WEAK_ALIAS (asm_out_file, name, IDENTIFIER_POINTER (target));
#endif
      /* Remove this function from the pending weak list so that
	 we do not emit multiple .weak directives for it.  */
      for (p = &weak_decls; (t = *p) ; )
	if (DECL_ASSEMBLER_NAME (decl)
	    == DECL_ASSEMBLER_NAME (TREE_VALUE (t)))
	  *p = TREE_CHAIN (t);
	else
	  p = &TREE_CHAIN (t);
    }
  else
    warning ("only weak aliases are supported in this configuration");

#else
  warning ("alias definitions not supported in this configuration; ignored");
#endif
#endif

  TREE_USED (decl) = 1;
  TREE_ASM_WRITTEN (decl) = 1;
  TREE_ASM_WRITTEN (DECL_ASSEMBLER_NAME (decl)) = 1;
}

/* Emit an assembler directive to set symbol for DECL visibility to
   the visibility type VIS, which must not be VISIBILITY_DEFAULT.  */

void
default_assemble_visibility (tree decl, int vis)
{
  static const char * const visibility_types[] = {
    NULL, "internal", "hidden", "protected"
  };

  const char *name, *type;

  name = (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)));
  type = visibility_types[vis];

#ifdef HAVE_GAS_HIDDEN
  fprintf (asm_out_file, "\t.%s\t", type);
  assemble_name (asm_out_file, name);
  fprintf (asm_out_file, "\n");
#else
  warning ("visibility attribute not supported in this configuration; ignored");
#endif
}

/* A helper function to call assemble_visibility when needed for a decl.  */

static void
maybe_assemble_visibility (tree decl)
{
  enum symbol_visibility vis = DECL_VISIBILITY (decl);

  if (vis != VISIBILITY_DEFAULT)
    (* targetm.asm_out.visibility) (decl, vis);
}

/* Returns 1 if the target configuration supports defining public symbols
   so that one of them will be chosen at link time instead of generating a
   multiply-defined symbol error, whether through the use of weak symbols or
   a target-specific mechanism for having duplicates discarded.  */

int
supports_one_only (void)
{
  if (SUPPORTS_ONE_ONLY)
    return 1;
  return SUPPORTS_WEAK;
}

/* Set up DECL as a public symbol that can be defined in multiple
   translation units without generating a linker error.  */

void
make_decl_one_only (tree decl)
{
  if (TREE_CODE (decl) != VAR_DECL && TREE_CODE (decl) != FUNCTION_DECL)
    abort ();

  TREE_PUBLIC (decl) = 1;

  if (SUPPORTS_ONE_ONLY)
    {
#ifdef MAKE_DECL_ONE_ONLY
      MAKE_DECL_ONE_ONLY (decl);
#endif
      DECL_ONE_ONLY (decl) = 1;
    }
  else if (TREE_CODE (decl) == VAR_DECL
      && (DECL_INITIAL (decl) == 0 || DECL_INITIAL (decl) == error_mark_node))
    DECL_COMMON (decl) = 1;
  else if (SUPPORTS_WEAK)
    DECL_WEAK (decl) = 1;
  else
    abort ();
}

void
init_varasm_once (void)
{
  in_named_htab = htab_create_ggc (31, in_named_entry_hash,
				   in_named_entry_eq, NULL);
  const_desc_htab = htab_create_ggc (1009, const_desc_hash,
				     const_desc_eq, NULL);

  const_alias_set = new_alias_set ();
}

enum tls_model
decl_tls_model (tree decl)
{
  enum tls_model kind;
  tree attr = lookup_attribute ("tls_model", DECL_ATTRIBUTES (decl));
  bool is_local;

  if (attr)
    {
      attr = TREE_VALUE (TREE_VALUE (attr));
      if (TREE_CODE (attr) != STRING_CST)
	abort ();
      if (!strcmp (TREE_STRING_POINTER (attr), "local-exec"))
	kind = TLS_MODEL_LOCAL_EXEC;
      else if (!strcmp (TREE_STRING_POINTER (attr), "initial-exec"))
	kind = TLS_MODEL_INITIAL_EXEC;
      else if (!strcmp (TREE_STRING_POINTER (attr), "local-dynamic"))
	kind = optimize ? TLS_MODEL_LOCAL_DYNAMIC : TLS_MODEL_GLOBAL_DYNAMIC;
      else if (!strcmp (TREE_STRING_POINTER (attr), "global-dynamic"))
	kind = TLS_MODEL_GLOBAL_DYNAMIC;
      else
	abort ();
      return kind;
    }

  is_local = (*targetm.binds_local_p) (decl);
  if (!flag_pic)
    {
      if (is_local)
	kind = TLS_MODEL_LOCAL_EXEC;
      else
	kind = TLS_MODEL_INITIAL_EXEC;
    }
  /* Local dynamic is inefficient when we're not combining the
     parts of the address.  */
  else if (optimize && is_local)
    kind = TLS_MODEL_LOCAL_DYNAMIC;
  else
    kind = TLS_MODEL_GLOBAL_DYNAMIC;
  if (kind < flag_tls_default)
    kind = flag_tls_default;

  return kind;
}

/* Select a set of attributes for section NAME based on the properties
   of DECL and whether or not RELOC indicates that DECL's initializer
   might contain runtime relocations.

   We make the section read-only and executable for a function decl,
   read-only for a const data decl, and writable for a non-const data decl.  */

unsigned int
default_section_type_flags (tree decl, const char *name, int reloc)
{
  return default_section_type_flags_1 (decl, name, reloc, flag_pic);
}

unsigned int
default_section_type_flags_1 (tree decl, const char *name, int reloc,
			      int shlib)
{
  unsigned int flags;

  if (decl && TREE_CODE (decl) == FUNCTION_DECL)
    flags = SECTION_CODE;
  else if (decl && decl_readonly_section_1 (decl, reloc, shlib))
    flags = 0;
  else
    flags = SECTION_WRITE;

  if (decl && DECL_ONE_ONLY (decl))
    flags |= SECTION_LINKONCE;

  if (decl && TREE_CODE (decl) == VAR_DECL && DECL_THREAD_LOCAL (decl))
    flags |= SECTION_TLS | SECTION_WRITE;

  if (strcmp (name, ".bss") == 0
      || strncmp (name, ".bss.", 5) == 0
      || strncmp (name, ".gnu.linkonce.b.", 16) == 0
      || strcmp (name, ".sbss") == 0
      || strncmp (name, ".sbss.", 6) == 0
      || strncmp (name, ".gnu.linkonce.sb.", 17) == 0
      || strcmp (name, ".tbss") == 0
      || strncmp (name, ".gnu.linkonce.tb.", 17) == 0)
    flags |= SECTION_BSS;

  if (strcmp (name, ".tdata") == 0
      || strcmp (name, ".tbss") == 0
      || strncmp (name, ".gnu.linkonce.td.", 17) == 0
      || strncmp (name, ".gnu.linkonce.tb.", 17) == 0)
    flags |= SECTION_TLS;

  /* These three sections have special ELF types.  They are neither
     SHT_PROGBITS nor SHT_NOBITS, so when changing sections we don't
     want to print a section type (@progbits or @nobits).  If someone
     is silly enough to emit code or TLS variables to one of these
     sections, then don't handle them specially.  */
  if (!(flags & (SECTION_CODE | SECTION_BSS | SECTION_TLS))
      && (strcmp (name, ".init_array") == 0
	  || strcmp (name, ".fini_array") == 0
	  || strcmp (name, ".preinit_array") == 0))
    flags |= SECTION_NOTYPE;

  return flags;
}

/* Output assembly to switch to section NAME with attribute FLAGS.
   Four variants for common object file formats.  */

void
default_no_named_section (const char *name ATTRIBUTE_UNUSED,
			  unsigned int flags ATTRIBUTE_UNUSED)
{
  /* Some object formats don't support named sections at all.  The
     front-end should already have flagged this as an error.  */
  abort ();
}

void
default_elf_asm_named_section (const char *name, unsigned int flags)
{
  char flagchars[10], *f = flagchars;

  if (! named_section_first_declaration (name))
    {
      fprintf (asm_out_file, "\t.section\t%s\n", name);
      return;
    }

  if (!(flags & SECTION_DEBUG))
    *f++ = 'a';
  if (flags & SECTION_WRITE)
    *f++ = 'w';
  if (flags & SECTION_CODE)
    *f++ = 'x';
  if (flags & SECTION_SMALL)
    *f++ = 's';
  if (flags & SECTION_MERGE)
    *f++ = 'M';
  if (flags & SECTION_STRINGS)
    *f++ = 'S';
  if (flags & SECTION_TLS)
    *f++ = 'T';
  *f = '\0';

  fprintf (asm_out_file, "\t.section\t%s,\"%s\"", name, flagchars);

  if (!(flags & SECTION_NOTYPE))
    {
      const char *type;

      if (flags & SECTION_BSS)
	type = "nobits";
      else
	type = "progbits";

      fprintf (asm_out_file, ",@%s", type);

      if (flags & SECTION_ENTSIZE)
	fprintf (asm_out_file, ",%d", flags & SECTION_ENTSIZE);
    }

  putc ('\n', asm_out_file);
}

void
default_coff_asm_named_section (const char *name, unsigned int flags)
{
  char flagchars[8], *f = flagchars;

  if (flags & SECTION_WRITE)
    *f++ = 'w';
  if (flags & SECTION_CODE)
    *f++ = 'x';
  *f = '\0';

  fprintf (asm_out_file, "\t.section\t%s,\"%s\"\n", name, flagchars);
}

void
default_pe_asm_named_section (const char *name, unsigned int flags)
{
  default_coff_asm_named_section (name, flags);

  if (flags & SECTION_LINKONCE)
    {
      /* Functions may have been compiled at various levels of
         optimization so we can't use `same_size' here.
         Instead, have the linker pick one.  */
      fprintf (asm_out_file, "\t.linkonce %s\n",
	       (flags & SECTION_CODE ? "discard" : "same_size"));
    }
}

/* The lame default section selector.  */

void
default_select_section (tree decl, int reloc,
			unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
{
  bool readonly = false;

  if (DECL_P (decl))
    {
      if (decl_readonly_section (decl, reloc))
	readonly = true;
    }
  else if (TREE_CODE (decl) == CONSTRUCTOR)
    {
      if (! ((flag_pic && reloc)
	     || !TREE_READONLY (decl)
	     || TREE_SIDE_EFFECTS (decl)
	     || !TREE_CONSTANT (decl)))
	readonly = true;
    }
  else if (TREE_CODE (decl) == STRING_CST)
    readonly = !flag_writable_strings;
  else if (! (flag_pic && reloc))
    readonly = true;

  if (readonly)
    readonly_data_section ();
  else
    data_section ();
}

/* A helper function for default_elf_select_section and
   default_elf_unique_section.  Categorizes the DECL.  */

enum section_category
{
  SECCAT_TEXT,

  SECCAT_RODATA,
  SECCAT_RODATA_MERGE_STR,
  SECCAT_RODATA_MERGE_STR_INIT,
  SECCAT_RODATA_MERGE_CONST,
  SECCAT_SRODATA,

  SECCAT_DATA,

  /* To optimize loading of shared programs, define following subsections
     of data section:
	_REL	Contains data that has relocations, so they get grouped
		together and dynamic linker will visit fewer pages in memory.
	_RO	Contains data that is otherwise read-only.  This is useful
		with prelinking as most relocations won't be dynamically
		linked and thus stay read only.
	_LOCAL	Marks data containing relocations only to local objects.
		These relocations will get fully resolved by prelinking.  */
  SECCAT_DATA_REL,
  SECCAT_DATA_REL_LOCAL,
  SECCAT_DATA_REL_RO,
  SECCAT_DATA_REL_RO_LOCAL,

  SECCAT_SDATA,
  SECCAT_TDATA,

  SECCAT_BSS,
  SECCAT_SBSS,
  SECCAT_TBSS
};

static enum section_category
categorize_decl_for_section (tree, int, int);

static enum section_category
categorize_decl_for_section (tree decl, int reloc, int shlib)
{
  enum section_category ret;

  if (TREE_CODE (decl) == FUNCTION_DECL)
    return SECCAT_TEXT;
  else if (TREE_CODE (decl) == STRING_CST)
    {
      if (flag_writable_strings)
	return SECCAT_DATA;
      else
	return SECCAT_RODATA_MERGE_STR;
    }
  else if (TREE_CODE (decl) == VAR_DECL)
    {
      if (DECL_INITIAL (decl) == NULL
	  || DECL_INITIAL (decl) == error_mark_node)
	ret = SECCAT_BSS;
      else if (! TREE_READONLY (decl)
	       || TREE_SIDE_EFFECTS (decl)
	       || ! TREE_CONSTANT (DECL_INITIAL (decl)))
	{
	  if (shlib && (reloc & 2))
	    ret = SECCAT_DATA_REL;
	  else if (shlib && reloc)
	    ret = SECCAT_DATA_REL_LOCAL;
	  else
	    ret = SECCAT_DATA;
	}
      else if (shlib && (reloc & 2))
	ret = SECCAT_DATA_REL_RO;
      else if (shlib && reloc)
	ret = SECCAT_DATA_REL_RO_LOCAL;
      else if (reloc || flag_merge_constants < 2)
	/* C and C++ don't allow different variables to share the same
	   location.  -fmerge-all-constants allows even that (at the
	   expense of not conforming).  */
	ret = SECCAT_RODATA;
      else if (TREE_CODE (DECL_INITIAL (decl)) == STRING_CST)
	ret = SECCAT_RODATA_MERGE_STR_INIT;
      else
	ret = SECCAT_RODATA_MERGE_CONST;
    }
  else if (TREE_CODE (decl) == CONSTRUCTOR)
    {
      if ((shlib && reloc)
	  || TREE_SIDE_EFFECTS (decl)
	  || ! TREE_CONSTANT (decl))
	ret = SECCAT_DATA;
      else
	ret = SECCAT_RODATA;
    }
  else
    ret = SECCAT_RODATA;

  /* There are no read-only thread-local sections.  */
  if (TREE_CODE (decl) == VAR_DECL && DECL_THREAD_LOCAL (decl))
    {
      if (ret == SECCAT_BSS)
	ret = SECCAT_TBSS;
      else
	ret = SECCAT_TDATA;
    }

  /* If the target uses small data sections, select it.  */
  else if ((*targetm.in_small_data_p) (decl))
    {
      if (ret == SECCAT_BSS)
	ret = SECCAT_SBSS;
      else if (targetm.have_srodata_section && ret == SECCAT_RODATA)
	ret = SECCAT_SRODATA;
      else
	ret = SECCAT_SDATA;
    }

  return ret;
}

bool
decl_readonly_section (tree decl, int reloc)
{
  return decl_readonly_section_1 (decl, reloc, flag_pic);
}

bool
decl_readonly_section_1 (tree decl, int reloc, int shlib)
{
  switch (categorize_decl_for_section (decl, reloc, shlib))
    {
    case SECCAT_RODATA:
    case SECCAT_RODATA_MERGE_STR:
    case SECCAT_RODATA_MERGE_STR_INIT:
    case SECCAT_RODATA_MERGE_CONST:
    case SECCAT_SRODATA:
      return true;
      break;
    default:
      return false;
      break;
    }
}

/* Select a section based on the above categorization.  */

void
default_elf_select_section (tree decl, int reloc,
			    unsigned HOST_WIDE_INT align)
{
  default_elf_select_section_1 (decl, reloc, align, flag_pic);
}

void
default_elf_select_section_1 (tree decl, int reloc,
			      unsigned HOST_WIDE_INT align, int shlib)
{
  switch (categorize_decl_for_section (decl, reloc, shlib))
    {
    case SECCAT_TEXT:
      /* We're not supposed to be called on FUNCTION_DECLs.  */
      abort ();
    case SECCAT_RODATA:
      readonly_data_section ();
      break;
    case SECCAT_RODATA_MERGE_STR:
      mergeable_string_section (decl, align, 0);
      break;
    case SECCAT_RODATA_MERGE_STR_INIT:
      mergeable_string_section (DECL_INITIAL (decl), align, 0);
      break;
    case SECCAT_RODATA_MERGE_CONST:
      mergeable_constant_section (DECL_MODE (decl), align, 0);
      break;
    case SECCAT_SRODATA:
      named_section (NULL_TREE, ".sdata2", reloc);
      break;
    case SECCAT_DATA:
      data_section ();
      break;
    case SECCAT_DATA_REL:
      named_section (NULL_TREE, ".data.rel", reloc);
      break;
    case SECCAT_DATA_REL_LOCAL:
      named_section (NULL_TREE, ".data.rel.local", reloc);
      break;
    case SECCAT_DATA_REL_RO:
      named_section (NULL_TREE, ".data.rel.ro", reloc);
      break;
    case SECCAT_DATA_REL_RO_LOCAL:
      named_section (NULL_TREE, ".data.rel.ro.local", reloc);
      break;
    case SECCAT_SDATA:
      named_section (NULL_TREE, ".sdata", reloc);
      break;
    case SECCAT_TDATA:
      named_section (NULL_TREE, ".tdata", reloc);
      break;
    case SECCAT_BSS:
#ifdef BSS_SECTION_ASM_OP
      bss_section ();
#else
      named_section (NULL_TREE, ".bss", reloc);
#endif
      break;
    case SECCAT_SBSS:
      named_section (NULL_TREE, ".sbss", reloc);
      break;
    case SECCAT_TBSS:
      named_section (NULL_TREE, ".tbss", reloc);
      break;
    default:
      abort ();
    }
}

/* Construct a unique section name based on the decl name and the
   categorization performed above.  */

void
default_unique_section (tree decl, int reloc)
{
  default_unique_section_1 (decl, reloc, flag_pic);
}

void
default_unique_section_1 (tree decl, int reloc, int shlib)
{
  bool one_only = DECL_ONE_ONLY (decl);
  const char *prefix, *name;
  size_t nlen, plen;
  char *string;

  switch (categorize_decl_for_section (decl, reloc, shlib))
    {
    case SECCAT_TEXT:
      prefix = one_only ? ".gnu.linkonce.t." : ".text.";
      break;
    case SECCAT_RODATA:
    case SECCAT_RODATA_MERGE_STR:
    case SECCAT_RODATA_MERGE_STR_INIT:
    case SECCAT_RODATA_MERGE_CONST:
      prefix = one_only ? ".gnu.linkonce.r." : ".rodata.";
      break;
    case SECCAT_SRODATA:
      prefix = one_only ? ".gnu.linkonce.s2." : ".sdata2.";
      break;
    case SECCAT_DATA:
    case SECCAT_DATA_REL:
    case SECCAT_DATA_REL_LOCAL:
    case SECCAT_DATA_REL_RO:
    case SECCAT_DATA_REL_RO_LOCAL:
      prefix = one_only ? ".gnu.linkonce.d." : ".data.";
      break;
    case SECCAT_SDATA:
      prefix = one_only ? ".gnu.linkonce.s." : ".sdata.";
      break;
    case SECCAT_BSS:
      prefix = one_only ? ".gnu.linkonce.b." : ".bss.";
      break;
    case SECCAT_SBSS:
      prefix = one_only ? ".gnu.linkonce.sb." : ".sbss.";
      break;
    case SECCAT_TDATA:
      prefix = one_only ? ".gnu.linkonce.td." : ".tdata.";
      break;
    case SECCAT_TBSS:
      prefix = one_only ? ".gnu.linkonce.tb." : ".tbss.";
      break;
    default:
      abort ();
    }
  plen = strlen (prefix);

  name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
  name = (* targetm.strip_name_encoding) (name);
  nlen = strlen (name);

  string = alloca (nlen + plen + 1);
  memcpy (string, prefix, plen);
  memcpy (string + plen, name, nlen + 1);

  DECL_SECTION_NAME (decl) = build_string (nlen + plen, string);
}

void
default_select_rtx_section (enum machine_mode mode ATTRIBUTE_UNUSED,
			    rtx x,
			    unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
{
  if (flag_pic)
    switch (GET_CODE (x))
      {
      case CONST:
      case SYMBOL_REF:
      case LABEL_REF:
	data_section ();
	return;

      default:
	break;
      }

  readonly_data_section ();
}

void
default_elf_select_rtx_section (enum machine_mode mode, rtx x,
				unsigned HOST_WIDE_INT align)
{
  /* ??? Handle small data here somehow.  */

  if (flag_pic)
    switch (GET_CODE (x))
      {
      case CONST:
      case SYMBOL_REF:
	named_section (NULL_TREE, ".data.rel.ro", 3);
	return;

      case LABEL_REF:
	named_section (NULL_TREE, ".data.rel.ro.local", 1);
	return;

      default:
	break;
      }

  mergeable_constant_section (mode, align, 0);
}

/* Set the generally applicable flags on the SYMBOL_REF for EXP.  */

void
default_encode_section_info (tree decl, rtx rtl, int first ATTRIBUTE_UNUSED)
{
  rtx symbol;
  int flags;

  /* Careful not to prod global register variables.  */
  if (GET_CODE (rtl) != MEM)
    return;
  symbol = XEXP (rtl, 0);
  if (GET_CODE (symbol) != SYMBOL_REF)
    return;

  flags = 0;
  if (TREE_CODE (decl) == FUNCTION_DECL)
    flags |= SYMBOL_FLAG_FUNCTION;
  if ((*targetm.binds_local_p) (decl))
    flags |= SYMBOL_FLAG_LOCAL;
  if ((*targetm.in_small_data_p) (decl))
    flags |= SYMBOL_FLAG_SMALL;
  if (TREE_CODE (decl) == VAR_DECL && DECL_THREAD_LOCAL (decl))
    flags |= decl_tls_model (decl) << SYMBOL_FLAG_TLS_SHIFT;
  /* ??? Why is DECL_EXTERNAL ever set for non-PUBLIC names?  Without
     being PUBLIC, the thing *must* be defined in this translation unit.
     Prevent this buglet from being propagated into rtl code as well.  */
  if (DECL_P (decl) && DECL_EXTERNAL (decl) && TREE_PUBLIC (decl))
    flags |= SYMBOL_FLAG_EXTERNAL;

  SYMBOL_REF_FLAGS (symbol) = flags;
}

/* By default, we do nothing for encode_section_info, so we need not
   do anything but discard the '*' marker.  */

const char *
default_strip_name_encoding (const char *str)
{
  return str + (*str == '*');
}

/* Assume ELF-ish defaults, since that's pretty much the most liberal
   wrt cross-module name binding.  */

bool
default_binds_local_p (tree exp)
{
  return default_binds_local_p_1 (exp, flag_shlib);
}

bool
default_binds_local_p_1 (tree exp, int shlib)
{
  bool local_p;

  /* A non-decl is an entry in the constant pool.  */
  if (!DECL_P (exp))
    local_p = true;
  /* Static variables are always local.  */
  else if (! TREE_PUBLIC (exp))
    local_p = true;
  /* A variable is local if the user tells us so.  */
  else if (DECL_VISIBILITY (exp) != VISIBILITY_DEFAULT)
    local_p = true;
  /* Otherwise, variables defined outside this object may not be local.  */
  else if (DECL_EXTERNAL (exp))
    local_p = false;
  /* Linkonce and weak data are never local.  */
  else if (DECL_ONE_ONLY (exp) || DECL_WEAK (exp))
    local_p = false;
  /* If PIC, then assume that any global name can be overridden by
     symbols resolved from other modules.  */
  else if (shlib)
    local_p = false;
  /* Uninitialized COMMON variable may be unified with symbols
     resolved from other modules.  */
  else if (DECL_COMMON (exp)
	   && (DECL_INITIAL (exp) == NULL
	       || DECL_INITIAL (exp) == error_mark_node))
    local_p = false;
  /* Otherwise we're left with initialized (or non-common) global data
     which is of necessity defined locally.  */
  else
    local_p = true;

  return local_p;
}

/* Determine whether or not a pointer mode is valid. Assume defaults
   of ptr_mode or Pmode - can be overridden.  */
bool
default_valid_pointer_mode (enum machine_mode mode)
{
  return (mode == ptr_mode || mode == Pmode);
}

/* Default function to output code that will globalize a label.  A
   target must define GLOBAL_ASM_OP or provide it's own function to
   globalize a label.  */
#ifdef GLOBAL_ASM_OP
void
default_globalize_label (FILE * stream, const char *name)
{
  fputs (GLOBAL_ASM_OP, stream);
  assemble_name (stream, name);
  putc ('\n', stream);
}
#endif /* GLOBAL_ASM_OP */

/* This is how to output an internal numbered label where PREFIX is
   the class of label and LABELNO is the number within the class.  */

void
default_internal_label (FILE *stream, const char *prefix,
			unsigned long labelno)
{
  char *const buf = alloca (40 + strlen (prefix));
  ASM_GENERATE_INTERNAL_LABEL (buf, prefix, labelno);
  ASM_OUTPUT_LABEL (stream, buf);
}

/* This is the default behavior at the beginning of a file.  It's
   controlled by two other target-hook toggles.  */
void
default_file_start (void)
{
  if (targetm.file_start_app_off && !flag_verbose_asm)
    fputs (ASM_APP_OFF, asm_out_file);

  if (targetm.file_start_file_directive)
    output_file_directive (asm_out_file, main_input_filename);
}

/* This is a generic routine suitable for use as TARGET_ASM_FILE_END
   which emits a special section directive used to indicate whether or
   not this object file needs an executable stack.  This is primarily
   a GNU extension to ELF but could be used on other targets.  */
void
file_end_indicate_exec_stack (void)
{
  unsigned int flags = SECTION_DEBUG;
  if (trampolines_created)
    flags |= SECTION_CODE;

  named_section_flags (".note.GNU-stack", flags);
}

#include "gt-varasm.h"
