/* Subroutines for insn-output.c for HPPA.
   Copyright (C) 1992-2021 Free Software Foundation, Inc.
   Contributed by Tim Moore (moore@cs.utah.edu), based on sparc.c

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 3, 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 COPYING3.  If not see
<http://www.gnu.org/licenses/>.  */

#define IN_TARGET_CODE 1

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "memmodel.h"
#include "backend.h"
#include "target.h"
#include "rtl.h"
#include "tree.h"
#include "df.h"
#include "tm_p.h"
#include "stringpool.h"
#include "attribs.h"
#include "optabs.h"
#include "regs.h"
#include "emit-rtl.h"
#include "recog.h"
#include "diagnostic-core.h"
#include "insn-attr.h"
#include "alias.h"
#include "fold-const.h"
#include "stor-layout.h"
#include "varasm.h"
#include "calls.h"
#include "output.h"
#include "except.h"
#include "explow.h"
#include "expr.h"
#include "reload.h"
#include "common/common-target.h"
#include "langhooks.h"
#include "cfgrtl.h"
#include "opts.h"
#include "builtins.h"

/* This file should be included last.  */
#include "target-def.h"

/* Return nonzero if there is a bypass for the output of 
   OUT_INSN and the fp store IN_INSN.  */
int
pa_fpstore_bypass_p (rtx_insn *out_insn, rtx_insn *in_insn)
{
  machine_mode store_mode;
  machine_mode other_mode;
  rtx set;

  if (recog_memoized (in_insn) < 0
      || (get_attr_type (in_insn) != TYPE_FPSTORE
	  && get_attr_type (in_insn) != TYPE_FPSTORE_LOAD)
      || recog_memoized (out_insn) < 0)
    return 0;

  store_mode = GET_MODE (SET_SRC (PATTERN (in_insn)));

  set = single_set (out_insn);
  if (!set)
    return 0;

  other_mode = GET_MODE (SET_SRC (set));

  return (GET_MODE_SIZE (store_mode) == GET_MODE_SIZE (other_mode));
}
  

#ifndef DO_FRAME_NOTES
#ifdef INCOMING_RETURN_ADDR_RTX
#define DO_FRAME_NOTES 1
#else
#define DO_FRAME_NOTES 0
#endif
#endif

static void pa_option_override (void);
static void copy_reg_pointer (rtx, rtx);
static void fix_range (const char *);
static int hppa_register_move_cost (machine_mode mode, reg_class_t,
				    reg_class_t);
static int hppa_address_cost (rtx, machine_mode mode, addr_space_t, bool);
static bool hppa_rtx_costs (rtx, machine_mode, int, int, int *, bool);
static inline rtx force_mode (machine_mode, rtx);
static void pa_reorg (void);
static void pa_combine_instructions (void);
static int pa_can_combine_p (rtx_insn *, rtx_insn *, rtx_insn *, int, rtx,
			     rtx, rtx);
static bool forward_branch_p (rtx_insn *);
static void compute_zdepwi_operands (unsigned HOST_WIDE_INT, unsigned *);
static void compute_zdepdi_operands (unsigned HOST_WIDE_INT, unsigned *);
static int compute_cpymem_length (rtx_insn *);
static int compute_clrmem_length (rtx_insn *);
static bool pa_assemble_integer (rtx, unsigned int, int);
static void remove_useless_addtr_insns (int);
static void store_reg (int, HOST_WIDE_INT, int);
static void store_reg_modify (int, int, HOST_WIDE_INT);
static void load_reg (int, HOST_WIDE_INT, int);
static void set_reg_plus_d (int, int, HOST_WIDE_INT, int);
static rtx pa_function_value (const_tree, const_tree, bool);
static rtx pa_libcall_value (machine_mode, const_rtx);
static bool pa_function_value_regno_p (const unsigned int);
static void pa_output_function_prologue (FILE *) ATTRIBUTE_UNUSED;
static void pa_linux_output_function_prologue (FILE *) ATTRIBUTE_UNUSED;
static void update_total_code_bytes (unsigned int);
static void pa_output_function_epilogue (FILE *);
static int pa_adjust_cost (rtx_insn *, int, rtx_insn *, int, unsigned int);
static int pa_issue_rate (void);
static int pa_reloc_rw_mask (void);
static void pa_som_asm_init_sections (void) ATTRIBUTE_UNUSED;
static section *pa_som_tm_clone_table_section (void) ATTRIBUTE_UNUSED;
static section *pa_select_section (tree, int, unsigned HOST_WIDE_INT)
     ATTRIBUTE_UNUSED;
static void pa_encode_section_info (tree, rtx, int);
static const char *pa_strip_name_encoding (const char *);
static bool pa_function_ok_for_sibcall (tree, tree);
static void pa_globalize_label (FILE *, const char *)
     ATTRIBUTE_UNUSED;
static void pa_asm_output_mi_thunk (FILE *, tree, HOST_WIDE_INT,
				    HOST_WIDE_INT, tree);
#if !defined(USE_COLLECT2)
static void pa_asm_out_constructor (rtx, int);
static void pa_asm_out_destructor (rtx, int);
#endif
static void pa_init_builtins (void);
static rtx pa_expand_builtin (tree, rtx, rtx, machine_mode mode, int);
static rtx hppa_builtin_saveregs (void);
static void hppa_va_start (tree, rtx);
static tree hppa_gimplify_va_arg_expr (tree, tree, gimple_seq *, gimple_seq *);
static bool pa_scalar_mode_supported_p (scalar_mode);
static bool pa_commutative_p (const_rtx x, int outer_code);
static void copy_fp_args (rtx_insn *) ATTRIBUTE_UNUSED;
static int length_fp_args (rtx_insn *) ATTRIBUTE_UNUSED;
static rtx hppa_legitimize_address (rtx, rtx, machine_mode);
static inline void pa_file_start_level (void) ATTRIBUTE_UNUSED;
static inline void pa_file_start_space (int) ATTRIBUTE_UNUSED;
static inline void pa_file_start_file (int) ATTRIBUTE_UNUSED;
static inline void pa_file_start_mcount (const char*) ATTRIBUTE_UNUSED;
static void pa_elf_file_start (void) ATTRIBUTE_UNUSED;
static void pa_som_file_start (void) ATTRIBUTE_UNUSED;
static void pa_linux_file_start (void) ATTRIBUTE_UNUSED;
static void pa_hpux64_gas_file_start (void) ATTRIBUTE_UNUSED;
static void pa_hpux64_hpas_file_start (void) ATTRIBUTE_UNUSED;
static void output_deferred_plabels (void);
static void output_deferred_profile_counters (void) ATTRIBUTE_UNUSED;
static void pa_file_end (void);
static void pa_init_libfuncs (void);
static rtx pa_struct_value_rtx (tree, int);
static bool pa_pass_by_reference (cumulative_args_t,
				  const function_arg_info &);
static int pa_arg_partial_bytes (cumulative_args_t, const function_arg_info &);
static void pa_function_arg_advance (cumulative_args_t,
				     const function_arg_info &);
static rtx pa_function_arg (cumulative_args_t, const function_arg_info &);
static pad_direction pa_function_arg_padding (machine_mode, const_tree);
static unsigned int pa_function_arg_boundary (machine_mode, const_tree);
static struct machine_function * pa_init_machine_status (void);
static reg_class_t pa_secondary_reload (bool, rtx, reg_class_t,
					machine_mode,
					secondary_reload_info *);
static bool pa_secondary_memory_needed (machine_mode,
					reg_class_t, reg_class_t);
static void pa_extra_live_on_entry (bitmap);
static machine_mode pa_promote_function_mode (const_tree,
						   machine_mode, int *,
						   const_tree, int);

static void pa_asm_trampoline_template (FILE *);
static void pa_trampoline_init (rtx, tree, rtx);
static rtx pa_trampoline_adjust_address (rtx);
static rtx pa_delegitimize_address (rtx);
static bool pa_print_operand_punct_valid_p (unsigned char);
static rtx pa_internal_arg_pointer (void);
static bool pa_can_eliminate (const int, const int);
static void pa_conditional_register_usage (void);
static machine_mode pa_c_mode_for_suffix (char);
static section *pa_function_section (tree, enum node_frequency, bool, bool);
static bool pa_cannot_force_const_mem (machine_mode, rtx);
static bool pa_legitimate_constant_p (machine_mode, rtx);
static unsigned int pa_section_type_flags (tree, const char *, int);
static bool pa_legitimate_address_p (machine_mode, rtx, bool);
static bool pa_callee_copies (cumulative_args_t, const function_arg_info &);
static unsigned int pa_hard_regno_nregs (unsigned int, machine_mode);
static bool pa_hard_regno_mode_ok (unsigned int, machine_mode);
static bool pa_modes_tieable_p (machine_mode, machine_mode);
static bool pa_can_change_mode_class (machine_mode, machine_mode, reg_class_t);
static HOST_WIDE_INT pa_starting_frame_offset (void);
static section* pa_elf_select_rtx_section(machine_mode, rtx, unsigned HOST_WIDE_INT) ATTRIBUTE_UNUSED;

/* The following extra sections are only used for SOM.  */
static GTY(()) section *som_readonly_data_section;
static GTY(()) section *som_one_only_readonly_data_section;
static GTY(()) section *som_one_only_data_section;
static GTY(()) section *som_tm_clone_table_section;

/* Counts for the number of callee-saved general and floating point
   registers which were saved by the current function's prologue.  */
static int gr_saved, fr_saved;

/* Boolean indicating whether the return pointer was saved by the
   current function's prologue.  */
static bool rp_saved;

static rtx find_addr_reg (rtx);

/* Keep track of the number of bytes we have output in the CODE subspace
   during this compilation so we'll know when to emit inline long-calls.  */
unsigned long total_code_bytes;

/* The last address of the previous function plus the number of bytes in
   associated thunks that have been output.  This is used to determine if
   a thunk can use an IA-relative branch to reach its target function.  */
static unsigned int last_address;

/* Variables to handle plabels that we discover are necessary at assembly
   output time.  They are output after the current function.  */
struct GTY(()) deferred_plabel
{
  rtx internal_label;
  rtx symbol;
};
static GTY((length ("n_deferred_plabels"))) struct deferred_plabel *
  deferred_plabels;
static size_t n_deferred_plabels = 0;

/* Initialize the GCC target structure.  */

#undef TARGET_OPTION_OVERRIDE
#define TARGET_OPTION_OVERRIDE pa_option_override

#undef TARGET_ASM_ALIGNED_HI_OP
#define TARGET_ASM_ALIGNED_HI_OP "\t.half\t"
#undef TARGET_ASM_ALIGNED_SI_OP
#define TARGET_ASM_ALIGNED_SI_OP "\t.word\t"
#undef TARGET_ASM_ALIGNED_DI_OP
#define TARGET_ASM_ALIGNED_DI_OP "\t.dword\t"
#undef TARGET_ASM_UNALIGNED_HI_OP
#define TARGET_ASM_UNALIGNED_HI_OP TARGET_ASM_ALIGNED_HI_OP
#undef TARGET_ASM_UNALIGNED_SI_OP
#define TARGET_ASM_UNALIGNED_SI_OP TARGET_ASM_ALIGNED_SI_OP
#undef TARGET_ASM_UNALIGNED_DI_OP
#define TARGET_ASM_UNALIGNED_DI_OP TARGET_ASM_ALIGNED_DI_OP
#undef TARGET_ASM_INTEGER
#define TARGET_ASM_INTEGER pa_assemble_integer

#undef TARGET_ASM_FUNCTION_EPILOGUE
#define TARGET_ASM_FUNCTION_EPILOGUE pa_output_function_epilogue

#undef TARGET_FUNCTION_VALUE
#define TARGET_FUNCTION_VALUE pa_function_value
#undef TARGET_LIBCALL_VALUE
#define TARGET_LIBCALL_VALUE pa_libcall_value
#undef TARGET_FUNCTION_VALUE_REGNO_P
#define TARGET_FUNCTION_VALUE_REGNO_P pa_function_value_regno_p

#undef TARGET_LEGITIMIZE_ADDRESS
#define TARGET_LEGITIMIZE_ADDRESS hppa_legitimize_address

#undef TARGET_SCHED_ADJUST_COST
#define TARGET_SCHED_ADJUST_COST pa_adjust_cost
#undef TARGET_SCHED_ISSUE_RATE
#define TARGET_SCHED_ISSUE_RATE pa_issue_rate

#undef TARGET_ENCODE_SECTION_INFO
#define TARGET_ENCODE_SECTION_INFO pa_encode_section_info
#undef TARGET_STRIP_NAME_ENCODING
#define TARGET_STRIP_NAME_ENCODING pa_strip_name_encoding

#undef TARGET_FUNCTION_OK_FOR_SIBCALL
#define TARGET_FUNCTION_OK_FOR_SIBCALL pa_function_ok_for_sibcall

#undef TARGET_COMMUTATIVE_P
#define TARGET_COMMUTATIVE_P pa_commutative_p

#undef TARGET_ASM_OUTPUT_MI_THUNK
#define TARGET_ASM_OUTPUT_MI_THUNK pa_asm_output_mi_thunk
#undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
#define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_const_tree_hwi_hwi_const_tree_true

#undef TARGET_ASM_FILE_END
#define TARGET_ASM_FILE_END pa_file_end

#undef TARGET_ASM_RELOC_RW_MASK
#define TARGET_ASM_RELOC_RW_MASK pa_reloc_rw_mask

#undef TARGET_PRINT_OPERAND_PUNCT_VALID_P
#define TARGET_PRINT_OPERAND_PUNCT_VALID_P pa_print_operand_punct_valid_p

#if !defined(USE_COLLECT2)
#undef TARGET_ASM_CONSTRUCTOR
#define TARGET_ASM_CONSTRUCTOR pa_asm_out_constructor
#undef TARGET_ASM_DESTRUCTOR
#define TARGET_ASM_DESTRUCTOR pa_asm_out_destructor
#endif

#undef TARGET_INIT_BUILTINS
#define TARGET_INIT_BUILTINS pa_init_builtins

#undef TARGET_EXPAND_BUILTIN
#define TARGET_EXPAND_BUILTIN pa_expand_builtin

#undef TARGET_REGISTER_MOVE_COST
#define TARGET_REGISTER_MOVE_COST hppa_register_move_cost
#undef TARGET_RTX_COSTS
#define TARGET_RTX_COSTS hppa_rtx_costs
#undef TARGET_ADDRESS_COST
#define TARGET_ADDRESS_COST hppa_address_cost

#undef TARGET_MACHINE_DEPENDENT_REORG
#define TARGET_MACHINE_DEPENDENT_REORG pa_reorg

#undef TARGET_INIT_LIBFUNCS
#define TARGET_INIT_LIBFUNCS pa_init_libfuncs

#undef TARGET_PROMOTE_FUNCTION_MODE
#define TARGET_PROMOTE_FUNCTION_MODE pa_promote_function_mode
#undef TARGET_PROMOTE_PROTOTYPES
#define TARGET_PROMOTE_PROTOTYPES hook_bool_const_tree_true

#undef TARGET_STRUCT_VALUE_RTX
#define TARGET_STRUCT_VALUE_RTX pa_struct_value_rtx
#undef TARGET_RETURN_IN_MEMORY
#define TARGET_RETURN_IN_MEMORY pa_return_in_memory
#undef TARGET_MUST_PASS_IN_STACK
#define TARGET_MUST_PASS_IN_STACK must_pass_in_stack_var_size
#undef TARGET_PASS_BY_REFERENCE
#define TARGET_PASS_BY_REFERENCE pa_pass_by_reference
#undef TARGET_CALLEE_COPIES
#define TARGET_CALLEE_COPIES pa_callee_copies
#undef TARGET_ARG_PARTIAL_BYTES
#define TARGET_ARG_PARTIAL_BYTES pa_arg_partial_bytes
#undef TARGET_FUNCTION_ARG
#define TARGET_FUNCTION_ARG pa_function_arg
#undef TARGET_FUNCTION_ARG_ADVANCE
#define TARGET_FUNCTION_ARG_ADVANCE pa_function_arg_advance
#undef TARGET_FUNCTION_ARG_PADDING
#define TARGET_FUNCTION_ARG_PADDING pa_function_arg_padding
#undef TARGET_FUNCTION_ARG_BOUNDARY
#define TARGET_FUNCTION_ARG_BOUNDARY pa_function_arg_boundary

#undef TARGET_EXPAND_BUILTIN_SAVEREGS
#define TARGET_EXPAND_BUILTIN_SAVEREGS hppa_builtin_saveregs
#undef TARGET_EXPAND_BUILTIN_VA_START
#define TARGET_EXPAND_BUILTIN_VA_START hppa_va_start
#undef TARGET_GIMPLIFY_VA_ARG_EXPR
#define TARGET_GIMPLIFY_VA_ARG_EXPR hppa_gimplify_va_arg_expr

#undef TARGET_SCALAR_MODE_SUPPORTED_P
#define TARGET_SCALAR_MODE_SUPPORTED_P pa_scalar_mode_supported_p

#undef TARGET_CANNOT_FORCE_CONST_MEM
#define TARGET_CANNOT_FORCE_CONST_MEM pa_cannot_force_const_mem

#undef TARGET_SECONDARY_RELOAD
#define TARGET_SECONDARY_RELOAD pa_secondary_reload
#undef TARGET_SECONDARY_MEMORY_NEEDED
#define TARGET_SECONDARY_MEMORY_NEEDED pa_secondary_memory_needed

#undef TARGET_EXTRA_LIVE_ON_ENTRY
#define TARGET_EXTRA_LIVE_ON_ENTRY pa_extra_live_on_entry

#undef TARGET_ASM_TRAMPOLINE_TEMPLATE
#define TARGET_ASM_TRAMPOLINE_TEMPLATE pa_asm_trampoline_template
#undef TARGET_TRAMPOLINE_INIT
#define TARGET_TRAMPOLINE_INIT pa_trampoline_init
#undef TARGET_TRAMPOLINE_ADJUST_ADDRESS
#define TARGET_TRAMPOLINE_ADJUST_ADDRESS pa_trampoline_adjust_address
#undef TARGET_DELEGITIMIZE_ADDRESS
#define TARGET_DELEGITIMIZE_ADDRESS pa_delegitimize_address
#undef TARGET_INTERNAL_ARG_POINTER
#define TARGET_INTERNAL_ARG_POINTER pa_internal_arg_pointer
#undef TARGET_CAN_ELIMINATE
#define TARGET_CAN_ELIMINATE pa_can_eliminate
#undef TARGET_CONDITIONAL_REGISTER_USAGE
#define TARGET_CONDITIONAL_REGISTER_USAGE pa_conditional_register_usage
#undef TARGET_C_MODE_FOR_SUFFIX
#define TARGET_C_MODE_FOR_SUFFIX pa_c_mode_for_suffix
#undef TARGET_ASM_FUNCTION_SECTION
#define TARGET_ASM_FUNCTION_SECTION pa_function_section

#undef TARGET_LEGITIMATE_CONSTANT_P
#define TARGET_LEGITIMATE_CONSTANT_P pa_legitimate_constant_p
#undef TARGET_SECTION_TYPE_FLAGS
#define TARGET_SECTION_TYPE_FLAGS pa_section_type_flags
#undef TARGET_LEGITIMATE_ADDRESS_P
#define TARGET_LEGITIMATE_ADDRESS_P pa_legitimate_address_p

#undef TARGET_LRA_P
#define TARGET_LRA_P hook_bool_void_false

#undef TARGET_HARD_REGNO_NREGS
#define TARGET_HARD_REGNO_NREGS pa_hard_regno_nregs
#undef TARGET_HARD_REGNO_MODE_OK
#define TARGET_HARD_REGNO_MODE_OK pa_hard_regno_mode_ok
#undef TARGET_MODES_TIEABLE_P
#define TARGET_MODES_TIEABLE_P pa_modes_tieable_p

#undef TARGET_CAN_CHANGE_MODE_CLASS
#define TARGET_CAN_CHANGE_MODE_CLASS pa_can_change_mode_class

#undef TARGET_CONSTANT_ALIGNMENT
#define TARGET_CONSTANT_ALIGNMENT constant_alignment_word_strings

#undef TARGET_STARTING_FRAME_OFFSET
#define TARGET_STARTING_FRAME_OFFSET pa_starting_frame_offset

#undef TARGET_HAVE_SPECULATION_SAFE_VALUE
#define TARGET_HAVE_SPECULATION_SAFE_VALUE speculation_safe_value_not_needed

struct gcc_target targetm = TARGET_INITIALIZER;

/* Parse the -mfixed-range= option string.  */

static void
fix_range (const char *const_str)
{
  int i, first, last;
  char *str, *dash, *comma;

  /* str must be of the form REG1'-'REG2{,REG1'-'REG} where REG1 and
     REG2 are either register names or register numbers.  The effect
     of this option is to mark the registers in the range from REG1 to
     REG2 as ``fixed'' so they won't be used by the compiler.  This is
     used, e.g., to ensure that kernel mode code doesn't use fr4-fr31.  */

  i = strlen (const_str);
  str = (char *) alloca (i + 1);
  memcpy (str, const_str, i + 1);

  while (1)
    {
      dash = strchr (str, '-');
      if (!dash)
	{
	  warning (0, "value of %<-mfixed-range%> must have form REG1-REG2");
	  return;
	}
      *dash = '\0';

      comma = strchr (dash + 1, ',');
      if (comma)
	*comma = '\0';

      first = decode_reg_name (str);
      if (first < 0)
	{
	  warning (0, "unknown register name: %s", str);
	  return;
	}

      last = decode_reg_name (dash + 1);
      if (last < 0)
	{
	  warning (0, "unknown register name: %s", dash + 1);
	  return;
	}

      *dash = '-';

      if (first > last)
	{
	  warning (0, "%s-%s is an empty range", str, dash + 1);
	  return;
	}

      for (i = first; i <= last; ++i)
	fixed_regs[i] = call_used_regs[i] = 1;

      if (!comma)
	break;

      *comma = ',';
      str = comma + 1;
    }

  /* Check if all floating point registers have been fixed.  */
  for (i = FP_REG_FIRST; i <= FP_REG_LAST; i++)
    if (!fixed_regs[i])
      break;

  if (i > FP_REG_LAST)
    target_flags |= MASK_DISABLE_FPREGS;
}

/* Implement the TARGET_OPTION_OVERRIDE hook.  */

static void
pa_option_override (void)
{
  unsigned int i;
  cl_deferred_option *opt;
  vec<cl_deferred_option> *v
    = (vec<cl_deferred_option> *) pa_deferred_options;

  if (v)
    FOR_EACH_VEC_ELT (*v, i, opt)
      {
	switch (opt->opt_index)
	  {
	  case OPT_mfixed_range_:
	    fix_range (opt->arg);
	    break;

	  default:
	    gcc_unreachable ();
	  }
      }

  if (flag_pic && TARGET_PORTABLE_RUNTIME)
    {
      warning (0, "PIC code generation is not supported in the portable runtime model");
    }

  if (flag_pic && TARGET_FAST_INDIRECT_CALLS)
   {
      warning (0, "PIC code generation is not compatible with fast indirect calls");
   }

  if (! TARGET_GAS && write_symbols != NO_DEBUG)
    {
      warning (0, "%<-g%> is only supported when using GAS on this processor");
      warning (0, "%<-g%> option disabled");
      write_symbols = NO_DEBUG;
    }

  if (TARGET_64BIT && TARGET_HPUX)
    {
      /* DWARF5 is not supported by gdb.  Don't emit DWARF5 unless
	 specifically selected.  */
      if (!OPTION_SET_P (dwarf_strict))
	dwarf_strict = 1;
      if (!OPTION_SET_P (dwarf_version))
	dwarf_version = 4;
    }

  /* We only support the "big PIC" model now.  And we always generate PIC
     code when in 64bit mode.  */
  if (flag_pic == 1 || TARGET_64BIT)
    flag_pic = 2;

  /* Disable -freorder-blocks-and-partition as we don't support hot and
     cold partitioning.  */
  if (flag_reorder_blocks_and_partition)
    {
      inform (input_location,
	      "%<-freorder-blocks-and-partition%> does not work "
	      "on this architecture");
      flag_reorder_blocks_and_partition = 0;
      flag_reorder_blocks = 1;
    }

  /* We can't guarantee that .dword is available for 32-bit targets.  */
  if (UNITS_PER_WORD == 4)
    targetm.asm_out.aligned_op.di = NULL;

  /* The unaligned ops are only available when using GAS.  */
  if (!TARGET_GAS)
    {
      targetm.asm_out.unaligned_op.hi = NULL;
      targetm.asm_out.unaligned_op.si = NULL;
      targetm.asm_out.unaligned_op.di = NULL;
    }

  init_machine_status = pa_init_machine_status;
}

enum pa_builtins
{
  PA_BUILTIN_COPYSIGNQ,
  PA_BUILTIN_FABSQ,
  PA_BUILTIN_INFQ,
  PA_BUILTIN_HUGE_VALQ,
  PA_BUILTIN_max
};

static GTY(()) tree pa_builtins[(int) PA_BUILTIN_max];

static void
pa_init_builtins (void)
{
#ifdef DONT_HAVE_FPUTC_UNLOCKED
  {
    tree decl = builtin_decl_explicit (BUILT_IN_PUTC_UNLOCKED);
    set_builtin_decl (BUILT_IN_FPUTC_UNLOCKED, decl,
		      builtin_decl_implicit_p (BUILT_IN_PUTC_UNLOCKED));
  }
#endif
#if TARGET_HPUX_11
  {
    tree decl;

    if ((decl = builtin_decl_explicit (BUILT_IN_FINITE)) != NULL_TREE)
      set_user_assembler_name (decl, "_Isfinite");
    if ((decl = builtin_decl_explicit (BUILT_IN_FINITEF)) != NULL_TREE)
      set_user_assembler_name (decl, "_Isfinitef");
  }
#endif

  if (HPUX_LONG_DOUBLE_LIBRARY)
    {
      tree decl, ftype;

      /* Under HPUX, the __float128 type is a synonym for "long double".  */
      (*lang_hooks.types.register_builtin_type) (long_double_type_node,
						 "__float128");

      /* TFmode support builtins.  */
      ftype = build_function_type_list (long_double_type_node,
					long_double_type_node,
					NULL_TREE);
      decl = add_builtin_function ("__builtin_fabsq", ftype,
				   PA_BUILTIN_FABSQ, BUILT_IN_MD,
				   "_U_Qfabs", NULL_TREE);
      TREE_READONLY (decl) = 1;
      pa_builtins[PA_BUILTIN_FABSQ] = decl;

      ftype = build_function_type_list (long_double_type_node,
					long_double_type_node,
					long_double_type_node,
					NULL_TREE);
      decl = add_builtin_function ("__builtin_copysignq", ftype,
				   PA_BUILTIN_COPYSIGNQ, BUILT_IN_MD,
				   "_U_Qfcopysign", NULL_TREE);
      TREE_READONLY (decl) = 1;
      pa_builtins[PA_BUILTIN_COPYSIGNQ] = decl;

      ftype = build_function_type_list (long_double_type_node, NULL_TREE);
      decl = add_builtin_function ("__builtin_infq", ftype,
				   PA_BUILTIN_INFQ, BUILT_IN_MD,
				   NULL, NULL_TREE);
      pa_builtins[PA_BUILTIN_INFQ] = decl;

      decl = add_builtin_function ("__builtin_huge_valq", ftype,
                                   PA_BUILTIN_HUGE_VALQ, BUILT_IN_MD,
                                   NULL, NULL_TREE);
      pa_builtins[PA_BUILTIN_HUGE_VALQ] = decl;
    }
}

static rtx
pa_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
		   machine_mode mode ATTRIBUTE_UNUSED,
		   int ignore ATTRIBUTE_UNUSED)
{
  tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
  unsigned int fcode = DECL_MD_FUNCTION_CODE (fndecl);

  switch (fcode)
    {
    case PA_BUILTIN_FABSQ:
    case PA_BUILTIN_COPYSIGNQ:
      return expand_call (exp, target, ignore);

    case PA_BUILTIN_INFQ:
    case PA_BUILTIN_HUGE_VALQ:
      {
	machine_mode target_mode = TYPE_MODE (TREE_TYPE (exp));
	REAL_VALUE_TYPE inf;
	rtx tmp;

	real_inf (&inf);
	tmp = const_double_from_real_value (inf, target_mode);

	tmp = validize_mem (force_const_mem (target_mode, tmp));

	if (target == 0)
	  target = gen_reg_rtx (target_mode);

	emit_move_insn (target, tmp);
	return target;
      }

    default:
      gcc_unreachable ();
    }

  return NULL_RTX;
}

/* Function to init struct machine_function.
   This will be called, via a pointer variable,
   from push_function_context.  */

static struct machine_function *
pa_init_machine_status (void)
{
  return ggc_cleared_alloc<machine_function> ();
}

/* If FROM is a probable pointer register, mark TO as a probable
   pointer register with the same pointer alignment as FROM.  */

static void
copy_reg_pointer (rtx to, rtx from)
{
  if (REG_POINTER (from))
    mark_reg_pointer (to, REGNO_POINTER_ALIGN (REGNO (from)));
}

/* Return 1 if X contains a symbolic expression.  We know these
   expressions will have one of a few well defined forms, so
   we need only check those forms.  */
int
pa_symbolic_expression_p (rtx x)
{

  /* Strip off any HIGH.  */
  if (GET_CODE (x) == HIGH)
    x = XEXP (x, 0);

  return symbolic_operand (x, VOIDmode);
}

/* Accept any constant that can be moved in one instruction into a
   general register.  */
int
pa_cint_ok_for_move (unsigned HOST_WIDE_INT ival)
{
  /* OK if ldo, ldil, or zdepi, can be used.  */
  return (VAL_14_BITS_P (ival)
	  || pa_ldil_cint_p (ival)
	  || pa_zdepi_cint_p (ival));
}

/* True iff ldil can be used to load this CONST_INT.  The least
   significant 11 bits of the value must be zero and the value must
   not change sign when extended from 32 to 64 bits.  */
int
pa_ldil_cint_p (unsigned HOST_WIDE_INT ival)
{
  unsigned HOST_WIDE_INT x;

  x = ival & (((unsigned HOST_WIDE_INT) -1 << 31) | 0x7ff);
  return x == 0 || x == ((unsigned HOST_WIDE_INT) -1 << 31);
}

/* True iff zdepi can be used to generate this CONST_INT.
   zdepi first sign extends a 5-bit signed number to a given field
   length, then places this field anywhere in a zero.  */
int
pa_zdepi_cint_p (unsigned HOST_WIDE_INT x)
{
  unsigned HOST_WIDE_INT lsb_mask, t;

  /* This might not be obvious, but it's at least fast.
     This function is critical; we don't have the time loops would take.  */
  lsb_mask = x & -x;
  t = ((x >> 4) + lsb_mask) & ~(lsb_mask - 1);
  /* Return true iff t is a power of two.  */
  return ((t & (t - 1)) == 0);
}

/* True iff depi or extru can be used to compute (reg & mask).
   Accept bit pattern like these:
   0....01....1
   1....10....0
   1..10..01..1  */
int
pa_and_mask_p (unsigned HOST_WIDE_INT mask)
{
  mask = ~mask;
  mask += mask & -mask;
  return (mask & (mask - 1)) == 0;
}

/* True iff depi can be used to compute (reg | MASK).  */
int
pa_ior_mask_p (unsigned HOST_WIDE_INT mask)
{
  mask += mask & -mask;
  return (mask & (mask - 1)) == 0;
}

/* Legitimize PIC addresses.  If the address is already
   position-independent, we return ORIG.  Newly generated
   position-independent addresses go to REG.  If we need more
   than one register, we lose.  */

static rtx
legitimize_pic_address (rtx orig, machine_mode mode, rtx reg)
{
  rtx pic_ref = orig;

  gcc_assert (!PA_SYMBOL_REF_TLS_P (orig));

  /* Labels need special handling.  */
  if (pic_label_operand (orig, mode))
    {
      rtx_insn *insn;

      /* We do not want to go through the movXX expanders here since that
	 would create recursion.

	 Nor do we really want to call a generator for a named pattern
	 since that requires multiple patterns if we want to support
	 multiple word sizes.

	 So instead we just emit the raw set, which avoids the movXX
	 expanders completely.  */
      mark_reg_pointer (reg, BITS_PER_UNIT);
      insn = emit_insn (gen_rtx_SET (reg, orig));

      /* Put a REG_EQUAL note on this insn, so that it can be optimized.  */
      add_reg_note (insn, REG_EQUAL, orig);

      /* During and after reload, we need to generate a REG_LABEL_OPERAND note
	 and update LABEL_NUSES because this is not done automatically.  */
      if (reload_in_progress || reload_completed)
	{
	  /* Extract LABEL_REF.  */
	  if (GET_CODE (orig) == CONST)
	    orig = XEXP (XEXP (orig, 0), 0);
	  /* Extract CODE_LABEL.  */
	  orig = XEXP (orig, 0);
	  add_reg_note (insn, REG_LABEL_OPERAND, orig);
	  /* Make sure we have label and not a note.  */
	  if (LABEL_P (orig))
	    LABEL_NUSES (orig)++;
	}
      crtl->uses_pic_offset_table = 1;
      return reg;
    }
  if (GET_CODE (orig) == SYMBOL_REF)
    {
      rtx_insn *insn;
      rtx tmp_reg;

      gcc_assert (reg);

      /* Before reload, allocate a temporary register for the intermediate
	 result.  This allows the sequence to be deleted when the final
	 result is unused and the insns are trivially dead.  */
      tmp_reg = ((reload_in_progress || reload_completed)
		 ? reg : gen_reg_rtx (Pmode));

      if (function_label_operand (orig, VOIDmode))
	{
	  /* Force function label into memory in word mode.  */
	  orig = XEXP (force_const_mem (word_mode, orig), 0);
	  /* Load plabel address from DLT.  */
	  emit_move_insn (tmp_reg,
			  gen_rtx_PLUS (word_mode, pic_offset_table_rtx,
					gen_rtx_HIGH (word_mode, orig)));
	  pic_ref
	    = gen_const_mem (Pmode,
			     gen_rtx_LO_SUM (Pmode, tmp_reg,
					     gen_rtx_UNSPEC (Pmode,
						         gen_rtvec (1, orig),
						         UNSPEC_DLTIND14R)));
	  emit_move_insn (reg, pic_ref);
	  /* Now load address of function descriptor.  */
	  pic_ref = gen_rtx_MEM (Pmode, reg);
	}
      else
	{
	  /* Load symbol reference from DLT.  */
	  emit_move_insn (tmp_reg,
			  gen_rtx_PLUS (word_mode, pic_offset_table_rtx,
					gen_rtx_HIGH (word_mode, orig)));
	  pic_ref
	    = gen_const_mem (Pmode,
			     gen_rtx_LO_SUM (Pmode, tmp_reg,
					     gen_rtx_UNSPEC (Pmode,
						         gen_rtvec (1, orig),
						         UNSPEC_DLTIND14R)));
	}

      crtl->uses_pic_offset_table = 1;
      mark_reg_pointer (reg, BITS_PER_UNIT);
      insn = emit_move_insn (reg, pic_ref);

      /* Put a REG_EQUAL note on this insn, so that it can be optimized.  */
      set_unique_reg_note (insn, REG_EQUAL, orig);

      return reg;
    }
  else if (GET_CODE (orig) == CONST)
    {
      rtx base;

      if (GET_CODE (XEXP (orig, 0)) == PLUS
	  && XEXP (XEXP (orig, 0), 0) == pic_offset_table_rtx)
	return orig;

      gcc_assert (reg);
      gcc_assert (GET_CODE (XEXP (orig, 0)) == PLUS);
      
      base = legitimize_pic_address (XEXP (XEXP (orig, 0), 0), Pmode, reg);
      orig = legitimize_pic_address (XEXP (XEXP (orig, 0), 1), Pmode,
				     base == reg ? 0 : reg);

      if (GET_CODE (orig) == CONST_INT)
	{
	  if (INT_14_BITS (orig))
	    return plus_constant (Pmode, base, INTVAL (orig));
	  orig = force_reg (Pmode, orig);
	}
      pic_ref = gen_rtx_PLUS (Pmode, base, orig);
      /* Likewise, should we set special REG_NOTEs here?  */
    }

  return pic_ref;
}

static GTY(()) rtx gen_tls_tga;

static rtx
gen_tls_get_addr (void)
{
  if (!gen_tls_tga)
    gen_tls_tga = init_one_libfunc ("__tls_get_addr");
  return gen_tls_tga;
}

static rtx
hppa_tls_call (rtx arg)
{
  rtx ret;

  ret = gen_reg_rtx (Pmode);
  emit_library_call_value (gen_tls_get_addr (), ret,
			   LCT_CONST, Pmode, arg, Pmode);

  return ret;
}

static rtx
legitimize_tls_address (rtx addr)
{
  rtx ret, tmp, t1, t2, tp;
  rtx_insn *insn;

  /* Currently, we can't handle anything but a SYMBOL_REF.  */
  if (GET_CODE (addr) != SYMBOL_REF)
    return addr;

  switch (SYMBOL_REF_TLS_MODEL (addr)) 
    {
      case TLS_MODEL_GLOBAL_DYNAMIC:
	tmp = gen_reg_rtx (Pmode);
	if (flag_pic)
	  emit_insn (gen_tgd_load_pic (tmp, addr));
	else
	  emit_insn (gen_tgd_load (tmp, addr));
	ret = hppa_tls_call (tmp);
	break;

      case TLS_MODEL_LOCAL_DYNAMIC:
	ret = gen_reg_rtx (Pmode);
	tmp = gen_reg_rtx (Pmode);
	start_sequence ();
	if (flag_pic)
	  emit_insn (gen_tld_load_pic (tmp, addr));
	else
	  emit_insn (gen_tld_load (tmp, addr));
	t1 = hppa_tls_call (tmp);
	insn = get_insns ();
	end_sequence ();
	t2 = gen_reg_rtx (Pmode);
	emit_libcall_block (insn, t2, t1, 
			    gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
				            UNSPEC_TLSLDBASE));
	emit_insn (gen_tld_offset_load (ret, addr, t2));
	break;

      case TLS_MODEL_INITIAL_EXEC:
	tp = gen_reg_rtx (Pmode);
	tmp = gen_reg_rtx (Pmode);
	ret = gen_reg_rtx (Pmode);
	emit_insn (gen_tp_load (tp));
	if (flag_pic)
	  emit_insn (gen_tie_load_pic (tmp, addr));
	else
	  emit_insn (gen_tie_load (tmp, addr));
	emit_move_insn (ret, gen_rtx_PLUS (Pmode, tp, tmp));
	break;

      case TLS_MODEL_LOCAL_EXEC:
	tp = gen_reg_rtx (Pmode);
	ret = gen_reg_rtx (Pmode);
	emit_insn (gen_tp_load (tp));
	emit_insn (gen_tle_load (ret, addr, tp));
	break;

      default:
	gcc_unreachable ();
    }

  return ret;
}

/* Helper for hppa_legitimize_address.  Given X, return true if it
   is a left shift by 1, 2 or 3 positions or a multiply by 2, 4 or 8.

   This respectively represent canonical shift-add rtxs or scaled
   memory addresses.  */
static bool
mem_shadd_or_shadd_rtx_p (rtx x)
{
  return ((GET_CODE (x) == ASHIFT
	   || GET_CODE (x) == MULT)
	  && GET_CODE (XEXP (x, 1)) == CONST_INT
	  && ((GET_CODE (x) == ASHIFT
	       && pa_shadd_constant_p (INTVAL (XEXP (x, 1))))
	      || (GET_CODE (x) == MULT
		  && pa_mem_shadd_constant_p (INTVAL (XEXP (x, 1))))));
}

/* Try machine-dependent ways of modifying an illegitimate address
   to be legitimate.  If we find one, return the new, valid address.
   This macro is used in only one place: `memory_address' in explow.c.

   OLDX is the address as it was before break_out_memory_refs was called.
   In some cases it is useful to look at this to decide what needs to be done.

   It is always safe for this macro to do nothing.  It exists to recognize
   opportunities to optimize the output.

   For the PA, transform:

	memory(X + <large int>)

   into:

	if (<large int> & mask) >= 16
	  Y = (<large int> & ~mask) + mask + 1	Round up.
	else
	  Y = (<large int> & ~mask)		Round down.
	Z = X + Y
	memory (Z + (<large int> - Y));

   This is for CSE to find several similar references, and only use one Z.

   X can either be a SYMBOL_REF or REG, but because combine cannot
   perform a 4->2 combination we do nothing for SYMBOL_REF + D where
   D will not fit in 14 bits.

   MODE_FLOAT references allow displacements which fit in 5 bits, so use
   0x1f as the mask.

   MODE_INT references allow displacements which fit in 14 bits, so use
   0x3fff as the mask.

   This relies on the fact that most mode MODE_FLOAT references will use FP
   registers and most mode MODE_INT references will use integer registers.
   (In the rare case of an FP register used in an integer MODE, we depend
   on secondary reloads to clean things up.)


   It is also beneficial to handle (plus (mult (X) (Y)) (Z)) in a special
   manner if Y is 2, 4, or 8.  (allows more shadd insns and shifted indexed
   addressing modes to be used).

   Note that the addresses passed into hppa_legitimize_address always
   come from a MEM, so we only have to match the MULT form on incoming
   addresses.  But to be future proof we also match the ASHIFT form.

   However, this routine always places those shift-add sequences into
   registers, so we have to generate the ASHIFT form as our output.

   Put X and Z into registers.  Then put the entire expression into
   a register.  */

rtx
hppa_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
			 machine_mode mode)
{
  rtx orig = x;

  /* We need to canonicalize the order of operands in unscaled indexed
     addresses since the code that checks if an address is valid doesn't
     always try both orders.  */
  if (!TARGET_NO_SPACE_REGS
      && GET_CODE (x) == PLUS
      && GET_MODE (x) == Pmode
      && REG_P (XEXP (x, 0))
      && REG_P (XEXP (x, 1))
      && REG_POINTER (XEXP (x, 0))
      && !REG_POINTER (XEXP (x, 1)))
    return gen_rtx_PLUS (Pmode, XEXP (x, 1), XEXP (x, 0));

  if (tls_referenced_p (x))
    return legitimize_tls_address (x);
  else if (flag_pic)
    return legitimize_pic_address (x, mode, gen_reg_rtx (Pmode));

  /* Strip off CONST.  */
  if (GET_CODE (x) == CONST)
    x = XEXP (x, 0);

  /* Special case.  Get the SYMBOL_REF into a register and use indexing.
     That should always be safe.  */
  if (GET_CODE (x) == PLUS
      && GET_CODE (XEXP (x, 0)) == REG
      && GET_CODE (XEXP (x, 1)) == SYMBOL_REF)
    {
      rtx reg = force_reg (Pmode, XEXP (x, 1));
      return force_reg (Pmode, gen_rtx_PLUS (Pmode, reg, XEXP (x, 0)));
    }

  /* Note we must reject symbols which represent function addresses
     since the assembler/linker can't handle arithmetic on plabels.  */
  if (GET_CODE (x) == PLUS
      && GET_CODE (XEXP (x, 1)) == CONST_INT
      && ((GET_CODE (XEXP (x, 0)) == SYMBOL_REF
	   && !FUNCTION_NAME_P (XSTR (XEXP (x, 0), 0)))
	  || GET_CODE (XEXP (x, 0)) == REG))
    {
      rtx int_part, ptr_reg;
      int newoffset;
      int offset = INTVAL (XEXP (x, 1));
      int mask;

      mask = (GET_MODE_CLASS (mode) == MODE_FLOAT
	      && !INT14_OK_STRICT ? 0x1f : 0x3fff);

      /* Choose which way to round the offset.  Round up if we
	 are >= halfway to the next boundary.  */
      if ((offset & mask) >= ((mask + 1) / 2))
	newoffset = (offset & ~ mask) + mask + 1;
      else
	newoffset = (offset & ~ mask);

      /* If the newoffset will not fit in 14 bits (ldo), then
	 handling this would take 4 or 5 instructions (2 to load
	 the SYMBOL_REF + 1 or 2 to load the newoffset + 1 to
	 add the new offset and the SYMBOL_REF.)  Combine cannot
	 handle 4->2 or 5->2 combinations, so do not create
	 them.  */
      if (! VAL_14_BITS_P (newoffset)
	  && GET_CODE (XEXP (x, 0)) == SYMBOL_REF)
	{
	  rtx const_part = plus_constant (Pmode, XEXP (x, 0), newoffset);
	  rtx tmp_reg
	    = force_reg (Pmode,
			 gen_rtx_HIGH (Pmode, const_part));
	  ptr_reg
	    = force_reg (Pmode,
			 gen_rtx_LO_SUM (Pmode,
					 tmp_reg, const_part));
	}
      else
	{
	  if (! VAL_14_BITS_P (newoffset))
	    int_part = force_reg (Pmode, GEN_INT (newoffset));
	  else
	    int_part = GEN_INT (newoffset);

	  ptr_reg = force_reg (Pmode,
			       gen_rtx_PLUS (Pmode,
					     force_reg (Pmode, XEXP (x, 0)),
					     int_part));
	}
      return plus_constant (Pmode, ptr_reg, offset - newoffset);
    }

  /* Handle (plus (mult (a) (mem_shadd_constant)) (b)).  */

  if (GET_CODE (x) == PLUS
      && mem_shadd_or_shadd_rtx_p (XEXP (x, 0))
      && (OBJECT_P (XEXP (x, 1))
	  || GET_CODE (XEXP (x, 1)) == SUBREG)
      && GET_CODE (XEXP (x, 1)) != CONST)
    {
      /* If we were given a MULT, we must fix the constant
	 as we're going to create the ASHIFT form.  */
      int shift_val = INTVAL (XEXP (XEXP (x, 0), 1));
      if (GET_CODE (XEXP (x, 0)) == MULT)
	shift_val = exact_log2 (shift_val);

      rtx reg1, reg2;
      reg1 = XEXP (x, 1);
      if (GET_CODE (reg1) != REG)
	reg1 = force_reg (Pmode, force_operand (reg1, 0));

      reg2 = XEXP (XEXP (x, 0), 0);
      if (GET_CODE (reg2) != REG)
        reg2 = force_reg (Pmode, force_operand (reg2, 0));

      return force_reg (Pmode,
			gen_rtx_PLUS (Pmode,
				      gen_rtx_ASHIFT (Pmode, reg2,
						      GEN_INT (shift_val)),
				      reg1));
    }

  /* Similarly for (plus (plus (mult (a) (mem_shadd_constant)) (b)) (c)).

     Only do so for floating point modes since this is more speculative
     and we lose if it's an integer store.  */
  if (GET_CODE (x) == PLUS
      && GET_CODE (XEXP (x, 0)) == PLUS
      && mem_shadd_or_shadd_rtx_p (XEXP (XEXP (x, 0), 0))
      && (mode == SFmode || mode == DFmode))
    {
      int shift_val = INTVAL (XEXP (XEXP (XEXP (x, 0), 0), 1));

      /* If we were given a MULT, we must fix the constant
	 as we're going to create the ASHIFT form.  */
      if (GET_CODE (XEXP (XEXP (x, 0), 0)) == MULT)
	shift_val = exact_log2 (shift_val);

      /* Try and figure out what to use as a base register.  */
      rtx reg1, reg2, base, idx;

      reg1 = XEXP (XEXP (x, 0), 1);
      reg2 = XEXP (x, 1);
      base = NULL_RTX;
      idx = NULL_RTX;

      /* Make sure they're both regs.  If one was a SYMBOL_REF [+ const],
	 then pa_emit_move_sequence will turn on REG_POINTER so we'll know
	 it's a base register below.  */
      if (GET_CODE (reg1) != REG)
	reg1 = force_reg (Pmode, force_operand (reg1, 0));

      if (GET_CODE (reg2) != REG)
	reg2 = force_reg (Pmode, force_operand (reg2, 0));

      /* Figure out what the base and index are.  */

      if (GET_CODE (reg1) == REG
	  && REG_POINTER (reg1))
	{
	  base = reg1;
	  idx = gen_rtx_PLUS (Pmode,
			      gen_rtx_ASHIFT (Pmode,
					      XEXP (XEXP (XEXP (x, 0), 0), 0),
					      GEN_INT (shift_val)),
			      XEXP (x, 1));
	}
      else if (GET_CODE (reg2) == REG
	       && REG_POINTER (reg2))
	{
	  base = reg2;
	  idx = XEXP (x, 0);
	}

      if (base == 0)
	return orig;

      /* If the index adds a large constant, try to scale the
	 constant so that it can be loaded with only one insn.  */
      if (GET_CODE (XEXP (idx, 1)) == CONST_INT
	  && VAL_14_BITS_P (INTVAL (XEXP (idx, 1))
			    / INTVAL (XEXP (XEXP (idx, 0), 1)))
	  && INTVAL (XEXP (idx, 1)) % INTVAL (XEXP (XEXP (idx, 0), 1)) == 0)
	{
	  /* Divide the CONST_INT by the scale factor, then add it to A.  */
	  int val = INTVAL (XEXP (idx, 1));
	  val /= (1 << shift_val);

	  reg1 = XEXP (XEXP (idx, 0), 0);
	  if (GET_CODE (reg1) != REG)
	    reg1 = force_reg (Pmode, force_operand (reg1, 0));

	  reg1 = force_reg (Pmode, gen_rtx_PLUS (Pmode, reg1, GEN_INT (val)));

	  /* We can now generate a simple scaled indexed address.  */
	  return
	    force_reg
	      (Pmode, gen_rtx_PLUS (Pmode,
				    gen_rtx_ASHIFT (Pmode, reg1,
						    GEN_INT (shift_val)),
				    base));
	}

      /* If B + C is still a valid base register, then add them.  */
      if (GET_CODE (XEXP (idx, 1)) == CONST_INT
	  && INTVAL (XEXP (idx, 1)) <= 4096
	  && INTVAL (XEXP (idx, 1)) >= -4096)
	{
	  rtx reg1, reg2;

	  reg1 = force_reg (Pmode, gen_rtx_PLUS (Pmode, base, XEXP (idx, 1)));

	  reg2 = XEXP (XEXP (idx, 0), 0);
	  if (GET_CODE (reg2) != CONST_INT)
	    reg2 = force_reg (Pmode, force_operand (reg2, 0));

	  return force_reg (Pmode,
			    gen_rtx_PLUS (Pmode,
					  gen_rtx_ASHIFT (Pmode, reg2,
							  GEN_INT (shift_val)),
					  reg1));
	}

      /* Get the index into a register, then add the base + index and
	 return a register holding the result.  */

      /* First get A into a register.  */
      reg1 = XEXP (XEXP (idx, 0), 0);
      if (GET_CODE (reg1) != REG)
	reg1 = force_reg (Pmode, force_operand (reg1, 0));

      /* And get B into a register.  */
      reg2 = XEXP (idx, 1);
      if (GET_CODE (reg2) != REG)
	reg2 = force_reg (Pmode, force_operand (reg2, 0));

      reg1 = force_reg (Pmode,
			gen_rtx_PLUS (Pmode,
				      gen_rtx_ASHIFT (Pmode, reg1,
						      GEN_INT (shift_val)),
				      reg2));

      /* Add the result to our base register and return.  */
      return force_reg (Pmode, gen_rtx_PLUS (Pmode, base, reg1));

    }

  /* Uh-oh.  We might have an address for x[n-100000].  This needs
     special handling to avoid creating an indexed memory address
     with x-100000 as the base.

     If the constant part is small enough, then it's still safe because
     there is a guard page at the beginning and end of the data segment.

     Scaled references are common enough that we want to try and rearrange the
     terms so that we can use indexing for these addresses too.  Only
     do the optimization for floatint point modes.  */

  if (GET_CODE (x) == PLUS
      && pa_symbolic_expression_p (XEXP (x, 1)))
    {
      /* Ugly.  We modify things here so that the address offset specified
	 by the index expression is computed first, then added to x to form
	 the entire address.  */

      rtx regx1, regx2, regy1, regy2, y;

      /* Strip off any CONST.  */
      y = XEXP (x, 1);
      if (GET_CODE (y) == CONST)
	y = XEXP (y, 0);

      if (GET_CODE (y) == PLUS || GET_CODE (y) == MINUS)
	{
	  /* See if this looks like
		(plus (mult (reg) (mem_shadd_const))
		      (const (plus (symbol_ref) (const_int))))

	     Where const_int is small.  In that case the const
	     expression is a valid pointer for indexing.

	     If const_int is big, but can be divided evenly by shadd_const
	     and added to (reg).  This allows more scaled indexed addresses.  */
	  if (GET_CODE (XEXP (y, 0)) == SYMBOL_REF
	      && mem_shadd_or_shadd_rtx_p (XEXP (x, 0))
	      && GET_CODE (XEXP (y, 1)) == CONST_INT
	      && INTVAL (XEXP (y, 1)) >= -4096
	      && INTVAL (XEXP (y, 1)) <= 4095)
	    {
	      int shift_val = INTVAL (XEXP (XEXP (x, 0), 1));

	      /* If we were given a MULT, we must fix the constant
		 as we're going to create the ASHIFT form.  */
	      if (GET_CODE (XEXP (x, 0)) == MULT)
		shift_val = exact_log2 (shift_val);

	      rtx reg1, reg2;

	      reg1 = XEXP (x, 1);
	      if (GET_CODE (reg1) != REG)
		reg1 = force_reg (Pmode, force_operand (reg1, 0));

	      reg2 = XEXP (XEXP (x, 0), 0);
	      if (GET_CODE (reg2) != REG)
	        reg2 = force_reg (Pmode, force_operand (reg2, 0));

	      return
		force_reg (Pmode,
			   gen_rtx_PLUS (Pmode,
					 gen_rtx_ASHIFT (Pmode,
							 reg2,
							 GEN_INT (shift_val)),
					 reg1));
	    }
	  else if ((mode == DFmode || mode == SFmode)
		   && GET_CODE (XEXP (y, 0)) == SYMBOL_REF
		   && mem_shadd_or_shadd_rtx_p (XEXP (x, 0))
		   && GET_CODE (XEXP (y, 1)) == CONST_INT
		   && INTVAL (XEXP (y, 1)) % (1 << INTVAL (XEXP (XEXP (x, 0), 1))) == 0)
	    {
	      int shift_val = INTVAL (XEXP (XEXP (x, 0), 1));

	      /* If we were given a MULT, we must fix the constant
		 as we're going to create the ASHIFT form.  */
	      if (GET_CODE (XEXP (x, 0)) == MULT)
		shift_val = exact_log2 (shift_val);

	      regx1
		= force_reg (Pmode, GEN_INT (INTVAL (XEXP (y, 1))
					     / INTVAL (XEXP (XEXP (x, 0), 1))));
	      regx2 = XEXP (XEXP (x, 0), 0);
	      if (GET_CODE (regx2) != REG)
		regx2 = force_reg (Pmode, force_operand (regx2, 0));
	      regx2 = force_reg (Pmode, gen_rtx_fmt_ee (GET_CODE (y), Pmode,
							regx2, regx1));
	      return
		force_reg (Pmode,
			   gen_rtx_PLUS (Pmode,
					 gen_rtx_ASHIFT (Pmode, regx2,
						         GEN_INT (shift_val)),
					 force_reg (Pmode, XEXP (y, 0))));
	    }
	  else if (GET_CODE (XEXP (y, 1)) == CONST_INT
		   && INTVAL (XEXP (y, 1)) >= -4096
		   && INTVAL (XEXP (y, 1)) <= 4095)
	    {
	      /* This is safe because of the guard page at the
		 beginning and end of the data space.  Just
		 return the original address.  */
	      return orig;
	    }
	  else
	    {
	      /* Doesn't look like one we can optimize.  */
	      regx1 = force_reg (Pmode, force_operand (XEXP (x, 0), 0));
	      regy1 = force_reg (Pmode, force_operand (XEXP (y, 0), 0));
	      regy2 = force_reg (Pmode, force_operand (XEXP (y, 1), 0));
	      regx1 = force_reg (Pmode,
				 gen_rtx_fmt_ee (GET_CODE (y), Pmode,
						 regx1, regy2));
	      return force_reg (Pmode, gen_rtx_PLUS (Pmode, regx1, regy1));
	    }
	}
    }

  return orig;
}

/* Implement the TARGET_REGISTER_MOVE_COST hook.

   Compute extra cost of moving data between one register class
   and another.

   Make moves from SAR so expensive they should never happen.  We used to
   have 0xffff here, but that generates overflow in rare cases.

   Copies involving a FP register and a non-FP register are relatively
   expensive because they must go through memory.

   Other copies are reasonably cheap.  */

static int
hppa_register_move_cost (machine_mode mode ATTRIBUTE_UNUSED,
			 reg_class_t from, reg_class_t to)
{
  if (from == SHIFT_REGS)
    return 0x100;
  else if (to == SHIFT_REGS && FP_REG_CLASS_P (from))
    return 18;
  else if ((FP_REG_CLASS_P (from) && ! FP_REG_CLASS_P (to))
           || (FP_REG_CLASS_P (to) && ! FP_REG_CLASS_P (from)))
    return 16;
  else
    return 2;
}

/* For the HPPA, REG and REG+CONST is cost 0
   and addresses involving symbolic constants are cost 2.

   PIC addresses are very expensive.

   It is no coincidence that this has the same structure
   as pa_legitimate_address_p.  */

static int
hppa_address_cost (rtx X, machine_mode mode ATTRIBUTE_UNUSED,
		   addr_space_t as ATTRIBUTE_UNUSED,
		   bool speed ATTRIBUTE_UNUSED)
{
  switch (GET_CODE (X))
    {
    case REG:
    case PLUS:
    case LO_SUM:
      return 1;
    case HIGH:
      return 2;
    default:
      return 4;
    }
}

/* Return true if X represents a (possibly non-canonical) shNadd pattern.
   The machine mode of X is known to be SImode or DImode.  */

static bool
hppa_rtx_costs_shadd_p (rtx x)
{
  if (GET_CODE (x) != PLUS
      || !REG_P (XEXP (x, 1)))
    return false;
  rtx op0 = XEXP (x, 0);
  if (GET_CODE (op0) == ASHIFT
      && CONST_INT_P (XEXP (op0, 1))
      && REG_P (XEXP (op0, 0)))
    {
      unsigned HOST_WIDE_INT x = UINTVAL (XEXP (op0, 1));
      return x == 1 || x == 2 || x == 3;
    }
  if (GET_CODE (op0) == MULT
      && CONST_INT_P (XEXP (op0, 1))
      && REG_P (XEXP (op0, 0)))
    {
      unsigned HOST_WIDE_INT x = UINTVAL (XEXP (op0, 1));
      return x == 2 || x == 4 || x == 8;
    }
  return false;
}

/* Compute a (partial) cost for rtx X.  Return true if the complete
   cost has been computed, and false if subexpressions should be
   scanned.  In either case, *TOTAL contains the cost result.  */

static bool
hppa_rtx_costs (rtx x, machine_mode mode, int outer_code,
		int opno ATTRIBUTE_UNUSED,
		int *total, bool speed)
{
  int code = GET_CODE (x);

  switch (code)
    {
    case CONST_INT:
      if (outer_code == SET)
	*total = COSTS_N_INSNS (1);
      else if (INTVAL (x) == 0)
	*total = 0;
      else if (INT_14_BITS (x))
	*total = 1;
      else
	*total = 2;
      return true;

    case HIGH:
      *total = 2;
      return true;

    case CONST:
    case LABEL_REF:
    case SYMBOL_REF:
      *total = 4;
      return true;

    case CONST_DOUBLE:
      if ((x == CONST0_RTX (DFmode) || x == CONST0_RTX (SFmode))
	  && outer_code != SET)
	*total = 0;
      else
	*total = 8;
      return true;

    case MULT:
      if (GET_MODE_CLASS (mode) == MODE_FLOAT)
	{
	  *total = COSTS_N_INSNS (3);
	}
      else if (mode == DImode)
	{
	  if (TARGET_PA_11 && !TARGET_DISABLE_FPREGS && !TARGET_SOFT_FLOAT)
	    *total = COSTS_N_INSNS (32);
	  else
	    *total = COSTS_N_INSNS (80);
	}
      else
	{
	  if (TARGET_PA_11 && !TARGET_DISABLE_FPREGS && !TARGET_SOFT_FLOAT)
	    *total = COSTS_N_INSNS (8);
	  else
	    *total = COSTS_N_INSNS (20);
	}
      return REG_P (XEXP (x, 0)) && REG_P (XEXP (x, 1));

    case DIV:
      if (GET_MODE_CLASS (mode) == MODE_FLOAT)
	{
	  *total = COSTS_N_INSNS (14);
	  return false;
	}
      /* FALLTHRU */

    case UDIV:
    case MOD:
    case UMOD:
      /* A mode size N times larger than SImode needs O(N*N) more insns.  */
      if (mode == DImode)
	*total = COSTS_N_INSNS (240);
      else
	*total = COSTS_N_INSNS (60);
      return REG_P (XEXP (x, 0)) && REG_P (XEXP (x, 1));

    case PLUS: /* this includes shNadd insns */
    case MINUS:
      if (GET_MODE_CLASS (mode) == MODE_FLOAT)
	*total = COSTS_N_INSNS (3);
      else if (mode == DImode)
	{
	  if (TARGET_64BIT)
	    {
	      *total = COSTS_N_INSNS (1);
	      /* Handle shladd,l instructions.  */
	      if (hppa_rtx_costs_shadd_p (x))
		return true;
	    }
	  else
	    *total = COSTS_N_INSNS (2);
	}
      else
	{
	  *total = COSTS_N_INSNS (1);
	  /* Handle shNadd instructions.  */
	  if (hppa_rtx_costs_shadd_p (x))
	    return true;
	}
      return REG_P (XEXP (x, 0))
	     && (REG_P (XEXP (x, 1))
		 || CONST_INT_P (XEXP (x, 1)));

    case ASHIFT:
      if (mode == DImode)
	{
	  if (REG_P (XEXP (x, 0)) && CONST_INT_P (XEXP (x, 1)))
	    {
	      if (TARGET_64BIT)
		*total = COSTS_N_INSNS (1);
	      else
		*total = COSTS_N_INSNS (2);
	      return true;
	    }
	  else if (TARGET_64BIT)
	    *total = COSTS_N_INSNS (3);
	  else if (speed)
	    *total = COSTS_N_INSNS (13);
	  else
	    *total = COSTS_N_INSNS (18);
	}
      else if (REG_P (XEXP (x, 0)) && CONST_INT_P (XEXP (x, 1)))
	{
	  if (TARGET_64BIT)
	    *total = COSTS_N_INSNS (2);
	  else
	    *total = COSTS_N_INSNS (1);
	  return true;
	}
      else if (TARGET_64BIT)
	*total = COSTS_N_INSNS (4);
      else
	*total = COSTS_N_INSNS (2);
      return REG_P (XEXP (x, 0))
	     && (REG_P (XEXP (x, 1))
		 || CONST_INT_P (XEXP (x, 1)));

    case ASHIFTRT:
      if (mode == DImode)
	{
	  if (REG_P (XEXP (x, 0)) && CONST_INT_P (XEXP (x, 1)))
	    {
	      if (TARGET_64BIT)
		*total = COSTS_N_INSNS (1);
	      else
		*total = COSTS_N_INSNS (2);
	      return true;
	    }
	  else if (TARGET_64BIT)
	    *total = COSTS_N_INSNS (3);
	  else if (speed)
	    *total = COSTS_N_INSNS (14);
	  else
	    *total = COSTS_N_INSNS (19);
	}
      else if (REG_P (XEXP (x, 0)) && CONST_INT_P (XEXP (x, 1)))
	{
	  if (TARGET_64BIT)
	    *total = COSTS_N_INSNS (2);
	  else
	    *total = COSTS_N_INSNS (1);
	  return true;
	}
      else if (TARGET_64BIT)
	*total = COSTS_N_INSNS (4);
      else
	*total = COSTS_N_INSNS (2);
      return REG_P (XEXP (x, 0))
	     && (REG_P (XEXP (x, 1))
		 || CONST_INT_P (XEXP (x, 1)));

    case LSHIFTRT:
      if (mode == DImode)
	{
	  if (REG_P (XEXP (x, 0)) && CONST_INT_P (XEXP (x, 1)))
	    {
	      if (TARGET_64BIT)
		*total = COSTS_N_INSNS (1);
	      else
		*total = COSTS_N_INSNS (2);
	      return true;
	    }
	  else if (TARGET_64BIT)
	    *total = COSTS_N_INSNS (2);
	  else if (speed)
	    *total = COSTS_N_INSNS (12);
	  else
	    *total = COSTS_N_INSNS (15);
	}
      else if (REG_P (XEXP (x, 0)) && CONST_INT_P (XEXP (x, 1)))
	{
	  *total = COSTS_N_INSNS (1);
	  return true;
	}
      else if (TARGET_64BIT)
	*total = COSTS_N_INSNS (3);
      else
	*total = COSTS_N_INSNS (2);
      return REG_P (XEXP (x, 0))
	     && (REG_P (XEXP (x, 1))
		 || CONST_INT_P (XEXP (x, 1)));

    default:
      return false;
    }
}

/* Ensure mode of ORIG, a REG rtx, is MODE.  Returns either ORIG or a
   new rtx with the correct mode.  */
static inline rtx
force_mode (machine_mode mode, rtx orig)
{
  if (mode == GET_MODE (orig))
    return orig;

  gcc_assert (REGNO (orig) < FIRST_PSEUDO_REGISTER);

  return gen_rtx_REG (mode, REGNO (orig));
}

/* Implement TARGET_CANNOT_FORCE_CONST_MEM.  */

static bool
pa_cannot_force_const_mem (machine_mode mode ATTRIBUTE_UNUSED, rtx x)
{
  return tls_referenced_p (x);
}

/* Emit insns to move operands[1] into operands[0].

   Return 1 if we have written out everything that needs to be done to
   do the move.  Otherwise, return 0 and the caller will emit the move
   normally.

   Note SCRATCH_REG may not be in the proper mode depending on how it
   will be used.  This routine is responsible for creating a new copy
   of SCRATCH_REG in the proper mode.  */

int
pa_emit_move_sequence (rtx *operands, machine_mode mode, rtx scratch_reg)
{
  rtx operand0 = operands[0];
  rtx operand1 = operands[1];
  rtx tem;

  /* We can only handle indexed addresses in the destination operand
     of floating point stores.  Thus, we need to break out indexed
     addresses from the destination operand.  */
  if (GET_CODE (operand0) == MEM && IS_INDEX_ADDR_P (XEXP (operand0, 0)))
    {
      gcc_assert (can_create_pseudo_p ());

      tem = copy_to_mode_reg (Pmode, XEXP (operand0, 0));
      operand0 = replace_equiv_address (operand0, tem);
    }

  /* On targets with non-equivalent space registers, break out unscaled
     indexed addresses from the source operand before the final CSE.
     We have to do this because the REG_POINTER flag is not correctly
     carried through various optimization passes and CSE may substitute
     a pseudo without the pointer set for one with the pointer set.  As
     a result, we loose various opportunities to create insns with
     unscaled indexed addresses.  */
  if (!TARGET_NO_SPACE_REGS
      && !cse_not_expected
      && GET_CODE (operand1) == MEM
      && GET_CODE (XEXP (operand1, 0)) == PLUS
      && REG_P (XEXP (XEXP (operand1, 0), 0))
      && REG_P (XEXP (XEXP (operand1, 0), 1)))
    operand1
      = replace_equiv_address (operand1,
			       copy_to_mode_reg (Pmode, XEXP (operand1, 0)));

  if (scratch_reg
      && reload_in_progress && GET_CODE (operand0) == REG
      && REGNO (operand0) >= FIRST_PSEUDO_REGISTER)
    operand0 = reg_equiv_mem (REGNO (operand0));
  else if (scratch_reg
	   && reload_in_progress && GET_CODE (operand0) == SUBREG
	   && GET_CODE (SUBREG_REG (operand0)) == REG
	   && REGNO (SUBREG_REG (operand0)) >= FIRST_PSEUDO_REGISTER)
    {
     /* We must not alter SUBREG_BYTE (operand0) since that would confuse
	the code which tracks sets/uses for delete_output_reload.  */
      rtx temp = gen_rtx_SUBREG (GET_MODE (operand0),
				 reg_equiv_mem (REGNO (SUBREG_REG (operand0))),
				 SUBREG_BYTE (operand0));
      operand0 = alter_subreg (&temp, true);
    }

  if (scratch_reg
      && reload_in_progress && GET_CODE (operand1) == REG
      && REGNO (operand1) >= FIRST_PSEUDO_REGISTER)
    operand1 = reg_equiv_mem (REGNO (operand1));
  else if (scratch_reg
	   && reload_in_progress && GET_CODE (operand1) == SUBREG
	   && GET_CODE (SUBREG_REG (operand1)) == REG
	   && REGNO (SUBREG_REG (operand1)) >= FIRST_PSEUDO_REGISTER)
    {
     /* We must not alter SUBREG_BYTE (operand0) since that would confuse
	the code which tracks sets/uses for delete_output_reload.  */
      rtx temp = gen_rtx_SUBREG (GET_MODE (operand1),
				 reg_equiv_mem (REGNO (SUBREG_REG (operand1))),
				 SUBREG_BYTE (operand1));
      operand1 = alter_subreg (&temp, true);
    }

  if (scratch_reg && reload_in_progress && GET_CODE (operand0) == MEM
      && ((tem = find_replacement (&XEXP (operand0, 0)))
	  != XEXP (operand0, 0)))
    operand0 = replace_equiv_address (operand0, tem);

  if (scratch_reg && reload_in_progress && GET_CODE (operand1) == MEM
      && ((tem = find_replacement (&XEXP (operand1, 0)))
	  != XEXP (operand1, 0)))
    operand1 = replace_equiv_address (operand1, tem);

  /* Handle secondary reloads for loads/stores of FP registers from
     REG+D addresses where D does not fit in 5 or 14 bits, including
     (subreg (mem (addr))) cases, and reloads for other unsupported
     memory operands.  */
  if (scratch_reg
      && FP_REG_P (operand0)
      && (MEM_P (operand1)
	  || (GET_CODE (operand1) == SUBREG
	      && MEM_P (XEXP (operand1, 0)))))
    {
      rtx op1 = operand1;

      if (GET_CODE (op1) == SUBREG)
	op1 = XEXP (op1, 0);

      if (reg_plus_base_memory_operand (op1, GET_MODE (op1)))
	{
	  if (!(TARGET_PA_20
		&& !TARGET_ELF32
		&& INT_14_BITS (XEXP (XEXP (op1, 0), 1)))
	      && !INT_5_BITS (XEXP (XEXP (op1, 0), 1)))
	    {
	      /* SCRATCH_REG will hold an address and maybe the actual data.
		 We want it in WORD_MODE regardless of what mode it was
		 originally given to us.  */
	      scratch_reg = force_mode (word_mode, scratch_reg);

	      /* D might not fit in 14 bits either; for such cases load D
		 into scratch reg.  */
	      if (!INT_14_BITS (XEXP (XEXP (op1, 0), 1)))
		{
		  emit_move_insn (scratch_reg, XEXP (XEXP (op1, 0), 1));
		  emit_move_insn (scratch_reg,
				  gen_rtx_fmt_ee (GET_CODE (XEXP (op1, 0)),
						  Pmode,
						  XEXP (XEXP (op1, 0), 0),
						  scratch_reg));
		}
	      else
		emit_move_insn (scratch_reg, XEXP (op1, 0));
	      op1 = replace_equiv_address (op1, scratch_reg);
	    }
	}
      else if ((!INT14_OK_STRICT && symbolic_memory_operand (op1, VOIDmode))
	       || IS_LO_SUM_DLT_ADDR_P (XEXP (op1, 0))
	       || IS_INDEX_ADDR_P (XEXP (op1, 0)))
	{
	  /* Load memory address into SCRATCH_REG.  */
	  scratch_reg = force_mode (word_mode, scratch_reg);
	  emit_move_insn (scratch_reg, XEXP (op1, 0));
	  op1 = replace_equiv_address (op1, scratch_reg);
	}
      emit_insn (gen_rtx_SET (operand0, op1));
      return 1;
    }
  else if (scratch_reg
	   && FP_REG_P (operand1)
	   && (MEM_P (operand0)
	       || (GET_CODE (operand0) == SUBREG
		   && MEM_P (XEXP (operand0, 0)))))
    {
      rtx op0 = operand0;

      if (GET_CODE (op0) == SUBREG)
	op0 = XEXP (op0, 0);

      if (reg_plus_base_memory_operand (op0, GET_MODE (op0)))
	{
	  if (!(TARGET_PA_20
		&& !TARGET_ELF32
		&& INT_14_BITS (XEXP (XEXP (op0, 0), 1)))
	      && !INT_5_BITS (XEXP (XEXP (op0, 0), 1)))
	    {
	      /* SCRATCH_REG will hold an address and maybe the actual data.
		 We want it in WORD_MODE regardless of what mode it was
		 originally given to us.  */
	      scratch_reg = force_mode (word_mode, scratch_reg);

	      /* D might not fit in 14 bits either; for such cases load D
		 into scratch reg.  */
	      if (!INT_14_BITS (XEXP (XEXP (op0, 0), 1)))
		{
		  emit_move_insn (scratch_reg, XEXP (XEXP (op0, 0), 1));
		  emit_move_insn (scratch_reg,
				  gen_rtx_fmt_ee (GET_CODE (XEXP (op0, 0)),
						  Pmode,
						  XEXP (XEXP (op0, 0), 0),
						  scratch_reg));
		}
	      else
		emit_move_insn (scratch_reg, XEXP (op0, 0));
	      op0 = replace_equiv_address (op0, scratch_reg);
	    }
	}
      else if ((!INT14_OK_STRICT && symbolic_memory_operand (op0, VOIDmode))
	       || IS_LO_SUM_DLT_ADDR_P (XEXP (op0, 0))
	       || IS_INDEX_ADDR_P (XEXP (op0, 0)))
	{
	  /* Load memory address into SCRATCH_REG.  */
	  scratch_reg = force_mode (word_mode, scratch_reg);
	  emit_move_insn (scratch_reg, XEXP (op0, 0));
	  op0 = replace_equiv_address (op0, scratch_reg);
	}
      emit_insn (gen_rtx_SET (op0, operand1));
      return 1;
    }
  /* Handle secondary reloads for loads of FP registers from constant
     expressions by forcing the constant into memory.  For the most part,
     this is only necessary for SImode and DImode.

     Use scratch_reg to hold the address of the memory location.  */
  else if (scratch_reg
	   && CONSTANT_P (operand1)
	   && FP_REG_P (operand0))
    {
      rtx const_mem, xoperands[2];

      if (operand1 == CONST0_RTX (mode))
	{
	  emit_insn (gen_rtx_SET (operand0, operand1));
	  return 1;
	}

      /* SCRATCH_REG will hold an address and maybe the actual data.  We want
	 it in WORD_MODE regardless of what mode it was originally given
	 to us.  */
      scratch_reg = force_mode (word_mode, scratch_reg);

      /* Force the constant into memory and put the address of the
	 memory location into scratch_reg.  */
      const_mem = force_const_mem (mode, operand1);
      xoperands[0] = scratch_reg;
      xoperands[1] = XEXP (const_mem, 0);
      pa_emit_move_sequence (xoperands, Pmode, 0);

      /* Now load the destination register.  */
      emit_insn (gen_rtx_SET (operand0,
			      replace_equiv_address (const_mem, scratch_reg)));
      return 1;
    }
  /* Handle secondary reloads for SAR.  These occur when trying to load
     the SAR from memory or a constant.  */
  else if (scratch_reg
	   && GET_CODE (operand0) == REG
	   && REGNO (operand0) < FIRST_PSEUDO_REGISTER
	   && REGNO_REG_CLASS (REGNO (operand0)) == SHIFT_REGS
	   && (GET_CODE (operand1) == MEM || GET_CODE (operand1) == CONST_INT))
    {
      /* D might not fit in 14 bits either; for such cases load D into
	 scratch reg.  */
      if (GET_CODE (operand1) == MEM
	  && !memory_address_p (GET_MODE (operand0), XEXP (operand1, 0)))
	{
	  /* We are reloading the address into the scratch register, so we
	     want to make sure the scratch register is a full register.  */
	  scratch_reg = force_mode (word_mode, scratch_reg);

	  emit_move_insn (scratch_reg, XEXP (XEXP (operand1, 0), 1));
	  emit_move_insn (scratch_reg, gen_rtx_fmt_ee (GET_CODE (XEXP (operand1,
								        0)),
						       Pmode,
						       XEXP (XEXP (operand1, 0),
						       0),
						       scratch_reg));

	  /* Now we are going to load the scratch register from memory,
	     we want to load it in the same width as the original MEM,
	     which must be the same as the width of the ultimate destination,
	     OPERAND0.  */
	  scratch_reg = force_mode (GET_MODE (operand0), scratch_reg);

	  emit_move_insn (scratch_reg,
			  replace_equiv_address (operand1, scratch_reg));
	}
      else
	{
	  /* We want to load the scratch register using the same mode as
	     the ultimate destination.  */
	  scratch_reg = force_mode (GET_MODE (operand0), scratch_reg);

	  emit_move_insn (scratch_reg, operand1);
	}

      /* And emit the insn to set the ultimate destination.  We know that
	 the scratch register has the same mode as the destination at this
	 point.  */
      emit_move_insn (operand0, scratch_reg);
      return 1;
    }

  /* Handle the most common case: storing into a register.  */
  if (register_operand (operand0, mode))
    {
      /* Legitimize TLS symbol references.  This happens for references
	 that aren't a legitimate constant.  */
      if (PA_SYMBOL_REF_TLS_P (operand1))
	operand1 = legitimize_tls_address (operand1);

      if (register_operand (operand1, mode)
	  || (GET_CODE (operand1) == CONST_INT
	      && pa_cint_ok_for_move (UINTVAL (operand1)))
	  || (operand1 == CONST0_RTX (mode))
	  || (GET_CODE (operand1) == HIGH
	      && !symbolic_operand (XEXP (operand1, 0), VOIDmode))
	  /* Only `general_operands' can come here, so MEM is ok.  */
	  || GET_CODE (operand1) == MEM)
	{
	  /* Various sets are created during RTL generation which don't
	     have the REG_POINTER flag correctly set.  After the CSE pass,
	     instruction recognition can fail if we don't consistently
	     set this flag when performing register copies.  This should
	     also improve the opportunities for creating insns that use
	     unscaled indexing.  */
	  if (REG_P (operand0) && REG_P (operand1))
	    {
	      if (REG_POINTER (operand1)
		  && !REG_POINTER (operand0)
		  && !HARD_REGISTER_P (operand0))
		copy_reg_pointer (operand0, operand1);
	    }
	  
	  /* When MEMs are broken out, the REG_POINTER flag doesn't
	     get set.  In some cases, we can set the REG_POINTER flag
	     from the declaration for the MEM.  */
	  if (REG_P (operand0)
	      && GET_CODE (operand1) == MEM
	      && !REG_POINTER (operand0))
	    {
	      tree decl = MEM_EXPR (operand1);

	      /* Set the register pointer flag and register alignment
		 if the declaration for this memory reference is a
		 pointer type.  */
	      if (decl)
		{
		  tree type;

		  /* If this is a COMPONENT_REF, use the FIELD_DECL from
		     tree operand 1.  */
		  if (TREE_CODE (decl) == COMPONENT_REF)
		    decl = TREE_OPERAND (decl, 1);

		  type = TREE_TYPE (decl);
		  type = strip_array_types (type);

		  if (POINTER_TYPE_P (type))
		    mark_reg_pointer (operand0, BITS_PER_UNIT);
		}
	    }

	  emit_insn (gen_rtx_SET (operand0, operand1));
	  return 1;
	}
    }
  else if (GET_CODE (operand0) == MEM)
    {
      if (mode == DFmode && operand1 == CONST0_RTX (mode)
	  && !(reload_in_progress || reload_completed))
	{
	  rtx temp = gen_reg_rtx (DFmode);

	  emit_insn (gen_rtx_SET (temp, operand1));
	  emit_insn (gen_rtx_SET (operand0, temp));
	  return 1;
	}
      if (register_operand (operand1, mode) || operand1 == CONST0_RTX (mode))
	{
	  /* Run this case quickly.  */
	  emit_insn (gen_rtx_SET (operand0, operand1));
	  return 1;
	}
      if (! (reload_in_progress || reload_completed))
	{
	  operands[0] = validize_mem (operand0);
	  operands[1] = operand1 = force_reg (mode, operand1);
	}
    }

  /* Simplify the source if we need to.
     Note we do have to handle function labels here, even though we do
     not consider them legitimate constants.  Loop optimizations can
     call the emit_move_xxx with one as a source.  */
  if ((GET_CODE (operand1) != HIGH && immediate_operand (operand1, mode))
      || (GET_CODE (operand1) == HIGH
	  && symbolic_operand (XEXP (operand1, 0), mode))
      || function_label_operand (operand1, VOIDmode)
      || tls_referenced_p (operand1))
    {
      int ishighonly = 0;

      if (GET_CODE (operand1) == HIGH)
	{
	  ishighonly = 1;
	  operand1 = XEXP (operand1, 0);
	}
      if (symbolic_operand (operand1, mode))
	{
	  /* Argh.  The assembler and linker can't handle arithmetic
	     involving plabels.

	     So we force the plabel into memory, load operand0 from
	     the memory location, then add in the constant part.  */
	  if ((GET_CODE (operand1) == CONST
	       && GET_CODE (XEXP (operand1, 0)) == PLUS
	       && function_label_operand (XEXP (XEXP (operand1, 0), 0),
					  VOIDmode))
	      || function_label_operand (operand1, VOIDmode))
	    {
	      rtx temp, const_part;

	      /* Figure out what (if any) scratch register to use.  */
	      if (reload_in_progress || reload_completed)
		{
		  scratch_reg = scratch_reg ? scratch_reg : operand0;
		  /* SCRATCH_REG will hold an address and maybe the actual
		     data.  We want it in WORD_MODE regardless of what mode it
		     was originally given to us.  */
		  scratch_reg = force_mode (word_mode, scratch_reg);
		}
	      else if (flag_pic)
		scratch_reg = gen_reg_rtx (Pmode);

	      if (GET_CODE (operand1) == CONST)
		{
		  /* Save away the constant part of the expression.  */
		  const_part = XEXP (XEXP (operand1, 0), 1);
		  gcc_assert (GET_CODE (const_part) == CONST_INT);

		  /* Force the function label into memory.  */
		  temp = force_const_mem (mode, XEXP (XEXP (operand1, 0), 0));
		}
	      else
		{
		  /* No constant part.  */
		  const_part = NULL_RTX;

		  /* Force the function label into memory.  */
		  temp = force_const_mem (mode, operand1);
		}


	      /* Get the address of the memory location.  PIC-ify it if
		 necessary.  */
	      temp = XEXP (temp, 0);
	      if (flag_pic)
		temp = legitimize_pic_address (temp, mode, scratch_reg);

	      /* Put the address of the memory location into our destination
		 register.  */
	      operands[1] = temp;
	      pa_emit_move_sequence (operands, mode, scratch_reg);

	      /* Now load from the memory location into our destination
		 register.  */
	      operands[1] = gen_rtx_MEM (Pmode, operands[0]);
	      pa_emit_move_sequence (operands, mode, scratch_reg);

	      /* And add back in the constant part.  */
	      if (const_part != NULL_RTX)
		expand_inc (operand0, const_part);

	      return 1;
	    }

	  if (flag_pic)
	    {
	      rtx_insn *insn;
	      rtx temp;

	      if (reload_in_progress || reload_completed)
		{
		  temp = scratch_reg ? scratch_reg : operand0;
		  /* TEMP will hold an address and maybe the actual
		     data.  We want it in WORD_MODE regardless of what mode it
		     was originally given to us.  */
		  temp = force_mode (word_mode, temp);
		}
	      else
		temp = gen_reg_rtx (Pmode);

	      /* Force (const (plus (symbol) (const_int))) to memory
	         if the const_int will not fit in 14 bits.  Although
		 this requires a relocation, the instruction sequence
		 needed to load the value is shorter.  */
	      if (GET_CODE (operand1) == CONST
		       && GET_CODE (XEXP (operand1, 0)) == PLUS
		       && GET_CODE (XEXP (XEXP (operand1, 0), 1)) == CONST_INT
		       && !INT_14_BITS (XEXP (XEXP (operand1, 0), 1)))
		{
		  rtx x, m = force_const_mem (mode, operand1);

		  x = legitimize_pic_address (XEXP (m, 0), mode, temp);
		  x = replace_equiv_address (m, x);
		  insn = emit_move_insn (operand0, x);
		}
	      else
		{
		  operands[1] = legitimize_pic_address (operand1, mode, temp);
		  if (REG_P (operand0) && REG_P (operands[1]))
		    copy_reg_pointer (operand0, operands[1]);
		  insn = emit_move_insn (operand0, operands[1]);
		}

	      /* Put a REG_EQUAL note on this insn.  */
	      set_unique_reg_note (insn, REG_EQUAL, operand1);
	    }
	  /* On the HPPA, references to data space are supposed to use dp,
	     register 27, but showing it in the RTL inhibits various cse
	     and loop optimizations.  */
	  else
	    {
	      rtx temp, set;

	      if (reload_in_progress || reload_completed)
		{
		  temp = scratch_reg ? scratch_reg : operand0;
		  /* TEMP will hold an address and maybe the actual
		     data.  We want it in WORD_MODE regardless of what mode it
		     was originally given to us.  */
		  temp = force_mode (word_mode, temp);
		}
	      else
		temp = gen_reg_rtx (mode);

	      /* Loading a SYMBOL_REF into a register makes that register
		 safe to be used as the base in an indexed address.

		 Don't mark hard registers though.  That loses.  */
	      if (GET_CODE (operand0) == REG
		  && REGNO (operand0) >= FIRST_PSEUDO_REGISTER)
		mark_reg_pointer (operand0, BITS_PER_UNIT);
	      if (REGNO (temp) >= FIRST_PSEUDO_REGISTER)
		mark_reg_pointer (temp, BITS_PER_UNIT);

	      if (ishighonly)
		set = gen_rtx_SET (operand0, temp);
	      else
		set = gen_rtx_SET (operand0,
				   gen_rtx_LO_SUM (mode, temp, operand1));

	      emit_insn (gen_rtx_SET (temp, gen_rtx_HIGH (mode, operand1)));
	      emit_insn (set);

	    }
	  return 1;
	}
      else if (tls_referenced_p (operand1))
	{
	  rtx tmp = operand1;
	  rtx addend = NULL;

	  if (GET_CODE (tmp) == CONST && GET_CODE (XEXP (tmp, 0)) == PLUS)
	    {
	      addend = XEXP (XEXP (tmp, 0), 1);
	      tmp = XEXP (XEXP (tmp, 0), 0);
	    }

	  gcc_assert (GET_CODE (tmp) == SYMBOL_REF);
	  tmp = legitimize_tls_address (tmp);
	  if (addend)
	    {
	      tmp = gen_rtx_PLUS (mode, tmp, addend);
	      tmp = force_operand (tmp, operands[0]);
	    }
	  operands[1] = tmp;
	}
      else if (GET_CODE (operand1) != CONST_INT
	       || !pa_cint_ok_for_move (UINTVAL (operand1)))
	{
	  rtx temp;
	  rtx_insn *insn;
	  rtx op1 = operand1;
	  HOST_WIDE_INT value = 0;
	  HOST_WIDE_INT insv = 0;
	  int insert = 0;

	  if (GET_CODE (operand1) == CONST_INT)
	    value = INTVAL (operand1);

	  if (TARGET_64BIT
	      && GET_CODE (operand1) == CONST_INT
	      && HOST_BITS_PER_WIDE_INT > 32
	      && GET_MODE_BITSIZE (GET_MODE (operand0)) > 32)
	    {
	      HOST_WIDE_INT nval;

	      /* Extract the low order 32 bits of the value and sign extend.
		 If the new value is the same as the original value, we can
		 can use the original value as-is.  If the new value is
		 different, we use it and insert the most-significant 32-bits
		 of the original value into the final result.  */
	      nval = ((value & (((HOST_WIDE_INT) 2 << 31) - 1))
		      ^ ((HOST_WIDE_INT) 1 << 31)) - ((HOST_WIDE_INT) 1 << 31);
	      if (value != nval)
		{
#if HOST_BITS_PER_WIDE_INT > 32
		  insv = value >= 0 ? value >> 32 : ~(~value >> 32);
#endif
		  insert = 1;
		  value = nval;
		  operand1 = GEN_INT (nval);
		}
	    }

	  if (reload_in_progress || reload_completed)
	    temp = scratch_reg ? scratch_reg : operand0;
	  else
	    temp = gen_reg_rtx (mode);

	  /* We don't directly split DImode constants on 32-bit targets
	     because PLUS uses an 11-bit immediate and the insn sequence
	     generated is not as efficient as the one using HIGH/LO_SUM.  */
	  if (GET_CODE (operand1) == CONST_INT
	      && GET_MODE_BITSIZE (mode) <= BITS_PER_WORD
	      && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
	      && !insert)
	    {
	      /* Directly break constant into high and low parts.  This
		 provides better optimization opportunities because various
		 passes recognize constants split with PLUS but not LO_SUM.
		 We use a 14-bit signed low part except when the addition
		 of 0x4000 to the high part might change the sign of the
		 high part.  */
	      HOST_WIDE_INT low = value & 0x3fff;
	      HOST_WIDE_INT high = value & ~ 0x3fff;

	      if (low >= 0x2000)
		{
		  if (high == 0x7fffc000 || (mode == HImode && high == 0x4000))
		    high += 0x2000;
		  else
		    high += 0x4000;
		}

	      low = value - high;

	      emit_insn (gen_rtx_SET (temp, GEN_INT (high)));
	      operands[1] = gen_rtx_PLUS (mode, temp, GEN_INT (low));
	    }
	  else
	    {
	      emit_insn (gen_rtx_SET (temp, gen_rtx_HIGH (mode, operand1)));
	      operands[1] = gen_rtx_LO_SUM (mode, temp, operand1);
	    }

	  insn = emit_move_insn (operands[0], operands[1]);

	  /* Now insert the most significant 32 bits of the value
	     into the register.  When we don't have a second register
	     available, it could take up to nine instructions to load
	     a 64-bit integer constant.  Prior to reload, we force
	     constants that would take more than three instructions
	     to load to the constant pool.  During and after reload,
	     we have to handle all possible values.  */
	  if (insert)
	    {
	      /* Use a HIGH/LO_SUM/INSV sequence if we have a second
		 register and the value to be inserted is outside the
		 range that can be loaded with three depdi instructions.  */
	      if (temp != operand0 && (insv >= 16384 || insv < -16384))
		{
		  operand1 = GEN_INT (insv);

		  emit_insn (gen_rtx_SET (temp,
					  gen_rtx_HIGH (mode, operand1)));
		  emit_move_insn (temp, gen_rtx_LO_SUM (mode, temp, operand1));
		  if (mode == DImode)
		    insn = emit_insn (gen_insvdi (operand0, GEN_INT (32),
						  const0_rtx, temp));
		  else
		    insn = emit_insn (gen_insvsi (operand0, GEN_INT (32),
						  const0_rtx, temp));
		}
	      else
		{
		  int len = 5, pos = 27;

		  /* Insert the bits using the depdi instruction.  */
		  while (pos >= 0)
		    {
		      HOST_WIDE_INT v5 = ((insv & 31) ^ 16) - 16;
		      HOST_WIDE_INT sign = v5 < 0;

		      /* Left extend the insertion.  */
		      insv = (insv >= 0 ? insv >> len : ~(~insv >> len));
		      while (pos > 0 && (insv & 1) == sign)
			{
			  insv = (insv >= 0 ? insv >> 1 : ~(~insv >> 1));
			  len += 1;
			  pos -= 1;
			}

		      if (mode == DImode)
			insn = emit_insn (gen_insvdi (operand0,
						      GEN_INT (len),
						      GEN_INT (pos),
						      GEN_INT (v5)));
		      else
			insn = emit_insn (gen_insvsi (operand0,
						      GEN_INT (len),
						      GEN_INT (pos),
						      GEN_INT (v5)));

		      len = pos > 0 && pos < 5 ? pos : 5;
		      pos -= len;
		    }
		}
	    }

	  set_unique_reg_note (insn, REG_EQUAL, op1);

	  return 1;
	}
    }
  /* Now have insn-emit do whatever it normally does.  */
  return 0;
}

/* Examine EXP and return nonzero if it contains an ADDR_EXPR (meaning
   it will need a link/runtime reloc).  */

int
pa_reloc_needed (tree exp)
{
  int reloc = 0;

  switch (TREE_CODE (exp))
    {
    case ADDR_EXPR:
      return 1;

    case POINTER_PLUS_EXPR:
    case PLUS_EXPR:
    case MINUS_EXPR:
      reloc = pa_reloc_needed (TREE_OPERAND (exp, 0));
      reloc |= pa_reloc_needed (TREE_OPERAND (exp, 1));
      break;

    CASE_CONVERT:
    case NON_LVALUE_EXPR:
      reloc = pa_reloc_needed (TREE_OPERAND (exp, 0));
      break;

    case CONSTRUCTOR:
      {
	tree value;
	unsigned HOST_WIDE_INT ix;

	FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (exp), ix, value)
	  if (value)
	    reloc |= pa_reloc_needed (value);
      }
      break;

    case ERROR_MARK:
      break;

    default:
      break;
    }
  return reloc;
}


/* Return the best assembler insn template
   for moving operands[1] into operands[0] as a fullword.  */
const char *
pa_singlemove_string (rtx *operands)
{
  HOST_WIDE_INT intval;

  if (GET_CODE (operands[0]) == MEM)
    return "stw %r1,%0";
  if (GET_CODE (operands[1]) == MEM)
    return "ldw %1,%0";
  if (GET_CODE (operands[1]) == CONST_DOUBLE)
    {
      long i;

      gcc_assert (GET_MODE (operands[1]) == SFmode);

      /* Translate the CONST_DOUBLE to a CONST_INT with the same target
	 bit pattern.  */
      REAL_VALUE_TO_TARGET_SINGLE (*CONST_DOUBLE_REAL_VALUE (operands[1]), i);

      operands[1] = GEN_INT (i);
      /* Fall through to CONST_INT case.  */
    }
  if (GET_CODE (operands[1]) == CONST_INT)
    {
      intval = INTVAL (operands[1]);

      if (VAL_14_BITS_P (intval))
	return "ldi %1,%0";
      else if ((intval & 0x7ff) == 0)
	return "ldil L'%1,%0";
      else if (pa_zdepi_cint_p (intval))
	return "{zdepi %Z1,%0|depwi,z %Z1,%0}";
      else
	return "ldil L'%1,%0\n\tldo R'%1(%0),%0";
    }
  return "copy %1,%0";
}


/* Compute position (in OP[1]) and width (in OP[2])
   useful for copying IMM to a register using the zdepi
   instructions.  Store the immediate value to insert in OP[0].  */
static void
compute_zdepwi_operands (unsigned HOST_WIDE_INT imm, unsigned *op)
{
  int lsb, len;

  /* Find the least significant set bit in IMM.  */
  for (lsb = 0; lsb < 32; lsb++)
    {
      if ((imm & 1) != 0)
        break;
      imm >>= 1;
    }

  /* Choose variants based on *sign* of the 5-bit field.  */
  if ((imm & 0x10) == 0)
    len = (lsb <= 28) ? 4 : 32 - lsb;
  else
    {
      /* Find the width of the bitstring in IMM.  */
      for (len = 5; len < 32 - lsb; len++)
	{
	  if ((imm & ((unsigned HOST_WIDE_INT) 1 << len)) == 0)
	    break;
	}

      /* Sign extend IMM as a 5-bit value.  */
      imm = (imm & 0xf) - 0x10;
    }

  op[0] = imm;
  op[1] = 31 - lsb;
  op[2] = len;
}

/* Compute position (in OP[1]) and width (in OP[2])
   useful for copying IMM to a register using the depdi,z
   instructions.  Store the immediate value to insert in OP[0].  */

static void
compute_zdepdi_operands (unsigned HOST_WIDE_INT imm, unsigned *op)
{
  int lsb, len, maxlen;

  maxlen = MIN (HOST_BITS_PER_WIDE_INT, 64);

  /* Find the least significant set bit in IMM.  */
  for (lsb = 0; lsb < maxlen; lsb++)
    {
      if ((imm & 1) != 0)
        break;
      imm >>= 1;
    }

  /* Choose variants based on *sign* of the 5-bit field.  */
  if ((imm & 0x10) == 0)
    len = (lsb <= maxlen - 4) ? 4 : maxlen - lsb;
  else
    {
      /* Find the width of the bitstring in IMM.  */
      for (len = 5; len < maxlen - lsb; len++)
	{
	  if ((imm & ((unsigned HOST_WIDE_INT) 1 << len)) == 0)
	    break;
	}

      /* Extend length if host is narrow and IMM is negative.  */
      if (HOST_BITS_PER_WIDE_INT == 32 && len == maxlen - lsb)
	len += 32;

      /* Sign extend IMM as a 5-bit value.  */
      imm = (imm & 0xf) - 0x10;
    }

  op[0] = imm;
  op[1] = 63 - lsb;
  op[2] = len;
}

/* Output assembler code to perform a doubleword move insn
   with operands OPERANDS.  */

const char *
pa_output_move_double (rtx *operands)
{
  enum { REGOP, OFFSOP, MEMOP, CNSTOP, RNDOP } optype0, optype1;
  rtx latehalf[2];
  rtx addreg0 = 0, addreg1 = 0;
  int highonly = 0;

  /* First classify both operands.  */

  if (REG_P (operands[0]))
    optype0 = REGOP;
  else if (offsettable_memref_p (operands[0]))
    optype0 = OFFSOP;
  else if (GET_CODE (operands[0]) == MEM)
    optype0 = MEMOP;
  else
    optype0 = RNDOP;

  if (REG_P (operands[1]))
    optype1 = REGOP;
  else if (CONSTANT_P (operands[1]))
    optype1 = CNSTOP;
  else if (offsettable_memref_p (operands[1]))
    optype1 = OFFSOP;
  else if (GET_CODE (operands[1]) == MEM)
    optype1 = MEMOP;
  else
    optype1 = RNDOP;

  /* Check for the cases that the operand constraints are not
     supposed to allow to happen.  */
  gcc_assert (optype0 == REGOP || optype1 == REGOP);

  /* Handle copies between general and floating registers.  */

  if (optype0 == REGOP && optype1 == REGOP
      && FP_REG_P (operands[0]) ^ FP_REG_P (operands[1]))
    {
      if (FP_REG_P (operands[0]))
	{
	  output_asm_insn ("{stws|stw} %1,-16(%%sp)", operands);
	  output_asm_insn ("{stws|stw} %R1,-12(%%sp)", operands);
	  return "{fldds|fldd} -16(%%sp),%0";
	}
      else
	{
	  output_asm_insn ("{fstds|fstd} %1,-16(%%sp)", operands);
	  output_asm_insn ("{ldws|ldw} -16(%%sp),%0", operands);
	  return "{ldws|ldw} -12(%%sp),%R0";
	}
    }

   /* Handle auto decrementing and incrementing loads and stores
     specifically, since the structure of the function doesn't work
     for them without major modification.  Do it better when we learn
     this port about the general inc/dec addressing of PA.
     (This was written by tege.  Chide him if it doesn't work.)  */

  if (optype0 == MEMOP)
    {
      /* We have to output the address syntax ourselves, since print_operand
	 doesn't deal with the addresses we want to use.  Fix this later.  */

      rtx addr = XEXP (operands[0], 0);
      if (GET_CODE (addr) == POST_INC || GET_CODE (addr) == POST_DEC)
	{
	  rtx high_reg = gen_rtx_SUBREG (SImode, operands[1], 0);

	  operands[0] = XEXP (addr, 0);
	  gcc_assert (GET_CODE (operands[1]) == REG
		      && GET_CODE (operands[0]) == REG);

	  gcc_assert (!reg_overlap_mentioned_p (high_reg, addr));
	  
	  /* No overlap between high target register and address
	     register.  (We do this in a non-obvious way to
	     save a register file writeback)  */
	  if (GET_CODE (addr) == POST_INC)
	    return "{stws|stw},ma %1,8(%0)\n\tstw %R1,-4(%0)";
	  return "{stws|stw},ma %1,-8(%0)\n\tstw %R1,12(%0)";
	}
      else if (GET_CODE (addr) == PRE_INC || GET_CODE (addr) == PRE_DEC)
	{
	  rtx high_reg = gen_rtx_SUBREG (SImode, operands[1], 0);

	  operands[0] = XEXP (addr, 0);
	  gcc_assert (GET_CODE (operands[1]) == REG
		      && GET_CODE (operands[0]) == REG);
	  
	  gcc_assert (!reg_overlap_mentioned_p (high_reg, addr));
	  /* No overlap between high target register and address
	     register.  (We do this in a non-obvious way to save a
	     register file writeback)  */
	  if (GET_CODE (addr) == PRE_INC)
	    return "{stws|stw},mb %1,8(%0)\n\tstw %R1,4(%0)";
	  return "{stws|stw},mb %1,-8(%0)\n\tstw %R1,4(%0)";
	}
    }
  if (optype1 == MEMOP)
    {
      /* We have to output the address syntax ourselves, since print_operand
	 doesn't deal with the addresses we want to use.  Fix this later.  */

      rtx addr = XEXP (operands[1], 0);
      if (GET_CODE (addr) == POST_INC || GET_CODE (addr) == POST_DEC)
	{
	  rtx high_reg = gen_rtx_SUBREG (SImode, operands[0], 0);

	  operands[1] = XEXP (addr, 0);
	  gcc_assert (GET_CODE (operands[0]) == REG
		      && GET_CODE (operands[1]) == REG);

	  if (!reg_overlap_mentioned_p (high_reg, addr))
	    {
	      /* No overlap between high target register and address
		 register.  (We do this in a non-obvious way to
		 save a register file writeback)  */
	      if (GET_CODE (addr) == POST_INC)
		return "{ldws|ldw},ma 8(%1),%0\n\tldw -4(%1),%R0";
	      return "{ldws|ldw},ma -8(%1),%0\n\tldw 12(%1),%R0";
	    }
	  else
	    {
	      /* This is an undefined situation.  We should load into the
		 address register *and* update that register.  Probably
		 we don't need to handle this at all.  */
	      if (GET_CODE (addr) == POST_INC)
		return "ldw 4(%1),%R0\n\t{ldws|ldw},ma 8(%1),%0";
	      return "ldw 4(%1),%R0\n\t{ldws|ldw},ma -8(%1),%0";
	    }
	}
      else if (GET_CODE (addr) == PRE_INC || GET_CODE (addr) == PRE_DEC)
	{
	  rtx high_reg = gen_rtx_SUBREG (SImode, operands[0], 0);

	  operands[1] = XEXP (addr, 0);
	  gcc_assert (GET_CODE (operands[0]) == REG
		      && GET_CODE (operands[1]) == REG);

	  if (!reg_overlap_mentioned_p (high_reg, addr))
	    {
	      /* No overlap between high target register and address
		 register.  (We do this in a non-obvious way to
		 save a register file writeback)  */
	      if (GET_CODE (addr) == PRE_INC)
		return "{ldws|ldw},mb 8(%1),%0\n\tldw 4(%1),%R0";
	      return "{ldws|ldw},mb -8(%1),%0\n\tldw 4(%1),%R0";
	    }
	  else
	    {
	      /* This is an undefined situation.  We should load into the
		 address register *and* update that register.  Probably
		 we don't need to handle this at all.  */
	      if (GET_CODE (addr) == PRE_INC)
		return "ldw 12(%1),%R0\n\t{ldws|ldw},mb 8(%1),%0";
	      return "ldw -4(%1),%R0\n\t{ldws|ldw},mb -8(%1),%0";
	    }
	}
      else if (GET_CODE (addr) == PLUS
	       && GET_CODE (XEXP (addr, 0)) == MULT)
	{
	  rtx xoperands[4];

	  /* Load address into left half of destination register.  */
	  xoperands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
	  xoperands[1] = XEXP (addr, 1);
	  xoperands[2] = XEXP (XEXP (addr, 0), 0);
	  xoperands[3] = XEXP (XEXP (addr, 0), 1);
	  output_asm_insn ("{sh%O3addl %2,%1,%0|shladd,l %2,%O3,%1,%0}",
			   xoperands);
	  return "ldw 4(%0),%R0\n\tldw 0(%0),%0";
	}
      else if (GET_CODE (addr) == PLUS
	       && REG_P (XEXP (addr, 0))
	       && REG_P (XEXP (addr, 1)))
	{
	  rtx xoperands[3];

	  /* Load address into left half of destination register.  */
	  xoperands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
	  xoperands[1] = XEXP (addr, 0);
	  xoperands[2] = XEXP (addr, 1);
	  output_asm_insn ("{addl|add,l} %1,%2,%0",
			   xoperands);
	  return "ldw 4(%0),%R0\n\tldw 0(%0),%0";
	}
    }

  /* If an operand is an unoffsettable memory ref, find a register
     we can increment temporarily to make it refer to the second word.  */

  if (optype0 == MEMOP)
    addreg0 = find_addr_reg (XEXP (operands[0], 0));

  if (optype1 == MEMOP)
    addreg1 = find_addr_reg (XEXP (operands[1], 0));

  /* Ok, we can do one word at a time.
     Normally we do the low-numbered word first.

     In either case, set up in LATEHALF the operands to use
     for the high-numbered word and in some cases alter the
     operands in OPERANDS to be suitable for the low-numbered word.  */

  if (optype0 == REGOP)
    latehalf[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
  else if (optype0 == OFFSOP)
    latehalf[0] = adjust_address_nv (operands[0], SImode, 4);
  else
    latehalf[0] = operands[0];

  if (optype1 == REGOP)
    latehalf[1] = gen_rtx_REG (SImode, REGNO (operands[1]) + 1);
  else if (optype1 == OFFSOP)
    latehalf[1] = adjust_address_nv (operands[1], SImode, 4);
  else if (optype1 == CNSTOP)
    {
      if (GET_CODE (operands[1]) == HIGH)
	{
	  operands[1] = XEXP (operands[1], 0);
	  highonly = 1;
	}
      split_double (operands[1], &operands[1], &latehalf[1]);
    }
  else
    latehalf[1] = operands[1];

  /* If the first move would clobber the source of the second one,
     do them in the other order.

     This can happen in two cases:

	mem -> register where the first half of the destination register
 	is the same register used in the memory's address.  Reload
	can create such insns.

	mem in this case will be either register indirect or register
	indirect plus a valid offset.

	register -> register move where REGNO(dst) == REGNO(src + 1)
	someone (Tim/Tege?) claimed this can happen for parameter loads.

     Handle mem -> register case first.  */
  if (optype0 == REGOP
      && (optype1 == MEMOP || optype1 == OFFSOP)
      && refers_to_regno_p (REGNO (operands[0]), operands[1]))
    {
      /* Do the late half first.  */
      if (addreg1)
	output_asm_insn ("ldo 4(%0),%0", &addreg1);
      output_asm_insn (pa_singlemove_string (latehalf), latehalf);

      /* Then clobber.  */
      if (addreg1)
	output_asm_insn ("ldo -4(%0),%0", &addreg1);
      return pa_singlemove_string (operands);
    }

  /* Now handle register -> register case.  */
  if (optype0 == REGOP && optype1 == REGOP
      && REGNO (operands[0]) == REGNO (operands[1]) + 1)
    {
      output_asm_insn (pa_singlemove_string (latehalf), latehalf);
      return pa_singlemove_string (operands);
    }

  /* Normal case: do the two words, low-numbered first.  */

  output_asm_insn (pa_singlemove_string (operands), operands);

  /* Make any unoffsettable addresses point at high-numbered word.  */
  if (addreg0)
    output_asm_insn ("ldo 4(%0),%0", &addreg0);
  if (addreg1)
    output_asm_insn ("ldo 4(%0),%0", &addreg1);

  /* Do high-numbered word.  */
  if (highonly)
    output_asm_insn ("ldil L'%1,%0", latehalf);
  else
    output_asm_insn (pa_singlemove_string (latehalf), latehalf);

  /* Undo the adds we just did.  */
  if (addreg0)
    output_asm_insn ("ldo -4(%0),%0", &addreg0);
  if (addreg1)
    output_asm_insn ("ldo -4(%0),%0", &addreg1);

  return "";
}

const char *
pa_output_fp_move_double (rtx *operands)
{
  if (FP_REG_P (operands[0]))
    {
      if (FP_REG_P (operands[1])
	  || operands[1] == CONST0_RTX (GET_MODE (operands[0])))
	output_asm_insn ("fcpy,dbl %f1,%0", operands);
      else
	output_asm_insn ("fldd%F1 %1,%0", operands);
    }
  else if (FP_REG_P (operands[1]))
    {
      output_asm_insn ("fstd%F0 %1,%0", operands);
    }
  else
    {
      rtx xoperands[2];
      
      gcc_assert (operands[1] == CONST0_RTX (GET_MODE (operands[0])));
      
      /* This is a pain.  You have to be prepared to deal with an
	 arbitrary address here including pre/post increment/decrement.

	 so avoid this in the MD.  */
      gcc_assert (GET_CODE (operands[0]) == REG);
      
      xoperands[1] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
      xoperands[0] = operands[0];
      output_asm_insn ("copy %%r0,%0\n\tcopy %%r0,%1", xoperands);
    }
  return "";
}

/* Return a REG that occurs in ADDR with coefficient 1.
   ADDR can be effectively incremented by incrementing REG.  */

static rtx
find_addr_reg (rtx addr)
{
  while (GET_CODE (addr) == PLUS)
    {
      if (GET_CODE (XEXP (addr, 0)) == REG)
	addr = XEXP (addr, 0);
      else if (GET_CODE (XEXP (addr, 1)) == REG)
	addr = XEXP (addr, 1);
      else if (CONSTANT_P (XEXP (addr, 0)))
	addr = XEXP (addr, 1);
      else if (CONSTANT_P (XEXP (addr, 1)))
	addr = XEXP (addr, 0);
      else
	gcc_unreachable ();
    }
  gcc_assert (GET_CODE (addr) == REG);
  return addr;
}

/* Emit code to perform a block move.

   OPERANDS[0] is the destination pointer as a REG, clobbered.
   OPERANDS[1] is the source pointer as a REG, clobbered.
   OPERANDS[2] is a register for temporary storage.
   OPERANDS[3] is a register for temporary storage.
   OPERANDS[4] is the size as a CONST_INT
   OPERANDS[5] is the alignment safe to use, as a CONST_INT.
   OPERANDS[6] is another temporary register.  */

const char *
pa_output_block_move (rtx *operands, int size_is_constant ATTRIBUTE_UNUSED)
{
  int align = INTVAL (operands[5]);
  unsigned long n_bytes = INTVAL (operands[4]);

  /* We can't move more than a word at a time because the PA
     has no longer integer move insns.  (Could use fp mem ops?)  */
  if (align > (TARGET_64BIT ? 8 : 4))
    align = (TARGET_64BIT ? 8 : 4);

  /* Note that we know each loop below will execute at least twice
     (else we would have open-coded the copy).  */
  switch (align)
    {
      case 8:
	/* Pre-adjust the loop counter.  */
	operands[4] = GEN_INT (n_bytes - 16);
	output_asm_insn ("ldi %4,%2", operands);

	/* Copying loop.  */
	output_asm_insn ("ldd,ma 8(%1),%3", operands);
	output_asm_insn ("ldd,ma 8(%1),%6", operands);
	output_asm_insn ("std,ma %3,8(%0)", operands);
	output_asm_insn ("addib,>= -16,%2,.-12", operands);
	output_asm_insn ("std,ma %6,8(%0)", operands);

	/* Handle the residual.  There could be up to 7 bytes of
	   residual to copy!  */
	if (n_bytes % 16 != 0)
	  {
	    operands[4] = GEN_INT (n_bytes % 8);
	    if (n_bytes % 16 >= 8)
	      output_asm_insn ("ldd,ma 8(%1),%3", operands);
	    if (n_bytes % 8 != 0)
	      output_asm_insn ("ldd 0(%1),%6", operands);
	    if (n_bytes % 16 >= 8)
	      output_asm_insn ("std,ma %3,8(%0)", operands);
	    if (n_bytes % 8 != 0)
	      output_asm_insn ("stdby,e %6,%4(%0)", operands);
	  }
	return "";

      case 4:
	/* Pre-adjust the loop counter.  */
	operands[4] = GEN_INT (n_bytes - 8);
	output_asm_insn ("ldi %4,%2", operands);

	/* Copying loop.  */
	output_asm_insn ("{ldws|ldw},ma 4(%1),%3", operands);
	output_asm_insn ("{ldws|ldw},ma 4(%1),%6", operands);
	output_asm_insn ("{stws|stw},ma %3,4(%0)", operands);
	output_asm_insn ("addib,>= -8,%2,.-12", operands);
	output_asm_insn ("{stws|stw},ma %6,4(%0)", operands);

	/* Handle the residual.  There could be up to 7 bytes of
	   residual to copy!  */
	if (n_bytes % 8 != 0)
	  {
	    operands[4] = GEN_INT (n_bytes % 4);
	    if (n_bytes % 8 >= 4)
	      output_asm_insn ("{ldws|ldw},ma 4(%1),%3", operands);
	    if (n_bytes % 4 != 0)
	      output_asm_insn ("ldw 0(%1),%6", operands);
	    if (n_bytes % 8 >= 4)
	      output_asm_insn ("{stws|stw},ma %3,4(%0)", operands);
	    if (n_bytes % 4 != 0)
	      output_asm_insn ("{stbys|stby},e %6,%4(%0)", operands);
	  }
	return "";

      case 2:
	/* Pre-adjust the loop counter.  */
	operands[4] = GEN_INT (n_bytes - 4);
	output_asm_insn ("ldi %4,%2", operands);

	/* Copying loop.  */
	output_asm_insn ("{ldhs|ldh},ma 2(%1),%3", operands);
	output_asm_insn ("{ldhs|ldh},ma 2(%1),%6", operands);
	output_asm_insn ("{sths|sth},ma %3,2(%0)", operands);
	output_asm_insn ("addib,>= -4,%2,.-12", operands);
	output_asm_insn ("{sths|sth},ma %6,2(%0)", operands);

	/* Handle the residual.  */
	if (n_bytes % 4 != 0)
	  {
	    if (n_bytes % 4 >= 2)
	      output_asm_insn ("{ldhs|ldh},ma 2(%1),%3", operands);
	    if (n_bytes % 2 != 0)
	      output_asm_insn ("ldb 0(%1),%6", operands);
	    if (n_bytes % 4 >= 2)
	      output_asm_insn ("{sths|sth},ma %3,2(%0)", operands);
	    if (n_bytes % 2 != 0)
	      output_asm_insn ("stb %6,0(%0)", operands);
	  }
	return "";

      case 1:
	/* Pre-adjust the loop counter.  */
	operands[4] = GEN_INT (n_bytes - 2);
	output_asm_insn ("ldi %4,%2", operands);

	/* Copying loop.  */
	output_asm_insn ("{ldbs|ldb},ma 1(%1),%3", operands);
	output_asm_insn ("{ldbs|ldb},ma 1(%1),%6", operands);
	output_asm_insn ("{stbs|stb},ma %3,1(%0)", operands);
	output_asm_insn ("addib,>= -2,%2,.-12", operands);
	output_asm_insn ("{stbs|stb},ma %6,1(%0)", operands);

	/* Handle the residual.  */
	if (n_bytes % 2 != 0)
	  {
	    output_asm_insn ("ldb 0(%1),%3", operands);
	    output_asm_insn ("stb %3,0(%0)", operands);
	  }
	return "";

      default:
	gcc_unreachable ();
    }
}

/* Count the number of insns necessary to handle this block move.

   Basic structure is the same as emit_block_move, except that we
   count insns rather than emit them.  */

static int
compute_cpymem_length (rtx_insn *insn)
{
  rtx pat = PATTERN (insn);
  unsigned int align = INTVAL (XEXP (XVECEXP (pat, 0, 7), 0));
  unsigned long n_bytes = INTVAL (XEXP (XVECEXP (pat, 0, 6), 0));
  unsigned int n_insns = 0;

  /* We can't move more than four bytes at a time because the PA
     has no longer integer move insns.  (Could use fp mem ops?)  */
  if (align > (TARGET_64BIT ? 8 : 4))
    align = (TARGET_64BIT ? 8 : 4);

  /* The basic copying loop.  */
  n_insns = 6;

  /* Residuals.  */
  if (n_bytes % (2 * align) != 0)
    {
      if ((n_bytes % (2 * align)) >= align)
	n_insns += 2;

      if ((n_bytes % align) != 0)
	n_insns += 2;
    }

  /* Lengths are expressed in bytes now; each insn is 4 bytes.  */
  return n_insns * 4;
}

/* Emit code to perform a block clear.

   OPERANDS[0] is the destination pointer as a REG, clobbered.
   OPERANDS[1] is a register for temporary storage.
   OPERANDS[2] is the size as a CONST_INT
   OPERANDS[3] is the alignment safe to use, as a CONST_INT.  */

const char *
pa_output_block_clear (rtx *operands, int size_is_constant ATTRIBUTE_UNUSED)
{
  int align = INTVAL (operands[3]);
  unsigned long n_bytes = INTVAL (operands[2]);

  /* We can't clear more than a word at a time because the PA
     has no longer integer move insns.  */
  if (align > (TARGET_64BIT ? 8 : 4))
    align = (TARGET_64BIT ? 8 : 4);

  /* Note that we know each loop below will execute at least twice
     (else we would have open-coded the copy).  */
  switch (align)
    {
      case 8:
	/* Pre-adjust the loop counter.  */
	operands[2] = GEN_INT (n_bytes - 16);
	output_asm_insn ("ldi %2,%1", operands);

	/* Loop.  */
	output_asm_insn ("std,ma %%r0,8(%0)", operands);
	output_asm_insn ("addib,>= -16,%1,.-4", operands);
	output_asm_insn ("std,ma %%r0,8(%0)", operands);

	/* Handle the residual.  There could be up to 7 bytes of
	   residual to copy!  */
	if (n_bytes % 16 != 0)
	  {
	    operands[2] = GEN_INT (n_bytes % 8);
	    if (n_bytes % 16 >= 8)
	      output_asm_insn ("std,ma %%r0,8(%0)", operands);
	    if (n_bytes % 8 != 0)
	      output_asm_insn ("stdby,e %%r0,%2(%0)", operands);
	  }
	return "";

      case 4:
	/* Pre-adjust the loop counter.  */
	operands[2] = GEN_INT (n_bytes - 8);
	output_asm_insn ("ldi %2,%1", operands);

	/* Loop.  */
	output_asm_insn ("{stws|stw},ma %%r0,4(%0)", operands);
	output_asm_insn ("addib,>= -8,%1,.-4", operands);
	output_asm_insn ("{stws|stw},ma %%r0,4(%0)", operands);

	/* Handle the residual.  There could be up to 7 bytes of
	   residual to copy!  */
	if (n_bytes % 8 != 0)
	  {
	    operands[2] = GEN_INT (n_bytes % 4);
	    if (n_bytes % 8 >= 4)
	      output_asm_insn ("{stws|stw},ma %%r0,4(%0)", operands);
	    if (n_bytes % 4 != 0)
	      output_asm_insn ("{stbys|stby},e %%r0,%2(%0)", operands);
	  }
	return "";

      case 2:
	/* Pre-adjust the loop counter.  */
	operands[2] = GEN_INT (n_bytes - 4);
	output_asm_insn ("ldi %2,%1", operands);

	/* Loop.  */
	output_asm_insn ("{sths|sth},ma %%r0,2(%0)", operands);
	output_asm_insn ("addib,>= -4,%1,.-4", operands);
	output_asm_insn ("{sths|sth},ma %%r0,2(%0)", operands);

	/* Handle the residual.  */
	if (n_bytes % 4 != 0)
	  {
	    if (n_bytes % 4 >= 2)
	      output_asm_insn ("{sths|sth},ma %%r0,2(%0)", operands);
	    if (n_bytes % 2 != 0)
	      output_asm_insn ("stb %%r0,0(%0)", operands);
	  }
	return "";

      case 1:
	/* Pre-adjust the loop counter.  */
	operands[2] = GEN_INT (n_bytes - 2);
	output_asm_insn ("ldi %2,%1", operands);

	/* Loop.  */
	output_asm_insn ("{stbs|stb},ma %%r0,1(%0)", operands);
	output_asm_insn ("addib,>= -2,%1,.-4", operands);
	output_asm_insn ("{stbs|stb},ma %%r0,1(%0)", operands);

	/* Handle the residual.  */
	if (n_bytes % 2 != 0)
	  output_asm_insn ("stb %%r0,0(%0)", operands);

	return "";

      default:
	gcc_unreachable ();
    }
}

/* Count the number of insns necessary to handle this block move.

   Basic structure is the same as emit_block_move, except that we
   count insns rather than emit them.  */

static int
compute_clrmem_length (rtx_insn *insn)
{
  rtx pat = PATTERN (insn);
  unsigned int align = INTVAL (XEXP (XVECEXP (pat, 0, 4), 0));
  unsigned long n_bytes = INTVAL (XEXP (XVECEXP (pat, 0, 3), 0));
  unsigned int n_insns = 0;

  /* We can't clear more than a word at a time because the PA
     has no longer integer move insns.  */
  if (align > (TARGET_64BIT ? 8 : 4))
    align = (TARGET_64BIT ? 8 : 4);

  /* The basic loop.  */
  n_insns = 4;

  /* Residuals.  */
  if (n_bytes % (2 * align) != 0)
    {
      if ((n_bytes % (2 * align)) >= align)
	n_insns++;

      if ((n_bytes % align) != 0)
	n_insns++;
    }

  /* Lengths are expressed in bytes now; each insn is 4 bytes.  */
  return n_insns * 4;
}


const char *
pa_output_and (rtx *operands)
{
  if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) != 0)
    {
      unsigned HOST_WIDE_INT mask = INTVAL (operands[2]);
      int ls0, ls1, ms0, p, len;

      for (ls0 = 0; ls0 < 32; ls0++)
	if ((mask & (1 << ls0)) == 0)
	  break;

      for (ls1 = ls0; ls1 < 32; ls1++)
	if ((mask & (1 << ls1)) != 0)
	  break;

      for (ms0 = ls1; ms0 < 32; ms0++)
	if ((mask & (1 << ms0)) == 0)
	  break;

      gcc_assert (ms0 == 32);

      if (ls1 == 32)
	{
	  len = ls0;

	  gcc_assert (len);

	  operands[2] = GEN_INT (len);
	  return "{extru|extrw,u} %1,31,%2,%0";
	}
      else
	{
	  /* We could use this `depi' for the case above as well, but `depi'
	     requires one more register file access than an `extru'.  */

	  p = 31 - ls0;
	  len = ls1 - ls0;

	  operands[2] = GEN_INT (p);
	  operands[3] = GEN_INT (len);
	  return "{depi|depwi} 0,%2,%3,%0";
	}
    }
  else
    return "and %1,%2,%0";
}

/* Return a string to perform a bitwise-and of operands[1] with operands[2]
   storing the result in operands[0].  */
const char *
pa_output_64bit_and (rtx *operands)
{
  if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) != 0)
    {
      unsigned HOST_WIDE_INT mask = INTVAL (operands[2]);
      int ls0, ls1, ms0, p, len;

      for (ls0 = 0; ls0 < HOST_BITS_PER_WIDE_INT; ls0++)
	if ((mask & ((unsigned HOST_WIDE_INT) 1 << ls0)) == 0)
	  break;

      for (ls1 = ls0; ls1 < HOST_BITS_PER_WIDE_INT; ls1++)
	if ((mask & ((unsigned HOST_WIDE_INT) 1 << ls1)) != 0)
	  break;

      for (ms0 = ls1; ms0 < HOST_BITS_PER_WIDE_INT; ms0++)
	if ((mask & ((unsigned HOST_WIDE_INT) 1 << ms0)) == 0)
	  break;

      gcc_assert (ms0 == HOST_BITS_PER_WIDE_INT);

      if (ls1 == HOST_BITS_PER_WIDE_INT)
	{
	  len = ls0;

	  gcc_assert (len);

	  operands[2] = GEN_INT (len);
	  return "extrd,u %1,63,%2,%0";
	}
      else
	{
	  /* We could use this `depi' for the case above as well, but `depi'
	     requires one more register file access than an `extru'.  */

	  p = 63 - ls0;
	  len = ls1 - ls0;

	  operands[2] = GEN_INT (p);
	  operands[3] = GEN_INT (len);
	  return "depdi 0,%2,%3,%0";
	}
    }
  else
    return "and %1,%2,%0";
}

const char *
pa_output_ior (rtx *operands)
{
  unsigned HOST_WIDE_INT mask = INTVAL (operands[2]);
  int bs0, bs1, p, len;

  if (INTVAL (operands[2]) == 0)
    return "copy %1,%0";

  for (bs0 = 0; bs0 < 32; bs0++)
    if ((mask & (1 << bs0)) != 0)
      break;

  for (bs1 = bs0; bs1 < 32; bs1++)
    if ((mask & (1 << bs1)) == 0)
      break;

  gcc_assert (bs1 == 32 || ((unsigned HOST_WIDE_INT) 1 << bs1) > mask);

  p = 31 - bs0;
  len = bs1 - bs0;

  operands[2] = GEN_INT (p);
  operands[3] = GEN_INT (len);
  return "{depi|depwi} -1,%2,%3,%0";
}

/* Return a string to perform a bitwise-and of operands[1] with operands[2]
   storing the result in operands[0].  */
const char *
pa_output_64bit_ior (rtx *operands)
{
  unsigned HOST_WIDE_INT mask = INTVAL (operands[2]);
  int bs0, bs1, p, len;

  if (INTVAL (operands[2]) == 0)
    return "copy %1,%0";

  for (bs0 = 0; bs0 < HOST_BITS_PER_WIDE_INT; bs0++)
    if ((mask & ((unsigned HOST_WIDE_INT) 1 << bs0)) != 0)
      break;

  for (bs1 = bs0; bs1 < HOST_BITS_PER_WIDE_INT; bs1++)
    if ((mask & ((unsigned HOST_WIDE_INT) 1 << bs1)) == 0)
      break;

  gcc_assert (bs1 == HOST_BITS_PER_WIDE_INT
	      || ((unsigned HOST_WIDE_INT) 1 << bs1) > mask);

  p = 63 - bs0;
  len = bs1 - bs0;

  operands[2] = GEN_INT (p);
  operands[3] = GEN_INT (len);
  return "depdi -1,%2,%3,%0";
}

/* Target hook for assembling integer objects.  This code handles
   aligned SI and DI integers specially since function references
   must be preceded by P%.  */

static bool
pa_assemble_integer (rtx x, unsigned int size, int aligned_p)
{
  bool result;
  tree decl = NULL;

  /* When we have a SYMBOL_REF with a SYMBOL_REF_DECL, we need to call
     call assemble_external and set the SYMBOL_REF_DECL to NULL before
     calling output_addr_const.  Otherwise, it may call assemble_external
     in the midst of outputing the assembler code for the SYMBOL_REF.
     We restore the SYMBOL_REF_DECL after the output is done.  */
  if (GET_CODE (x) == SYMBOL_REF)
    {
      decl = SYMBOL_REF_DECL (x);
      if (decl)
	{
	  assemble_external (decl);
	  SET_SYMBOL_REF_DECL (x, NULL);
	}
    }

  if (size == UNITS_PER_WORD
      && aligned_p
      && function_label_operand (x, VOIDmode))
    {
      fputs (size == 8? "\t.dword\t" : "\t.word\t", asm_out_file);

      /* We don't want an OPD when generating fast indirect calls.  */
      if (!TARGET_FAST_INDIRECT_CALLS)
	fputs ("P%", asm_out_file);

      output_addr_const (asm_out_file, x);
      fputc ('\n', asm_out_file);
      result = true;
    }
  else
    result = default_assemble_integer (x, size, aligned_p);

  if (decl)
    SET_SYMBOL_REF_DECL (x, decl);

  return result;
}

/* Output an ascii string.  */
void
pa_output_ascii (FILE *file, const char *p, int size)
{
  int i;
  int chars_output;
  unsigned char partial_output[16];	/* Max space 4 chars can occupy.  */

  /* The HP assembler can only take strings of 256 characters at one
     time.  This is a limitation on input line length, *not* the
     length of the string.  Sigh.  Even worse, it seems that the
     restriction is in number of input characters (see \xnn &
     \whatever).  So we have to do this very carefully.  */

  fputs ("\t.STRING \"", file);

  chars_output = 0;
  for (i = 0; i < size; i += 4)
    {
      int co = 0;
      int io = 0;
      for (io = 0, co = 0; io < MIN (4, size - i); io++)
	{
	  unsigned int c = (unsigned char) p[i + io];

	  if (c == '\"' || c == '\\')
	    partial_output[co++] = '\\';
	  if (c >= ' ' && c < 0177)
	    partial_output[co++] = c;
	  else
	    {
	      unsigned int hexd;
	      partial_output[co++] = '\\';
	      partial_output[co++] = 'x';
	      hexd =  c  / 16 - 0 + '0';
	      if (hexd > '9')
		hexd -= '9' - 'a' + 1;
	      partial_output[co++] = hexd;
	      hexd =  c % 16 - 0 + '0';
	      if (hexd > '9')
		hexd -= '9' - 'a' + 1;
	      partial_output[co++] = hexd;
	    }
	}
      if (chars_output + co > 243)
	{
	  fputs ("\"\n\t.STRING \"", file);
	  chars_output = 0;
	}
      fwrite (partial_output, 1, (size_t) co, file);
      chars_output += co;
      co = 0;
    }
  fputs ("\"\n", file);
}

/* Try to rewrite floating point comparisons & branches to avoid
   useless add,tr insns.

   CHECK_NOTES is nonzero if we should examine REG_DEAD notes
   to see if FPCC is dead.  CHECK_NOTES is nonzero for the
   first attempt to remove useless add,tr insns.  It is zero
   for the second pass as reorg sometimes leaves bogus REG_DEAD
   notes lying around.

   When CHECK_NOTES is zero we can only eliminate add,tr insns
   when there's a 1:1 correspondence between fcmp and ftest/fbranch
   instructions.  */
static void
remove_useless_addtr_insns (int check_notes)
{
  rtx_insn *insn;
  static int pass = 0;

  /* This is fairly cheap, so always run it when optimizing.  */
  if (optimize > 0)
    {
      int fcmp_count = 0;
      int fbranch_count = 0;

      /* Walk all the insns in this function looking for fcmp & fbranch
	 instructions.  Keep track of how many of each we find.  */
      for (insn = get_insns (); insn; insn = next_insn (insn))
	{
	  rtx tmp;

	  /* Ignore anything that isn't an INSN or a JUMP_INSN.  */
	  if (! NONJUMP_INSN_P (insn) && ! JUMP_P (insn))
	    continue;

	  tmp = PATTERN (insn);

	  /* It must be a set.  */
	  if (GET_CODE (tmp) != SET)
	    continue;

	  /* If the destination is CCFP, then we've found an fcmp insn.  */
	  tmp = SET_DEST (tmp);
	  if (GET_CODE (tmp) == REG && REGNO (tmp) == 0)
	    {
	      fcmp_count++;
	      continue;
	    }

	  tmp = PATTERN (insn);
	  /* If this is an fbranch instruction, bump the fbranch counter.  */
	  if (GET_CODE (tmp) == SET
	      && SET_DEST (tmp) == pc_rtx
	      && GET_CODE (SET_SRC (tmp)) == IF_THEN_ELSE
	      && GET_CODE (XEXP (SET_SRC (tmp), 0)) == NE
	      && GET_CODE (XEXP (XEXP (SET_SRC (tmp), 0), 0)) == REG
	      && REGNO (XEXP (XEXP (SET_SRC (tmp), 0), 0)) == 0)
	    {
	      fbranch_count++;
	      continue;
	    }
	}


      /* Find all floating point compare + branch insns.  If possible,
	 reverse the comparison & the branch to avoid add,tr insns.  */
      for (insn = get_insns (); insn; insn = next_insn (insn))
	{
	  rtx tmp;
	  rtx_insn *next;

	  /* Ignore anything that isn't an INSN.  */
	  if (! NONJUMP_INSN_P (insn))
	    continue;

	  tmp = PATTERN (insn);

	  /* It must be a set.  */
	  if (GET_CODE (tmp) != SET)
	    continue;

	  /* The destination must be CCFP, which is register zero.  */
	  tmp = SET_DEST (tmp);
	  if (GET_CODE (tmp) != REG || REGNO (tmp) != 0)
	    continue;

	  /* INSN should be a set of CCFP.

	     See if the result of this insn is used in a reversed FP
	     conditional branch.  If so, reverse our condition and
	     the branch.  Doing so avoids useless add,tr insns.  */
	  next = next_insn (insn);
	  while (next)
	    {
	      /* Jumps, calls and labels stop our search.  */
	      if (JUMP_P (next) || CALL_P (next) || LABEL_P (next))
		break;

	      /* As does another fcmp insn.  */
	      if (NONJUMP_INSN_P (next)
		  && GET_CODE (PATTERN (next)) == SET
		  && GET_CODE (SET_DEST (PATTERN (next))) == REG
		  && REGNO (SET_DEST (PATTERN (next))) == 0)
		break;

	      next = next_insn (next);
	    }

	  /* Is NEXT_INSN a branch?  */
	  if (next && JUMP_P (next))
	    {
	      rtx pattern = PATTERN (next);

	      /* If it a reversed fp conditional branch (e.g. uses add,tr)
		 and CCFP dies, then reverse our conditional and the branch
		 to avoid the add,tr.  */
	      if (GET_CODE (pattern) == SET
		  && SET_DEST (pattern) == pc_rtx
		  && GET_CODE (SET_SRC (pattern)) == IF_THEN_ELSE
		  && GET_CODE (XEXP (SET_SRC (pattern), 0)) == NE
		  && GET_CODE (XEXP (XEXP (SET_SRC (pattern), 0), 0)) == REG
		  && REGNO (XEXP (XEXP (SET_SRC (pattern), 0), 0)) == 0
		  && GET_CODE (XEXP (SET_SRC (pattern), 1)) == PC
		  && (fcmp_count == fbranch_count
		      || (check_notes
			  && find_regno_note (next, REG_DEAD, 0))))
		{
		  /* Reverse the branch.  */
		  tmp = XEXP (SET_SRC (pattern), 1);
		  XEXP (SET_SRC (pattern), 1) = XEXP (SET_SRC (pattern), 2);
		  XEXP (SET_SRC (pattern), 2) = tmp;
		  INSN_CODE (next) = -1;

		  /* Reverse our condition.  */
		  tmp = PATTERN (insn);
		  PUT_CODE (XEXP (tmp, 1),
			    (reverse_condition_maybe_unordered
			     (GET_CODE (XEXP (tmp, 1)))));
		}
	    }
	}
    }

  pass = !pass;

}

/* You may have trouble believing this, but this is the 32 bit HP-PA
   stack layout.  Wow.

   Offset		Contents

   Variable arguments	(optional; any number may be allocated)

   SP-(4*(N+9))		arg word N
   	:		    :
      SP-56		arg word 5
      SP-52		arg word 4

   Fixed arguments	(must be allocated; may remain unused)

      SP-48		arg word 3
      SP-44		arg word 2
      SP-40		arg word 1
      SP-36		arg word 0

   Frame Marker

      SP-32		External Data Pointer (DP)
      SP-28		External sr4
      SP-24		External/stub RP (RP')
      SP-20		Current RP
      SP-16		Static Link
      SP-12		Clean up
      SP-8		Calling Stub RP (RP'')
      SP-4		Previous SP

   Top of Frame

      SP-0		Stack Pointer (points to next available address)

*/

/* This function saves registers as follows.  Registers marked with ' are
   this function's registers (as opposed to the previous function's).
   If a frame_pointer isn't needed, r4 is saved as a general register;
   the space for the frame pointer is still allocated, though, to keep
   things simple.


   Top of Frame

       SP (FP')		Previous FP
       SP + 4		Alignment filler (sigh)
       SP + 8		Space for locals reserved here.
       .
       .
       .
       SP + n		All call saved register used.
       .
       .
       .
       SP + o		All call saved fp registers used.
       .
       .
       .
       SP + p (SP')	points to next available address.

*/

/* Global variables set by output_function_prologue().  */
/* Size of frame.  Need to know this to emit return insns from
   leaf procedures.  */
static HOST_WIDE_INT actual_fsize, local_fsize;
static int save_fregs;

/* Emit RTL to store REG at the memory location specified by BASE+DISP.
   Handle case where DISP > 8k by using the add_high_const patterns.

   Note in DISP > 8k case, we will leave the high part of the address
   in %r1.  There is code in expand_hppa_{prologue,epilogue} that knows this.*/

static void
store_reg (int reg, HOST_WIDE_INT disp, int base)
{
  rtx dest, src, basereg;
  rtx_insn *insn;

  src = gen_rtx_REG (word_mode, reg);
  basereg = gen_rtx_REG (Pmode, base);
  if (VAL_14_BITS_P (disp))
    {
      dest = gen_rtx_MEM (word_mode, plus_constant (Pmode, basereg, disp));
      insn = emit_move_insn (dest, src);
    }
  else if (TARGET_64BIT && !VAL_32_BITS_P (disp))
    {
      rtx delta = GEN_INT (disp);
      rtx tmpreg = gen_rtx_REG (Pmode, 1);

      emit_move_insn (tmpreg, delta);
      insn = emit_move_insn (tmpreg, gen_rtx_PLUS (Pmode, tmpreg, basereg));
      if (DO_FRAME_NOTES)
	{
	  add_reg_note (insn, REG_FRAME_RELATED_EXPR,
			gen_rtx_SET (tmpreg,
				     gen_rtx_PLUS (Pmode, basereg, delta)));
	  RTX_FRAME_RELATED_P (insn) = 1;
	}
      dest = gen_rtx_MEM (word_mode, tmpreg);
      insn = emit_move_insn (dest, src);
    }
  else
    {
      rtx delta = GEN_INT (disp);
      rtx high = gen_rtx_PLUS (Pmode, basereg, gen_rtx_HIGH (Pmode, delta));
      rtx tmpreg = gen_rtx_REG (Pmode, 1);

      emit_move_insn (tmpreg, high);
      dest = gen_rtx_MEM (word_mode, gen_rtx_LO_SUM (Pmode, tmpreg, delta));
      insn = emit_move_insn (dest, src);
      if (DO_FRAME_NOTES)
	add_reg_note (insn, REG_FRAME_RELATED_EXPR,
		      gen_rtx_SET (gen_rtx_MEM (word_mode,
						gen_rtx_PLUS (word_mode,
							      basereg,
							      delta)),
				   src));
    }

  if (DO_FRAME_NOTES)
    RTX_FRAME_RELATED_P (insn) = 1;
}

/* Emit RTL to store REG at the memory location specified by BASE and then
   add MOD to BASE.  MOD must be <= 8k.  */

static void
store_reg_modify (int base, int reg, HOST_WIDE_INT mod)
{
  rtx basereg, srcreg, delta;
  rtx_insn *insn;

  gcc_assert (VAL_14_BITS_P (mod));

  basereg = gen_rtx_REG (Pmode, base);
  srcreg = gen_rtx_REG (word_mode, reg);
  delta = GEN_INT (mod);

  insn = emit_insn (gen_post_store (basereg, srcreg, delta));
  if (DO_FRAME_NOTES)
    {
      RTX_FRAME_RELATED_P (insn) = 1;

      /* RTX_FRAME_RELATED_P must be set on each frame related set
	 in a parallel with more than one element.  */
      RTX_FRAME_RELATED_P (XVECEXP (PATTERN (insn), 0, 0)) = 1;
      RTX_FRAME_RELATED_P (XVECEXP (PATTERN (insn), 0, 1)) = 1;
    }
}

/* Emit RTL to set REG to the value specified by BASE+DISP.  Handle case
   where DISP > 8k by using the add_high_const patterns.  NOTE indicates
   whether to add a frame note or not.

   In the DISP > 8k case, we leave the high part of the address in %r1.
   There is code in expand_hppa_{prologue,epilogue} that knows about this.  */

static void
set_reg_plus_d (int reg, int base, HOST_WIDE_INT disp, int note)
{
  rtx_insn *insn;

  if (VAL_14_BITS_P (disp))
    {
      insn = emit_move_insn (gen_rtx_REG (Pmode, reg),
			     plus_constant (Pmode,
					    gen_rtx_REG (Pmode, base), disp));
    }
  else if (TARGET_64BIT && !VAL_32_BITS_P (disp))
    {
      rtx basereg = gen_rtx_REG (Pmode, base);
      rtx delta = GEN_INT (disp);
      rtx tmpreg = gen_rtx_REG (Pmode, 1);

      emit_move_insn (tmpreg, delta);
      insn = emit_move_insn (gen_rtx_REG (Pmode, reg),
			     gen_rtx_PLUS (Pmode, tmpreg, basereg));
      if (DO_FRAME_NOTES)
	add_reg_note (insn, REG_FRAME_RELATED_EXPR,
		      gen_rtx_SET (tmpreg,
				   gen_rtx_PLUS (Pmode, basereg, delta)));
    }
  else
    {
      rtx basereg = gen_rtx_REG (Pmode, base);
      rtx delta = GEN_INT (disp);
      rtx tmpreg = gen_rtx_REG (Pmode, 1);

      emit_move_insn (tmpreg,
		      gen_rtx_PLUS (Pmode, basereg,
				    gen_rtx_HIGH (Pmode, delta)));
      insn = emit_move_insn (gen_rtx_REG (Pmode, reg),
			     gen_rtx_LO_SUM (Pmode, tmpreg, delta));
    }

  if (DO_FRAME_NOTES && note)
    RTX_FRAME_RELATED_P (insn) = 1;
}

HOST_WIDE_INT
pa_compute_frame_size (poly_int64 size, int *fregs_live)
{
  int freg_saved = 0;
  int i, j;

  /* The code in pa_expand_prologue and pa_expand_epilogue must
     be consistent with the rounding and size calculation done here.
     Change them at the same time.  */

  /* We do our own stack alignment.  First, round the size of the
     stack locals up to a word boundary.  */
  size = (size + UNITS_PER_WORD - 1) & ~(UNITS_PER_WORD - 1);

  /* Space for previous frame pointer + filler.  If any frame is
     allocated, we need to add in the TARGET_STARTING_FRAME_OFFSET.  We
     waste some space here for the sake of HP compatibility.  The
     first slot is only used when the frame pointer is needed.  */
  if (size || frame_pointer_needed)
    size += pa_starting_frame_offset ();
  
  /* If the current function calls __builtin_eh_return, then we need
     to allocate stack space for registers that will hold data for
     the exception handler.  */
  if (DO_FRAME_NOTES && crtl->calls_eh_return)
    {
      unsigned int i;

      for (i = 0; EH_RETURN_DATA_REGNO (i) != INVALID_REGNUM; ++i)
	continue;
      size += i * UNITS_PER_WORD;
    }

  /* Account for space used by the callee general register saves.  */
  for (i = 18, j = frame_pointer_needed ? 4 : 3; i >= j; i--)
    if (df_regs_ever_live_p (i))
      size += UNITS_PER_WORD;

  /* Account for space used by the callee floating point register saves.  */
  for (i = FP_SAVED_REG_LAST; i >= FP_SAVED_REG_FIRST; i -= FP_REG_STEP)
    if (df_regs_ever_live_p (i)
	|| (!TARGET_64BIT && df_regs_ever_live_p (i + 1)))
      {
	freg_saved = 1;

	/* We always save both halves of the FP register, so always
	   increment the frame size by 8 bytes.  */
	size += 8;
      }

  /* If any of the floating registers are saved, account for the
     alignment needed for the floating point register save block.  */
  if (freg_saved)
    {
      size = (size + 7) & ~7;
      if (fregs_live)
	*fregs_live = 1;
    }

  /* The various ABIs include space for the outgoing parameters in the
     size of the current function's stack frame.  We don't need to align
     for the outgoing arguments as their alignment is set by the final
     rounding for the frame as a whole.  */
  size += crtl->outgoing_args_size;

  /* Allocate space for the fixed frame marker.  This space must be
     allocated for any function that makes calls or allocates
     stack space.  */
  if (!crtl->is_leaf || size)
    size += TARGET_64BIT ? 48 : 32;

  /* Finally, round to the preferred stack boundary.  */
  return ((size + PREFERRED_STACK_BOUNDARY / BITS_PER_UNIT - 1)
	  & ~(PREFERRED_STACK_BOUNDARY / BITS_PER_UNIT - 1));
}

/* Output function label, and associated .PROC and .CALLINFO statements.  */

void
pa_output_function_label (FILE *file)
{
  /* The function's label and associated .PROC must never be
     separated and must be output *after* any profiling declarations
     to avoid changing spaces/subspaces within a procedure.  */
  ASM_OUTPUT_LABEL (file, XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0));
  fputs ("\t.PROC\n", file);

  /* pa_expand_prologue does the dirty work now.  We just need
     to output the assembler directives which denote the start
     of a function.  */
  fprintf (file, "\t.CALLINFO FRAME=" HOST_WIDE_INT_PRINT_DEC, actual_fsize);
  if (crtl->is_leaf)
    fputs (",NO_CALLS", file);
  else
    fputs (",CALLS", file);
  if (rp_saved)
    fputs (",SAVE_RP", file);

  /* The SAVE_SP flag is used to indicate that register %r3 is stored
     at the beginning of the frame and that it is used as the frame
     pointer for the frame.  We do this because our current frame
     layout doesn't conform to that specified in the HP runtime
     documentation and we need a way to indicate to programs such as
     GDB where %r3 is saved.  The SAVE_SP flag was chosen because it
     isn't used by HP compilers but is supported by the assembler.
     However, SAVE_SP is supposed to indicate that the previous stack
     pointer has been saved in the frame marker.  */
  if (frame_pointer_needed)
    fputs (",SAVE_SP", file);

  /* Pass on information about the number of callee register saves
     performed in the prologue.

     The compiler is supposed to pass the highest register number
     saved, the assembler then has to adjust that number before
     entering it into the unwind descriptor (to account for any
     caller saved registers with lower register numbers than the
     first callee saved register).  */
  if (gr_saved)
    fprintf (file, ",ENTRY_GR=%d", gr_saved + 2);

  if (fr_saved)
    fprintf (file, ",ENTRY_FR=%d", fr_saved + 11);

  fputs ("\n\t.ENTRY\n", file);
}

/* Output function prologue.  */

static void
pa_output_function_prologue (FILE *file)
{
  pa_output_function_label (file);
  remove_useless_addtr_insns (0);
}

/* The label is output by ASM_DECLARE_FUNCTION_NAME on linux.  */

static void
pa_linux_output_function_prologue (FILE *file ATTRIBUTE_UNUSED)
{
  remove_useless_addtr_insns (0);
}

void
pa_expand_prologue (void)
{
  int merge_sp_adjust_with_store = 0;
  HOST_WIDE_INT size = get_frame_size ();
  HOST_WIDE_INT offset;
  int i;
  rtx tmpreg;
  rtx_insn *insn;

  gr_saved = 0;
  fr_saved = 0;
  save_fregs = 0;

  /* Compute total size for frame pointer, filler, locals and rounding to
     the next word boundary.  Similar code appears in pa_compute_frame_size
     and must be changed in tandem with this code.  */
  local_fsize = (size + UNITS_PER_WORD - 1) & ~(UNITS_PER_WORD - 1);
  if (local_fsize || frame_pointer_needed)
    local_fsize += pa_starting_frame_offset ();

  actual_fsize = pa_compute_frame_size (size, &save_fregs);
  if (flag_stack_usage_info)
    current_function_static_stack_size = actual_fsize;

  /* Compute a few things we will use often.  */
  tmpreg = gen_rtx_REG (word_mode, 1);

  /* Save RP first.  The calling conventions manual states RP will
     always be stored into the caller's frame at sp - 20 or sp - 16
     depending on which ABI is in use.  */
  if (df_regs_ever_live_p (2) || crtl->calls_eh_return)
    {
      store_reg (2, TARGET_64BIT ? -16 : -20, STACK_POINTER_REGNUM);
      rp_saved = true;
    }
  else
    rp_saved = false;

  /* Allocate the local frame and set up the frame pointer if needed.  */
  if (actual_fsize != 0)
    {
      if (frame_pointer_needed)
	{
	  /* Copy the old frame pointer temporarily into %r1.  Set up the
	     new stack pointer, then store away the saved old frame pointer
	     into the stack at sp and at the same time update the stack
	     pointer by actual_fsize bytes.  Two versions, first
	     handles small (<8k) frames.  The second handles large (>=8k)
	     frames.  */
	  insn = emit_move_insn (tmpreg, hard_frame_pointer_rtx);
	  if (DO_FRAME_NOTES)
	    RTX_FRAME_RELATED_P (insn) = 1;

	  insn = emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx);
	  if (DO_FRAME_NOTES)
	    RTX_FRAME_RELATED_P (insn) = 1;

	  if (VAL_14_BITS_P (actual_fsize))
	    store_reg_modify (STACK_POINTER_REGNUM, 1, actual_fsize);
	  else
	    {
	      /* It is incorrect to store the saved frame pointer at *sp,
		 then increment sp (writes beyond the current stack boundary).

		 So instead use stwm to store at *sp and post-increment the
		 stack pointer as an atomic operation.  Then increment sp to
		 finish allocating the new frame.  */
	      HOST_WIDE_INT adjust1 = 8192 - 64;
	      HOST_WIDE_INT adjust2 = actual_fsize - adjust1;

	      store_reg_modify (STACK_POINTER_REGNUM, 1, adjust1);
	      set_reg_plus_d (STACK_POINTER_REGNUM, STACK_POINTER_REGNUM,
			      adjust2, 1);
	    }

	  /* We set SAVE_SP in frames that need a frame pointer.  Thus,
	     we need to store the previous stack pointer (frame pointer)
	     into the frame marker on targets that use the HP unwind
	     library.  This allows the HP unwind library to be used to
	     unwind GCC frames.  However, we are not fully compatible
	     with the HP library because our frame layout differs from
	     that specified in the HP runtime specification.

	     We don't want a frame note on this instruction as the frame
	     marker moves during dynamic stack allocation.

	     This instruction also serves as a blockage to prevent
	     register spills from being scheduled before the stack
	     pointer is raised.  This is necessary as we store
	     registers using the frame pointer as a base register,
	     and the frame pointer is set before sp is raised.  */
	  if (TARGET_HPUX_UNWIND_LIBRARY)
	    {
	      rtx addr = gen_rtx_PLUS (word_mode, stack_pointer_rtx,
				       GEN_INT (TARGET_64BIT ? -8 : -4));

	      emit_move_insn (gen_rtx_MEM (word_mode, addr),
			      hard_frame_pointer_rtx);
	    }
	  else
	    emit_insn (gen_blockage ());
	}
      /* no frame pointer needed.  */
      else
	{
	  /* In some cases we can perform the first callee register save
	     and allocating the stack frame at the same time.   If so, just
	     make a note of it and defer allocating the frame until saving
	     the callee registers.  */
	  if (VAL_14_BITS_P (actual_fsize) && local_fsize == 0)
	    merge_sp_adjust_with_store = 1;
	  /* Cannot optimize.  Adjust the stack frame by actual_fsize
	     bytes.  */
	  else
	    set_reg_plus_d (STACK_POINTER_REGNUM, STACK_POINTER_REGNUM,
			    actual_fsize, 1);
	}
    }

  /* Normal register save.

     Do not save the frame pointer in the frame_pointer_needed case.  It
     was done earlier.  */
  if (frame_pointer_needed)
    {
      offset = local_fsize;

      /* Saving the EH return data registers in the frame is the simplest
	 way to get the frame unwind information emitted.  We put them
	 just before the general registers.  */
      if (DO_FRAME_NOTES && crtl->calls_eh_return)
	{
	  unsigned int i, regno;

	  for (i = 0; ; ++i)
	    {
	      regno = EH_RETURN_DATA_REGNO (i);
	      if (regno == INVALID_REGNUM)
		break;

	      store_reg (regno, offset, HARD_FRAME_POINTER_REGNUM);
	      offset += UNITS_PER_WORD;
	    }
	}

      for (i = 18; i >= 4; i--)
	if (df_regs_ever_live_p (i) && !call_used_or_fixed_reg_p (i))
	  {
	    store_reg (i, offset, HARD_FRAME_POINTER_REGNUM);
	    offset += UNITS_PER_WORD;
	    gr_saved++;
	  }
      /* Account for %r3 which is saved in a special place.  */
      gr_saved++;
    }
  /* No frame pointer needed.  */
  else
    {
      offset = local_fsize - actual_fsize;

      /* Saving the EH return data registers in the frame is the simplest
         way to get the frame unwind information emitted.  */
      if (DO_FRAME_NOTES && crtl->calls_eh_return)
	{
	  unsigned int i, regno;

	  for (i = 0; ; ++i)
	    {
	      regno = EH_RETURN_DATA_REGNO (i);
	      if (regno == INVALID_REGNUM)
		break;

	      /* If merge_sp_adjust_with_store is nonzero, then we can
		 optimize the first save.  */
	      if (merge_sp_adjust_with_store)
		{
		  store_reg_modify (STACK_POINTER_REGNUM, regno, -offset);
		  merge_sp_adjust_with_store = 0;
		}
	      else
		store_reg (regno, offset, STACK_POINTER_REGNUM);
	      offset += UNITS_PER_WORD;
	    }
	}

      for (i = 18; i >= 3; i--)
	if (df_regs_ever_live_p (i) && !call_used_or_fixed_reg_p (i))
	  {
	    /* If merge_sp_adjust_with_store is nonzero, then we can
	       optimize the first GR save.  */
	    if (merge_sp_adjust_with_store)
	      {
		store_reg_modify (STACK_POINTER_REGNUM, i, -offset);
		merge_sp_adjust_with_store = 0;
	      }
	    else
	      store_reg (i, offset, STACK_POINTER_REGNUM);
	    offset += UNITS_PER_WORD;
	    gr_saved++;
	  }

      /* If we wanted to merge the SP adjustment with a GR save, but we never
	 did any GR saves, then just emit the adjustment here.  */
      if (merge_sp_adjust_with_store)
	set_reg_plus_d (STACK_POINTER_REGNUM, STACK_POINTER_REGNUM,
			actual_fsize, 1);
    }

  /* The hppa calling conventions say that %r19, the pic offset
     register, is saved at sp - 32 (in this function's frame)
     when generating PIC code.  FIXME:  What is the correct thing
     to do for functions which make no calls and allocate no
     frame?  Do we need to allocate a frame, or can we just omit
     the save?   For now we'll just omit the save.
     
     We don't want a note on this insn as the frame marker can
     move if there is a dynamic stack allocation.  */
  if (flag_pic && actual_fsize != 0 && !TARGET_64BIT)
    {
      rtx addr = gen_rtx_PLUS (word_mode, stack_pointer_rtx, GEN_INT (-32));

      emit_move_insn (gen_rtx_MEM (word_mode, addr), pic_offset_table_rtx);

    }

  /* Align pointer properly (doubleword boundary).  */
  offset = (offset + 7) & ~7;

  /* Floating point register store.  */
  if (save_fregs)
    {
      rtx base;

      /* First get the frame or stack pointer to the start of the FP register
	 save area.  */
      if (frame_pointer_needed)
	{
	  set_reg_plus_d (1, HARD_FRAME_POINTER_REGNUM, offset, 0);
	  base = hard_frame_pointer_rtx;
	}
      else
	{
	  set_reg_plus_d (1, STACK_POINTER_REGNUM, offset, 0);
	  base = stack_pointer_rtx;
	}

      /* Now actually save the FP registers.  */
      for (i = FP_SAVED_REG_LAST; i >= FP_SAVED_REG_FIRST; i -= FP_REG_STEP)
	{
	  if (df_regs_ever_live_p (i)
	      || (! TARGET_64BIT && df_regs_ever_live_p (i + 1)))
	    {
	      rtx addr, reg;
	      rtx_insn *insn;
	      addr = gen_rtx_MEM (DFmode,
				  gen_rtx_POST_INC (word_mode, tmpreg));
	      reg = gen_rtx_REG (DFmode, i);
	      insn = emit_move_insn (addr, reg);
	      if (DO_FRAME_NOTES)
		{
		  RTX_FRAME_RELATED_P (insn) = 1;
		  if (TARGET_64BIT)
		    {
		      rtx mem = gen_rtx_MEM (DFmode,
					     plus_constant (Pmode, base,
							    offset));
		      add_reg_note (insn, REG_FRAME_RELATED_EXPR,
				    gen_rtx_SET (mem, reg));
		    }
		  else
		    {
		      rtx meml = gen_rtx_MEM (SFmode,
					      plus_constant (Pmode, base,
							     offset));
		      rtx memr = gen_rtx_MEM (SFmode,
					      plus_constant (Pmode, base,
							     offset + 4));
		      rtx regl = gen_rtx_REG (SFmode, i);
		      rtx regr = gen_rtx_REG (SFmode, i + 1);
		      rtx setl = gen_rtx_SET (meml, regl);
		      rtx setr = gen_rtx_SET (memr, regr);
		      rtvec vec;

		      RTX_FRAME_RELATED_P (setl) = 1;
		      RTX_FRAME_RELATED_P (setr) = 1;
		      vec = gen_rtvec (2, setl, setr);
		      add_reg_note (insn, REG_FRAME_RELATED_EXPR,
				    gen_rtx_SEQUENCE (VOIDmode, vec));
		    }
		}
	      offset += GET_MODE_SIZE (DFmode);
	      fr_saved++;
	    }
	}
    }
}

/* Emit RTL to load REG from the memory location specified by BASE+DISP.
   Handle case where DISP > 8k by using the add_high_const patterns.  */

static void
load_reg (int reg, HOST_WIDE_INT disp, int base)
{
  rtx dest = gen_rtx_REG (word_mode, reg);
  rtx basereg = gen_rtx_REG (Pmode, base);
  rtx src;

  if (VAL_14_BITS_P (disp))
    src = gen_rtx_MEM (word_mode, plus_constant (Pmode, basereg, disp));
  else if (TARGET_64BIT && !VAL_32_BITS_P (disp))
    {
      rtx delta = GEN_INT (disp);
      rtx tmpreg = gen_rtx_REG (Pmode, 1);

      emit_move_insn (tmpreg, delta);
      if (TARGET_DISABLE_INDEXING)
	{
	  emit_move_insn (tmpreg, gen_rtx_PLUS (Pmode, tmpreg, basereg));
	  src = gen_rtx_MEM (word_mode, tmpreg);
	}
      else
	src = gen_rtx_MEM (word_mode, gen_rtx_PLUS (Pmode, tmpreg, basereg));
    }
  else
    {
      rtx delta = GEN_INT (disp);
      rtx high = gen_rtx_PLUS (Pmode, basereg, gen_rtx_HIGH (Pmode, delta));
      rtx tmpreg = gen_rtx_REG (Pmode, 1);

      emit_move_insn (tmpreg, high);
      src = gen_rtx_MEM (word_mode, gen_rtx_LO_SUM (Pmode, tmpreg, delta));
    }

  emit_move_insn (dest, src);
}

/* Update the total code bytes output to the text section.  */

static void
update_total_code_bytes (unsigned int nbytes)
{
  if ((TARGET_PORTABLE_RUNTIME || !TARGET_GAS || !TARGET_SOM)
      && !IN_NAMED_SECTION_P (cfun->decl))
    {
      unsigned int old_total = total_code_bytes;

      total_code_bytes += nbytes;

      /* Be prepared to handle overflows.  */
      if (old_total > total_code_bytes)
        total_code_bytes = UINT_MAX;
    }
}

/* This function generates the assembly code for function exit.
   Args are as for output_function_prologue ().

   The function epilogue should not depend on the current stack
   pointer!  It should use the frame pointer only.  This is mandatory
   because of alloca; we also take advantage of it to omit stack
   adjustments before returning.  */

static void
pa_output_function_epilogue (FILE *file)
{
  rtx_insn *insn = get_last_insn ();
  bool extra_nop;

  /* pa_expand_epilogue does the dirty work now.  We just need
     to output the assembler directives which denote the end
     of a function.

     To make debuggers happy, emit a nop if the epilogue was completely
     eliminated due to a volatile call as the last insn in the
     current function.  That way the return address (in %r2) will
     always point to a valid instruction in the current function.  */

  /* Get the last real insn.  */
  if (NOTE_P (insn))
    insn = prev_real_insn (insn);

  /* If it is a sequence, then look inside.  */
  if (insn && NONJUMP_INSN_P (insn) && GET_CODE (PATTERN (insn)) == SEQUENCE)
    insn = as_a <rtx_sequence *> (PATTERN (insn))-> insn (0);

  /* If insn is a CALL_INSN, then it must be a call to a volatile
     function (otherwise there would be epilogue insns).  */
  if (insn && CALL_P (insn))
    {
      fputs ("\tnop\n", file);
      extra_nop = true;
    }
  else
    extra_nop = false;

  fputs ("\t.EXIT\n\t.PROCEND\n", file);

  if (TARGET_SOM && TARGET_GAS)
    {
      /* We are done with this subspace except possibly for some additional
	 debug information.  Forget that we are in this subspace to ensure
	 that the next function is output in its own subspace.  */
      in_section = NULL;
      cfun->machine->in_nsubspa = 2;
    }

  /* Thunks do their own insn accounting.  */
  if (cfun->is_thunk)
    return;

  if (INSN_ADDRESSES_SET_P ())
    {
      last_address = extra_nop ? 4 : 0;
      insn = get_last_nonnote_insn ();
      if (insn)
	{
	  last_address += INSN_ADDRESSES (INSN_UID (insn));
	  if (INSN_P (insn))
	    last_address += insn_default_length (insn);
	}
      last_address = ((last_address + FUNCTION_BOUNDARY / BITS_PER_UNIT - 1)
		      & ~(FUNCTION_BOUNDARY / BITS_PER_UNIT - 1));
    }
  else
    last_address = UINT_MAX;

  /* Finally, update the total number of code bytes output so far.  */
  update_total_code_bytes (last_address);
}

void
pa_expand_epilogue (void)
{
  rtx tmpreg;
  HOST_WIDE_INT offset;
  HOST_WIDE_INT ret_off = 0;
  int i;
  int merge_sp_adjust_with_load = 0;

  /* We will use this often.  */
  tmpreg = gen_rtx_REG (word_mode, 1);

  /* Try to restore RP early to avoid load/use interlocks when
     RP gets used in the return (bv) instruction.  This appears to still
     be necessary even when we schedule the prologue and epilogue.  */
  if (rp_saved)
    {
      ret_off = TARGET_64BIT ? -16 : -20;
      if (frame_pointer_needed)
	{
	  load_reg (2, ret_off, HARD_FRAME_POINTER_REGNUM);
	  ret_off = 0;
	}
      else
	{
	  /* No frame pointer, and stack is smaller than 8k.  */
	  if (VAL_14_BITS_P (ret_off - actual_fsize))
	    {
	      load_reg (2, ret_off - actual_fsize, STACK_POINTER_REGNUM);
	      ret_off = 0;
	    }
	}
    }

  /* General register restores.  */
  if (frame_pointer_needed)
    {
      offset = local_fsize;

      /* If the current function calls __builtin_eh_return, then we need
         to restore the saved EH data registers.  */
      if (DO_FRAME_NOTES && crtl->calls_eh_return)
	{
	  unsigned int i, regno;

	  for (i = 0; ; ++i)
	    {
	      regno = EH_RETURN_DATA_REGNO (i);
	      if (regno == INVALID_REGNUM)
		break;

	      load_reg (regno, offset, HARD_FRAME_POINTER_REGNUM);
	      offset += UNITS_PER_WORD;
	    }
	}

      for (i = 18; i >= 4; i--)
	if (df_regs_ever_live_p (i) && !call_used_or_fixed_reg_p (i))
	  {
	    load_reg (i, offset, HARD_FRAME_POINTER_REGNUM);
	    offset += UNITS_PER_WORD;
	  }
    }
  else
    {
      offset = local_fsize - actual_fsize;

      /* If the current function calls __builtin_eh_return, then we need
         to restore the saved EH data registers.  */
      if (DO_FRAME_NOTES && crtl->calls_eh_return)
	{
	  unsigned int i, regno;

	  for (i = 0; ; ++i)
	    {
	      regno = EH_RETURN_DATA_REGNO (i);
	      if (regno == INVALID_REGNUM)
		break;

	      /* Only for the first load.
	         merge_sp_adjust_with_load holds the register load
	         with which we will merge the sp adjustment.  */
	      if (merge_sp_adjust_with_load == 0
		  && local_fsize == 0
		  && VAL_14_BITS_P (-actual_fsize))
	        merge_sp_adjust_with_load = regno;
	      else
		load_reg (regno, offset, STACK_POINTER_REGNUM);
	      offset += UNITS_PER_WORD;
	    }
	}

      for (i = 18; i >= 3; i--)
	{
	  if (df_regs_ever_live_p (i) && !call_used_or_fixed_reg_p (i))
	    {
	      /* Only for the first load.
	         merge_sp_adjust_with_load holds the register load
	         with which we will merge the sp adjustment.  */
	      if (merge_sp_adjust_with_load == 0
		  && local_fsize == 0
		  && VAL_14_BITS_P (-actual_fsize))
	        merge_sp_adjust_with_load = i;
	      else
		load_reg (i, offset, STACK_POINTER_REGNUM);
	      offset += UNITS_PER_WORD;
	    }
	}
    }

  /* Align pointer properly (doubleword boundary).  */
  offset = (offset + 7) & ~7;

  /* FP register restores.  */
  if (save_fregs)
    {
      /* Adjust the register to index off of.  */
      if (frame_pointer_needed)
	set_reg_plus_d (1, HARD_FRAME_POINTER_REGNUM, offset, 0);
      else
	set_reg_plus_d (1, STACK_POINTER_REGNUM, offset, 0);

      /* Actually do the restores now.  */
      for (i = FP_SAVED_REG_LAST; i >= FP_SAVED_REG_FIRST; i -= FP_REG_STEP)
	if (df_regs_ever_live_p (i)
	    || (! TARGET_64BIT && df_regs_ever_live_p (i + 1)))
	  {
	    rtx src = gen_rtx_MEM (DFmode,
				   gen_rtx_POST_INC (word_mode, tmpreg));
	    rtx dest = gen_rtx_REG (DFmode, i);
	    emit_move_insn (dest, src);
	  }
    }

  /* Emit a blockage insn here to keep these insns from being moved to
     an earlier spot in the epilogue, or into the main instruction stream.

     This is necessary as we must not cut the stack back before all the
     restores are finished.  */
  emit_insn (gen_blockage ());

  /* Reset stack pointer (and possibly frame pointer).  The stack
     pointer is initially set to fp + 64 to avoid a race condition.  */
  if (frame_pointer_needed)
    {
      rtx delta = GEN_INT (-64);

      set_reg_plus_d (STACK_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM, 64, 0);
      emit_insn (gen_pre_load (hard_frame_pointer_rtx,
			       stack_pointer_rtx, delta));
    }
  /* If we were deferring a callee register restore, do it now.  */
  else if (merge_sp_adjust_with_load)
    {
      rtx delta = GEN_INT (-actual_fsize);
      rtx dest = gen_rtx_REG (word_mode, merge_sp_adjust_with_load);

      emit_insn (gen_pre_load (dest, stack_pointer_rtx, delta));
    }
  else if (actual_fsize != 0)
    set_reg_plus_d (STACK_POINTER_REGNUM, STACK_POINTER_REGNUM,
		    - actual_fsize, 0);

  /* If we haven't restored %r2 yet (no frame pointer, and a stack
     frame greater than 8k), do so now.  */
  if (ret_off != 0)
    load_reg (2, ret_off, STACK_POINTER_REGNUM);

  if (DO_FRAME_NOTES && crtl->calls_eh_return)
    {
      rtx sa = EH_RETURN_STACKADJ_RTX;

      emit_insn (gen_blockage ());
      emit_insn (TARGET_64BIT
		 ? gen_subdi3 (stack_pointer_rtx, stack_pointer_rtx, sa)
		 : gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx, sa));
    }
}

bool
pa_can_use_return_insn (void)
{
  if (!reload_completed)
    return false;

  if (frame_pointer_needed)
    return false;

  if (df_regs_ever_live_p (2))
    return false;

  if (crtl->profile)
    return false;

  return pa_compute_frame_size (get_frame_size (), 0) == 0;
}

rtx
hppa_pic_save_rtx (void)
{
  return get_hard_reg_initial_val (word_mode, PIC_OFFSET_TABLE_REGNUM);
}

#ifndef NO_DEFERRED_PROFILE_COUNTERS
#define NO_DEFERRED_PROFILE_COUNTERS 0
#endif


/* Vector of funcdef numbers.  */
static vec<int> funcdef_nos;

/* Output deferred profile counters.  */
static void
output_deferred_profile_counters (void)
{
  unsigned int i;
  int align, n;

  if (funcdef_nos.is_empty ())
   return;

  switch_to_section (data_section);
  align = MIN (BIGGEST_ALIGNMENT, LONG_TYPE_SIZE);
  ASM_OUTPUT_ALIGN (asm_out_file, floor_log2 (align / BITS_PER_UNIT));

  for (i = 0; funcdef_nos.iterate (i, &n); i++)
    {
      targetm.asm_out.internal_label (asm_out_file, "LP", n);
      assemble_integer (const0_rtx, LONG_TYPE_SIZE / BITS_PER_UNIT, align, 1);
    }

  funcdef_nos.release ();
}

void
hppa_profile_hook (int label_no)
{
  rtx_code_label *label_rtx = gen_label_rtx ();
  int reg_parm_stack_space = REG_PARM_STACK_SPACE (NULL_TREE);
  rtx arg_bytes, begin_label_rtx, mcount, sym;
  rtx_insn *call_insn;
  char begin_label_name[16];
  bool use_mcount_pcrel_call;

  /* Set up call destination.  */
  sym = gen_rtx_SYMBOL_REF (Pmode, "_mcount");
  pa_encode_label (sym);
  mcount = gen_rtx_MEM (Pmode, sym);

  /* If we can reach _mcount with a pc-relative call, we can optimize
     loading the address of the current function.  This requires linker
     long branch stub support.  */
  if (!TARGET_PORTABLE_RUNTIME
      && !TARGET_LONG_CALLS
      && (TARGET_SOM || flag_function_sections))
    use_mcount_pcrel_call = TRUE;
  else
    use_mcount_pcrel_call = FALSE;

  ASM_GENERATE_INTERNAL_LABEL (begin_label_name, FUNC_BEGIN_PROLOG_LABEL,
			       label_no);
  begin_label_rtx = gen_rtx_SYMBOL_REF (SImode, ggc_strdup (begin_label_name));

  emit_move_insn (gen_rtx_REG (word_mode, 26), gen_rtx_REG (word_mode, 2));

  if (!use_mcount_pcrel_call)
    {
      /* The address of the function is loaded into %r25 with an instruction-
	 relative sequence that avoids the use of relocations.  We use SImode
	 for the address of the function in both 32 and 64-bit code to avoid
	 having to provide DImode versions of the lcla2 pattern.  */
      if (TARGET_PA_20)
	emit_insn (gen_lcla2 (gen_rtx_REG (SImode, 25), label_rtx));
      else
	emit_insn (gen_lcla1 (gen_rtx_REG (SImode, 25), label_rtx));
    }

  if (!NO_DEFERRED_PROFILE_COUNTERS)
    {
      rtx count_label_rtx, addr, r24;
      char count_label_name[16];

      funcdef_nos.safe_push (label_no);
      ASM_GENERATE_INTERNAL_LABEL (count_label_name, "LP", label_no);
      count_label_rtx = gen_rtx_SYMBOL_REF (Pmode,
					    ggc_strdup (count_label_name));

      addr = force_reg (Pmode, count_label_rtx);
      r24 = gen_rtx_REG (Pmode, 24);
      emit_move_insn (r24, addr);

      arg_bytes = GEN_INT (TARGET_64BIT ? 24 : 12);
      if (use_mcount_pcrel_call)
	call_insn = emit_call_insn (gen_call_mcount (mcount, arg_bytes,
						     begin_label_rtx));
      else
	call_insn = emit_call_insn (gen_call (mcount, arg_bytes));

      use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), r24);
    }
  else
    {
      arg_bytes = GEN_INT (TARGET_64BIT ? 16 : 8);
      if (use_mcount_pcrel_call)
	call_insn = emit_call_insn (gen_call_mcount (mcount, arg_bytes,
						     begin_label_rtx));
      else
	call_insn = emit_call_insn (gen_call (mcount, arg_bytes));
    }

  use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), gen_rtx_REG (SImode, 25));
  use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), gen_rtx_REG (SImode, 26));

  /* Indicate the _mcount call cannot throw, nor will it execute a
     non-local goto.  */
  make_reg_eh_region_note_nothrow_nononlocal (call_insn);

  /* Allocate space for fixed arguments.  */
  if (reg_parm_stack_space > crtl->outgoing_args_size)
    crtl->outgoing_args_size = reg_parm_stack_space;
}

/* Fetch the return address for the frame COUNT steps up from
   the current frame, after the prologue.  FRAMEADDR is the
   frame pointer of the COUNT frame.

   We want to ignore any export stub remnants here.  To handle this,
   we examine the code at the return address, and if it is an export
   stub, we return a memory rtx for the stub return address stored
   at frame-24.

   The value returned is used in two different ways:

	1. To find a function's caller.

	2. To change the return address for a function.

   This function handles most instances of case 1; however, it will
   fail if there are two levels of stubs to execute on the return
   path.  The only way I believe that can happen is if the return value
   needs a parameter relocation, which never happens for C code.

   This function handles most instances of case 2; however, it will
   fail if we did not originally have stub code on the return path
   but will need stub code on the new return path.  This can happen if
   the caller & callee are both in the main program, but the new
   return location is in a shared library.  */

rtx
pa_return_addr_rtx (int count, rtx frameaddr)
{
  rtx label;
  rtx rp;
  rtx saved_rp;
  rtx ins;

  /* The instruction stream at the return address of a PA1.X export stub is:

	0x4bc23fd1 | stub+8:   ldw -18(sr0,sp),rp
	0x004010a1 | stub+12:  ldsid (sr0,rp),r1
	0x00011820 | stub+16:  mtsp r1,sr0
	0xe0400002 | stub+20:  be,n 0(sr0,rp)

     0xe0400002 must be specified as -532676606 so that it won't be
     rejected as an invalid immediate operand on 64-bit hosts.

     The instruction stream at the return address of a PA2.0 export stub is:

	0x4bc23fd1 | stub+8:   ldw -18(sr0,sp),rp
	0xe840d002 | stub+12:  bve,n (rp)
  */

  HOST_WIDE_INT insns[4];
  int i, len;

  if (count != 0)
    return NULL_RTX;

  rp = get_hard_reg_initial_val (Pmode, 2);

  if (TARGET_64BIT || TARGET_NO_SPACE_REGS)
    return rp;

  /* If there is no export stub then just use the value saved from
     the return pointer register.  */

  saved_rp = gen_reg_rtx (Pmode);
  emit_move_insn (saved_rp, rp);

  /* Get pointer to the instruction stream.  We have to mask out the
     privilege level from the two low order bits of the return address
     pointer here so that ins will point to the start of the first
     instruction that would have been executed if we returned.  */
  ins = copy_to_reg (gen_rtx_AND (Pmode, rp, MASK_RETURN_ADDR));
  label = gen_label_rtx ();

  if (TARGET_PA_20)
    {
      insns[0] = 0x4bc23fd1;
      insns[1] = -398405630;
      len = 2;
    }
  else
    {
      insns[0] = 0x4bc23fd1;
      insns[1] = 0x004010a1;
      insns[2] = 0x00011820;
      insns[3] = -532676606;
      len = 4;
    }

  /* Check the instruction stream at the normal return address for the
     export stub.  If it is an export stub, than our return address is
     really in -24[frameaddr].  */

  for (i = 0; i < len; i++)
    {
      rtx op0 = gen_rtx_MEM (SImode, plus_constant (Pmode, ins, i * 4));
      rtx op1 = GEN_INT (insns[i]);
      emit_cmp_and_jump_insns (op0, op1, NE, NULL, SImode, 0, label);
    }

  /* Here we know that our return address points to an export
     stub.  We don't want to return the address of the export stub,
     but rather the return address of the export stub.  That return
     address is stored at -24[frameaddr].  */

  emit_move_insn (saved_rp,
		  gen_rtx_MEM (Pmode,
			       memory_address (Pmode,
					       plus_constant (Pmode, frameaddr,
							      -24))));

  emit_label (label);

  return saved_rp;
}

void
pa_emit_bcond_fp (rtx operands[])
{
  enum rtx_code code = GET_CODE (operands[0]);
  rtx operand0 = operands[1];
  rtx operand1 = operands[2];
  rtx label = operands[3];

  emit_insn (gen_rtx_SET (gen_rtx_REG (CCFPmode, 0),
		          gen_rtx_fmt_ee (code, CCFPmode, operand0, operand1)));

  emit_jump_insn (gen_rtx_SET (pc_rtx,
			       gen_rtx_IF_THEN_ELSE (VOIDmode,
						     gen_rtx_fmt_ee (NE,
							      VOIDmode,
							      gen_rtx_REG (CCFPmode, 0),
							      const0_rtx),
						     gen_rtx_LABEL_REF (VOIDmode, label),
						     pc_rtx)));

}

/* Adjust the cost of a scheduling dependency.  Return the new cost of
   a dependency LINK or INSN on DEP_INSN.  COST is the current cost.  */

static int
pa_adjust_cost (rtx_insn *insn, int dep_type, rtx_insn *dep_insn, int cost,
		unsigned int)
{
  enum attr_type attr_type;

  /* Don't adjust costs for a pa8000 chip, also do not adjust any
     true dependencies as they are described with bypasses now.  */
  if (pa_cpu >= PROCESSOR_8000 || dep_type == 0)
    return cost;

  if (! recog_memoized (insn))
    return 0;

  attr_type = get_attr_type (insn);

  switch (dep_type)
    {
    case REG_DEP_ANTI:
      /* Anti dependency; DEP_INSN reads a register that INSN writes some
	 cycles later.  */

      if (attr_type == TYPE_FPLOAD)
	{
	  rtx pat = PATTERN (insn);
	  rtx dep_pat = PATTERN (dep_insn);
	  if (GET_CODE (pat) == PARALLEL)
	    {
	      /* This happens for the fldXs,mb patterns.  */
	      pat = XVECEXP (pat, 0, 0);
	    }
	  if (GET_CODE (pat) != SET || GET_CODE (dep_pat) != SET)
	    /* If this happens, we have to extend this to schedule
	       optimally.  Return 0 for now.  */
	  return 0;

	  if (reg_mentioned_p (SET_DEST (pat), SET_SRC (dep_pat)))
	    {
	      if (! recog_memoized (dep_insn))
		return 0;
	      switch (get_attr_type (dep_insn))
		{
		case TYPE_FPALU:
		case TYPE_FPMULSGL:
		case TYPE_FPMULDBL:
		case TYPE_FPDIVSGL:
		case TYPE_FPDIVDBL:
		case TYPE_FPSQRTSGL:
		case TYPE_FPSQRTDBL:
		  /* A fpload can't be issued until one cycle before a
		     preceding arithmetic operation has finished if
		     the target of the fpload is any of the sources
		     (or destination) of the arithmetic operation.  */
		  return insn_default_latency (dep_insn) - 1;

		default:
		  return 0;
		}
	    }
	}
      else if (attr_type == TYPE_FPALU)
	{
	  rtx pat = PATTERN (insn);
	  rtx dep_pat = PATTERN (dep_insn);
	  if (GET_CODE (pat) == PARALLEL)
	    {
	      /* This happens for the fldXs,mb patterns.  */
	      pat = XVECEXP (pat, 0, 0);
	    }
	  if (GET_CODE (pat) != SET || GET_CODE (dep_pat) != SET)
	    /* If this happens, we have to extend this to schedule
	       optimally.  Return 0 for now.  */
	  return 0;

	  if (reg_mentioned_p (SET_DEST (pat), SET_SRC (dep_pat)))
	    {
	      if (! recog_memoized (dep_insn))
		return 0;
	      switch (get_attr_type (dep_insn))
		{
		case TYPE_FPDIVSGL:
		case TYPE_FPDIVDBL:
		case TYPE_FPSQRTSGL:
		case TYPE_FPSQRTDBL:
		  /* An ALU flop can't be issued until two cycles before a
		     preceding divide or sqrt operation has finished if
		     the target of the ALU flop is any of the sources
		     (or destination) of the divide or sqrt operation.  */
		  return insn_default_latency (dep_insn) - 2;

		default:
		  return 0;
		}
	    }
	}

      /* For other anti dependencies, the cost is 0.  */
      return 0;

    case REG_DEP_OUTPUT:
      /* Output dependency; DEP_INSN writes a register that INSN writes some
	 cycles later.  */
      if (attr_type == TYPE_FPLOAD)
	{
	  rtx pat = PATTERN (insn);
	  rtx dep_pat = PATTERN (dep_insn);
	  if (GET_CODE (pat) == PARALLEL)
	    {
	      /* This happens for the fldXs,mb patterns.  */
	      pat = XVECEXP (pat, 0, 0);
	    }
	  if (GET_CODE (pat) != SET || GET_CODE (dep_pat) != SET)
	    /* If this happens, we have to extend this to schedule
	       optimally.  Return 0 for now.  */
	  return 0;

	  if (reg_mentioned_p (SET_DEST (pat), SET_DEST (dep_pat)))
	    {
	      if (! recog_memoized (dep_insn))
		return 0;
	      switch (get_attr_type (dep_insn))
		{
		case TYPE_FPALU:
		case TYPE_FPMULSGL:
		case TYPE_FPMULDBL:
		case TYPE_FPDIVSGL:
		case TYPE_FPDIVDBL:
		case TYPE_FPSQRTSGL:
		case TYPE_FPSQRTDBL:
		  /* A fpload can't be issued until one cycle before a
		     preceding arithmetic operation has finished if
		     the target of the fpload is the destination of the
		     arithmetic operation. 

		     Exception: For PA7100LC, PA7200 and PA7300, the cost
		     is 3 cycles, unless they bundle together.   We also
		     pay the penalty if the second insn is a fpload.  */
		  return insn_default_latency (dep_insn) - 1;

		default:
		  return 0;
		}
	    }
	}
      else if (attr_type == TYPE_FPALU)
	{
	  rtx pat = PATTERN (insn);
	  rtx dep_pat = PATTERN (dep_insn);
	  if (GET_CODE (pat) == PARALLEL)
	    {
	      /* This happens for the fldXs,mb patterns.  */
	      pat = XVECEXP (pat, 0, 0);
	    }
	  if (GET_CODE (pat) != SET || GET_CODE (dep_pat) != SET)
	    /* If this happens, we have to extend this to schedule
	       optimally.  Return 0 for now.  */
	  return 0;

	  if (reg_mentioned_p (SET_DEST (pat), SET_DEST (dep_pat)))
	    {
	      if (! recog_memoized (dep_insn))
		return 0;
	      switch (get_attr_type (dep_insn))
		{
		case TYPE_FPDIVSGL:
		case TYPE_FPDIVDBL:
		case TYPE_FPSQRTSGL:
		case TYPE_FPSQRTDBL:
		  /* An ALU flop can't be issued until two cycles before a
		     preceding divide or sqrt operation has finished if
		     the target of the ALU flop is also the target of
		     the divide or sqrt operation.  */
		  return insn_default_latency (dep_insn) - 2;

		default:
		  return 0;
		}
	    }
	}

      /* For other output dependencies, the cost is 0.  */
      return 0;

    default:
      gcc_unreachable ();
    }
}

/* The 700 can only issue a single insn at a time.
   The 7XXX processors can issue two insns at a time.
   The 8000 can issue 4 insns at a time.  */
static int
pa_issue_rate (void)
{
  switch (pa_cpu)
    {
    case PROCESSOR_700:		return 1;
    case PROCESSOR_7100:	return 2;
    case PROCESSOR_7100LC:	return 2;
    case PROCESSOR_7200:	return 2;
    case PROCESSOR_7300:	return 2;
    case PROCESSOR_8000:	return 4;

    default:
      gcc_unreachable ();
    }
}



/* Return any length plus adjustment needed by INSN which already has
   its length computed as LENGTH.   Return LENGTH if no adjustment is
   necessary.

   Also compute the length of an inline block move here as it is too
   complicated to express as a length attribute in pa.md.  */
int
pa_adjust_insn_length (rtx_insn *insn, int length)
{
  rtx pat = PATTERN (insn);

  /* If length is negative or undefined, provide initial length.  */
  if ((unsigned int) length >= INT_MAX)
    {
      if (GET_CODE (pat) == SEQUENCE)
	insn = as_a <rtx_insn *> (XVECEXP (pat, 0, 0));

      switch (get_attr_type (insn))
	{
	case TYPE_MILLI:
	  length = pa_attr_length_millicode_call (insn);
	  break;
	case TYPE_CALL:
	  length = pa_attr_length_call (insn, 0);
	  break;
	case TYPE_SIBCALL:
	  length = pa_attr_length_call (insn, 1);
	  break;
	case TYPE_DYNCALL:
	  length = pa_attr_length_indirect_call (insn);
	  break;
	case TYPE_SH_FUNC_ADRS:
	  length = pa_attr_length_millicode_call (insn) + 20;
	  break;
	default:
	  gcc_unreachable ();
	}
    }

  /* Block move pattern.  */
  if (NONJUMP_INSN_P (insn)
      && GET_CODE (pat) == PARALLEL
      && GET_CODE (XVECEXP (pat, 0, 0)) == SET
      && GET_CODE (XEXP (XVECEXP (pat, 0, 0), 0)) == MEM
      && GET_CODE (XEXP (XVECEXP (pat, 0, 0), 1)) == MEM
      && GET_MODE (XEXP (XVECEXP (pat, 0, 0), 0)) == BLKmode
      && GET_MODE (XEXP (XVECEXP (pat, 0, 0), 1)) == BLKmode)
    length += compute_cpymem_length (insn) - 4;
  /* Block clear pattern.  */
  else if (NONJUMP_INSN_P (insn)
	   && GET_CODE (pat) == PARALLEL
	   && GET_CODE (XVECEXP (pat, 0, 0)) == SET
	   && GET_CODE (XEXP (XVECEXP (pat, 0, 0), 0)) == MEM
	   && XEXP (XVECEXP (pat, 0, 0), 1) == const0_rtx
	   && GET_MODE (XEXP (XVECEXP (pat, 0, 0), 0)) == BLKmode)
    length += compute_clrmem_length (insn) - 4;
  /* Conditional branch with an unfilled delay slot.  */
  else if (JUMP_P (insn) && ! simplejump_p (insn))
    {
      /* Adjust a short backwards conditional with an unfilled delay slot.  */
      if (GET_CODE (pat) == SET
	  && length == 4
	  && JUMP_LABEL (insn) != NULL_RTX
	  && ! forward_branch_p (insn))
	length += 4;
      else if (GET_CODE (pat) == PARALLEL
	       && get_attr_type (insn) == TYPE_PARALLEL_BRANCH
	       && length == 4)
	length += 4;
      /* Adjust dbra insn with short backwards conditional branch with
	 unfilled delay slot -- only for case where counter is in a
	 general register register.  */
      else if (GET_CODE (pat) == PARALLEL
	       && GET_CODE (XVECEXP (pat, 0, 1)) == SET
	       && GET_CODE (XEXP (XVECEXP (pat, 0, 1), 0)) == REG
 	       && ! FP_REG_P (XEXP (XVECEXP (pat, 0, 1), 0))
	       && length == 4
	       && ! forward_branch_p (insn))
	length += 4;
    }
  return length;
}

/* Implement the TARGET_PRINT_OPERAND_PUNCT_VALID_P hook.  */

static bool
pa_print_operand_punct_valid_p (unsigned char code)
{
  if (code == '@'
      || code == '#'
      || code == '*'
      || code == '^')
    return true;

  return false;
}

/* Print operand X (an rtx) in assembler syntax to file FILE.
   CODE is a letter or dot (`z' in `%z0') or 0 if no letter was specified.
   For `%' followed by punctuation, CODE is the punctuation and X is null.  */

void
pa_print_operand (FILE *file, rtx x, int code)
{
  switch (code)
    {
    case '#':
      /* Output a 'nop' if there's nothing for the delay slot.  */
      if (dbr_sequence_length () == 0)
	fputs ("\n\tnop", file);
      return;
    case '*':
      /* Output a nullification completer if there's nothing for the */
      /* delay slot or nullification is requested.  */
      if (dbr_sequence_length () == 0 ||
	  (final_sequence &&
	   INSN_ANNULLED_BRANCH_P (XVECEXP (final_sequence, 0, 0))))
        fputs (",n", file);
      return;
    case 'R':
      /* Print out the second register name of a register pair.
	 I.e., R (6) => 7.  */
      fputs (reg_names[REGNO (x) + 1], file);
      return;
    case 'r':
      /* A register or zero.  */
      if (x == const0_rtx
	  || (x == CONST0_RTX (DFmode))
	  || (x == CONST0_RTX (SFmode)))
	{
	  fputs ("%r0", file);
	  return;
	}
      else
	break;
    case 'f':
      /* A register or zero (floating point).  */
      if (x == const0_rtx
	  || (x == CONST0_RTX (DFmode))
	  || (x == CONST0_RTX (SFmode)))
	{
	  fputs ("%fr0", file);
	  return;
	}
      else
	break;
    case 'A':
      {
	rtx xoperands[2];

	xoperands[0] = XEXP (XEXP (x, 0), 0);
	xoperands[1] = XVECEXP (XEXP (XEXP (x, 0), 1), 0, 0);
	pa_output_global_address (file, xoperands[1], 0);
        fprintf (file, "(%s)", reg_names [REGNO (xoperands[0])]);
	return;
      }

    case 'C':			/* Plain (C)ondition */
    case 'X':
      switch (GET_CODE (x))
	{
	case EQ:
	  fputs ("=", file);  break;
	case NE:
	  fputs ("<>", file);  break;
	case GT:
	  fputs (">", file);  break;
	case GE:
	  fputs (">=", file);  break;
	case GEU:
	  fputs (">>=", file);  break;
	case GTU:
	  fputs (">>", file);  break;
	case LT:
	  fputs ("<", file);  break;
	case LE:
	  fputs ("<=", file);  break;
	case LEU:
	  fputs ("<<=", file);  break;
	case LTU:
	  fputs ("<<", file);  break;
	default:
	  gcc_unreachable ();
	}
      return;
    case 'N':			/* Condition, (N)egated */
      switch (GET_CODE (x))
	{
	case EQ:
	  fputs ("<>", file);  break;
	case NE:
	  fputs ("=", file);  break;
	case GT:
	  fputs ("<=", file);  break;
	case GE:
	  fputs ("<", file);  break;
	case GEU:
	  fputs ("<<", file);  break;
	case GTU:
	  fputs ("<<=", file);  break;
	case LT:
	  fputs (">=", file);  break;
	case LE:
	  fputs (">", file);  break;
	case LEU:
	  fputs (">>", file);  break;
	case LTU:
	  fputs (">>=", file);  break;
	default:
	  gcc_unreachable ();
	}
      return;
    /* For floating point comparisons.  Note that the output
       predicates are the complement of the desired mode.  The
       conditions for GT, GE, LT, LE and LTGT cause an invalid
       operation exception if the result is unordered and this
       exception is enabled in the floating-point status register.  */
    case 'Y':
      switch (GET_CODE (x))
	{
	case EQ:
	  fputs ("!=", file);  break;
	case NE:
	  fputs ("=", file);  break;
	case GT:
	  fputs ("!>", file);  break;
	case GE:
	  fputs ("!>=", file);  break;
	case LT:
	  fputs ("!<", file);  break;
	case LE:
	  fputs ("!<=", file);  break;
	case LTGT:
	  fputs ("!<>", file);  break;
	case UNLE:
	  fputs ("!?<=", file);  break;
	case UNLT:
	  fputs ("!?<", file);  break;
	case UNGE:
	  fputs ("!?>=", file);  break;
	case UNGT:
	  fputs ("!?>", file);  break;
	case UNEQ:
	  fputs ("!?=", file);  break;
	case UNORDERED:
	  fputs ("!?", file);  break;
	case ORDERED:
	  fputs ("?", file);  break;
	default:
	  gcc_unreachable ();
	}
      return;
    case 'S':			/* Condition, operands are (S)wapped.  */
      switch (GET_CODE (x))
	{
	case EQ:
	  fputs ("=", file);  break;
	case NE:
	  fputs ("<>", file);  break;
	case GT:
	  fputs ("<", file);  break;
	case GE:
	  fputs ("<=", file);  break;
	case GEU:
	  fputs ("<<=", file);  break;
	case GTU:
	  fputs ("<<", file);  break;
	case LT:
	  fputs (">", file);  break;
	case LE:
	  fputs (">=", file);  break;
	case LEU:
	  fputs (">>=", file);  break;
	case LTU:
	  fputs (">>", file);  break;
	default:
	  gcc_unreachable ();
	}
      return;
    case 'B':			/* Condition, (B)oth swapped and negate.  */
      switch (GET_CODE (x))
	{
	case EQ:
	  fputs ("<>", file);  break;
	case NE:
	  fputs ("=", file);  break;
	case GT:
	  fputs (">=", file);  break;
	case GE:
	  fputs (">", file);  break;
	case GEU:
	  fputs (">>", file);  break;
	case GTU:
	  fputs (">>=", file);  break;
	case LT:
	  fputs ("<=", file);  break;
	case LE:
	  fputs ("<", file);  break;
	case LEU:
	  fputs ("<<", file);  break;
	case LTU:
	  fputs ("<<=", file);  break;
	default:
	  gcc_unreachable ();
	}
      return;
    case 'k':
      gcc_assert (GET_CODE (x) == CONST_INT);
      fprintf (file, HOST_WIDE_INT_PRINT_DEC, ~INTVAL (x));
      return;
    case 'Q':
      gcc_assert (GET_CODE (x) == CONST_INT);
      fprintf (file, HOST_WIDE_INT_PRINT_DEC, 64 - (INTVAL (x) & 63));
      return;
    case 'L':
      gcc_assert (GET_CODE (x) == CONST_INT);
      fprintf (file, HOST_WIDE_INT_PRINT_DEC, 32 - (INTVAL (x) & 31));
      return;
    case 'o':
      gcc_assert (GET_CODE (x) == CONST_INT
		  && (INTVAL (x) == 1 || INTVAL (x) == 2 || INTVAL (x) == 3));
      fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x));
      return;
    case 'O':
      gcc_assert (GET_CODE (x) == CONST_INT && exact_log2 (INTVAL (x)) >= 0);
      fprintf (file, "%d", exact_log2 (INTVAL (x)));
      return;
    case 'p':
      gcc_assert (GET_CODE (x) == CONST_INT);
      fprintf (file, HOST_WIDE_INT_PRINT_DEC, 63 - (INTVAL (x) & 63));
      return;
    case 'P':
      gcc_assert (GET_CODE (x) == CONST_INT);
      fprintf (file, HOST_WIDE_INT_PRINT_DEC, 31 - (INTVAL (x) & 31));
      return;
    case 'I':
      if (GET_CODE (x) == CONST_INT)
	fputs ("i", file);
      return;
    case 'M':
    case 'F':
      switch (GET_CODE (XEXP (x, 0)))
	{
	case PRE_DEC:
	case PRE_INC:
	  if (ASSEMBLER_DIALECT == 0)
	    fputs ("s,mb", file);
	  else
	    fputs (",mb", file);
	  break;
	case POST_DEC:
	case POST_INC:
	  if (ASSEMBLER_DIALECT == 0)
	    fputs ("s,ma", file);
	  else
	    fputs (",ma", file);
	  break;
	case PLUS:
	  if (GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
	      && GET_CODE (XEXP (XEXP (x, 0), 1)) == REG)
	    {
	      if (ASSEMBLER_DIALECT == 0)
		fputs ("x", file);
	    }
	  else if (GET_CODE (XEXP (XEXP (x, 0), 0)) == MULT
		   || GET_CODE (XEXP (XEXP (x, 0), 1)) == MULT)
	    {
	      if (ASSEMBLER_DIALECT == 0)
		fputs ("x,s", file);
	      else
		fputs (",s", file);
	    }
	  else if (code == 'F' && ASSEMBLER_DIALECT == 0)
	    fputs ("s", file);
	  break;
	default:
	  if (code == 'F' && ASSEMBLER_DIALECT == 0)
	    fputs ("s", file);
	  break;
	}
      return;
    case 'G':
      pa_output_global_address (file, x, 0);
      return;
    case 'H':
      pa_output_global_address (file, x, 1);
      return;
    case 0:			/* Don't do anything special */
      break;
    case 'Z':
      {
	unsigned op[3];
	compute_zdepwi_operands (INTVAL (x), op);
	fprintf (file, "%d,%d,%d", op[0], op[1], op[2]);
	return;
      }
    case 'z':
      {
	unsigned op[3];
	compute_zdepdi_operands (INTVAL (x), op);
	fprintf (file, "%d,%d,%d", op[0], op[1], op[2]);
	return;
      }
    case 'c':
      /* We can get here from a .vtable_inherit due to our
	 CONSTANT_ADDRESS_P rejecting perfectly good constant
	 addresses.  */
      break;
    default:
      gcc_unreachable ();
    }
  if (GET_CODE (x) == REG)
    {
      fputs (reg_names [REGNO (x)], file);
      if (TARGET_64BIT && FP_REG_P (x) && GET_MODE_SIZE (GET_MODE (x)) <= 4)
	{
	  fputs ("R", file);
	  return;
	}
      if (FP_REG_P (x)
	  && GET_MODE_SIZE (GET_MODE (x)) <= 4
	  && (REGNO (x) & 1) == 0)
	fputs ("L", file);
    }
  else if (GET_CODE (x) == MEM)
    {
      int size = GET_MODE_SIZE (GET_MODE (x));
      rtx base = NULL_RTX;
      switch (GET_CODE (XEXP (x, 0)))
	{
	case PRE_DEC:
	case POST_DEC:
          base = XEXP (XEXP (x, 0), 0);
	  fprintf (file, "-%d(%s)", size, reg_names [REGNO (base)]);
	  break;
	case PRE_INC:
	case POST_INC:
          base = XEXP (XEXP (x, 0), 0);
	  fprintf (file, "%d(%s)", size, reg_names [REGNO (base)]);
	  break;
	case PLUS:
	  if (GET_CODE (XEXP (XEXP (x, 0), 0)) == MULT)
	    fprintf (file, "%s(%s)",
		     reg_names [REGNO (XEXP (XEXP (XEXP (x, 0), 0), 0))],
		     reg_names [REGNO (XEXP (XEXP (x, 0), 1))]);
	  else if (GET_CODE (XEXP (XEXP (x, 0), 1)) == MULT)
	    fprintf (file, "%s(%s)",
		     reg_names [REGNO (XEXP (XEXP (XEXP (x, 0), 1), 0))],
		     reg_names [REGNO (XEXP (XEXP (x, 0), 0))]);
	  else if (GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
		   && GET_CODE (XEXP (XEXP (x, 0), 1)) == REG)
	    {
	      /* Because the REG_POINTER flag can get lost during reload,
		 pa_legitimate_address_p canonicalizes the order of the
		 index and base registers in the combined move patterns.  */
	      rtx base = XEXP (XEXP (x, 0), 1);
	      rtx index = XEXP (XEXP (x, 0), 0);

	      fprintf (file, "%s(%s)",
		       reg_names [REGNO (index)], reg_names [REGNO (base)]);
	    }
	  else
	    output_address (GET_MODE (x), XEXP (x, 0));
	  break;
	default:
	  output_address (GET_MODE (x), XEXP (x, 0));
	  break;
	}
    }
  else
    output_addr_const (file, x);
}

/* output a SYMBOL_REF or a CONST expression involving a SYMBOL_REF.  */

void
pa_output_global_address (FILE *file, rtx x, int round_constant)
{

  /* Imagine  (high (const (plus ...))).  */
  if (GET_CODE (x) == HIGH)
    x = XEXP (x, 0);

  if (GET_CODE (x) == SYMBOL_REF && read_only_operand (x, VOIDmode))
    output_addr_const (file, x);
  else if (GET_CODE (x) == SYMBOL_REF && !flag_pic)
    {
      output_addr_const (file, x);
      fputs ("-$global$", file);
    }
  else if (GET_CODE (x) == CONST)
    {
      const char *sep = "";
      int offset = 0;		/* assembler wants -$global$ at end */
      rtx base = NULL_RTX;

      switch (GET_CODE (XEXP (XEXP (x, 0), 0)))
	{
	case LABEL_REF:
	case SYMBOL_REF:
	  base = XEXP (XEXP (x, 0), 0);
	  output_addr_const (file, base);
	  break;
	case CONST_INT:
	  offset = INTVAL (XEXP (XEXP (x, 0), 0));
	  break;
	default:
	  gcc_unreachable ();
	}

      switch (GET_CODE (XEXP (XEXP (x, 0), 1)))
	{
	case LABEL_REF:
	case SYMBOL_REF:
	  base = XEXP (XEXP (x, 0), 1);
	  output_addr_const (file, base);
	  break;
	case CONST_INT:
	  offset = INTVAL (XEXP (XEXP (x, 0), 1));
	  break;
	default:
	  gcc_unreachable ();
	}

      /* How bogus.  The compiler is apparently responsible for
	 rounding the constant if it uses an LR field selector.

	 The linker and/or assembler seem a better place since
	 they have to do this kind of thing already.

	 If we fail to do this, HP's optimizing linker may eliminate
	 an addil, but not update the ldw/stw/ldo instruction that
	 uses the result of the addil.  */
      if (round_constant)
	offset = ((offset + 0x1000) & ~0x1fff);

      switch (GET_CODE (XEXP (x, 0)))
	{
	case PLUS:
	  if (offset < 0)
	    {
	      offset = -offset;
	      sep = "-";
	    }
	  else
	    sep = "+";
	  break;

	case MINUS:
	  gcc_assert (GET_CODE (XEXP (XEXP (x, 0), 0)) == SYMBOL_REF);
	  sep = "-";
	  break;

	default:
	  gcc_unreachable ();
	}
      
      if (!read_only_operand (base, VOIDmode) && !flag_pic)
	fputs ("-$global$", file);
      if (offset)
	fprintf (file, "%s%d", sep, offset);
    }
  else
    output_addr_const (file, x);
}

/* Output boilerplate text to appear at the beginning of the file.
   There are several possible versions.  */
#define aputs(x) fputs(x, asm_out_file)
static inline void
pa_file_start_level (void)
{
  if (TARGET_64BIT)
    aputs ("\t.LEVEL 2.0w\n");
  else if (TARGET_PA_20)
    aputs ("\t.LEVEL 2.0\n");
  else if (TARGET_PA_11)
    aputs ("\t.LEVEL 1.1\n");
  else
    aputs ("\t.LEVEL 1.0\n");
}

static inline void
pa_file_start_space (int sortspace)
{
  aputs ("\t.SPACE $PRIVATE$");
  if (sortspace)
    aputs (",SORT=16");
  aputs ("\n\t.SUBSPA $DATA$,QUAD=1,ALIGN=8,ACCESS=31");
  if (flag_tm)
    aputs ("\n\t.SUBSPA $TM_CLONE_TABLE$,QUAD=1,ALIGN=8,ACCESS=31");
  aputs ("\n\t.SUBSPA $BSS$,QUAD=1,ALIGN=8,ACCESS=31,ZERO,SORT=82"
	 "\n\t.SPACE $TEXT$");
  if (sortspace)
    aputs (",SORT=8");
  aputs ("\n\t.SUBSPA $LIT$,QUAD=0,ALIGN=8,ACCESS=44"
	 "\n\t.SUBSPA $CODE$,QUAD=0,ALIGN=8,ACCESS=44,CODE_ONLY\n");
}

static inline void
pa_file_start_file (int want_version)
{
  if (write_symbols != NO_DEBUG)
    {
      output_file_directive (asm_out_file, main_input_filename);
      if (want_version)
	aputs ("\t.version\t\"01.01\"\n");
    }
}

static inline void
pa_file_start_mcount (const char *aswhat)
{
  if (profile_flag)
    fprintf (asm_out_file, "\t.IMPORT _mcount,%s\n", aswhat);
}
  
static void
pa_elf_file_start (void)
{
  pa_file_start_level ();
  pa_file_start_mcount ("ENTRY");
  pa_file_start_file (0);
}

static void
pa_som_file_start (void)
{
  pa_file_start_level ();
  pa_file_start_space (0);
  aputs ("\t.IMPORT $global$,DATA\n"
         "\t.IMPORT $$dyncall,MILLICODE\n");
  pa_file_start_mcount ("CODE");
  pa_file_start_file (0);
}

static void
pa_linux_file_start (void)
{
  pa_file_start_file (1);
  pa_file_start_level ();
  pa_file_start_mcount ("CODE");
}

static void
pa_hpux64_gas_file_start (void)
{
  pa_file_start_level ();
#ifdef ASM_OUTPUT_TYPE_DIRECTIVE
  if (profile_flag)
    ASM_OUTPUT_TYPE_DIRECTIVE (asm_out_file, "_mcount", "function");
#endif
  pa_file_start_file (1);
}

static void
pa_hpux64_hpas_file_start (void)
{
  pa_file_start_level ();
  pa_file_start_space (1);
  pa_file_start_mcount ("CODE");
  pa_file_start_file (0);
}
#undef aputs

/* Search the deferred plabel list for SYMBOL and return its internal
   label.  If an entry for SYMBOL is not found, a new entry is created.  */

rtx
pa_get_deferred_plabel (rtx symbol)
{
  const char *fname = XSTR (symbol, 0);
  size_t i;

  /* See if we have already put this function on the list of deferred
     plabels.  This list is generally small, so a liner search is not
     too ugly.  If it proves too slow replace it with something faster.  */
  for (i = 0; i < n_deferred_plabels; i++)
    if (strcmp (fname, XSTR (deferred_plabels[i].symbol, 0)) == 0)
      break;

  /* If the deferred plabel list is empty, or this entry was not found
     on the list, create a new entry on the list.  */
  if (deferred_plabels == NULL || i == n_deferred_plabels)
    {
      tree id;

      if (deferred_plabels == 0)
	deferred_plabels =  ggc_alloc<deferred_plabel> ();
      else
        deferred_plabels = GGC_RESIZEVEC (struct deferred_plabel,
                                          deferred_plabels,
                                          n_deferred_plabels + 1);

      i = n_deferred_plabels++;
      deferred_plabels[i].internal_label = gen_label_rtx ();
      deferred_plabels[i].symbol = symbol;

      /* Gross.  We have just implicitly taken the address of this
	 function.  Mark it in the same manner as assemble_name.  */
      id = maybe_get_identifier (targetm.strip_name_encoding (fname));
      if (id)
	mark_referenced (id);
    }

  return deferred_plabels[i].internal_label;
}

static void
output_deferred_plabels (void)
{
  size_t i;

  /* If we have some deferred plabels, then we need to switch into the
     data or readonly data section, and align it to a 4 byte boundary
     before outputting the deferred plabels.  */
  if (n_deferred_plabels)
    {
      switch_to_section (flag_pic ? data_section : readonly_data_section);
      ASM_OUTPUT_ALIGN (asm_out_file, TARGET_64BIT ? 3 : 2);
    }

  /* Now output the deferred plabels.  */
  for (i = 0; i < n_deferred_plabels; i++)
    {
      targetm.asm_out.internal_label (asm_out_file, "L",
		 CODE_LABEL_NUMBER (deferred_plabels[i].internal_label));
      assemble_integer (deferred_plabels[i].symbol,
			TARGET_64BIT ? 8 : 4, TARGET_64BIT ? 64 : 32, 1);
    }
}

/* Initialize optabs to point to emulation routines.  */

static void
pa_init_libfuncs (void)
{
  if (HPUX_LONG_DOUBLE_LIBRARY)
    {
      set_optab_libfunc (add_optab, TFmode, "_U_Qfadd");
      set_optab_libfunc (sub_optab, TFmode, "_U_Qfsub");
      set_optab_libfunc (smul_optab, TFmode, "_U_Qfmpy");
      set_optab_libfunc (sdiv_optab, TFmode, "_U_Qfdiv");
      set_optab_libfunc (smin_optab, TFmode, "_U_Qmin");
      set_optab_libfunc (smax_optab, TFmode, "_U_Qfmax");
      set_optab_libfunc (sqrt_optab, TFmode, "_U_Qfsqrt");
      set_optab_libfunc (abs_optab, TFmode, "_U_Qfabs");
      set_optab_libfunc (neg_optab, TFmode, "_U_Qfneg");

      set_optab_libfunc (eq_optab, TFmode, "_U_Qfeq");
      set_optab_libfunc (ne_optab, TFmode, "_U_Qfne");
      set_optab_libfunc (gt_optab, TFmode, "_U_Qfgt");
      set_optab_libfunc (ge_optab, TFmode, "_U_Qfge");
      set_optab_libfunc (lt_optab, TFmode, "_U_Qflt");
      set_optab_libfunc (le_optab, TFmode, "_U_Qfle");
      set_optab_libfunc (unord_optab, TFmode, "_U_Qfunord");

      set_conv_libfunc (sext_optab, TFmode, SFmode, "_U_Qfcnvff_sgl_to_quad");
      set_conv_libfunc (sext_optab, TFmode, DFmode, "_U_Qfcnvff_dbl_to_quad");
      set_conv_libfunc (trunc_optab, SFmode, TFmode, "_U_Qfcnvff_quad_to_sgl");
      set_conv_libfunc (trunc_optab, DFmode, TFmode, "_U_Qfcnvff_quad_to_dbl");

      set_conv_libfunc (sfix_optab, SImode, TFmode,
			TARGET_64BIT ? "__U_Qfcnvfxt_quad_to_sgl"
				     : "_U_Qfcnvfxt_quad_to_sgl");
      set_conv_libfunc (sfix_optab, DImode, TFmode,
			"_U_Qfcnvfxt_quad_to_dbl");
      set_conv_libfunc (ufix_optab, SImode, TFmode,
			"_U_Qfcnvfxt_quad_to_usgl");
      set_conv_libfunc (ufix_optab, DImode, TFmode,
			"_U_Qfcnvfxt_quad_to_udbl");

      set_conv_libfunc (sfloat_optab, TFmode, SImode,
			"_U_Qfcnvxf_sgl_to_quad");
      set_conv_libfunc (sfloat_optab, TFmode, DImode,
			"_U_Qfcnvxf_dbl_to_quad");
      set_conv_libfunc (ufloat_optab, TFmode, SImode,
			"_U_Qfcnvxf_usgl_to_quad");
      set_conv_libfunc (ufloat_optab, TFmode, DImode,
			"_U_Qfcnvxf_udbl_to_quad");
    }

  if (TARGET_SYNC_LIBCALL)
    init_sync_libfuncs (8);
}

/* HP's millicode routines mean something special to the assembler.
   Keep track of which ones we have used.  */

enum millicodes { remI, remU, divI, divU, mulI, end1000 };
static void import_milli (enum millicodes);
static char imported[(int) end1000];
static const char * const milli_names[] = {"remI", "remU", "divI", "divU", "mulI"};
static const char import_string[] = ".IMPORT $$....,MILLICODE";
#define MILLI_START 10

static void
import_milli (enum millicodes code)
{
  char str[sizeof (import_string)];

  if (!imported[(int) code])
    {
      imported[(int) code] = 1;
      strcpy (str, import_string);
      memcpy (str + MILLI_START, milli_names[(int) code], 4);
      output_asm_insn (str, 0);
    }
}

/* The register constraints have put the operands and return value in
   the proper registers.  */

const char *
pa_output_mul_insn (int unsignedp ATTRIBUTE_UNUSED, rtx_insn *insn)
{
  import_milli (mulI);
  return pa_output_millicode_call (insn, gen_rtx_SYMBOL_REF (Pmode, "$$mulI"));
}

/* Emit the rtl for doing a division by a constant.  */

/* Do magic division millicodes exist for this value? */
const int pa_magic_milli[]= {0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1};

/* We'll use an array to keep track of the magic millicodes and
   whether or not we've used them already. [n][0] is signed, [n][1] is
   unsigned.  */

static int div_milli[16][2];

int
pa_emit_hpdiv_const (rtx *operands, int unsignedp)
{
  if (GET_CODE (operands[2]) == CONST_INT
      && INTVAL (operands[2]) > 0
      && INTVAL (operands[2]) < 16
      && pa_magic_milli[INTVAL (operands[2])])
    {
      rtx ret = gen_rtx_REG (SImode, TARGET_64BIT ? 2 : 31);

      emit_move_insn (gen_rtx_REG (SImode, 26), operands[1]);
      emit
	(gen_rtx_PARALLEL
	 (VOIDmode,
	  gen_rtvec (6, gen_rtx_SET (gen_rtx_REG (SImode, 29),
				     gen_rtx_fmt_ee (unsignedp ? UDIV : DIV,
						     SImode,
						     gen_rtx_REG (SImode, 26),
						     operands[2])),
		     gen_rtx_CLOBBER (VOIDmode, operands[4]),
		     gen_rtx_CLOBBER (VOIDmode, operands[3]),
		     gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 26)),
		     gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 25)),
		     gen_rtx_CLOBBER (VOIDmode, ret))));
      emit_move_insn (operands[0], gen_rtx_REG (SImode, 29));
      return 1;
    }
  return 0;
}

const char *
pa_output_div_insn (rtx *operands, int unsignedp, rtx_insn *insn)
{
  int divisor;

  /* If the divisor is a constant, try to use one of the special
     opcodes .*/
  if (GET_CODE (operands[0]) == CONST_INT)
    {
      static char buf[100];
      divisor = INTVAL (operands[0]);
      if (!div_milli[divisor][unsignedp])
	{
	  div_milli[divisor][unsignedp] = 1;
	  if (unsignedp)
	    output_asm_insn (".IMPORT $$divU_%0,MILLICODE", operands);
	  else
	    output_asm_insn (".IMPORT $$divI_%0,MILLICODE", operands);
	}
      if (unsignedp)
	{
	  sprintf (buf, "$$divU_" HOST_WIDE_INT_PRINT_DEC,
		   INTVAL (operands[0]));
	  return pa_output_millicode_call (insn,
					   gen_rtx_SYMBOL_REF (SImode, buf));
	}
      else
	{
	  sprintf (buf, "$$divI_" HOST_WIDE_INT_PRINT_DEC,
		   INTVAL (operands[0]));
	  return pa_output_millicode_call (insn,
					   gen_rtx_SYMBOL_REF (SImode, buf));
	}
    }
  /* Divisor isn't a special constant.  */
  else
    {
      if (unsignedp)
	{
	  import_milli (divU);
	  return pa_output_millicode_call (insn,
					gen_rtx_SYMBOL_REF (SImode, "$$divU"));
	}
      else
	{
	  import_milli (divI);
	  return pa_output_millicode_call (insn,
					gen_rtx_SYMBOL_REF (SImode, "$$divI"));
	}
    }
}

/* Output a $$rem millicode to do mod.  */

const char *
pa_output_mod_insn (int unsignedp, rtx_insn *insn)
{
  if (unsignedp)
    {
      import_milli (remU);
      return pa_output_millicode_call (insn,
				       gen_rtx_SYMBOL_REF (SImode, "$$remU"));
    }
  else
    {
      import_milli (remI);
      return pa_output_millicode_call (insn,
				       gen_rtx_SYMBOL_REF (SImode, "$$remI"));
    }
}

void
pa_output_arg_descriptor (rtx_insn *call_insn)
{
  const char *arg_regs[4];
  machine_mode arg_mode;
  rtx link;
  int i, output_flag = 0;
  int regno;

  /* We neither need nor want argument location descriptors for the
     64bit runtime environment or the ELF32 environment.  */
  if (TARGET_64BIT || TARGET_ELF32)
    return;

  for (i = 0; i < 4; i++)
    arg_regs[i] = 0;

  /* Specify explicitly that no argument relocations should take place
     if using the portable runtime calling conventions.  */
  if (TARGET_PORTABLE_RUNTIME)
    {
      fputs ("\t.CALL ARGW0=NO,ARGW1=NO,ARGW2=NO,ARGW3=NO,RETVAL=NO\n",
	     asm_out_file);
      return;
    }

  gcc_assert (CALL_P (call_insn));
  for (link = CALL_INSN_FUNCTION_USAGE (call_insn);
       link; link = XEXP (link, 1))
    {
      rtx use = XEXP (link, 0);

      if (! (GET_CODE (use) == USE
	     && GET_CODE (XEXP (use, 0)) == REG
	     && FUNCTION_ARG_REGNO_P (REGNO (XEXP (use, 0)))))
	continue;

      arg_mode = GET_MODE (XEXP (use, 0));
      regno = REGNO (XEXP (use, 0));
      if (regno >= 23 && regno <= 26)
	{
	  arg_regs[26 - regno] = "GR";
	  if (arg_mode == DImode)
	    arg_regs[25 - regno] = "GR";
	}
      else if (regno >= 32 && regno <= 39)
	{
	  if (arg_mode == SFmode)
	    arg_regs[(regno - 32) / 2] = "FR";
	  else
	    {
#ifndef HP_FP_ARG_DESCRIPTOR_REVERSED
	      arg_regs[(regno - 34) / 2] = "FR";
	      arg_regs[(regno - 34) / 2 + 1] = "FU";
#else
	      arg_regs[(regno - 34) / 2] = "FU";
	      arg_regs[(regno - 34) / 2 + 1] = "FR";
#endif
	    }
	}
    }
  fputs ("\t.CALL ", asm_out_file);
  for (i = 0; i < 4; i++)
    {
      if (arg_regs[i])
	{
	  if (output_flag++)
	    fputc (',', asm_out_file);
	  fprintf (asm_out_file, "ARGW%d=%s", i, arg_regs[i]);
	}
    }
  fputc ('\n', asm_out_file);
}

/* Inform reload about cases where moving X with a mode MODE to or from
   a register in RCLASS requires an extra scratch or immediate register.
   Return the class needed for the immediate register.  */

static reg_class_t
pa_secondary_reload (bool in_p, rtx x, reg_class_t rclass_i,
		     machine_mode mode, secondary_reload_info *sri)
{
  int regno;
  enum reg_class rclass = (enum reg_class) rclass_i;

  /* Handle the easy stuff first.  */
  if (rclass == R1_REGS)
    return NO_REGS;

  if (REG_P (x))
    {
      regno = REGNO (x);
      if (rclass == BASE_REG_CLASS && regno < FIRST_PSEUDO_REGISTER)
	return NO_REGS;
    }
  else
    regno = -1;

  /* If we have something like (mem (mem (...)), we can safely assume the
     inner MEM will end up in a general register after reloading, so there's
     no need for a secondary reload.  */
  if (GET_CODE (x) == MEM && GET_CODE (XEXP (x, 0)) == MEM)
    return NO_REGS;

  /* Trying to load a constant into a FP register during PIC code
     generation requires %r1 as a scratch register.  For float modes,
     the only legitimate constant is CONST0_RTX.  However, there are
     a few patterns that accept constant double operands.  */
  if (flag_pic
      && FP_REG_CLASS_P (rclass)
      && (GET_CODE (x) == CONST_INT || GET_CODE (x) == CONST_DOUBLE))
    {
      switch (mode)
	{
	case E_SImode:
	  sri->icode = CODE_FOR_reload_insi_r1;
	  break;

	case E_DImode:
	  sri->icode = CODE_FOR_reload_indi_r1;
	  break;

	case E_SFmode:
	  sri->icode = CODE_FOR_reload_insf_r1;
	  break;

	case E_DFmode:
	  sri->icode = CODE_FOR_reload_indf_r1;
	  break;

	default:
	  gcc_unreachable ();
	}
      return NO_REGS;
    }

  /* Secondary reloads of symbolic expressions require %r1 as a scratch
     register when we're generating PIC code or when the operand isn't
     readonly.  */
  if (pa_symbolic_expression_p (x))
    {
      if (GET_CODE (x) == HIGH)
	x = XEXP (x, 0);

      if (flag_pic || !read_only_operand (x, VOIDmode))
	{
	  switch (mode)
	    {
	    case E_SImode:
	      sri->icode = CODE_FOR_reload_insi_r1;
	      break;

	    case E_DImode:
	      sri->icode = CODE_FOR_reload_indi_r1;
	      break;

	    default:
	      gcc_unreachable ();
	    }
	  return NO_REGS;
	}
    }

  /* Profiling showed the PA port spends about 1.3% of its compilation
     time in true_regnum from calls inside pa_secondary_reload_class.  */
  if (regno >= FIRST_PSEUDO_REGISTER || GET_CODE (x) == SUBREG)
    regno = true_regnum (x);

  /* Handle reloads for floating point loads and stores.  */
  if ((regno >= FIRST_PSEUDO_REGISTER || regno == -1)
      && FP_REG_CLASS_P (rclass))
    {
      if (MEM_P (x))
	{
	  x = XEXP (x, 0);

	  /* We don't need a secondary reload for indexed memory addresses.

	     When INT14_OK_STRICT is true, it might appear that we could
	     directly allow register indirect memory addresses.  However,
	     this doesn't work because we don't support SUBREGs in
	     floating-point register copies and reload doesn't tell us
	     when it's going to use a SUBREG.  */
	  if (IS_INDEX_ADDR_P (x))
	    return NO_REGS;
	}

      /* Request a secondary reload with a general scratch register
	 for everything else.  ??? Could symbolic operands be handled
	 directly when generating non-pic PA 2.0 code?  */
      sri->icode = (in_p
		    ? direct_optab_handler (reload_in_optab, mode)
		    : direct_optab_handler (reload_out_optab, mode));
      return NO_REGS;
    }

  /* A SAR<->FP register copy requires an intermediate general register
     and secondary memory.  We need a secondary reload with a general
     scratch register for spills.  */
  if (rclass == SHIFT_REGS)
    {
      /* Handle spill.  */
      if (regno >= FIRST_PSEUDO_REGISTER || regno < 0)
	{
	  sri->icode = (in_p
			? direct_optab_handler (reload_in_optab, mode)
			: direct_optab_handler (reload_out_optab, mode));
	  return NO_REGS;
	}

      /* Handle FP copy.  */
      if (FP_REG_CLASS_P (REGNO_REG_CLASS (regno)))
	return GENERAL_REGS;
    }

  if (regno >= 0 && regno < FIRST_PSEUDO_REGISTER
      && REGNO_REG_CLASS (regno) == SHIFT_REGS
      && FP_REG_CLASS_P (rclass))
    return GENERAL_REGS;

  return NO_REGS;
}

/* Implement TARGET_SECONDARY_MEMORY_NEEDED.  */

static bool
pa_secondary_memory_needed (machine_mode mode ATTRIBUTE_UNUSED,
			    reg_class_t class1 ATTRIBUTE_UNUSED,
			    reg_class_t class2 ATTRIBUTE_UNUSED)
{
#ifdef PA_SECONDARY_MEMORY_NEEDED
  return PA_SECONDARY_MEMORY_NEEDED (mode, class1, class2);
#else
  return false;
#endif
}

/* Implement TARGET_EXTRA_LIVE_ON_ENTRY.  The argument pointer
   is only marked as live on entry by df-scan when it is a fixed
   register.  It isn't a fixed register in the 64-bit runtime,
   so we need to mark it here.  */

static void
pa_extra_live_on_entry (bitmap regs)
{
  if (TARGET_64BIT)
    bitmap_set_bit (regs, ARG_POINTER_REGNUM);
}

/* Implement EH_RETURN_HANDLER_RTX.  The MEM needs to be volatile
   to prevent it from being deleted.  */

rtx
pa_eh_return_handler_rtx (void)
{
  rtx tmp;

  tmp = gen_rtx_PLUS (word_mode, hard_frame_pointer_rtx,
		      TARGET_64BIT ? GEN_INT (-16) : GEN_INT (-20));
  tmp = gen_rtx_MEM (word_mode, tmp);
  tmp->volatil = 1;
  return tmp;
}

/* In the 32-bit runtime, arguments larger than eight bytes are passed
   by invisible reference.  As a GCC extension, we also pass anything
   with a zero or variable size by reference.

   The 64-bit runtime does not describe passing any types by invisible
   reference.  The internals of GCC can't currently handle passing
   empty structures, and zero or variable length arrays when they are
   not passed entirely on the stack or by reference.  Thus, as a GCC
   extension, we pass these types by reference.  The HP compiler doesn't
   support these types, so hopefully there shouldn't be any compatibility
   issues.  This may have to be revisited when HP releases a C99 compiler
   or updates the ABI.  */

static bool
pa_pass_by_reference (cumulative_args_t, const function_arg_info &arg)
{
  HOST_WIDE_INT size = arg.type_size_in_bytes ();
  if (TARGET_64BIT)
    return size <= 0;
  else
    return size <= 0 || size > 8;
}

/* Implement TARGET_FUNCTION_ARG_PADDING.  */

static pad_direction
pa_function_arg_padding (machine_mode mode, const_tree type)
{
  if (mode == BLKmode
      || (TARGET_64BIT
	  && type
	  && (AGGREGATE_TYPE_P (type)
	      || TREE_CODE (type) == COMPLEX_TYPE
	      || TREE_CODE (type) == VECTOR_TYPE)))
    {
      /* Return PAD_NONE if justification is not required.  */
      if (type
	  && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST
	  && (int_size_in_bytes (type) * BITS_PER_UNIT) % PARM_BOUNDARY == 0)
	return PAD_NONE;

      /* The directions set here are ignored when a BLKmode argument larger
	 than a word is placed in a register.  Different code is used for
	 the stack and registers.  This makes it difficult to have a
	 consistent data representation for both the stack and registers.
	 For both runtimes, the justification and padding for arguments on
	 the stack and in registers should be identical.  */
      if (TARGET_64BIT)
	/* The 64-bit runtime specifies left justification for aggregates.  */
	return PAD_UPWARD;
      else
	/* The 32-bit runtime architecture specifies right justification.
	   When the argument is passed on the stack, the argument is padded
	   with garbage on the left.  The HP compiler pads with zeros.  */
	return PAD_DOWNWARD;
    }

  if (GET_MODE_BITSIZE (mode) < PARM_BOUNDARY)
    return PAD_DOWNWARD;
  else
    return PAD_NONE;
}


/* Do what is necessary for `va_start'.  We look at the current function
   to determine if stdargs or varargs is used and fill in an initial
   va_list.  A pointer to this constructor is returned.  */

static rtx
hppa_builtin_saveregs (void)
{
  rtx offset, dest;
  tree fntype = TREE_TYPE (current_function_decl);
  int argadj = ((!stdarg_p (fntype))
		? UNITS_PER_WORD : 0);

  if (argadj)
    offset = plus_constant (Pmode, crtl->args.arg_offset_rtx, argadj);
  else
    offset = crtl->args.arg_offset_rtx;

  if (TARGET_64BIT)
    {
      int i, off;

      /* Adjust for varargs/stdarg differences.  */
      if (argadj)
	offset = plus_constant (Pmode, crtl->args.arg_offset_rtx, -argadj);
      else
	offset = crtl->args.arg_offset_rtx;

      /* We need to save %r26 .. %r19 inclusive starting at offset -64
	 from the incoming arg pointer and growing to larger addresses.  */
      for (i = 26, off = -64; i >= 19; i--, off += 8)
	emit_move_insn (gen_rtx_MEM (word_mode,
				     plus_constant (Pmode,
						    arg_pointer_rtx, off)),
			gen_rtx_REG (word_mode, i));

      /* The incoming args pointer points just beyond the flushback area;
	 normally this is not a serious concern.  However, when we are doing
	 varargs/stdargs we want to make the arg pointer point to the start
	 of the incoming argument area.  */
      emit_move_insn (virtual_incoming_args_rtx,
		      plus_constant (Pmode, arg_pointer_rtx, -64));

      /* Now return a pointer to the first anonymous argument.  */
      return copy_to_reg (expand_binop (Pmode, add_optab,
					virtual_incoming_args_rtx,
					offset, 0, 0, OPTAB_LIB_WIDEN));
    }

  /* Store general registers on the stack.  */
  dest = gen_rtx_MEM (BLKmode,
		      plus_constant (Pmode, crtl->args.internal_arg_pointer,
				     -16));
  set_mem_alias_set (dest, get_varargs_alias_set ());
  set_mem_align (dest, BITS_PER_WORD);
  move_block_from_reg (23, dest, 4);

  /* move_block_from_reg will emit code to store the argument registers
     individually as scalar stores.

     However, other insns may later load from the same addresses for
     a structure load (passing a struct to a varargs routine).

     The alias code assumes that such aliasing can never happen, so we
     have to keep memory referencing insns from moving up beyond the
     last argument register store.  So we emit a blockage insn here.  */
  emit_insn (gen_blockage ());

  return copy_to_reg (expand_binop (Pmode, add_optab,
				    crtl->args.internal_arg_pointer,
				    offset, 0, 0, OPTAB_LIB_WIDEN));
}

static void
hppa_va_start (tree valist, rtx nextarg)
{
  nextarg = expand_builtin_saveregs ();
  std_expand_builtin_va_start (valist, nextarg);
}

static tree
hppa_gimplify_va_arg_expr (tree valist, tree type, gimple_seq *pre_p,
			   gimple_seq *post_p)
{
  if (TARGET_64BIT)
    {
      /* Args grow upward.  We can use the generic routines.  */
      return std_gimplify_va_arg_expr (valist, type, pre_p, post_p);
    }
  else /* !TARGET_64BIT */
    {
      tree ptr = build_pointer_type (type);
      tree valist_type;
      tree t, u;
      unsigned int size, ofs;
      bool indirect;

      indirect = pass_va_arg_by_reference (type);
      if (indirect)
	{
	  type = ptr;
	  ptr = build_pointer_type (type);
	}
      size = int_size_in_bytes (type);
      valist_type = TREE_TYPE (valist);

      /* Args grow down.  Not handled by generic routines.  */

      u = fold_convert (sizetype, size_in_bytes (type));
      u = fold_build1 (NEGATE_EXPR, sizetype, u);
      t = fold_build_pointer_plus (valist, u);

      /* Align to 4 or 8 byte boundary depending on argument size.  */

      u = build_int_cst (TREE_TYPE (t), (HOST_WIDE_INT)(size > 4 ? -8 : -4));
      t = build2 (BIT_AND_EXPR, TREE_TYPE (t), t, u);
      t = fold_convert (valist_type, t);

      t = build2 (MODIFY_EXPR, valist_type, valist, t);

      ofs = (8 - size) % 4;
      if (ofs != 0)
	t = fold_build_pointer_plus_hwi (t, ofs);

      t = fold_convert (ptr, t);
      t = build_va_arg_indirect_ref (t);

      if (indirect)
	t = build_va_arg_indirect_ref (t);

      return t;
    }
}

/* True if MODE is valid for the target.  By "valid", we mean able to
   be manipulated in non-trivial ways.  In particular, this means all
   the arithmetic is supported.

   Currently, TImode is not valid as the HP 64-bit runtime documentation
   doesn't document the alignment and calling conventions for this type. 
   Thus, we return false when PRECISION is 2 * BITS_PER_WORD and
   2 * BITS_PER_WORD isn't equal LONG_LONG_TYPE_SIZE.  */

static bool
pa_scalar_mode_supported_p (scalar_mode mode)
{
  int precision = GET_MODE_PRECISION (mode);

  switch (GET_MODE_CLASS (mode))
    {
    case MODE_PARTIAL_INT:
    case MODE_INT:
      if (precision == CHAR_TYPE_SIZE)
	return true;
      if (precision == SHORT_TYPE_SIZE)
	return true;
      if (precision == INT_TYPE_SIZE)
	return true;
      if (precision == LONG_TYPE_SIZE)
	return true;
      if (precision == LONG_LONG_TYPE_SIZE)
	return true;
      return false;

    case MODE_FLOAT:
      if (precision == FLOAT_TYPE_SIZE)
	return true;
      if (precision == DOUBLE_TYPE_SIZE)
	return true;
      if (precision == LONG_DOUBLE_TYPE_SIZE)
	return true;
      return false;

    case MODE_DECIMAL_FLOAT:
      return false;

    default:
      gcc_unreachable ();
    }
}

/* Return TRUE if INSN, a jump insn, has an unfilled delay slot and
   it branches into the delay slot.  Otherwise, return FALSE.  */

static bool
branch_to_delay_slot_p (rtx_insn *insn)
{
  rtx_insn *jump_insn;

  if (dbr_sequence_length ())
    return FALSE;

  jump_insn = next_active_insn (JUMP_LABEL_AS_INSN (insn));
  while (insn)
    {
      insn = next_active_insn (insn);
      if (jump_insn == insn)
	return TRUE;

      /* We can't rely on the length of asms.  So, we return FALSE when
	 the branch is followed by an asm.  */
      if (!insn
	  || GET_CODE (PATTERN (insn)) == ASM_INPUT
	  || asm_noperands (PATTERN (insn)) >= 0
	  || get_attr_length (insn) > 0)
	break;
    }

  return FALSE;
}

/* Return TRUE if INSN, a forward jump insn, needs a nop in its delay slot.

   This occurs when INSN has an unfilled delay slot and is followed
   by an asm.  Disaster can occur if the asm is empty and the jump
   branches into the delay slot.  So, we add a nop in the delay slot
   when this occurs.  */

static bool
branch_needs_nop_p (rtx_insn *insn)
{
  rtx_insn *jump_insn;

  if (dbr_sequence_length ())
    return FALSE;

  jump_insn = next_active_insn (JUMP_LABEL_AS_INSN (insn));
  while (insn)
    {
      insn = next_active_insn (insn);
      if (!insn || jump_insn == insn)
	return TRUE;

      if (!(GET_CODE (PATTERN (insn)) == ASM_INPUT
	   || asm_noperands (PATTERN (insn)) >= 0)
	  && get_attr_length (insn) > 0)
	break;
    }

  return FALSE;
}

/* Return TRUE if INSN, a forward jump insn, can use nullification
   to skip the following instruction.  This avoids an extra cycle due
   to a mis-predicted branch when we fall through.  */

static bool
use_skip_p (rtx_insn *insn)
{
  rtx_insn *jump_insn = next_active_insn (JUMP_LABEL_AS_INSN (insn));

  while (insn)
    {
      insn = next_active_insn (insn);

      /* We can't rely on the length of asms, so we can't skip asms.  */
      if (!insn
	  || GET_CODE (PATTERN (insn)) == ASM_INPUT
	  || asm_noperands (PATTERN (insn)) >= 0)
	break;
      if (get_attr_length (insn) == 4
	  && jump_insn == next_active_insn (insn))
	return TRUE;
      if (get_attr_length (insn) > 0)
	break;
    }

  return FALSE;
}

/* This routine handles all the normal conditional branch sequences we
   might need to generate.  It handles compare immediate vs compare
   register, nullification of delay slots, varying length branches,
   negated branches, and all combinations of the above.  It returns the
   output appropriate to emit the branch corresponding to all given
   parameters.  */

const char *
pa_output_cbranch (rtx *operands, int negated, rtx_insn *insn)
{
  static char buf[100];
  bool useskip;
  int nullify = INSN_ANNULLED_BRANCH_P (insn);
  int length = get_attr_length (insn);
  int xdelay;

  /* A conditional branch to the following instruction (e.g. the delay slot)
     is asking for a disaster.  This can happen when not optimizing and
     when jump optimization fails.

     While it is usually safe to emit nothing, this can fail if the
     preceding instruction is a nullified branch with an empty delay
     slot and the same branch target as this branch.  We could check
     for this but jump optimization should eliminate nop jumps.  It
     is always safe to emit a nop.  */
  if (branch_to_delay_slot_p (insn))
    return "nop";

  /* The doubleword form of the cmpib instruction doesn't have the LEU
     and GTU conditions while the cmpb instruction does.  Since we accept
     zero for cmpb, we must ensure that we use cmpb for the comparison.  */
  if (GET_MODE (operands[1]) == DImode && operands[2] == const0_rtx)
    operands[2] = gen_rtx_REG (DImode, 0);
  if (GET_MODE (operands[2]) == DImode && operands[1] == const0_rtx)
    operands[1] = gen_rtx_REG (DImode, 0);

  /* If this is a long branch with its delay slot unfilled, set `nullify'
     as it can nullify the delay slot and save a nop.  */
  if (length == 8 && dbr_sequence_length () == 0)
    nullify = 1;

  /* If this is a short forward conditional branch which did not get
     its delay slot filled, the delay slot can still be nullified.  */
  if (! nullify && length == 4 && dbr_sequence_length () == 0)
    nullify = forward_branch_p (insn);

  /* A forward branch over a single nullified insn can be done with a
     comclr instruction.  This avoids a single cycle penalty due to
     mis-predicted branch if we fall through (branch not taken).  */
  useskip = (length == 4 && nullify) ? use_skip_p (insn) : FALSE;

  switch (length)
    {
      /* All short conditional branches except backwards with an unfilled
	 delay slot.  */
      case 4:
	if (useskip)
	  strcpy (buf, "{com%I2clr,|cmp%I2clr,}");
	else
	  strcpy (buf, "{com%I2b,|cmp%I2b,}");
	if (GET_MODE (operands[1]) == DImode)
	  strcat (buf, "*");
	if (negated)
	  strcat (buf, "%B3");
	else
	  strcat (buf, "%S3");
	if (useskip)
	  strcat (buf, " %2,%r1,%%r0");
	else if (nullify)
	  {
	    if (branch_needs_nop_p (insn))
	      strcat (buf, ",n %2,%r1,%0%#");
	    else
	      strcat (buf, ",n %2,%r1,%0");
	  }
	else
	  strcat (buf, " %2,%r1,%0");
	break;

     /* All long conditionals.  Note a short backward branch with an
	unfilled delay slot is treated just like a long backward branch
	with an unfilled delay slot.  */
      case 8:
	/* Handle weird backwards branch with a filled delay slot
	   which is nullified.  */
	if (dbr_sequence_length () != 0
	    && ! forward_branch_p (insn)
	    && nullify)
	  {
	    strcpy (buf, "{com%I2b,|cmp%I2b,}");
	    if (GET_MODE (operands[1]) == DImode)
	      strcat (buf, "*");
	    if (negated)
	      strcat (buf, "%S3");
	    else
	      strcat (buf, "%B3");
	    strcat (buf, ",n %2,%r1,.+12\n\tb %0");
	  }
	/* Handle short backwards branch with an unfilled delay slot.
	   Using a comb;nop rather than comiclr;bl saves 1 cycle for both
	   taken and untaken branches.  */
	else if (dbr_sequence_length () == 0
		 && ! forward_branch_p (insn)
		 && INSN_ADDRESSES_SET_P ()
		 && VAL_14_BITS_P (INSN_ADDRESSES (INSN_UID (JUMP_LABEL (insn)))
				    - INSN_ADDRESSES (INSN_UID (insn)) - 8))
	  {
	    strcpy (buf, "{com%I2b,|cmp%I2b,}");
	    if (GET_MODE (operands[1]) == DImode)
	      strcat (buf, "*");
	    if (negated)
	      strcat (buf, "%B3 %2,%r1,%0%#");
	    else
	      strcat (buf, "%S3 %2,%r1,%0%#");
	  }
	else
	  {
	    strcpy (buf, "{com%I2clr,|cmp%I2clr,}");
	    if (GET_MODE (operands[1]) == DImode)
	      strcat (buf, "*");
	    if (negated)
	      strcat (buf, "%S3");
	    else
	      strcat (buf, "%B3");
	    if (nullify)
	      strcat (buf, " %2,%r1,%%r0\n\tb,n %0");
	    else
	      strcat (buf, " %2,%r1,%%r0\n\tb %0");
	  }
	break;

      default:
	/* The reversed conditional branch must branch over one additional
	   instruction if the delay slot is filled and needs to be extracted
	   by pa_output_lbranch.  If the delay slot is empty or this is a
	   nullified forward branch, the instruction after the reversed
	   condition branch must be nullified.  */
	if (dbr_sequence_length () == 0
	    || (nullify && forward_branch_p (insn)))
	  {
	    nullify = 1;
	    xdelay = 0;
	    operands[4] = GEN_INT (length);
	  }
	else
	  {
	    xdelay = 1;
	    operands[4] = GEN_INT (length + 4);
	  }

	/* Create a reversed conditional branch which branches around
	   the following insns.  */
	if (GET_MODE (operands[1]) != DImode)
	  {
	    if (nullify)
	      {
		if (negated)
		  strcpy (buf,
		    "{com%I2b,%S3,n %2,%r1,.+%4|cmp%I2b,%S3,n %2,%r1,.+%4}");
		else
		  strcpy (buf,
		    "{com%I2b,%B3,n %2,%r1,.+%4|cmp%I2b,%B3,n %2,%r1,.+%4}");
	      }
	    else
	      {
		if (negated)
		  strcpy (buf,
		    "{com%I2b,%S3 %2,%r1,.+%4|cmp%I2b,%S3 %2,%r1,.+%4}");
		else
		  strcpy (buf,
		    "{com%I2b,%B3 %2,%r1,.+%4|cmp%I2b,%B3 %2,%r1,.+%4}");
	      }
	  }
	else
	  {
	    if (nullify)
	      {
		if (negated)
		  strcpy (buf,
		    "{com%I2b,*%S3,n %2,%r1,.+%4|cmp%I2b,*%S3,n %2,%r1,.+%4}");
		else
		  strcpy (buf,
		    "{com%I2b,*%B3,n %2,%r1,.+%4|cmp%I2b,*%B3,n %2,%r1,.+%4}");
	      }
	    else
	      {
		if (negated)
		  strcpy (buf,
		    "{com%I2b,*%S3 %2,%r1,.+%4|cmp%I2b,*%S3 %2,%r1,.+%4}");
		else
		  strcpy (buf,
		    "{com%I2b,*%B3 %2,%r1,.+%4|cmp%I2b,*%B3 %2,%r1,.+%4}");
	      }
	  }

	output_asm_insn (buf, operands);
	return pa_output_lbranch (operands[0], insn, xdelay);
    }
  return buf;
}

/* Output a PIC pc-relative instruction sequence to load the address of
   OPERANDS[0] to register OPERANDS[2].  OPERANDS[0] is a symbol ref
   or a code label.  OPERANDS[1] specifies the register to use to load
   the program counter.  OPERANDS[3] may be used for label generation
   The sequence is always three instructions in length.  The program
   counter recorded for PA 1.X is eight bytes more than that for PA 2.0.
   Register %r1 is clobbered.  */

static void
pa_output_pic_pcrel_sequence (rtx *operands)
{
  gcc_assert (SYMBOL_REF_P (operands[0]) || LABEL_P (operands[0]));
  if (TARGET_PA_20)
    {
      /* We can use mfia to determine the current program counter.  */
      if (TARGET_SOM || !TARGET_GAS)
	{
	  operands[3] = gen_label_rtx ();
	  targetm.asm_out.internal_label (asm_out_file, "L",
					  CODE_LABEL_NUMBER (operands[3]));
	  output_asm_insn ("mfia %1", operands);
	  output_asm_insn ("addil L'%0-%l3,%1", operands);
	  output_asm_insn ("ldo R'%0-%l3(%%r1),%2", operands);
	}
      else
	{
	  output_asm_insn ("mfia %1", operands);
	  output_asm_insn ("addil L'%0-$PIC_pcrel$0+12,%1", operands);
	  output_asm_insn ("ldo R'%0-$PIC_pcrel$0+16(%%r1),%2", operands);
	}
    }
  else
    {
      /* We need to use a branch to determine the current program counter.  */
      output_asm_insn ("{bl|b,l} .+8,%1", operands);
      if (TARGET_SOM || !TARGET_GAS)
	{
	  operands[3] = gen_label_rtx ();
	  output_asm_insn ("addil L'%0-%l3,%1", operands);
	  targetm.asm_out.internal_label (asm_out_file, "L",
					  CODE_LABEL_NUMBER (operands[3]));
	  output_asm_insn ("ldo R'%0-%l3(%%r1),%2", operands);
	}
      else
	{
	  output_asm_insn ("addil L'%0-$PIC_pcrel$0+4,%1", operands);
	  output_asm_insn ("ldo R'%0-$PIC_pcrel$0+8(%%r1),%2", operands);
	}
    }
}

/* This routine handles output of long unconditional branches that
   exceed the maximum range of a simple branch instruction.  Since
   we don't have a register available for the branch, we save register
   %r1 in the frame marker, load the branch destination DEST into %r1,
   execute the branch, and restore %r1 in the delay slot of the branch.

   Since long branches may have an insn in the delay slot and the
   delay slot is used to restore %r1, we in general need to extract
   this insn and execute it before the branch.  However, to facilitate
   use of this function by conditional branches, we also provide an
   option to not extract the delay insn so that it will be emitted
   after the long branch.  So, if there is an insn in the delay slot,
   it is extracted if XDELAY is nonzero.

   The lengths of the various long-branch sequences are 20, 16 and 24
   bytes for the portable runtime, non-PIC and PIC cases, respectively.  */

const char *
pa_output_lbranch (rtx dest, rtx_insn *insn, int xdelay)
{
  rtx xoperands[4];
 
  xoperands[0] = dest;

  /* First, free up the delay slot.  */
  if (xdelay && dbr_sequence_length () != 0)
    {
      /* We can't handle a jump in the delay slot.  */
      gcc_assert (! JUMP_P (NEXT_INSN (insn)));

      final_scan_insn (NEXT_INSN (insn), asm_out_file,
		       optimize, 0, NULL);

      /* Now delete the delay insn.  */
      SET_INSN_DELETED (NEXT_INSN (insn));
    }

  /* Output an insn to save %r1.  The runtime documentation doesn't
     specify whether the "Clean Up" slot in the callers frame can
     be clobbered by the callee.  It isn't copied by HP's builtin
     alloca, so this suggests that it can be clobbered if necessary.
     The "Static Link" location is copied by HP builtin alloca, so
     we avoid using it.  Using the cleanup slot might be a problem
     if we have to interoperate with languages that pass cleanup
     information.  However, it should be possible to handle these
     situations with GCC's asm feature.

     The "Current RP" slot is reserved for the called procedure, so
     we try to use it when we don't have a frame of our own.  It's
     rather unlikely that we won't have a frame when we need to emit
     a very long branch.

     Really the way to go long term is a register scavenger; goto
     the target of the jump and find a register which we can use
     as a scratch to hold the value in %r1.  Then, we wouldn't have
     to free up the delay slot or clobber a slot that may be needed
     for other purposes.  */
  if (TARGET_64BIT)
    {
      if (actual_fsize == 0 && !df_regs_ever_live_p (2))
	/* Use the return pointer slot in the frame marker.  */
	output_asm_insn ("std %%r1,-16(%%r30)", xoperands);
      else
	/* Use the slot at -40 in the frame marker since HP builtin
	   alloca doesn't copy it.  */
	output_asm_insn ("std %%r1,-40(%%r30)", xoperands);
    }
  else
    {
      if (actual_fsize == 0 && !df_regs_ever_live_p (2))
	/* Use the return pointer slot in the frame marker.  */
	output_asm_insn ("stw %%r1,-20(%%r30)", xoperands);
      else
	/* Use the "Clean Up" slot in the frame marker.  In GCC,
	   the only other use of this location is for copying a
	   floating point double argument from a floating-point
	   register to two general registers.  The copy is done
	   as an "atomic" operation when outputting a call, so it
	   won't interfere with our using the location here.  */
	output_asm_insn ("stw %%r1,-12(%%r30)", xoperands);
    }

  if (TARGET_PORTABLE_RUNTIME)
    {
      output_asm_insn ("ldil L'%0,%%r1", xoperands);
      output_asm_insn ("ldo R'%0(%%r1),%%r1", xoperands);
      output_asm_insn ("bv %%r0(%%r1)", xoperands);
    }
  else if (flag_pic)
    {
      xoperands[1] = gen_rtx_REG (Pmode, 1);
      xoperands[2] = xoperands[1];
      pa_output_pic_pcrel_sequence (xoperands);
      output_asm_insn ("bv %%r0(%%r1)", xoperands);
    }
  else
    /* Now output a very long branch to the original target.  */
    output_asm_insn ("ldil L'%l0,%%r1\n\tbe R'%l0(%%sr4,%%r1)", xoperands);

  /* Now restore the value of %r1 in the delay slot.  */
  if (TARGET_64BIT)
    {
      if (actual_fsize == 0 && !df_regs_ever_live_p (2))
	return "ldd -16(%%r30),%%r1";
      else
	return "ldd -40(%%r30),%%r1";
    }
  else
    {
      if (actual_fsize == 0 && !df_regs_ever_live_p (2))
	return "ldw -20(%%r30),%%r1";
      else
	return "ldw -12(%%r30),%%r1";
    }
}

/* This routine handles all the branch-on-bit conditional branch sequences we
   might need to generate.  It handles nullification of delay slots,
   varying length branches, negated branches and all combinations of the
   above.  it returns the appropriate output template to emit the branch.  */

const char *
pa_output_bb (rtx *operands ATTRIBUTE_UNUSED, int negated, rtx_insn *insn, int which)
{
  static char buf[100];
  bool useskip;
  int nullify = INSN_ANNULLED_BRANCH_P (insn);
  int length = get_attr_length (insn);
  int xdelay;

  /* A conditional branch to the following instruction (e.g. the delay slot) is
     asking for a disaster.  I do not think this can happen as this pattern
     is only used when optimizing; jump optimization should eliminate the
     jump.  But be prepared just in case.  */

  if (branch_to_delay_slot_p (insn))
    return "nop";

  /* If this is a long branch with its delay slot unfilled, set `nullify'
     as it can nullify the delay slot and save a nop.  */
  if (length == 8 && dbr_sequence_length () == 0)
    nullify = 1;

  /* If this is a short forward conditional branch which did not get
     its delay slot filled, the delay slot can still be nullified.  */
  if (! nullify && length == 4 && dbr_sequence_length () == 0)
    nullify = forward_branch_p (insn);

  /* A forward branch over a single nullified insn can be done with a
     extrs instruction.  This avoids a single cycle penalty due to
     mis-predicted branch if we fall through (branch not taken).  */
  useskip = (length == 4 && nullify) ? use_skip_p (insn) : FALSE;

  switch (length)
    {

      /* All short conditional branches except backwards with an unfilled
	 delay slot.  */
      case 4:
	if (useskip)
	  strcpy (buf, "{extrs,|extrw,s,}");
	else
	  strcpy (buf, "bb,");
	if (useskip && GET_MODE (operands[0]) == DImode)
	  strcpy (buf, "extrd,s,*");
	else if (GET_MODE (operands[0]) == DImode)
	  strcpy (buf, "bb,*");
	if ((which == 0 && negated)
	     || (which == 1 && ! negated))
	  strcat (buf, ">=");
	else
	  strcat (buf, "<");
	if (useskip)
	  strcat (buf, " %0,%1,1,%%r0");
	else if (nullify && negated)
	  {
	    if (branch_needs_nop_p (insn))
	      strcat (buf, ",n %0,%1,%3%#");
	    else
	      strcat (buf, ",n %0,%1,%3");
	  }
	else if (nullify && ! negated)
	  {
	    if (branch_needs_nop_p (insn))
	      strcat (buf, ",n %0,%1,%2%#");
	    else
	      strcat (buf, ",n %0,%1,%2");
	  }
	else if (! nullify && negated)
	  strcat (buf, " %0,%1,%3");
	else if (! nullify && ! negated)
	  strcat (buf, " %0,%1,%2");
	break;

     /* All long conditionals.  Note a short backward branch with an
	unfilled delay slot is treated just like a long backward branch
	with an unfilled delay slot.  */
      case 8:
	/* Handle weird backwards branch with a filled delay slot
	   which is nullified.  */
	if (dbr_sequence_length () != 0
	    && ! forward_branch_p (insn)
	    && nullify)
	  {
	    strcpy (buf, "bb,");
	    if (GET_MODE (operands[0]) == DImode)
	      strcat (buf, "*");
	    if ((which == 0 && negated)
		|| (which == 1 && ! negated))
	      strcat (buf, "<");
	    else
	      strcat (buf, ">=");
	    if (negated)
	      strcat (buf, ",n %0,%1,.+12\n\tb %3");
	    else
	      strcat (buf, ",n %0,%1,.+12\n\tb %2");
	  }
	/* Handle short backwards branch with an unfilled delay slot.
	   Using a bb;nop rather than extrs;bl saves 1 cycle for both
	   taken and untaken branches.  */
	else if (dbr_sequence_length () == 0
		 && ! forward_branch_p (insn)
		 && INSN_ADDRESSES_SET_P ()
		 && VAL_14_BITS_P (INSN_ADDRESSES (INSN_UID (JUMP_LABEL (insn)))
				    - INSN_ADDRESSES (INSN_UID (insn)) - 8))
	  {
	    strcpy (buf, "bb,");
	    if (GET_MODE (operands[0]) == DImode)
	      strcat (buf, "*");
	    if ((which == 0 && negated)
		|| (which == 1 && ! negated))
	      strcat (buf, ">=");
	    else
	      strcat (buf, "<");
	    if (negated)
	      strcat (buf, " %0,%1,%3%#");
	    else
	      strcat (buf, " %0,%1,%2%#");
	  }
	else
	  {
	    if (GET_MODE (operands[0]) == DImode)
	      strcpy (buf, "extrd,s,*");
	    else
	      strcpy (buf, "{extrs,|extrw,s,}");
	    if ((which == 0 && negated)
		|| (which == 1 && ! negated))
	      strcat (buf, "<");
	    else
	      strcat (buf, ">=");
	    if (nullify && negated)
	      strcat (buf, " %0,%1,1,%%r0\n\tb,n %3");
	    else if (nullify && ! negated)
	      strcat (buf, " %0,%1,1,%%r0\n\tb,n %2");
	    else if (negated)
	      strcat (buf, " %0,%1,1,%%r0\n\tb %3");
	    else
	      strcat (buf, " %0,%1,1,%%r0\n\tb %2");
	  }
	break;

      default:
	/* The reversed conditional branch must branch over one additional
	   instruction if the delay slot is filled and needs to be extracted
	   by pa_output_lbranch.  If the delay slot is empty or this is a
	   nullified forward branch, the instruction after the reversed
	   condition branch must be nullified.  */
	if (dbr_sequence_length () == 0
	    || (nullify && forward_branch_p (insn)))
	  {
	    nullify = 1;
	    xdelay = 0;
	    operands[4] = GEN_INT (length);
	  }
	else
	  {
	    xdelay = 1;
	    operands[4] = GEN_INT (length + 4);
	  }

	if (GET_MODE (operands[0]) == DImode)
	  strcpy (buf, "bb,*");
	else
	  strcpy (buf, "bb,");
	if ((which == 0 && negated)
	    || (which == 1 && !negated))
	  strcat (buf, "<");
	else
	  strcat (buf, ">=");
	if (nullify)
	  strcat (buf, ",n %0,%1,.+%4");
	else
	  strcat (buf, " %0,%1,.+%4");
	output_asm_insn (buf, operands);
	return pa_output_lbranch (negated ? operands[3] : operands[2],
				  insn, xdelay);
    }
  return buf;
}

/* This routine handles all the branch-on-variable-bit conditional branch
   sequences we might need to generate.  It handles nullification of delay
   slots, varying length branches, negated branches and all combinations
   of the above.  it returns the appropriate output template to emit the
   branch.  */

const char *
pa_output_bvb (rtx *operands ATTRIBUTE_UNUSED, int negated, rtx_insn *insn,
	       int which)
{
  static char buf[100];
  bool useskip;
  int nullify = INSN_ANNULLED_BRANCH_P (insn);
  int length = get_attr_length (insn);
  int xdelay;

  /* A conditional branch to the following instruction (e.g. the delay slot) is
     asking for a disaster.  I do not think this can happen as this pattern
     is only used when optimizing; jump optimization should eliminate the
     jump.  But be prepared just in case.  */

  if (branch_to_delay_slot_p (insn))
    return "nop";

  /* If this is a long branch with its delay slot unfilled, set `nullify'
     as it can nullify the delay slot and save a nop.  */
  if (length == 8 && dbr_sequence_length () == 0)
    nullify = 1;

  /* If this is a short forward conditional branch which did not get
     its delay slot filled, the delay slot can still be nullified.  */
  if (! nullify && length == 4 && dbr_sequence_length () == 0)
    nullify = forward_branch_p (insn);

  /* A forward branch over a single nullified insn can be done with a
     extrs instruction.  This avoids a single cycle penalty due to
     mis-predicted branch if we fall through (branch not taken).  */
  useskip = (length == 4 && nullify) ? use_skip_p (insn) : FALSE;

  switch (length)
    {

      /* All short conditional branches except backwards with an unfilled
	 delay slot.  */
      case 4:
	if (useskip)
	  strcpy (buf, "{vextrs,|extrw,s,}");
	else
	  strcpy (buf, "{bvb,|bb,}");
	if (useskip && GET_MODE (operands[0]) == DImode)
	  strcpy (buf, "extrd,s,*");
	else if (GET_MODE (operands[0]) == DImode)
	  strcpy (buf, "bb,*");
	if ((which == 0 && negated)
	     || (which == 1 && ! negated))
	  strcat (buf, ">=");
	else
	  strcat (buf, "<");
	if (useskip)
	  strcat (buf, "{ %0,1,%%r0| %0,%%sar,1,%%r0}");
	else if (nullify && negated)
	  {
	    if (branch_needs_nop_p (insn))
	      strcat (buf, "{,n %0,%3%#|,n %0,%%sar,%3%#}");
	    else
	      strcat (buf, "{,n %0,%3|,n %0,%%sar,%3}");
	  }
	else if (nullify && ! negated)
	  {
	    if (branch_needs_nop_p (insn))
	      strcat (buf, "{,n %0,%2%#|,n %0,%%sar,%2%#}");
	    else
	      strcat (buf, "{,n %0,%2|,n %0,%%sar,%2}");
	  }
	else if (! nullify && negated)
	  strcat (buf, "{ %0,%3| %0,%%sar,%3}");
	else if (! nullify && ! negated)
	  strcat (buf, "{ %0,%2| %0,%%sar,%2}");
	break;

     /* All long conditionals.  Note a short backward branch with an
	unfilled delay slot is treated just like a long backward branch
	with an unfilled delay slot.  */
      case 8:
	/* Handle weird backwards branch with a filled delay slot
	   which is nullified.  */
	if (dbr_sequence_length () != 0
	    && ! forward_branch_p (insn)
	    && nullify)
	  {
	    strcpy (buf, "{bvb,|bb,}");
	    if (GET_MODE (operands[0]) == DImode)
	      strcat (buf, "*");
	    if ((which == 0 && negated)
		|| (which == 1 && ! negated))
	      strcat (buf, "<");
	    else
	      strcat (buf, ">=");
	    if (negated)
	      strcat (buf, "{,n %0,.+12\n\tb %3|,n %0,%%sar,.+12\n\tb %3}");
	    else
	      strcat (buf, "{,n %0,.+12\n\tb %2|,n %0,%%sar,.+12\n\tb %2}");
	  }
	/* Handle short backwards branch with an unfilled delay slot.
	   Using a bb;nop rather than extrs;bl saves 1 cycle for both
	   taken and untaken branches.  */
	else if (dbr_sequence_length () == 0
		 && ! forward_branch_p (insn)
		 && INSN_ADDRESSES_SET_P ()
		 && VAL_14_BITS_P (INSN_ADDRESSES (INSN_UID (JUMP_LABEL (insn)))
				    - INSN_ADDRESSES (INSN_UID (insn)) - 8))
	  {
	    strcpy (buf, "{bvb,|bb,}");
	    if (GET_MODE (operands[0]) == DImode)
	      strcat (buf, "*");
	    if ((which == 0 && negated)
		|| (which == 1 && ! negated))
	      strcat (buf, ">=");
	    else
	      strcat (buf, "<");
	    if (negated)
	      strcat (buf, "{ %0,%3%#| %0,%%sar,%3%#}");
	    else
	      strcat (buf, "{ %0,%2%#| %0,%%sar,%2%#}");
	  }
	else
	  {
	    strcpy (buf, "{vextrs,|extrw,s,}");
	    if (GET_MODE (operands[0]) == DImode)
	      strcpy (buf, "extrd,s,*");
	    if ((which == 0 && negated)
		|| (which == 1 && ! negated))
	      strcat (buf, "<");
	    else
	      strcat (buf, ">=");
	    if (nullify && negated)
	      strcat (buf, "{ %0,1,%%r0\n\tb,n %3| %0,%%sar,1,%%r0\n\tb,n %3}");
	    else if (nullify && ! negated)
	      strcat (buf, "{ %0,1,%%r0\n\tb,n %2| %0,%%sar,1,%%r0\n\tb,n %2}");
	    else if (negated)
	      strcat (buf, "{ %0,1,%%r0\n\tb %3| %0,%%sar,1,%%r0\n\tb %3}");
	    else
	      strcat (buf, "{ %0,1,%%r0\n\tb %2| %0,%%sar,1,%%r0\n\tb %2}");
	  }
	break;

      default:
	/* The reversed conditional branch must branch over one additional
	   instruction if the delay slot is filled and needs to be extracted
	   by pa_output_lbranch.  If the delay slot is empty or this is a
	   nullified forward branch, the instruction after the reversed
	   condition branch must be nullified.  */
	if (dbr_sequence_length () == 0
	    || (nullify && forward_branch_p (insn)))
	  {
	    nullify = 1;
	    xdelay = 0;
	    operands[4] = GEN_INT (length);
	  }
	else
	  {
	    xdelay = 1;
	    operands[4] = GEN_INT (length + 4);
	  }

	if (GET_MODE (operands[0]) == DImode)
	  strcpy (buf, "bb,*");
	else
	  strcpy (buf, "{bvb,|bb,}");
	if ((which == 0 && negated)
	    || (which == 1 && !negated))
	  strcat (buf, "<");
	else
	  strcat (buf, ">=");
	if (nullify)
	  strcat (buf, ",n {%0,.+%4|%0,%%sar,.+%4}");
	else
	  strcat (buf, " {%0,.+%4|%0,%%sar,.+%4}");
	output_asm_insn (buf, operands);
	return pa_output_lbranch (negated ? operands[3] : operands[2],
				  insn, xdelay);
    }
  return buf;
}

/* Return the output template for emitting a dbra type insn.

   Note it may perform some output operations on its own before
   returning the final output string.  */
const char *
pa_output_dbra (rtx *operands, rtx_insn *insn, int which_alternative)
{
  int length = get_attr_length (insn);

  /* A conditional branch to the following instruction (e.g. the delay slot) is
     asking for a disaster.  Be prepared!  */

  if (branch_to_delay_slot_p (insn))
    {
      if (which_alternative == 0)
	return "ldo %1(%0),%0";
      else if (which_alternative == 1)
	{
	  output_asm_insn ("{fstws|fstw} %0,-16(%%r30)", operands);
	  output_asm_insn ("ldw -16(%%r30),%4", operands);
	  output_asm_insn ("ldo %1(%4),%4\n\tstw %4,-16(%%r30)", operands);
	  return "{fldws|fldw} -16(%%r30),%0";
	}
      else
	{
	  output_asm_insn ("ldw %0,%4", operands);
	  return "ldo %1(%4),%4\n\tstw %4,%0";
	}
    }

  if (which_alternative == 0)
    {
      int nullify = INSN_ANNULLED_BRANCH_P (insn);
      int xdelay;

      /* If this is a long branch with its delay slot unfilled, set `nullify'
	 as it can nullify the delay slot and save a nop.  */
      if (length == 8 && dbr_sequence_length () == 0)
	nullify = 1;

      /* If this is a short forward conditional branch which did not get
	 its delay slot filled, the delay slot can still be nullified.  */
      if (! nullify && length == 4 && dbr_sequence_length () == 0)
	nullify = forward_branch_p (insn);

      switch (length)
	{
	case 4:
	  if (nullify)
	    {
	      if (branch_needs_nop_p (insn))
		return "addib,%C2,n %1,%0,%3%#";
	      else
		return "addib,%C2,n %1,%0,%3";
	    }
	  else
	    return "addib,%C2 %1,%0,%3";
      
	case 8:
	  /* Handle weird backwards branch with a fulled delay slot
	     which is nullified.  */
	  if (dbr_sequence_length () != 0
	      && ! forward_branch_p (insn)
	      && nullify)
	    return "addib,%N2,n %1,%0,.+12\n\tb %3";
	  /* Handle short backwards branch with an unfilled delay slot.
	     Using a addb;nop rather than addi;bl saves 1 cycle for both
	     taken and untaken branches.  */
	  else if (dbr_sequence_length () == 0
		   && ! forward_branch_p (insn)
		   && INSN_ADDRESSES_SET_P ()
		   && VAL_14_BITS_P (INSN_ADDRESSES (INSN_UID (JUMP_LABEL (insn)))
				      - INSN_ADDRESSES (INSN_UID (insn)) - 8))
	      return "addib,%C2 %1,%0,%3%#";

	  /* Handle normal cases.  */
	  if (nullify)
	    return "addi,%N2 %1,%0,%0\n\tb,n %3";
	  else
	    return "addi,%N2 %1,%0,%0\n\tb %3";

	default:
	  /* The reversed conditional branch must branch over one additional
	     instruction if the delay slot is filled and needs to be extracted
	     by pa_output_lbranch.  If the delay slot is empty or this is a
	     nullified forward branch, the instruction after the reversed
	     condition branch must be nullified.  */
	  if (dbr_sequence_length () == 0
	      || (nullify && forward_branch_p (insn)))
	    {
	      nullify = 1;
	      xdelay = 0;
	      operands[4] = GEN_INT (length);
	    }
	  else
	    {
	      xdelay = 1;
	      operands[4] = GEN_INT (length + 4);
	    }

	  if (nullify)
	    output_asm_insn ("addib,%N2,n %1,%0,.+%4", operands);
	  else
	    output_asm_insn ("addib,%N2 %1,%0,.+%4", operands);

	  return pa_output_lbranch (operands[3], insn, xdelay);
	}
      
    }
  /* Deal with gross reload from FP register case.  */
  else if (which_alternative == 1)
    {
      /* Move loop counter from FP register to MEM then into a GR,
	 increment the GR, store the GR into MEM, and finally reload
	 the FP register from MEM from within the branch's delay slot.  */
      output_asm_insn ("{fstws|fstw} %0,-16(%%r30)\n\tldw -16(%%r30),%4",
		       operands);
      output_asm_insn ("ldo %1(%4),%4\n\tstw %4,-16(%%r30)", operands);
      if (length == 24)
	return "{comb|cmpb},%S2 %%r0,%4,%3\n\t{fldws|fldw} -16(%%r30),%0";
      else if (length == 28)
	return "{comclr|cmpclr},%B2 %%r0,%4,%%r0\n\tb %3\n\t{fldws|fldw} -16(%%r30),%0";
      else
	{
	  operands[5] = GEN_INT (length - 16);
	  output_asm_insn ("{comb|cmpb},%B2 %%r0,%4,.+%5", operands);
	  output_asm_insn ("{fldws|fldw} -16(%%r30),%0", operands);
	  return pa_output_lbranch (operands[3], insn, 0);
	}
    }
  /* Deal with gross reload from memory case.  */
  else
    {
      /* Reload loop counter from memory, the store back to memory
	 happens in the branch's delay slot.  */
      output_asm_insn ("ldw %0,%4", operands);
      if (length == 12)
	return "addib,%C2 %1,%4,%3\n\tstw %4,%0";
      else if (length == 16)
	return "addi,%N2 %1,%4,%4\n\tb %3\n\tstw %4,%0";
      else
	{
	  operands[5] = GEN_INT (length - 4);
	  output_asm_insn ("addib,%N2 %1,%4,.+%5\n\tstw %4,%0", operands);
	  return pa_output_lbranch (operands[3], insn, 0);
	}
    }
}

/* Return the output template for emitting a movb type insn.

   Note it may perform some output operations on its own before
   returning the final output string.  */
const char *
pa_output_movb (rtx *operands, rtx_insn *insn, int which_alternative,
	     int reverse_comparison)
{
  int length = get_attr_length (insn);

  /* A conditional branch to the following instruction (e.g. the delay slot) is
     asking for a disaster.  Be prepared!  */

  if (branch_to_delay_slot_p (insn))
    {
      if (which_alternative == 0)
	return "copy %1,%0";
      else if (which_alternative == 1)
	{
	  output_asm_insn ("stw %1,-16(%%r30)", operands);
	  return "{fldws|fldw} -16(%%r30),%0";
	}
      else if (which_alternative == 2)
	return "stw %1,%0";
      else
	return "mtsar %r1";
    }

  /* Support the second variant.  */
  if (reverse_comparison)
    PUT_CODE (operands[2], reverse_condition (GET_CODE (operands[2])));

  if (which_alternative == 0)
    {
      int nullify = INSN_ANNULLED_BRANCH_P (insn);
      int xdelay;

      /* If this is a long branch with its delay slot unfilled, set `nullify'
	 as it can nullify the delay slot and save a nop.  */
      if (length == 8 && dbr_sequence_length () == 0)
	nullify = 1;

      /* If this is a short forward conditional branch which did not get
	 its delay slot filled, the delay slot can still be nullified.  */
      if (! nullify && length == 4 && dbr_sequence_length () == 0)
	nullify = forward_branch_p (insn);

      switch (length)
	{
	case 4:
	  if (nullify)
	    {
	      if (branch_needs_nop_p (insn))
		return "movb,%C2,n %1,%0,%3%#";
	      else
		return "movb,%C2,n %1,%0,%3";
	    }
	  else
	    return "movb,%C2 %1,%0,%3";

	case 8:
	  /* Handle weird backwards branch with a filled delay slot
	     which is nullified.  */
	  if (dbr_sequence_length () != 0
	      && ! forward_branch_p (insn)
	      && nullify)
	    return "movb,%N2,n %1,%0,.+12\n\tb %3";

	  /* Handle short backwards branch with an unfilled delay slot.
	     Using a movb;nop rather than or;bl saves 1 cycle for both
	     taken and untaken branches.  */
	  else if (dbr_sequence_length () == 0
		   && ! forward_branch_p (insn)
		   && INSN_ADDRESSES_SET_P ()
		   && VAL_14_BITS_P (INSN_ADDRESSES (INSN_UID (JUMP_LABEL (insn)))
				      - INSN_ADDRESSES (INSN_UID (insn)) - 8))
	    return "movb,%C2 %1,%0,%3%#";
	  /* Handle normal cases.  */
	  if (nullify)
	    return "or,%N2 %1,%%r0,%0\n\tb,n %3";
	  else
	    return "or,%N2 %1,%%r0,%0\n\tb %3";

	default:
	  /* The reversed conditional branch must branch over one additional
	     instruction if the delay slot is filled and needs to be extracted
	     by pa_output_lbranch.  If the delay slot is empty or this is a
	     nullified forward branch, the instruction after the reversed
	     condition branch must be nullified.  */
	  if (dbr_sequence_length () == 0
	      || (nullify && forward_branch_p (insn)))
	    {
	      nullify = 1;
	      xdelay = 0;
	      operands[4] = GEN_INT (length);
	    }
	  else
	    {
	      xdelay = 1;
	      operands[4] = GEN_INT (length + 4);
	    }

	  if (nullify)
	    output_asm_insn ("movb,%N2,n %1,%0,.+%4", operands);
	  else
	    output_asm_insn ("movb,%N2 %1,%0,.+%4", operands);

	  return pa_output_lbranch (operands[3], insn, xdelay);
	}
    }
  /* Deal with gross reload for FP destination register case.  */
  else if (which_alternative == 1)
    {
      /* Move source register to MEM, perform the branch test, then
	 finally load the FP register from MEM from within the branch's
	 delay slot.  */
      output_asm_insn ("stw %1,-16(%%r30)", operands);
      if (length == 12)
	return "{comb|cmpb},%S2 %%r0,%1,%3\n\t{fldws|fldw} -16(%%r30),%0";
      else if (length == 16)
	return "{comclr|cmpclr},%B2 %%r0,%1,%%r0\n\tb %3\n\t{fldws|fldw} -16(%%r30),%0";
      else
	{
	  operands[4] = GEN_INT (length - 4);
	  output_asm_insn ("{comb|cmpb},%B2 %%r0,%1,.+%4", operands);
	  output_asm_insn ("{fldws|fldw} -16(%%r30),%0", operands);
	  return pa_output_lbranch (operands[3], insn, 0);
	}
    }
  /* Deal with gross reload from memory case.  */
  else if (which_alternative == 2)
    {
      /* Reload loop counter from memory, the store back to memory
	 happens in the branch's delay slot.  */
      if (length == 8)
	return "{comb|cmpb},%S2 %%r0,%1,%3\n\tstw %1,%0";
      else if (length == 12)
	return "{comclr|cmpclr},%B2 %%r0,%1,%%r0\n\tb %3\n\tstw %1,%0";
      else
	{
	  operands[4] = GEN_INT (length);
	  output_asm_insn ("{comb|cmpb},%B2 %%r0,%1,.+%4\n\tstw %1,%0",
			   operands);
	  return pa_output_lbranch (operands[3], insn, 0);
	}
    }
  /* Handle SAR as a destination.  */
  else
    {
      if (length == 8)
	return "{comb|cmpb},%S2 %%r0,%1,%3\n\tmtsar %r1";
      else if (length == 12)
	return "{comclr|cmpclr},%B2 %%r0,%1,%%r0\n\tb %3\n\tmtsar %r1";
      else
	{
	  operands[4] = GEN_INT (length);
	  output_asm_insn ("{comb|cmpb},%B2 %%r0,%1,.+%4\n\tmtsar %r1",
			   operands);
	  return pa_output_lbranch (operands[3], insn, 0);
	}
    }
}

/* Copy any FP arguments in INSN into integer registers.  */
static void
copy_fp_args (rtx_insn *insn)
{
  rtx link;
  rtx xoperands[2];

  for (link = CALL_INSN_FUNCTION_USAGE (insn); link; link = XEXP (link, 1))
    {
      int arg_mode, regno;
      rtx use = XEXP (link, 0);

      if (! (GET_CODE (use) == USE
	  && GET_CODE (XEXP (use, 0)) == REG
	  && FUNCTION_ARG_REGNO_P (REGNO (XEXP (use, 0)))))
	continue;

      arg_mode = GET_MODE (XEXP (use, 0));
      regno = REGNO (XEXP (use, 0));

      /* Is it a floating point register?  */
      if (regno >= 32 && regno <= 39)
	{
	  /* Copy the FP register into an integer register via memory.  */
	  if (arg_mode == SFmode)
	    {
	      xoperands[0] = XEXP (use, 0);
	      xoperands[1] = gen_rtx_REG (SImode, 26 - (regno - 32) / 2);
	      output_asm_insn ("{fstws|fstw} %0,-16(%%sr0,%%r30)", xoperands);
	      output_asm_insn ("ldw -16(%%sr0,%%r30),%1", xoperands);
	    }
	  else
	    {
	      xoperands[0] = XEXP (use, 0);
	      xoperands[1] = gen_rtx_REG (DImode, 25 - (regno - 34) / 2);
	      output_asm_insn ("{fstds|fstd} %0,-16(%%sr0,%%r30)", xoperands);
	      output_asm_insn ("ldw -12(%%sr0,%%r30),%R1", xoperands);
	      output_asm_insn ("ldw -16(%%sr0,%%r30),%1", xoperands);
	    }
	}
    }
}

/* Compute length of the FP argument copy sequence for INSN.  */
static int
length_fp_args (rtx_insn *insn)
{
  int length = 0;
  rtx link;

  for (link = CALL_INSN_FUNCTION_USAGE (insn); link; link = XEXP (link, 1))
    {
      int arg_mode, regno;
      rtx use = XEXP (link, 0);

      if (! (GET_CODE (use) == USE
	  && GET_CODE (XEXP (use, 0)) == REG
	  && FUNCTION_ARG_REGNO_P (REGNO (XEXP (use, 0)))))
	continue;

      arg_mode = GET_MODE (XEXP (use, 0));
      regno = REGNO (XEXP (use, 0));

      /* Is it a floating point register?  */
      if (regno >= 32 && regno <= 39)
	{
	  if (arg_mode == SFmode)
	    length += 8;
	  else
	    length += 12;
	}
    }

  return length;
}

/* Return the attribute length for the millicode call instruction INSN.
   The length must match the code generated by pa_output_millicode_call.
   We include the delay slot in the returned length as it is better to
   over estimate the length than to under estimate it.  */

int
pa_attr_length_millicode_call (rtx_insn *insn)
{
  unsigned long distance = -1;
  unsigned long total = IN_NAMED_SECTION_P (cfun->decl) ? 0 : total_code_bytes;

  if (INSN_ADDRESSES_SET_P ())
    {
      distance = (total + insn_current_reference_address (insn));
      if (distance < total)
	distance = -1;
    }

  if (TARGET_64BIT)
    {
      if (!TARGET_LONG_CALLS && distance < 7600000)
	return 8;

      return 20;
    }
  else if (TARGET_PORTABLE_RUNTIME)
    return 24;
  else
    {
      if (!TARGET_LONG_CALLS && distance < MAX_PCREL17F_OFFSET)
	return 8;

      if (!flag_pic)
	return 12;

      return 24;
    }
}

/* INSN is a function call.

   CALL_DEST is the routine we are calling.  */

const char *
pa_output_millicode_call (rtx_insn *insn, rtx call_dest)
{
  int attr_length = get_attr_length (insn);
  int seq_length = dbr_sequence_length ();
  rtx xoperands[4];

  xoperands[0] = call_dest;

  /* Handle the common case where we are sure that the branch will
     reach the beginning of the $CODE$ subspace.  The within reach
     form of the $$sh_func_adrs call has a length of 28.  Because it
     has an attribute type of sh_func_adrs, it never has a nonzero
     sequence length (i.e., the delay slot is never filled).  */
  if (!TARGET_LONG_CALLS
      && (attr_length == 8
	  || (attr_length == 28
	      && get_attr_type (insn) == TYPE_SH_FUNC_ADRS)))
    {
      xoperands[1] = gen_rtx_REG (Pmode, TARGET_64BIT ? 2 : 31);
      output_asm_insn ("{bl|b,l} %0,%1", xoperands);
    }
  else
    {
      if (TARGET_64BIT)
	{
	  /* It might seem that one insn could be saved by accessing
	     the millicode function using the linkage table.  However,
	     this doesn't work in shared libraries and other dynamically
	     loaded objects.  Using a pc-relative sequence also avoids
	     problems related to the implicit use of the gp register.  */
	  xoperands[1] = gen_rtx_REG (Pmode, 1);
	  xoperands[2] = xoperands[1];
	  pa_output_pic_pcrel_sequence (xoperands);
	  output_asm_insn ("bve,l (%%r1),%%r2", xoperands);
	}
      else if (TARGET_PORTABLE_RUNTIME)
	{
	  /* Pure portable runtime doesn't allow be/ble; we also don't
	     have PIC support in the assembler/linker, so this sequence
	     is needed.  */

	  /* Get the address of our target into %r1.  */
	  output_asm_insn ("ldil L'%0,%%r1", xoperands);
	  output_asm_insn ("ldo R'%0(%%r1),%%r1", xoperands);

	  /* Get our return address into %r31.  */
	  output_asm_insn ("{bl|b,l} .+8,%%r31", xoperands);
	  output_asm_insn ("addi 8,%%r31,%%r31", xoperands);

	  /* Jump to our target address in %r1.  */
	  output_asm_insn ("bv %%r0(%%r1)", xoperands);
	}
      else if (!flag_pic)
	{
	  output_asm_insn ("ldil L'%0,%%r1", xoperands);
	  if (TARGET_PA_20)
	    output_asm_insn ("be,l R'%0(%%sr4,%%r1),%%sr0,%%r31", xoperands);
	  else
	    output_asm_insn ("ble R'%0(%%sr4,%%r1)", xoperands);
	}
      else
	{
	  xoperands[1] = gen_rtx_REG (Pmode, 31);
	  xoperands[2] = gen_rtx_REG (Pmode, 1);
	  pa_output_pic_pcrel_sequence (xoperands);

	  /* Adjust return address.  */
	  output_asm_insn ("ldo {16|24}(%%r31),%%r31", xoperands);

	  /* Jump to our target address in %r1.  */
	  output_asm_insn ("bv %%r0(%%r1)", xoperands);
	}
    }

  if (seq_length == 0)
    output_asm_insn ("nop", xoperands);

  return "";
}

/* Return the attribute length of the call instruction INSN.  The SIBCALL
   flag indicates whether INSN is a regular call or a sibling call.  The
   length returned must be longer than the code actually generated by
   pa_output_call.  Since branch shortening is done before delay branch
   sequencing, there is no way to determine whether or not the delay
   slot will be filled during branch shortening.  Even when the delay
   slot is filled, we may have to add a nop if the delay slot contains
   a branch that can't reach its target.  Thus, we always have to include
   the delay slot in the length estimate.  This used to be done in
   pa_adjust_insn_length but we do it here now as some sequences always
   fill the delay slot and we can save four bytes in the estimate for
   these sequences.  */

int
pa_attr_length_call (rtx_insn *insn, int sibcall)
{
  int local_call;
  rtx call, call_dest;
  tree call_decl;
  int length = 0;
  rtx pat = PATTERN (insn);
  unsigned long distance = -1;

  gcc_assert (CALL_P (insn));

  if (INSN_ADDRESSES_SET_P ())
    {
      unsigned long total;

      total = IN_NAMED_SECTION_P (cfun->decl) ? 0 : total_code_bytes;
      distance = (total + insn_current_reference_address (insn));
      if (distance < total)
	distance = -1;
    }

  gcc_assert (GET_CODE (pat) == PARALLEL);

  /* Get the call rtx.  */
  call = XVECEXP (pat, 0, 0);
  if (GET_CODE (call) == SET)
    call = SET_SRC (call);

  gcc_assert (GET_CODE (call) == CALL);

  /* Determine if this is a local call.  */
  call_dest = XEXP (XEXP (call, 0), 0);
  call_decl = SYMBOL_REF_DECL (call_dest);
  local_call = call_decl && targetm.binds_local_p (call_decl);

  /* pc-relative branch.  */
  if (!TARGET_LONG_CALLS
      && ((TARGET_PA_20 && !sibcall && distance < 7600000)
	  || distance < MAX_PCREL17F_OFFSET))
    length += 8;

  /* 64-bit plabel sequence.  */
  else if (TARGET_64BIT && !local_call)
    length += 24;

  /* non-pic long absolute branch sequence.  */
  else if ((TARGET_LONG_ABS_CALL || local_call) && !flag_pic)
    length += 12;

  /* long pc-relative branch sequence.  */
  else if (TARGET_LONG_PIC_SDIFF_CALL
	   || (TARGET_GAS && !TARGET_SOM && local_call))
    {
      length += 20;

      if (!TARGET_PA_20 && !TARGET_NO_SPACE_REGS && (!local_call || flag_pic))
	length += 8;
    }

  /* 32-bit plabel sequence.  */
  else
    {
      length += 32;

      if (TARGET_SOM)
	length += length_fp_args (insn);

      if (flag_pic)
	length += 4;

      if (!TARGET_PA_20)
	{
	  if (!sibcall)
	    length += 8;

	  if (!TARGET_NO_SPACE_REGS && (!local_call || flag_pic))
	    length += 8;
	}
    }

  return length;
}

/* INSN is a function call.

   CALL_DEST is the routine we are calling.  */

const char *
pa_output_call (rtx_insn *insn, rtx call_dest, int sibcall)
{
  int seq_length = dbr_sequence_length ();
  tree call_decl = SYMBOL_REF_DECL (call_dest);
  int local_call = call_decl && targetm.binds_local_p (call_decl);
  rtx xoperands[4];

  xoperands[0] = call_dest;

  /* Handle the common case where we're sure that the branch will reach
     the beginning of the "$CODE$" subspace.  This is the beginning of
     the current function if we are in a named section.  */
  if (!TARGET_LONG_CALLS && pa_attr_length_call (insn, sibcall) == 8)
    {
      xoperands[1] = gen_rtx_REG (word_mode, sibcall ? 0 : 2);
      output_asm_insn ("{bl|b,l} %0,%1", xoperands);
    }
  else
    {
      if (TARGET_64BIT && !local_call)
	{
	  /* ??? As far as I can tell, the HP linker doesn't support the
	     long pc-relative sequence described in the 64-bit runtime
	     architecture.  So, we use a slightly longer indirect call.  */
	  xoperands[0] = pa_get_deferred_plabel (call_dest);
	  xoperands[1] = gen_label_rtx ();

	  /* Put the load of %r27 into the delay slot.  We don't need to
	     do anything when generating fast indirect calls.  */
	  if (seq_length != 0)
	    {
	      final_scan_insn (NEXT_INSN (insn), asm_out_file,
			       optimize, 0, NULL);

	      /* Now delete the delay insn.  */
	      SET_INSN_DELETED (NEXT_INSN (insn));
	    }

	  output_asm_insn ("addil LT'%0,%%r27", xoperands);
	  output_asm_insn ("ldd RT'%0(%%r1),%%r1", xoperands);
	  output_asm_insn ("ldd 0(%%r1),%%r1", xoperands);
	  output_asm_insn ("ldd 16(%%r1),%%r2", xoperands);
	  output_asm_insn ("bve,l (%%r2),%%r2", xoperands);
	  output_asm_insn ("ldd 24(%%r1),%%r27", xoperands);
	  seq_length = 1;
	}
      else
	{
	  int indirect_call = 0;

	  /* Emit a long call.  There are several different sequences
	     of increasing length and complexity.  In most cases,
             they don't allow an instruction in the delay slot.  */
	  if (!((TARGET_LONG_ABS_CALL || local_call) && !flag_pic)
	      && !TARGET_LONG_PIC_SDIFF_CALL
	      && !(TARGET_GAS && !TARGET_SOM && local_call)
	      && !TARGET_64BIT)
	    indirect_call = 1;

	  if (seq_length != 0
	      && !sibcall
	      && (!TARGET_PA_20
		  || indirect_call
		  || ((TARGET_LONG_ABS_CALL || local_call) && !flag_pic)))
	    {
	      /* A non-jump insn in the delay slot.  By definition we can
		 emit this insn before the call (and in fact before argument
		 relocating.  */
	      final_scan_insn (NEXT_INSN (insn), asm_out_file, optimize, 0,
			       NULL);

	      /* Now delete the delay insn.  */
	      SET_INSN_DELETED (NEXT_INSN (insn));
	      seq_length = 0;
	    }

	  if ((TARGET_LONG_ABS_CALL || local_call) && !flag_pic)
	    {
	      /* This is the best sequence for making long calls in
		 non-pic code.  Unfortunately, GNU ld doesn't provide
		 the stub needed for external calls, and GAS's support
		 for this with the SOM linker is buggy.  It is safe
		 to use this for local calls.  */
	      output_asm_insn ("ldil L'%0,%%r1", xoperands);
	      if (sibcall)
		output_asm_insn ("be R'%0(%%sr4,%%r1)", xoperands);
	      else
		{
		  if (TARGET_PA_20)
		    output_asm_insn ("be,l R'%0(%%sr4,%%r1),%%sr0,%%r31",
				     xoperands);
		  else
		    output_asm_insn ("ble R'%0(%%sr4,%%r1)", xoperands);

		  output_asm_insn ("copy %%r31,%%r2", xoperands);
		  seq_length = 1;
		}
	    }
	  else
	    {
	      /* The HP assembler and linker can handle relocations for
		 the difference of two symbols.  The HP assembler
		 recognizes the sequence as a pc-relative call and
		 the linker provides stubs when needed.  */

	      /* GAS currently can't generate the relocations that
		 are needed for the SOM linker under HP-UX using this
		 sequence.  The GNU linker doesn't generate the stubs
		 that are needed for external calls on TARGET_ELF32
		 with this sequence.  For now, we have to use a longer
	         plabel sequence when using GAS for non local calls.  */
	      if (TARGET_LONG_PIC_SDIFF_CALL
		  || (TARGET_GAS && !TARGET_SOM && local_call))
		{
		  xoperands[1] = gen_rtx_REG (Pmode, 1);
		  xoperands[2] = xoperands[1];
		  pa_output_pic_pcrel_sequence (xoperands);
		}
	      else
		{
		  /* Emit a long plabel-based call sequence.  This is
		     essentially an inline implementation of $$dyncall.
		     We don't actually try to call $$dyncall as this is
		     as difficult as calling the function itself.  */
		  xoperands[0] = pa_get_deferred_plabel (call_dest);
		  xoperands[1] = gen_label_rtx ();

		  /* Since the call is indirect, FP arguments in registers
		     need to be copied to the general registers.  Then, the
		     argument relocation stub will copy them back.  */
		  if (TARGET_SOM)
		    copy_fp_args (insn);

		  if (flag_pic)
		    {
		      output_asm_insn ("addil LT'%0,%%r19", xoperands);
		      output_asm_insn ("ldw RT'%0(%%r1),%%r1", xoperands);
		      output_asm_insn ("ldw 0(%%r1),%%r22", xoperands);
		    }
		  else
		    {
		      output_asm_insn ("addil LR'%0-$global$,%%r27",
				       xoperands);
		      output_asm_insn ("ldw RR'%0-$global$(%%r1),%%r22",
				       xoperands);
		    }

		  output_asm_insn ("bb,>=,n %%r22,30,.+16", xoperands);
		  output_asm_insn ("depi 0,31,2,%%r22", xoperands);
		  /* Should this be an ordered load to ensure the target
	             address is loaded before the global pointer?  */
		  output_asm_insn ("ldw 0(%%r22),%%r1", xoperands);
		  output_asm_insn ("ldw 4(%%r22),%%r19", xoperands);

		  if (!sibcall && !TARGET_PA_20)
		    {
		      output_asm_insn ("{bl|b,l} .+8,%%r2", xoperands);
		      if (TARGET_NO_SPACE_REGS || (local_call && !flag_pic))
			output_asm_insn ("addi 8,%%r2,%%r2", xoperands);
		      else
			output_asm_insn ("addi 16,%%r2,%%r2", xoperands);
		    }
		}

	      if (TARGET_PA_20)
		{
		  if (sibcall)
		    output_asm_insn ("bve (%%r1)", xoperands);
		  else
		    {
		      if (indirect_call)
			{
			  output_asm_insn ("bve,l (%%r1),%%r2", xoperands);
			  output_asm_insn ("stw %%r2,-24(%%sp)", xoperands);
			  seq_length = 1;
			}
		      else
			output_asm_insn ("bve,l (%%r1),%%r2", xoperands);
		    }
		}
	      else
		{
		  if (!TARGET_NO_SPACE_REGS && (!local_call || flag_pic))
		    output_asm_insn ("ldsid (%%r1),%%r31\n\tmtsp %%r31,%%sr0",
				     xoperands);

		  if (sibcall)
		    {
		      if (TARGET_NO_SPACE_REGS || (local_call && !flag_pic))
			output_asm_insn ("be 0(%%sr4,%%r1)", xoperands);
		      else
			output_asm_insn ("be 0(%%sr0,%%r1)", xoperands);
		    }
		  else
		    {
		      if (TARGET_NO_SPACE_REGS || (local_call && !flag_pic))
			output_asm_insn ("ble 0(%%sr4,%%r1)", xoperands);
		      else
			output_asm_insn ("ble 0(%%sr0,%%r1)", xoperands);

		      if (indirect_call)
			output_asm_insn ("stw %%r31,-24(%%sp)", xoperands);
		      else
			output_asm_insn ("copy %%r31,%%r2", xoperands);
		      seq_length = 1;
		    }
		}
	    }
	}
    }

  if (seq_length == 0)
    output_asm_insn ("nop", xoperands);

  return "";
}

/* Return the attribute length of the indirect call instruction INSN.
   The length must match the code generated by output_indirect call.
   The returned length includes the delay slot.  Currently, the delay
   slot of an indirect call sequence is not exposed and it is used by
   the sequence itself.  */

int
pa_attr_length_indirect_call (rtx_insn *insn)
{
  unsigned long distance = -1;
  unsigned long total = IN_NAMED_SECTION_P (cfun->decl) ? 0 : total_code_bytes;

  if (INSN_ADDRESSES_SET_P ())
    {
      distance = (total + insn_current_reference_address (insn));
      if (distance < total)
	distance = -1;
    }

  if (TARGET_64BIT)
    return 12;

  if (TARGET_FAST_INDIRECT_CALLS)
    return 8;

  if (TARGET_PORTABLE_RUNTIME)
    return 16;

  if (!TARGET_LONG_CALLS
      && ((TARGET_PA_20 && !TARGET_SOM && distance < 7600000)
	  || distance < MAX_PCREL17F_OFFSET))
    return 8;

  /* Out of reach, can use ble.  */
  if (!flag_pic)
    return 12;

  /* Inline versions of $$dyncall.  */
  if (!optimize_size)
    {
      if (TARGET_NO_SPACE_REGS)
	return 28;

      if (TARGET_PA_20)
	return 32;
    }

  /* Long PIC pc-relative call.  */
  return 20;
}

const char *
pa_output_indirect_call (rtx_insn *insn, rtx call_dest)
{
  rtx xoperands[4];
  int length;

  if (TARGET_64BIT)
    {
      xoperands[0] = call_dest;
      output_asm_insn ("ldd 16(%0),%%r2\n\t"
		       "bve,l (%%r2),%%r2\n\t"
		       "ldd 24(%0),%%r27", xoperands);
      return "";
    }

  /* First the special case for kernels, level 0 systems, etc.  */
  if (TARGET_FAST_INDIRECT_CALLS)
    {
      pa_output_arg_descriptor (insn);
      if (TARGET_PA_20)
	return "bve,l,n (%%r22),%%r2\n\tnop";
      return "ble 0(%%sr4,%%r22)\n\tcopy %%r31,%%r2"; 
    }

  if (TARGET_PORTABLE_RUNTIME)
    {
      output_asm_insn ("ldil L'$$dyncall,%%r31\n\t"
		       "ldo R'$$dyncall(%%r31),%%r31", xoperands);
      pa_output_arg_descriptor (insn);
      return "blr %%r0,%%r2\n\tbv,n %%r0(%%r31)";
    }

  /* Now the normal case -- we can reach $$dyncall directly or
     we're sure that we can get there via a long-branch stub. 

     No need to check target flags as the length uniquely identifies
     the remaining cases.  */
  length = pa_attr_length_indirect_call (insn);
  if (length == 8)
    {
      pa_output_arg_descriptor (insn);

      /* The HP linker sometimes substitutes a BLE for BL/B,L calls to
	 $$dyncall.  Since BLE uses %r31 as the link register, the 22-bit
	 variant of the B,L instruction can't be used on the SOM target.  */
      if (TARGET_PA_20 && !TARGET_SOM)
	return "b,l,n $$dyncall,%%r2\n\tnop";
      else
	return "bl $$dyncall,%%r31\n\tcopy %%r31,%%r2";
    }

  /* Long millicode call, but we are not generating PIC or portable runtime
     code.  */
  if (length == 12)
    {
      output_asm_insn ("ldil L'$$dyncall,%%r2", xoperands);
      pa_output_arg_descriptor (insn);
      return "ble R'$$dyncall(%%sr4,%%r2)\n\tcopy %%r31,%%r2";
    }

  /* The long PIC pc-relative call sequence is five instructions.  So,
     let's use an inline version of $$dyncall when the calling sequence
     has a roughly similar number of instructions and we are not optimizing
     for size.  We need two instructions to load the return pointer plus
     the $$dyncall implementation.  */
  if (!optimize_size)
    {
      if (TARGET_NO_SPACE_REGS)
	{
	  pa_output_arg_descriptor (insn);
	  output_asm_insn ("bl .+8,%%r2\n\t"
			   "ldo 20(%%r2),%%r2\n\t"
			   "extru,<> %%r22,30,1,%%r0\n\t"
			   "bv,n %%r0(%%r22)\n\t"
			   "ldw -2(%%r22),%%r21\n\t"
			   "bv %%r0(%%r21)\n\t"
			   "ldw 2(%%r22),%%r19", xoperands);
	  return "";
	}
      if (TARGET_PA_20)
	{
	  pa_output_arg_descriptor (insn);
	  output_asm_insn ("bl .+8,%%r2\n\t"
			   "ldo 24(%%r2),%%r2\n\t"
			   "stw %%r2,-24(%%sp)\n\t"
			   "extru,<> %r22,30,1,%%r0\n\t"
			   "bve,n (%%r22)\n\t"
			   "ldw -2(%%r22),%%r21\n\t"
			   "bve (%%r21)\n\t"
			   "ldw 2(%%r22),%%r19", xoperands);
	  return "";
	}
    }

  /* We need a long PIC call to $$dyncall.  */
  xoperands[0] = gen_rtx_SYMBOL_REF (Pmode, "$$dyncall");
  xoperands[1] = gen_rtx_REG (Pmode, 2);
  xoperands[2] = gen_rtx_REG (Pmode, 1);
  pa_output_pic_pcrel_sequence (xoperands);
  pa_output_arg_descriptor (insn);
  return "bv %%r0(%%r1)\n\tldo {12|20}(%%r2),%%r2";
}

/* In HPUX 8.0's shared library scheme, special relocations are needed
   for function labels if they might be passed to a function
   in a shared library (because shared libraries don't live in code
   space), and special magic is needed to construct their address.  */

void
pa_encode_label (rtx sym)
{
  const char *str = XSTR (sym, 0);
  int len = strlen (str) + 1;
  char *newstr, *p;

  p = newstr = XALLOCAVEC (char, len + 1);
  *p++ = '@';
  strcpy (p, str);

  XSTR (sym, 0) = ggc_alloc_string (newstr, len);
}

static void
pa_encode_section_info (tree decl, rtx rtl, int first)
{
  int old_referenced = 0;

  if (!first && MEM_P (rtl) && GET_CODE (XEXP (rtl, 0)) == SYMBOL_REF)
    old_referenced
      = SYMBOL_REF_FLAGS (XEXP (rtl, 0)) & SYMBOL_FLAG_REFERENCED;

  default_encode_section_info (decl, rtl, first);

  if (first && TEXT_SPACE_P (decl))
    {
      SYMBOL_REF_FLAG (XEXP (rtl, 0)) = 1;
      if (TREE_CODE (decl) == FUNCTION_DECL)
	pa_encode_label (XEXP (rtl, 0));
    }
  else if (old_referenced)
    SYMBOL_REF_FLAGS (XEXP (rtl, 0)) |= old_referenced;
}

/* This is sort of inverse to pa_encode_section_info.  */

static const char *
pa_strip_name_encoding (const char *str)
{
  str += (*str == '@');
  str += (*str == '*');
  return str;
}

/* Returns 1 if OP is a function label involved in a simple addition
   with a constant.  Used to keep certain patterns from matching
   during instruction combination.  */
int
pa_is_function_label_plus_const (rtx op)
{
  /* Strip off any CONST.  */
  if (GET_CODE (op) == CONST)
    op = XEXP (op, 0);

  return (GET_CODE (op) == PLUS
	  && function_label_operand (XEXP (op, 0), VOIDmode)
	  && GET_CODE (XEXP (op, 1)) == CONST_INT);
}

/* Output the assembler code for a thunk function.  THUNK_DECL is the
   declaration for the thunk function itself, FUNCTION is the decl for
   the target function.  DELTA is an immediate constant offset to be
   added to THIS.  If VCALL_OFFSET is nonzero, the word at
   *(*this + vcall_offset) should be added to THIS.  */

static void
pa_asm_output_mi_thunk (FILE *file, tree thunk_fndecl, HOST_WIDE_INT delta,
			HOST_WIDE_INT vcall_offset, tree function)
{
  const char *fnname = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (thunk_fndecl));
  static unsigned int current_thunk_number;
  int val_14 = VAL_14_BITS_P (delta);
  unsigned int old_last_address = last_address, nbytes = 0;
  char label[17];
  rtx xoperands[4];

  xoperands[0] = XEXP (DECL_RTL (function), 0);
  xoperands[1] = XEXP (DECL_RTL (thunk_fndecl), 0);
  xoperands[2] = GEN_INT (delta);

  assemble_start_function (thunk_fndecl, fnname);
  final_start_function (emit_barrier (), file, 1);

  if (!vcall_offset)
    {
      /* Output the thunk.  We know that the function is in the same
	 translation unit (i.e., the same space) as the thunk, and that
	 thunks are output after their method.  Thus, we don't need an
	 external branch to reach the function.  With SOM and GAS,
	 functions and thunks are effectively in different sections.
	 Thus, we can always use a IA-relative branch and the linker
	 will add a long branch stub if necessary.

	 However, we have to be careful when generating PIC code on the
	 SOM port to ensure that the sequence does not transfer to an
	 import stub for the target function as this could clobber the
	 return value saved at SP-24.  This would also apply to the
	32-bit linux port if the multi-space model is implemented.  */
      if ((!TARGET_LONG_CALLS && TARGET_SOM && !TARGET_PORTABLE_RUNTIME
	   && !(flag_pic && TREE_PUBLIC (function))
	   && (TARGET_GAS || last_address < 262132))
	  || (!TARGET_LONG_CALLS && !TARGET_SOM && !TARGET_PORTABLE_RUNTIME
	      && ((targetm_common.have_named_sections
		   && DECL_SECTION_NAME (thunk_fndecl) != NULL
		   /* The GNU 64-bit linker has rather poor stub management.
		      So, we use a long branch from thunks that aren't in
		      the same section as the target function.  */
		    && ((!TARGET_64BIT
			 && (DECL_SECTION_NAME (thunk_fndecl)
			     != DECL_SECTION_NAME (function)))
			|| ((DECL_SECTION_NAME (thunk_fndecl)
			     == DECL_SECTION_NAME (function))
			    && last_address < 262132)))
		  /* In this case, we need to be able to reach the start of
		     the stub table even though the function is likely closer
		     and can be jumped to directly.  */
		  || (targetm_common.have_named_sections
		      && DECL_SECTION_NAME (thunk_fndecl) == NULL
		      && DECL_SECTION_NAME (function) == NULL
		      && total_code_bytes < MAX_PCREL17F_OFFSET)
		  /* Likewise.  */
		  || (!targetm_common.have_named_sections
		      && total_code_bytes < MAX_PCREL17F_OFFSET))))
	{
	  if (!val_14)
	    output_asm_insn ("addil L'%2,%%r26", xoperands);

	  output_asm_insn ("b %0", xoperands);

	  if (val_14)
	    {
	      output_asm_insn ("ldo %2(%%r26),%%r26", xoperands);
	      nbytes += 8;
	    }
	  else
	    {
	      output_asm_insn ("ldo R'%2(%%r1),%%r26", xoperands);
	      nbytes += 12;
	    }
	}
      else if (TARGET_64BIT)
	{
	  rtx xop[4];

	  /* We only have one call-clobbered scratch register, so we can't
	     make use of the delay slot if delta doesn't fit in 14 bits.  */
	  if (!val_14)
	    {
	      output_asm_insn ("addil L'%2,%%r26", xoperands);
	      output_asm_insn ("ldo R'%2(%%r1),%%r26", xoperands);
	    }

	  /* Load function address into %r1.  */
	  xop[0] = xoperands[0];
	  xop[1] = gen_rtx_REG (Pmode, 1);
	  xop[2] = xop[1];
	  pa_output_pic_pcrel_sequence (xop);

	  if (val_14)
	    {
	      output_asm_insn ("bv %%r0(%%r1)", xoperands);
	      output_asm_insn ("ldo %2(%%r26),%%r26", xoperands);
	      nbytes += 20;
	    }
	  else
	    {
	      output_asm_insn ("bv,n %%r0(%%r1)", xoperands);
	      nbytes += 24;
	    }
	}
      else if (TARGET_PORTABLE_RUNTIME)
	{
	  output_asm_insn ("ldil L'%0,%%r1", xoperands);
	  output_asm_insn ("ldo R'%0(%%r1),%%r22", xoperands);

	  if (!val_14)
	    output_asm_insn ("ldil L'%2,%%r26", xoperands);

	  output_asm_insn ("bv %%r0(%%r22)", xoperands);

	  if (val_14)
	    {
	      output_asm_insn ("ldo %2(%%r26),%%r26", xoperands);
	      nbytes += 16;
	    }
	  else
	    {
	      output_asm_insn ("ldo R'%2(%%r26),%%r26", xoperands);
	      nbytes += 20;
	    }
	}
      else if (TARGET_SOM && flag_pic && TREE_PUBLIC (function))
	{
	  /* The function is accessible from outside this module.  The only
	     way to avoid an import stub between the thunk and function is to
	     call the function directly with an indirect sequence similar to
	     that used by $$dyncall.  This is possible because $$dyncall acts
	     as the import stub in an indirect call.  */
	  ASM_GENERATE_INTERNAL_LABEL (label, "LTHN", current_thunk_number);
	  xoperands[3] = gen_rtx_SYMBOL_REF (Pmode, label);
	  output_asm_insn ("addil LT'%3,%%r19", xoperands);
	  output_asm_insn ("ldw RT'%3(%%r1),%%r22", xoperands);
	  output_asm_insn ("ldw 0(%%sr0,%%r22),%%r22", xoperands);
	  output_asm_insn ("bb,>=,n %%r22,30,.+16", xoperands);
	  output_asm_insn ("depi 0,31,2,%%r22", xoperands);
	  output_asm_insn ("ldw 4(%%sr0,%%r22),%%r19", xoperands);
	  output_asm_insn ("ldw 0(%%sr0,%%r22),%%r22", xoperands);

	  if (!val_14)
	    {
	      output_asm_insn ("addil L'%2,%%r26", xoperands);
	      nbytes += 4;
	    }

	  if (TARGET_PA_20)
	    {
	      output_asm_insn ("bve (%%r22)", xoperands);
	      nbytes += 36;
	    }
	  else if (TARGET_NO_SPACE_REGS)
	    {
	      output_asm_insn ("be 0(%%sr4,%%r22)", xoperands);
	      nbytes += 36;
	    }
	  else
	    {
	      output_asm_insn ("ldsid (%%sr0,%%r22),%%r21", xoperands);
	      output_asm_insn ("mtsp %%r21,%%sr0", xoperands);
	      output_asm_insn ("be 0(%%sr0,%%r22)", xoperands);
	      nbytes += 44;
	    }

	  if (val_14)
	    output_asm_insn ("ldo %2(%%r26),%%r26", xoperands);
	  else
	    output_asm_insn ("ldo R'%2(%%r1),%%r26", xoperands);
	}
      else if (flag_pic)
	{
	  rtx xop[4];

	  /* Load function address into %r22.  */
	  xop[0] = xoperands[0];
	  xop[1] = gen_rtx_REG (Pmode, 1);
	  xop[2] = gen_rtx_REG (Pmode, 22);
	  pa_output_pic_pcrel_sequence (xop);

	  if (!val_14)
	    output_asm_insn ("addil L'%2,%%r26", xoperands);

	  output_asm_insn ("bv %%r0(%%r22)", xoperands);

	  if (val_14)
	    {
	      output_asm_insn ("ldo %2(%%r26),%%r26", xoperands);
	      nbytes += 20;
	    }
	  else
	    {
	      output_asm_insn ("ldo R'%2(%%r1),%%r26", xoperands);
	      nbytes += 24;
	    }
	}
      else
	{
	  if (!val_14)
	    output_asm_insn ("addil L'%2,%%r26", xoperands);

	  output_asm_insn ("ldil L'%0,%%r22", xoperands);
	  output_asm_insn ("be R'%0(%%sr4,%%r22)", xoperands);

	  if (val_14)
	    {
	      output_asm_insn ("ldo %2(%%r26),%%r26", xoperands);
	      nbytes += 12;
	    }
	  else
	    {
	      output_asm_insn ("ldo R'%2(%%r1),%%r26", xoperands);
	      nbytes += 16;
	    }
	}
    }
  else
    {
      rtx xop[4];

      /* Add DELTA to THIS.  */
      if (val_14)
	{
	  output_asm_insn ("ldo %2(%%r26),%%r26", xoperands);
	  nbytes += 4;
	}
      else
	{
	  output_asm_insn ("addil L'%2,%%r26", xoperands);
	  output_asm_insn ("ldo R'%2(%%r1),%%r26", xoperands);
	  nbytes += 8;
	}

      if (TARGET_64BIT)
	{
	  /* Load *(THIS + DELTA) to %r1.  */
	  output_asm_insn ("ldd 0(%%r26),%%r1", xoperands);

	  val_14 = VAL_14_BITS_P (vcall_offset);
	  xoperands[2] = GEN_INT (vcall_offset);

	  /* Load  *(*(THIS + DELTA) + VCALL_OFFSET) to %r1.  */
	  if (val_14)
	    {
	      output_asm_insn ("ldd %2(%%r1),%%r1", xoperands);
	      nbytes += 8;
	    }
	  else
	    {
	      output_asm_insn ("addil L'%2,%%r1", xoperands);
	      output_asm_insn ("ldd R'%2(%%r1),%%r1", xoperands);
	      nbytes += 12;
	    }
	}
      else
	{
	  /* Load *(THIS + DELTA) to %r1.  */
	  output_asm_insn ("ldw 0(%%r26),%%r1", xoperands);

	  val_14 = VAL_14_BITS_P (vcall_offset);
	  xoperands[2] = GEN_INT (vcall_offset);

	  /* Load  *(*(THIS + DELTA) + VCALL_OFFSET) to %r1.  */
	  if (val_14)
	    {
	      output_asm_insn ("ldw %2(%%r1),%%r1", xoperands);
	      nbytes += 8;
	    }
	  else
	    {
	      output_asm_insn ("addil L'%2,%%r1", xoperands);
	      output_asm_insn ("ldw R'%2(%%r1),%%r1", xoperands);
	      nbytes += 12;
	    }
	}

      /* Branch to FUNCTION and add %r1 to THIS in delay slot if possible.  */
      if ((!TARGET_LONG_CALLS && TARGET_SOM && !TARGET_PORTABLE_RUNTIME
	   && !(flag_pic && TREE_PUBLIC (function))
	   && (TARGET_GAS || last_address < 262132))
	  || (!TARGET_LONG_CALLS && !TARGET_SOM && !TARGET_PORTABLE_RUNTIME
	      && ((targetm_common.have_named_sections
		   && DECL_SECTION_NAME (thunk_fndecl) != NULL
		   /* The GNU 64-bit linker has rather poor stub management.
		      So, we use a long branch from thunks that aren't in
		      the same section as the target function.  */
		    && ((!TARGET_64BIT
			 && (DECL_SECTION_NAME (thunk_fndecl)
			     != DECL_SECTION_NAME (function)))
			|| ((DECL_SECTION_NAME (thunk_fndecl)
			     == DECL_SECTION_NAME (function))
			    && last_address < 262132)))
		  /* In this case, we need to be able to reach the start of
		     the stub table even though the function is likely closer
		     and can be jumped to directly.  */
		  || (targetm_common.have_named_sections
		      && DECL_SECTION_NAME (thunk_fndecl) == NULL
		      && DECL_SECTION_NAME (function) == NULL
		      && total_code_bytes < MAX_PCREL17F_OFFSET)
		  /* Likewise.  */
		  || (!targetm_common.have_named_sections
		      && total_code_bytes < MAX_PCREL17F_OFFSET))))
	{
	  nbytes += 4;
	  output_asm_insn ("b %0", xoperands);

	  /* Add *(*(THIS + DELTA) + VCALL_OFFSET) to THIS.  */
	  output_asm_insn ("addl %%r1,%%r26,%%r26", xoperands);
	}
      else if (TARGET_64BIT)
	{
	  /* Add *(*(THIS + DELTA) + VCALL_OFFSET) to THIS.  */
	  output_asm_insn ("addl %%r1,%%r26,%%r26", xoperands);

	  /* Load function address into %r1.  */
	  nbytes += 16;
	  xop[0] = xoperands[0];
	  xop[1] = gen_rtx_REG (Pmode, 1);
	  xop[2] = xop[1];
	  pa_output_pic_pcrel_sequence (xop);

	  output_asm_insn ("bv,n %%r0(%%r1)", xoperands);
	}
      else if (TARGET_PORTABLE_RUNTIME)
	{
	  /* Load function address into %r22.  */
	  nbytes += 12;
	  output_asm_insn ("ldil L'%0,%%r22", xoperands);
	  output_asm_insn ("ldo R'%0(%%r22),%%r22", xoperands);

	  output_asm_insn ("bv %%r0(%%r22)", xoperands);

	  /* Add *(*(THIS + DELTA) + VCALL_OFFSET) to THIS.  */
	  output_asm_insn ("addl %%r1,%%r26,%%r26", xoperands);
	}
      else if (TARGET_SOM && flag_pic && TREE_PUBLIC (function))
	{
	  /* Add *(*(THIS + DELTA) + VCALL_OFFSET) to THIS.  */
	  output_asm_insn ("addl %%r1,%%r26,%%r26", xoperands);

	  /* The function is accessible from outside this module.  The only
	     way to avoid an import stub between the thunk and function is to
	     call the function directly with an indirect sequence similar to
	     that used by $$dyncall.  This is possible because $$dyncall acts
	     as the import stub in an indirect call.  */
	  ASM_GENERATE_INTERNAL_LABEL (label, "LTHN", current_thunk_number);
	  xoperands[3] = gen_rtx_SYMBOL_REF (Pmode, label);
	  output_asm_insn ("addil LT'%3,%%r19", xoperands);
	  output_asm_insn ("ldw RT'%3(%%r1),%%r22", xoperands);
	  output_asm_insn ("ldw 0(%%sr0,%%r22),%%r22", xoperands);
	  output_asm_insn ("bb,>=,n %%r22,30,.+16", xoperands);
	  output_asm_insn ("depi 0,31,2,%%r22", xoperands);
	  output_asm_insn ("ldw 4(%%sr0,%%r22),%%r19", xoperands);
	  output_asm_insn ("ldw 0(%%sr0,%%r22),%%r22", xoperands);

	  if (TARGET_PA_20)
	    {
	      output_asm_insn ("bve,n (%%r22)", xoperands);
	      nbytes += 32;
	    }
	  else if (TARGET_NO_SPACE_REGS)
	    {
	      output_asm_insn ("be,n 0(%%sr4,%%r22)", xoperands);
	      nbytes += 32;
	    }
	  else
	    {
	      output_asm_insn ("ldsid (%%sr0,%%r22),%%r21", xoperands);
	      output_asm_insn ("mtsp %%r21,%%sr0", xoperands);
	      output_asm_insn ("be,n 0(%%sr0,%%r22)", xoperands);
	      nbytes += 40;
	    }
	}
      else if (flag_pic)
	{
	  /* Add *(*(THIS + DELTA) + VCALL_OFFSET) to THIS.  */
	  output_asm_insn ("addl %%r1,%%r26,%%r26", xoperands);

	  /* Load function address into %r1.  */
	  nbytes += 16;
	  xop[0] = xoperands[0];
	  xop[1] = gen_rtx_REG (Pmode, 1);
	  xop[2] = xop[1];
	  pa_output_pic_pcrel_sequence (xop);

	  output_asm_insn ("bv,n %%r0(%%r1)", xoperands);
	}
      else
	{
	  /* Load function address into %r22.  */
	  nbytes += 8;
	  output_asm_insn ("ldil L'%0,%%r22", xoperands);
	  output_asm_insn ("be R'%0(%%sr4,%%r22)", xoperands);

	  /* Add *(*(THIS + DELTA) + VCALL_OFFSET) to THIS.  */
	  output_asm_insn ("addl %%r1,%%r26,%%r26", xoperands);
	}
    }

  final_end_function ();

  if (TARGET_SOM && flag_pic && TREE_PUBLIC (function))
    {
      switch_to_section (data_section);
      output_asm_insn (".align 4", xoperands);
      ASM_OUTPUT_LABEL (file, label);
      output_asm_insn (".word P'%0", xoperands);
    }

  current_thunk_number++;
  nbytes = ((nbytes + FUNCTION_BOUNDARY / BITS_PER_UNIT - 1)
	    & ~(FUNCTION_BOUNDARY / BITS_PER_UNIT - 1));
  last_address += nbytes;
  if (old_last_address > last_address)
    last_address = UINT_MAX;
  update_total_code_bytes (nbytes);
  assemble_end_function (thunk_fndecl, fnname);
}

/* Only direct calls to static functions are allowed to be sibling (tail)
   call optimized.

   This restriction is necessary because some linker generated stubs will
   store return pointers into rp' in some cases which might clobber a
   live value already in rp'.

   In a sibcall the current function and the target function share stack
   space.  Thus if the path to the current function and the path to the
   target function save a value in rp', they save the value into the
   same stack slot, which has undesirable consequences.

   Because of the deferred binding nature of shared libraries any function
   with external scope could be in a different load module and thus require
   rp' to be saved when calling that function.  So sibcall optimizations
   can only be safe for static function.

   Note that GCC never needs return value relocations, so we don't have to
   worry about static calls with return value relocations (which require
   saving rp').

   It is safe to perform a sibcall optimization when the target function
   will never return.  */
static bool
pa_function_ok_for_sibcall (tree decl, tree exp ATTRIBUTE_UNUSED)
{
  /* Sibcalls are not ok because the arg pointer register is not a fixed
     register.  This prevents the sibcall optimization from occurring.  In
     addition, there are problems with stub placement using GNU ld.  This
     is because a normal sibcall branch uses a 17-bit relocation while
     a regular call branch uses a 22-bit relocation.  As a result, more
     care needs to be taken in the placement of long-branch stubs.  */
  if (TARGET_64BIT)
    return false;

  if (TARGET_PORTABLE_RUNTIME)
    return false;

  /* Sibcalls are only ok within a translation unit.  */
  return decl && targetm.binds_local_p (decl);
}

/* ??? Addition is not commutative on the PA due to the weird implicit
   space register selection rules for memory addresses.  Therefore, we
   don't consider a + b == b + a, as this might be inside a MEM.  */
static bool
pa_commutative_p (const_rtx x, int outer_code)
{
  return (COMMUTATIVE_P (x)
	  && (TARGET_NO_SPACE_REGS
	      || (outer_code != UNKNOWN && outer_code != MEM)
	      || GET_CODE (x) != PLUS));
}

/* Returns 1 if the 6 operands specified in OPERANDS are suitable for
   use in fmpyadd instructions.  */
int
pa_fmpyaddoperands (rtx *operands)
{
  machine_mode mode = GET_MODE (operands[0]);

  /* Must be a floating point mode.  */
  if (mode != SFmode && mode != DFmode)
    return 0;

  /* All modes must be the same.  */
  if (! (mode == GET_MODE (operands[1])
	 && mode == GET_MODE (operands[2])
	 && mode == GET_MODE (operands[3])
	 && mode == GET_MODE (operands[4])
	 && mode == GET_MODE (operands[5])))
    return 0;

  /* All operands must be registers.  */
  if (! (GET_CODE (operands[1]) == REG
	 && GET_CODE (operands[2]) == REG
	 && GET_CODE (operands[3]) == REG
	 && GET_CODE (operands[4]) == REG
	 && GET_CODE (operands[5]) == REG))
    return 0;

  /* Only 2 real operands to the addition.  One of the input operands must
     be the same as the output operand.  */
  if (! rtx_equal_p (operands[3], operands[4])
      && ! rtx_equal_p (operands[3], operands[5]))
    return 0;

  /* Inout operand of add cannot conflict with any operands from multiply.  */
  if (rtx_equal_p (operands[3], operands[0])
     || rtx_equal_p (operands[3], operands[1])
     || rtx_equal_p (operands[3], operands[2]))
    return 0;

  /* multiply cannot feed into addition operands.  */
  if (rtx_equal_p (operands[4], operands[0])
      || rtx_equal_p (operands[5], operands[0]))
    return 0;

  /* SFmode limits the registers to the upper 32 of the 32bit FP regs.  */
  if (mode == SFmode
      && (REGNO_REG_CLASS (REGNO (operands[0])) != FPUPPER_REGS
	  || REGNO_REG_CLASS (REGNO (operands[1])) != FPUPPER_REGS
	  || REGNO_REG_CLASS (REGNO (operands[2])) != FPUPPER_REGS
	  || REGNO_REG_CLASS (REGNO (operands[3])) != FPUPPER_REGS
	  || REGNO_REG_CLASS (REGNO (operands[4])) != FPUPPER_REGS
	  || REGNO_REG_CLASS (REGNO (operands[5])) != FPUPPER_REGS))
    return 0;

  /* Passed.  Operands are suitable for fmpyadd.  */
  return 1;
}

#if !defined(USE_COLLECT2)
static void
pa_asm_out_constructor (rtx symbol, int priority)
{
  if (!function_label_operand (symbol, VOIDmode))
    pa_encode_label (symbol);

#ifdef CTORS_SECTION_ASM_OP
  default_ctor_section_asm_out_constructor (symbol, priority);
#else
# ifdef TARGET_ASM_NAMED_SECTION
  default_named_section_asm_out_constructor (symbol, priority);
# else
  default_stabs_asm_out_constructor (symbol, priority);
# endif
#endif
}

static void
pa_asm_out_destructor (rtx symbol, int priority)
{
  if (!function_label_operand (symbol, VOIDmode))
    pa_encode_label (symbol);

#ifdef DTORS_SECTION_ASM_OP
  default_dtor_section_asm_out_destructor (symbol, priority);
#else
# ifdef TARGET_ASM_NAMED_SECTION
  default_named_section_asm_out_destructor (symbol, priority);
# else
  default_stabs_asm_out_destructor (symbol, priority);
# endif
#endif
}
#endif

/* This function places uninitialized global data in the bss section.
   The ASM_OUTPUT_ALIGNED_BSS macro needs to be defined to call this
   function on the SOM port to prevent uninitialized global data from
   being placed in the data section.  */
   
void
pa_asm_output_aligned_bss (FILE *stream,
			   const char *name,
			   unsigned HOST_WIDE_INT size,
			   unsigned int align)
{
  switch_to_section (bss_section);

#ifdef ASM_OUTPUT_TYPE_DIRECTIVE
  ASM_OUTPUT_TYPE_DIRECTIVE (stream, name, "object");
#endif

#ifdef ASM_OUTPUT_SIZE_DIRECTIVE
  ASM_OUTPUT_SIZE_DIRECTIVE (stream, name, size);
#endif

  fprintf (stream, "\t.align %u\n", align / BITS_PER_UNIT);
  ASM_OUTPUT_LABEL (stream, name);
  fprintf (stream, "\t.block " HOST_WIDE_INT_PRINT_UNSIGNED"\n", size);
}

/* Both the HP and GNU assemblers under HP-UX provide a .comm directive
   that doesn't allow the alignment of global common storage to be directly
   specified.  The SOM linker aligns common storage based on the rounded
   value of the NUM_BYTES parameter in the .comm directive.  It's not
   possible to use the .align directive as it doesn't affect the alignment
   of the label associated with a .comm directive.  */

void
pa_asm_output_aligned_common (FILE *stream,
			      const char *name,
			      unsigned HOST_WIDE_INT size,
			      unsigned int align)
{
  unsigned int max_common_align;

  max_common_align = TARGET_64BIT ? 128 : (size >= 4096 ? 256 : 64);
  if (align > max_common_align)
    {
      /* Alignment exceeds maximum alignment for global common data.  */
      align = max_common_align;
    }

  switch_to_section (bss_section);

  assemble_name (stream, name);
  fprintf (stream, "\t.comm " HOST_WIDE_INT_PRINT_UNSIGNED"\n",
           MAX (size, align / BITS_PER_UNIT));
}

/* We can't use .comm for local common storage as the SOM linker effectively
   treats the symbol as universal and uses the same storage for local symbols
   with the same name in different object files.  The .block directive
   reserves an uninitialized block of storage.  However, it's not common
   storage.  Fortunately, GCC never requests common storage with the same
   name in any given translation unit.  */

void
pa_asm_output_aligned_local (FILE *stream,
			     const char *name,
			     unsigned HOST_WIDE_INT size,
			     unsigned int align)
{
  switch_to_section (bss_section);
  fprintf (stream, "\t.align %u\n", align / BITS_PER_UNIT);

#ifdef LOCAL_ASM_OP
  fprintf (stream, "%s", LOCAL_ASM_OP);
  assemble_name (stream, name);
  fprintf (stream, "\n");
#endif

  ASM_OUTPUT_LABEL (stream, name);
  fprintf (stream, "\t.block " HOST_WIDE_INT_PRINT_UNSIGNED"\n", size);
}

/* Returns 1 if the 6 operands specified in OPERANDS are suitable for
   use in fmpysub instructions.  */
int
pa_fmpysuboperands (rtx *operands)
{
  machine_mode mode = GET_MODE (operands[0]);

  /* Must be a floating point mode.  */
  if (mode != SFmode && mode != DFmode)
    return 0;

  /* All modes must be the same.  */
  if (! (mode == GET_MODE (operands[1])
	 && mode == GET_MODE (operands[2])
	 && mode == GET_MODE (operands[3])
	 && mode == GET_MODE (operands[4])
	 && mode == GET_MODE (operands[5])))
    return 0;

  /* All operands must be registers.  */
  if (! (GET_CODE (operands[1]) == REG
	 && GET_CODE (operands[2]) == REG
	 && GET_CODE (operands[3]) == REG
	 && GET_CODE (operands[4]) == REG
	 && GET_CODE (operands[5]) == REG))
    return 0;

  /* Only 2 real operands to the subtraction.  Subtraction is not a commutative
     operation, so operands[4] must be the same as operand[3].  */
  if (! rtx_equal_p (operands[3], operands[4]))
    return 0;

  /* multiply cannot feed into subtraction.  */
  if (rtx_equal_p (operands[5], operands[0]))
    return 0;

  /* Inout operand of sub cannot conflict with any operands from multiply.  */
  if (rtx_equal_p (operands[3], operands[0])
     || rtx_equal_p (operands[3], operands[1])
     || rtx_equal_p (operands[3], operands[2]))
    return 0;

  /* SFmode limits the registers to the upper 32 of the 32bit FP regs.  */
  if (mode == SFmode
      && (REGNO_REG_CLASS (REGNO (operands[0])) != FPUPPER_REGS
	  || REGNO_REG_CLASS (REGNO (operands[1])) != FPUPPER_REGS
	  || REGNO_REG_CLASS (REGNO (operands[2])) != FPUPPER_REGS
	  || REGNO_REG_CLASS (REGNO (operands[3])) != FPUPPER_REGS
	  || REGNO_REG_CLASS (REGNO (operands[4])) != FPUPPER_REGS
	  || REGNO_REG_CLASS (REGNO (operands[5])) != FPUPPER_REGS))
    return 0;

  /* Passed.  Operands are suitable for fmpysub.  */
  return 1;
}

/* Return 1 if the given constant is 2, 4, or 8.  These are the valid
   constants for a MULT embedded inside a memory address.  */
int
pa_mem_shadd_constant_p (int val)
{
  if (val == 2 || val == 4 || val == 8)
    return 1;
  else
    return 0;
}

/* Return 1 if the given constant is 1, 2, or 3.  These are the valid
   constants for shadd instructions.  */
int
pa_shadd_constant_p (int val)
{
  if (val == 1 || val == 2 || val == 3)
    return 1;
  else
    return 0;
}

/* Return TRUE if INSN branches forward.  */

static bool
forward_branch_p (rtx_insn *insn)
{
  rtx lab = JUMP_LABEL (insn);

  /* The INSN must have a jump label.  */
  gcc_assert (lab != NULL_RTX);

  if (INSN_ADDRESSES_SET_P ())
    return INSN_ADDRESSES (INSN_UID (lab)) > INSN_ADDRESSES (INSN_UID (insn));  

  while (insn)
    {
      if (insn == lab)
	return true;
      else
	insn = NEXT_INSN (insn);
    }

  return false;
}

/* Output an unconditional move and branch insn.  */

const char *
pa_output_parallel_movb (rtx *operands, rtx_insn *insn)
{
  int length = get_attr_length (insn);

  /* These are the cases in which we win.  */
  if (length == 4)
    return "mov%I1b,tr %1,%0,%2";

  /* None of the following cases win, but they don't lose either.  */
  if (length == 8)
    {
      if (dbr_sequence_length () == 0)
	{
	  /* Nothing in the delay slot, fake it by putting the combined
	     insn (the copy or add) in the delay slot of a bl.  */
	  if (GET_CODE (operands[1]) == CONST_INT)
	    return "b %2\n\tldi %1,%0";
	  else
	    return "b %2\n\tcopy %1,%0";
	}
      else
	{
	  /* Something in the delay slot, but we've got a long branch.  */
	  if (GET_CODE (operands[1]) == CONST_INT)
	    return "ldi %1,%0\n\tb %2";
	  else
	    return "copy %1,%0\n\tb %2";
	}
    }

  if (GET_CODE (operands[1]) == CONST_INT)
    output_asm_insn ("ldi %1,%0", operands);
  else
    output_asm_insn ("copy %1,%0", operands);
  return pa_output_lbranch (operands[2], insn, 1);
}

/* Output an unconditional add and branch insn.  */

const char *
pa_output_parallel_addb (rtx *operands, rtx_insn *insn)
{
  int length = get_attr_length (insn);

  /* To make life easy we want operand0 to be the shared input/output
     operand and operand1 to be the readonly operand.  */
  if (operands[0] == operands[1])
    operands[1] = operands[2];

  /* These are the cases in which we win.  */
  if (length == 4)
    return "add%I1b,tr %1,%0,%3";

  /* None of the following cases win, but they don't lose either.  */
  if (length == 8)
    {
      if (dbr_sequence_length () == 0)
	/* Nothing in the delay slot, fake it by putting the combined
	   insn (the copy or add) in the delay slot of a bl.  */
	return "b %3\n\tadd%I1 %1,%0,%0";
      else
	/* Something in the delay slot, but we've got a long branch.  */
	return "add%I1 %1,%0,%0\n\tb %3";
    }

  output_asm_insn ("add%I1 %1,%0,%0", operands);
  return pa_output_lbranch (operands[3], insn, 1);
}

/* We use this hook to perform a PA specific optimization which is difficult
   to do in earlier passes.  */

static void
pa_reorg (void)
{
  remove_useless_addtr_insns (1);

  if (pa_cpu < PROCESSOR_8000)
    pa_combine_instructions ();
}

/* The PA has a number of odd instructions which can perform multiple
   tasks at once.  On first generation PA machines (PA1.0 and PA1.1)
   it may be profitable to combine two instructions into one instruction
   with two outputs.  It's not profitable PA2.0 machines because the
   two outputs would take two slots in the reorder buffers.

   This routine finds instructions which can be combined and combines
   them.  We only support some of the potential combinations, and we
   only try common ways to find suitable instructions.

      * addb can add two registers or a register and a small integer
      and jump to a nearby (+-8k) location.  Normally the jump to the
      nearby location is conditional on the result of the add, but by
      using the "true" condition we can make the jump unconditional.
      Thus addb can perform two independent operations in one insn.

      * movb is similar to addb in that it can perform a reg->reg
      or small immediate->reg copy and jump to a nearby (+-8k location).

      * fmpyadd and fmpysub can perform a FP multiply and either an
      FP add or FP sub if the operands of the multiply and add/sub are
      independent (there are other minor restrictions).  Note both
      the fmpy and fadd/fsub can in theory move to better spots according
      to data dependencies, but for now we require the fmpy stay at a
      fixed location.

      * Many of the memory operations can perform pre & post updates
      of index registers.  GCC's pre/post increment/decrement addressing
      is far too simple to take advantage of all the possibilities.  This
      pass may not be suitable since those insns may not be independent.

      * comclr can compare two ints or an int and a register, nullify
      the following instruction and zero some other register.  This
      is more difficult to use as it's harder to find an insn which
      will generate a comclr than finding something like an unconditional
      branch.  (conditional moves & long branches create comclr insns).

      * Most arithmetic operations can conditionally skip the next
      instruction.  They can be viewed as "perform this operation
      and conditionally jump to this nearby location" (where nearby
      is an insns away).  These are difficult to use due to the
      branch length restrictions.  */

static void
pa_combine_instructions (void)
{
  rtx_insn *anchor;

  /* This can get expensive since the basic algorithm is on the
     order of O(n^2) (or worse).  Only do it for -O2 or higher
     levels of optimization.  */
  if (optimize < 2)
    return;

  /* Walk down the list of insns looking for "anchor" insns which
     may be combined with "floating" insns.  As the name implies,
     "anchor" instructions don't move, while "floating" insns may
     move around.  */
  rtx par = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, NULL_RTX, NULL_RTX));
  rtx_insn *new_rtx = make_insn_raw (par);

  for (anchor = get_insns (); anchor; anchor = NEXT_INSN (anchor))
    {
      enum attr_pa_combine_type anchor_attr;
      enum attr_pa_combine_type floater_attr;

      /* We only care about INSNs, JUMP_INSNs, and CALL_INSNs.
	 Also ignore any special USE insns.  */
      if ((! NONJUMP_INSN_P (anchor) && ! JUMP_P (anchor) && ! CALL_P (anchor))
	  || GET_CODE (PATTERN (anchor)) == USE
	  || GET_CODE (PATTERN (anchor)) == CLOBBER)
	continue;

      anchor_attr = get_attr_pa_combine_type (anchor);
      /* See if anchor is an insn suitable for combination.  */
      if (anchor_attr == PA_COMBINE_TYPE_FMPY
	  || anchor_attr == PA_COMBINE_TYPE_FADDSUB
	  || (anchor_attr == PA_COMBINE_TYPE_UNCOND_BRANCH
	      && ! forward_branch_p (anchor)))
	{
	  rtx_insn *floater;

	  for (floater = PREV_INSN (anchor);
	       floater;
	       floater = PREV_INSN (floater))
	    {
	      if (NOTE_P (floater)
		  || (NONJUMP_INSN_P (floater)
		      && (GET_CODE (PATTERN (floater)) == USE
			  || GET_CODE (PATTERN (floater)) == CLOBBER)))
		continue;

	      /* Anything except a regular INSN will stop our search.  */
	      if (! NONJUMP_INSN_P (floater))
		{
		  floater = NULL;
		  break;
		}

	      /* See if FLOATER is suitable for combination with the
		 anchor.  */
	      floater_attr = get_attr_pa_combine_type (floater);
	      if ((anchor_attr == PA_COMBINE_TYPE_FMPY
		   && floater_attr == PA_COMBINE_TYPE_FADDSUB)
		  || (anchor_attr == PA_COMBINE_TYPE_FADDSUB
		      && floater_attr == PA_COMBINE_TYPE_FMPY))
		{
		  /* If ANCHOR and FLOATER can be combined, then we're
		     done with this pass.  */
		  if (pa_can_combine_p (new_rtx, anchor, floater, 0,
					SET_DEST (PATTERN (floater)),
					XEXP (SET_SRC (PATTERN (floater)), 0),
					XEXP (SET_SRC (PATTERN (floater)), 1)))
		    break;
		}

	      else if (anchor_attr == PA_COMBINE_TYPE_UNCOND_BRANCH
		       && floater_attr == PA_COMBINE_TYPE_ADDMOVE)
		{
		  if (GET_CODE (SET_SRC (PATTERN (floater))) == PLUS)
		    {
		      if (pa_can_combine_p (new_rtx, anchor, floater, 0,
					    SET_DEST (PATTERN (floater)),
					XEXP (SET_SRC (PATTERN (floater)), 0),
					XEXP (SET_SRC (PATTERN (floater)), 1)))
			break;
		    }
		  else
		    {
		      if (pa_can_combine_p (new_rtx, anchor, floater, 0,
					    SET_DEST (PATTERN (floater)),
					    SET_SRC (PATTERN (floater)),
					    SET_SRC (PATTERN (floater))))
			break;
		    }
		}
	    }

	  /* If we didn't find anything on the backwards scan try forwards.  */
	  if (!floater
	      && (anchor_attr == PA_COMBINE_TYPE_FMPY
		  || anchor_attr == PA_COMBINE_TYPE_FADDSUB))
	    {
	      for (floater = anchor; floater; floater = NEXT_INSN (floater))
		{
		  if (NOTE_P (floater)
		      || (NONJUMP_INSN_P (floater)
			  && (GET_CODE (PATTERN (floater)) == USE
			      || GET_CODE (PATTERN (floater)) == CLOBBER)))

		    continue;

		  /* Anything except a regular INSN will stop our search.  */
		  if (! NONJUMP_INSN_P (floater))
		    {
		      floater = NULL;
		      break;
		    }

		  /* See if FLOATER is suitable for combination with the
		     anchor.  */
		  floater_attr = get_attr_pa_combine_type (floater);
		  if ((anchor_attr == PA_COMBINE_TYPE_FMPY
		       && floater_attr == PA_COMBINE_TYPE_FADDSUB)
		      || (anchor_attr == PA_COMBINE_TYPE_FADDSUB
			  && floater_attr == PA_COMBINE_TYPE_FMPY))
		    {
		      /* If ANCHOR and FLOATER can be combined, then we're
			 done with this pass.  */
		      if (pa_can_combine_p (new_rtx, anchor, floater, 1,
					    SET_DEST (PATTERN (floater)),
					    XEXP (SET_SRC (PATTERN (floater)),
						  0),
					    XEXP (SET_SRC (PATTERN (floater)),
						  1)))
			break;
		    }
		}
	    }

	  /* FLOATER will be nonzero if we found a suitable floating
	     insn for combination with ANCHOR.  */
	  if (floater
	      && (anchor_attr == PA_COMBINE_TYPE_FADDSUB
		  || anchor_attr == PA_COMBINE_TYPE_FMPY))
	    {
	      /* Emit the new instruction and delete the old anchor.  */
	      rtvec vtemp = gen_rtvec (2, copy_rtx (PATTERN (anchor)),
				       copy_rtx (PATTERN (floater)));
	      rtx temp = gen_rtx_PARALLEL (VOIDmode, vtemp);
	      emit_insn_before (temp, anchor);

	      SET_INSN_DELETED (anchor);

	      /* Emit a special USE insn for FLOATER, then delete
		 the floating insn.  */
	      temp = copy_rtx (PATTERN (floater));
	      emit_insn_before (gen_rtx_USE (VOIDmode, temp), floater);
	      delete_insn (floater);

	      continue;
	    }
	  else if (floater
		   && anchor_attr == PA_COMBINE_TYPE_UNCOND_BRANCH)
	    {
	      /* Emit the new_jump instruction and delete the old anchor.  */
	      rtvec vtemp = gen_rtvec (2, copy_rtx (PATTERN (anchor)),
				       copy_rtx (PATTERN (floater)));
	      rtx temp = gen_rtx_PARALLEL (VOIDmode, vtemp);
	      temp = emit_jump_insn_before (temp, anchor);

	      JUMP_LABEL (temp) = JUMP_LABEL (anchor);
	      SET_INSN_DELETED (anchor);

	      /* Emit a special USE insn for FLOATER, then delete
		 the floating insn.  */
	      temp = copy_rtx (PATTERN (floater));
	      emit_insn_before (gen_rtx_USE (VOIDmode, temp), floater);
	      delete_insn (floater);
	      continue;
	    }
	}
    }
}

static int
pa_can_combine_p (rtx_insn *new_rtx, rtx_insn *anchor, rtx_insn *floater,
		  int reversed, rtx dest,
		  rtx src1, rtx src2)
{
  int insn_code_number;
  rtx_insn *start, *end;

  /* Create a PARALLEL with the patterns of ANCHOR and
     FLOATER, try to recognize it, then test constraints
     for the resulting pattern.

     If the pattern doesn't match or the constraints
     aren't met keep searching for a suitable floater
     insn.  */
  XVECEXP (PATTERN (new_rtx), 0, 0) = PATTERN (anchor);
  XVECEXP (PATTERN (new_rtx), 0, 1) = PATTERN (floater);
  INSN_CODE (new_rtx) = -1;
  insn_code_number = recog_memoized (new_rtx);
  basic_block bb = BLOCK_FOR_INSN (anchor);
  if (insn_code_number < 0
      || (extract_insn (new_rtx),
	  !constrain_operands (1, get_preferred_alternatives (new_rtx, bb))))
    return 0;

  if (reversed)
    {
      start = anchor;
      end = floater;
    }
  else
    {
      start = floater;
      end = anchor;
    }

  /* There's up to three operands to consider.  One
     output and two inputs.

     The output must not be used between FLOATER & ANCHOR
     exclusive.  The inputs must not be set between
     FLOATER and ANCHOR exclusive.  */

  if (reg_used_between_p (dest, start, end))
    return 0;

  if (reg_set_between_p (src1, start, end))
    return 0;

  if (reg_set_between_p (src2, start, end))
    return 0;

  /* If we get here, then everything is good.  */
  return 1;
}

/* Return nonzero if references for INSN are delayed.

   Millicode insns are actually function calls with some special
   constraints on arguments and register usage.

   Millicode calls always expect their arguments in the integer argument
   registers, and always return their result in %r29 (ret1).  They
   are expected to clobber their arguments, %r1, %r29, and the return
   pointer which is %r31 on 32-bit and %r2 on 64-bit, and nothing else.

   This function tells reorg that the references to arguments and
   millicode calls do not appear to happen until after the millicode call.
   This allows reorg to put insns which set the argument registers into the
   delay slot of the millicode call -- thus they act more like traditional
   CALL_INSNs.

   Note we cannot consider side effects of the insn to be delayed because
   the branch and link insn will clobber the return pointer.  If we happened
   to use the return pointer in the delay slot of the call, then we lose.

   get_attr_type will try to recognize the given insn, so make sure to
   filter out things it will not accept -- SEQUENCE, USE and CLOBBER insns
   in particular.  */
int
pa_insn_refs_are_delayed (rtx_insn *insn)
{
  return ((NONJUMP_INSN_P (insn)
	   && GET_CODE (PATTERN (insn)) != SEQUENCE
	   && GET_CODE (PATTERN (insn)) != USE
	   && GET_CODE (PATTERN (insn)) != CLOBBER
	   && get_attr_type (insn) == TYPE_MILLI));
}

/* Promote the return value, but not the arguments.  */

static machine_mode
pa_promote_function_mode (const_tree type ATTRIBUTE_UNUSED,
                          machine_mode mode,
                          int *punsignedp ATTRIBUTE_UNUSED,
                          const_tree fntype ATTRIBUTE_UNUSED,
                          int for_return)
{
  if (for_return == 0)
    return mode;
  return promote_mode (type, mode, punsignedp);
}

/* On the HP-PA the value is found in register(s) 28(-29), unless
   the mode is SF or DF. Then the value is returned in fr4 (32).

   This must perform the same promotions as PROMOTE_MODE, else promoting
   return values in TARGET_PROMOTE_FUNCTION_MODE will not work correctly.

   Small structures must be returned in a PARALLEL on PA64 in order
   to match the HP Compiler ABI.  */

static rtx
pa_function_value (const_tree valtype, 
                   const_tree func ATTRIBUTE_UNUSED, 
                   bool outgoing ATTRIBUTE_UNUSED)
{
  machine_mode valmode;

  if (AGGREGATE_TYPE_P (valtype)
      || TREE_CODE (valtype) == COMPLEX_TYPE
      || TREE_CODE (valtype) == VECTOR_TYPE)
    {
      HOST_WIDE_INT valsize = int_size_in_bytes (valtype);

      /* Handle aggregates that fit exactly in a word or double word.  */
      if (valsize == UNITS_PER_WORD || valsize == 2 * UNITS_PER_WORD)
	return gen_rtx_REG (TYPE_MODE (valtype), 28);

      if (TARGET_64BIT)
	{
          /* Aggregates with a size less than or equal to 128 bits are
	     returned in GR 28(-29).  They are left justified.  The pad
	     bits are undefined.  Larger aggregates are returned in
	     memory.  */
	  rtx loc[2];
	  int i, offset = 0;
	  int ub = valsize <= UNITS_PER_WORD ? 1 : 2;

	  for (i = 0; i < ub; i++)
	    {
	      loc[i] = gen_rtx_EXPR_LIST (VOIDmode,
					  gen_rtx_REG (DImode, 28 + i),
					  GEN_INT (offset));
	      offset += 8;
	    }

	  return gen_rtx_PARALLEL (BLKmode, gen_rtvec_v (ub, loc));
	}
      else if (valsize > UNITS_PER_WORD)
	{
	  /* Aggregates 5 to 8 bytes in size are returned in general
	     registers r28-r29 in the same manner as other non
	     floating-point objects.  The data is right-justified and
	     zero-extended to 64 bits.  This is opposite to the normal
	     justification used on big endian targets and requires
	     special treatment.  */
	  rtx loc = gen_rtx_EXPR_LIST (VOIDmode,
				       gen_rtx_REG (DImode, 28), const0_rtx);
	  return gen_rtx_PARALLEL (BLKmode, gen_rtvec (1, loc));
	}
    }

  if ((INTEGRAL_TYPE_P (valtype)
       && GET_MODE_BITSIZE (TYPE_MODE (valtype)) < BITS_PER_WORD)
      || POINTER_TYPE_P (valtype))
    valmode = word_mode;
  else
    valmode = TYPE_MODE (valtype);

  if (TREE_CODE (valtype) == REAL_TYPE
      && !AGGREGATE_TYPE_P (valtype)
      && TYPE_MODE (valtype) != TFmode
      && !TARGET_SOFT_FLOAT)
    return gen_rtx_REG (valmode, 32);

  return gen_rtx_REG (valmode, 28);
}

/* Implement the TARGET_LIBCALL_VALUE hook.  */

static rtx
pa_libcall_value (machine_mode mode,
		  const_rtx fun ATTRIBUTE_UNUSED)
{
  if (! TARGET_SOFT_FLOAT
      && (mode == SFmode || mode == DFmode))
    return  gen_rtx_REG (mode, 32);
  else
    return  gen_rtx_REG (mode, 28);
}

/* Implement the TARGET_FUNCTION_VALUE_REGNO_P hook.  */

static bool
pa_function_value_regno_p (const unsigned int regno)
{
  if (regno == 28
      || (! TARGET_SOFT_FLOAT &&  regno == 32))
    return true;

  return false;
}

/* Update the data in CUM to advance over argument ARG.  */

static void
pa_function_arg_advance (cumulative_args_t cum_v,
			 const function_arg_info &arg)
{
  CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
  int arg_size = pa_function_arg_size (arg.mode, arg.type);

  cum->nargs_prototype--;
  cum->words += (arg_size
		 + ((cum->words & 01)
		    && arg.type != NULL_TREE
		    && arg_size > 1));
}

/* Return the location of a parameter that is passed in a register or NULL
   if the parameter has any component that is passed in memory.

   This is new code and will be pushed to into the net sources after
   further testing.

   ??? We might want to restructure this so that it looks more like other
   ports.  */
static rtx
pa_function_arg (cumulative_args_t cum_v, const function_arg_info &arg)
{
  CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
  tree type = arg.type;
  machine_mode mode = arg.mode;
  int max_arg_words = (TARGET_64BIT ? 8 : 4);
  int alignment = 0;
  int arg_size;
  int fpr_reg_base;
  int gpr_reg_base;
  rtx retval;

  if (arg.end_marker_p ())
    return NULL_RTX;

  arg_size = pa_function_arg_size (mode, type);

  /* If this arg would be passed partially or totally on the stack, then
     this routine should return zero.  pa_arg_partial_bytes will
     handle arguments which are split between regs and stack slots if
     the ABI mandates split arguments.  */
  if (!TARGET_64BIT)
    {
      /* The 32-bit ABI does not split arguments.  */
      if (cum->words + arg_size > max_arg_words)
	return NULL_RTX;
    }
  else
    {
      if (arg_size > 1)
	alignment = cum->words & 1;
      if (cum->words + alignment >= max_arg_words)
	return NULL_RTX;
    }

  /* The 32bit ABIs and the 64bit ABIs are rather different,
     particularly in their handling of FP registers.  We might
     be able to cleverly share code between them, but I'm not
     going to bother in the hope that splitting them up results
     in code that is more easily understood.  */

  if (TARGET_64BIT)
    {
      /* Advance the base registers to their current locations.

         Remember, gprs grow towards smaller register numbers while
	 fprs grow to higher register numbers.  Also remember that
	 although FP regs are 32-bit addressable, we pretend that
	 the registers are 64-bits wide.  */
      gpr_reg_base = 26 - cum->words;
      fpr_reg_base = 32 + cum->words;

      /* Arguments wider than one word and small aggregates need special
	 treatment.  */
      if (arg_size > 1
	  || mode == BLKmode
	  || (type && (AGGREGATE_TYPE_P (type)
		       || TREE_CODE (type) == COMPLEX_TYPE
		       || TREE_CODE (type) == VECTOR_TYPE)))
	{
	  /* Double-extended precision (80-bit), quad-precision (128-bit)
	     and aggregates including complex numbers are aligned on
	     128-bit boundaries.  The first eight 64-bit argument slots
	     are associated one-to-one, with general registers r26
	     through r19, and also with floating-point registers fr4
	     through fr11.  Arguments larger than one word are always
	     passed in general registers.

	     Using a PARALLEL with a word mode register results in left
	     justified data on a big-endian target.  */

	  rtx loc[8];
	  int i, offset = 0, ub = arg_size;

	  /* Align the base register.  */
	  gpr_reg_base -= alignment;

	  ub = MIN (ub, max_arg_words - cum->words - alignment);
	  for (i = 0; i < ub; i++)
	    {
	      loc[i] = gen_rtx_EXPR_LIST (VOIDmode,
					  gen_rtx_REG (DImode, gpr_reg_base),
					  GEN_INT (offset));
	      gpr_reg_base -= 1;
	      offset += 8;
	    }

	  return gen_rtx_PARALLEL (mode, gen_rtvec_v (ub, loc));
	}
     }
  else
    {
      /* If the argument is larger than a word, then we know precisely
	 which registers we must use.  */
      if (arg_size > 1)
	{
	  if (cum->words)
	    {
	      gpr_reg_base = 23;
	      fpr_reg_base = 38;
	    }
	  else
	    {
	      gpr_reg_base = 25;
	      fpr_reg_base = 34;
	    }

	  /* Structures 5 to 8 bytes in size are passed in the general
	     registers in the same manner as other non floating-point
	     objects.  The data is right-justified and zero-extended
	     to 64 bits.  This is opposite to the normal justification
	     used on big endian targets and requires special treatment.
	     We now define BLOCK_REG_PADDING to pad these objects.
	     Aggregates, complex and vector types are passed in the same
	     manner as structures.  */
	  if (mode == BLKmode
	      || (type && (AGGREGATE_TYPE_P (type)
			   || TREE_CODE (type) == COMPLEX_TYPE
			   || TREE_CODE (type) == VECTOR_TYPE)))
	    {
	      rtx loc = gen_rtx_EXPR_LIST (VOIDmode,
					   gen_rtx_REG (DImode, gpr_reg_base),
					   const0_rtx);
	      return gen_rtx_PARALLEL (BLKmode, gen_rtvec (1, loc));
	    }
	}
      else
        {
	   /* We have a single word (32 bits).  A simple computation
	      will get us the register #s we need.  */
	   gpr_reg_base = 26 - cum->words;
	   fpr_reg_base = 32 + 2 * cum->words;
	}
    }

  /* Determine if the argument needs to be passed in both general and
     floating point registers.  */
  if (((TARGET_PORTABLE_RUNTIME || TARGET_64BIT || TARGET_ELF32)
       /* If we are doing soft-float with portable runtime, then there
	  is no need to worry about FP regs.  */
       && !TARGET_SOFT_FLOAT
       /* The parameter must be some kind of scalar float, else we just
	  pass it in integer registers.  */
       && GET_MODE_CLASS (mode) == MODE_FLOAT
       /* The target function must not have a prototype.  */
       && cum->nargs_prototype <= 0
       /* libcalls do not need to pass items in both FP and general
	  registers.  */
       && type != NULL_TREE
       /* All this hair applies to "outgoing" args only.  This includes
	  sibcall arguments setup with FUNCTION_INCOMING_ARG.  */
       && !cum->incoming)
      /* Also pass outgoing floating arguments in both registers in indirect
	 calls with the 32 bit ABI and the HP assembler since there is no
	 way to the specify argument locations in static functions.  */
      || (!TARGET_64BIT
	  && !TARGET_GAS
	  && !cum->incoming
	  && cum->indirect
	  && GET_MODE_CLASS (mode) == MODE_FLOAT))
    {
      retval
	= gen_rtx_PARALLEL
	    (mode,
	     gen_rtvec (2,
			gen_rtx_EXPR_LIST (VOIDmode,
					   gen_rtx_REG (mode, fpr_reg_base),
					   const0_rtx),
			gen_rtx_EXPR_LIST (VOIDmode,
					   gen_rtx_REG (mode, gpr_reg_base),
					   const0_rtx)));
    }
  else
    {
      /* See if we should pass this parameter in a general register.  */
      if (TARGET_SOFT_FLOAT
	  /* Indirect calls in the normal 32bit ABI require all arguments
	     to be passed in general registers.  */
	  || (!TARGET_PORTABLE_RUNTIME
	      && !TARGET_64BIT
	      && !TARGET_ELF32
	      && cum->indirect)
	  /* If the parameter is not a scalar floating-point parameter,
	     then it belongs in GPRs.  */
	  || GET_MODE_CLASS (mode) != MODE_FLOAT
	  /* Structure with single SFmode field belongs in GPR.  */
	  || (type && AGGREGATE_TYPE_P (type)))
	retval = gen_rtx_REG (mode, gpr_reg_base);
      else
	retval = gen_rtx_REG (mode, fpr_reg_base);
    }
  return retval;
}

/* Arguments larger than one word are double word aligned.  */

static unsigned int
pa_function_arg_boundary (machine_mode mode, const_tree type)
{
  bool singleword = (type
		     ? (integer_zerop (TYPE_SIZE (type))
			|| !TREE_CONSTANT (TYPE_SIZE (type))
			|| int_size_in_bytes (type) <= UNITS_PER_WORD)
		     : GET_MODE_SIZE (mode) <= UNITS_PER_WORD);

  return singleword ? PARM_BOUNDARY : MAX_PARM_BOUNDARY;
}

/* If this arg would be passed totally in registers or totally on the stack,
   then this routine should return zero.  */

static int
pa_arg_partial_bytes (cumulative_args_t cum_v, const function_arg_info &arg)
{
  CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
  unsigned int max_arg_words = 8;
  unsigned int offset = 0;

  if (!TARGET_64BIT)
    return 0;

  if (pa_function_arg_size (arg.mode, arg.type) > 1 && (cum->words & 1))
    offset = 1;

  if (cum->words + offset + pa_function_arg_size (arg.mode, arg.type)
      <= max_arg_words)
    /* Arg fits fully into registers.  */
    return 0;
  else if (cum->words + offset >= max_arg_words)
    /* Arg fully on the stack.  */
    return 0;
  else
    /* Arg is split.  */
    return (max_arg_words - cum->words - offset) * UNITS_PER_WORD;
}


/* A get_unnamed_section callback for switching to the text section.

   This function is only used with SOM.  Because we don't support
   named subspaces, we can only create a new subspace or switch back
   to the default text subspace.  */

static void
som_output_text_section_asm_op (const void *data ATTRIBUTE_UNUSED)
{
  gcc_assert (TARGET_SOM);
  if (TARGET_GAS)
    {
      if (cfun && cfun->machine && !cfun->machine->in_nsubspa)
	{
	  /* We only want to emit a .nsubspa directive once at the
	     start of the function.  */
	  cfun->machine->in_nsubspa = 1;

	  /* Create a new subspace for the text.  This provides
	     better stub placement and one-only functions.  */
	  if (cfun->decl
	      && DECL_ONE_ONLY (cfun->decl)
	      && !DECL_WEAK (cfun->decl))
	    {
	      output_section_asm_op ("\t.SPACE $TEXT$\n"
				     "\t.NSUBSPA $CODE$,QUAD=0,ALIGN=8,"
				     "ACCESS=44,SORT=24,COMDAT");
	      return;
	    }
	}
      else
	{
	  /* There isn't a current function or the body of the current
	     function has been completed.  So, we are changing to the
	     text section to output debugging information.  Thus, we
	     need to forget that we are in the text section so that
	     varasm.c will call us when text_section is selected again.  */
	  gcc_assert (!cfun || !cfun->machine
		      || cfun->machine->in_nsubspa == 2);
	  in_section = NULL;
	}
      output_section_asm_op ("\t.SPACE $TEXT$\n\t.NSUBSPA $CODE$");
      return;
    }
  output_section_asm_op ("\t.SPACE $TEXT$\n\t.SUBSPA $CODE$");
}

/* A get_unnamed_section callback for switching to comdat data
   sections.  This function is only used with SOM.  */

static void
som_output_comdat_data_section_asm_op (const void *data)
{
  in_section = NULL;
  output_section_asm_op (data);
}

/* Implement TARGET_ASM_INIT_SECTIONS.  */

static void
pa_som_asm_init_sections (void)
{
  text_section
    = get_unnamed_section (0, som_output_text_section_asm_op, NULL);

  /* SOM puts readonly data in the default $LIT$ subspace when PIC code
     is not being generated.  */
  som_readonly_data_section
    = get_unnamed_section (0, output_section_asm_op,
			   "\t.SPACE $TEXT$\n\t.SUBSPA $LIT$");

  /* When secondary definitions are not supported, SOM makes readonly
     data one-only by creating a new $LIT$ subspace in $TEXT$ with
     the comdat flag.  */
  som_one_only_readonly_data_section
    = get_unnamed_section (0, som_output_comdat_data_section_asm_op,
			   "\t.SPACE $TEXT$\n"
			   "\t.NSUBSPA $LIT$,QUAD=0,ALIGN=8,"
			   "ACCESS=0x2c,SORT=16,COMDAT");


  /* When secondary definitions are not supported, SOM makes data one-only
     by creating a new $DATA$ subspace in $PRIVATE$ with the comdat flag.  */
  som_one_only_data_section
    = get_unnamed_section (SECTION_WRITE,
			   som_output_comdat_data_section_asm_op,
			   "\t.SPACE $PRIVATE$\n"
			   "\t.NSUBSPA $DATA$,QUAD=1,ALIGN=8,"
			   "ACCESS=31,SORT=24,COMDAT");

  if (flag_tm)
    som_tm_clone_table_section
      = get_unnamed_section (0, output_section_asm_op,
			     "\t.SPACE $PRIVATE$\n\t.SUBSPA $TM_CLONE_TABLE$");

  /* HPUX ld generates incorrect GOT entries for "T" fixups which
     reference data within the $TEXT$ space (for example constant
     strings in the $LIT$ subspace).

     The assemblers (GAS and HP as) both have problems with handling
     the difference of two symbols.  This is the other correct way to
     reference constant data during PIC code generation.

     Thus, we can't put constant data needing relocation in the $TEXT$
     space during PIC generation.

     Previously, we placed all constant data into the $DATA$ subspace
     when generating PIC code.  This reduces sharing, but it works
     correctly.  Now we rely on pa_reloc_rw_mask() for section selection.
     This puts constant data not needing relocation into the $TEXT$ space.  */
  readonly_data_section = som_readonly_data_section;

  /* We must not have a reference to an external symbol defined in a
     shared library in a readonly section, else the SOM linker will
     complain.

     So, we force exception information into the data section.  */
  exception_section = data_section;
}

/* Implement TARGET_ASM_TM_CLONE_TABLE_SECTION.  */

static section *
pa_som_tm_clone_table_section (void)
{
  return som_tm_clone_table_section;
}

/* On hpux10, the linker will give an error if we have a reference
   in the read-only data section to a symbol defined in a shared
   library.  Therefore, expressions that might require a reloc
   cannot be placed in the read-only data section.  */

static section *
pa_select_section (tree exp, int reloc,
		   unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
{
  if (TREE_CODE (exp) == VAR_DECL
      && TREE_READONLY (exp)
      && !TREE_THIS_VOLATILE (exp)
      && DECL_INITIAL (exp)
      && (DECL_INITIAL (exp) == error_mark_node
          || TREE_CONSTANT (DECL_INITIAL (exp)))
      && !(reloc & pa_reloc_rw_mask ()))
    {
      if (TARGET_SOM
	  && DECL_ONE_ONLY (exp)
	  && !DECL_WEAK (exp))
	return som_one_only_readonly_data_section;
      else
	return readonly_data_section;
    }
  else if (CONSTANT_CLASS_P (exp)
	   && !(reloc & pa_reloc_rw_mask ()))
    return readonly_data_section;
  else if (TARGET_SOM
	   && TREE_CODE (exp) == VAR_DECL
	   && DECL_ONE_ONLY (exp)
	   && !DECL_WEAK (exp))
    return som_one_only_data_section;
  else
    return data_section;
}

/* Implement pa_elf_select_rtx_section.  If X is a function label operand
   and the function is in a COMDAT group, place the plabel reference in the
   .data.rel.ro.local section.  The linker ignores references to symbols in
   discarded sections from this section.  */
   
static section *
pa_elf_select_rtx_section (machine_mode mode, rtx x,
			   unsigned HOST_WIDE_INT align)
{
  if (function_label_operand (x, VOIDmode))
    {
      tree decl = SYMBOL_REF_DECL (x);

      if (!decl || (DECL_P (decl) && DECL_COMDAT_GROUP (decl)))
	return get_named_section (NULL, ".data.rel.ro.local", 1);
    }

  return default_elf_select_rtx_section (mode, x, align);
}

/* Implement pa_reloc_rw_mask.  */

static int
pa_reloc_rw_mask (void)
{
  if (flag_pic || (TARGET_SOM && !TARGET_HPUX_11))
    return 3;

  /* HP linker does not support global relocs in readonly memory.  */
  return TARGET_SOM ? 2 : 0;
}

static void
pa_globalize_label (FILE *stream, const char *name)
{
  /* We only handle DATA objects here, functions are globalized in
     ASM_DECLARE_FUNCTION_NAME.  */
  if (! FUNCTION_NAME_P (name))
  {
    fputs ("\t.EXPORT ", stream);
    assemble_name (stream, name);
    fputs (",DATA\n", stream);
  }
}

/* Worker function for TARGET_STRUCT_VALUE_RTX.  */

static rtx
pa_struct_value_rtx (tree fntype ATTRIBUTE_UNUSED,
		     int incoming ATTRIBUTE_UNUSED)
{
  return gen_rtx_REG (Pmode, PA_STRUCT_VALUE_REGNUM);
}

/* Worker function for TARGET_RETURN_IN_MEMORY.  */

bool
pa_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
{
  /* SOM ABI says that objects larger than 64 bits are returned in memory.
     PA64 ABI says that objects larger than 128 bits are returned in memory.
     Note, int_size_in_bytes can return -1 if the size of the object is
     variable or larger than the maximum value that can be expressed as
     a HOST_WIDE_INT.   It can also return zero for an empty type.  The
     simplest way to handle variable and empty types is to pass them in
     memory.  This avoids problems in defining the boundaries of argument
     slots, allocating registers, etc.  */
  return (int_size_in_bytes (type) > (TARGET_64BIT ? 16 : 8)
	  || int_size_in_bytes (type) <= 0);
}

/* Structure to hold declaration and name of external symbols that are
   emitted by GCC.  We generate a vector of these symbols and output them
   at the end of the file if and only if SYMBOL_REF_REFERENCED_P is true.
   This avoids putting out names that are never really used.  */

typedef struct GTY(()) extern_symbol
{
  tree decl;
  const char *name;
} extern_symbol;

/* Define gc'd vector type for extern_symbol.  */

/* Vector of extern_symbol pointers.  */
static GTY(()) vec<extern_symbol, va_gc> *extern_symbols;

#ifdef ASM_OUTPUT_EXTERNAL_REAL
/* Mark DECL (name NAME) as an external reference (assembler output
   file FILE).  This saves the names to output at the end of the file
   if actually referenced.  */

void
pa_hpux_asm_output_external (FILE *file, tree decl, const char *name)
{
  gcc_assert (file == asm_out_file);
  extern_symbol p = {decl, name};
  vec_safe_push (extern_symbols, p);
}
#endif

/* Output text required at the end of an assembler file.
   This includes deferred plabels and .import directives for
   all external symbols that were actually referenced.  */

static void
pa_file_end (void)
{
#ifdef ASM_OUTPUT_EXTERNAL_REAL
  unsigned int i;
  extern_symbol *p;

  if (!NO_DEFERRED_PROFILE_COUNTERS)
    output_deferred_profile_counters ();
#endif

  output_deferred_plabels ();

#ifdef ASM_OUTPUT_EXTERNAL_REAL
  for (i = 0; vec_safe_iterate (extern_symbols, i, &p); i++)
    {
      tree decl = p->decl;

      if (!TREE_ASM_WRITTEN (decl)
	  && SYMBOL_REF_REFERENCED_P (XEXP (DECL_RTL (decl), 0)))
	ASM_OUTPUT_EXTERNAL_REAL (asm_out_file, decl, p->name);
    }

  vec_free (extern_symbols);
#endif

  if (NEED_INDICATE_EXEC_STACK)
    file_end_indicate_exec_stack ();
}

/* Implement TARGET_CAN_CHANGE_MODE_CLASS.  */

static bool
pa_can_change_mode_class (machine_mode from, machine_mode to,
			  reg_class_t rclass)
{
  if (from == to)
    return true;

  if (GET_MODE_SIZE (from) == GET_MODE_SIZE (to))
    return true;

  /* Reject changes to/from modes with zero size.  */
  if (!GET_MODE_SIZE (from) || !GET_MODE_SIZE (to))
    return false;

  /* Reject changes to/from complex and vector modes.  */
  if (COMPLEX_MODE_P (from) || VECTOR_MODE_P (from)
      || COMPLEX_MODE_P (to) || VECTOR_MODE_P (to))
    return false;
      
  /* There is no way to load QImode or HImode values directly from memory
     to a FP register.  SImode loads to the FP registers are not zero
     extended.  On the 64-bit target, this conflicts with the definition
     of LOAD_EXTEND_OP.  Thus, we reject all mode changes in the FP registers
     except for DImode to SImode on the 64-bit target.  It is handled by
     register renaming in pa_print_operand.  */
  if (MAYBE_FP_REG_CLASS_P (rclass))
    return TARGET_64BIT && from == DImode && to == SImode;

  /* TARGET_HARD_REGNO_MODE_OK places modes with sizes larger than a word
     in specific sets of registers.  Thus, we cannot allow changing
     to a larger mode when it's larger than a word.  */
  if (GET_MODE_SIZE (to) > UNITS_PER_WORD
      && GET_MODE_SIZE (to) > GET_MODE_SIZE (from))
    return false;

  return true;
}

/* Implement TARGET_MODES_TIEABLE_P.
   
   We should return FALSE for QImode and HImode because these modes
   are not ok in the floating-point registers.  However, this prevents
   tieing these modes to SImode and DImode in the general registers.
   So, this isn't a good idea.  We rely on TARGET_HARD_REGNO_MODE_OK and
   TARGET_CAN_CHANGE_MODE_CLASS to prevent these modes from being used
   in the floating-point registers.  */

static bool
pa_modes_tieable_p (machine_mode mode1, machine_mode mode2)
{
  /* Don't tie modes in different classes.  */
  if (GET_MODE_CLASS (mode1) != GET_MODE_CLASS (mode2))
    return false;

  return true;
}


/* Length in units of the trampoline instruction code.  */

#define TRAMPOLINE_CODE_SIZE (TARGET_64BIT ? 24 : (TARGET_PA_20 ? 36 : 48))


/* Output assembler code for a block containing the constant parts
   of a trampoline, leaving space for the variable parts.\

   The trampoline sets the static chain pointer to STATIC_CHAIN_REGNUM
   and then branches to the specified routine.

   This code template is copied from text segment to stack location
   and then patched with pa_trampoline_init to contain valid values,
   and then entered as a subroutine.

   It is best to keep this as small as possible to avoid having to
   flush multiple lines in the cache.  */

static void
pa_asm_trampoline_template (FILE *f)
{
  if (!TARGET_64BIT)
    {
      if (TARGET_PA_20)
	{
	  fputs ("\tmfia	%r20\n", f);
	  fputs ("\tldw		48(%r20),%r22\n", f);
	  fputs ("\tcopy	%r22,%r21\n", f);
	  fputs ("\tbb,>=,n	%r22,30,.+16\n", f);
	  fputs ("\tdepwi	0,31,2,%r22\n", f);
	  fputs ("\tldw		0(%r22),%r21\n", f);
	  fputs ("\tldw		4(%r22),%r19\n", f);
	  fputs ("\tbve		(%r21)\n", f);
	  fputs ("\tldw		52(%r1),%r29\n", f);
	  fputs ("\t.word	0\n", f);
	  fputs ("\t.word	0\n", f);
	  fputs ("\t.word	0\n", f);
	}
      else
	{
	  if (ASSEMBLER_DIALECT == 0)
	    {
	      fputs ("\tbl	.+8,%r20\n", f);
	      fputs ("\tdepi	0,31,2,%r20\n", f);
	    }
	  else
	    {
	      fputs ("\tb,l	.+8,%r20\n", f);
	      fputs ("\tdepwi	0,31,2,%r20\n", f);
	    }
	  fputs ("\tldw		40(%r20),%r22\n", f);
	  fputs ("\tcopy	%r22,%r21\n", f);
	  fputs ("\tbb,>=,n	%r22,30,.+16\n", f);
	  if (ASSEMBLER_DIALECT == 0)
	    fputs ("\tdepi	0,31,2,%r22\n", f);
	  else
	    fputs ("\tdepwi	0,31,2,%r22\n", f);
	  fputs ("\tldw		0(%r22),%r21\n", f);
	  fputs ("\tldw		4(%r22),%r19\n", f);
	  fputs ("\tldsid	(%r21),%r1\n", f);
	  fputs ("\tmtsp	%r1,%sr0\n", f);
	  fputs ("\tbe		0(%sr0,%r21)\n", f);
	  fputs ("\tldw		44(%r20),%r29\n", f);
	}
      fputs ("\t.word	0\n", f);
      fputs ("\t.word	0\n", f);
      fputs ("\t.word	0\n", f);
      fputs ("\t.word	0\n", f);
    }
  else
    {
      fputs ("\t.dword 0\n", f);
      fputs ("\t.dword 0\n", f);
      fputs ("\t.dword 0\n", f);
      fputs ("\t.dword 0\n", f);
      fputs ("\tmfia	%r31\n", f);
      fputs ("\tldd	24(%r31),%r27\n", f);
      fputs ("\tldd	32(%r31),%r31\n", f);
      fputs ("\tldd	16(%r27),%r1\n", f);
      fputs ("\tbve	(%r1)\n", f);
      fputs ("\tldd	24(%r27),%r27\n", f);
      fputs ("\t.dword 0  ; fptr\n", f);
      fputs ("\t.dword 0  ; static link\n", f);
    }
}

/* Emit RTL insns to initialize the variable parts of a trampoline.
   FNADDR is an RTX for the address of the function's pure code.
   CXT is an RTX for the static chain value for the function.

   Move the function address to the trampoline template at offset 48.
   Move the static chain value to trampoline template at offset 52.
   Move the trampoline address to trampoline template at offset 56.
   Move r19 to trampoline template at offset 60.  The latter two
   words create a plabel for the indirect call to the trampoline.

   A similar sequence is used for the 64-bit port but the plabel is
   at the beginning of the trampoline.

   Finally, the cache entries for the trampoline code are flushed.
   This is necessary to ensure that the trampoline instruction sequence
   is written to memory prior to any attempts at prefetching the code
   sequence.  */

static void
pa_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value)
{
  rtx fnaddr = XEXP (DECL_RTL (fndecl), 0);
  rtx start_addr = gen_reg_rtx (Pmode);
  rtx end_addr = gen_reg_rtx (Pmode);
  rtx line_length = gen_reg_rtx (Pmode);
  rtx r_tramp, tmp;

  emit_block_move (m_tramp, assemble_trampoline_template (),
		   GEN_INT (TRAMPOLINE_SIZE), BLOCK_OP_NORMAL);
  r_tramp = force_reg (Pmode, XEXP (m_tramp, 0));

  if (!TARGET_64BIT)
    {
      tmp = adjust_address (m_tramp, Pmode, 48);
      emit_move_insn (tmp, fnaddr);
      tmp = adjust_address (m_tramp, Pmode, 52);
      emit_move_insn (tmp, chain_value);

      /* Create a fat pointer for the trampoline.  */
      tmp = adjust_address (m_tramp, Pmode, 56);
      emit_move_insn (tmp, r_tramp);
      tmp = adjust_address (m_tramp, Pmode, 60);
      emit_move_insn (tmp, gen_rtx_REG (Pmode, 19));

      /* fdc and fic only use registers for the address to flush,
	 they do not accept integer displacements.  We align the
	 start and end addresses to the beginning of their respective
	 cache lines to minimize the number of lines flushed.  */
      emit_insn (gen_andsi3 (start_addr, r_tramp,
			     GEN_INT (-MIN_CACHELINE_SIZE)));
      tmp = force_reg (Pmode, plus_constant (Pmode, r_tramp,
					     TRAMPOLINE_CODE_SIZE-1));
      emit_insn (gen_andsi3 (end_addr, tmp,
			     GEN_INT (-MIN_CACHELINE_SIZE)));
      emit_move_insn (line_length, GEN_INT (MIN_CACHELINE_SIZE));
      emit_insn (gen_dcacheflushsi (start_addr, end_addr, line_length));
      emit_insn (gen_icacheflushsi (start_addr, end_addr, line_length,
				    gen_reg_rtx (Pmode),
				    gen_reg_rtx (Pmode)));
    }
  else
    {
      tmp = adjust_address (m_tramp, Pmode, 56);
      emit_move_insn (tmp, fnaddr);
      tmp = adjust_address (m_tramp, Pmode, 64);
      emit_move_insn (tmp, chain_value);

      /* Create a fat pointer for the trampoline.  */
      tmp = adjust_address (m_tramp, Pmode, 16);
      emit_move_insn (tmp, force_reg (Pmode, plus_constant (Pmode,
							    r_tramp, 32)));
      tmp = adjust_address (m_tramp, Pmode, 24);
      emit_move_insn (tmp, gen_rtx_REG (Pmode, 27));

      /* fdc and fic only use registers for the address to flush,
	 they do not accept integer displacements.  We align the
	 start and end addresses to the beginning of their respective
	 cache lines to minimize the number of lines flushed.  */
      tmp = force_reg (Pmode, plus_constant (Pmode, r_tramp, 32));
      emit_insn (gen_anddi3 (start_addr, tmp,
			     GEN_INT (-MIN_CACHELINE_SIZE)));
      tmp = force_reg (Pmode, plus_constant (Pmode, tmp,
					     TRAMPOLINE_CODE_SIZE - 1));
      emit_insn (gen_anddi3 (end_addr, tmp,
			     GEN_INT (-MIN_CACHELINE_SIZE)));
      emit_move_insn (line_length, GEN_INT (MIN_CACHELINE_SIZE));
      emit_insn (gen_dcacheflushdi (start_addr, end_addr, line_length));
      emit_insn (gen_icacheflushdi (start_addr, end_addr, line_length,
				    gen_reg_rtx (Pmode),
				    gen_reg_rtx (Pmode)));
    }

#ifdef HAVE_ENABLE_EXECUTE_STACK
  emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__enable_execute_stack"),
		     LCT_NORMAL, VOIDmode, XEXP (m_tramp, 0), Pmode);
#endif
}

/* Perform any machine-specific adjustment in the address of the trampoline.
   ADDR contains the address that was passed to pa_trampoline_init.
   Adjust the trampoline address to point to the plabel at offset 56.  */

static rtx
pa_trampoline_adjust_address (rtx addr)
{
  if (!TARGET_64BIT)
    addr = memory_address (Pmode, plus_constant (Pmode, addr, 58));
  return addr;
}

static rtx
pa_delegitimize_address (rtx orig_x)
{
  rtx x = delegitimize_mem_from_attrs (orig_x);

  if (GET_CODE (x) == LO_SUM
      && GET_CODE (XEXP (x, 1)) == UNSPEC
      && XINT (XEXP (x, 1), 1) == UNSPEC_DLTIND14R)
    return gen_const_mem (Pmode, XVECEXP (XEXP (x, 1), 0, 0));
  return x;
}

static rtx
pa_internal_arg_pointer (void)
{
  /* The argument pointer and the hard frame pointer are the same in
     the 32-bit runtime, so we don't need a copy.  */
  if (TARGET_64BIT)
    return copy_to_reg (virtual_incoming_args_rtx);
  else
    return virtual_incoming_args_rtx;
}

/* Given FROM and TO register numbers, say whether this elimination is allowed.
   Frame pointer elimination is automatically handled.  */

static bool
pa_can_eliminate (const int from, const int to)
{
  /* The argument cannot be eliminated in the 64-bit runtime.  */
  if (TARGET_64BIT && from == ARG_POINTER_REGNUM)
    return false;

  return (from == HARD_FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM
          ? ! frame_pointer_needed
          : true);
}

/* Define the offset between two registers, FROM to be eliminated and its
   replacement TO, at the start of a routine.  */
HOST_WIDE_INT
pa_initial_elimination_offset (int from, int to)
{
  HOST_WIDE_INT offset;

  if ((from == HARD_FRAME_POINTER_REGNUM || from == FRAME_POINTER_REGNUM)
      && to == STACK_POINTER_REGNUM)
    offset = -pa_compute_frame_size (get_frame_size (), 0);
  else if (from == FRAME_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
    offset = 0;
  else
    gcc_unreachable ();

  return offset;
}

static void
pa_conditional_register_usage (void)
{
  int i;

  if (!TARGET_64BIT && !TARGET_PA_11)
    {
      for (i = 56; i <= FP_REG_LAST; i++)
	fixed_regs[i] = call_used_regs[i] = 1;
      for (i = 33; i < 56; i += 2)
	fixed_regs[i] = call_used_regs[i] = 1;
    }
  if (TARGET_DISABLE_FPREGS || TARGET_SOFT_FLOAT)
    {
      for (i = FP_REG_FIRST; i <= FP_REG_LAST; i++)
	fixed_regs[i] = call_used_regs[i] = 1;
    }
  if (flag_pic)
    fixed_regs[PIC_OFFSET_TABLE_REGNUM] = 1;
}

/* Target hook for c_mode_for_suffix.  */

static machine_mode
pa_c_mode_for_suffix (char suffix)
{
  if (HPUX_LONG_DOUBLE_LIBRARY)
    {
      if (suffix == 'q')
	return TFmode;
    }

  return VOIDmode;
}

/* Target hook for function_section.  */

static section *
pa_function_section (tree decl, enum node_frequency freq,
		     bool startup, bool exit)
{
  /* Put functions in text section if target doesn't have named sections.  */
  if (!targetm_common.have_named_sections)
    return text_section;

  /* Force nested functions into the same section as the containing
     function.  */
  if (decl
      && DECL_SECTION_NAME (decl) == NULL
      && DECL_CONTEXT (decl) != NULL_TREE
      && TREE_CODE (DECL_CONTEXT (decl)) == FUNCTION_DECL
      && DECL_SECTION_NAME (DECL_CONTEXT (decl)) == NULL)
    return function_section (DECL_CONTEXT (decl));

  /* Otherwise, use the default function section.  */
  return default_function_section (decl, freq, startup, exit);
}

/* Implement TARGET_LEGITIMATE_CONSTANT_P.

   In 64-bit mode, we reject CONST_DOUBLES.  We also reject CONST_INTS
   that need more than three instructions to load prior to reload.  This
   limit is somewhat arbitrary.  It takes three instructions to load a
   CONST_INT from memory but two are memory accesses.  It may be better
   to increase the allowed range for CONST_INTS.  We may also be able
   to handle CONST_DOUBLES.  */

static bool
pa_legitimate_constant_p (machine_mode mode, rtx x)
{
  if (GET_MODE_CLASS (mode) == MODE_FLOAT && x != CONST0_RTX (mode))
    return false;

  if (!NEW_HP_ASSEMBLER && !TARGET_GAS && GET_CODE (x) == LABEL_REF)
    return false;

  /* TLS_MODEL_GLOBAL_DYNAMIC and TLS_MODEL_LOCAL_DYNAMIC are not
     legitimate constants.  The other variants can't be handled by
     the move patterns after reload starts.  */
  if (tls_referenced_p (x))
    return false;

  if (TARGET_64BIT && GET_CODE (x) == CONST_DOUBLE)
    return false;

  if (TARGET_64BIT
      && HOST_BITS_PER_WIDE_INT > 32
      && GET_CODE (x) == CONST_INT
      && !reload_in_progress
      && !reload_completed
      && !LEGITIMATE_64BIT_CONST_INT_P (INTVAL (x))
      && !pa_cint_ok_for_move (UINTVAL (x)))
    return false;

  if (function_label_operand (x, mode))
    return false;

  return true;
}

/* Implement TARGET_SECTION_TYPE_FLAGS.  */

static unsigned int
pa_section_type_flags (tree decl, const char *name, int reloc)
{
  unsigned int flags;

  flags = default_section_type_flags (decl, name, reloc);

  /* Function labels are placed in the constant pool.  This can
     cause a section conflict if decls are put in ".data.rel.ro"
     or ".data.rel.ro.local" using the __attribute__ construct.  */
  if (strcmp (name, ".data.rel.ro") == 0
      || strcmp (name, ".data.rel.ro.local") == 0)
    flags |= SECTION_WRITE | SECTION_RELRO;

  return flags;
}

/* pa_legitimate_address_p recognizes an RTL expression that is a
   valid memory address for an instruction.  The MODE argument is the
   machine mode for the MEM expression that wants to use this address.

   On HP PA-RISC, the legitimate address forms are REG+SMALLINT,
   REG+REG, and REG+(REG*SCALE).  The indexed address forms are only
   available with floating point loads and stores, and integer loads.
   We get better code by allowing indexed addresses in the initial
   RTL generation.

   The acceptance of indexed addresses as legitimate implies that we
   must provide patterns for doing indexed integer stores, or the move
   expanders must force the address of an indexed store to a register.
   We have adopted the latter approach.
   
   Another function of pa_legitimate_address_p is to ensure that
   the base register is a valid pointer for indexed instructions.
   On targets that have non-equivalent space registers, we have to
   know at the time of assembler output which register in a REG+REG
   pair is the base register.  The REG_POINTER flag is sometimes lost
   in reload and the following passes, so it can't be relied on during
   code generation.  Thus, we either have to canonicalize the order
   of the registers in REG+REG indexed addresses, or treat REG+REG
   addresses separately and provide patterns for both permutations.

   The latter approach requires several hundred additional lines of
   code in pa.md.  The downside to canonicalizing is that a PLUS
   in the wrong order can't combine to form to make a scaled indexed
   memory operand.  As we won't need to canonicalize the operands if
   the REG_POINTER lossage can be fixed, it seems better canonicalize.

   We initially break out scaled indexed addresses in canonical order
   in pa_emit_move_sequence.  LEGITIMIZE_ADDRESS also canonicalizes
   scaled indexed addresses during RTL generation.  However, fold_rtx
   has its own opinion on how the operands of a PLUS should be ordered.
   If one of the operands is equivalent to a constant, it will make
   that operand the second operand.  As the base register is likely to
   be equivalent to a SYMBOL_REF, we have made it the second operand.

   pa_legitimate_address_p accepts REG+REG as legitimate when the
   operands are in the order INDEX+BASE on targets with non-equivalent
   space registers, and in any order on targets with equivalent space
   registers.  It accepts both MULT+BASE and BASE+MULT for scaled indexing.

   We treat a SYMBOL_REF as legitimate if it is part of the current
   function's constant-pool, because such addresses can actually be
   output as REG+SMALLINT.  */

static bool
pa_legitimate_address_p (machine_mode mode, rtx x, bool strict)
{
  if ((REG_P (x)
       && (strict ? STRICT_REG_OK_FOR_BASE_P (x)
		  : REG_OK_FOR_BASE_P (x)))
      || ((GET_CODE (x) == PRE_DEC || GET_CODE (x) == POST_DEC
	   || GET_CODE (x) == PRE_INC || GET_CODE (x) == POST_INC)
	  && REG_P (XEXP (x, 0))
	  && (strict ? STRICT_REG_OK_FOR_BASE_P (XEXP (x, 0))
		     : REG_OK_FOR_BASE_P (XEXP (x, 0)))))
    return true;

  if (GET_CODE (x) == PLUS)
    {
      rtx base, index;

      /* For REG+REG, the base register should be in XEXP (x, 1),
	 so check it first.  */
      if (REG_P (XEXP (x, 1))
	  && (strict ? STRICT_REG_OK_FOR_BASE_P (XEXP (x, 1))
		     : REG_OK_FOR_BASE_P (XEXP (x, 1))))
	base = XEXP (x, 1), index = XEXP (x, 0);
      else if (REG_P (XEXP (x, 0))
	       && (strict ? STRICT_REG_OK_FOR_BASE_P (XEXP (x, 0))
			  : REG_OK_FOR_BASE_P (XEXP (x, 0))))
	base = XEXP (x, 0), index = XEXP (x, 1);
      else
	return false;

      if (GET_CODE (index) == CONST_INT)
	{
	  if (INT_5_BITS (index))
	    return true;

	  /* When INT14_OK_STRICT is false, a secondary reload is needed
	     to adjust the displacement of SImode and DImode floating point
	     instructions but this may fail when the register also needs
	     reloading.  So, we return false when STRICT is true.  We
	     also reject long displacements for float mode addresses since
	     the majority of accesses will use floating point instructions
	     that don't support 14-bit offsets.  */
	  if (!INT14_OK_STRICT
	      && (strict || !(reload_in_progress || reload_completed))
	      && mode != QImode
	      && mode != HImode)
	    return false;

	  return base14_operand (index, mode);
	}

      if (!TARGET_DISABLE_INDEXING
	  /* Only accept the "canonical" INDEX+BASE operand order
	     on targets with non-equivalent space registers.  */
	  && (TARGET_NO_SPACE_REGS
	      ? REG_P (index)
	      : (base == XEXP (x, 1) && REG_P (index)
		 && (reload_completed
		     || (reload_in_progress && HARD_REGISTER_P (base))
		     || REG_POINTER (base))
		 && (reload_completed
		     || (reload_in_progress && HARD_REGISTER_P (index))
		     || !REG_POINTER (index))))
	  && MODE_OK_FOR_UNSCALED_INDEXING_P (mode)
	  && (strict ? STRICT_REG_OK_FOR_INDEX_P (index)
		     : REG_OK_FOR_INDEX_P (index))
	  && borx_reg_operand (base, Pmode)
	  && borx_reg_operand (index, Pmode))
	return true;

      if (!TARGET_DISABLE_INDEXING
	  && GET_CODE (index) == MULT
	  /* Only accept base operands with the REG_POINTER flag prior to
	     reload on targets with non-equivalent space registers.  */
	  && (TARGET_NO_SPACE_REGS
	      || (base == XEXP (x, 1)
		  && (reload_completed
		      || (reload_in_progress && HARD_REGISTER_P (base))
		      || REG_POINTER (base))))
	  && REG_P (XEXP (index, 0))
	  && GET_MODE (XEXP (index, 0)) == Pmode
	  && MODE_OK_FOR_SCALED_INDEXING_P (mode)
	  && (strict ? STRICT_REG_OK_FOR_INDEX_P (XEXP (index, 0))
		     : REG_OK_FOR_INDEX_P (XEXP (index, 0)))
	  && GET_CODE (XEXP (index, 1)) == CONST_INT
	  && INTVAL (XEXP (index, 1))
	     == (HOST_WIDE_INT) GET_MODE_SIZE (mode)
	  && borx_reg_operand (base, Pmode))
	return true;

      return false;
    }

  if (GET_CODE (x) == LO_SUM)
    {
      rtx y = XEXP (x, 0);

      if (GET_CODE (y) == SUBREG)
	y = SUBREG_REG (y);

      if (REG_P (y)
	  && (strict ? STRICT_REG_OK_FOR_BASE_P (y)
		     : REG_OK_FOR_BASE_P (y)))
	{
	  /* Needed for -fPIC */
	  if (mode == Pmode
	      && GET_CODE (XEXP (x, 1)) == UNSPEC)
	    return true;

	  if (!INT14_OK_STRICT
	      && (strict || !(reload_in_progress || reload_completed))
	      && mode != QImode
	      && mode != HImode)
	    return false;

	  if (CONSTANT_P (XEXP (x, 1)))
	    return true;
	}
      return false;
    }

  if (GET_CODE (x) == CONST_INT && INT_5_BITS (x))
    return true;

  return false;
}

/* Look for machine dependent ways to make the invalid address AD a
   valid address.

   For the PA, transform:

        memory(X + <large int>)

   into:

        if (<large int> & mask) >= 16
          Y = (<large int> & ~mask) + mask + 1  Round up.
        else
          Y = (<large int> & ~mask)             Round down.
        Z = X + Y
        memory (Z + (<large int> - Y));

   This makes reload inheritance and reload_cse work better since Z
   can be reused.

   There may be more opportunities to improve code with this hook.  */

rtx
pa_legitimize_reload_address (rtx ad, machine_mode mode,
			      int opnum, int type,
			      int ind_levels ATTRIBUTE_UNUSED)
{
  long offset, newoffset, mask;
  rtx new_rtx, temp = NULL_RTX;

  mask = (GET_MODE_CLASS (mode) == MODE_FLOAT
	  && !INT14_OK_STRICT ? 0x1f : 0x3fff);

  if (optimize && GET_CODE (ad) == PLUS)
    temp = simplify_binary_operation (PLUS, Pmode,
				      XEXP (ad, 0), XEXP (ad, 1));

  new_rtx = temp ? temp : ad;

  if (optimize
      && GET_CODE (new_rtx) == PLUS
      && GET_CODE (XEXP (new_rtx, 0)) == REG
      && GET_CODE (XEXP (new_rtx, 1)) == CONST_INT)
    {
      offset = INTVAL (XEXP ((new_rtx), 1));

      /* Choose rounding direction.  Round up if we are >= halfway.  */
      if ((offset & mask) >= ((mask + 1) / 2))
	newoffset = (offset & ~mask) + mask + 1;
      else
	newoffset = offset & ~mask;

      /* Ensure that long displacements are aligned.  */
      if (mask == 0x3fff
	  && (GET_MODE_CLASS (mode) == MODE_FLOAT
	      || (TARGET_64BIT && (mode) == DImode)))
	newoffset &= ~(GET_MODE_SIZE (mode) - 1);

      if (newoffset != 0 && VAL_14_BITS_P (newoffset))
	{
	  temp = gen_rtx_PLUS (Pmode, XEXP (new_rtx, 0),
			       GEN_INT (newoffset));
	  ad = gen_rtx_PLUS (Pmode, temp, GEN_INT (offset - newoffset));
	  push_reload (XEXP (ad, 0), 0, &XEXP (ad, 0), 0,
		       BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
		       opnum, (enum reload_type) type);
	  return ad;
	}
    }

  return NULL_RTX;
}

/* Output address vector.  */

void
pa_output_addr_vec (rtx lab, rtx body)
{
  int idx, vlen = XVECLEN (body, 0);

  if (!TARGET_SOM)
    fputs ("\t.align 4\n", asm_out_file);
  targetm.asm_out.internal_label (asm_out_file, "L", CODE_LABEL_NUMBER (lab));
  if (TARGET_GAS)
    fputs ("\t.begin_brtab\n", asm_out_file);
  for (idx = 0; idx < vlen; idx++)
    {
      ASM_OUTPUT_ADDR_VEC_ELT
	(asm_out_file, CODE_LABEL_NUMBER (XEXP (XVECEXP (body, 0, idx), 0)));
    }
  if (TARGET_GAS)
    fputs ("\t.end_brtab\n", asm_out_file);
}

/* Output address difference vector.  */

void
pa_output_addr_diff_vec (rtx lab, rtx body)
{
  rtx base = XEXP (XEXP (body, 0), 0);
  int idx, vlen = XVECLEN (body, 1);

  targetm.asm_out.internal_label (asm_out_file, "L", CODE_LABEL_NUMBER (lab));
  if (TARGET_GAS)
    fputs ("\t.begin_brtab\n", asm_out_file);
  for (idx = 0; idx < vlen; idx++)
    {
      ASM_OUTPUT_ADDR_DIFF_ELT
	(asm_out_file,
	 body,
	 CODE_LABEL_NUMBER (XEXP (XVECEXP (body, 1, idx), 0)),
	 CODE_LABEL_NUMBER (base));
    }
  if (TARGET_GAS)
    fputs ("\t.end_brtab\n", asm_out_file);
}

/* This is a helper function for the other atomic operations.  This function
   emits a loop that contains SEQ that iterates until a compare-and-swap
   operation at the end succeeds.  MEM is the memory to be modified.  SEQ is
   a set of instructions that takes a value from OLD_REG as an input and
   produces a value in NEW_REG as an output.  Before SEQ, OLD_REG will be
   set to the current contents of MEM.  After SEQ, a compare-and-swap will
   attempt to update MEM with NEW_REG.  The function returns true when the
   loop was generated successfully.  */

static bool
pa_expand_compare_and_swap_loop (rtx mem, rtx old_reg, rtx new_reg, rtx seq)
{
  machine_mode mode = GET_MODE (mem);
  rtx_code_label *label;
  rtx cmp_reg, success, oldval;

  /* The loop we want to generate looks like

        cmp_reg = mem;
      label:
        old_reg = cmp_reg;
        seq;
        (success, cmp_reg) = compare-and-swap(mem, old_reg, new_reg)
        if (success)
          goto label;

     Note that we only do the plain load from memory once.  Subsequent
     iterations use the value loaded by the compare-and-swap pattern.  */

  label = gen_label_rtx ();
  cmp_reg = gen_reg_rtx (mode);

  emit_move_insn (cmp_reg, mem);
  emit_label (label);
  emit_move_insn (old_reg, cmp_reg);
  if (seq)
    emit_insn (seq);

  success = NULL_RTX;
  oldval = cmp_reg;
  if (!expand_atomic_compare_and_swap (&success, &oldval, mem, old_reg,
                                       new_reg, false, MEMMODEL_SYNC_SEQ_CST,
                                       MEMMODEL_RELAXED))
    return false;

  if (oldval != cmp_reg)
    emit_move_insn (cmp_reg, oldval);

  /* Mark this jump predicted not taken.  */
  emit_cmp_and_jump_insns (success, const0_rtx, EQ, const0_rtx,
                           GET_MODE (success), 1, label,
			   profile_probability::guessed_never ());
  return true;
}

/* This function tries to implement an atomic exchange operation using a 
   compare_and_swap loop. VAL is written to *MEM.  The previous contents of
   *MEM are returned, using TARGET if possible.  No memory model is required
   since a compare_and_swap loop is seq-cst.  */

rtx
pa_maybe_emit_compare_and_swap_exchange_loop (rtx target, rtx mem, rtx val)
{
  machine_mode mode = GET_MODE (mem);

  if (can_compare_and_swap_p (mode, true))
    {
      if (!target || !register_operand (target, mode))
        target = gen_reg_rtx (mode);
      if (pa_expand_compare_and_swap_loop (mem, target, val, NULL_RTX))
        return target;
    }

  return NULL_RTX;
}

/* Implement TARGET_CALLEE_COPIES.  The callee is responsible for copying
   arguments passed by hidden reference in the 32-bit HP runtime.  Users
   can override this behavior for better compatibility with openmp at the
   risk of library incompatibilities.  Arguments are always passed by value
   in the 64-bit HP runtime.  */

static bool
pa_callee_copies (cumulative_args_t, const function_arg_info &)
{
  return !TARGET_CALLER_COPIES;
}

/* Implement TARGET_HARD_REGNO_NREGS.  */

static unsigned int
pa_hard_regno_nregs (unsigned int regno ATTRIBUTE_UNUSED, machine_mode mode)
{
  return PA_HARD_REGNO_NREGS (regno, mode);
}

/* Implement TARGET_HARD_REGNO_MODE_OK.  */

static bool
pa_hard_regno_mode_ok (unsigned int regno, machine_mode mode)
{
  return PA_HARD_REGNO_MODE_OK (regno, mode);
}

/* Implement TARGET_STARTING_FRAME_OFFSET.

   On the 32-bit ports, we reserve one slot for the previous frame
   pointer and one fill slot.  The fill slot is for compatibility
   with HP compiled programs.  On the 64-bit ports, we reserve one
   slot for the previous frame pointer.  */

static HOST_WIDE_INT
pa_starting_frame_offset (void)
{
  return 8;
}

/* Figure out the size in words of the function argument.  The size
   returned by this function should always be greater than zero because
   we pass variable and zero sized objects by reference.  */

HOST_WIDE_INT
pa_function_arg_size (machine_mode mode, const_tree type)
{
  HOST_WIDE_INT size;

  size = mode != BLKmode ? GET_MODE_SIZE (mode) : int_size_in_bytes (type); 
  return CEIL (size, UNITS_PER_WORD);
}

#include "gt-pa.h"
