/* Definitions of target machine for GNU compiler.
   Copyright (C) 1999-2022 Free Software Foundation, Inc.
   Contributed by James E. Wilson <wilson@cygnus.com> and
		  David Mosberger <davidm@hpl.hp.com>.

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 "backend.h"
#include "target.h"
#include "rtl.h"
#include "tree.h"
#include "memmodel.h"
#include "cfghooks.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 "alias.h"
#include "fold-const.h"
#include "stor-layout.h"
#include "calls.h"
#include "varasm.h"
#include "output.h"
#include "insn-attr.h"
#include "flags.h"
#include "explow.h"
#include "expr.h"
#include "cfgrtl.h"
#include "libfuncs.h"
#include "sched-int.h"
#include "common/common-target.h"
#include "langhooks.h"
#include "gimplify.h"
#include "intl.h"
#include "debug.h"
#include "dbgcnt.h"
#include "tm-constrs.h"
#include "sel-sched.h"
#include "reload.h"
#include "opts.h"
#include "dumpfile.h"
#include "builtins.h"

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

/* This is used for communication between ASM_OUTPUT_LABEL and
   ASM_OUTPUT_LABELREF.  */
int ia64_asm_output_label = 0;

/* Register names for ia64_expand_prologue.  */
static const char * const ia64_reg_numbers[96] =
{ "r32", "r33", "r34", "r35", "r36", "r37", "r38", "r39",
  "r40", "r41", "r42", "r43", "r44", "r45", "r46", "r47",
  "r48", "r49", "r50", "r51", "r52", "r53", "r54", "r55",
  "r56", "r57", "r58", "r59", "r60", "r61", "r62", "r63",
  "r64", "r65", "r66", "r67", "r68", "r69", "r70", "r71",
  "r72", "r73", "r74", "r75", "r76", "r77", "r78", "r79",
  "r80", "r81", "r82", "r83", "r84", "r85", "r86", "r87",
  "r88", "r89", "r90", "r91", "r92", "r93", "r94", "r95",
  "r96", "r97", "r98", "r99", "r100","r101","r102","r103",
  "r104","r105","r106","r107","r108","r109","r110","r111",
  "r112","r113","r114","r115","r116","r117","r118","r119",
  "r120","r121","r122","r123","r124","r125","r126","r127"};

/* ??? These strings could be shared with REGISTER_NAMES.  */
static const char * const ia64_input_reg_names[8] =
{ "in0",  "in1",  "in2",  "in3",  "in4",  "in5",  "in6",  "in7" };

/* ??? These strings could be shared with REGISTER_NAMES.  */
static const char * const ia64_local_reg_names[80] =
{ "loc0", "loc1", "loc2", "loc3", "loc4", "loc5", "loc6", "loc7",
  "loc8", "loc9", "loc10","loc11","loc12","loc13","loc14","loc15",
  "loc16","loc17","loc18","loc19","loc20","loc21","loc22","loc23",
  "loc24","loc25","loc26","loc27","loc28","loc29","loc30","loc31",
  "loc32","loc33","loc34","loc35","loc36","loc37","loc38","loc39",
  "loc40","loc41","loc42","loc43","loc44","loc45","loc46","loc47",
  "loc48","loc49","loc50","loc51","loc52","loc53","loc54","loc55",
  "loc56","loc57","loc58","loc59","loc60","loc61","loc62","loc63",
  "loc64","loc65","loc66","loc67","loc68","loc69","loc70","loc71",
  "loc72","loc73","loc74","loc75","loc76","loc77","loc78","loc79" };

/* ??? These strings could be shared with REGISTER_NAMES.  */
static const char * const ia64_output_reg_names[8] =
{ "out0", "out1", "out2", "out3", "out4", "out5", "out6", "out7" };

/* Variables which are this size or smaller are put in the sdata/sbss
   sections.  */

unsigned int ia64_section_threshold;

/* The following variable is used by the DFA insn scheduler.  The value is
   TRUE if we do insn bundling instead of insn scheduling.  */
int bundling_p = 0;

enum ia64_frame_regs
{
   reg_fp,
   reg_save_b0,
   reg_save_pr,
   reg_save_ar_pfs,
   reg_save_ar_unat,
   reg_save_ar_lc,
   reg_save_gp,
   number_of_ia64_frame_regs
};

/* Structure to be filled in by ia64_compute_frame_size with register
   save masks and offsets for the current function.  */

struct ia64_frame_info
{
  HOST_WIDE_INT total_size;	/* size of the stack frame, not including
				   the caller's scratch area.  */
  HOST_WIDE_INT spill_cfa_off;	/* top of the reg spill area from the cfa.  */
  HOST_WIDE_INT spill_size;	/* size of the gr/br/fr spill area.  */
  HOST_WIDE_INT extra_spill_size;  /* size of spill area for others.  */
  HARD_REG_SET mask;		/* mask of saved registers.  */
  unsigned int gr_used_mask;	/* mask of registers in use as gr spill
				   registers or long-term scratches.  */
  int n_spilled;		/* number of spilled registers.  */
  int r[number_of_ia64_frame_regs];  /* Frame related registers.  */
  int n_input_regs;		/* number of input registers used.  */
  int n_local_regs;		/* number of local registers used.  */
  int n_output_regs;		/* number of output registers used.  */
  int n_rotate_regs;		/* number of rotating registers used.  */

  char need_regstk;		/* true if a .regstk directive needed.  */
  char initialized;		/* true if the data is finalized.  */
};

/* Current frame information calculated by ia64_compute_frame_size.  */
static struct ia64_frame_info current_frame_info;
/* The actual registers that are emitted.  */
static int emitted_frame_related_regs[number_of_ia64_frame_regs];

static int ia64_first_cycle_multipass_dfa_lookahead (void);
static void ia64_dependencies_evaluation_hook (rtx_insn *, rtx_insn *);
static void ia64_init_dfa_pre_cycle_insn (void);
static rtx ia64_dfa_pre_cycle_insn (void);
static int ia64_first_cycle_multipass_dfa_lookahead_guard (rtx_insn *, int);
static int ia64_dfa_new_cycle (FILE *, int, rtx_insn *, int, int, int *);
static void ia64_h_i_d_extended (void);
static void * ia64_alloc_sched_context (void);
static void ia64_init_sched_context (void *, bool);
static void ia64_set_sched_context (void *);
static void ia64_clear_sched_context (void *);
static void ia64_free_sched_context (void *);
static int ia64_mode_to_int (machine_mode);
static void ia64_set_sched_flags (spec_info_t);
static ds_t ia64_get_insn_spec_ds (rtx_insn *);
static ds_t ia64_get_insn_checked_ds (rtx_insn *);
static bool ia64_skip_rtx_p (const_rtx);
static int ia64_speculate_insn (rtx_insn *, ds_t, rtx *);
static bool ia64_needs_block_p (ds_t);
static rtx ia64_gen_spec_check (rtx_insn *, rtx_insn *, ds_t);
static int ia64_spec_check_p (rtx);
static int ia64_spec_check_src_p (rtx);
static rtx gen_tls_get_addr (void);
static rtx gen_thread_pointer (void);
static int find_gr_spill (enum ia64_frame_regs, int);
static int next_scratch_gr_reg (void);
static void mark_reg_gr_used_mask (rtx, void *);
static void ia64_compute_frame_size (HOST_WIDE_INT);
static void setup_spill_pointers (int, rtx, HOST_WIDE_INT);
static void finish_spill_pointers (void);
static rtx spill_restore_mem (rtx, HOST_WIDE_INT);
static void do_spill (rtx (*)(rtx, rtx, rtx), rtx, HOST_WIDE_INT, rtx);
static void do_restore (rtx (*)(rtx, rtx, rtx), rtx, HOST_WIDE_INT);
static rtx gen_movdi_x (rtx, rtx, rtx);
static rtx gen_fr_spill_x (rtx, rtx, rtx);
static rtx gen_fr_restore_x (rtx, rtx, rtx);

static void ia64_option_override (void);
static bool ia64_can_eliminate (const int, const int);
static machine_mode hfa_element_mode (const_tree, bool);
static void ia64_setup_incoming_varargs (cumulative_args_t,
					 const function_arg_info &,
					 int *, int);
static int ia64_arg_partial_bytes (cumulative_args_t,
				   const function_arg_info &);
static rtx ia64_function_arg (cumulative_args_t, const function_arg_info &);
static rtx ia64_function_incoming_arg (cumulative_args_t,
				       const function_arg_info &);
static void ia64_function_arg_advance (cumulative_args_t,
				       const function_arg_info &);
static pad_direction ia64_function_arg_padding (machine_mode, const_tree);
static unsigned int ia64_function_arg_boundary (machine_mode,
						const_tree);
static bool ia64_function_ok_for_sibcall (tree, tree);
static bool ia64_return_in_memory (const_tree, const_tree);
static rtx ia64_function_value (const_tree, const_tree, bool);
static rtx ia64_libcall_value (machine_mode, const_rtx);
static bool ia64_function_value_regno_p (const unsigned int);
static int ia64_register_move_cost (machine_mode, reg_class_t,
                                    reg_class_t);
static int ia64_memory_move_cost (machine_mode mode, reg_class_t,
				  bool);
static bool ia64_rtx_costs (rtx, machine_mode, int, int, int *, bool);
static int ia64_unspec_may_trap_p (const_rtx, unsigned);
static void fix_range (const char *);
static struct machine_function * ia64_init_machine_status (void);
static void emit_insn_group_barriers (FILE *);
static void emit_all_insn_group_barriers (FILE *);
static void final_emit_insn_group_barriers (FILE *);
static void emit_predicate_relation_info (void);
static void ia64_reorg (void);
static bool ia64_in_small_data_p (const_tree);
static void process_epilogue (FILE *, rtx, bool, bool);

static bool ia64_assemble_integer (rtx, unsigned int, int);
static void ia64_output_function_prologue (FILE *);
static void ia64_output_function_epilogue (FILE *);
static void ia64_output_function_end_prologue (FILE *);

static void ia64_print_operand (FILE *, rtx, int);
static void ia64_print_operand_address (FILE *, machine_mode, rtx);
static bool ia64_print_operand_punct_valid_p (unsigned char code);

static int ia64_issue_rate (void);
static int ia64_adjust_cost (rtx_insn *, int, rtx_insn *, int, dw_t);
static void ia64_sched_init (FILE *, int, int);
static void ia64_sched_init_global (FILE *, int, int);
static void ia64_sched_finish_global (FILE *, int);
static void ia64_sched_finish (FILE *, int);
static int ia64_dfa_sched_reorder (FILE *, int, rtx_insn **, int *, int, int);
static int ia64_sched_reorder (FILE *, int, rtx_insn **, int *, int);
static int ia64_sched_reorder2 (FILE *, int, rtx_insn **, int *, int);
static int ia64_variable_issue (FILE *, int, rtx_insn *, int);

static void ia64_asm_unwind_emit (FILE *, rtx_insn *);
static void ia64_asm_emit_except_personality (rtx);
static void ia64_asm_init_sections (void);

static enum unwind_info_type ia64_debug_unwind_info (void);

static struct bundle_state *get_free_bundle_state (void);
static void free_bundle_state (struct bundle_state *);
static void initiate_bundle_states (void);
static void finish_bundle_states (void);
static int insert_bundle_state (struct bundle_state *);
static void initiate_bundle_state_table (void);
static void finish_bundle_state_table (void);
static int try_issue_nops (struct bundle_state *, int);
static int try_issue_insn (struct bundle_state *, rtx);
static void issue_nops_and_insn (struct bundle_state *, int, rtx_insn *,
				 int, int);
static int get_max_pos (state_t);
static int get_template (state_t, int);

static rtx_insn *get_next_important_insn (rtx_insn *, rtx_insn *);
static bool important_for_bundling_p (rtx_insn *);
static bool unknown_for_bundling_p (rtx_insn *);
static void bundling (FILE *, int, rtx_insn *, rtx_insn *);

static void ia64_output_mi_thunk (FILE *, tree, HOST_WIDE_INT,
				  HOST_WIDE_INT, tree);
static void ia64_file_start (void);
static void ia64_globalize_decl_name (FILE *, tree);

static int ia64_hpux_reloc_rw_mask (void) ATTRIBUTE_UNUSED;
static int ia64_reloc_rw_mask (void) ATTRIBUTE_UNUSED;
static section *ia64_select_rtx_section (machine_mode, rtx,
					 unsigned HOST_WIDE_INT);
static void ia64_output_dwarf_dtprel (FILE *, int, rtx)
     ATTRIBUTE_UNUSED;
static unsigned int ia64_section_type_flags (tree, const char *, int);
static void ia64_init_libfuncs (void)
     ATTRIBUTE_UNUSED;
static void ia64_hpux_init_libfuncs (void)
     ATTRIBUTE_UNUSED;
static void ia64_sysv4_init_libfuncs (void)
     ATTRIBUTE_UNUSED;
static void ia64_vms_init_libfuncs (void)
     ATTRIBUTE_UNUSED;
static void ia64_soft_fp_init_libfuncs (void)
     ATTRIBUTE_UNUSED;
static bool ia64_vms_valid_pointer_mode (scalar_int_mode mode)
     ATTRIBUTE_UNUSED;
static tree ia64_vms_common_object_attribute (tree *, tree, tree, int, bool *)
     ATTRIBUTE_UNUSED;

static bool ia64_attribute_takes_identifier_p (const_tree);
static tree ia64_handle_model_attribute (tree *, tree, tree, int, bool *);
static tree ia64_handle_version_id_attribute (tree *, tree, tree, int, bool *);
static void ia64_encode_section_info (tree, rtx, int);
static rtx ia64_struct_value_rtx (tree, int);
static tree ia64_gimplify_va_arg (tree, tree, gimple_seq *, gimple_seq *);
static bool ia64_scalar_mode_supported_p (scalar_mode mode);
static bool ia64_vector_mode_supported_p (machine_mode mode);
static bool ia64_legitimate_constant_p (machine_mode, rtx);
static bool ia64_legitimate_address_p (machine_mode, rtx, bool);
static bool ia64_cannot_force_const_mem (machine_mode, rtx);
static const char *ia64_mangle_type (const_tree);
static const char *ia64_invalid_conversion (const_tree, const_tree);
static const char *ia64_invalid_unary_op (int, const_tree);
static const char *ia64_invalid_binary_op (int, const_tree, const_tree);
static machine_mode ia64_c_mode_for_suffix (char);
static void ia64_trampoline_init (rtx, tree, rtx);
static void ia64_override_options_after_change (void);
static bool ia64_member_type_forces_blk (const_tree, machine_mode);

static tree ia64_fold_builtin (tree, int, tree *, bool);
static tree ia64_builtin_decl (unsigned, bool);

static reg_class_t ia64_preferred_reload_class (rtx, reg_class_t);
static fixed_size_mode ia64_get_reg_raw_mode (int regno);
static section * ia64_hpux_function_section (tree, enum node_frequency,
					     bool, bool);

static bool ia64_vectorize_vec_perm_const (machine_mode, machine_mode, rtx,
					   rtx, rtx, const vec_perm_indices &);

static unsigned int ia64_hard_regno_nregs (unsigned int, machine_mode);
static bool ia64_hard_regno_mode_ok (unsigned int, machine_mode);
static bool ia64_modes_tieable_p (machine_mode, machine_mode);
static bool ia64_can_change_mode_class (machine_mode, machine_mode,
					reg_class_t);

#define MAX_VECT_LEN	8

struct expand_vec_perm_d
{
  rtx target, op0, op1;
  unsigned char perm[MAX_VECT_LEN];
  machine_mode vmode;
  unsigned char nelt;
  bool one_operand_p;
  bool testing_p; 
};

static bool ia64_expand_vec_perm_const_1 (struct expand_vec_perm_d *d);


/* Table of valid machine attributes.  */
static const struct attribute_spec ia64_attribute_table[] =
{
  /* { name, min_len, max_len, decl_req, type_req, fn_type_req,
       affects_type_identity, handler, exclude } */
  { "syscall_linkage", 0, 0, false, true,  true,  false, NULL, NULL },
  { "model",	       1, 1, true, false, false,  false,
    ia64_handle_model_attribute, NULL },
#if TARGET_ABI_OPEN_VMS
  { "common_object",   1, 1, true, false, false, false,
    ia64_vms_common_object_attribute, NULL },
#endif
  { "version_id",      1, 1, true, false, false, false,
    ia64_handle_version_id_attribute, NULL },
  { NULL,	       0, 0, false, false, false, false, NULL, NULL }
};

/* Initialize the GCC target structure.  */
#undef TARGET_ATTRIBUTE_TABLE
#define TARGET_ATTRIBUTE_TABLE ia64_attribute_table

#undef TARGET_INIT_BUILTINS
#define TARGET_INIT_BUILTINS ia64_init_builtins

#undef TARGET_FOLD_BUILTIN
#define TARGET_FOLD_BUILTIN ia64_fold_builtin

#undef TARGET_EXPAND_BUILTIN
#define TARGET_EXPAND_BUILTIN ia64_expand_builtin

#undef TARGET_BUILTIN_DECL
#define TARGET_BUILTIN_DECL ia64_builtin_decl

#undef TARGET_ASM_BYTE_OP
#define TARGET_ASM_BYTE_OP "\tdata1\t"
#undef TARGET_ASM_ALIGNED_HI_OP
#define TARGET_ASM_ALIGNED_HI_OP "\tdata2\t"
#undef TARGET_ASM_ALIGNED_SI_OP
#define TARGET_ASM_ALIGNED_SI_OP "\tdata4\t"
#undef TARGET_ASM_ALIGNED_DI_OP
#define TARGET_ASM_ALIGNED_DI_OP "\tdata8\t"
#undef TARGET_ASM_UNALIGNED_HI_OP
#define TARGET_ASM_UNALIGNED_HI_OP "\tdata2.ua\t"
#undef TARGET_ASM_UNALIGNED_SI_OP
#define TARGET_ASM_UNALIGNED_SI_OP "\tdata4.ua\t"
#undef TARGET_ASM_UNALIGNED_DI_OP
#define TARGET_ASM_UNALIGNED_DI_OP "\tdata8.ua\t"
#undef TARGET_ASM_INTEGER
#define TARGET_ASM_INTEGER ia64_assemble_integer

#undef TARGET_OPTION_OVERRIDE
#define TARGET_OPTION_OVERRIDE ia64_option_override

#undef TARGET_ASM_FUNCTION_PROLOGUE
#define TARGET_ASM_FUNCTION_PROLOGUE ia64_output_function_prologue
#undef TARGET_ASM_FUNCTION_END_PROLOGUE
#define TARGET_ASM_FUNCTION_END_PROLOGUE ia64_output_function_end_prologue
#undef TARGET_ASM_FUNCTION_EPILOGUE
#define TARGET_ASM_FUNCTION_EPILOGUE ia64_output_function_epilogue

#undef TARGET_PRINT_OPERAND
#define TARGET_PRINT_OPERAND ia64_print_operand
#undef TARGET_PRINT_OPERAND_ADDRESS
#define TARGET_PRINT_OPERAND_ADDRESS ia64_print_operand_address
#undef TARGET_PRINT_OPERAND_PUNCT_VALID_P
#define TARGET_PRINT_OPERAND_PUNCT_VALID_P ia64_print_operand_punct_valid_p

#undef TARGET_IN_SMALL_DATA_P
#define TARGET_IN_SMALL_DATA_P  ia64_in_small_data_p

#undef TARGET_SCHED_ADJUST_COST
#define TARGET_SCHED_ADJUST_COST ia64_adjust_cost
#undef TARGET_SCHED_ISSUE_RATE
#define TARGET_SCHED_ISSUE_RATE ia64_issue_rate
#undef TARGET_SCHED_VARIABLE_ISSUE
#define TARGET_SCHED_VARIABLE_ISSUE ia64_variable_issue
#undef TARGET_SCHED_INIT
#define TARGET_SCHED_INIT ia64_sched_init
#undef TARGET_SCHED_FINISH
#define TARGET_SCHED_FINISH ia64_sched_finish
#undef TARGET_SCHED_INIT_GLOBAL
#define TARGET_SCHED_INIT_GLOBAL ia64_sched_init_global
#undef TARGET_SCHED_FINISH_GLOBAL
#define TARGET_SCHED_FINISH_GLOBAL ia64_sched_finish_global
#undef TARGET_SCHED_REORDER
#define TARGET_SCHED_REORDER ia64_sched_reorder
#undef TARGET_SCHED_REORDER2
#define TARGET_SCHED_REORDER2 ia64_sched_reorder2

#undef TARGET_SCHED_DEPENDENCIES_EVALUATION_HOOK
#define TARGET_SCHED_DEPENDENCIES_EVALUATION_HOOK ia64_dependencies_evaluation_hook

#undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
#define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD ia64_first_cycle_multipass_dfa_lookahead

#undef TARGET_SCHED_INIT_DFA_PRE_CYCLE_INSN
#define TARGET_SCHED_INIT_DFA_PRE_CYCLE_INSN ia64_init_dfa_pre_cycle_insn
#undef TARGET_SCHED_DFA_PRE_CYCLE_INSN
#define TARGET_SCHED_DFA_PRE_CYCLE_INSN ia64_dfa_pre_cycle_insn

#undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD
#define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD\
  ia64_first_cycle_multipass_dfa_lookahead_guard

#undef TARGET_SCHED_DFA_NEW_CYCLE
#define TARGET_SCHED_DFA_NEW_CYCLE ia64_dfa_new_cycle

#undef TARGET_SCHED_H_I_D_EXTENDED
#define TARGET_SCHED_H_I_D_EXTENDED ia64_h_i_d_extended

#undef TARGET_SCHED_ALLOC_SCHED_CONTEXT
#define TARGET_SCHED_ALLOC_SCHED_CONTEXT ia64_alloc_sched_context

#undef TARGET_SCHED_INIT_SCHED_CONTEXT
#define TARGET_SCHED_INIT_SCHED_CONTEXT ia64_init_sched_context

#undef TARGET_SCHED_SET_SCHED_CONTEXT
#define TARGET_SCHED_SET_SCHED_CONTEXT ia64_set_sched_context

#undef TARGET_SCHED_CLEAR_SCHED_CONTEXT
#define TARGET_SCHED_CLEAR_SCHED_CONTEXT ia64_clear_sched_context

#undef TARGET_SCHED_FREE_SCHED_CONTEXT
#define TARGET_SCHED_FREE_SCHED_CONTEXT ia64_free_sched_context

#undef TARGET_SCHED_SET_SCHED_FLAGS
#define TARGET_SCHED_SET_SCHED_FLAGS ia64_set_sched_flags

#undef TARGET_SCHED_GET_INSN_SPEC_DS
#define TARGET_SCHED_GET_INSN_SPEC_DS ia64_get_insn_spec_ds

#undef TARGET_SCHED_GET_INSN_CHECKED_DS
#define TARGET_SCHED_GET_INSN_CHECKED_DS ia64_get_insn_checked_ds

#undef TARGET_SCHED_SPECULATE_INSN
#define TARGET_SCHED_SPECULATE_INSN ia64_speculate_insn

#undef TARGET_SCHED_NEEDS_BLOCK_P
#define TARGET_SCHED_NEEDS_BLOCK_P ia64_needs_block_p

#undef TARGET_SCHED_GEN_SPEC_CHECK
#define TARGET_SCHED_GEN_SPEC_CHECK ia64_gen_spec_check

#undef TARGET_SCHED_SKIP_RTX_P
#define TARGET_SCHED_SKIP_RTX_P ia64_skip_rtx_p

#undef TARGET_FUNCTION_OK_FOR_SIBCALL
#define TARGET_FUNCTION_OK_FOR_SIBCALL ia64_function_ok_for_sibcall
#undef TARGET_ARG_PARTIAL_BYTES
#define TARGET_ARG_PARTIAL_BYTES ia64_arg_partial_bytes
#undef TARGET_FUNCTION_ARG
#define TARGET_FUNCTION_ARG ia64_function_arg
#undef TARGET_FUNCTION_INCOMING_ARG
#define TARGET_FUNCTION_INCOMING_ARG ia64_function_incoming_arg
#undef TARGET_FUNCTION_ARG_ADVANCE
#define TARGET_FUNCTION_ARG_ADVANCE ia64_function_arg_advance
#undef TARGET_FUNCTION_ARG_PADDING
#define TARGET_FUNCTION_ARG_PADDING ia64_function_arg_padding
#undef TARGET_FUNCTION_ARG_BOUNDARY
#define TARGET_FUNCTION_ARG_BOUNDARY ia64_function_arg_boundary

#undef TARGET_ASM_OUTPUT_MI_THUNK
#define TARGET_ASM_OUTPUT_MI_THUNK ia64_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_START
#define TARGET_ASM_FILE_START ia64_file_start

#undef TARGET_ASM_GLOBALIZE_DECL_NAME
#define TARGET_ASM_GLOBALIZE_DECL_NAME ia64_globalize_decl_name

#undef TARGET_REGISTER_MOVE_COST
#define TARGET_REGISTER_MOVE_COST ia64_register_move_cost
#undef TARGET_MEMORY_MOVE_COST
#define TARGET_MEMORY_MOVE_COST ia64_memory_move_cost
#undef TARGET_RTX_COSTS
#define TARGET_RTX_COSTS ia64_rtx_costs
#undef TARGET_ADDRESS_COST
#define TARGET_ADDRESS_COST hook_int_rtx_mode_as_bool_0

#undef TARGET_UNSPEC_MAY_TRAP_P
#define TARGET_UNSPEC_MAY_TRAP_P ia64_unspec_may_trap_p

#undef TARGET_MACHINE_DEPENDENT_REORG
#define TARGET_MACHINE_DEPENDENT_REORG ia64_reorg

#undef TARGET_ENCODE_SECTION_INFO
#define TARGET_ENCODE_SECTION_INFO ia64_encode_section_info

#undef  TARGET_SECTION_TYPE_FLAGS
#define TARGET_SECTION_TYPE_FLAGS  ia64_section_type_flags

#ifdef HAVE_AS_TLS
#undef TARGET_ASM_OUTPUT_DWARF_DTPREL
#define TARGET_ASM_OUTPUT_DWARF_DTPREL ia64_output_dwarf_dtprel
#endif

/* ??? Investigate.  */
#if 0
#undef TARGET_PROMOTE_PROTOTYPES
#define TARGET_PROMOTE_PROTOTYPES hook_bool_tree_true
#endif

#undef TARGET_FUNCTION_VALUE
#define TARGET_FUNCTION_VALUE ia64_function_value
#undef TARGET_LIBCALL_VALUE
#define TARGET_LIBCALL_VALUE ia64_libcall_value
#undef TARGET_FUNCTION_VALUE_REGNO_P
#define TARGET_FUNCTION_VALUE_REGNO_P ia64_function_value_regno_p

#undef TARGET_STRUCT_VALUE_RTX
#define TARGET_STRUCT_VALUE_RTX ia64_struct_value_rtx
#undef TARGET_RETURN_IN_MEMORY
#define TARGET_RETURN_IN_MEMORY ia64_return_in_memory
#undef TARGET_SETUP_INCOMING_VARARGS
#define TARGET_SETUP_INCOMING_VARARGS ia64_setup_incoming_varargs
#undef TARGET_STRICT_ARGUMENT_NAMING
#define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
#undef TARGET_MUST_PASS_IN_STACK
#define TARGET_MUST_PASS_IN_STACK must_pass_in_stack_var_size
#undef TARGET_GET_RAW_RESULT_MODE
#define TARGET_GET_RAW_RESULT_MODE ia64_get_reg_raw_mode
#undef TARGET_GET_RAW_ARG_MODE
#define TARGET_GET_RAW_ARG_MODE ia64_get_reg_raw_mode

#undef TARGET_MEMBER_TYPE_FORCES_BLK
#define TARGET_MEMBER_TYPE_FORCES_BLK ia64_member_type_forces_blk

#undef TARGET_GIMPLIFY_VA_ARG_EXPR
#define TARGET_GIMPLIFY_VA_ARG_EXPR ia64_gimplify_va_arg

#undef TARGET_ASM_UNWIND_EMIT
#define TARGET_ASM_UNWIND_EMIT ia64_asm_unwind_emit
#undef TARGET_ASM_EMIT_EXCEPT_PERSONALITY
#define TARGET_ASM_EMIT_EXCEPT_PERSONALITY  ia64_asm_emit_except_personality
#undef TARGET_ASM_INIT_SECTIONS
#define TARGET_ASM_INIT_SECTIONS  ia64_asm_init_sections

#undef TARGET_DEBUG_UNWIND_INFO
#define TARGET_DEBUG_UNWIND_INFO  ia64_debug_unwind_info

#undef TARGET_SCALAR_MODE_SUPPORTED_P
#define TARGET_SCALAR_MODE_SUPPORTED_P ia64_scalar_mode_supported_p
#undef TARGET_VECTOR_MODE_SUPPORTED_P
#define TARGET_VECTOR_MODE_SUPPORTED_P ia64_vector_mode_supported_p

#undef TARGET_LEGITIMATE_CONSTANT_P
#define TARGET_LEGITIMATE_CONSTANT_P ia64_legitimate_constant_p
#undef TARGET_LEGITIMATE_ADDRESS_P
#define TARGET_LEGITIMATE_ADDRESS_P ia64_legitimate_address_p

#undef TARGET_LRA_P
#define TARGET_LRA_P hook_bool_void_false

#undef TARGET_CANNOT_FORCE_CONST_MEM
#define TARGET_CANNOT_FORCE_CONST_MEM ia64_cannot_force_const_mem

#undef TARGET_MANGLE_TYPE
#define TARGET_MANGLE_TYPE ia64_mangle_type

#undef TARGET_INVALID_CONVERSION
#define TARGET_INVALID_CONVERSION ia64_invalid_conversion
#undef TARGET_INVALID_UNARY_OP
#define TARGET_INVALID_UNARY_OP ia64_invalid_unary_op
#undef TARGET_INVALID_BINARY_OP
#define TARGET_INVALID_BINARY_OP ia64_invalid_binary_op

#undef TARGET_C_MODE_FOR_SUFFIX
#define TARGET_C_MODE_FOR_SUFFIX ia64_c_mode_for_suffix

#undef TARGET_CAN_ELIMINATE
#define TARGET_CAN_ELIMINATE ia64_can_eliminate

#undef TARGET_TRAMPOLINE_INIT
#define TARGET_TRAMPOLINE_INIT ia64_trampoline_init

#undef TARGET_CAN_USE_DOLOOP_P
#define TARGET_CAN_USE_DOLOOP_P can_use_doloop_if_innermost
#undef TARGET_INVALID_WITHIN_DOLOOP
#define TARGET_INVALID_WITHIN_DOLOOP hook_constcharptr_const_rtx_insn_null

#undef TARGET_OVERRIDE_OPTIONS_AFTER_CHANGE
#define TARGET_OVERRIDE_OPTIONS_AFTER_CHANGE ia64_override_options_after_change

#undef TARGET_PREFERRED_RELOAD_CLASS
#define TARGET_PREFERRED_RELOAD_CLASS ia64_preferred_reload_class

#undef TARGET_DELAY_SCHED2
#define TARGET_DELAY_SCHED2 true

/* Variable tracking should be run after all optimizations which
   change order of insns.  It also needs a valid CFG.  */
#undef TARGET_DELAY_VARTRACK
#define TARGET_DELAY_VARTRACK true

#undef TARGET_VECTORIZE_VEC_PERM_CONST
#define TARGET_VECTORIZE_VEC_PERM_CONST ia64_vectorize_vec_perm_const

#undef TARGET_ATTRIBUTE_TAKES_IDENTIFIER_P
#define TARGET_ATTRIBUTE_TAKES_IDENTIFIER_P ia64_attribute_takes_identifier_p

#undef TARGET_CUSTOM_FUNCTION_DESCRIPTORS
#define TARGET_CUSTOM_FUNCTION_DESCRIPTORS 0

#undef TARGET_HARD_REGNO_NREGS
#define TARGET_HARD_REGNO_NREGS ia64_hard_regno_nregs
#undef TARGET_HARD_REGNO_MODE_OK
#define TARGET_HARD_REGNO_MODE_OK ia64_hard_regno_mode_ok

#undef TARGET_MODES_TIEABLE_P
#define TARGET_MODES_TIEABLE_P ia64_modes_tieable_p

#undef TARGET_CAN_CHANGE_MODE_CLASS
#define TARGET_CAN_CHANGE_MODE_CLASS ia64_can_change_mode_class

#undef TARGET_CONSTANT_ALIGNMENT
#define TARGET_CONSTANT_ALIGNMENT constant_alignment_word_strings

struct gcc_target targetm = TARGET_INITIALIZER;

/* Returns TRUE iff the target attribute indicated by ATTR_ID takes a plain
   identifier as an argument, so the front end shouldn't look it up.  */

static bool
ia64_attribute_takes_identifier_p (const_tree attr_id)
{
  if (is_attribute_p ("model", attr_id))
    return true;
#if TARGET_ABI_OPEN_VMS
  if (is_attribute_p ("common_object", attr_id))
    return true;
#endif
  return false;
}

typedef enum
  {
    ADDR_AREA_NORMAL,	/* normal address area */
    ADDR_AREA_SMALL	/* addressable by "addl" (-2MB < addr < 2MB) */
  }
ia64_addr_area;

static GTY(()) tree small_ident1;
static GTY(()) tree small_ident2;

static void
init_idents (void)
{
  if (small_ident1 == 0)
    {
      small_ident1 = get_identifier ("small");
      small_ident2 = get_identifier ("__small__");
    }
}

/* Retrieve the address area that has been chosen for the given decl.  */

static ia64_addr_area
ia64_get_addr_area (tree decl)
{
  tree model_attr;

  model_attr = lookup_attribute ("model", DECL_ATTRIBUTES (decl));
  if (model_attr)
    {
      tree id;

      init_idents ();
      id = TREE_VALUE (TREE_VALUE (model_attr));
      if (id == small_ident1 || id == small_ident2)
	return ADDR_AREA_SMALL;
    }
  return ADDR_AREA_NORMAL;
}

static tree
ia64_handle_model_attribute (tree *node, tree name, tree args,
			     int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
{
  ia64_addr_area addr_area = ADDR_AREA_NORMAL;
  ia64_addr_area area;
  tree arg, decl = *node;

  init_idents ();
  arg = TREE_VALUE (args);
  if (arg == small_ident1 || arg == small_ident2)
    {
      addr_area = ADDR_AREA_SMALL;
    }
  else
    {
      warning (OPT_Wattributes, "invalid argument of %qE attribute",
	       name);
      *no_add_attrs = true;
    }

  switch (TREE_CODE (decl))
    {
    case VAR_DECL:
      if ((DECL_CONTEXT (decl) && TREE_CODE (DECL_CONTEXT (decl))
	   == FUNCTION_DECL)
	  && !TREE_STATIC (decl))
	{
	  error_at (DECL_SOURCE_LOCATION (decl),
		    "an address area attribute cannot be specified for "
		    "local variables");
	  *no_add_attrs = true;
	}
      area = ia64_get_addr_area (decl);
      if (area != ADDR_AREA_NORMAL && addr_area != area)
	{
	  error ("address area of %q+D conflicts with previous "
		 "declaration", decl);
	  *no_add_attrs = true;
	}
      break;

    case FUNCTION_DECL:
      error_at (DECL_SOURCE_LOCATION (decl),
		"address area attribute cannot be specified for "
		"functions");
      *no_add_attrs = true;
      break;

    default:
      warning (OPT_Wattributes, "%qE attribute ignored",
	       name);
      *no_add_attrs = true;
      break;
    }

  return NULL_TREE;
}

/* Part of the low level implementation of DEC Ada pragma Common_Object which
   enables the shared use of variables stored in overlaid linker areas
   corresponding to the use of Fortran COMMON.  */

static tree
ia64_vms_common_object_attribute (tree *node, tree name, tree args,
				  int flags ATTRIBUTE_UNUSED,
				  bool *no_add_attrs)
{
    tree decl = *node;
    tree id;

    gcc_assert (DECL_P (decl));
  
    DECL_COMMON (decl) = 1;
    id = TREE_VALUE (args);
    if (TREE_CODE (id) != IDENTIFIER_NODE && TREE_CODE (id) != STRING_CST)
      {
	error ("%qE attribute requires a string constant argument", name);
	*no_add_attrs = true;
	return NULL_TREE;
      }
    return NULL_TREE;
}

/* Part of the low level implementation of DEC Ada pragma Common_Object.  */

void
ia64_vms_output_aligned_decl_common (FILE *file, tree decl, const char *name,
				     unsigned HOST_WIDE_INT size,
				     unsigned int align)
{
  tree attr = DECL_ATTRIBUTES (decl);

  if (attr)
    attr = lookup_attribute ("common_object", attr);
  if (attr)
    {
      tree id = TREE_VALUE (TREE_VALUE (attr));
      const char *name;

      if (TREE_CODE (id) == IDENTIFIER_NODE)
        name = IDENTIFIER_POINTER (id);
      else if (TREE_CODE (id) == STRING_CST)
        name = TREE_STRING_POINTER (id);
      else
        abort ();

      fprintf (file, "\t.vms_common\t\"%s\",", name);
    }
  else
    fprintf (file, "%s", COMMON_ASM_OP);

  /*  Code from elfos.h.  */
  assemble_name (file, name);
  fprintf (file, "," HOST_WIDE_INT_PRINT_UNSIGNED",%u",
           size, align / BITS_PER_UNIT);

  fputc ('\n', file);
}

static void
ia64_encode_addr_area (tree decl, rtx symbol)
{
  int flags;

  flags = SYMBOL_REF_FLAGS (symbol);
  switch (ia64_get_addr_area (decl))
    {
    case ADDR_AREA_NORMAL: break;
    case ADDR_AREA_SMALL: flags |= SYMBOL_FLAG_SMALL_ADDR; break;
    default: gcc_unreachable ();
    }
  SYMBOL_REF_FLAGS (symbol) = flags;
}

static void
ia64_encode_section_info (tree decl, rtx rtl, int first)
{
  default_encode_section_info (decl, rtl, first);

  /* Careful not to prod global register variables.  */
  if (TREE_CODE (decl) == VAR_DECL
      && GET_CODE (DECL_RTL (decl)) == MEM
      && GET_CODE (XEXP (DECL_RTL (decl), 0)) == SYMBOL_REF
      && (TREE_STATIC (decl) || DECL_EXTERNAL (decl)))
    ia64_encode_addr_area (decl, XEXP (rtl, 0));
}

/* Return 1 if the operands of a move are ok.  */

int
ia64_move_ok (rtx dst, rtx src)
{
  /* If we're under init_recog_no_volatile, we'll not be able to use
     memory_operand.  So check the code directly and don't worry about
     the validity of the underlying address, which should have been
     checked elsewhere anyway.  */
  if (GET_CODE (dst) != MEM)
    return 1;
  if (GET_CODE (src) == MEM)
    return 0;
  if (register_operand (src, VOIDmode))
    return 1;

  /* Otherwise, this must be a constant, and that either 0 or 0.0 or 1.0.  */
  if (INTEGRAL_MODE_P (GET_MODE (dst)))
    return src == const0_rtx;
  else
    return satisfies_constraint_G (src);
}

/* Return 1 if the operands are ok for a floating point load pair.  */

int
ia64_load_pair_ok (rtx dst, rtx src)
{
  /* ??? There is a thinko in the implementation of the "x" constraint and the
     FP_REGS class.  The constraint will also reject (reg f30:TI) so we must
     also return false for it.  */
  if (GET_CODE (dst) != REG
      || !(FP_REGNO_P (REGNO (dst)) && FP_REGNO_P (REGNO (dst) + 1)))
    return 0;
  if (GET_CODE (src) != MEM || MEM_VOLATILE_P (src))
    return 0;
  switch (GET_CODE (XEXP (src, 0)))
    {
    case REG:
    case POST_INC:
      break;
    case POST_DEC:
      return 0;
    case POST_MODIFY:
      {
	rtx adjust = XEXP (XEXP (XEXP (src, 0), 1), 1);

	if (GET_CODE (adjust) != CONST_INT
	    || INTVAL (adjust) != GET_MODE_SIZE (GET_MODE (src)))
	  return 0;
      }
      break;
    default:
      abort ();
    }
  return 1;
}

int
addp4_optimize_ok (rtx op1, rtx op2)
{
  return (basereg_operand (op1, GET_MODE(op1)) !=
	  basereg_operand (op2, GET_MODE(op2)));
}

/* Check if OP is a mask suitable for use with SHIFT in a dep.z instruction.
   Return the length of the field, or <= 0 on failure.  */

int
ia64_depz_field_mask (rtx rop, rtx rshift)
{
  unsigned HOST_WIDE_INT op = INTVAL (rop);
  unsigned HOST_WIDE_INT shift = INTVAL (rshift);

  /* Get rid of the zero bits we're shifting in.  */
  op >>= shift;

  /* We must now have a solid block of 1's at bit 0.  */
  return exact_log2 (op + 1);
}

/* Return the TLS model to use for ADDR.  */

static enum tls_model
tls_symbolic_operand_type (rtx addr)
{
  enum tls_model tls_kind = TLS_MODEL_NONE;

  if (GET_CODE (addr) == CONST)
    {
      if (GET_CODE (XEXP (addr, 0)) == PLUS
	  && GET_CODE (XEXP (XEXP (addr, 0), 0)) == SYMBOL_REF)
        tls_kind = SYMBOL_REF_TLS_MODEL (XEXP (XEXP (addr, 0), 0));
    }
  else if (GET_CODE (addr) == SYMBOL_REF)
    tls_kind = SYMBOL_REF_TLS_MODEL (addr);

  return tls_kind;
}

/* Returns true if REG (assumed to be a `reg' RTX) is valid for use
   as a base register.  */

static inline bool
ia64_reg_ok_for_base_p (const_rtx reg, bool strict)
{
  if (strict
      && REGNO_OK_FOR_BASE_P (REGNO (reg)))
    return true;
  else if (!strict
	   && (GENERAL_REGNO_P (REGNO (reg))
	       || !HARD_REGISTER_P (reg)))
    return true;
  else
    return false;
}

static bool
ia64_legitimate_address_reg (const_rtx reg, bool strict)
{
  if ((REG_P (reg) && ia64_reg_ok_for_base_p (reg, strict))
      || (GET_CODE (reg) == SUBREG && REG_P (XEXP (reg, 0))
	  && ia64_reg_ok_for_base_p (XEXP (reg, 0), strict)))
    return true;

  return false;
}

static bool
ia64_legitimate_address_disp (const_rtx reg, const_rtx disp, bool strict)
{
  if (GET_CODE (disp) == PLUS
      && rtx_equal_p (reg, XEXP (disp, 0))
      && (ia64_legitimate_address_reg (XEXP (disp, 1), strict)
	  || (CONST_INT_P (XEXP (disp, 1))
	      && IN_RANGE (INTVAL (XEXP (disp, 1)), -256, 255))))
    return true;

  return false;
}

/* Implement TARGET_LEGITIMATE_ADDRESS_P.  */

static bool
ia64_legitimate_address_p (machine_mode mode ATTRIBUTE_UNUSED,
			   rtx x, bool strict)
{
  if (ia64_legitimate_address_reg (x, strict))
    return true;
  else if ((GET_CODE (x) == POST_INC || GET_CODE (x) == POST_DEC)
	   && ia64_legitimate_address_reg (XEXP (x, 0), strict)
	   && XEXP (x, 0) != arg_pointer_rtx) 
    return true;
  else if (GET_CODE (x) == POST_MODIFY
	   && ia64_legitimate_address_reg (XEXP (x, 0), strict)
	   && XEXP (x, 0) != arg_pointer_rtx
	   && ia64_legitimate_address_disp (XEXP (x, 0), XEXP (x, 1), strict))
    return true;
  else
    return false;
}

/* Return true if X is a constant that is valid for some immediate
   field in an instruction.  */

static bool
ia64_legitimate_constant_p (machine_mode mode, rtx x)
{
  switch (GET_CODE (x))
    {
    case CONST_INT:
    case LABEL_REF:
      return true;

    case CONST_DOUBLE:
      if (GET_MODE (x) == VOIDmode || mode == SFmode || mode == DFmode)
	return true;
      return satisfies_constraint_G (x);

    case CONST:
    case SYMBOL_REF:
      /* ??? Short term workaround for PR 28490.  We must make the code here
	 match the code in ia64_expand_move and move_operand, even though they
	 are both technically wrong.  */
      if (tls_symbolic_operand_type (x) == 0)
	{
	  HOST_WIDE_INT addend = 0;
	  rtx op = x;

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

          if (any_offset_symbol_operand (op, mode)
              || function_operand (op, mode))
            return true;
	  if (aligned_offset_symbol_operand (op, mode))
	    return (addend & 0x3fff) == 0;
	  return false;
	}
      return false;

    case CONST_VECTOR:
      if (mode == V2SFmode)
	return satisfies_constraint_Y (x);

      return (GET_MODE_CLASS (mode) == MODE_VECTOR_INT
	      && GET_MODE_SIZE (mode) <= 8);

    default:
      return false;
    }
}

/* Don't allow TLS addresses to get spilled to memory.  */

static bool
ia64_cannot_force_const_mem (machine_mode mode, rtx x)
{
  if (mode == RFmode)
    return true;
  return tls_symbolic_operand_type (x) != 0;
}

/* Expand a symbolic constant load.  */

bool
ia64_expand_load_address (rtx dest, rtx src)
{
  gcc_assert (GET_CODE (dest) == REG);

  /* ILP32 mode still loads 64-bits of data from the GOT.  This avoids
     having to pointer-extend the value afterward.  Other forms of address
     computation below are also more natural to compute as 64-bit quantities.
     If we've been given an SImode destination register, change it.  */
  if (GET_MODE (dest) != Pmode)
    dest = gen_rtx_REG_offset (dest, Pmode, REGNO (dest),
			       byte_lowpart_offset (Pmode, GET_MODE (dest)));

  if (TARGET_NO_PIC)
    return false;
  if (small_addr_symbolic_operand (src, VOIDmode))
    return false;

  if (TARGET_AUTO_PIC)
    emit_insn (gen_load_gprel64 (dest, src));
  else if (GET_CODE (src) == SYMBOL_REF && SYMBOL_REF_FUNCTION_P (src))
    emit_insn (gen_load_fptr (dest, src));
  else if (sdata_symbolic_operand (src, VOIDmode))
    emit_insn (gen_load_gprel (dest, src));
  else if (local_symbolic_operand64 (src, VOIDmode))
    {
      /* We want to use @gprel rather than @ltoff relocations for local
	 symbols:
	  - @gprel does not require dynamic linker
	  - and does not use .sdata section
	 https://gcc.gnu.org/bugzilla/60465 */
      emit_insn (gen_load_gprel64 (dest, src));
    }
  else
    {
      HOST_WIDE_INT addend = 0;
      rtx tmp;

      /* We did split constant offsets in ia64_expand_move, and we did try
	 to keep them split in move_operand, but we also allowed reload to
	 rematerialize arbitrary constants rather than spill the value to
	 the stack and reload it.  So we have to be prepared here to split
	 them apart again.  */
      if (GET_CODE (src) == CONST)
	{
	  HOST_WIDE_INT hi, lo;

	  hi = INTVAL (XEXP (XEXP (src, 0), 1));
	  lo = ((hi & 0x3fff) ^ 0x2000) - 0x2000;
	  hi = hi - lo;

	  if (lo != 0)
	    {
	      addend = lo;
	      src = plus_constant (Pmode, XEXP (XEXP (src, 0), 0), hi);
	    }
	}

      tmp = gen_rtx_HIGH (Pmode, src);
      tmp = gen_rtx_PLUS (Pmode, tmp, pic_offset_table_rtx);
      emit_insn (gen_rtx_SET (dest, tmp));

      tmp = gen_rtx_LO_SUM (Pmode, gen_const_mem (Pmode, dest), src);
      emit_insn (gen_rtx_SET (dest, tmp));

      if (addend)
	{
	  tmp = gen_rtx_PLUS (Pmode, dest, GEN_INT (addend));
	  emit_insn (gen_rtx_SET (dest, tmp));
	}
    }

  return true;
}

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 GTY(()) rtx thread_pointer_rtx;
static rtx
gen_thread_pointer (void)
{
  if (!thread_pointer_rtx)
    thread_pointer_rtx = gen_rtx_REG (Pmode, 13);
  return thread_pointer_rtx;
}

static rtx
ia64_expand_tls_address (enum tls_model tls_kind, rtx op0, rtx op1,
			 rtx orig_op1, HOST_WIDE_INT addend)
{
  rtx tga_op1, tga_op2, tga_ret, tga_eqv, tmp;
  rtx_insn *insns;
  rtx orig_op0 = op0;
  HOST_WIDE_INT addend_lo, addend_hi;

  switch (tls_kind)
    {
    case TLS_MODEL_GLOBAL_DYNAMIC:
      start_sequence ();

      tga_op1 = gen_reg_rtx (Pmode);
      emit_insn (gen_load_dtpmod (tga_op1, op1));

      tga_op2 = gen_reg_rtx (Pmode);
      emit_insn (gen_load_dtprel (tga_op2, op1));

      tga_ret = emit_library_call_value (gen_tls_get_addr (), NULL_RTX,
					 LCT_CONST, Pmode,
					 tga_op1, Pmode, tga_op2, Pmode);

      insns = get_insns ();
      end_sequence ();

      if (GET_MODE (op0) != Pmode)
	op0 = tga_ret;
      emit_libcall_block (insns, op0, tga_ret, op1);
      break;

    case TLS_MODEL_LOCAL_DYNAMIC:
      /* ??? This isn't the completely proper way to do local-dynamic
	 If the call to __tls_get_addr is used only by a single symbol,
	 then we should (somehow) move the dtprel to the second arg
	 to avoid the extra add.  */
      start_sequence ();

      tga_op1 = gen_reg_rtx (Pmode);
      emit_insn (gen_load_dtpmod (tga_op1, op1));

      tga_op2 = const0_rtx;

      tga_ret = emit_library_call_value (gen_tls_get_addr (), NULL_RTX,
					 LCT_CONST, Pmode,
					 tga_op1, Pmode, tga_op2, Pmode);

      insns = get_insns ();
      end_sequence ();

      tga_eqv = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
				UNSPEC_LD_BASE);
      tmp = gen_reg_rtx (Pmode);
      emit_libcall_block (insns, tmp, tga_ret, tga_eqv);

      if (!register_operand (op0, Pmode))
	op0 = gen_reg_rtx (Pmode);
      if (TARGET_TLS64)
	{
	  emit_insn (gen_load_dtprel (op0, op1));
	  emit_insn (gen_adddi3 (op0, tmp, op0));
	}
      else
	emit_insn (gen_add_dtprel (op0, op1, tmp));
      break;

    case TLS_MODEL_INITIAL_EXEC:
      addend_lo = ((addend & 0x3fff) ^ 0x2000) - 0x2000;
      addend_hi = addend - addend_lo;

      op1 = plus_constant (Pmode, op1, addend_hi);
      addend = addend_lo;

      tmp = gen_reg_rtx (Pmode);
      emit_insn (gen_load_tprel (tmp, op1));

      if (!register_operand (op0, Pmode))
	op0 = gen_reg_rtx (Pmode);
      emit_insn (gen_adddi3 (op0, tmp, gen_thread_pointer ()));
      break;

    case TLS_MODEL_LOCAL_EXEC:
      if (!register_operand (op0, Pmode))
	op0 = gen_reg_rtx (Pmode);

      op1 = orig_op1;
      addend = 0;
      if (TARGET_TLS64)
	{
	  emit_insn (gen_load_tprel (op0, op1));
	  emit_insn (gen_adddi3 (op0, op0, gen_thread_pointer ()));
	}
      else
	emit_insn (gen_add_tprel (op0, op1, gen_thread_pointer ()));
      break;

    default:
      gcc_unreachable ();
    }

  if (addend)
    op0 = expand_simple_binop (Pmode, PLUS, op0, GEN_INT (addend),
			       orig_op0, 1, OPTAB_DIRECT);
  if (orig_op0 == op0)
    return NULL_RTX;
  if (GET_MODE (orig_op0) == Pmode)
    return op0;
  return gen_lowpart (GET_MODE (orig_op0), op0);
}

rtx
ia64_expand_move (rtx op0, rtx op1)
{
  machine_mode mode = GET_MODE (op0);

  if (!reload_in_progress && !reload_completed && !ia64_move_ok (op0, op1))
    op1 = force_reg (mode, op1);

  if ((mode == Pmode || mode == ptr_mode) && symbolic_operand (op1, VOIDmode))
    {
      HOST_WIDE_INT addend = 0;
      enum tls_model tls_kind;
      rtx sym = op1;

      if (GET_CODE (op1) == CONST
	  && GET_CODE (XEXP (op1, 0)) == PLUS
	  && GET_CODE (XEXP (XEXP (op1, 0), 1)) == CONST_INT)
	{
	  addend = INTVAL (XEXP (XEXP (op1, 0), 1));
	  sym = XEXP (XEXP (op1, 0), 0);
	}

      tls_kind = tls_symbolic_operand_type (sym);
      if (tls_kind)
	return ia64_expand_tls_address (tls_kind, op0, sym, op1, addend);

      if (any_offset_symbol_operand (sym, mode))
	addend = 0;
      else if (aligned_offset_symbol_operand (sym, mode))
	{
	  HOST_WIDE_INT addend_lo, addend_hi;
	      
	  addend_lo = ((addend & 0x3fff) ^ 0x2000) - 0x2000;
	  addend_hi = addend - addend_lo;

	  if (addend_lo != 0)
	    {
	      op1 = plus_constant (mode, sym, addend_hi);
	      addend = addend_lo;
	    }
	  else
	    addend = 0;
	}
      else
	op1 = sym;

      if (reload_completed)
	{
	  /* We really should have taken care of this offset earlier.  */
	  gcc_assert (addend == 0);
	  if (ia64_expand_load_address (op0, op1))
	    return NULL_RTX;
	}

      if (addend)
	{
	  rtx subtarget = !can_create_pseudo_p () ? op0 : gen_reg_rtx (mode);

	  emit_insn (gen_rtx_SET (subtarget, op1));

	  op1 = expand_simple_binop (mode, PLUS, subtarget,
				     GEN_INT (addend), op0, 1, OPTAB_DIRECT);
	  if (op0 == op1)
	    return NULL_RTX;
	}
    }

  return op1;
}

/* Split a move from OP1 to OP0 conditional on COND.  */

void
ia64_emit_cond_move (rtx op0, rtx op1, rtx cond)
{
  rtx_insn *insn, *first = get_last_insn ();

  emit_move_insn (op0, op1);

  for (insn = get_last_insn (); insn != first; insn = PREV_INSN (insn))
    if (INSN_P (insn))
      PATTERN (insn) = gen_rtx_COND_EXEC (VOIDmode, copy_rtx (cond),
					  PATTERN (insn));
}

/* Split a post-reload TImode or TFmode reference into two DImode
   components.  This is made extra difficult by the fact that we do
   not get any scratch registers to work with, because reload cannot
   be prevented from giving us a scratch that overlaps the register
   pair involved.  So instead, when addressing memory, we tweak the
   pointer register up and back down with POST_INCs.  Or up and not
   back down when we can get away with it.

   REVERSED is true when the loads must be done in reversed order
   (high word first) for correctness.  DEAD is true when the pointer
   dies with the second insn we generate and therefore the second
   address must not carry a postmodify.

   May return an insn which is to be emitted after the moves.  */

static rtx
ia64_split_tmode (rtx out[2], rtx in, bool reversed, bool dead)
{
  rtx fixup = 0;

  switch (GET_CODE (in))
    {
    case REG:
      out[reversed] = gen_rtx_REG (DImode, REGNO (in));
      out[!reversed] = gen_rtx_REG (DImode, REGNO (in) + 1);
      break;

    case CONST_INT:
    case CONST_DOUBLE:
      /* Cannot occur reversed.  */
      gcc_assert (!reversed);
      
      if (GET_MODE (in) != TFmode)
	split_double (in, &out[0], &out[1]);
      else
	/* split_double does not understand how to split a TFmode
	   quantity into a pair of DImode constants.  */
	{
	  unsigned HOST_WIDE_INT p[2];
	  long l[4];  /* TFmode is 128 bits */

	  real_to_target (l, CONST_DOUBLE_REAL_VALUE (in), TFmode);

	  if (FLOAT_WORDS_BIG_ENDIAN)
	    {
	      p[0] = (((unsigned HOST_WIDE_INT) l[0]) << 32) + l[1];
	      p[1] = (((unsigned HOST_WIDE_INT) l[2]) << 32) + l[3];
	    }
	  else
	    {
	      p[0] = (((unsigned HOST_WIDE_INT) l[1]) << 32) + l[0];
	      p[1] = (((unsigned HOST_WIDE_INT) l[3]) << 32) + l[2];
	    }
	  out[0] = GEN_INT (p[0]);
	  out[1] = GEN_INT (p[1]);
	}
      break;

    case MEM:
      {
	rtx base = XEXP (in, 0);
	rtx offset;

	switch (GET_CODE (base))
	  {
	  case REG:
	    if (!reversed)
	      {
		out[0] = adjust_automodify_address
		  (in, DImode, gen_rtx_POST_INC (Pmode, base), 0);
		out[1] = adjust_automodify_address
		  (in, DImode, dead ? 0 : gen_rtx_POST_DEC (Pmode, base), 8);
	      }
	    else
	      {
		/* Reversal requires a pre-increment, which can only
		   be done as a separate insn.  */
		emit_insn (gen_adddi3 (base, base, GEN_INT (8)));
		out[0] = adjust_automodify_address
		  (in, DImode, gen_rtx_POST_DEC (Pmode, base), 8);
		out[1] = adjust_address (in, DImode, 0);
	      }
	    break;

	  case POST_INC:
	    gcc_assert (!reversed && !dead);
	    
	    /* Just do the increment in two steps.  */
	    out[0] = adjust_automodify_address (in, DImode, 0, 0);
	    out[1] = adjust_automodify_address (in, DImode, 0, 8);
	    break;

	  case POST_DEC:
	    gcc_assert (!reversed && !dead);
	    
	    /* Add 8, subtract 24.  */
	    base = XEXP (base, 0);
	    out[0] = adjust_automodify_address
	      (in, DImode, gen_rtx_POST_INC (Pmode, base), 0);
	    out[1] = adjust_automodify_address
	      (in, DImode,
	       gen_rtx_POST_MODIFY (Pmode, base,
				    plus_constant (Pmode, base, -24)),
	       8);
	    break;

	  case POST_MODIFY:
	    gcc_assert (!reversed && !dead);

	    /* Extract and adjust the modification.  This case is
	       trickier than the others, because we might have an
	       index register, or we might have a combined offset that
	       doesn't fit a signed 9-bit displacement field.  We can
	       assume the incoming expression is already legitimate.  */
	    offset = XEXP (base, 1);
	    base = XEXP (base, 0);

	    out[0] = adjust_automodify_address
	      (in, DImode, gen_rtx_POST_INC (Pmode, base), 0);

	    if (GET_CODE (XEXP (offset, 1)) == REG)
	      {
		/* Can't adjust the postmodify to match.  Emit the
		   original, then a separate addition insn.  */
		out[1] = adjust_automodify_address (in, DImode, 0, 8);
		fixup = gen_adddi3 (base, base, GEN_INT (-8));
	      }
	    else
	      {
		gcc_assert (GET_CODE (XEXP (offset, 1)) == CONST_INT);
		if (INTVAL (XEXP (offset, 1)) < -256 + 8)
		  {
		    /* Again the postmodify cannot be made to match,
		       but in this case it's more efficient to get rid
		       of the postmodify entirely and fix up with an
		       add insn.  */
		    out[1] = adjust_automodify_address (in, DImode, base, 8);
		    fixup = gen_adddi3
		      (base, base, GEN_INT (INTVAL (XEXP (offset, 1)) - 8));
		  }
		else
		  {
		    /* Combined offset still fits in the displacement field.
		       (We cannot overflow it at the high end.)  */
		    out[1] = adjust_automodify_address
		      (in, DImode, gen_rtx_POST_MODIFY
		       (Pmode, base, gen_rtx_PLUS
			(Pmode, base,
			 GEN_INT (INTVAL (XEXP (offset, 1)) - 8))),
		       8);
		  }
	      }
	    break;

	  default:
	    gcc_unreachable ();
	  }
	break;
      }

    default:
      gcc_unreachable ();
    }

  return fixup;
}

/* Split a TImode or TFmode move instruction after reload.
   This is used by *movtf_internal and *movti_internal.  */
void
ia64_split_tmode_move (rtx operands[])
{
  rtx in[2], out[2], insn;
  rtx fixup[2];
  bool dead = false;
  bool reversed = false;

  /* It is possible for reload to decide to overwrite a pointer with
     the value it points to.  In that case we have to do the loads in
     the appropriate order so that the pointer is not destroyed too
     early.  Also we must not generate a postmodify for that second
     load, or rws_access_regno will die.  And we must not generate a
     postmodify for the second load if the destination register 
     overlaps with the base register.  */
  if (GET_CODE (operands[1]) == MEM
      && reg_overlap_mentioned_p (operands[0], operands[1]))
    {
      rtx base = XEXP (operands[1], 0);
      while (GET_CODE (base) != REG)
	base = XEXP (base, 0);

      if (REGNO (base) == REGNO (operands[0]))
	reversed = true;

      if (refers_to_regno_p (REGNO (operands[0]),
			     REGNO (operands[0])+2,
			     base, 0))
	dead = true;
    }
  /* Another reason to do the moves in reversed order is if the first
     element of the target register pair is also the second element of
     the source register pair.  */
  if (GET_CODE (operands[0]) == REG && GET_CODE (operands[1]) == REG
      && REGNO (operands[0]) == REGNO (operands[1]) + 1)
    reversed = true;

  fixup[0] = ia64_split_tmode (in, operands[1], reversed, dead);
  fixup[1] = ia64_split_tmode (out, operands[0], reversed, dead);

#define MAYBE_ADD_REG_INC_NOTE(INSN, EXP)				\
  if (GET_CODE (EXP) == MEM						\
      && (GET_CODE (XEXP (EXP, 0)) == POST_MODIFY			\
	  || GET_CODE (XEXP (EXP, 0)) == POST_INC			\
	  || GET_CODE (XEXP (EXP, 0)) == POST_DEC))			\
    add_reg_note (insn, REG_INC, XEXP (XEXP (EXP, 0), 0))

  insn = emit_insn (gen_rtx_SET (out[0], in[0]));
  MAYBE_ADD_REG_INC_NOTE (insn, in[0]);
  MAYBE_ADD_REG_INC_NOTE (insn, out[0]);

  insn = emit_insn (gen_rtx_SET (out[1], in[1]));
  MAYBE_ADD_REG_INC_NOTE (insn, in[1]);
  MAYBE_ADD_REG_INC_NOTE (insn, out[1]);

  if (fixup[0])
    emit_insn (fixup[0]);
  if (fixup[1])
    emit_insn (fixup[1]);

#undef MAYBE_ADD_REG_INC_NOTE
}

/* ??? Fixing GR->FR XFmode moves during reload is hard.  You need to go
   through memory plus an extra GR scratch register.  Except that you can
   either get the first from TARGET_SECONDARY_MEMORY_NEEDED or the second
   from SECONDARY_RELOAD_CLASS, but not both.

   We got into problems in the first place by allowing a construct like
   (subreg:XF (reg:TI)), which we got from a union containing a long double.
   This solution attempts to prevent this situation from occurring.  When
   we see something like the above, we spill the inner register to memory.  */

static rtx
spill_xfmode_rfmode_operand (rtx in, int force, machine_mode mode)
{
  if (GET_CODE (in) == SUBREG
      && GET_MODE (SUBREG_REG (in)) == TImode
      && GET_CODE (SUBREG_REG (in)) == REG)
    {
      rtx memt = assign_stack_temp (TImode, 16);
      emit_move_insn (memt, SUBREG_REG (in));
      return adjust_address (memt, mode, 0);
    }
  else if (force && GET_CODE (in) == REG)
    {
      rtx memx = assign_stack_temp (mode, 16);
      emit_move_insn (memx, in);
      return memx;
    }
  else
    return in;
}

/* Expand the movxf or movrf pattern (MODE says which) with the given
   OPERANDS, returning true if the pattern should then invoke
   DONE.  */

bool
ia64_expand_movxf_movrf (machine_mode mode, rtx operands[])
{
  rtx op0 = operands[0];

  if (GET_CODE (op0) == SUBREG)
    op0 = SUBREG_REG (op0);

  /* We must support XFmode loads into general registers for stdarg/vararg,
     unprototyped calls, and a rare case where a long double is passed as
     an argument after a float HFA fills the FP registers.  We split them into
     DImode loads for convenience.  We also need to support XFmode stores
     for the last case.  This case does not happen for stdarg/vararg routines,
     because we do a block store to memory of unnamed arguments.  */

  if (GET_CODE (op0) == REG && GR_REGNO_P (REGNO (op0)))
    {
      rtx out[2];

      /* We're hoping to transform everything that deals with XFmode
	 quantities and GR registers early in the compiler.  */
      gcc_assert (can_create_pseudo_p ());

      /* Struct to register can just use TImode instead.  */
      if ((GET_CODE (operands[1]) == SUBREG
	   && GET_MODE (SUBREG_REG (operands[1])) == TImode)
	  || (GET_CODE (operands[1]) == REG
	      && GR_REGNO_P (REGNO (operands[1]))))
	{
	  rtx op1 = operands[1];

	  if (GET_CODE (op1) == SUBREG)
	    op1 = SUBREG_REG (op1);
	  else
	    op1 = gen_rtx_REG (TImode, REGNO (op1));

	  emit_move_insn (gen_rtx_REG (TImode, REGNO (op0)), op1);
	  return true;
	}

      if (GET_CODE (operands[1]) == CONST_DOUBLE)
	{
	  /* Don't word-swap when reading in the constant.  */
	  emit_move_insn (gen_rtx_REG (DImode, REGNO (op0)),
			  operand_subword (operands[1], WORDS_BIG_ENDIAN,
					   0, mode));
	  emit_move_insn (gen_rtx_REG (DImode, REGNO (op0) + 1),
			  operand_subword (operands[1], !WORDS_BIG_ENDIAN,
					   0, mode));
	  return true;
	}

      /* If the quantity is in a register not known to be GR, spill it.  */
      if (register_operand (operands[1], mode))
	operands[1] = spill_xfmode_rfmode_operand (operands[1], 1, mode);

      gcc_assert (GET_CODE (operands[1]) == MEM);

      /* Don't word-swap when reading in the value.  */
      out[0] = gen_rtx_REG (DImode, REGNO (op0));
      out[1] = gen_rtx_REG (DImode, REGNO (op0) + 1);

      emit_move_insn (out[0], adjust_address (operands[1], DImode, 0));
      emit_move_insn (out[1], adjust_address (operands[1], DImode, 8));
      return true;
    }

  if (GET_CODE (operands[1]) == REG && GR_REGNO_P (REGNO (operands[1])))
    {
      /* We're hoping to transform everything that deals with XFmode
	 quantities and GR registers early in the compiler.  */
      gcc_assert (can_create_pseudo_p ());

      /* Op0 can't be a GR_REG here, as that case is handled above.
	 If op0 is a register, then we spill op1, so that we now have a
	 MEM operand.  This requires creating an XFmode subreg of a TImode reg
	 to force the spill.  */
      if (register_operand (operands[0], mode))
	{
	  rtx op1 = gen_rtx_REG (TImode, REGNO (operands[1]));
	  op1 = gen_rtx_SUBREG (mode, op1, 0);
	  operands[1] = spill_xfmode_rfmode_operand (op1, 0, mode);
	}

      else
	{
	  rtx in[2];

	  gcc_assert (GET_CODE (operands[0]) == MEM);

	  /* Don't word-swap when writing out the value.  */
	  in[0] = gen_rtx_REG (DImode, REGNO (operands[1]));
	  in[1] = gen_rtx_REG (DImode, REGNO (operands[1]) + 1);

	  emit_move_insn (adjust_address (operands[0], DImode, 0), in[0]);
	  emit_move_insn (adjust_address (operands[0], DImode, 8), in[1]);
	  return true;
	}
    }

  if (!reload_in_progress && !reload_completed)
    {
      operands[1] = spill_xfmode_rfmode_operand (operands[1], 0, mode);

      if (GET_MODE (op0) == TImode && GET_CODE (op0) == REG)
	{
	  rtx memt, memx, in = operands[1];
	  if (CONSTANT_P (in))
	    in = validize_mem (force_const_mem (mode, in));
	  if (GET_CODE (in) == MEM)
	    memt = adjust_address (in, TImode, 0);
	  else
	    {
	      memt = assign_stack_temp (TImode, 16);
	      memx = adjust_address (memt, mode, 0);
	      emit_move_insn (memx, in);
	    }
	  emit_move_insn (op0, memt);
	  return true;
	}

      if (!ia64_move_ok (operands[0], operands[1]))
	operands[1] = force_reg (mode, operands[1]);
    }

  return false;
}

/* Emit comparison instruction if necessary, replacing *EXPR, *OP0, *OP1
   with the expression that holds the compare result (in VOIDmode).  */

static GTY(()) rtx cmptf_libfunc;

void
ia64_expand_compare (rtx *expr, rtx *op0, rtx *op1)
{
  enum rtx_code code = GET_CODE (*expr);
  rtx cmp;

  /* If we have a BImode input, then we already have a compare result, and
     do not need to emit another comparison.  */
  if (GET_MODE (*op0) == BImode)
    {
      gcc_assert ((code == NE || code == EQ) && *op1 == const0_rtx);
      cmp = *op0;
    }
  /* HPUX TFmode compare requires a library call to _U_Qfcmp, which takes a
     magic number as its third argument, that indicates what to do.
     The return value is an integer to be compared against zero.  */
  else if (TARGET_HPUX && GET_MODE (*op0) == TFmode)
    {
      enum qfcmp_magic {
	QCMP_INV = 1,	/* Raise FP_INVALID on NaNs as a side effect.  */
	QCMP_UNORD = 2,
	QCMP_EQ = 4,
	QCMP_LT = 8,
	QCMP_GT = 16
      };
      int magic;
      enum rtx_code ncode;
      rtx ret;
      
      gcc_assert (cmptf_libfunc && GET_MODE (*op1) == TFmode);
      switch (code)
	{
	  /* 1 = equal, 0 = not equal.  Equality operators do
	     not raise FP_INVALID when given a NaN operand.  */
	case EQ:        magic = QCMP_EQ;                  ncode = NE; break;
	case NE:        magic = QCMP_EQ;                  ncode = EQ; break;
	  /* isunordered() from C99.  */
	case UNORDERED: magic = QCMP_UNORD;               ncode = NE; break;
	case ORDERED:   magic = QCMP_UNORD;               ncode = EQ; break;
	  /* Relational operators raise FP_INVALID when given
	     a NaN operand.  */
	case LT:        magic = QCMP_LT        |QCMP_INV; ncode = NE; break;
	case LE:        magic = QCMP_LT|QCMP_EQ|QCMP_INV; ncode = NE; break;
	case GT:        magic = QCMP_GT        |QCMP_INV; ncode = NE; break;
	case GE:        magic = QCMP_GT|QCMP_EQ|QCMP_INV; ncode = NE; break;
          /* Unordered relational operators do not raise FP_INVALID
	     when given a NaN operand.  */
	case UNLT:    magic = QCMP_LT        |QCMP_UNORD; ncode = NE; break;
	case UNLE:    magic = QCMP_LT|QCMP_EQ|QCMP_UNORD; ncode = NE; break;
	case UNGT:    magic = QCMP_GT        |QCMP_UNORD; ncode = NE; break;
	case UNGE:    magic = QCMP_GT|QCMP_EQ|QCMP_UNORD; ncode = NE; break;
	  /* Not supported.  */
	case UNEQ:
	case LTGT:
	default: gcc_unreachable ();
	}

      start_sequence ();

      ret = emit_library_call_value (cmptf_libfunc, 0, LCT_CONST, DImode,
				     *op0, TFmode, *op1, TFmode,
				     GEN_INT (magic), DImode);
      cmp = gen_reg_rtx (BImode);
      emit_insn (gen_rtx_SET (cmp, gen_rtx_fmt_ee (ncode, BImode,
						   ret, const0_rtx)));

      rtx_insn *insns = get_insns ();
      end_sequence ();

      emit_libcall_block (insns, cmp, cmp,
			  gen_rtx_fmt_ee (code, BImode, *op0, *op1));
      code = NE;
    }
  else
    {
      cmp = gen_reg_rtx (BImode);
      emit_insn (gen_rtx_SET (cmp, gen_rtx_fmt_ee (code, BImode, *op0, *op1)));
      code = NE;
    }

  *expr = gen_rtx_fmt_ee (code, VOIDmode, cmp, const0_rtx);
  *op0 = cmp;
  *op1 = const0_rtx;
}

/* Generate an integral vector comparison.  Return true if the condition has
   been reversed, and so the sense of the comparison should be inverted.  */

static bool
ia64_expand_vecint_compare (enum rtx_code code, machine_mode mode,
			    rtx dest, rtx op0, rtx op1)
{
  bool negate = false;
  rtx x;

  /* Canonicalize the comparison to EQ, GT, GTU.  */
  switch (code)
    {
    case EQ:
    case GT:
    case GTU:
      break;

    case NE:
    case LE:
    case LEU:
      code = reverse_condition (code);
      negate = true;
      break;

    case GE:
    case GEU:
      code = reverse_condition (code);
      negate = true;
      /* FALLTHRU */

    case LT:
    case LTU:
      code = swap_condition (code);
      x = op0, op0 = op1, op1 = x;
      break;

    default:
      gcc_unreachable ();
    }

  /* Unsigned parallel compare is not supported by the hardware.  Play some
     tricks to turn this into a signed comparison against 0.  */
  if (code == GTU)
    {
      switch (mode)
	{
	case E_V2SImode:
	  {
	    rtx t1, t2, mask;

	    /* Subtract (-(INT MAX) - 1) from both operands to make
	       them signed.  */
	    mask = gen_int_mode (0x80000000, SImode);
	    mask = gen_const_vec_duplicate (V2SImode, mask);
	    mask = force_reg (mode, mask);
	    t1 = gen_reg_rtx (mode);
	    emit_insn (gen_subv2si3 (t1, op0, mask));
	    t2 = gen_reg_rtx (mode);
	    emit_insn (gen_subv2si3 (t2, op1, mask));
	    op0 = t1;
	    op1 = t2;
	    code = GT;
	  }
	  break;

	case E_V8QImode:
	case E_V4HImode:
	  /* Perform a parallel unsigned saturating subtraction.  */
	  x = gen_reg_rtx (mode);
	  emit_insn (gen_rtx_SET (x, gen_rtx_US_MINUS (mode, op0, op1)));

	  code = EQ;
	  op0 = x;
	  op1 = CONST0_RTX (mode);
	  negate = !negate;
	  break;

	default:
	  gcc_unreachable ();
	}
    }

  x = gen_rtx_fmt_ee (code, mode, op0, op1);
  emit_insn (gen_rtx_SET (dest, x));

  return negate;
}

/* Emit an integral vector conditional move.  */

void
ia64_expand_vecint_cmov (rtx operands[])
{
  machine_mode mode = GET_MODE (operands[0]);
  enum rtx_code code = GET_CODE (operands[3]);
  bool negate;
  rtx cmp, x, ot, of;

  cmp = gen_reg_rtx (mode);
  negate = ia64_expand_vecint_compare (code, mode, cmp,
				       operands[4], operands[5]);

  ot = operands[1+negate];
  of = operands[2-negate];

  if (ot == CONST0_RTX (mode))
    {
      if (of == CONST0_RTX (mode))
	{
	  emit_move_insn (operands[0], ot);
	  return;
	}

      x = gen_rtx_NOT (mode, cmp);
      x = gen_rtx_AND (mode, x, of);
      emit_insn (gen_rtx_SET (operands[0], x));
    }
  else if (of == CONST0_RTX (mode))
    {
      x = gen_rtx_AND (mode, cmp, ot);
      emit_insn (gen_rtx_SET (operands[0], x));
    }
  else
    {
      rtx t, f;

      t = gen_reg_rtx (mode);
      x = gen_rtx_AND (mode, cmp, operands[1+negate]);
      emit_insn (gen_rtx_SET (t, x));

      f = gen_reg_rtx (mode);
      x = gen_rtx_NOT (mode, cmp);
      x = gen_rtx_AND (mode, x, operands[2-negate]);
      emit_insn (gen_rtx_SET (f, x));

      x = gen_rtx_IOR (mode, t, f);
      emit_insn (gen_rtx_SET (operands[0], x));
    }
}

/* Emit an integral vector min or max operation.  Return true if all done.  */

bool
ia64_expand_vecint_minmax (enum rtx_code code, machine_mode mode,
			   rtx operands[])
{
  rtx xops[6];

  /* These four combinations are supported directly.  */
  if (mode == V8QImode && (code == UMIN || code == UMAX))
    return false;
  if (mode == V4HImode && (code == SMIN || code == SMAX))
    return false;

  /* This combination can be implemented with only saturating subtraction.  */
  if (mode == V4HImode && code == UMAX)
    {
      rtx x, tmp = gen_reg_rtx (mode);

      x = gen_rtx_US_MINUS (mode, operands[1], operands[2]);
      emit_insn (gen_rtx_SET (tmp, x));

      emit_insn (gen_addv4hi3 (operands[0], tmp, operands[2]));
      return true;
    }

  /* Everything else implemented via vector comparisons.  */
  xops[0] = operands[0];
  xops[4] = xops[1] = operands[1];
  xops[5] = xops[2] = operands[2];

  switch (code)
    {
    case UMIN:
      code = LTU;
      break;
    case UMAX:
      code = GTU;
      break;
    case SMIN:
      code = LT;
      break;
    case SMAX:
      code = GT;
      break;
    default:
      gcc_unreachable ();
    }
  xops[3] = gen_rtx_fmt_ee (code, VOIDmode, operands[1], operands[2]);

  ia64_expand_vecint_cmov (xops);
  return true;
}

/* The vectors LO and HI each contain N halves of a double-wide vector.
   Reassemble either the first N/2 or the second N/2 elements.  */

void
ia64_unpack_assemble (rtx out, rtx lo, rtx hi, bool highp)
{
  machine_mode vmode = GET_MODE (lo);
  unsigned int i, high, nelt = GET_MODE_NUNITS (vmode);
  struct expand_vec_perm_d d;
  bool ok;

  d.target = gen_lowpart (vmode, out);
  d.op0 = (TARGET_BIG_ENDIAN ? hi : lo);
  d.op1 = (TARGET_BIG_ENDIAN ? lo : hi);
  d.vmode = vmode;
  d.nelt = nelt;
  d.one_operand_p = false;
  d.testing_p = false;

  high = (highp ? nelt / 2 : 0);
  for (i = 0; i < nelt / 2; ++i)
    {
      d.perm[i * 2] = i + high;
      d.perm[i * 2 + 1] = i + high + nelt;
    }

  ok = ia64_expand_vec_perm_const_1 (&d);
  gcc_assert (ok);
}

/* Return a vector of the sign-extension of VEC.  */

static rtx
ia64_unpack_sign (rtx vec, bool unsignedp)
{
  machine_mode mode = GET_MODE (vec);
  rtx zero = CONST0_RTX (mode);

  if (unsignedp)
    return zero;
  else
    {
      rtx sign = gen_reg_rtx (mode);
      bool neg;

      neg = ia64_expand_vecint_compare (LT, mode, sign, vec, zero);
      gcc_assert (!neg);

      return sign;
    }
}

/* Emit an integral vector unpack operation.  */

void
ia64_expand_unpack (rtx operands[3], bool unsignedp, bool highp)
{
  rtx sign = ia64_unpack_sign (operands[1], unsignedp);
  ia64_unpack_assemble (operands[0], operands[1], sign, highp);
}

/* Emit an integral vector widening sum operations.  */

void
ia64_expand_widen_sum (rtx operands[3], bool unsignedp)
{
  machine_mode wmode;
  rtx l, h, t, sign;

  sign = ia64_unpack_sign (operands[1], unsignedp);

  wmode = GET_MODE (operands[0]);
  l = gen_reg_rtx (wmode);
  h = gen_reg_rtx (wmode);

  ia64_unpack_assemble (l, operands[1], sign, false);
  ia64_unpack_assemble (h, operands[1], sign, true);

  t = expand_binop (wmode, add_optab, l, operands[2], NULL, 0, OPTAB_DIRECT);
  t = expand_binop (wmode, add_optab, h, t, operands[0], 0, OPTAB_DIRECT);
  if (t != operands[0])
    emit_move_insn (operands[0], t);
}

/* Emit the appropriate sequence for a call.  */

void
ia64_expand_call (rtx retval, rtx addr, rtx nextarg ATTRIBUTE_UNUSED,
		  int sibcall_p)
{
  rtx insn, b0;

  addr = XEXP (addr, 0);
  addr = convert_memory_address (DImode, addr);
  b0 = gen_rtx_REG (DImode, R_BR (0));

  /* ??? Should do this for functions known to bind local too.  */
  if (TARGET_NO_PIC || TARGET_AUTO_PIC)
    {
      if (sibcall_p)
	insn = gen_sibcall_nogp (addr);
      else if (! retval)
	insn = gen_call_nogp (addr, b0);
      else
	insn = gen_call_value_nogp (retval, addr, b0);
      insn = emit_call_insn (insn);
    }
  else
    {
      if (sibcall_p)
	insn = gen_sibcall_gp (addr);
      else if (! retval)
	insn = gen_call_gp (addr, b0);
      else
	insn = gen_call_value_gp (retval, addr, b0);
      insn = emit_call_insn (insn);

      use_reg (&CALL_INSN_FUNCTION_USAGE (insn), pic_offset_table_rtx);
    }

  if (sibcall_p)
    use_reg (&CALL_INSN_FUNCTION_USAGE (insn), b0);

  if (TARGET_ABI_OPEN_VMS)
    use_reg (&CALL_INSN_FUNCTION_USAGE (insn),
	     gen_rtx_REG (DImode, GR_REG (25)));
}

static void
reg_emitted (enum ia64_frame_regs r)
{
  if (emitted_frame_related_regs[r] == 0)
    emitted_frame_related_regs[r] = current_frame_info.r[r];
  else
    gcc_assert (emitted_frame_related_regs[r] == current_frame_info.r[r]);
}

static int
get_reg (enum ia64_frame_regs r)
{
  reg_emitted (r);
  return current_frame_info.r[r];
}

static bool
is_emitted (int regno)
{
  unsigned int r;

  for (r = reg_fp; r < number_of_ia64_frame_regs; r++)
    if (emitted_frame_related_regs[r] == regno)
      return true;
  return false;
}

void
ia64_reload_gp (void)
{
  rtx tmp;

  if (current_frame_info.r[reg_save_gp])
    {
      tmp = gen_rtx_REG (DImode, get_reg (reg_save_gp));
    }
  else
    {
      HOST_WIDE_INT offset;
      rtx offset_r;

      offset = (current_frame_info.spill_cfa_off
	        + current_frame_info.spill_size);
      if (frame_pointer_needed)
        {
          tmp = hard_frame_pointer_rtx;
          offset = -offset;
        }
      else
        {
          tmp = stack_pointer_rtx;
          offset = current_frame_info.total_size - offset;
        }

      offset_r = GEN_INT (offset);
      if (satisfies_constraint_I (offset_r))
        emit_insn (gen_adddi3 (pic_offset_table_rtx, tmp, offset_r));
      else
        {
          emit_move_insn (pic_offset_table_rtx, offset_r);
          emit_insn (gen_adddi3 (pic_offset_table_rtx,
			         pic_offset_table_rtx, tmp));
        }

      tmp = gen_rtx_MEM (DImode, pic_offset_table_rtx);
    }

  emit_move_insn (pic_offset_table_rtx, tmp);
}

void
ia64_split_call (rtx retval, rtx addr, rtx retaddr, rtx scratch_r,
		 rtx scratch_b, int noreturn_p, int sibcall_p)
{
  rtx insn;
  bool is_desc = false;

  /* If we find we're calling through a register, then we're actually
     calling through a descriptor, so load up the values.  */
  if (REG_P (addr) && GR_REGNO_P (REGNO (addr)))
    {
      rtx tmp;
      bool addr_dead_p;

      /* ??? We are currently constrained to *not* use peep2, because
	 we can legitimately change the global lifetime of the GP
	 (in the form of killing where previously live).  This is
	 because a call through a descriptor doesn't use the previous
	 value of the GP, while a direct call does, and we do not
	 commit to either form until the split here.

	 That said, this means that we lack precise life info for
	 whether ADDR is dead after this call.  This is not terribly
	 important, since we can fix things up essentially for free
	 with the POST_DEC below, but it's nice to not use it when we
	 can immediately tell it's not necessary.  */
      addr_dead_p = ((noreturn_p || sibcall_p
		      || TEST_HARD_REG_BIT (regs_invalidated_by_call,
					    REGNO (addr)))
		     && !FUNCTION_ARG_REGNO_P (REGNO (addr)));

      /* Load the code address into scratch_b.  */
      tmp = gen_rtx_POST_INC (Pmode, addr);
      tmp = gen_rtx_MEM (Pmode, tmp);
      emit_move_insn (scratch_r, tmp);
      emit_move_insn (scratch_b, scratch_r);

      /* Load the GP address.  If ADDR is not dead here, then we must
	 revert the change made above via the POST_INCREMENT.  */
      if (!addr_dead_p)
	tmp = gen_rtx_POST_DEC (Pmode, addr);
      else
	tmp = addr;
      tmp = gen_rtx_MEM (Pmode, tmp);
      emit_move_insn (pic_offset_table_rtx, tmp);

      is_desc = true;
      addr = scratch_b;
    }

  if (sibcall_p)
    insn = gen_sibcall_nogp (addr);
  else if (retval)
    insn = gen_call_value_nogp (retval, addr, retaddr);
  else
    insn = gen_call_nogp (addr, retaddr);
  emit_call_insn (insn);

  if ((!TARGET_CONST_GP || is_desc) && !noreturn_p && !sibcall_p)
    ia64_reload_gp ();
}

/* Expand an atomic operation.  We want to perform MEM <CODE>= VAL atomically.

   This differs from the generic code in that we know about the zero-extending
   properties of cmpxchg, and the zero-extending requirements of ar.ccv.  We
   also know that ld.acq+cmpxchg.rel equals a full barrier.

   The loop we want to generate looks like

	cmp_reg = mem;
      label:
        old_reg = cmp_reg;
	new_reg = cmp_reg op val;
	cmp_reg = compare-and-swap(mem, old_reg, new_reg)
	if (cmp_reg != old_reg)
	  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.  */

void
ia64_expand_atomic_op (enum rtx_code code, rtx mem, rtx val,
		       rtx old_dst, rtx new_dst, enum memmodel model)
{
  machine_mode mode = GET_MODE (mem);
  rtx old_reg, new_reg, cmp_reg, ar_ccv, label;
  enum insn_code icode;

  /* Special case for using fetchadd.  */
  if ((mode == SImode || mode == DImode)
      && (code == PLUS || code == MINUS)
      && fetchadd_operand (val, mode))
    {
      if (code == MINUS)
	val = GEN_INT (-INTVAL (val));

      if (!old_dst)
        old_dst = gen_reg_rtx (mode);

      switch (model)
	{
	case MEMMODEL_ACQ_REL:
	case MEMMODEL_SEQ_CST:
	case MEMMODEL_SYNC_SEQ_CST:
	  emit_insn (gen_memory_barrier ());
	  /* FALLTHRU */
	case MEMMODEL_RELAXED:
	case MEMMODEL_ACQUIRE:
	case MEMMODEL_SYNC_ACQUIRE:
	case MEMMODEL_CONSUME:
	  if (mode == SImode)
	    icode = CODE_FOR_fetchadd_acq_si;
	  else
	    icode = CODE_FOR_fetchadd_acq_di;
	  break;
	case MEMMODEL_RELEASE:
	case MEMMODEL_SYNC_RELEASE:
	  if (mode == SImode)
	    icode = CODE_FOR_fetchadd_rel_si;
	  else
	    icode = CODE_FOR_fetchadd_rel_di;
	  break;

	default:
	  gcc_unreachable ();
	}

      emit_insn (GEN_FCN (icode) (old_dst, mem, val));

      if (new_dst)
	{
	  new_reg = expand_simple_binop (mode, PLUS, old_dst, val, new_dst,
					 true, OPTAB_WIDEN);
	  if (new_reg != new_dst)
	    emit_move_insn (new_dst, new_reg);
	}
      return;
    }

  /* Because of the volatile mem read, we get an ld.acq, which is the
     front half of the full barrier.  The end half is the cmpxchg.rel.
     For relaxed and release memory models, we don't need this.  But we
     also don't bother trying to prevent it either.  */
  gcc_assert (is_mm_relaxed (model) || is_mm_release (model)
	      || MEM_VOLATILE_P (mem));

  old_reg = gen_reg_rtx (DImode);
  cmp_reg = gen_reg_rtx (DImode);
  label = gen_label_rtx ();

  if (mode != DImode)
    {
      val = simplify_gen_subreg (DImode, val, mode, 0);
      emit_insn (gen_extend_insn (cmp_reg, mem, DImode, mode, 1));
    }
  else
    emit_move_insn (cmp_reg, mem);

  emit_label (label);

  ar_ccv = gen_rtx_REG (DImode, AR_CCV_REGNUM);
  emit_move_insn (old_reg, cmp_reg);
  emit_move_insn (ar_ccv, cmp_reg);

  if (old_dst)
    emit_move_insn (old_dst, gen_lowpart (mode, cmp_reg));

  new_reg = cmp_reg;
  if (code == NOT)
    {
      new_reg = expand_simple_binop (DImode, AND, new_reg, val, NULL_RTX,
				     true, OPTAB_DIRECT);
      new_reg = expand_simple_unop (DImode, code, new_reg, NULL_RTX, true);
    }
  else
    new_reg = expand_simple_binop (DImode, code, new_reg, val, NULL_RTX,
				   true, OPTAB_DIRECT);

  if (mode != DImode)
    new_reg = gen_lowpart (mode, new_reg);
  if (new_dst)
    emit_move_insn (new_dst, new_reg);

  switch (model)
    {
    case MEMMODEL_RELAXED:
    case MEMMODEL_ACQUIRE:
    case MEMMODEL_SYNC_ACQUIRE:
    case MEMMODEL_CONSUME:
      switch (mode)
	{
	case E_QImode: icode = CODE_FOR_cmpxchg_acq_qi;  break;
	case E_HImode: icode = CODE_FOR_cmpxchg_acq_hi;  break;
	case E_SImode: icode = CODE_FOR_cmpxchg_acq_si;  break;
	case E_DImode: icode = CODE_FOR_cmpxchg_acq_di;  break;
	default:
	  gcc_unreachable ();
	}
      break;

    case MEMMODEL_RELEASE:
    case MEMMODEL_SYNC_RELEASE:
    case MEMMODEL_ACQ_REL:
    case MEMMODEL_SEQ_CST:
    case MEMMODEL_SYNC_SEQ_CST:
      switch (mode)
	{
	case E_QImode: icode = CODE_FOR_cmpxchg_rel_qi;  break;
	case E_HImode: icode = CODE_FOR_cmpxchg_rel_hi;  break;
	case E_SImode: icode = CODE_FOR_cmpxchg_rel_si;  break;
	case E_DImode: icode = CODE_FOR_cmpxchg_rel_di;  break;
	default:
	  gcc_unreachable ();
	}
      break;

    default:
      gcc_unreachable ();
    }

  emit_insn (GEN_FCN (icode) (cmp_reg, mem, ar_ccv, new_reg));

  emit_cmp_and_jump_insns (cmp_reg, old_reg, NE, NULL, DImode, true, label);
}

/* Begin the assembly file.  */

static void
ia64_file_start (void)
{
  default_file_start ();
  emit_safe_across_calls ();
}

void
emit_safe_across_calls (void)
{
  unsigned int rs, re;
  int out_state;

  rs = 1;
  out_state = 0;
  while (1)
    {
      while (rs < 64 && call_used_or_fixed_reg_p (PR_REG (rs)))
	rs++;
      if (rs >= 64)
	break;
      for (re = rs + 1;
	   re < 64 && ! call_used_or_fixed_reg_p (PR_REG (re)); re++)
	continue;
      if (out_state == 0)
	{
	  fputs ("\t.pred.safe_across_calls ", asm_out_file);
	  out_state = 1;
	}
      else
	fputc (',', asm_out_file);
      if (re == rs + 1)
	fprintf (asm_out_file, "p%u", rs);
      else
	fprintf (asm_out_file, "p%u-p%u", rs, re - 1);
      rs = re + 1;
    }
  if (out_state)
    fputc ('\n', asm_out_file);
}

/* Globalize a declaration.  */

static void
ia64_globalize_decl_name (FILE * stream, tree decl)
{
  const char *name = XSTR (XEXP (DECL_RTL (decl), 0), 0);
  tree version_attr = lookup_attribute ("version_id", DECL_ATTRIBUTES (decl));
  if (version_attr)
    {
      tree v = TREE_VALUE (TREE_VALUE (version_attr));
      const char *p = TREE_STRING_POINTER (v);
      fprintf (stream, "\t.alias %s#, \"%s{%s}\"\n", name, name, p);
    }
  targetm.asm_out.globalize_label (stream, name);
  if (TREE_CODE (decl) == FUNCTION_DECL)
    ASM_OUTPUT_TYPE_DIRECTIVE (stream, name, "function");
}

/* Helper function for ia64_compute_frame_size: find an appropriate general
   register to spill some special register to.  SPECIAL_SPILL_MASK contains
   bits in GR0 to GR31 that have already been allocated by this routine.
   TRY_LOCALS is true if we should attempt to locate a local regnum.  */

static int
find_gr_spill (enum ia64_frame_regs r, int try_locals)
{
  int regno;

  if (emitted_frame_related_regs[r] != 0)
    {
      regno = emitted_frame_related_regs[r];
      if (regno >= LOC_REG (0) && regno < LOC_REG (80 - frame_pointer_needed)
	  && current_frame_info.n_local_regs < regno - LOC_REG (0) + 1)
        current_frame_info.n_local_regs = regno - LOC_REG (0) + 1;
      else if (crtl->is_leaf
               && regno >= GR_REG (1) && regno <= GR_REG (31))
        current_frame_info.gr_used_mask |= 1 << regno;

      return regno;
    }

  /* If this is a leaf function, first try an otherwise unused
     call-clobbered register.  */
  if (crtl->is_leaf)
    {
      for (regno = GR_REG (1); regno <= GR_REG (31); regno++)
	if (! df_regs_ever_live_p (regno)
	    && call_used_or_fixed_reg_p (regno)
	    && ! fixed_regs[regno]
	    && ! global_regs[regno]
	    && ((current_frame_info.gr_used_mask >> regno) & 1) == 0
            && ! is_emitted (regno))
	  {
	    current_frame_info.gr_used_mask |= 1 << regno;
	    return regno;
	  }
    }

  if (try_locals)
    {
      regno = current_frame_info.n_local_regs;
      /* If there is a frame pointer, then we can't use loc79, because
	 that is HARD_FRAME_POINTER_REGNUM.  In particular, see the
	 reg_name switching code in ia64_expand_prologue.  */
      while (regno < (80 - frame_pointer_needed))
	if (! is_emitted (LOC_REG (regno++)))
	  {
	    current_frame_info.n_local_regs = regno;
	    return LOC_REG (regno - 1);
	  }
    }

  /* Failed to find a general register to spill to.  Must use stack.  */
  return 0;
}

/* In order to make for nice schedules, we try to allocate every temporary
   to a different register.  We must of course stay away from call-saved,
   fixed, and global registers.  We must also stay away from registers
   allocated in current_frame_info.gr_used_mask, since those include regs
   used all through the prologue.

   Any register allocated here must be used immediately.  The idea is to
   aid scheduling, not to solve data flow problems.  */

static int last_scratch_gr_reg;

static int
next_scratch_gr_reg (void)
{
  int i, regno;

  for (i = 0; i < 32; ++i)
    {
      regno = (last_scratch_gr_reg + i + 1) & 31;
      if (call_used_or_fixed_reg_p (regno)
	  && ! fixed_regs[regno]
	  && ! global_regs[regno]
	  && ((current_frame_info.gr_used_mask >> regno) & 1) == 0)
	{
	  last_scratch_gr_reg = regno;
	  return regno;
	}
    }

  /* There must be _something_ available.  */
  gcc_unreachable ();
}

/* Helper function for ia64_compute_frame_size, called through
   diddle_return_value.  Mark REG in current_frame_info.gr_used_mask.  */

static void
mark_reg_gr_used_mask (rtx reg, void *data ATTRIBUTE_UNUSED)
{
  unsigned int regno = REGNO (reg);
  if (regno < 32)
    {
      unsigned int i, n = REG_NREGS (reg);
      for (i = 0; i < n; ++i)
	current_frame_info.gr_used_mask |= 1 << (regno + i);
    }
}


/* Returns the number of bytes offset between the frame pointer and the stack
   pointer for the current function.  SIZE is the number of bytes of space
   needed for local variables.  */

static void
ia64_compute_frame_size (HOST_WIDE_INT size)
{
  HOST_WIDE_INT total_size;
  HOST_WIDE_INT spill_size = 0;
  HOST_WIDE_INT extra_spill_size = 0;
  HOST_WIDE_INT pretend_args_size;
  HARD_REG_SET mask;
  int n_spilled = 0;
  int spilled_gr_p = 0;
  int spilled_fr_p = 0;
  unsigned int regno;
  int min_regno;
  int max_regno;
  int i;

  if (current_frame_info.initialized)
    return;

  memset (&current_frame_info, 0, sizeof current_frame_info);
  CLEAR_HARD_REG_SET (mask);

  /* Don't allocate scratches to the return register.  */
  diddle_return_value (mark_reg_gr_used_mask, NULL);

  /* Don't allocate scratches to the EH scratch registers.  */
  if (cfun->machine->ia64_eh_epilogue_sp)
    mark_reg_gr_used_mask (cfun->machine->ia64_eh_epilogue_sp, NULL);
  if (cfun->machine->ia64_eh_epilogue_bsp)
    mark_reg_gr_used_mask (cfun->machine->ia64_eh_epilogue_bsp, NULL);

  /* Static stack checking uses r2 and r3.  */
  if (flag_stack_check == STATIC_BUILTIN_STACK_CHECK
      || flag_stack_clash_protection)
    current_frame_info.gr_used_mask |= 0xc;

  /* Find the size of the register stack frame.  We have only 80 local
     registers, because we reserve 8 for the inputs and 8 for the
     outputs.  */

  /* Skip HARD_FRAME_POINTER_REGNUM (loc79) when frame_pointer_needed,
     since we'll be adjusting that down later.  */
  regno = LOC_REG (78) + ! frame_pointer_needed;
  for (; regno >= LOC_REG (0); regno--)
    if (df_regs_ever_live_p (regno) && !is_emitted (regno))
      break;
  current_frame_info.n_local_regs = regno - LOC_REG (0) + 1;

  /* For functions marked with the syscall_linkage attribute, we must mark
     all eight input registers as in use, so that locals aren't visible to
     the caller.  */

  if (cfun->machine->n_varargs > 0
      || lookup_attribute ("syscall_linkage",
			   TYPE_ATTRIBUTES (TREE_TYPE (current_function_decl))))
    current_frame_info.n_input_regs = 8;
  else
    {
      for (regno = IN_REG (7); regno >= IN_REG (0); regno--)
	if (df_regs_ever_live_p (regno))
	  break;
      current_frame_info.n_input_regs = regno - IN_REG (0) + 1;
    }

  for (regno = OUT_REG (7); regno >= OUT_REG (0); regno--)
    if (df_regs_ever_live_p (regno))
      break;
  i = regno - OUT_REG (0) + 1;

#ifndef PROFILE_HOOK
  /* When -p profiling, we need one output register for the mcount argument.
     Likewise for -a profiling for the bb_init_func argument.  For -ax
     profiling, we need two output registers for the two bb_init_trace_func
     arguments.  */
  if (crtl->profile)
    i = MAX (i, 1);
#endif
  current_frame_info.n_output_regs = i;

  /* ??? No rotating register support yet.  */
  current_frame_info.n_rotate_regs = 0;

  /* Discover which registers need spilling, and how much room that
     will take.  Begin with floating point and general registers,
     which will always wind up on the stack.  */

  for (regno = FR_REG (2); regno <= FR_REG (127); regno++)
    if (df_regs_ever_live_p (regno) && ! call_used_or_fixed_reg_p (regno))
      {
	SET_HARD_REG_BIT (mask, regno);
	spill_size += 16;
	n_spilled += 1;
	spilled_fr_p = 1;
      }

  for (regno = GR_REG (1); regno <= GR_REG (31); regno++)
    if (df_regs_ever_live_p (regno) && ! call_used_or_fixed_reg_p (regno))
      {
	SET_HARD_REG_BIT (mask, regno);
	spill_size += 8;
	n_spilled += 1;
	spilled_gr_p = 1;
      }

  for (regno = BR_REG (1); regno <= BR_REG (7); regno++)
    if (df_regs_ever_live_p (regno) && ! call_used_or_fixed_reg_p (regno))
      {
	SET_HARD_REG_BIT (mask, regno);
	spill_size += 8;
	n_spilled += 1;
      }

  /* Now come all special registers that might get saved in other
     general registers.  */

  if (frame_pointer_needed)
    {
      current_frame_info.r[reg_fp] = find_gr_spill (reg_fp, 1);
      /* If we did not get a register, then we take LOC79.  This is guaranteed
	 to be free, even if regs_ever_live is already set, because this is
	 HARD_FRAME_POINTER_REGNUM.  This requires incrementing n_local_regs,
	 as we don't count loc79 above.  */
      if (current_frame_info.r[reg_fp] == 0)
	{
	  current_frame_info.r[reg_fp] = LOC_REG (79);
	  current_frame_info.n_local_regs = LOC_REG (79) - LOC_REG (0) + 1;
	}
    }

  if (! crtl->is_leaf)
    {
      /* Emit a save of BR0 if we call other functions.  Do this even
	 if this function doesn't return, as EH depends on this to be
	 able to unwind the stack.  */
      SET_HARD_REG_BIT (mask, BR_REG (0));

      current_frame_info.r[reg_save_b0] = find_gr_spill (reg_save_b0, 1);
      if (current_frame_info.r[reg_save_b0] == 0)
	{
	  extra_spill_size += 8;
	  n_spilled += 1;
	}

      /* Similarly for ar.pfs.  */
      SET_HARD_REG_BIT (mask, AR_PFS_REGNUM);
      current_frame_info.r[reg_save_ar_pfs] = find_gr_spill (reg_save_ar_pfs, 1);
      if (current_frame_info.r[reg_save_ar_pfs] == 0)
	{
	  extra_spill_size += 8;
	  n_spilled += 1;
	}

      /* Similarly for gp.  Note that if we're calling setjmp, the stacked
	 registers are clobbered, so we fall back to the stack.  */
      current_frame_info.r[reg_save_gp]
	= (cfun->calls_setjmp ? 0 : find_gr_spill (reg_save_gp, 1));
      if (current_frame_info.r[reg_save_gp] == 0)
	{
	  SET_HARD_REG_BIT (mask, GR_REG (1));
	  spill_size += 8;
	  n_spilled += 1;
	}
    }
  else
    {
      if (df_regs_ever_live_p (BR_REG (0))
	  && ! call_used_or_fixed_reg_p (BR_REG (0)))
	{
	  SET_HARD_REG_BIT (mask, BR_REG (0));
	  extra_spill_size += 8;
	  n_spilled += 1;
	}

      if (df_regs_ever_live_p (AR_PFS_REGNUM))
	{
	  SET_HARD_REG_BIT (mask, AR_PFS_REGNUM);
 	  current_frame_info.r[reg_save_ar_pfs] 
            = find_gr_spill (reg_save_ar_pfs, 1);
	  if (current_frame_info.r[reg_save_ar_pfs] == 0)
	    {
	      extra_spill_size += 8;
	      n_spilled += 1;
	    }
	}
    }

  /* Unwind descriptor hackery: things are most efficient if we allocate
     consecutive GR save registers for RP, PFS, FP in that order. However,
     it is absolutely critical that FP get the only hard register that's
     guaranteed to be free, so we allocated it first.  If all three did
     happen to be allocated hard regs, and are consecutive, rearrange them
     into the preferred order now.  
     
     If we have already emitted code for any of those registers,
     then it's already too late to change.  */
  min_regno = MIN (current_frame_info.r[reg_fp],
		   MIN (current_frame_info.r[reg_save_b0],
			current_frame_info.r[reg_save_ar_pfs]));
  max_regno = MAX (current_frame_info.r[reg_fp],
		   MAX (current_frame_info.r[reg_save_b0],
			current_frame_info.r[reg_save_ar_pfs]));
  if (min_regno > 0
      && min_regno + 2 == max_regno
      && (current_frame_info.r[reg_fp] == min_regno + 1
	  || current_frame_info.r[reg_save_b0] == min_regno + 1
	  || current_frame_info.r[reg_save_ar_pfs] == min_regno + 1)
      && (emitted_frame_related_regs[reg_save_b0] == 0
	  || emitted_frame_related_regs[reg_save_b0] == min_regno)
      && (emitted_frame_related_regs[reg_save_ar_pfs] == 0
	  || emitted_frame_related_regs[reg_save_ar_pfs] == min_regno + 1)
      && (emitted_frame_related_regs[reg_fp] == 0
	  || emitted_frame_related_regs[reg_fp] == min_regno + 2))
    {
      current_frame_info.r[reg_save_b0] = min_regno;
      current_frame_info.r[reg_save_ar_pfs] = min_regno + 1;
      current_frame_info.r[reg_fp] = min_regno + 2;
    }

  /* See if we need to store the predicate register block.  */
  for (regno = PR_REG (0); regno <= PR_REG (63); regno++)
    if (df_regs_ever_live_p (regno) && ! call_used_or_fixed_reg_p (regno))
      break;
  if (regno <= PR_REG (63))
    {
      SET_HARD_REG_BIT (mask, PR_REG (0));
      current_frame_info.r[reg_save_pr] = find_gr_spill (reg_save_pr, 1);
      if (current_frame_info.r[reg_save_pr] == 0)
	{
	  extra_spill_size += 8;
	  n_spilled += 1;
	}

      /* ??? Mark them all as used so that register renaming and such
	 are free to use them.  */
      for (regno = PR_REG (0); regno <= PR_REG (63); regno++)
	df_set_regs_ever_live (regno, true);
    }

  /* If we're forced to use st8.spill, we're forced to save and restore
     ar.unat as well.  The check for existing liveness allows inline asm
     to touch ar.unat.  */
  if (spilled_gr_p || cfun->machine->n_varargs
      || df_regs_ever_live_p (AR_UNAT_REGNUM))
    {
      df_set_regs_ever_live (AR_UNAT_REGNUM, true);
      SET_HARD_REG_BIT (mask, AR_UNAT_REGNUM);
      current_frame_info.r[reg_save_ar_unat] 
        = find_gr_spill (reg_save_ar_unat, spill_size == 0);
      if (current_frame_info.r[reg_save_ar_unat] == 0)
	{
	  extra_spill_size += 8;
	  n_spilled += 1;
	}
    }

  if (df_regs_ever_live_p (AR_LC_REGNUM))
    {
      SET_HARD_REG_BIT (mask, AR_LC_REGNUM);
      current_frame_info.r[reg_save_ar_lc] 
        = find_gr_spill (reg_save_ar_lc, spill_size == 0);
      if (current_frame_info.r[reg_save_ar_lc] == 0)
	{
	  extra_spill_size += 8;
	  n_spilled += 1;
	}
    }

  /* If we have an odd number of words of pretend arguments written to
     the stack, then the FR save area will be unaligned.  We round the
     size of this area up to keep things 16 byte aligned.  */
  if (spilled_fr_p)
    pretend_args_size = IA64_STACK_ALIGN (crtl->args.pretend_args_size);
  else
    pretend_args_size = crtl->args.pretend_args_size;

  total_size = (spill_size + extra_spill_size + size + pretend_args_size
		+ crtl->outgoing_args_size);
  total_size = IA64_STACK_ALIGN (total_size);

  /* We always use the 16-byte scratch area provided by the caller, but
     if we are a leaf function, there's no one to which we need to provide
     a scratch area.  However, if the function allocates dynamic stack space,
     the dynamic offset is computed early and contains STACK_POINTER_OFFSET,
     so we need to cope.  */
  if (crtl->is_leaf && !cfun->calls_alloca)
    total_size = MAX (0, total_size - 16);

  current_frame_info.total_size = total_size;
  current_frame_info.spill_cfa_off = pretend_args_size - 16;
  current_frame_info.spill_size = spill_size;
  current_frame_info.extra_spill_size = extra_spill_size;
  current_frame_info.mask = mask;
  current_frame_info.n_spilled = n_spilled;
  current_frame_info.initialized = reload_completed;
}

/* Worker function for TARGET_CAN_ELIMINATE.  */

bool
ia64_can_eliminate (const int from ATTRIBUTE_UNUSED, const int to)
{
  return (to == BR_REG (0) ? crtl->is_leaf : true);
}

/* Compute the initial difference between the specified pair of registers.  */

HOST_WIDE_INT
ia64_initial_elimination_offset (int from, int to)
{
  HOST_WIDE_INT offset;

  ia64_compute_frame_size (get_frame_size ());
  switch (from)
    {
    case FRAME_POINTER_REGNUM:
      switch (to)
	{
	case HARD_FRAME_POINTER_REGNUM:
	  offset = -current_frame_info.total_size;
	  if (!crtl->is_leaf || cfun->calls_alloca)
	    offset += 16 + crtl->outgoing_args_size;
	  break;

	case STACK_POINTER_REGNUM:
	  offset = 0;
	  if (!crtl->is_leaf || cfun->calls_alloca)
	    offset += 16 + crtl->outgoing_args_size;
	  break;

	default:
	  gcc_unreachable ();
	}
      break;

    case ARG_POINTER_REGNUM:
      /* Arguments start above the 16 byte save area, unless stdarg
	 in which case we store through the 16 byte save area.  */
      switch (to)
	{
	case HARD_FRAME_POINTER_REGNUM:
	  offset = 16 - crtl->args.pretend_args_size;
	  break;

	case STACK_POINTER_REGNUM:
	  offset = (current_frame_info.total_size
		    + 16 - crtl->args.pretend_args_size);
	  break;

	default:
	  gcc_unreachable ();
	}
      break;

    default:
      gcc_unreachable ();
    }

  return offset;
}

/* If there are more than a trivial number of register spills, we use
   two interleaved iterators so that we can get two memory references
   per insn group.

   In order to simplify things in the prologue and epilogue expanders,
   we use helper functions to fix up the memory references after the
   fact with the appropriate offsets to a POST_MODIFY memory mode.
   The following data structure tracks the state of the two iterators
   while insns are being emitted.  */

struct spill_fill_data
{
  rtx_insn *init_after;		/* point at which to emit initializations */
  rtx init_reg[2];		/* initial base register */
  rtx iter_reg[2];		/* the iterator registers */
  rtx *prev_addr[2];		/* address of last memory use */
  rtx_insn *prev_insn[2];	/* the insn corresponding to prev_addr */
  HOST_WIDE_INT prev_off[2];	/* last offset */
  int n_iter;			/* number of iterators in use */
  int next_iter;		/* next iterator to use */
  unsigned int save_gr_used_mask;
};

static struct spill_fill_data spill_fill_data;

static void
setup_spill_pointers (int n_spills, rtx init_reg, HOST_WIDE_INT cfa_off)
{
  int i;

  spill_fill_data.init_after = get_last_insn ();
  spill_fill_data.init_reg[0] = init_reg;
  spill_fill_data.init_reg[1] = init_reg;
  spill_fill_data.prev_addr[0] = NULL;
  spill_fill_data.prev_addr[1] = NULL;
  spill_fill_data.prev_insn[0] = NULL;
  spill_fill_data.prev_insn[1] = NULL;
  spill_fill_data.prev_off[0] = cfa_off;
  spill_fill_data.prev_off[1] = cfa_off;
  spill_fill_data.next_iter = 0;
  spill_fill_data.save_gr_used_mask = current_frame_info.gr_used_mask;

  spill_fill_data.n_iter = 1 + (n_spills > 2);
  for (i = 0; i < spill_fill_data.n_iter; ++i)
    {
      int regno = next_scratch_gr_reg ();
      spill_fill_data.iter_reg[i] = gen_rtx_REG (DImode, regno);
      current_frame_info.gr_used_mask |= 1 << regno;
    }
}

static void
finish_spill_pointers (void)
{
  current_frame_info.gr_used_mask = spill_fill_data.save_gr_used_mask;
}

static rtx
spill_restore_mem (rtx reg, HOST_WIDE_INT cfa_off)
{
  int iter = spill_fill_data.next_iter;
  HOST_WIDE_INT disp = spill_fill_data.prev_off[iter] - cfa_off;
  rtx disp_rtx = GEN_INT (disp);
  rtx mem;

  if (spill_fill_data.prev_addr[iter])
    {
      if (satisfies_constraint_N (disp_rtx))
	{
	  *spill_fill_data.prev_addr[iter]
	    = gen_rtx_POST_MODIFY (DImode, spill_fill_data.iter_reg[iter],
				   gen_rtx_PLUS (DImode,
						 spill_fill_data.iter_reg[iter],
						 disp_rtx));
	  add_reg_note (spill_fill_data.prev_insn[iter],
			REG_INC, spill_fill_data.iter_reg[iter]);
	}
      else
	{
	  /* ??? Could use register post_modify for loads.  */
	  if (!satisfies_constraint_I (disp_rtx))
	    {
	      rtx tmp = gen_rtx_REG (DImode, next_scratch_gr_reg ());
	      emit_move_insn (tmp, disp_rtx);
	      disp_rtx = tmp;
	    }
	  emit_insn (gen_adddi3 (spill_fill_data.iter_reg[iter],
				 spill_fill_data.iter_reg[iter], disp_rtx));
	}
    }
  /* Micro-optimization: if we've created a frame pointer, it's at
     CFA 0, which may allow the real iterator to be initialized lower,
     slightly increasing parallelism.  Also, if there are few saves
     it may eliminate the iterator entirely.  */
  else if (disp == 0
	   && spill_fill_data.init_reg[iter] == stack_pointer_rtx
	   && frame_pointer_needed)
    {
      mem = gen_rtx_MEM (GET_MODE (reg), hard_frame_pointer_rtx);
      set_mem_alias_set (mem, get_varargs_alias_set ());
      return mem;
    }
  else
    {
      rtx seq;
      rtx_insn *insn;

      if (disp == 0)
	seq = gen_movdi (spill_fill_data.iter_reg[iter],
			 spill_fill_data.init_reg[iter]);
      else
	{
	  start_sequence ();

	  if (!satisfies_constraint_I (disp_rtx))
	    {
	      rtx tmp = gen_rtx_REG (DImode, next_scratch_gr_reg ());
	      emit_move_insn (tmp, disp_rtx);
	      disp_rtx = tmp;
	    }

	  emit_insn (gen_adddi3 (spill_fill_data.iter_reg[iter],
				 spill_fill_data.init_reg[iter],
				 disp_rtx));

	  seq = get_insns ();
	  end_sequence ();
	}

      /* Careful for being the first insn in a sequence.  */
      if (spill_fill_data.init_after)
	insn = emit_insn_after (seq, spill_fill_data.init_after);
      else
	{
	  rtx_insn *first = get_insns ();
	  if (first)
	    insn = emit_insn_before (seq, first);
	  else
	    insn = emit_insn (seq);
	}
      spill_fill_data.init_after = insn;
    }

  mem = gen_rtx_MEM (GET_MODE (reg), spill_fill_data.iter_reg[iter]);

  /* ??? Not all of the spills are for varargs, but some of them are.
     The rest of the spills belong in an alias set of their own.  But
     it doesn't actually hurt to include them here.  */
  set_mem_alias_set (mem, get_varargs_alias_set ());

  spill_fill_data.prev_addr[iter] = &XEXP (mem, 0);
  spill_fill_data.prev_off[iter] = cfa_off;

  if (++iter >= spill_fill_data.n_iter)
    iter = 0;
  spill_fill_data.next_iter = iter;

  return mem;
}

static void
do_spill (rtx (*move_fn) (rtx, rtx, rtx), rtx reg, HOST_WIDE_INT cfa_off,
	  rtx frame_reg)
{
  int iter = spill_fill_data.next_iter;
  rtx mem;
  rtx_insn *insn;

  mem = spill_restore_mem (reg, cfa_off);
  insn = emit_insn ((*move_fn) (mem, reg, GEN_INT (cfa_off)));
  spill_fill_data.prev_insn[iter] = insn;

  if (frame_reg)
    {
      rtx base;
      HOST_WIDE_INT off;

      RTX_FRAME_RELATED_P (insn) = 1;

      /* Don't even pretend that the unwind code can intuit its way
	 through a pair of interleaved post_modify iterators.  Just
	 provide the correct answer.  */

      if (frame_pointer_needed)
	{
	  base = hard_frame_pointer_rtx;
	  off = - cfa_off;
	}
      else
	{
	  base = stack_pointer_rtx;
	  off = current_frame_info.total_size - cfa_off;
	}

      add_reg_note (insn, REG_CFA_OFFSET,
		    gen_rtx_SET (gen_rtx_MEM (GET_MODE (reg),
					      plus_constant (Pmode,
							     base, off)),
				 frame_reg));
    }
}

static void
do_restore (rtx (*move_fn) (rtx, rtx, rtx), rtx reg, HOST_WIDE_INT cfa_off)
{
  int iter = spill_fill_data.next_iter;
  rtx_insn *insn;

  insn = emit_insn ((*move_fn) (reg, spill_restore_mem (reg, cfa_off),
				GEN_INT (cfa_off)));
  spill_fill_data.prev_insn[iter] = insn;
}

/* Wrapper functions that discards the CONST_INT spill offset.  These
   exist so that we can give gr_spill/gr_fill the offset they need and
   use a consistent function interface.  */

static rtx
gen_movdi_x (rtx dest, rtx src, rtx offset ATTRIBUTE_UNUSED)
{
  return gen_movdi (dest, src);
}

static rtx
gen_fr_spill_x (rtx dest, rtx src, rtx offset ATTRIBUTE_UNUSED)
{
  return gen_fr_spill (dest, src);
}

static rtx
gen_fr_restore_x (rtx dest, rtx src, rtx offset ATTRIBUTE_UNUSED)
{
  return gen_fr_restore (dest, src);
}

#define PROBE_INTERVAL (1 << STACK_CHECK_PROBE_INTERVAL_EXP)

/* See Table 6.2 of the IA-64 Software Developer Manual, Volume 2.  */
#define BACKING_STORE_SIZE(N) ((N) > 0 ? ((N) + (N)/63 + 1) * 8 : 0)

/* Emit code to probe a range of stack addresses from FIRST to FIRST+SIZE,
   inclusive.  These are offsets from the current stack pointer.  BS_SIZE
   is the size of the backing store.  ??? This clobbers r2 and r3.  */

static void
ia64_emit_probe_stack_range (HOST_WIDE_INT first, HOST_WIDE_INT size,
			     int bs_size)
{
  rtx r2 = gen_rtx_REG (Pmode, GR_REG (2));
  rtx r3 = gen_rtx_REG (Pmode, GR_REG (3));
  rtx p6 = gen_rtx_REG (BImode, PR_REG (6));

  /* On the IA-64 there is a second stack in memory, namely the Backing Store
     of the Register Stack Engine.  We also need to probe it after checking
     that the 2 stacks don't overlap.  */
  emit_insn (gen_bsp_value (r3));
  emit_move_insn (r2, GEN_INT (-(first + size)));

  /* Compare current value of BSP and SP registers.  */
  emit_insn (gen_rtx_SET (p6, gen_rtx_fmt_ee (LTU, BImode,
					      r3, stack_pointer_rtx)));

  /* Compute the address of the probe for the Backing Store (which grows
     towards higher addresses).  We probe only at the first offset of
     the next page because some OS (eg Linux/ia64) only extend the
     backing store when this specific address is hit (but generate a SEGV
     on other address).  Page size is the worst case (4KB).  The reserve
     size is at least 4096 - (96 + 2) * 8 = 3312 bytes, which is enough.
     Also compute the address of the last probe for the memory stack
     (which grows towards lower addresses).  */
  emit_insn (gen_rtx_SET (r3, plus_constant (Pmode, r3, 4095)));
  emit_insn (gen_rtx_SET (r2, gen_rtx_PLUS (Pmode, stack_pointer_rtx, r2)));

  /* Compare them and raise SEGV if the former has topped the latter.  */
  emit_insn (gen_rtx_COND_EXEC (VOIDmode,
				gen_rtx_fmt_ee (NE, VOIDmode, p6, const0_rtx),
				gen_rtx_SET (p6, gen_rtx_fmt_ee (GEU, BImode,
								 r3, r2))));
  emit_insn (gen_rtx_SET (gen_rtx_ZERO_EXTRACT (DImode, r3, GEN_INT (12),
						const0_rtx),
			  const0_rtx));
  emit_insn (gen_rtx_COND_EXEC (VOIDmode,
				gen_rtx_fmt_ee (NE, VOIDmode, p6, const0_rtx),
				gen_rtx_TRAP_IF (VOIDmode, const1_rtx,
						 GEN_INT (11))));

  /* Probe the Backing Store if necessary.  */
  if (bs_size > 0)
    emit_stack_probe (r3);

  /* Probe the memory stack if necessary.  */
  if (size == 0)
    ;

  /* See if we have a constant small number of probes to generate.  If so,
     that's the easy case.  */
  else if (size <= PROBE_INTERVAL)
    emit_stack_probe (r2);

  /* The run-time loop is made up of 9 insns in the generic case while this
     compile-time loop is made up of 5+2*(n-2) insns for n # of intervals.  */
  else if (size <= 4 * PROBE_INTERVAL)
    {
      HOST_WIDE_INT i;

      emit_move_insn (r2, GEN_INT (-(first + PROBE_INTERVAL)));
      emit_insn (gen_rtx_SET (r2,
			      gen_rtx_PLUS (Pmode, stack_pointer_rtx, r2)));
      emit_stack_probe (r2);

      /* Probe at FIRST + N * PROBE_INTERVAL for values of N from 2 until
	 it exceeds SIZE.  If only two probes are needed, this will not
	 generate any code.  Then probe at FIRST + SIZE.  */
      for (i = 2 * PROBE_INTERVAL; i < size; i += PROBE_INTERVAL)
	{
	  emit_insn (gen_rtx_SET (r2,
				  plus_constant (Pmode, r2, -PROBE_INTERVAL)));
	  emit_stack_probe (r2);
	}

      emit_insn (gen_rtx_SET (r2,
			      plus_constant (Pmode, r2,
					     (i - PROBE_INTERVAL) - size)));
      emit_stack_probe (r2);
    }

  /* Otherwise, do the same as above, but in a loop.  Note that we must be
     extra careful with variables wrapping around because we might be at
     the very top (or the very bottom) of the address space and we have
     to be able to handle this case properly; in particular, we use an
     equality test for the loop condition.  */
  else
    {
      HOST_WIDE_INT rounded_size;

      emit_move_insn (r2, GEN_INT (-first));


      /* Step 1: round SIZE to the previous multiple of the interval.  */

      rounded_size = size & -PROBE_INTERVAL;


      /* Step 2: compute initial and final value of the loop counter.  */

      /* TEST_ADDR = SP + FIRST.  */
      emit_insn (gen_rtx_SET (r2,
			      gen_rtx_PLUS (Pmode, stack_pointer_rtx, r2)));

      /* LAST_ADDR = SP + FIRST + ROUNDED_SIZE.  */
      if (rounded_size > (1 << 21))
	{
	  emit_move_insn (r3, GEN_INT (-rounded_size));
	  emit_insn (gen_rtx_SET (r3, gen_rtx_PLUS (Pmode, r2, r3)));
	}
      else
        emit_insn (gen_rtx_SET (r3, gen_rtx_PLUS (Pmode, r2,
						  GEN_INT (-rounded_size))));


      /* Step 3: the loop

	 do
	   {
	     TEST_ADDR = TEST_ADDR + PROBE_INTERVAL
	     probe at TEST_ADDR
	   }
	 while (TEST_ADDR != LAST_ADDR)

	 probes at FIRST + N * PROBE_INTERVAL for values of N from 1
	 until it is equal to ROUNDED_SIZE.  */

      emit_insn (gen_probe_stack_range (r2, r2, r3));


      /* Step 4: probe at FIRST + SIZE if we cannot assert at compile-time
	 that SIZE is equal to ROUNDED_SIZE.  */

      /* TEMP = SIZE - ROUNDED_SIZE.  */
      if (size != rounded_size)
	{
	  emit_insn (gen_rtx_SET (r2, plus_constant (Pmode, r2,
						     rounded_size - size)));
	  emit_stack_probe (r2);
	}
    }

  /* Make sure nothing is scheduled before we are done.  */
  emit_insn (gen_blockage ());
}

/* Probe a range of stack addresses from REG1 to REG2 inclusive.  These are
   absolute addresses.  */

const char *
output_probe_stack_range (rtx reg1, rtx reg2)
{
  static int labelno = 0;
  char loop_lab[32];
  rtx xops[3];

  ASM_GENERATE_INTERNAL_LABEL (loop_lab, "LPSRL", labelno++);

  /* Loop.  */
  ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, loop_lab);

  /* TEST_ADDR = TEST_ADDR + PROBE_INTERVAL.  */
  xops[0] = reg1;
  xops[1] = GEN_INT (-PROBE_INTERVAL);
  output_asm_insn ("addl %0 = %1, %0", xops);
  fputs ("\t;;\n", asm_out_file);

  /* Probe at TEST_ADDR.  */
  output_asm_insn ("probe.w.fault %0, 0", xops);

  /* Test if TEST_ADDR == LAST_ADDR.  */
  xops[1] = reg2;
  xops[2] = gen_rtx_REG (BImode, PR_REG (6));
  output_asm_insn ("cmp.eq %2, %I2 = %0, %1", xops);

  /* Branch.  */
  fprintf (asm_out_file, "\t(%s) br.cond.dpnt ", reg_names [PR_REG (7)]);
  assemble_name_raw (asm_out_file, loop_lab);
  fputc ('\n', asm_out_file);

  return "";
}

/* Called after register allocation to add any instructions needed for the
   prologue.  Using a prologue insn is favored compared to putting all of the
   instructions in output_function_prologue(), since it allows the scheduler
   to intermix instructions with the saves of the caller saved registers.  In
   some cases, it might be necessary to emit a barrier instruction as the last
   insn to prevent such scheduling.

   Also any insns generated here should have RTX_FRAME_RELATED_P(insn) = 1
   so that the debug info generation code can handle them properly.

   The register save area is laid out like so:
   cfa+16
	[ varargs spill area ]
	[ fr register spill area ]
	[ br register spill area ]
	[ ar register spill area ]
	[ pr register spill area ]
	[ gr register spill area ] */

/* ??? Get inefficient code when the frame size is larger than can fit in an
   adds instruction.  */

void
ia64_expand_prologue (void)
{
  rtx_insn *insn;
  rtx ar_pfs_save_reg, ar_unat_save_reg;
  int i, epilogue_p, regno, alt_regno, cfa_off, n_varargs;
  rtx reg, alt_reg;

  ia64_compute_frame_size (get_frame_size ());
  last_scratch_gr_reg = 15;

  if (flag_stack_usage_info)
    current_function_static_stack_size = current_frame_info.total_size;

  if (flag_stack_check == STATIC_BUILTIN_STACK_CHECK
      || flag_stack_clash_protection)
    {
      HOST_WIDE_INT size = current_frame_info.total_size;
      int bs_size = BACKING_STORE_SIZE (current_frame_info.n_input_regs
					  + current_frame_info.n_local_regs);

      if (crtl->is_leaf && !cfun->calls_alloca)
	{
	  if (size > PROBE_INTERVAL && size > get_stack_check_protect ())
	    ia64_emit_probe_stack_range (get_stack_check_protect (),
					 size - get_stack_check_protect (),
					 bs_size);
	  else if (size + bs_size > get_stack_check_protect ())
	    ia64_emit_probe_stack_range (get_stack_check_protect (),
					 0, bs_size);
	}
      else if (size + bs_size > 0)
	ia64_emit_probe_stack_range (get_stack_check_protect (), size, bs_size);
    }

  if (dump_file) 
    {
      fprintf (dump_file, "ia64 frame related registers "
               "recorded in current_frame_info.r[]:\n");
#define PRINTREG(a) if (current_frame_info.r[a]) \
        fprintf(dump_file, "%s = %d\n", #a, current_frame_info.r[a])
      PRINTREG(reg_fp);
      PRINTREG(reg_save_b0);
      PRINTREG(reg_save_pr);
      PRINTREG(reg_save_ar_pfs);
      PRINTREG(reg_save_ar_unat);
      PRINTREG(reg_save_ar_lc);
      PRINTREG(reg_save_gp);
#undef PRINTREG
    }

  /* If there is no epilogue, then we don't need some prologue insns.
     We need to avoid emitting the dead prologue insns, because flow
     will complain about them.  */
  if (optimize)
    {
      edge e;
      edge_iterator ei;

      FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR_FOR_FN (cfun)->preds)
	if ((e->flags & EDGE_FAKE) == 0
	    && (e->flags & EDGE_FALLTHRU) != 0)
	  break;
      epilogue_p = (e != NULL);
    }
  else
    epilogue_p = 1;

  /* Set the local, input, and output register names.  We need to do this
     for GNU libc, which creates crti.S/crtn.S by splitting initfini.c in
     half.  If we use in/loc/out register names, then we get assembler errors
     in crtn.S because there is no alloc insn or regstk directive in there.  */
  if (! TARGET_REG_NAMES)
    {
      int inputs = current_frame_info.n_input_regs;
      int locals = current_frame_info.n_local_regs;
      int outputs = current_frame_info.n_output_regs;

      for (i = 0; i < inputs; i++)
	reg_names[IN_REG (i)] = ia64_reg_numbers[i];
      for (i = 0; i < locals; i++)
	reg_names[LOC_REG (i)] = ia64_reg_numbers[inputs + i];
      for (i = 0; i < outputs; i++)
	reg_names[OUT_REG (i)] = ia64_reg_numbers[inputs + locals + i];
    }

  /* Set the frame pointer register name.  The regnum is logically loc79,
     but of course we'll not have allocated that many locals.  Rather than
     worrying about renumbering the existing rtxs, we adjust the name.  */
  /* ??? This code means that we can never use one local register when
     there is a frame pointer.  loc79 gets wasted in this case, as it is
     renamed to a register that will never be used.  See also the try_locals
     code in find_gr_spill.  */
  if (current_frame_info.r[reg_fp])
    {
      const char *tmp = reg_names[HARD_FRAME_POINTER_REGNUM];
      reg_names[HARD_FRAME_POINTER_REGNUM]
	= reg_names[current_frame_info.r[reg_fp]];
      reg_names[current_frame_info.r[reg_fp]] = tmp;
    }

  /* We don't need an alloc instruction if we've used no outputs or locals.  */
  if (current_frame_info.n_local_regs == 0
      && current_frame_info.n_output_regs == 0
      && current_frame_info.n_input_regs <= crtl->args.info.int_regs
      && !TEST_HARD_REG_BIT (current_frame_info.mask, AR_PFS_REGNUM))
    {
      /* If there is no alloc, but there are input registers used, then we
	 need a .regstk directive.  */
      current_frame_info.need_regstk = (TARGET_REG_NAMES != 0);
      ar_pfs_save_reg = NULL_RTX;
    }
  else
    {
      current_frame_info.need_regstk = 0;

      if (current_frame_info.r[reg_save_ar_pfs])
        {
	  regno = current_frame_info.r[reg_save_ar_pfs];
	  reg_emitted (reg_save_ar_pfs);
	}
      else
	regno = next_scratch_gr_reg ();
      ar_pfs_save_reg = gen_rtx_REG (DImode, regno);

      insn = emit_insn (gen_alloc (ar_pfs_save_reg,
				   GEN_INT (current_frame_info.n_input_regs),
				   GEN_INT (current_frame_info.n_local_regs),
				   GEN_INT (current_frame_info.n_output_regs),
				   GEN_INT (current_frame_info.n_rotate_regs)));
      if (current_frame_info.r[reg_save_ar_pfs])
	{
	  RTX_FRAME_RELATED_P (insn) = 1;
	  add_reg_note (insn, REG_CFA_REGISTER,
			gen_rtx_SET (ar_pfs_save_reg,
				     gen_rtx_REG (DImode, AR_PFS_REGNUM)));
	}
    }

  /* Set up frame pointer, stack pointer, and spill iterators.  */

  n_varargs = cfun->machine->n_varargs;
  setup_spill_pointers (current_frame_info.n_spilled + n_varargs,
			stack_pointer_rtx, 0);

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

      /* Force the unwind info to recognize this as defining a new CFA,
	 rather than some temp register setup.  */
      add_reg_note (insn, REG_CFA_ADJUST_CFA, NULL_RTX);
    }

  if (current_frame_info.total_size != 0)
    {
      rtx frame_size_rtx = GEN_INT (- current_frame_info.total_size);
      rtx offset;

      if (satisfies_constraint_I (frame_size_rtx))
	offset = frame_size_rtx;
      else
	{
	  regno = next_scratch_gr_reg ();
	  offset = gen_rtx_REG (DImode, regno);
	  emit_move_insn (offset, frame_size_rtx);
	}

      insn = emit_insn (gen_adddi3 (stack_pointer_rtx,
				    stack_pointer_rtx, offset));

      if (! frame_pointer_needed)
	{
	  RTX_FRAME_RELATED_P (insn) = 1;
	  add_reg_note (insn, REG_CFA_ADJUST_CFA,
			gen_rtx_SET (stack_pointer_rtx,
				     gen_rtx_PLUS (DImode,
						   stack_pointer_rtx,
						   frame_size_rtx)));
	}

      /* ??? At this point we must generate a magic insn that appears to
	 modify the stack pointer, the frame pointer, and all spill
	 iterators.  This would allow the most scheduling freedom.  For
	 now, just hard stop.  */
      emit_insn (gen_blockage ());
    }

  /* Must copy out ar.unat before doing any integer spills.  */
  if (TEST_HARD_REG_BIT (current_frame_info.mask, AR_UNAT_REGNUM))
    {
      if (current_frame_info.r[reg_save_ar_unat])
        {
	  ar_unat_save_reg
	    = gen_rtx_REG (DImode, current_frame_info.r[reg_save_ar_unat]);
	  reg_emitted (reg_save_ar_unat);
	}
      else
	{
	  alt_regno = next_scratch_gr_reg ();
	  ar_unat_save_reg = gen_rtx_REG (DImode, alt_regno);
	  current_frame_info.gr_used_mask |= 1 << alt_regno;
	}

      reg = gen_rtx_REG (DImode, AR_UNAT_REGNUM);
      insn = emit_move_insn (ar_unat_save_reg, reg);
      if (current_frame_info.r[reg_save_ar_unat])
	{
	  RTX_FRAME_RELATED_P (insn) = 1;
	  add_reg_note (insn, REG_CFA_REGISTER, NULL_RTX);
	}

      /* Even if we're not going to generate an epilogue, we still
	 need to save the register so that EH works.  */
      if (! epilogue_p && current_frame_info.r[reg_save_ar_unat])
	emit_insn (gen_prologue_use (ar_unat_save_reg));
    }
  else
    ar_unat_save_reg = NULL_RTX;

  /* Spill all varargs registers.  Do this before spilling any GR registers,
     since we want the UNAT bits for the GR registers to override the UNAT
     bits from varargs, which we don't care about.  */

  cfa_off = -16;
  for (regno = GR_ARG_FIRST + 7; n_varargs > 0; --n_varargs, --regno)
    {
      reg = gen_rtx_REG (DImode, regno);
      do_spill (gen_gr_spill, reg, cfa_off += 8, NULL_RTX);
    }

  /* Locate the bottom of the register save area.  */
  cfa_off = (current_frame_info.spill_cfa_off
	     + current_frame_info.spill_size
	     + current_frame_info.extra_spill_size);

  /* Save the predicate register block either in a register or in memory.  */
  if (TEST_HARD_REG_BIT (current_frame_info.mask, PR_REG (0)))
    {
      reg = gen_rtx_REG (DImode, PR_REG (0));
      if (current_frame_info.r[reg_save_pr] != 0)
	{
	  alt_reg = gen_rtx_REG (DImode, current_frame_info.r[reg_save_pr]);
	  reg_emitted (reg_save_pr);
	  insn = emit_move_insn (alt_reg, reg);

	  /* ??? Denote pr spill/fill by a DImode move that modifies all
	     64 hard registers.  */
	  RTX_FRAME_RELATED_P (insn) = 1;
	  add_reg_note (insn, REG_CFA_REGISTER, NULL_RTX);

	  /* Even if we're not going to generate an epilogue, we still
	     need to save the register so that EH works.  */
	  if (! epilogue_p)
	    emit_insn (gen_prologue_use (alt_reg));
	}
      else
	{
	  alt_regno = next_scratch_gr_reg ();
	  alt_reg = gen_rtx_REG (DImode, alt_regno);
	  insn = emit_move_insn (alt_reg, reg);
	  do_spill (gen_movdi_x, alt_reg, cfa_off, reg);
	  cfa_off -= 8;
	}
    }

  /* Handle AR regs in numerical order.  All of them get special handling.  */
  if (TEST_HARD_REG_BIT (current_frame_info.mask, AR_UNAT_REGNUM)
      && current_frame_info.r[reg_save_ar_unat] == 0)
    {
      reg = gen_rtx_REG (DImode, AR_UNAT_REGNUM);
      do_spill (gen_movdi_x, ar_unat_save_reg, cfa_off, reg);
      cfa_off -= 8;
    }

  /* The alloc insn already copied ar.pfs into a general register.  The
     only thing we have to do now is copy that register to a stack slot
     if we'd not allocated a local register for the job.  */
  if (TEST_HARD_REG_BIT (current_frame_info.mask, AR_PFS_REGNUM)
      && current_frame_info.r[reg_save_ar_pfs] == 0)
    {
      reg = gen_rtx_REG (DImode, AR_PFS_REGNUM);
      do_spill (gen_movdi_x, ar_pfs_save_reg, cfa_off, reg);
      cfa_off -= 8;
    }

  if (TEST_HARD_REG_BIT (current_frame_info.mask, AR_LC_REGNUM))
    {
      reg = gen_rtx_REG (DImode, AR_LC_REGNUM);
      if (current_frame_info.r[reg_save_ar_lc] != 0)
	{
	  alt_reg = gen_rtx_REG (DImode, current_frame_info.r[reg_save_ar_lc]);
	  reg_emitted (reg_save_ar_lc);
	  insn = emit_move_insn (alt_reg, reg);
	  RTX_FRAME_RELATED_P (insn) = 1;
	  add_reg_note (insn, REG_CFA_REGISTER, NULL_RTX);

	  /* Even if we're not going to generate an epilogue, we still
	     need to save the register so that EH works.  */
	  if (! epilogue_p)
	    emit_insn (gen_prologue_use (alt_reg));
	}
      else
	{
	  alt_regno = next_scratch_gr_reg ();
	  alt_reg = gen_rtx_REG (DImode, alt_regno);
	  emit_move_insn (alt_reg, reg);
	  do_spill (gen_movdi_x, alt_reg, cfa_off, reg);
	  cfa_off -= 8;
	}
    }

  /* Save the return pointer.  */
  if (TEST_HARD_REG_BIT (current_frame_info.mask, BR_REG (0)))
    {
      reg = gen_rtx_REG (DImode, BR_REG (0));
      if (current_frame_info.r[reg_save_b0] != 0)
	{
          alt_reg = gen_rtx_REG (DImode, current_frame_info.r[reg_save_b0]);
          reg_emitted (reg_save_b0);
	  insn = emit_move_insn (alt_reg, reg);
	  RTX_FRAME_RELATED_P (insn) = 1;
	  add_reg_note (insn, REG_CFA_REGISTER, gen_rtx_SET (alt_reg, pc_rtx));

	  /* Even if we're not going to generate an epilogue, we still
	     need to save the register so that EH works.  */
	  if (! epilogue_p)
	    emit_insn (gen_prologue_use (alt_reg));
	}
      else
	{
	  alt_regno = next_scratch_gr_reg ();
	  alt_reg = gen_rtx_REG (DImode, alt_regno);
	  emit_move_insn (alt_reg, reg);
	  do_spill (gen_movdi_x, alt_reg, cfa_off, reg);
	  cfa_off -= 8;
	}
    }

  if (current_frame_info.r[reg_save_gp])
    {
      reg_emitted (reg_save_gp);
      insn = emit_move_insn (gen_rtx_REG (DImode,
					  current_frame_info.r[reg_save_gp]),
			     pic_offset_table_rtx);
    }

  /* We should now be at the base of the gr/br/fr spill area.  */
  gcc_assert (cfa_off == (current_frame_info.spill_cfa_off
			  + current_frame_info.spill_size));

  /* Spill all general registers.  */
  for (regno = GR_REG (1); regno <= GR_REG (31); ++regno)
    if (TEST_HARD_REG_BIT (current_frame_info.mask, regno))
      {
	reg = gen_rtx_REG (DImode, regno);
	do_spill (gen_gr_spill, reg, cfa_off, reg);
	cfa_off -= 8;
      }

  /* Spill the rest of the BR registers.  */
  for (regno = BR_REG (1); regno <= BR_REG (7); ++regno)
    if (TEST_HARD_REG_BIT (current_frame_info.mask, regno))
      {
	alt_regno = next_scratch_gr_reg ();
	alt_reg = gen_rtx_REG (DImode, alt_regno);
	reg = gen_rtx_REG (DImode, regno);
	emit_move_insn (alt_reg, reg);
	do_spill (gen_movdi_x, alt_reg, cfa_off, reg);
	cfa_off -= 8;
      }

  /* Align the frame and spill all FR registers.  */
  for (regno = FR_REG (2); regno <= FR_REG (127); ++regno)
    if (TEST_HARD_REG_BIT (current_frame_info.mask, regno))
      {
        gcc_assert (!(cfa_off & 15));
	reg = gen_rtx_REG (XFmode, regno);
	do_spill (gen_fr_spill_x, reg, cfa_off, reg);
	cfa_off -= 16;
      }

  gcc_assert (cfa_off == current_frame_info.spill_cfa_off);

  finish_spill_pointers ();
}

/* Output the textual info surrounding the prologue.  */

void
ia64_start_function (FILE *file, const char *fnname,
		     tree decl ATTRIBUTE_UNUSED)
{
#if TARGET_ABI_OPEN_VMS
  vms_start_function (fnname);
#endif

  fputs ("\t.proc ", file);
  assemble_name (file, fnname);
  fputc ('\n', file);
  ASM_OUTPUT_LABEL (file, fnname);
}

/* Called after register allocation to add any instructions needed for the
   epilogue.  Using an epilogue insn is favored compared to putting all of the
   instructions in output_function_prologue(), since it allows the scheduler
   to intermix instructions with the saves of the caller saved registers.  In
   some cases, it might be necessary to emit a barrier instruction as the last
   insn to prevent such scheduling.  */

void
ia64_expand_epilogue (int sibcall_p)
{
  rtx_insn *insn;
  rtx reg, alt_reg, ar_unat_save_reg;
  int regno, alt_regno, cfa_off;

  ia64_compute_frame_size (get_frame_size ());

  /* If there is a frame pointer, then we use it instead of the stack
     pointer, so that the stack pointer does not need to be valid when
     the epilogue starts.  See EXIT_IGNORE_STACK.  */
  if (frame_pointer_needed)
    setup_spill_pointers (current_frame_info.n_spilled,
			  hard_frame_pointer_rtx, 0);
  else
    setup_spill_pointers (current_frame_info.n_spilled, stack_pointer_rtx,
			  current_frame_info.total_size);

  if (current_frame_info.total_size != 0)
    {
      /* ??? At this point we must generate a magic insn that appears to
         modify the spill iterators and the frame pointer.  This would
	 allow the most scheduling freedom.  For now, just hard stop.  */
      emit_insn (gen_blockage ());
    }

  /* Locate the bottom of the register save area.  */
  cfa_off = (current_frame_info.spill_cfa_off
	     + current_frame_info.spill_size
	     + current_frame_info.extra_spill_size);

  /* Restore the predicate registers.  */
  if (TEST_HARD_REG_BIT (current_frame_info.mask, PR_REG (0)))
    {
      if (current_frame_info.r[reg_save_pr] != 0)
        {
	  alt_reg = gen_rtx_REG (DImode, current_frame_info.r[reg_save_pr]);
	  reg_emitted (reg_save_pr);
	}
      else
	{
	  alt_regno = next_scratch_gr_reg ();
	  alt_reg = gen_rtx_REG (DImode, alt_regno);
	  do_restore (gen_movdi_x, alt_reg, cfa_off);
	  cfa_off -= 8;
	}
      reg = gen_rtx_REG (DImode, PR_REG (0));
      emit_move_insn (reg, alt_reg);
    }

  /* Restore the application registers.  */

  /* Load the saved unat from the stack, but do not restore it until
     after the GRs have been restored.  */
  if (TEST_HARD_REG_BIT (current_frame_info.mask, AR_UNAT_REGNUM))
    {
      if (current_frame_info.r[reg_save_ar_unat] != 0)
        {
          ar_unat_save_reg
	    = gen_rtx_REG (DImode, current_frame_info.r[reg_save_ar_unat]);
	  reg_emitted (reg_save_ar_unat);
	}
      else
	{
	  alt_regno = next_scratch_gr_reg ();
	  ar_unat_save_reg = gen_rtx_REG (DImode, alt_regno);
	  current_frame_info.gr_used_mask |= 1 << alt_regno;
	  do_restore (gen_movdi_x, ar_unat_save_reg, cfa_off);
	  cfa_off -= 8;
	}
    }
  else
    ar_unat_save_reg = NULL_RTX;

  if (current_frame_info.r[reg_save_ar_pfs] != 0)
    {
      reg_emitted (reg_save_ar_pfs);
      alt_reg = gen_rtx_REG (DImode, current_frame_info.r[reg_save_ar_pfs]);
      reg = gen_rtx_REG (DImode, AR_PFS_REGNUM);
      emit_move_insn (reg, alt_reg);
    }
  else if (TEST_HARD_REG_BIT (current_frame_info.mask, AR_PFS_REGNUM))
    {
      alt_regno = next_scratch_gr_reg ();
      alt_reg = gen_rtx_REG (DImode, alt_regno);
      do_restore (gen_movdi_x, alt_reg, cfa_off);
      cfa_off -= 8;
      reg = gen_rtx_REG (DImode, AR_PFS_REGNUM);
      emit_move_insn (reg, alt_reg);
    }

  if (TEST_HARD_REG_BIT (current_frame_info.mask, AR_LC_REGNUM))
    {
      if (current_frame_info.r[reg_save_ar_lc] != 0)
        {
	  alt_reg = gen_rtx_REG (DImode, current_frame_info.r[reg_save_ar_lc]);
          reg_emitted (reg_save_ar_lc);
	}
      else
	{
	  alt_regno = next_scratch_gr_reg ();
	  alt_reg = gen_rtx_REG (DImode, alt_regno);
	  do_restore (gen_movdi_x, alt_reg, cfa_off);
	  cfa_off -= 8;
	}
      reg = gen_rtx_REG (DImode, AR_LC_REGNUM);
      emit_move_insn (reg, alt_reg);
    }

  /* Restore the return pointer.  */
  if (TEST_HARD_REG_BIT (current_frame_info.mask, BR_REG (0)))
    {
      if (current_frame_info.r[reg_save_b0] != 0)
        {
         alt_reg = gen_rtx_REG (DImode, current_frame_info.r[reg_save_b0]);
         reg_emitted (reg_save_b0);
        }
      else
	{
	  alt_regno = next_scratch_gr_reg ();
	  alt_reg = gen_rtx_REG (DImode, alt_regno);
	  do_restore (gen_movdi_x, alt_reg, cfa_off);
	  cfa_off -= 8;
	}
      reg = gen_rtx_REG (DImode, BR_REG (0));
      emit_move_insn (reg, alt_reg);
    }

  /* We should now be at the base of the gr/br/fr spill area.  */
  gcc_assert (cfa_off == (current_frame_info.spill_cfa_off
			  + current_frame_info.spill_size));

  /* The GP may be stored on the stack in the prologue, but it's
     never restored in the epilogue.  Skip the stack slot.  */
  if (TEST_HARD_REG_BIT (current_frame_info.mask, GR_REG (1)))
    cfa_off -= 8;

  /* Restore all general registers.  */
  for (regno = GR_REG (2); regno <= GR_REG (31); ++regno)
    if (TEST_HARD_REG_BIT (current_frame_info.mask, regno))
      {
	reg = gen_rtx_REG (DImode, regno);
	do_restore (gen_gr_restore, reg, cfa_off);
	cfa_off -= 8;
      }

  /* Restore the branch registers.  */
  for (regno = BR_REG (1); regno <= BR_REG (7); ++regno)
    if (TEST_HARD_REG_BIT (current_frame_info.mask, regno))
      {
	alt_regno = next_scratch_gr_reg ();
	alt_reg = gen_rtx_REG (DImode, alt_regno);
	do_restore (gen_movdi_x, alt_reg, cfa_off);
	cfa_off -= 8;
	reg = gen_rtx_REG (DImode, regno);
	emit_move_insn (reg, alt_reg);
      }

  /* Restore floating point registers.  */
  for (regno = FR_REG (2); regno <= FR_REG (127); ++regno)
    if (TEST_HARD_REG_BIT (current_frame_info.mask, regno))
      {
        gcc_assert (!(cfa_off & 15));
	reg = gen_rtx_REG (XFmode, regno);
	do_restore (gen_fr_restore_x, reg, cfa_off);
	cfa_off -= 16;
      }

  /* Restore ar.unat for real.  */
  if (TEST_HARD_REG_BIT (current_frame_info.mask, AR_UNAT_REGNUM))
    {
      reg = gen_rtx_REG (DImode, AR_UNAT_REGNUM);
      emit_move_insn (reg, ar_unat_save_reg);
    }

  gcc_assert (cfa_off == current_frame_info.spill_cfa_off);

  finish_spill_pointers ();

  if (current_frame_info.total_size
      || cfun->machine->ia64_eh_epilogue_sp
      || frame_pointer_needed)
    {
      /* ??? At this point we must generate a magic insn that appears to
         modify the spill iterators, the stack pointer, and the frame
	 pointer.  This would allow the most scheduling freedom.  For now,
	 just hard stop.  */
      emit_insn (gen_blockage ());
    }

  if (cfun->machine->ia64_eh_epilogue_sp)
    emit_move_insn (stack_pointer_rtx, cfun->machine->ia64_eh_epilogue_sp);
  else if (frame_pointer_needed)
    {
      insn = emit_move_insn (stack_pointer_rtx, hard_frame_pointer_rtx);
      RTX_FRAME_RELATED_P (insn) = 1;
      add_reg_note (insn, REG_CFA_ADJUST_CFA, NULL);
    }
  else if (current_frame_info.total_size)
    {
      rtx offset, frame_size_rtx;

      frame_size_rtx = GEN_INT (current_frame_info.total_size);
      if (satisfies_constraint_I (frame_size_rtx))
	offset = frame_size_rtx;
      else
	{
	  regno = next_scratch_gr_reg ();
	  offset = gen_rtx_REG (DImode, regno);
	  emit_move_insn (offset, frame_size_rtx);
	}

      insn = emit_insn (gen_adddi3 (stack_pointer_rtx, stack_pointer_rtx,
				    offset));

      RTX_FRAME_RELATED_P (insn) = 1;
      add_reg_note (insn, REG_CFA_ADJUST_CFA,
		    gen_rtx_SET (stack_pointer_rtx,
				 gen_rtx_PLUS (DImode,
					       stack_pointer_rtx,
					       frame_size_rtx)));
    }

  if (cfun->machine->ia64_eh_epilogue_bsp)
    emit_insn (gen_set_bsp (cfun->machine->ia64_eh_epilogue_bsp));

  if (! sibcall_p)
    emit_jump_insn (gen_return_internal (gen_rtx_REG (DImode, BR_REG (0))));
  else
    {
      int fp = GR_REG (2);
      /* We need a throw away register here, r0 and r1 are reserved,
	 so r2 is the first available call clobbered register.  If
	 there was a frame_pointer register, we may have swapped the
	 names of r2 and HARD_FRAME_POINTER_REGNUM, so we have to make
	 sure we're using the string "r2" when emitting the register
	 name for the assembler.  */
      if (current_frame_info.r[reg_fp] 
          && current_frame_info.r[reg_fp] == GR_REG (2))
	fp = HARD_FRAME_POINTER_REGNUM;

      /* We must emit an alloc to force the input registers to become output
	 registers.  Otherwise, if the callee tries to pass its parameters
	 through to another call without an intervening alloc, then these
	 values get lost.  */
      /* ??? We don't need to preserve all input registers.  We only need to
	 preserve those input registers used as arguments to the sibling call.
	 It is unclear how to compute that number here.  */
      if (current_frame_info.n_input_regs != 0)
	{
	  rtx n_inputs = GEN_INT (current_frame_info.n_input_regs);

	  insn = emit_insn (gen_alloc (gen_rtx_REG (DImode, fp),
				const0_rtx, const0_rtx,
				n_inputs, const0_rtx));
	  RTX_FRAME_RELATED_P (insn) = 1;

	  /* ??? We need to mark the alloc as frame-related so that it gets
	     passed into ia64_asm_unwind_emit for ia64-specific unwinding.
	     But there's nothing dwarf2 related to be done wrt the register
	     windows.  If we do nothing, dwarf2out will abort on the UNSPEC;
	     the empty parallel means dwarf2out will not see anything.  */
	  add_reg_note (insn, REG_FRAME_RELATED_EXPR,
			gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (0)));
	}
    }
}

/* Return 1 if br.ret can do all the work required to return from a
   function.  */

int
ia64_direct_return (void)
{
  if (reload_completed && ! frame_pointer_needed)
    {
      ia64_compute_frame_size (get_frame_size ());

      return (current_frame_info.total_size == 0
	      && current_frame_info.n_spilled == 0
	      && current_frame_info.r[reg_save_b0] == 0
	      && current_frame_info.r[reg_save_pr] == 0
	      && current_frame_info.r[reg_save_ar_pfs] == 0
	      && current_frame_info.r[reg_save_ar_unat] == 0
	      && current_frame_info.r[reg_save_ar_lc] == 0);
    }
  return 0;
}

/* Return the magic cookie that we use to hold the return address
   during early compilation.  */

rtx
ia64_return_addr_rtx (HOST_WIDE_INT count, rtx frame ATTRIBUTE_UNUSED)
{
  if (count != 0)
    return NULL;
  return gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx), UNSPEC_RET_ADDR);
}

/* Split this value after reload, now that we know where the return
   address is saved.  */

void
ia64_split_return_addr_rtx (rtx dest)
{
  rtx src;

  if (TEST_HARD_REG_BIT (current_frame_info.mask, BR_REG (0)))
    {
      if (current_frame_info.r[reg_save_b0] != 0)
        {
	  src = gen_rtx_REG (DImode, current_frame_info.r[reg_save_b0]);
	  reg_emitted (reg_save_b0);
	}
      else
	{
	  HOST_WIDE_INT off;
	  unsigned int regno;
	  rtx off_r;

	  /* Compute offset from CFA for BR0.  */
	  /* ??? Must be kept in sync with ia64_expand_prologue.  */
	  off = (current_frame_info.spill_cfa_off
		 + current_frame_info.spill_size);
	  for (regno = GR_REG (1); regno <= GR_REG (31); ++regno)
	    if (TEST_HARD_REG_BIT (current_frame_info.mask, regno))
	      off -= 8;

	  /* Convert CFA offset to a register based offset.  */
	  if (frame_pointer_needed)
	    src = hard_frame_pointer_rtx;
	  else
	    {
	      src = stack_pointer_rtx;
	      off += current_frame_info.total_size;
	    }

	  /* Load address into scratch register.  */
	  off_r = GEN_INT (off);
	  if (satisfies_constraint_I (off_r))
	    emit_insn (gen_adddi3 (dest, src, off_r));
	  else
	    {
	      emit_move_insn (dest, off_r);
	      emit_insn (gen_adddi3 (dest, src, dest));
	    }

	  src = gen_rtx_MEM (Pmode, dest);
	}
    }
  else
    src = gen_rtx_REG (DImode, BR_REG (0));

  emit_move_insn (dest, src);
}

int
ia64_hard_regno_rename_ok (int from, int to)
{
  /* Don't clobber any of the registers we reserved for the prologue.  */
  unsigned int r;

  for (r = reg_fp; r <= reg_save_ar_lc; r++)
    if (to == current_frame_info.r[r] 
        || from == current_frame_info.r[r]
        || to == emitted_frame_related_regs[r]
        || from == emitted_frame_related_regs[r])
      return 0;

  /* Don't use output registers outside the register frame.  */
  if (OUT_REGNO_P (to) && to >= OUT_REG (current_frame_info.n_output_regs))
    return 0;

  /* Retain even/oddness on predicate register pairs.  */
  if (PR_REGNO_P (from) && PR_REGNO_P (to))
    return (from & 1) == (to & 1);

  return 1;
}

/* Implement TARGET_HARD_REGNO_NREGS.

   ??? We say that BImode PR values require two registers.  This allows us to
   easily store the normal and inverted values.  We use CCImode to indicate
   a single predicate register.  */

static unsigned int
ia64_hard_regno_nregs (unsigned int regno, machine_mode mode)
{
  if (regno == PR_REG (0) && mode == DImode)
    return 64;
  if (PR_REGNO_P (regno) && (mode) == BImode)
    return 2;
  if ((PR_REGNO_P (regno) || GR_REGNO_P (regno)) && mode == CCImode)
    return 1;
  if (FR_REGNO_P (regno) && mode == XFmode)
    return 1;
  if (FR_REGNO_P (regno) && mode == RFmode)
    return 1;
  if (FR_REGNO_P (regno) && mode == XCmode)
    return 2;
  return CEIL (GET_MODE_SIZE (mode), UNITS_PER_WORD);
}

/* Implement TARGET_HARD_REGNO_MODE_OK.  */

static bool
ia64_hard_regno_mode_ok (unsigned int regno, machine_mode mode)
{
  if (FR_REGNO_P (regno))
    return (GET_MODE_CLASS (mode) != MODE_CC
	    && mode != BImode
	    && mode != TFmode);

  if (PR_REGNO_P (regno))
    return mode == BImode || GET_MODE_CLASS (mode) == MODE_CC;

  if (GR_REGNO_P (regno))
    return mode != XFmode && mode != XCmode && mode != RFmode;

  if (AR_REGNO_P (regno))
    return mode == DImode;

  if (BR_REGNO_P (regno))
    return mode == DImode;

  return false;
}

/* Implement TARGET_MODES_TIEABLE_P.

   Don't tie integer and FP modes, as that causes us to get integer registers
   allocated for FP instructions.  XFmode only supported in FP registers so
   we can't tie it with any other modes.  */

static bool
ia64_modes_tieable_p (machine_mode mode1, machine_mode mode2)
{
  return (GET_MODE_CLASS (mode1) == GET_MODE_CLASS (mode2)
	  && ((mode1 == XFmode || mode1 == XCmode || mode1 == RFmode)
	      == (mode2 == XFmode || mode2 == XCmode || mode2 == RFmode))
	  && (mode1 == BImode) == (mode2 == BImode));
}

/* Target hook for assembling integer objects.  Handle word-sized
   aligned objects and detect the cases when @fptr is needed.  */

static bool
ia64_assemble_integer (rtx x, unsigned int size, int aligned_p)
{
  if (size == POINTER_SIZE / BITS_PER_UNIT
      && !(TARGET_NO_PIC || TARGET_AUTO_PIC)
      && GET_CODE (x) == SYMBOL_REF
      && SYMBOL_REF_FUNCTION_P (x))
    {
      static const char * const directive[2][2] = {
	  /* 64-bit pointer */  /* 32-bit pointer */
	{ "\tdata8.ua\t@fptr(", "\tdata4.ua\t@fptr("},	/* unaligned */
	{ "\tdata8\t@fptr(",    "\tdata4\t@fptr("}	/* aligned */
      };
      fputs (directive[(aligned_p != 0)][POINTER_SIZE == 32], asm_out_file);
      output_addr_const (asm_out_file, x);
      fputs (")\n", asm_out_file);
      return true;
    }
  return default_assemble_integer (x, size, aligned_p);
}

/* Emit the function prologue.  */

static void
ia64_output_function_prologue (FILE *file)
{
  int mask, grsave, grsave_prev;

  if (current_frame_info.need_regstk)
    fprintf (file, "\t.regstk %d, %d, %d, %d\n",
	     current_frame_info.n_input_regs,
	     current_frame_info.n_local_regs,
	     current_frame_info.n_output_regs,
	     current_frame_info.n_rotate_regs);

  if (ia64_except_unwind_info (&global_options) != UI_TARGET)
    return;

  /* Emit the .prologue directive.  */

  mask = 0;
  grsave = grsave_prev = 0;
  if (current_frame_info.r[reg_save_b0] != 0)
    {
      mask |= 8;
      grsave = grsave_prev = current_frame_info.r[reg_save_b0];
    }
  if (current_frame_info.r[reg_save_ar_pfs] != 0
      && (grsave_prev == 0
	  || current_frame_info.r[reg_save_ar_pfs] == grsave_prev + 1))
    {
      mask |= 4;
      if (grsave_prev == 0)
	grsave = current_frame_info.r[reg_save_ar_pfs];
      grsave_prev = current_frame_info.r[reg_save_ar_pfs];
    }
  if (current_frame_info.r[reg_fp] != 0
      && (grsave_prev == 0
	  || current_frame_info.r[reg_fp] == grsave_prev + 1))
    {
      mask |= 2;
      if (grsave_prev == 0)
	grsave = HARD_FRAME_POINTER_REGNUM;
      grsave_prev = current_frame_info.r[reg_fp];
    }
  if (current_frame_info.r[reg_save_pr] != 0
      && (grsave_prev == 0
	  || current_frame_info.r[reg_save_pr] == grsave_prev + 1))
    {
      mask |= 1;
      if (grsave_prev == 0)
	grsave = current_frame_info.r[reg_save_pr];
    }

  if (mask && TARGET_GNU_AS)
    fprintf (file, "\t.prologue %d, %d\n", mask,
	     ia64_debugger_regno (grsave));
  else
    fputs ("\t.prologue\n", file);

  /* Emit a .spill directive, if necessary, to relocate the base of
     the register spill area.  */
  if (current_frame_info.spill_cfa_off != -16)
    fprintf (file, "\t.spill %ld\n",
	     (long) (current_frame_info.spill_cfa_off
		     + current_frame_info.spill_size));
}

/* Emit the .body directive at the scheduled end of the prologue.  */

static void
ia64_output_function_end_prologue (FILE *file)
{
  if (ia64_except_unwind_info (&global_options) != UI_TARGET)
    return;

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

/* Emit the function epilogue.  */

static void
ia64_output_function_epilogue (FILE *)
{
  int i;

  if (current_frame_info.r[reg_fp])
    {
      const char *tmp = reg_names[HARD_FRAME_POINTER_REGNUM];
      reg_names[HARD_FRAME_POINTER_REGNUM]
	= reg_names[current_frame_info.r[reg_fp]];
      reg_names[current_frame_info.r[reg_fp]] = tmp;
      reg_emitted (reg_fp);
    }
  if (! TARGET_REG_NAMES)
    {
      for (i = 0; i < current_frame_info.n_input_regs; i++)
	reg_names[IN_REG (i)] = ia64_input_reg_names[i];
      for (i = 0; i < current_frame_info.n_local_regs; i++)
	reg_names[LOC_REG (i)] = ia64_local_reg_names[i];
      for (i = 0; i < current_frame_info.n_output_regs; i++)
	reg_names[OUT_REG (i)] = ia64_output_reg_names[i];
    }

  current_frame_info.initialized = 0;
}

int
ia64_debugger_regno (int regno)
{
  /* In ia64_expand_prologue we quite literally renamed the frame pointer
     from its home at loc79 to something inside the register frame.  We
     must perform the same renumbering here for the debug info.  */
  if (current_frame_info.r[reg_fp])
    {
      if (regno == HARD_FRAME_POINTER_REGNUM)
	regno = current_frame_info.r[reg_fp];
      else if (regno == current_frame_info.r[reg_fp])
	regno = HARD_FRAME_POINTER_REGNUM;
    }

  if (IN_REGNO_P (regno))
    return 32 + regno - IN_REG (0);
  else if (LOC_REGNO_P (regno))
    return 32 + current_frame_info.n_input_regs + regno - LOC_REG (0);
  else if (OUT_REGNO_P (regno))
    return (32 + current_frame_info.n_input_regs
	    + current_frame_info.n_local_regs + regno - OUT_REG (0));
  else
    return regno;
}

/* Implement TARGET_TRAMPOLINE_INIT.

   The trampoline should set the static chain pointer to value placed
   into the trampoline and should branch to the specified routine.
   To make the normal indirect-subroutine calling convention work,
   the trampoline must look like a function descriptor; the first
   word being the target address and the second being the target's
   global pointer.

   We abuse the concept of a global pointer by arranging for it
   to point to the data we need to load.  The complete trampoline
   has the following form:

		+-------------------+ \
	TRAMP:	| __ia64_trampoline | |
		+-------------------+  > fake function descriptor
		| TRAMP+16          | |
		+-------------------+ /
		| target descriptor |
		+-------------------+
		| static link	    |
		+-------------------+
*/

static void
ia64_trampoline_init (rtx m_tramp, tree fndecl, rtx static_chain)
{
  rtx fnaddr = XEXP (DECL_RTL (fndecl), 0);
  rtx addr, addr_reg, tramp, eight = GEN_INT (8);

  /* The Intel assembler requires that the global __ia64_trampoline symbol
     be declared explicitly */
  if (!TARGET_GNU_AS)
    {
      static bool declared_ia64_trampoline = false;

      if (!declared_ia64_trampoline)
	{
	  declared_ia64_trampoline = true;
	  (*targetm.asm_out.globalize_label) (asm_out_file,
					      "__ia64_trampoline");
	}
    }

  /* Make sure addresses are Pmode even if we are in ILP32 mode. */
  addr = convert_memory_address (Pmode, XEXP (m_tramp, 0));
  fnaddr = convert_memory_address (Pmode, fnaddr);
  static_chain = convert_memory_address (Pmode, static_chain);

  /* Load up our iterator.  */
  addr_reg = copy_to_reg (addr);
  m_tramp = adjust_automodify_address (m_tramp, Pmode, addr_reg, 0);

  /* The first two words are the fake descriptor:
     __ia64_trampoline, ADDR+16.  */
  tramp = gen_rtx_SYMBOL_REF (Pmode, "__ia64_trampoline");
  if (TARGET_ABI_OPEN_VMS)
    {
      /* HP decided to break the ELF ABI on VMS (to deal with an ambiguity
	 in the Macro-32 compiler) and changed the semantics of the LTOFF22
	 relocation against function symbols to make it identical to the
	 LTOFF_FPTR22 relocation.  Emit the latter directly to stay within
	 strict ELF and dereference to get the bare code address.  */
      rtx reg = gen_reg_rtx (Pmode);
      SYMBOL_REF_FLAGS (tramp) |= SYMBOL_FLAG_FUNCTION;
      emit_move_insn (reg, tramp);
      emit_move_insn (reg, gen_rtx_MEM (Pmode, reg));
      tramp = reg;
   }
  emit_move_insn (m_tramp, tramp);
  emit_insn (gen_adddi3 (addr_reg, addr_reg, eight));
  m_tramp = adjust_automodify_address (m_tramp, VOIDmode, NULL, 8);

  emit_move_insn (m_tramp, force_reg (Pmode, plus_constant (Pmode, addr, 16)));
  emit_insn (gen_adddi3 (addr_reg, addr_reg, eight));
  m_tramp = adjust_automodify_address (m_tramp, VOIDmode, NULL, 8);

  /* The third word is the target descriptor.  */
  emit_move_insn (m_tramp, force_reg (Pmode, fnaddr));
  emit_insn (gen_adddi3 (addr_reg, addr_reg, eight));
  m_tramp = adjust_automodify_address (m_tramp, VOIDmode, NULL, 8);

  /* The fourth word is the static chain.  */
  emit_move_insn (m_tramp, static_chain);
}

/* Do any needed setup for a variadic function.  CUM has not been updated
   for the last named argument, which is given by ARG.

   We generate the actual spill instructions during prologue generation.  */

static void
ia64_setup_incoming_varargs (cumulative_args_t cum,
			     const function_arg_info &arg,
			     int *pretend_size,
			     int second_time ATTRIBUTE_UNUSED)
{
  CUMULATIVE_ARGS next_cum = *get_cumulative_args (cum);

  if (!TYPE_NO_NAMED_ARGS_STDARG_P (TREE_TYPE (current_function_decl)))
    /* Skip the current argument.  */
    ia64_function_arg_advance (pack_cumulative_args (&next_cum), arg);

  if (next_cum.words < MAX_ARGUMENT_SLOTS)
    {
      int n = MAX_ARGUMENT_SLOTS - next_cum.words;
      *pretend_size = n * UNITS_PER_WORD;
      cfun->machine->n_varargs = n;
    }
}

/* Check whether TYPE is a homogeneous floating point aggregate.  If
   it is, return the mode of the floating point type that appears
   in all leafs.  If it is not, return VOIDmode.

   An aggregate is a homogeneous floating point aggregate is if all
   fields/elements in it have the same floating point type (e.g,
   SFmode).  128-bit quad-precision floats are excluded.

   Variable sized aggregates should never arrive here, since we should
   have already decided to pass them by reference.  Top-level zero-sized
   aggregates are excluded because our parallels crash the middle-end.  */

static machine_mode
hfa_element_mode (const_tree type, bool nested)
{
  machine_mode element_mode = VOIDmode;
  machine_mode mode;
  enum tree_code code = TREE_CODE (type);
  int know_element_mode = 0;
  tree t;

  if (!nested && (!TYPE_SIZE (type) || integer_zerop (TYPE_SIZE (type))))
    return VOIDmode;

  switch (code)
    {
    case VOID_TYPE:	case INTEGER_TYPE:	case ENUMERAL_TYPE:
    case BOOLEAN_TYPE:	case POINTER_TYPE:
    case OFFSET_TYPE:	case REFERENCE_TYPE:	case METHOD_TYPE:
    case LANG_TYPE:		case FUNCTION_TYPE:
      return VOIDmode;

      /* Fortran complex types are supposed to be HFAs, so we need to handle
	 gcc's COMPLEX_TYPEs as HFAs.  We need to exclude the integral complex
	 types though.  */
    case COMPLEX_TYPE:
      if (GET_MODE_CLASS (TYPE_MODE (type)) == MODE_COMPLEX_FLOAT
	  && TYPE_MODE (type) != TCmode)
	return GET_MODE_INNER (TYPE_MODE (type));
      else
	return VOIDmode;

    case REAL_TYPE:
      /* We want to return VOIDmode for raw REAL_TYPEs, but the actual
	 mode if this is contained within an aggregate.  */
      if (nested && TYPE_MODE (type) != TFmode)
	return TYPE_MODE (type);
      else
	return VOIDmode;

    case ARRAY_TYPE:
      return hfa_element_mode (TREE_TYPE (type), 1);

    case RECORD_TYPE:
    case UNION_TYPE:
    case QUAL_UNION_TYPE:
      for (t = TYPE_FIELDS (type); t; t = DECL_CHAIN (t))
	{
	  if (TREE_CODE (t) != FIELD_DECL || DECL_FIELD_ABI_IGNORED (t))
	    continue;

	  mode = hfa_element_mode (TREE_TYPE (t), 1);
	  if (know_element_mode)
	    {
	      if (mode != element_mode)
		return VOIDmode;
	    }
	  else if (GET_MODE_CLASS (mode) != MODE_FLOAT)
	    return VOIDmode;
	  else
	    {
	      know_element_mode = 1;
	      element_mode = mode;
	    }
	}
      return element_mode;

    default:
      /* If we reach here, we probably have some front-end specific type
	 that the backend doesn't know about.  This can happen via the
	 aggregate_value_p call in init_function_start.  All we can do is
	 ignore unknown tree types.  */
      return VOIDmode;
    }

  return VOIDmode;
}

/* Return the number of words required to hold a quantity of TYPE and MODE
   when passed as an argument.  */
static int
ia64_function_arg_words (const_tree type, machine_mode mode)
{
  int words;

  if (mode == BLKmode)
    words = int_size_in_bytes (type);
  else
    words = GET_MODE_SIZE (mode);

  return (words + UNITS_PER_WORD - 1) / UNITS_PER_WORD;  /* round up */
}

/* Return the number of registers that should be skipped so the current
   argument (described by TYPE and WORDS) will be properly aligned.

   Integer and float arguments larger than 8 bytes start at the next
   even boundary.  Aggregates larger than 8 bytes start at the next
   even boundary if the aggregate has 16 byte alignment.  Note that
   in the 32-bit ABI, TImode and TFmode have only 8-byte alignment
   but are still to be aligned in registers.

   ??? The ABI does not specify how to handle aggregates with
   alignment from 9 to 15 bytes, or greater than 16.  We handle them
   all as if they had 16 byte alignment.  Such aggregates can occur
   only if gcc extensions are used.  */
static int
ia64_function_arg_offset (const CUMULATIVE_ARGS *cum,
			  const_tree type, int words)
{
  /* No registers are skipped on VMS.  */
  if (TARGET_ABI_OPEN_VMS || (cum->words & 1) == 0)
    return 0;

  if (type
      && TREE_CODE (type) != INTEGER_TYPE
      && TREE_CODE (type) != REAL_TYPE)
    return TYPE_ALIGN (type) > 8 * BITS_PER_UNIT;
  else
    return words > 1;
}

/* Return rtx for register where argument is passed, or zero if it is passed
   on the stack.  */
/* ??? 128-bit quad-precision floats are always passed in general
   registers.  */

static rtx
ia64_function_arg_1 (cumulative_args_t cum_v, const function_arg_info &arg,
		     bool incoming)
{
  const CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);

  int basereg = (incoming ? GR_ARG_FIRST : AR_ARG_FIRST);
  int words = ia64_function_arg_words (arg.type, arg.mode);
  int offset = ia64_function_arg_offset (cum, arg.type, words);
  machine_mode hfa_mode = VOIDmode;

  /* For OPEN VMS, emit the instruction setting up the argument register here,
     when we know this will be together with the other arguments setup related
     insns.  This is not the conceptually best place to do this, but this is
     the easiest as we have convenient access to cumulative args info.  */

  if (TARGET_ABI_OPEN_VMS && arg.end_marker_p ())
    {
      unsigned HOST_WIDE_INT regval = cum->words;
      int i;

      for (i = 0; i < 8; i++)
	regval |= ((int) cum->atypes[i]) << (i * 3 + 8);

      emit_move_insn (gen_rtx_REG (DImode, GR_REG (25)),
		      GEN_INT (regval));
    }

  /* If all argument slots are used, then it must go on the stack.  */
  if (cum->words + offset >= MAX_ARGUMENT_SLOTS)
    return 0;

  /* On OpenVMS argument is either in Rn or Fn.  */
  if (TARGET_ABI_OPEN_VMS)
    {
      if (FLOAT_MODE_P (arg.mode))
	return gen_rtx_REG (arg.mode, FR_ARG_FIRST + cum->words);
      else
	return gen_rtx_REG (arg.mode, basereg + cum->words);
    }

  /* Check for and handle homogeneous FP aggregates.  */
  if (arg.type)
    hfa_mode = hfa_element_mode (arg.type, 0);

  /* Unnamed prototyped hfas are passed as usual.  Named prototyped hfas
     and unprototyped hfas are passed specially.  */
  if (hfa_mode != VOIDmode && (! cum->prototype || arg.named))
    {
      rtx loc[16];
      int i = 0;
      int fp_regs = cum->fp_regs;
      int int_regs = cum->words + offset;
      int hfa_size = GET_MODE_SIZE (hfa_mode);
      int byte_size;
      int args_byte_size;

      /* If prototyped, pass it in FR regs then GR regs.
	 If not prototyped, pass it in both FR and GR regs.

	 If this is an SFmode aggregate, then it is possible to run out of
	 FR regs while GR regs are still left.  In that case, we pass the
	 remaining part in the GR regs.  */

      /* Fill the FP regs.  We do this always.  We stop if we reach the end
	 of the argument, the last FP register, or the last argument slot.  */

      byte_size = arg.promoted_size_in_bytes ();
      args_byte_size = int_regs * UNITS_PER_WORD;
      offset = 0;
      for (; (offset < byte_size && fp_regs < MAX_ARGUMENT_SLOTS
	      && args_byte_size < (MAX_ARGUMENT_SLOTS * UNITS_PER_WORD)); i++)
	{
	  loc[i] = gen_rtx_EXPR_LIST (VOIDmode,
				      gen_rtx_REG (hfa_mode, (FR_ARG_FIRST
							      + fp_regs)),
				      GEN_INT (offset));
	  offset += hfa_size;
	  args_byte_size += hfa_size;
	  fp_regs++;
	}

      /* If no prototype, then the whole thing must go in GR regs.  */
      if (! cum->prototype)
	offset = 0;
      /* If this is an SFmode aggregate, then we might have some left over
	 that needs to go in GR regs.  */
      else if (byte_size != offset)
	int_regs += offset / UNITS_PER_WORD;

      /* Fill in the GR regs.  We must use DImode here, not the hfa mode.  */

      for (; offset < byte_size && int_regs < MAX_ARGUMENT_SLOTS; i++)
	{
	  machine_mode gr_mode = DImode;
	  unsigned int gr_size;

	  /* If we have an odd 4 byte hunk because we ran out of FR regs,
	     then this goes in a GR reg left adjusted/little endian, right
	     adjusted/big endian.  */
	  /* ??? Currently this is handled wrong, because 4-byte hunks are
	     always right adjusted/little endian.  */
	  if (offset & 0x4)
	    gr_mode = SImode;
	  /* If we have an even 4 byte hunk because the aggregate is a
	     multiple of 4 bytes in size, then this goes in a GR reg right
	     adjusted/little endian.  */
	  else if (byte_size - offset == 4)
	    gr_mode = SImode;

	  loc[i] = gen_rtx_EXPR_LIST (VOIDmode,
				      gen_rtx_REG (gr_mode, (basereg
							     + int_regs)),
				      GEN_INT (offset));

	  gr_size = GET_MODE_SIZE (gr_mode);
	  offset += gr_size;
	  if (gr_size == UNITS_PER_WORD
	      || (gr_size < UNITS_PER_WORD && offset % UNITS_PER_WORD == 0))
	    int_regs++;
	  else if (gr_size > UNITS_PER_WORD)
	    int_regs += gr_size / UNITS_PER_WORD;
	}
      return gen_rtx_PARALLEL (arg.mode, gen_rtvec_v (i, loc));
    }
  
  /* Integral and aggregates go in general registers.  If we have run out of
     FR registers, then FP values must also go in general registers.  This can
     happen when we have a SFmode HFA.  */
  else if (arg.mode == TFmode || arg.mode == TCmode
	   || !FLOAT_MODE_P (arg.mode)
	   || cum->fp_regs == MAX_ARGUMENT_SLOTS)
    {
      int byte_size = arg.promoted_size_in_bytes ();
      if (BYTES_BIG_ENDIAN
	  && (arg.mode == BLKmode || arg.aggregate_type_p ())
	  && byte_size < UNITS_PER_WORD
	  && byte_size > 0)
	{
	  rtx gr_reg = gen_rtx_EXPR_LIST (VOIDmode,
					  gen_rtx_REG (DImode,
						       (basereg + cum->words
							+ offset)),
					  const0_rtx);
	  return gen_rtx_PARALLEL (arg.mode, gen_rtvec (1, gr_reg));
	}
      else
	return gen_rtx_REG (arg.mode, basereg + cum->words + offset);

    }

  /* If there is a prototype, then FP values go in a FR register when
     named, and in a GR register when unnamed.  */
  else if (cum->prototype)
    {
      if (arg.named)
	return gen_rtx_REG (arg.mode, FR_ARG_FIRST + cum->fp_regs);
      /* In big-endian mode, an anonymous SFmode value must be represented
         as (parallel:SF [(expr_list (reg:DI n) (const_int 0))]) to force
	 the value into the high half of the general register.  */
      else if (BYTES_BIG_ENDIAN && arg.mode == SFmode)
	return gen_rtx_PARALLEL (arg.mode,
		 gen_rtvec (1,
                   gen_rtx_EXPR_LIST (VOIDmode,
		     gen_rtx_REG (DImode, basereg + cum->words + offset),
				      const0_rtx)));
      else
	return gen_rtx_REG (arg.mode, basereg + cum->words + offset);
    }
  /* If there is no prototype, then FP values go in both FR and GR
     registers.  */
  else
    {
      /* See comment above.  */
      machine_mode inner_mode =
	(BYTES_BIG_ENDIAN && arg.mode == SFmode) ? DImode : arg.mode;

      rtx fp_reg = gen_rtx_EXPR_LIST (VOIDmode,
				      gen_rtx_REG (arg.mode, (FR_ARG_FIRST
							  + cum->fp_regs)),
				      const0_rtx);
      rtx gr_reg = gen_rtx_EXPR_LIST (VOIDmode,
				      gen_rtx_REG (inner_mode,
						   (basereg + cum->words
						    + offset)),
				      const0_rtx);

      return gen_rtx_PARALLEL (arg.mode, gen_rtvec (2, fp_reg, gr_reg));
    }
}

/* Implement TARGET_FUNCION_ARG target hook.  */

static rtx
ia64_function_arg (cumulative_args_t cum, const function_arg_info &arg)
{
  return ia64_function_arg_1 (cum, arg, false);
}

/* Implement TARGET_FUNCION_INCOMING_ARG target hook.  */

static rtx
ia64_function_incoming_arg (cumulative_args_t cum,
			    const function_arg_info &arg)
{
  return ia64_function_arg_1 (cum, arg, true);
}

/* Return number of bytes, at the beginning of the argument, that must be
   put in registers.  0 is the argument is entirely in registers or entirely
   in memory.  */

static int
ia64_arg_partial_bytes (cumulative_args_t cum_v, const function_arg_info &arg)
{
  CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);

  int words = ia64_function_arg_words (arg.type, arg.mode);
  int offset = ia64_function_arg_offset (cum, arg.type, words);

  /* If all argument slots are used, then it must go on the stack.  */
  if (cum->words + offset >= MAX_ARGUMENT_SLOTS)
    return 0;

  /* It doesn't matter whether the argument goes in FR or GR regs.  If
     it fits within the 8 argument slots, then it goes entirely in
     registers.  If it extends past the last argument slot, then the rest
     goes on the stack.  */

  if (words + cum->words + offset <= MAX_ARGUMENT_SLOTS)
    return 0;

  return (MAX_ARGUMENT_SLOTS - cum->words - offset) * UNITS_PER_WORD;
}

/* Return ivms_arg_type based on machine_mode.  */

static enum ivms_arg_type
ia64_arg_type (machine_mode mode)
{
  switch (mode)
    {
    case E_SFmode:
      return FS;
    case E_DFmode:
      return FT;
    default:
      return I64;
    }
}

/* Update CUM to point after this argument.  This is patterned after
   ia64_function_arg.  */

static void
ia64_function_arg_advance (cumulative_args_t cum_v,
			   const function_arg_info &arg)
{
  CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
  int words = ia64_function_arg_words (arg.type, arg.mode);
  int offset = ia64_function_arg_offset (cum, arg.type, words);
  machine_mode hfa_mode = VOIDmode;

  /* If all arg slots are already full, then there is nothing to do.  */
  if (cum->words >= MAX_ARGUMENT_SLOTS)
    {
      cum->words += words + offset;
      return;
    }

  cum->atypes[cum->words] = ia64_arg_type (arg.mode);
  cum->words += words + offset;

  /* On OpenVMS argument is either in Rn or Fn.  */
  if (TARGET_ABI_OPEN_VMS)
    {
      cum->int_regs = cum->words;
      cum->fp_regs = cum->words;
      return;
    }

  /* Check for and handle homogeneous FP aggregates.  */
  if (arg.type)
    hfa_mode = hfa_element_mode (arg.type, 0);

  /* Unnamed prototyped hfas are passed as usual.  Named prototyped hfas
     and unprototyped hfas are passed specially.  */
  if (hfa_mode != VOIDmode && (! cum->prototype || arg.named))
    {
      int fp_regs = cum->fp_regs;
      /* This is the original value of cum->words + offset.  */
      int int_regs = cum->words - words;
      int hfa_size = GET_MODE_SIZE (hfa_mode);
      int byte_size;
      int args_byte_size;

      /* If prototyped, pass it in FR regs then GR regs.
	 If not prototyped, pass it in both FR and GR regs.

	 If this is an SFmode aggregate, then it is possible to run out of
	 FR regs while GR regs are still left.  In that case, we pass the
	 remaining part in the GR regs.  */

      /* Fill the FP regs.  We do this always.  We stop if we reach the end
	 of the argument, the last FP register, or the last argument slot.  */

      byte_size = arg.promoted_size_in_bytes ();
      args_byte_size = int_regs * UNITS_PER_WORD;
      offset = 0;
      for (; (offset < byte_size && fp_regs < MAX_ARGUMENT_SLOTS
	      && args_byte_size < (MAX_ARGUMENT_SLOTS * UNITS_PER_WORD));)
	{
	  offset += hfa_size;
	  args_byte_size += hfa_size;
	  fp_regs++;
	}

      cum->fp_regs = fp_regs;
    }

  /* Integral and aggregates go in general registers.  So do TFmode FP values.
     If we have run out of FR registers, then other FP values must also go in
     general registers.  This can happen when we have a SFmode HFA.  */
  else if (arg.mode == TFmode || arg.mode == TCmode
           || !FLOAT_MODE_P (arg.mode)
	   || cum->fp_regs == MAX_ARGUMENT_SLOTS)
    cum->int_regs = cum->words;

  /* If there is a prototype, then FP values go in a FR register when
     named, and in a GR register when unnamed.  */
  else if (cum->prototype)
    {
      if (! arg.named)
	cum->int_regs = cum->words;
      else
	/* ??? Complex types should not reach here.  */
	cum->fp_regs
	  += (GET_MODE_CLASS (arg.mode) == MODE_COMPLEX_FLOAT ? 2 : 1);
    }
  /* If there is no prototype, then FP values go in both FR and GR
     registers.  */
  else
    {
      /* ??? Complex types should not reach here.  */
      cum->fp_regs
	+= (GET_MODE_CLASS (arg.mode) == MODE_COMPLEX_FLOAT ? 2 : 1);
      cum->int_regs = cum->words;
    }
}

/* Arguments with alignment larger than 8 bytes start at the next even
   boundary.  On ILP32 HPUX, TFmode arguments start on next even boundary
   even though their normal alignment is 8 bytes.  See ia64_function_arg.  */

static unsigned int
ia64_function_arg_boundary (machine_mode mode, const_tree type)
{
  if (mode == TFmode && TARGET_HPUX && TARGET_ILP32)
    return PARM_BOUNDARY * 2;

  if (type)
    {
      if (TYPE_ALIGN (type) > PARM_BOUNDARY)
        return PARM_BOUNDARY * 2;
      else
        return PARM_BOUNDARY;
    }

  if (GET_MODE_BITSIZE (mode) > PARM_BOUNDARY)
    return PARM_BOUNDARY * 2;
  else
    return PARM_BOUNDARY;
}

/* True if it is OK to do sibling call optimization for the specified
   call expression EXP.  DECL will be the called function, or NULL if
   this is an indirect call.  */
static bool
ia64_function_ok_for_sibcall (tree decl, tree exp ATTRIBUTE_UNUSED)
{
  /* We can't perform a sibcall if the current function has the syscall_linkage
     attribute.  */
  if (lookup_attribute ("syscall_linkage",
			TYPE_ATTRIBUTES (TREE_TYPE (current_function_decl))))
    return false;

  /* We must always return with our current GP.  This means we can
     only sibcall to functions defined in the current module unless
     TARGET_CONST_GP is set to true.  */
  return (decl && (*targetm.binds_local_p) (decl)) || TARGET_CONST_GP;
}


/* Implement va_arg.  */

static tree
ia64_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p,
		      gimple_seq *post_p)
{
  /* Variable sized types are passed by reference.  */
  if (pass_va_arg_by_reference (type))
    {
      tree ptrtype = build_pointer_type (type);
      tree addr = std_gimplify_va_arg_expr (valist, ptrtype, pre_p, post_p);
      return build_va_arg_indirect_ref (addr);
    }

  /* Aggregate arguments with alignment larger than 8 bytes start at
     the next even boundary.  Integer and floating point arguments
     do so if they are larger than 8 bytes, whether or not they are
     also aligned larger than 8 bytes.  */
  if ((TREE_CODE (type) == REAL_TYPE || TREE_CODE (type) == INTEGER_TYPE)
      ? int_size_in_bytes (type) > 8 : TYPE_ALIGN (type) > 8 * BITS_PER_UNIT)
    {
      tree t = fold_build_pointer_plus_hwi (valist, 2 * UNITS_PER_WORD - 1);
      t = build2 (BIT_AND_EXPR, TREE_TYPE (t), t,
		  build_int_cst (TREE_TYPE (t), -2 * UNITS_PER_WORD));
      gimplify_assign (unshare_expr (valist), t, pre_p);
    }

  return std_gimplify_va_arg_expr (valist, type, pre_p, post_p);
}

/* Return 1 if function return value returned in memory.  Return 0 if it is
   in a register.  */

static bool
ia64_return_in_memory (const_tree valtype, const_tree fntype ATTRIBUTE_UNUSED)
{
  machine_mode mode;
  machine_mode hfa_mode;
  HOST_WIDE_INT byte_size;

  mode = TYPE_MODE (valtype);
  byte_size = GET_MODE_SIZE (mode);
  if (mode == BLKmode)
    {
      byte_size = int_size_in_bytes (valtype);
      if (byte_size < 0)
	return true;
    }

  /* Hfa's with up to 8 elements are returned in the FP argument registers.  */

  hfa_mode = hfa_element_mode (valtype, 0);
  if (hfa_mode != VOIDmode)
    {
      int hfa_size = GET_MODE_SIZE (hfa_mode);

      if (byte_size / hfa_size > MAX_ARGUMENT_SLOTS)
	return true;
      else
	return false;
    }
  else if (byte_size > UNITS_PER_WORD * MAX_INT_RETURN_SLOTS)
    return true;
  else
    return false;
}

/* Return rtx for register that holds the function return value.  */

static rtx
ia64_function_value (const_tree valtype,
		     const_tree fn_decl_or_type,
		     bool outgoing ATTRIBUTE_UNUSED)
{
  machine_mode mode;
  machine_mode hfa_mode;
  int unsignedp;
  const_tree func = fn_decl_or_type;

  if (fn_decl_or_type
      && !DECL_P (fn_decl_or_type))
    func = NULL;
  
  mode = TYPE_MODE (valtype);
  hfa_mode = hfa_element_mode (valtype, 0);

  if (hfa_mode != VOIDmode)
    {
      rtx loc[8];
      int i;
      int hfa_size;
      int byte_size;
      int offset;

      hfa_size = GET_MODE_SIZE (hfa_mode);
      byte_size = ((mode == BLKmode)
		   ? int_size_in_bytes (valtype) : GET_MODE_SIZE (mode));
      offset = 0;
      for (i = 0; offset < byte_size; i++)
	{
	  loc[i] = gen_rtx_EXPR_LIST (VOIDmode,
				      gen_rtx_REG (hfa_mode, FR_ARG_FIRST + i),
				      GEN_INT (offset));
	  offset += hfa_size;
	}
      return gen_rtx_PARALLEL (mode, gen_rtvec_v (i, loc));
    }
  else if (FLOAT_TYPE_P (valtype) && mode != TFmode && mode != TCmode)
    return gen_rtx_REG (mode, FR_ARG_FIRST);
  else
    {
      bool need_parallel = false;

      /* In big-endian mode, we need to manage the layout of aggregates
	 in the registers so that we get the bits properly aligned in
	 the highpart of the registers.  */
      if (BYTES_BIG_ENDIAN
	  && (mode == BLKmode || (valtype && AGGREGATE_TYPE_P (valtype))))
	need_parallel = true;

      /* Something like struct S { long double x; char a[0] } is not an
	 HFA structure, and therefore doesn't go in fp registers.  But
	 the middle-end will give it XFmode anyway, and XFmode values
	 don't normally fit in integer registers.  So we need to smuggle
	 the value inside a parallel.  */
      else if (mode == XFmode || mode == XCmode || mode == RFmode)
	need_parallel = true;

      if (need_parallel)
	{
	  rtx loc[8];
	  int offset;
	  int bytesize;
	  int i;

	  offset = 0;
	  bytesize = int_size_in_bytes (valtype);
	  /* An empty PARALLEL is invalid here, but the return value
	     doesn't matter for empty structs.  */
	  if (bytesize == 0)
	    return gen_rtx_REG (mode, GR_RET_FIRST);
	  for (i = 0; offset < bytesize; i++)
	    {
	      loc[i] = gen_rtx_EXPR_LIST (VOIDmode,
					  gen_rtx_REG (DImode,
						       GR_RET_FIRST + i),
					  GEN_INT (offset));
	      offset += UNITS_PER_WORD;
	    }
	  return gen_rtx_PARALLEL (mode, gen_rtvec_v (i, loc));
	}

      mode = promote_function_mode (valtype, mode, &unsignedp,
                                    func ? TREE_TYPE (func) : NULL_TREE,
                                    true);

      return gen_rtx_REG (mode, GR_RET_FIRST);
    }
}

/* Worker function for TARGET_LIBCALL_VALUE.  */

static rtx
ia64_libcall_value (machine_mode mode,
		    const_rtx fun ATTRIBUTE_UNUSED)
{
  return gen_rtx_REG (mode,
		      (((GET_MODE_CLASS (mode) == MODE_FLOAT
			 || GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT)
			&& (mode) != TFmode)
		       ? FR_RET_FIRST : GR_RET_FIRST));
}

/* Worker function for FUNCTION_VALUE_REGNO_P.  */

static bool
ia64_function_value_regno_p (const unsigned int regno)
{
  return ((regno >= GR_RET_FIRST && regno <= GR_RET_LAST)
          || (regno >= FR_RET_FIRST && regno <= FR_RET_LAST));
}

/* This is called from dwarf2out.cc via TARGET_ASM_OUTPUT_DWARF_DTPREL.
   We need to emit DTP-relative relocations.  */

static void
ia64_output_dwarf_dtprel (FILE *file, int size, rtx x)
{
  gcc_assert (size == 4 || size == 8);
  if (size == 4)
    fputs ("\tdata4.ua\t@dtprel(", file);
  else
    fputs ("\tdata8.ua\t@dtprel(", file);
  output_addr_const (file, x);
  fputs (")", file);
}

/* Print a memory address as an operand to reference that memory location.  */

/* ??? Do we need this?  It gets used only for 'a' operands.  We could perhaps
   also call this from ia64_print_operand for memory addresses.  */

static void
ia64_print_operand_address (FILE * stream ATTRIBUTE_UNUSED,
			    machine_mode /*mode*/,
			    rtx address ATTRIBUTE_UNUSED)
{
}

/* Print an operand to an assembler instruction.
   C	Swap and print a comparison operator.
   D	Print an FP comparison operator.
   E    Print 32 - constant, for SImode shifts as extract.
   e    Print 64 - constant, for DImode rotates.
   F	A floating point constant 0.0 emitted as f0, or 1.0 emitted as f1, or
        a floating point register emitted normally.
   G	A floating point constant.
   I	Invert a predicate register by adding 1.
   J    Select the proper predicate register for a condition.
   j    Select the inverse predicate register for a condition.
   O	Append .acq for volatile load.
   P	Postincrement of a MEM.
   Q	Append .rel for volatile store.
   R	Print .s .d or nothing for a single, double or no truncation.
   S	Shift amount for shladd instruction.
   T	Print an 8-bit sign extended number (K) as a 32-bit unsigned number
	for Intel assembler.
   U	Print an 8-bit sign extended number (K) as a 64-bit unsigned number
	for Intel assembler.
   X	A pair of floating point registers.
   r	Print register name, or constant 0 as r0.  HP compatibility for
	Linux kernel.
   v    Print vector constant value as an 8-byte integer value.  */

static void
ia64_print_operand (FILE * file, rtx x, int code)
{
  const char *str;

  switch (code)
    {
    case 0:
      /* Handled below.  */
      break;

    case 'C':
      {
	enum rtx_code c = swap_condition (GET_CODE (x));
	fputs (GET_RTX_NAME (c), file);
	return;
      }

    case 'D':
      switch (GET_CODE (x))
	{
	case NE:
	  str = "neq";
	  break;
	case UNORDERED:
	  str = "unord";
	  break;
	case ORDERED:
	  str = "ord";
	  break;
	case UNLT:
	  str = "nge";
	  break;
	case UNLE:
	  str = "ngt";
	  break;
	case UNGT:
	  str = "nle";
	  break;
	case UNGE:
	  str = "nlt";
	  break;
	case UNEQ:
	case LTGT:
	  gcc_unreachable ();
	default:
	  str = GET_RTX_NAME (GET_CODE (x));
	  break;
	}
      fputs (str, file);
      return;

    case 'E':
      fprintf (file, HOST_WIDE_INT_PRINT_DEC, 32 - INTVAL (x));
      return;

    case 'e':
      fprintf (file, HOST_WIDE_INT_PRINT_DEC, 64 - INTVAL (x));
      return;

    case 'F':
      if (x == CONST0_RTX (GET_MODE (x)))
	str = reg_names [FR_REG (0)];
      else if (x == CONST1_RTX (GET_MODE (x)))
	str = reg_names [FR_REG (1)];
      else
	{
	  gcc_assert (GET_CODE (x) == REG);
	  str = reg_names [REGNO (x)];
	}
      fputs (str, file);
      return;

    case 'G':
      {
	long val[4];
	real_to_target (val, CONST_DOUBLE_REAL_VALUE (x), GET_MODE (x));
	if (GET_MODE (x) == SFmode)
	  fprintf (file, "0x%08lx", val[0] & 0xffffffff);
	else if (GET_MODE (x) == DFmode)
	  fprintf (file, "0x%08lx%08lx", (WORDS_BIG_ENDIAN ? val[0] : val[1])
					  & 0xffffffff,
					 (WORDS_BIG_ENDIAN ? val[1] : val[0])
					  & 0xffffffff);
	else
	  output_operand_lossage ("invalid %%G mode");
      }
      return;

    case 'I':
      fputs (reg_names [REGNO (x) + 1], file);
      return;

    case 'J':
    case 'j':
      {
	unsigned int regno = REGNO (XEXP (x, 0));
	if (GET_CODE (x) == EQ)
	  regno += 1;
	if (code == 'j')
	  regno ^= 1;
        fputs (reg_names [regno], file);
      }
      return;

    case 'O':
      if (MEM_VOLATILE_P (x))
	fputs(".acq", file);
      return;

    case 'P':
      {
	HOST_WIDE_INT value;

	switch (GET_CODE (XEXP (x, 0)))
	  {
	  default:
	    return;

	  case POST_MODIFY:
	    x = XEXP (XEXP (XEXP (x, 0), 1), 1);
	    if (GET_CODE (x) == CONST_INT)
	      value = INTVAL (x);
	    else
	      {
		gcc_assert (GET_CODE (x) == REG);
		fprintf (file, ", %s", reg_names[REGNO (x)]);
		return;
	      }
	    break;

	  case POST_INC:
	    value = GET_MODE_SIZE (GET_MODE (x));
	    break;

	  case POST_DEC:
	    value = - (HOST_WIDE_INT) GET_MODE_SIZE (GET_MODE (x));
	    break;
	  }

	fprintf (file, ", " HOST_WIDE_INT_PRINT_DEC, value);
	return;
      }

    case 'Q':
      if (MEM_VOLATILE_P (x))
	fputs(".rel", file);
      return;

    case 'R':
      if (x == CONST0_RTX (GET_MODE (x)))
	fputs(".s", file);
      else if (x == CONST1_RTX (GET_MODE (x)))
	fputs(".d", file);
      else if (x == CONST2_RTX (GET_MODE (x)))
	;
      else
	output_operand_lossage ("invalid %%R value");
      return;

    case 'S':
      fprintf (file, "%d", exact_log2 (INTVAL (x)));
      return;

    case 'T':
      if (! TARGET_GNU_AS && GET_CODE (x) == CONST_INT)
	{
	  fprintf (file, "0x%x", (int) INTVAL (x) & 0xffffffff);
	  return;
	}
      break;

    case 'U':
      if (! TARGET_GNU_AS && GET_CODE (x) == CONST_INT)
	{
	  const char *prefix = "0x";
	  if (INTVAL (x) & 0x80000000)
	    {
	      fprintf (file, "0xffffffff");
	      prefix = "";
	    }
	  fprintf (file, "%s%x", prefix, (int) INTVAL (x) & 0xffffffff);
	  return;
	}
      break;

    case 'X':
      {
	unsigned int regno = REGNO (x);
	fprintf (file, "%s, %s", reg_names [regno], reg_names [regno + 1]);
      }
      return;

    case 'r':
      /* If this operand is the constant zero, write it as register zero.
	 Any register, zero, or CONST_INT value is OK here.  */
      if (GET_CODE (x) == REG)
	fputs (reg_names[REGNO (x)], file);
      else if (x == CONST0_RTX (GET_MODE (x)))
	fputs ("r0", file);
      else if (GET_CODE (x) == CONST_INT)
	output_addr_const (file, x);
      else
	output_operand_lossage ("invalid %%r value");
      return;

    case 'v':
      gcc_assert (GET_CODE (x) == CONST_VECTOR);
      x = simplify_subreg (DImode, x, GET_MODE (x), 0);
      break;

    case '+':
      {
	const char *which;

	/* For conditional branches, returns or calls, substitute
	   sptk, dptk, dpnt, or spnt for %s.  */
	x = find_reg_note (current_output_insn, REG_BR_PROB, 0);
	if (x)
	  {
	    int pred_val = profile_probability::from_reg_br_prob_note
				 (XINT (x, 0)).to_reg_br_prob_base ();

	    /* Guess top and bottom 10% statically predicted.  */
	    if (pred_val < REG_BR_PROB_BASE / 50
		&& br_prob_note_reliable_p (x))
	      which = ".spnt";
	    else if (pred_val < REG_BR_PROB_BASE / 2)
	      which = ".dpnt";
	    else if (pred_val < REG_BR_PROB_BASE / 100 * 98
		     || !br_prob_note_reliable_p (x))
	      which = ".dptk";
	    else
	      which = ".sptk";
	  }
	else if (CALL_P (current_output_insn))
	  which = ".sptk";
	else
	  which = ".dptk";

	fputs (which, file);
	return;
      }

    case ',':
      x = current_insn_predicate;
      if (x)
	{
	  unsigned int regno = REGNO (XEXP (x, 0));
	  if (GET_CODE (x) == EQ)
	    regno += 1;
          fprintf (file, "(%s) ", reg_names [regno]);
	}
      return;

    default:
      output_operand_lossage ("ia64_print_operand: unknown code");
      return;
    }

  switch (GET_CODE (x))
    {
      /* This happens for the spill/restore instructions.  */
    case POST_INC:
    case POST_DEC:
    case POST_MODIFY:
      x = XEXP (x, 0);
      /* fall through */

    case REG:
      fputs (reg_names [REGNO (x)], file);
      break;

    case MEM:
      {
	rtx addr = XEXP (x, 0);
	if (GET_RTX_CLASS (GET_CODE (addr)) == RTX_AUTOINC)
	  addr = XEXP (addr, 0);
	fprintf (file, "[%s]", reg_names [REGNO (addr)]);
	break;
      }

    default:
      output_addr_const (file, x);
      break;
    }

  return;
}

/* Worker function for TARGET_PRINT_OPERAND_PUNCT_VALID_P.  */

static bool
ia64_print_operand_punct_valid_p (unsigned char code)
{
  return (code == '+' || code == ',');
}

/* 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.  */
/* ??? This is incomplete.  */

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

  switch (code)
    {
    case CONST_INT:
      switch (outer_code)
        {
        case SET:
	  *total = satisfies_constraint_J (x) ? 0 : COSTS_N_INSNS (1);
	  return true;
        case PLUS:
	  if (satisfies_constraint_I (x))
	    *total = 0;
	  else if (satisfies_constraint_J (x))
	    *total = 1;
	  else
	    *total = COSTS_N_INSNS (1);
	  return true;
        default:
	  if (satisfies_constraint_K (x) || satisfies_constraint_L (x))
	    *total = 0;
	  else
	    *total = COSTS_N_INSNS (1);
	  return true;
	}

    case CONST_DOUBLE:
      *total = COSTS_N_INSNS (1);
      return true;

    case CONST:
    case SYMBOL_REF:
    case LABEL_REF:
      *total = COSTS_N_INSNS (3);
      return true;

    case FMA:
      *total = COSTS_N_INSNS (4);
      return true;

    case MULT:
      /* For multiplies wider than HImode, we have to go to the FPU,
         which normally involves copies.  Plus there's the latency
         of the multiply itself, and the latency of the instructions to
         transfer integer regs to FP regs.  */
      if (FLOAT_MODE_P (mode))
	*total = COSTS_N_INSNS (4);
      else if (GET_MODE_SIZE (mode) > 2)
        *total = COSTS_N_INSNS (10);
      else
	*total = COSTS_N_INSNS (2);
      return true;

    case PLUS:
    case MINUS:
      if (FLOAT_MODE_P (mode))
	{
	  *total = COSTS_N_INSNS (4);
	  return true;
	}
      /* FALLTHRU */

    case ASHIFT:
    case ASHIFTRT:
    case LSHIFTRT:
      *total = COSTS_N_INSNS (1);
      return true;

    case DIV:
    case UDIV:
    case MOD:
    case UMOD:
      /* We make divide expensive, so that divide-by-constant will be
         optimized to a multiply.  */
      *total = COSTS_N_INSNS (60);
      return true;

    default:
      return false;
    }
}

/* Calculate the cost of moving data from a register in class FROM to
   one in class TO, using MODE.  */

static int
ia64_register_move_cost (machine_mode mode, reg_class_t from,
			 reg_class_t to)
{
  /* ADDL_REGS is the same as GR_REGS for movement purposes.  */
  if (to == ADDL_REGS)
    to = GR_REGS;
  if (from == ADDL_REGS)
    from = GR_REGS;

  /* All costs are symmetric, so reduce cases by putting the
     lower number class as the destination.  */
  if (from < to)
    {
      reg_class_t tmp = to;
      to = from, from = tmp;
    }

  /* Moving from FR<->GR in XFmode must be more expensive than 2,
     so that we get secondary memory reloads.  Between FR_REGS,
     we have to make this at least as expensive as memory_move_cost
     to avoid spectacularly poor register class preferencing.  */
  if (mode == XFmode || mode == RFmode)
    {
      if (to != GR_REGS || from != GR_REGS)
        return memory_move_cost (mode, to, false);
      else
	return 3;
    }

  switch (to)
    {
    case PR_REGS:
      /* Moving between PR registers takes two insns.  */
      if (from == PR_REGS)
	return 3;
      /* Moving between PR and anything but GR is impossible.  */
      if (from != GR_REGS)
	return memory_move_cost (mode, to, false);
      break;

    case BR_REGS:
      /* Moving between BR and anything but GR is impossible.  */
      if (from != GR_REGS && from != GR_AND_BR_REGS)
	return memory_move_cost (mode, to, false);
      break;

    case AR_I_REGS:
    case AR_M_REGS:
      /* Moving between AR and anything but GR is impossible.  */
      if (from != GR_REGS)
	return memory_move_cost (mode, to, false);
      break;

    case GR_REGS:
    case FR_REGS:
    case FP_REGS:
    case GR_AND_FR_REGS:
    case GR_AND_BR_REGS:
    case ALL_REGS:
      break;

    default:
      gcc_unreachable ();
    }

  return 2;
}

/* Calculate the cost of moving data of MODE from a register to or from
   memory.  */

static int
ia64_memory_move_cost (machine_mode mode ATTRIBUTE_UNUSED,
		       reg_class_t rclass,
		       bool in ATTRIBUTE_UNUSED)
{
  if (rclass == GENERAL_REGS
      || rclass == FR_REGS
      || rclass == FP_REGS
      || rclass == GR_AND_FR_REGS)
    return 4;
  else
    return 10;
}

/* Implement TARGET_PREFERRED_RELOAD_CLASS.  Place additional restrictions
   on RCLASS to use when copying X into that class.  */

static reg_class_t
ia64_preferred_reload_class (rtx x, reg_class_t rclass)
{
  switch (rclass)
    {
    case FR_REGS:
    case FP_REGS:
      /* Don't allow volatile mem reloads into floating point registers.
	 This is defined to force reload to choose the r/m case instead
	 of the f/f case when reloading (set (reg fX) (mem/v)).  */
      if (MEM_P (x) && MEM_VOLATILE_P (x))
	return NO_REGS;
      
      /* Force all unrecognized constants into the constant pool.  */
      if (CONSTANT_P (x))
	return NO_REGS;
      break;

    case AR_M_REGS:
    case AR_I_REGS:
      if (!OBJECT_P (x))
	return NO_REGS;
      break;

    default:
      break;
    }

  return rclass;
}

/* This function returns the register class required for a secondary
   register when copying between one of the registers in RCLASS, and X,
   using MODE.  A return value of NO_REGS means that no secondary register
   is required.  */

enum reg_class
ia64_secondary_reload_class (enum reg_class rclass,
			     machine_mode mode ATTRIBUTE_UNUSED, rtx x)
{
  int regno = -1;

  if (GET_CODE (x) == REG || GET_CODE (x) == SUBREG)
    regno = true_regnum (x);

  switch (rclass)
    {
    case BR_REGS:
    case AR_M_REGS:
    case AR_I_REGS:
      /* ??? BR<->BR register copies can happen due to a bad gcse/cse/global
	 interaction.  We end up with two pseudos with overlapping lifetimes
	 both of which are equiv to the same constant, and both which need
	 to be in BR_REGS.  This seems to be a cse bug.  cse_basic_block_end
	 changes depending on the path length, which means the qty_first_reg
	 check in make_regs_eqv can give different answers at different times.
	 At some point I'll probably need a reload_indi pattern to handle
	 this.

	 We can also get GR_AND_FR_REGS to BR_REGS/AR_REGS copies, where we
	 wound up with a FP register from GR_AND_FR_REGS.  Extend that to all
	 non-general registers for good measure.  */
      if (regno >= 0 && ! GENERAL_REGNO_P (regno))
	return GR_REGS;

      /* This is needed if a pseudo used as a call_operand gets spilled to a
	 stack slot.  */
      if (GET_CODE (x) == MEM)
	return GR_REGS;
      break;

    case FR_REGS:
    case FP_REGS:
      /* Need to go through general registers to get to other class regs.  */
      if (regno >= 0 && ! (FR_REGNO_P (regno) || GENERAL_REGNO_P (regno)))
	return GR_REGS;

      /* This can happen when a paradoxical subreg is an operand to the
	 muldi3 pattern.  */
      /* ??? This shouldn't be necessary after instruction scheduling is
	 enabled, because paradoxical subregs are not accepted by
	 register_operand when INSN_SCHEDULING is defined.  Or alternatively,
	 stop the paradoxical subreg stupidity in the *_operand functions
	 in recog.cc.  */
      if (GET_CODE (x) == MEM
	  && (GET_MODE (x) == SImode || GET_MODE (x) == HImode
	      || GET_MODE (x) == QImode))
	return GR_REGS;

      /* This can happen because of the ior/and/etc patterns that accept FP
	 registers as operands.  If the third operand is a constant, then it
	 needs to be reloaded into a FP register.  */
      if (GET_CODE (x) == CONST_INT)
	return GR_REGS;

      /* This can happen because of register elimination in a muldi3 insn.
	 E.g. `26107 * (unsigned long)&u'.  */
      if (GET_CODE (x) == PLUS)
	return GR_REGS;
      break;

    case PR_REGS:
      /* ??? This happens if we cse/gcse a BImode value across a call,
	 and the function has a nonlocal goto.  This is because global
	 does not allocate call crossing pseudos to hard registers when
	 crtl->has_nonlocal_goto is true.  This is relatively
	 common for C++ programs that use exceptions.  To reproduce,
	 return NO_REGS and compile libstdc++.  */
      if (GET_CODE (x) == MEM)
	return GR_REGS;

      /* This can happen when we take a BImode subreg of a DImode value,
	 and that DImode value winds up in some non-GR register.  */
      if (regno >= 0 && ! GENERAL_REGNO_P (regno) && ! PR_REGNO_P (regno))
	return GR_REGS;
      break;

    default:
      break;
    }

  return NO_REGS;
}


/* Implement targetm.unspec_may_trap_p hook.  */
static int
ia64_unspec_may_trap_p (const_rtx x, unsigned flags)
{
  switch (XINT (x, 1))
    {
    case UNSPEC_LDA:
    case UNSPEC_LDS:
    case UNSPEC_LDSA:
    case UNSPEC_LDCCLR:
    case UNSPEC_CHKACLR:
    case UNSPEC_CHKS:
      /* These unspecs are just wrappers.  */
      return may_trap_p_1 (XVECEXP (x, 0, 0), flags);
    }

  return default_unspec_may_trap_p (x, flags);
}


/* 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 f32-f127.  */

  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] = 1;

      if (!comma)
	break;

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

/* Implement TARGET_OPTION_OVERRIDE.  */

static void
ia64_option_override (void)
{
  unsigned int i;
  cl_deferred_option *opt;
  vec<cl_deferred_option> *v
    = (vec<cl_deferred_option> *) ia64_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 (TARGET_AUTO_PIC)
    target_flags |= MASK_CONST_GP;

  /* Numerous experiment shows that IRA based loop pressure
     calculation works better for RTL loop invariant motion on targets
     with enough (>= 32) registers.  It is an expensive optimization.
     So it is on only for peak performance.  */
  if (optimize >= 3)
    flag_ira_loop_pressure = 1;


  ia64_section_threshold = (OPTION_SET_P (g_switch_value)
			    ? g_switch_value
			    : IA64_DEFAULT_GVALUE);

  init_machine_status = ia64_init_machine_status;

  if (flag_align_functions && !str_align_functions)
    str_align_functions = "64";
  if (flag_align_loops && !str_align_loops)
    str_align_loops = "32";
  if (TARGET_ABI_OPEN_VMS)
    flag_no_common = 1;

  ia64_override_options_after_change();
}

/* Implement targetm.override_options_after_change.  */

static void
ia64_override_options_after_change (void)
{
  if (optimize >= 3
      && !OPTION_SET_P (flag_selective_scheduling)
      && !OPTION_SET_P (flag_selective_scheduling2))
    {
      flag_selective_scheduling2 = 1;
      flag_sel_sched_pipelining = 1;
    }
  if (mflag_sched_control_spec == 2)
    {
      /* Control speculation is on by default for the selective scheduler,
         but not for the Haifa scheduler.  */
      mflag_sched_control_spec = flag_selective_scheduling2 ? 1 : 0;
    }
  if (flag_sel_sched_pipelining && flag_auto_inc_dec)
    {
      /* FIXME: remove this when we'd implement breaking autoinsns as
         a transformation.  */
      flag_auto_inc_dec = 0;
    }
}

/* Initialize the record of emitted frame related registers.  */

void ia64_init_expanders (void)
{
  memset (&emitted_frame_related_regs, 0, sizeof (emitted_frame_related_regs));
}

static struct machine_function *
ia64_init_machine_status (void)
{
  return ggc_cleared_alloc<machine_function> ();
}

static enum attr_itanium_class ia64_safe_itanium_class (rtx_insn *);
static enum attr_type ia64_safe_type (rtx_insn *);

static enum attr_itanium_class
ia64_safe_itanium_class (rtx_insn *insn)
{
  if (recog_memoized (insn) >= 0)
    return get_attr_itanium_class (insn);
  else if (DEBUG_INSN_P (insn))
    return ITANIUM_CLASS_IGNORE;
  else
    return ITANIUM_CLASS_UNKNOWN;
}

static enum attr_type
ia64_safe_type (rtx_insn *insn)
{
  if (recog_memoized (insn) >= 0)
    return get_attr_type (insn);
  else
    return TYPE_UNKNOWN;
}

/* The following collection of routines emit instruction group stop bits as
   necessary to avoid dependencies.  */

/* Need to track some additional registers as far as serialization is
   concerned so we can properly handle br.call and br.ret.  We could
   make these registers visible to gcc, but since these registers are
   never explicitly used in gcc generated code, it seems wasteful to
   do so (plus it would make the call and return patterns needlessly
   complex).  */
#define REG_RP		(BR_REG (0))
#define REG_AR_CFM	(FIRST_PSEUDO_REGISTER + 1)
/* This is used for volatile asms which may require a stop bit immediately
   before and after them.  */
#define REG_VOLATILE	(FIRST_PSEUDO_REGISTER + 2)
#define AR_UNAT_BIT_0	(FIRST_PSEUDO_REGISTER + 3)
#define NUM_REGS	(AR_UNAT_BIT_0 + 64)

/* For each register, we keep track of how it has been written in the
   current instruction group.

   If a register is written unconditionally (no qualifying predicate),
   WRITE_COUNT is set to 2 and FIRST_PRED is ignored.

   If a register is written if its qualifying predicate P is true, we
   set WRITE_COUNT to 1 and FIRST_PRED to P.  Later on, the same register
   may be written again by the complement of P (P^1) and when this happens,
   WRITE_COUNT gets set to 2.

   The result of this is that whenever an insn attempts to write a register
   whose WRITE_COUNT is two, we need to issue an insn group barrier first.

   If a predicate register is written by a floating-point insn, we set
   WRITTEN_BY_FP to true.

   If a predicate register is written by an AND.ORCM we set WRITTEN_BY_AND
   to true; if it was written by an OR.ANDCM we set WRITTEN_BY_OR to true.  */

#if GCC_VERSION >= 4000
#define RWS_FIELD_TYPE __extension__ unsigned short
#else
#define RWS_FIELD_TYPE unsigned int
#endif
struct reg_write_state
{
  RWS_FIELD_TYPE write_count : 2;
  RWS_FIELD_TYPE first_pred : 10;
  RWS_FIELD_TYPE written_by_fp : 1;
  RWS_FIELD_TYPE written_by_and : 1;
  RWS_FIELD_TYPE written_by_or : 1;
};

/* Cumulative info for the current instruction group.  */
struct reg_write_state rws_sum[NUM_REGS];
#if CHECKING_P
/* Bitmap whether a register has been written in the current insn.  */
unsigned HOST_WIDEST_FAST_INT rws_insn
  [(NUM_REGS + HOST_BITS_PER_WIDEST_FAST_INT - 1)
   / HOST_BITS_PER_WIDEST_FAST_INT];

static inline void
rws_insn_set (unsigned int regno)
{
  unsigned int elt = regno / HOST_BITS_PER_WIDEST_FAST_INT;
  unsigned int bit = regno % HOST_BITS_PER_WIDEST_FAST_INT;
  gcc_assert (!((rws_insn[elt] >> bit) & 1));
  rws_insn[elt] |= (unsigned HOST_WIDEST_FAST_INT) 1 << bit;
}

static inline int
rws_insn_test (unsigned int regno)
{
  unsigned int elt = regno / HOST_BITS_PER_WIDEST_FAST_INT;
  unsigned int bit = regno % HOST_BITS_PER_WIDEST_FAST_INT;
  return (rws_insn[elt] >> bit) & 1;
}
#else
/* When not checking, track just REG_AR_CFM and REG_VOLATILE.  */
unsigned char rws_insn[2];

static inline void
rws_insn_set (int regno)
{
  if (regno == REG_AR_CFM)
    rws_insn[0] = 1;
  else if (regno == REG_VOLATILE)
    rws_insn[1] = 1;
}

static inline int
rws_insn_test (int regno)
{
  if (regno == REG_AR_CFM)
    return rws_insn[0];
  if (regno == REG_VOLATILE)
    return rws_insn[1];
  return 0;
}
#endif

/* Indicates whether this is the first instruction after a stop bit,
   in which case we don't need another stop bit.  Without this,
   ia64_variable_issue will die when scheduling an alloc.  */
static int first_instruction;

/* Misc flags needed to compute RAW/WAW dependencies while we are traversing
   RTL for one instruction.  */
struct reg_flags
{
  unsigned int is_write : 1;	/* Is register being written?  */
  unsigned int is_fp : 1;	/* Is register used as part of an fp op?  */
  unsigned int is_branch : 1;	/* Is register used as part of a branch?  */
  unsigned int is_and : 1;	/* Is register used as part of and.orcm?  */
  unsigned int is_or : 1;	/* Is register used as part of or.andcm?  */
  unsigned int is_sibcall : 1;	/* Is this a sibling or normal call?  */
};

static void rws_update (int, struct reg_flags, int);
static int rws_access_regno (int, struct reg_flags, int);
static int rws_access_reg (rtx, struct reg_flags, int);
static void update_set_flags (rtx, struct reg_flags *);
static int set_src_needs_barrier (rtx, struct reg_flags, int);
static int rtx_needs_barrier (rtx, struct reg_flags, int);
static void init_insn_group_barriers (void);
static int group_barrier_needed (rtx_insn *);
static int safe_group_barrier_needed (rtx_insn *);
static int in_safe_group_barrier;

/* Update *RWS for REGNO, which is being written by the current instruction,
   with predicate PRED, and associated register flags in FLAGS.  */

static void
rws_update (int regno, struct reg_flags flags, int pred)
{
  if (pred)
    rws_sum[regno].write_count++;
  else
    rws_sum[regno].write_count = 2;
  rws_sum[regno].written_by_fp |= flags.is_fp;
  /* ??? Not tracking and/or across differing predicates.  */
  rws_sum[regno].written_by_and = flags.is_and;
  rws_sum[regno].written_by_or = flags.is_or;
  rws_sum[regno].first_pred = pred;
}

/* Handle an access to register REGNO of type FLAGS using predicate register
   PRED.  Update rws_sum array.  Return 1 if this access creates
   a dependency with an earlier instruction in the same group.  */

static int
rws_access_regno (int regno, struct reg_flags flags, int pred)
{
  int need_barrier = 0;

  gcc_assert (regno < NUM_REGS);

  if (! PR_REGNO_P (regno))
    flags.is_and = flags.is_or = 0;

  if (flags.is_write)
    {
      int write_count;

      rws_insn_set (regno);
      write_count = rws_sum[regno].write_count;

      switch (write_count)
	{
	case 0:
	  /* The register has not been written yet.  */
	  if (!in_safe_group_barrier)
	    rws_update (regno, flags, pred);
	  break;

	case 1:
	  /* The register has been written via a predicate.  Treat
	     it like a unconditional write and do not try to check
	     for complementary pred reg in earlier write.  */
	  if (flags.is_and && rws_sum[regno].written_by_and)
	    ;
	  else if (flags.is_or && rws_sum[regno].written_by_or)
	    ;
	  else
	    need_barrier = 1;
	  if (!in_safe_group_barrier)
	    rws_update (regno, flags, pred);
	  break;

	case 2:
	  /* The register has been unconditionally written already.  We
	     need a barrier.  */
	  if (flags.is_and && rws_sum[regno].written_by_and)
	    ;
	  else if (flags.is_or && rws_sum[regno].written_by_or)
	    ;
	  else
	    need_barrier = 1;
	  if (!in_safe_group_barrier)
	    {
	      rws_sum[regno].written_by_and = flags.is_and;
	      rws_sum[regno].written_by_or = flags.is_or;
	    }
	  break;

	default:
	  gcc_unreachable ();
	}
    }
  else
    {
      if (flags.is_branch)
	{
	  /* Branches have several RAW exceptions that allow to avoid
	     barriers.  */

	  if (REGNO_REG_CLASS (regno) == BR_REGS || regno == AR_PFS_REGNUM)
	    /* RAW dependencies on branch regs are permissible as long
	       as the writer is a non-branch instruction.  Since we
	       never generate code that uses a branch register written
	       by a branch instruction, handling this case is
	       easy.  */
	    return 0;

	  if (REGNO_REG_CLASS (regno) == PR_REGS
	      && ! rws_sum[regno].written_by_fp)
	    /* The predicates of a branch are available within the
	       same insn group as long as the predicate was written by
	       something other than a floating-point instruction.  */
	    return 0;
	}

      if (flags.is_and && rws_sum[regno].written_by_and)
	return 0;
      if (flags.is_or && rws_sum[regno].written_by_or)
	return 0;

      switch (rws_sum[regno].write_count)
	{
	case 0:
	  /* The register has not been written yet.  */
	  break;

	case 1:
	  /* The register has been written via a predicate, assume we
	     need a barrier (don't check for complementary regs).  */
	  need_barrier = 1;
	  break;

	case 2:
	  /* The register has been unconditionally written already.  We
	     need a barrier.  */
	  need_barrier = 1;
	  break;

	default:
	  gcc_unreachable ();
	}
    }

  return need_barrier;
}

static int
rws_access_reg (rtx reg, struct reg_flags flags, int pred)
{
  int regno = REGNO (reg);
  int n = REG_NREGS (reg);

  if (n == 1)
    return rws_access_regno (regno, flags, pred);
  else
    {
      int need_barrier = 0;
      while (--n >= 0)
	need_barrier |= rws_access_regno (regno + n, flags, pred);
      return need_barrier;
    }
}

/* Examine X, which is a SET rtx, and update the flags, the predicate, and
   the condition, stored in *PFLAGS, *PPRED and *PCOND.  */

static void
update_set_flags (rtx x, struct reg_flags *pflags)
{
  rtx src = SET_SRC (x);

  switch (GET_CODE (src))
    {
    case CALL:
      return;

    case IF_THEN_ELSE:
      /* There are four cases here:
	 (1) The destination is (pc), in which case this is a branch,
	 nothing here applies.
	 (2) The destination is ar.lc, in which case this is a
	 doloop_end_internal,
	 (3) The destination is an fp register, in which case this is
	 an fselect instruction.
	 (4) The condition has (unspec [(reg)] UNSPEC_LDC), in which case 
	 this is a check load.
	 In all cases, nothing we do in this function applies.  */
      return;

    default:
      if (COMPARISON_P (src)
	  && SCALAR_FLOAT_MODE_P (GET_MODE (XEXP (src, 0))))
	/* Set pflags->is_fp to 1 so that we know we're dealing
	   with a floating point comparison when processing the
	   destination of the SET.  */
	pflags->is_fp = 1;

      /* Discover if this is a parallel comparison.  We only handle
	 and.orcm and or.andcm at present, since we must retain a
	 strict inverse on the predicate pair.  */
      else if (GET_CODE (src) == AND)
	pflags->is_and = 1;
      else if (GET_CODE (src) == IOR)
	pflags->is_or = 1;

      break;
    }
}

/* Subroutine of rtx_needs_barrier; this function determines whether the
   source of a given SET rtx found in X needs a barrier.  FLAGS and PRED
   are as in rtx_needs_barrier.  COND is an rtx that holds the condition
   for this insn.  */

static int
set_src_needs_barrier (rtx x, struct reg_flags flags, int pred)
{
  int need_barrier = 0;
  rtx dst;
  rtx src = SET_SRC (x);

  if (GET_CODE (src) == CALL)
    /* We don't need to worry about the result registers that
       get written by subroutine call.  */
    return rtx_needs_barrier (src, flags, pred);
  else if (SET_DEST (x) == pc_rtx)
    {
      /* X is a conditional branch.  */
      /* ??? This seems redundant, as the caller sets this bit for
	 all JUMP_INSNs.  */
      if (!ia64_spec_check_src_p (src))
	flags.is_branch = 1;
      return rtx_needs_barrier (src, flags, pred);
    }

  if (ia64_spec_check_src_p (src))
    /* Avoid checking one register twice (in condition 
       and in 'then' section) for ldc pattern.  */
    {
      gcc_assert (REG_P (XEXP (src, 2)));
      need_barrier = rtx_needs_barrier (XEXP (src, 2), flags, pred);
		  
      /* We process MEM below.  */
      src = XEXP (src, 1);
    }

  need_barrier |= rtx_needs_barrier (src, flags, pred);

  dst = SET_DEST (x);
  if (GET_CODE (dst) == ZERO_EXTRACT)
    {
      need_barrier |= rtx_needs_barrier (XEXP (dst, 1), flags, pred);
      need_barrier |= rtx_needs_barrier (XEXP (dst, 2), flags, pred);
    }
  return need_barrier;
}

/* Handle an access to rtx X of type FLAGS using predicate register
   PRED.  Return 1 if this access creates a dependency with an earlier
   instruction in the same group.  */

static int
rtx_needs_barrier (rtx x, struct reg_flags flags, int pred)
{
  int i, j;
  int is_complemented = 0;
  int need_barrier = 0;
  const char *format_ptr;
  struct reg_flags new_flags;
  rtx cond;

  if (! x)
    return 0;

  new_flags = flags;

  switch (GET_CODE (x))
    {
    case SET:
      update_set_flags (x, &new_flags);
      need_barrier = set_src_needs_barrier (x, new_flags, pred);
      if (GET_CODE (SET_SRC (x)) != CALL)
	{
	  new_flags.is_write = 1;
	  need_barrier |= rtx_needs_barrier (SET_DEST (x), new_flags, pred);
	}
      break;

    case CALL:
      new_flags.is_write = 0;
      need_barrier |= rws_access_regno (AR_EC_REGNUM, new_flags, pred);

      /* Avoid multiple register writes, in case this is a pattern with
	 multiple CALL rtx.  This avoids a failure in rws_access_reg.  */
      if (! flags.is_sibcall && ! rws_insn_test (REG_AR_CFM))
	{
	  new_flags.is_write = 1;
	  need_barrier |= rws_access_regno (REG_RP, new_flags, pred);
	  need_barrier |= rws_access_regno (AR_PFS_REGNUM, new_flags, pred);
	  need_barrier |= rws_access_regno (REG_AR_CFM, new_flags, pred);
	}
      break;

    case COND_EXEC:
      /* X is a predicated instruction.  */

      cond = COND_EXEC_TEST (x);
      gcc_assert (!pred);
      need_barrier = rtx_needs_barrier (cond, flags, 0);

      if (GET_CODE (cond) == EQ)
	is_complemented = 1;
      cond = XEXP (cond, 0);
      gcc_assert (GET_CODE (cond) == REG
		  && REGNO_REG_CLASS (REGNO (cond)) == PR_REGS);
      pred = REGNO (cond);
      if (is_complemented)
	++pred;

      need_barrier |= rtx_needs_barrier (COND_EXEC_CODE (x), flags, pred);
      return need_barrier;

    case CLOBBER:
    case USE:
      /* Clobber & use are for earlier compiler-phases only.  */
      break;

    case ASM_OPERANDS:
    case ASM_INPUT:
      /* We always emit stop bits for traditional asms.  We emit stop bits
	 for volatile extended asms if TARGET_VOL_ASM_STOP is true.  */
      if (GET_CODE (x) != ASM_OPERANDS
	  || (MEM_VOLATILE_P (x) && TARGET_VOL_ASM_STOP))
	{
	  /* Avoid writing the register multiple times if we have multiple
	     asm outputs.  This avoids a failure in rws_access_reg.  */
	  if (! rws_insn_test (REG_VOLATILE))
	    {
	      new_flags.is_write = 1;
	      rws_access_regno (REG_VOLATILE, new_flags, pred);
	    }
	  return 1;
	}

      /* For all ASM_OPERANDS, we must traverse the vector of input operands.
	 We cannot just fall through here since then we would be confused
	 by the ASM_INPUT rtx inside ASM_OPERANDS, which do not indicate
	 traditional asms unlike their normal usage.  */

      for (i = ASM_OPERANDS_INPUT_LENGTH (x) - 1; i >= 0; --i)
	if (rtx_needs_barrier (ASM_OPERANDS_INPUT (x, i), flags, pred))
	  need_barrier = 1;
      break;

    case PARALLEL:
      for (i = XVECLEN (x, 0) - 1; i >= 0; --i)
	{
	  rtx pat = XVECEXP (x, 0, i);
	  switch (GET_CODE (pat))
	    {
	    case SET:
	      update_set_flags (pat, &new_flags);
	      need_barrier |= set_src_needs_barrier (pat, new_flags, pred);
	      break;

	    case USE:
	    case CALL:
	    case ASM_OPERANDS:
	    case ASM_INPUT:
	      need_barrier |= rtx_needs_barrier (pat, flags, pred);
	      break;

	    case CLOBBER:
	      if (REG_P (XEXP (pat, 0))
		  && extract_asm_operands (x) != NULL_RTX
		  && REGNO (XEXP (pat, 0)) != AR_UNAT_REGNUM)
		{
		  new_flags.is_write = 1;
		  need_barrier |= rtx_needs_barrier (XEXP (pat, 0),
						     new_flags, pred);
		  new_flags = flags;
		}
	      break;

	    case RETURN:
	      break;

	    default:
	      gcc_unreachable ();
	    }
	}
      for (i = XVECLEN (x, 0) - 1; i >= 0; --i)
	{
	  rtx pat = XVECEXP (x, 0, i);
	  if (GET_CODE (pat) == SET)
	    {
	      if (GET_CODE (SET_SRC (pat)) != CALL)
		{
		  new_flags.is_write = 1;
		  need_barrier |= rtx_needs_barrier (SET_DEST (pat), new_flags,
						     pred);
		}
	    }
	  else if (GET_CODE (pat) == CLOBBER || GET_CODE (pat) == RETURN)
	    need_barrier |= rtx_needs_barrier (pat, flags, pred);
	}
      break;

    case SUBREG:
      need_barrier |= rtx_needs_barrier (SUBREG_REG (x), flags, pred);
      break;
    case REG:
      if (REGNO (x) == AR_UNAT_REGNUM)
	{
	  for (i = 0; i < 64; ++i)
	    need_barrier |= rws_access_regno (AR_UNAT_BIT_0 + i, flags, pred);
	}
      else
	need_barrier = rws_access_reg (x, flags, pred);
      break;

    case MEM:
      /* Find the regs used in memory address computation.  */
      new_flags.is_write = 0;
      need_barrier = rtx_needs_barrier (XEXP (x, 0), new_flags, pred);
      break;

    case CONST_INT:   case CONST_DOUBLE:  case CONST_VECTOR:
    case SYMBOL_REF:  case LABEL_REF:     case CONST:
      break;

      /* Operators with side-effects.  */
    case POST_INC:    case POST_DEC:
      gcc_assert (GET_CODE (XEXP (x, 0)) == REG);

      new_flags.is_write = 0;
      need_barrier  = rws_access_reg (XEXP (x, 0), new_flags, pred);
      new_flags.is_write = 1;
      need_barrier |= rws_access_reg (XEXP (x, 0), new_flags, pred);
      break;

    case POST_MODIFY:
      gcc_assert (GET_CODE (XEXP (x, 0)) == REG);

      new_flags.is_write = 0;
      need_barrier  = rws_access_reg (XEXP (x, 0), new_flags, pred);
      need_barrier |= rtx_needs_barrier (XEXP (x, 1), new_flags, pred);
      new_flags.is_write = 1;
      need_barrier |= rws_access_reg (XEXP (x, 0), new_flags, pred);
      break;

      /* Handle common unary and binary ops for efficiency.  */
    case COMPARE:  case PLUS:    case MINUS:   case MULT:      case DIV:
    case MOD:      case UDIV:    case UMOD:    case AND:       case IOR:
    case XOR:      case ASHIFT:  case ROTATE:  case ASHIFTRT:  case LSHIFTRT:
    case ROTATERT: case SMIN:    case SMAX:    case UMIN:      case UMAX:
    case NE:       case EQ:      case GE:      case GT:        case LE:
    case LT:       case GEU:     case GTU:     case LEU:       case LTU:
      need_barrier = rtx_needs_barrier (XEXP (x, 0), new_flags, pred);
      need_barrier |= rtx_needs_barrier (XEXP (x, 1), new_flags, pred);
      break;

    case NEG:      case NOT:	        case SIGN_EXTEND:     case ZERO_EXTEND:
    case TRUNCATE: case FLOAT_EXTEND:   case FLOAT_TRUNCATE:  case FLOAT:
    case FIX:      case UNSIGNED_FLOAT: case UNSIGNED_FIX:    case ABS:
    case SQRT:     case FFS:		case POPCOUNT:
      need_barrier = rtx_needs_barrier (XEXP (x, 0), flags, pred);
      break;

    case VEC_SELECT:
      /* VEC_SELECT's second argument is a PARALLEL with integers that
	 describe the elements selected.  On ia64, those integers are
	 always constants.  Avoid walking the PARALLEL so that we don't
	 get confused with "normal" parallels and then die.  */
      need_barrier = rtx_needs_barrier (XEXP (x, 0), flags, pred);
      break;

    case UNSPEC:
      switch (XINT (x, 1))
	{
	case UNSPEC_LTOFF_DTPMOD:
	case UNSPEC_LTOFF_DTPREL:
	case UNSPEC_DTPREL:
	case UNSPEC_LTOFF_TPREL:
	case UNSPEC_TPREL:
	case UNSPEC_PRED_REL_MUTEX:
	case UNSPEC_PIC_CALL:
        case UNSPEC_MF:
        case UNSPEC_FETCHADD_ACQ:
        case UNSPEC_FETCHADD_REL:
	case UNSPEC_BSP_VALUE:
	case UNSPEC_FLUSHRS:
	case UNSPEC_BUNDLE_SELECTOR:
          break;

	case UNSPEC_GR_SPILL:
	case UNSPEC_GR_RESTORE:
	  {
	    HOST_WIDE_INT offset = INTVAL (XVECEXP (x, 0, 1));
	    HOST_WIDE_INT bit = (offset >> 3) & 63;

	    need_barrier = rtx_needs_barrier (XVECEXP (x, 0, 0), flags, pred);
	    new_flags.is_write = (XINT (x, 1) == UNSPEC_GR_SPILL);
	    need_barrier |= rws_access_regno (AR_UNAT_BIT_0 + bit,
					      new_flags, pred);
	    break;
	  }

	case UNSPEC_FR_SPILL:
	case UNSPEC_FR_RESTORE:
	case UNSPEC_GETF_EXP:
	case UNSPEC_SETF_EXP:
        case UNSPEC_ADDP4:
	case UNSPEC_FR_SQRT_RECIP_APPROX:
	case UNSPEC_FR_SQRT_RECIP_APPROX_RES:
	case UNSPEC_LDA:
	case UNSPEC_LDS:
	case UNSPEC_LDS_A:
	case UNSPEC_LDSA:
	case UNSPEC_CHKACLR:
        case UNSPEC_CHKS:
	  need_barrier = rtx_needs_barrier (XVECEXP (x, 0, 0), flags, pred);
	  break;

	case UNSPEC_FR_RECIP_APPROX:
	case UNSPEC_SHRP:
	case UNSPEC_COPYSIGN:
	case UNSPEC_FR_RECIP_APPROX_RES:
	  need_barrier = rtx_needs_barrier (XVECEXP (x, 0, 0), flags, pred);
	  need_barrier |= rtx_needs_barrier (XVECEXP (x, 0, 1), flags, pred);
	  break;

        case UNSPEC_CMPXCHG_ACQ:
        case UNSPEC_CMPXCHG_REL:
	  need_barrier = rtx_needs_barrier (XVECEXP (x, 0, 1), flags, pred);
	  need_barrier |= rtx_needs_barrier (XVECEXP (x, 0, 2), flags, pred);
	  break;

	default:
	  gcc_unreachable ();
	}
      break;

    case UNSPEC_VOLATILE:
      switch (XINT (x, 1))
	{
	case UNSPECV_ALLOC:
	  /* Alloc must always be the first instruction of a group.
	     We force this by always returning true.  */
	  /* ??? We might get better scheduling if we explicitly check for
	     input/local/output register dependencies, and modify the
	     scheduler so that alloc is always reordered to the start of
	     the current group.  We could then eliminate all of the
	     first_instruction code.  */
	  rws_access_regno (AR_PFS_REGNUM, flags, pred);

	  new_flags.is_write = 1;
	  rws_access_regno (REG_AR_CFM, new_flags, pred);
	  return 1;

	case UNSPECV_SET_BSP:
	case UNSPECV_PROBE_STACK_RANGE:
	  need_barrier = 1;
          break;

	case UNSPECV_BLOCKAGE:
	case UNSPECV_INSN_GROUP_BARRIER:
	case UNSPECV_BREAK:
	case UNSPECV_PSAC_ALL:
	case UNSPECV_PSAC_NORMAL:
	  return 0;

	case UNSPECV_PROBE_STACK_ADDRESS:
	  need_barrier = rtx_needs_barrier (XVECEXP (x, 0, 0), flags, pred);
	  break;

	default:
	  gcc_unreachable ();
	}
      break;

    case RETURN:
      new_flags.is_write = 0;
      need_barrier  = rws_access_regno (REG_RP, flags, pred);
      need_barrier |= rws_access_regno (AR_PFS_REGNUM, flags, pred);

      new_flags.is_write = 1;
      need_barrier |= rws_access_regno (AR_EC_REGNUM, new_flags, pred);
      need_barrier |= rws_access_regno (REG_AR_CFM, new_flags, pred);
      break;

    default:
      format_ptr = GET_RTX_FORMAT (GET_CODE (x));
      for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
	switch (format_ptr[i])
	  {
	  case '0':	/* unused field */
	  case 'i':	/* integer */
	  case 'n':	/* note */
	  case 'w':	/* wide integer */
	  case 's':	/* pointer to string */
	  case 'S':	/* optional pointer to string */
	    break;

	  case 'e':
	    if (rtx_needs_barrier (XEXP (x, i), flags, pred))
	      need_barrier = 1;
	    break;

	  case 'E':
	    for (j = XVECLEN (x, i) - 1; j >= 0; --j)
	      if (rtx_needs_barrier (XVECEXP (x, i, j), flags, pred))
		need_barrier = 1;
	    break;

	  default:
	    gcc_unreachable ();
	  }
      break;
    }
  return need_barrier;
}

/* Clear out the state for group_barrier_needed at the start of a
   sequence of insns.  */

static void
init_insn_group_barriers (void)
{
  memset (rws_sum, 0, sizeof (rws_sum));
  first_instruction = 1;
}

/* Given the current state, determine whether a group barrier (a stop bit) is
   necessary before INSN.  Return nonzero if so.  This modifies the state to
   include the effects of INSN as a side-effect.  */

static int
group_barrier_needed (rtx_insn *insn)
{
  rtx pat;
  int need_barrier = 0;
  struct reg_flags flags;

  memset (&flags, 0, sizeof (flags));
  switch (GET_CODE (insn))
    {
    case NOTE:
    case DEBUG_INSN:
      break;

    case BARRIER:
      /* A barrier doesn't imply an instruction group boundary.  */
      break;

    case CODE_LABEL:
      memset (rws_insn, 0, sizeof (rws_insn));
      return 1;

    case CALL_INSN:
      flags.is_branch = 1;
      flags.is_sibcall = SIBLING_CALL_P (insn);
      memset (rws_insn, 0, sizeof (rws_insn));

      /* Don't bundle a call following another call.  */
      if ((pat = prev_active_insn (insn)) && CALL_P (pat))
	{
	  need_barrier = 1;
	  break;
	}

      need_barrier = rtx_needs_barrier (PATTERN (insn), flags, 0);
      break;

    case JUMP_INSN:
      if (!ia64_spec_check_p (insn))
	flags.is_branch = 1;

      /* Don't bundle a jump following a call.  */
      if ((pat = prev_active_insn (insn)) && CALL_P (pat))
	{
	  need_barrier = 1;
	  break;
	}
      /* FALLTHRU */

    case INSN:
      if (GET_CODE (PATTERN (insn)) == USE
	  || GET_CODE (PATTERN (insn)) == CLOBBER)
	/* Don't care about USE and CLOBBER "insns"---those are used to
	   indicate to the optimizer that it shouldn't get rid of
	   certain operations.  */
	break;

      pat = PATTERN (insn);

      /* Ug.  Hack hacks hacked elsewhere.  */
      switch (recog_memoized (insn))
	{
	  /* We play dependency tricks with the epilogue in order
	     to get proper schedules.  Undo this for dv analysis.  */
	case CODE_FOR_epilogue_deallocate_stack:
	case CODE_FOR_prologue_allocate_stack:
	  pat = XVECEXP (pat, 0, 0);
	  break;

	  /* The pattern we use for br.cloop confuses the code above.
	     The second element of the vector is representative.  */
	case CODE_FOR_doloop_end_internal:
	  pat = XVECEXP (pat, 0, 1);
	  break;

	  /* Doesn't generate code.  */
	case CODE_FOR_pred_rel_mutex:
	case CODE_FOR_prologue_use:
	  return 0;

	default:
	  break;
	}

      memset (rws_insn, 0, sizeof (rws_insn));
      need_barrier = rtx_needs_barrier (pat, flags, 0);

      /* Check to see if the previous instruction was a volatile
	 asm.  */
      if (! need_barrier)
	need_barrier = rws_access_regno (REG_VOLATILE, flags, 0);

      break;

    default:
      gcc_unreachable ();
    }

  if (first_instruction && important_for_bundling_p (insn))
    {
      need_barrier = 0;
      first_instruction = 0;
    }

  return need_barrier;
}

/* Like group_barrier_needed, but do not clobber the current state.  */

static int
safe_group_barrier_needed (rtx_insn *insn)
{
  int saved_first_instruction;
  int t;

  saved_first_instruction = first_instruction;
  in_safe_group_barrier = 1;

  t = group_barrier_needed (insn);

  first_instruction = saved_first_instruction;
  in_safe_group_barrier = 0;

  return t;
}

/* Scan the current function and insert stop bits as necessary to
   eliminate dependencies.  This function assumes that a final
   instruction scheduling pass has been run which has already
   inserted most of the necessary stop bits.  This function only
   inserts new ones at basic block boundaries, since these are
   invisible to the scheduler.  */

static void
emit_insn_group_barriers (FILE *dump)
{
  rtx_insn *insn;
  rtx_insn *last_label = 0;
  int insns_since_last_label = 0;

  init_insn_group_barriers ();

  for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
    {
      if (LABEL_P (insn))
	{
	  if (insns_since_last_label)
	    last_label = insn;
	  insns_since_last_label = 0;
	}
      else if (NOTE_P (insn)
	       && NOTE_KIND (insn) == NOTE_INSN_BASIC_BLOCK)
	{
	  if (insns_since_last_label)
	    last_label = insn;
	  insns_since_last_label = 0;
	}
      else if (NONJUMP_INSN_P (insn)
	       && GET_CODE (PATTERN (insn)) == UNSPEC_VOLATILE
	       && XINT (PATTERN (insn), 1) == UNSPECV_INSN_GROUP_BARRIER)
	{
	  init_insn_group_barriers ();
	  last_label = 0;
	}
      else if (NONDEBUG_INSN_P (insn))
	{
	  insns_since_last_label = 1;

	  if (group_barrier_needed (insn))
	    {
	      if (last_label)
		{
		  if (dump)
		    fprintf (dump, "Emitting stop before label %d\n",
			     INSN_UID (last_label));
		  emit_insn_before (gen_insn_group_barrier (GEN_INT (3)), last_label);
		  insn = last_label;

		  init_insn_group_barriers ();
		  last_label = 0;
		}
	    }
	}
    }
}

/* Like emit_insn_group_barriers, but run if no final scheduling pass was run.
   This function has to emit all necessary group barriers.  */

static void
emit_all_insn_group_barriers (FILE *dump ATTRIBUTE_UNUSED)
{
  rtx_insn *insn;

  init_insn_group_barriers ();

  for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
    {
      if (BARRIER_P (insn))
	{
	  rtx_insn *last = prev_active_insn (insn);

	  if (! last)
	    continue;
	  if (JUMP_TABLE_DATA_P (last))
	    last = prev_active_insn (last);
	  if (recog_memoized (last) != CODE_FOR_insn_group_barrier)
	    emit_insn_after (gen_insn_group_barrier (GEN_INT (3)), last);

	  init_insn_group_barriers ();
	}
      else if (NONDEBUG_INSN_P (insn))
	{
	  if (recog_memoized (insn) == CODE_FOR_insn_group_barrier)
	    init_insn_group_barriers ();
	  else if (group_barrier_needed (insn))
	    {
	      emit_insn_before (gen_insn_group_barrier (GEN_INT (3)), insn);
	      init_insn_group_barriers ();
	      group_barrier_needed (insn);
	    }
	}
    }
}



/* Instruction scheduling support.  */

#define NR_BUNDLES 10

/* A list of names of all available bundles.  */

static const char *bundle_name [NR_BUNDLES] =
{
  ".mii",
  ".mmi",
  ".mfi",
  ".mmf",
#if NR_BUNDLES == 10
  ".bbb",
  ".mbb",
#endif
  ".mib",
  ".mmb",
  ".mfb",
  ".mlx"
};

/* Nonzero if we should insert stop bits into the schedule.  */

int ia64_final_schedule = 0;

/* Codes of the corresponding queried units: */

static int _0mii_, _0mmi_, _0mfi_, _0mmf_;
static int _0bbb_, _0mbb_, _0mib_, _0mmb_, _0mfb_, _0mlx_;

static int _1mii_, _1mmi_, _1mfi_, _1mmf_;
static int _1bbb_, _1mbb_, _1mib_, _1mmb_, _1mfb_, _1mlx_;

static int pos_1, pos_2, pos_3, pos_4, pos_5, pos_6;

/* The following variable value is an insn group barrier.  */

static rtx_insn *dfa_stop_insn;

/* The following variable value is the last issued insn.  */

static rtx_insn *last_scheduled_insn;

/* The following variable value is pointer to a DFA state used as
   temporary variable.  */

static state_t temp_dfa_state = NULL;

/* The following variable value is DFA state after issuing the last
   insn.  */

static state_t prev_cycle_state = NULL;

/* The following array element values are TRUE if the corresponding
   insn requires to add stop bits before it.  */

static char *stops_p = NULL;

/* The following variable is used to set up the mentioned above array.  */

static int stop_before_p = 0;

/* The following variable value is length of the arrays `clocks' and
   `add_cycles'. */

static int clocks_length;

/* The following variable value is number of data speculations in progress.  */
static int pending_data_specs = 0;

/* Number of memory references on current and three future processor cycles.  */
static char mem_ops_in_group[4];

/* Number of current processor cycle (from scheduler's point of view).  */
static int current_cycle;

static rtx ia64_single_set (rtx_insn *);
static void ia64_emit_insn_before (rtx, rtx_insn *);

/* Map a bundle number to its pseudo-op.  */

const char *
get_bundle_name (int b)
{
  return bundle_name[b];
}


/* Return the maximum number of instructions a cpu can issue.  */

static int
ia64_issue_rate (void)
{
  return 6;
}

/* Helper function - like single_set, but look inside COND_EXEC.  */

static rtx
ia64_single_set (rtx_insn *insn)
{
  rtx x = PATTERN (insn), ret;
  if (GET_CODE (x) == COND_EXEC)
    x = COND_EXEC_CODE (x);
  if (GET_CODE (x) == SET)
    return x;

  /* Special case here prologue_allocate_stack and epilogue_deallocate_stack.
     Although they are not classical single set, the second set is there just
     to protect it from moving past FP-relative stack accesses.  */
  switch (recog_memoized (insn))
    {
    case CODE_FOR_prologue_allocate_stack:
    case CODE_FOR_prologue_allocate_stack_pr:
    case CODE_FOR_epilogue_deallocate_stack:
    case CODE_FOR_epilogue_deallocate_stack_pr:
      ret = XVECEXP (x, 0, 0);
      break;

    default:
      ret = single_set_2 (insn, x);
      break;
    }

  return ret;
}

/* Adjust the cost of a scheduling dependency.
   Return the new cost of a dependency of type DEP_TYPE or INSN on DEP_INSN.
   COST is the current cost, DW is dependency weakness.  */
static int
ia64_adjust_cost (rtx_insn *insn, int dep_type1, rtx_insn *dep_insn,
		  int cost, dw_t dw)
{
  enum reg_note dep_type = (enum reg_note) dep_type1;
  enum attr_itanium_class dep_class;
  enum attr_itanium_class insn_class;

  insn_class = ia64_safe_itanium_class (insn);
  dep_class = ia64_safe_itanium_class (dep_insn);

  /* Treat true memory dependencies separately.  Ignore apparent true
     dependence between store and call (call has a MEM inside a SYMBOL_REF).  */
  if (dep_type == REG_DEP_TRUE
      && (dep_class == ITANIUM_CLASS_ST || dep_class == ITANIUM_CLASS_STF)
      && (insn_class == ITANIUM_CLASS_BR || insn_class == ITANIUM_CLASS_SCALL))
    return 0;

  if (dw == MIN_DEP_WEAK)
    /* Store and load are likely to alias, use higher cost to avoid stall.  */
    return param_sched_mem_true_dep_cost;
  else if (dw > MIN_DEP_WEAK)
    {
      /* Store and load are less likely to alias.  */
      if (mflag_sched_fp_mem_deps_zero_cost && dep_class == ITANIUM_CLASS_STF)
	/* Assume there will be no cache conflict for floating-point data.
	   For integer data, L1 conflict penalty is huge (17 cycles), so we
	   never assume it will not cause a conflict.  */
	return 0;
      else
	return cost;
    }

  if (dep_type != REG_DEP_OUTPUT)
    return cost;

  if (dep_class == ITANIUM_CLASS_ST || dep_class == ITANIUM_CLASS_STF
      || insn_class == ITANIUM_CLASS_ST || insn_class == ITANIUM_CLASS_STF)
    return 0;

  return cost;
}

/* Like emit_insn_before, but skip cycle_display notes.
   ??? When cycle display notes are implemented, update this.  */

static void
ia64_emit_insn_before (rtx insn, rtx_insn *before)
{
  emit_insn_before (insn, before);
}

/* The following function marks insns who produce addresses for load
   and store insns.  Such insns will be placed into M slots because it
   decrease latency time for Itanium1 (see function
   `ia64_produce_address_p' and the DFA descriptions).  */

static void
ia64_dependencies_evaluation_hook (rtx_insn *head, rtx_insn *tail)
{
  rtx_insn *insn, *next, *next_tail;

  /* Before reload, which_alternative is not set, which means that
     ia64_safe_itanium_class will produce wrong results for (at least)
     move instructions.  */
  if (!reload_completed)
    return;

  next_tail = NEXT_INSN (tail);
  for (insn = head; insn != next_tail; insn = NEXT_INSN (insn))
    if (INSN_P (insn))
      insn->call = 0;
  for (insn = head; insn != next_tail; insn = NEXT_INSN (insn))
    if (INSN_P (insn)
	&& ia64_safe_itanium_class (insn) == ITANIUM_CLASS_IALU)
      {
	sd_iterator_def sd_it;
	dep_t dep;
	bool has_mem_op_consumer_p = false;

	FOR_EACH_DEP (insn, SD_LIST_FORW, sd_it, dep)
	  {
	    enum attr_itanium_class c;

	    if (DEP_TYPE (dep) != REG_DEP_TRUE)
	      continue;

	    next = DEP_CON (dep);
	    c = ia64_safe_itanium_class (next);
	    if ((c == ITANIUM_CLASS_ST
		 || c == ITANIUM_CLASS_STF)
		&& ia64_st_address_bypass_p (insn, next))
	      {
		has_mem_op_consumer_p = true;
		break;
	      }
	    else if ((c == ITANIUM_CLASS_LD
		      || c == ITANIUM_CLASS_FLD
		      || c == ITANIUM_CLASS_FLDP)
		     && ia64_ld_address_bypass_p (insn, next))
	      {
		has_mem_op_consumer_p = true;
		break;
	      }
	  }

	insn->call = has_mem_op_consumer_p;
      }
}

/* We're beginning a new block.  Initialize data structures as necessary.  */

static void
ia64_sched_init (FILE *dump ATTRIBUTE_UNUSED,
		 int sched_verbose ATTRIBUTE_UNUSED,
		 int max_ready ATTRIBUTE_UNUSED)
{
  if (flag_checking && !sel_sched_p () && reload_completed)
    {
      for (rtx_insn *insn = NEXT_INSN (current_sched_info->prev_head);
	   insn != current_sched_info->next_tail;
	   insn = NEXT_INSN (insn))
	gcc_assert (!SCHED_GROUP_P (insn));
    }
  last_scheduled_insn = NULL;
  init_insn_group_barriers ();

  current_cycle = 0;
  memset (mem_ops_in_group, 0, sizeof (mem_ops_in_group));
}

/* We're beginning a scheduling pass.  Check assertion.  */

static void
ia64_sched_init_global (FILE *dump ATTRIBUTE_UNUSED,
                        int sched_verbose ATTRIBUTE_UNUSED,
                        int max_ready ATTRIBUTE_UNUSED)
{  
  gcc_assert (pending_data_specs == 0);
}

/* Scheduling pass is now finished.  Free/reset static variable.  */
static void
ia64_sched_finish_global (FILE *dump ATTRIBUTE_UNUSED,
			  int sched_verbose ATTRIBUTE_UNUSED)
{
  gcc_assert (pending_data_specs == 0);
}

/* Return TRUE if INSN is a load (either normal or speculative, but not a
   speculation check), FALSE otherwise.  */
static bool
is_load_p (rtx_insn *insn)
{
  enum attr_itanium_class insn_class = ia64_safe_itanium_class (insn);

  return
   ((insn_class == ITANIUM_CLASS_LD || insn_class == ITANIUM_CLASS_FLD)
    && get_attr_check_load (insn) == CHECK_LOAD_NO);
}

/* If INSN is a memory reference, memoize it in MEM_OPS_IN_GROUP global array
   (taking account for 3-cycle cache reference postponing for stores: Intel
   Itanium 2 Reference Manual for Software Development and Optimization,
   6.7.3.1).  */
static void
record_memory_reference (rtx_insn *insn)
{
  enum attr_itanium_class insn_class = ia64_safe_itanium_class (insn);

  switch (insn_class) {
    case ITANIUM_CLASS_FLD:
    case ITANIUM_CLASS_LD:
      mem_ops_in_group[current_cycle % 4]++;
      break;
    case ITANIUM_CLASS_STF:
    case ITANIUM_CLASS_ST:
      mem_ops_in_group[(current_cycle + 3) % 4]++;
      break;
    default:;
  }
}

/* We are about to being issuing insns for this clock cycle.
   Override the default sort algorithm to better slot instructions.  */

static int
ia64_dfa_sched_reorder (FILE *dump, int sched_verbose, rtx_insn **ready,
			int *pn_ready, int clock_var,
			int reorder_type)
{
  int n_asms;
  int n_ready = *pn_ready;
  rtx_insn **e_ready = ready + n_ready;
  rtx_insn **insnp;

  if (sched_verbose)
    fprintf (dump, "// ia64_dfa_sched_reorder (type %d):\n", reorder_type);

  if (reorder_type == 0)
    {
      /* First, move all USEs, CLOBBERs and other crud out of the way.  */
      n_asms = 0;
      for (insnp = ready; insnp < e_ready; insnp++)
	if (insnp < e_ready)
	  {
	    rtx_insn *insn = *insnp;
	    enum attr_type t = ia64_safe_type (insn);
	    if (t == TYPE_UNKNOWN)
	      {
		if (GET_CODE (PATTERN (insn)) == ASM_INPUT
		    || asm_noperands (PATTERN (insn)) >= 0)
		  {
		    rtx_insn *lowest = ready[n_asms];
		    ready[n_asms] = insn;
		    *insnp = lowest;
		    n_asms++;
		  }
		else
		  {
		    rtx_insn *highest = ready[n_ready - 1];
		    ready[n_ready - 1] = insn;
		    *insnp = highest;
		    return 1;
		  }
	      }
	  }

      if (n_asms < n_ready)
	{
	  /* Some normal insns to process.  Skip the asms.  */
	  ready += n_asms;
	  n_ready -= n_asms;
	}
      else if (n_ready > 0)
	return 1;
    }

  if (ia64_final_schedule)
    {
      int deleted = 0;
      int nr_need_stop = 0;

      for (insnp = ready; insnp < e_ready; insnp++)
	if (safe_group_barrier_needed (*insnp))
	  nr_need_stop++;

      if (reorder_type == 1 && n_ready == nr_need_stop)
	return 0;
      if (reorder_type == 0)
	return 1;
      insnp = e_ready;
      /* Move down everything that needs a stop bit, preserving
	 relative order.  */
      while (insnp-- > ready + deleted)
	while (insnp >= ready + deleted)
	  {
	    rtx_insn *insn = *insnp;
	    if (! safe_group_barrier_needed (insn))
	      break;
	    memmove (ready + 1, ready, (insnp - ready) * sizeof (rtx));
	    *ready = insn;
	    deleted++;
	  }
      n_ready -= deleted;
      ready += deleted;
    }

  current_cycle = clock_var;
  if (reload_completed && mem_ops_in_group[clock_var % 4] >= ia64_max_memory_insns)
    {
      int moved = 0;

      insnp = e_ready;
      /* Move down loads/stores, preserving relative order.  */
      while (insnp-- > ready + moved)
	while (insnp >= ready + moved)
	  {
	    rtx_insn *insn = *insnp;
	    if (! is_load_p (insn))
	      break;
	    memmove (ready + 1, ready, (insnp - ready) * sizeof (rtx));
	    *ready = insn;
	    moved++;
	  }
      n_ready -= moved;
      ready += moved;
    }

  return 1;
}

/* We are about to being issuing insns for this clock cycle.  Override
   the default sort algorithm to better slot instructions.  */

static int
ia64_sched_reorder (FILE *dump, int sched_verbose, rtx_insn **ready,
		    int *pn_ready, int clock_var)
{
  return ia64_dfa_sched_reorder (dump, sched_verbose, ready,
				 pn_ready, clock_var, 0);
}

/* Like ia64_sched_reorder, but called after issuing each insn.
   Override the default sort algorithm to better slot instructions.  */

static int
ia64_sched_reorder2 (FILE *dump ATTRIBUTE_UNUSED,
		     int sched_verbose ATTRIBUTE_UNUSED, rtx_insn **ready,
		     int *pn_ready, int clock_var)
{
  return ia64_dfa_sched_reorder (dump, sched_verbose, ready, pn_ready,
				 clock_var, 1);
}

/* We are about to issue INSN.  Return the number of insns left on the
   ready queue that can be issued this cycle.  */

static int
ia64_variable_issue (FILE *dump ATTRIBUTE_UNUSED,
		     int sched_verbose ATTRIBUTE_UNUSED,
		     rtx_insn *insn,
		     int can_issue_more ATTRIBUTE_UNUSED)
{
  if (sched_deps_info->generate_spec_deps && !sel_sched_p ())
    /* Modulo scheduling does not extend h_i_d when emitting
       new instructions.  Don't use h_i_d, if we don't have to.  */
    {
      if (DONE_SPEC (insn) & BEGIN_DATA)
	pending_data_specs++;
      if (CHECK_SPEC (insn) & BEGIN_DATA)
	pending_data_specs--;
    }

  if (DEBUG_INSN_P (insn))
    return 1;

  last_scheduled_insn = insn;
  memcpy (prev_cycle_state, curr_state, dfa_state_size);
  if (reload_completed)
    {
      int needed = group_barrier_needed (insn);
      
      gcc_assert (!needed);
      if (CALL_P (insn))
	init_insn_group_barriers ();
      stops_p [INSN_UID (insn)] = stop_before_p;
      stop_before_p = 0;

      record_memory_reference (insn);
    }
  return 1;
}

/* We are choosing insn from the ready queue.  Return zero if INSN
   can be chosen.  */

static int
ia64_first_cycle_multipass_dfa_lookahead_guard (rtx_insn *insn, int ready_index)
{
  gcc_assert (insn && INSN_P (insn));

  /* Size of ALAT is 32.  As far as we perform conservative
     data speculation, we keep ALAT half-empty.  */
  if (pending_data_specs >= 16 && (TODO_SPEC (insn) & BEGIN_DATA))
    return ready_index == 0 ? -1 : 1;

  if (ready_index == 0)
    return 0;

  if ((!reload_completed
       || !safe_group_barrier_needed (insn))
      && (!mflag_sched_mem_insns_hard_limit
	  || !is_load_p (insn)
	  || mem_ops_in_group[current_cycle % 4] < ia64_max_memory_insns))
    return 0;

  return 1;
}

/* The following variable value is pseudo-insn used by the DFA insn
   scheduler to change the DFA state when the simulated clock is
   increased.  */

static rtx_insn *dfa_pre_cycle_insn;

/* Returns 1 when a meaningful insn was scheduled between the last group
   barrier and LAST.  */
static int
scheduled_good_insn (rtx_insn *last)
{
  if (last && recog_memoized (last) >= 0)
    return 1;

  for ( ;
       last != NULL && !NOTE_INSN_BASIC_BLOCK_P (last)
       && !stops_p[INSN_UID (last)];
       last = PREV_INSN (last))
    /* We could hit a NOTE_INSN_DELETED here which is actually outside
       the ebb we're scheduling.  */
    if (INSN_P (last) && recog_memoized (last) >= 0)
      return 1;

  return 0;
}

/* We are about to being issuing INSN.  Return nonzero if we cannot
   issue it on given cycle CLOCK and return zero if we should not sort
   the ready queue on the next clock start.  */

static int
ia64_dfa_new_cycle (FILE *dump, int verbose, rtx_insn *insn, int last_clock,
		    int clock, int *sort_p)
{
  gcc_assert (insn && INSN_P (insn));

  if (DEBUG_INSN_P (insn))
    return 0;

  /* When a group barrier is needed for insn, last_scheduled_insn
     should be set.  */
  gcc_assert (!(reload_completed && safe_group_barrier_needed (insn))
              || last_scheduled_insn);

  if ((reload_completed
       && (safe_group_barrier_needed (insn)
	   || (mflag_sched_stop_bits_after_every_cycle
	       && last_clock != clock
	       && last_scheduled_insn
	       && scheduled_good_insn (last_scheduled_insn))))
      || (last_scheduled_insn
	  && (CALL_P (last_scheduled_insn)
	      || unknown_for_bundling_p (last_scheduled_insn))))
    {
      init_insn_group_barriers ();

      if (verbose && dump)
	fprintf (dump, "//    Stop should be before %d%s\n", INSN_UID (insn),
		 last_clock == clock ? " + cycle advance" : "");

      stop_before_p = 1;
      current_cycle = clock;
      mem_ops_in_group[current_cycle % 4] = 0;

      if (last_clock == clock)
	{
	  state_transition (curr_state, dfa_stop_insn);
	  if (TARGET_EARLY_STOP_BITS)
	    *sort_p = (last_scheduled_insn == NULL_RTX
		       || ! CALL_P (last_scheduled_insn));
	  else
	    *sort_p = 0;
	  return 1;
	}

      if (last_scheduled_insn)
	{
	  if (unknown_for_bundling_p (last_scheduled_insn))
	    state_reset (curr_state);
	  else
	    {
	      memcpy (curr_state, prev_cycle_state, dfa_state_size);
	      state_transition (curr_state, dfa_stop_insn);
	      state_transition (curr_state, dfa_pre_cycle_insn);
	      state_transition (curr_state, NULL);
	    }
	}
    }
  return 0;
}

/* Implement targetm.sched.h_i_d_extended hook.
   Extend internal data structures.  */
static void
ia64_h_i_d_extended (void)
{
  if (stops_p != NULL) 
    {
      int new_clocks_length = get_max_uid () * 3 / 2;
      stops_p = (char *) xrecalloc (stops_p, new_clocks_length, clocks_length, 1);
      clocks_length = new_clocks_length;
    }
}


/* This structure describes the data used by the backend to guide scheduling.
   When the current scheduling point is switched, this data should be saved
   and restored later, if the scheduler returns to this point.  */
struct _ia64_sched_context
{
  state_t prev_cycle_state;
  rtx_insn *last_scheduled_insn;
  struct reg_write_state rws_sum[NUM_REGS];
  struct reg_write_state rws_insn[NUM_REGS];
  int first_instruction;
  int pending_data_specs;
  int current_cycle;
  char mem_ops_in_group[4];
};
typedef struct _ia64_sched_context *ia64_sched_context_t;

/* Allocates a scheduling context.  */
static void *
ia64_alloc_sched_context (void)
{
  return xmalloc (sizeof (struct _ia64_sched_context));
}

/* Initializes the _SC context with clean data, if CLEAN_P, and from
   the global context otherwise.  */
static void
ia64_init_sched_context (void *_sc, bool clean_p)
{
  ia64_sched_context_t sc = (ia64_sched_context_t) _sc;

  sc->prev_cycle_state = xmalloc (dfa_state_size);
  if (clean_p)
    {
      state_reset (sc->prev_cycle_state);
      sc->last_scheduled_insn = NULL;
      memset (sc->rws_sum, 0, sizeof (rws_sum));
      memset (sc->rws_insn, 0, sizeof (rws_insn));
      sc->first_instruction = 1;
      sc->pending_data_specs = 0;
      sc->current_cycle = 0;
      memset (sc->mem_ops_in_group, 0, sizeof (mem_ops_in_group));
    }
  else
    {
      memcpy (sc->prev_cycle_state, prev_cycle_state, dfa_state_size);
      sc->last_scheduled_insn = last_scheduled_insn;
      memcpy (sc->rws_sum, rws_sum, sizeof (rws_sum));
      memcpy (sc->rws_insn, rws_insn, sizeof (rws_insn));
      sc->first_instruction = first_instruction;
      sc->pending_data_specs = pending_data_specs;
      sc->current_cycle = current_cycle;
      memcpy (sc->mem_ops_in_group, mem_ops_in_group, sizeof (mem_ops_in_group));
    }
}

/* Sets the global scheduling context to the one pointed to by _SC.  */
static void
ia64_set_sched_context (void *_sc)
{
  ia64_sched_context_t sc = (ia64_sched_context_t) _sc;

  gcc_assert (sc != NULL);

  memcpy (prev_cycle_state, sc->prev_cycle_state, dfa_state_size);
  last_scheduled_insn = sc->last_scheduled_insn;
  memcpy (rws_sum, sc->rws_sum, sizeof (rws_sum));
  memcpy (rws_insn, sc->rws_insn, sizeof (rws_insn));
  first_instruction = sc->first_instruction;
  pending_data_specs = sc->pending_data_specs;
  current_cycle = sc->current_cycle;
  memcpy (mem_ops_in_group, sc->mem_ops_in_group, sizeof (mem_ops_in_group));
}

/* Clears the data in the _SC scheduling context.  */
static void
ia64_clear_sched_context (void *_sc)
{
  ia64_sched_context_t sc = (ia64_sched_context_t) _sc;
  
  free (sc->prev_cycle_state);
  sc->prev_cycle_state = NULL;
}

/* Frees the _SC scheduling context.  */
static void
ia64_free_sched_context (void *_sc)
{
  gcc_assert (_sc != NULL);

  free (_sc);
}

typedef rtx (* gen_func_t) (rtx, rtx);

/* Return a function that will generate a load of mode MODE_NO
   with speculation types TS.  */
static gen_func_t
get_spec_load_gen_function (ds_t ts, int mode_no)
{
  static gen_func_t gen_ld_[] = {
    gen_movbi,
    gen_movqi_internal,
    gen_movhi_internal,
    gen_movsi_internal,
    gen_movdi_internal,
    gen_movsf_internal,
    gen_movdf_internal,
    gen_movxf_internal,
    gen_movti_internal,
    gen_zero_extendqidi2,
    gen_zero_extendhidi2,
    gen_zero_extendsidi2,
  };

  static gen_func_t gen_ld_a[] = {
    gen_movbi_advanced,
    gen_movqi_advanced,
    gen_movhi_advanced,
    gen_movsi_advanced,
    gen_movdi_advanced,
    gen_movsf_advanced,
    gen_movdf_advanced,
    gen_movxf_advanced,
    gen_movti_advanced,
    gen_zero_extendqidi2_advanced,
    gen_zero_extendhidi2_advanced,
    gen_zero_extendsidi2_advanced,
  };
  static gen_func_t gen_ld_s[] = {
    gen_movbi_speculative,
    gen_movqi_speculative,
    gen_movhi_speculative,
    gen_movsi_speculative,
    gen_movdi_speculative,
    gen_movsf_speculative,
    gen_movdf_speculative,
    gen_movxf_speculative,
    gen_movti_speculative,
    gen_zero_extendqidi2_speculative,
    gen_zero_extendhidi2_speculative,
    gen_zero_extendsidi2_speculative,
  };
  static gen_func_t gen_ld_sa[] = {
    gen_movbi_speculative_advanced,
    gen_movqi_speculative_advanced,
    gen_movhi_speculative_advanced,
    gen_movsi_speculative_advanced,
    gen_movdi_speculative_advanced,
    gen_movsf_speculative_advanced,
    gen_movdf_speculative_advanced,
    gen_movxf_speculative_advanced,
    gen_movti_speculative_advanced,
    gen_zero_extendqidi2_speculative_advanced,
    gen_zero_extendhidi2_speculative_advanced,
    gen_zero_extendsidi2_speculative_advanced,
  };
  static gen_func_t gen_ld_s_a[] = {
    gen_movbi_speculative_a,
    gen_movqi_speculative_a,
    gen_movhi_speculative_a,
    gen_movsi_speculative_a,
    gen_movdi_speculative_a,
    gen_movsf_speculative_a,
    gen_movdf_speculative_a,
    gen_movxf_speculative_a,
    gen_movti_speculative_a,
    gen_zero_extendqidi2_speculative_a,
    gen_zero_extendhidi2_speculative_a,
    gen_zero_extendsidi2_speculative_a,
  };

  gen_func_t *gen_ld;

  if (ts & BEGIN_DATA)
    {
      if (ts & BEGIN_CONTROL)
	gen_ld = gen_ld_sa;
      else
	gen_ld = gen_ld_a;
    }
  else if (ts & BEGIN_CONTROL)
    {
      if ((spec_info->flags & SEL_SCHED_SPEC_DONT_CHECK_CONTROL)
	  || ia64_needs_block_p (ts))
	gen_ld = gen_ld_s;
      else
	gen_ld = gen_ld_s_a;
    }
  else if (ts == 0)
    gen_ld = gen_ld_;
  else
    gcc_unreachable ();

  return gen_ld[mode_no];
}

/* Constants that help mapping 'machine_mode' to int.  */
enum SPEC_MODES
  {
    SPEC_MODE_INVALID = -1,
    SPEC_MODE_FIRST = 0,
    SPEC_MODE_FOR_EXTEND_FIRST = 1,
    SPEC_MODE_FOR_EXTEND_LAST = 3,
    SPEC_MODE_LAST = 8
  };

enum
  {
    /* Offset to reach ZERO_EXTEND patterns.  */
    SPEC_GEN_EXTEND_OFFSET = SPEC_MODE_LAST - SPEC_MODE_FOR_EXTEND_FIRST + 1
  };

/* Return index of the MODE.  */
static int
ia64_mode_to_int (machine_mode mode)
{
  switch (mode)
    {
    case E_BImode: return 0; /* SPEC_MODE_FIRST  */
    case E_QImode: return 1; /* SPEC_MODE_FOR_EXTEND_FIRST  */
    case E_HImode: return 2;
    case E_SImode: return 3; /* SPEC_MODE_FOR_EXTEND_LAST  */
    case E_DImode: return 4;
    case E_SFmode: return 5;
    case E_DFmode: return 6;
    case E_XFmode: return 7;
    case E_TImode:
      /* ??? This mode needs testing.  Bypasses for ldfp8 instruction are not
	 mentioned in itanium[12].md.  Predicate fp_register_operand also
	 needs to be defined.  Bottom line: better disable for now.  */
      return SPEC_MODE_INVALID;
    default:     return SPEC_MODE_INVALID;
    }
}

/* Provide information about speculation capabilities.  */
static void
ia64_set_sched_flags (spec_info_t spec_info)
{
  unsigned int *flags = &(current_sched_info->flags);

  if (*flags & SCHED_RGN
      || *flags & SCHED_EBB
      || *flags & SEL_SCHED)
    {
      int mask = 0;

      if ((mflag_sched_br_data_spec && !reload_completed && optimize > 0)
          || (mflag_sched_ar_data_spec && reload_completed))
	{
	  mask |= BEGIN_DATA;

	  if (!sel_sched_p ()
	      && ((mflag_sched_br_in_data_spec && !reload_completed)
		  || (mflag_sched_ar_in_data_spec && reload_completed)))
	    mask |= BE_IN_DATA;
	}
      
      if (mflag_sched_control_spec
          && (!sel_sched_p ()
	      || reload_completed))
	{
	  mask |= BEGIN_CONTROL;
	  
	  if (!sel_sched_p () && mflag_sched_in_control_spec)
	    mask |= BE_IN_CONTROL;
	}

      spec_info->mask = mask;

      if (mask)
	{
	  *flags |= USE_DEPS_LIST | DO_SPECULATION;

	  if (mask & BE_IN_SPEC)
	    *flags |= NEW_BBS;
	  
	  spec_info->flags = 0;
      
	  if ((mask & CONTROL_SPEC)
	      && sel_sched_p () && mflag_sel_sched_dont_check_control_spec)
	    spec_info->flags |= SEL_SCHED_SPEC_DONT_CHECK_CONTROL;

	  if (sched_verbose >= 1)
	    spec_info->dump = sched_dump;
	  else
	    spec_info->dump = 0;
	  
	  if (mflag_sched_count_spec_in_critical_path)
	    spec_info->flags |= COUNT_SPEC_IN_CRITICAL_PATH;
	}
    }
  else
    spec_info->mask = 0;
}

/* If INSN is an appropriate load return its mode.
   Return -1 otherwise.  */
static int
get_mode_no_for_insn (rtx_insn *insn)
{
  rtx reg, mem, mode_rtx;
  int mode_no;
  bool extend_p;

  extract_insn_cached (insn);

  /* We use WHICH_ALTERNATIVE only after reload.  This will
     guarantee that reload won't touch a speculative insn.  */

  if (recog_data.n_operands != 2)
    return -1;

  reg = recog_data.operand[0];
  mem = recog_data.operand[1];

  /* We should use MEM's mode since REG's mode in presence of
     ZERO_EXTEND will always be DImode.  */
  if (get_attr_speculable1 (insn) == SPECULABLE1_YES)
    /* Process non-speculative ld.  */
    {
      if (!reload_completed)
	{
	  /* Do not speculate into regs like ar.lc.  */
	  if (!REG_P (reg) || AR_REGNO_P (REGNO (reg)))
	    return -1;

	  if (!MEM_P (mem))
	    return -1;

	  {
	    rtx mem_reg = XEXP (mem, 0);

	    if (!REG_P (mem_reg))
	      return -1;
	  }

	  mode_rtx = mem;
	}
      else if (get_attr_speculable2 (insn) == SPECULABLE2_YES)
	{
	  gcc_assert (REG_P (reg) && MEM_P (mem));
	  mode_rtx = mem;
	}
      else
	return -1;
    }
  else if (get_attr_data_speculative (insn) == DATA_SPECULATIVE_YES
	   || get_attr_control_speculative (insn) == CONTROL_SPECULATIVE_YES
	   || get_attr_check_load (insn) == CHECK_LOAD_YES)
    /* Process speculative ld or ld.c.  */
    {
      gcc_assert (REG_P (reg) && MEM_P (mem));
      mode_rtx = mem;
    }
  else
    {
      enum attr_itanium_class attr_class = get_attr_itanium_class (insn);

      if (attr_class == ITANIUM_CLASS_CHK_A
	  || attr_class == ITANIUM_CLASS_CHK_S_I
	  || attr_class == ITANIUM_CLASS_CHK_S_F)
	/* Process chk.  */
	mode_rtx = reg;
      else
	return -1;
    }

  mode_no = ia64_mode_to_int (GET_MODE (mode_rtx));

  if (mode_no == SPEC_MODE_INVALID)
    return -1;

  extend_p = (GET_MODE (reg) != GET_MODE (mode_rtx));

  if (extend_p)
    {
      if (!(SPEC_MODE_FOR_EXTEND_FIRST <= mode_no
	    && mode_no <= SPEC_MODE_FOR_EXTEND_LAST))
	return -1;

      mode_no += SPEC_GEN_EXTEND_OFFSET;
    }

  return mode_no;
}

/* If X is an unspec part of a speculative load, return its code.
   Return -1 otherwise.  */
static int
get_spec_unspec_code (const_rtx x)
{
  if (GET_CODE (x) != UNSPEC)
    return -1;

  {
    int code;

    code = XINT (x, 1);

    switch (code)
      {
      case UNSPEC_LDA:
      case UNSPEC_LDS:
      case UNSPEC_LDS_A:
      case UNSPEC_LDSA:
	return code;

      default:
	return -1;
      }
  }
}

/* Implement skip_rtx_p hook.  */
static bool
ia64_skip_rtx_p (const_rtx x)
{
  return get_spec_unspec_code (x) != -1;
}

/* If INSN is a speculative load, return its UNSPEC code.
   Return -1 otherwise.  */
static int
get_insn_spec_code (const_rtx insn)
{
  rtx pat, reg, mem;

  pat = PATTERN (insn);

  if (GET_CODE (pat) == COND_EXEC)
    pat = COND_EXEC_CODE (pat);

  if (GET_CODE (pat) != SET)
    return -1;

  reg = SET_DEST (pat);
  if (!REG_P (reg))
    return -1;

  mem = SET_SRC (pat);
  if (GET_CODE (mem) == ZERO_EXTEND)
    mem = XEXP (mem, 0);

  return get_spec_unspec_code (mem);
}

/* If INSN is a speculative load, return a ds with the speculation types.
   Otherwise [if INSN is a normal instruction] return 0.  */
static ds_t
ia64_get_insn_spec_ds (rtx_insn *insn)
{
  int code = get_insn_spec_code (insn);

  switch (code)
    {
    case UNSPEC_LDA:
      return BEGIN_DATA;

    case UNSPEC_LDS:
    case UNSPEC_LDS_A:
      return BEGIN_CONTROL;

    case UNSPEC_LDSA:
      return BEGIN_DATA | BEGIN_CONTROL;

    default:
      return 0;
    }
}

/* If INSN is a speculative load return a ds with the speculation types that
   will be checked.
   Otherwise [if INSN is a normal instruction] return 0.  */
static ds_t
ia64_get_insn_checked_ds (rtx_insn *insn)
{
  int code = get_insn_spec_code (insn);

  switch (code)
    {
    case UNSPEC_LDA:
      return BEGIN_DATA | BEGIN_CONTROL;

    case UNSPEC_LDS:
      return BEGIN_CONTROL;

    case UNSPEC_LDS_A:
    case UNSPEC_LDSA:
      return BEGIN_DATA | BEGIN_CONTROL;

    default:
      return 0;
    }
}

/* If GEN_P is true, calculate the index of needed speculation check and return
   speculative pattern for INSN with speculative mode TS, machine mode
   MODE_NO and with ZERO_EXTEND (if EXTEND_P is true).
   If GEN_P is false, just calculate the index of needed speculation check.  */
static rtx
ia64_gen_spec_load (rtx insn, ds_t ts, int mode_no)
{
  rtx pat, new_pat;
  gen_func_t gen_load;

  gen_load = get_spec_load_gen_function (ts, mode_no);

  new_pat = gen_load (copy_rtx (recog_data.operand[0]),
		      copy_rtx (recog_data.operand[1]));

  pat = PATTERN (insn);
  if (GET_CODE (pat) == COND_EXEC)
    new_pat = gen_rtx_COND_EXEC (VOIDmode, copy_rtx (COND_EXEC_TEST (pat)),
				 new_pat);

  return new_pat;
}

static bool
insn_can_be_in_speculative_p (rtx insn ATTRIBUTE_UNUSED,
			      ds_t ds ATTRIBUTE_UNUSED)
{
  return false;
}

/* Implement targetm.sched.speculate_insn hook.
   Check if the INSN can be TS speculative.
   If 'no' - return -1.
   If 'yes' - generate speculative pattern in the NEW_PAT and return 1.
   If current pattern of the INSN already provides TS speculation,
   return 0.  */
static int
ia64_speculate_insn (rtx_insn *insn, ds_t ts, rtx *new_pat)
{  
  int mode_no;
  int res;
  
  gcc_assert (!(ts & ~SPECULATIVE));

  if (ia64_spec_check_p (insn))
    return -1;

  if ((ts & BE_IN_SPEC)
      && !insn_can_be_in_speculative_p (insn, ts))
    return -1;

  mode_no = get_mode_no_for_insn (insn);

  if (mode_no != SPEC_MODE_INVALID)
    {
      if (ia64_get_insn_spec_ds (insn) == ds_get_speculation_types (ts))
	res = 0;
      else
	{
	  res = 1;
	  *new_pat = ia64_gen_spec_load (insn, ts, mode_no);
	}
    }
  else
    res = -1;

  return res;
}

/* Return a function that will generate a check for speculation TS with mode
   MODE_NO.
   If simple check is needed, pass true for SIMPLE_CHECK_P.
   If clearing check is needed, pass true for CLEARING_CHECK_P.  */
static gen_func_t
get_spec_check_gen_function (ds_t ts, int mode_no,
			     bool simple_check_p, bool clearing_check_p)
{
  static gen_func_t gen_ld_c_clr[] = {
    gen_movbi_clr,
    gen_movqi_clr,
    gen_movhi_clr,
    gen_movsi_clr,
    gen_movdi_clr,
    gen_movsf_clr,
    gen_movdf_clr,
    gen_movxf_clr,
    gen_movti_clr,
    gen_zero_extendqidi2_clr,
    gen_zero_extendhidi2_clr,
    gen_zero_extendsidi2_clr,
  };
  static gen_func_t gen_ld_c_nc[] = {
    gen_movbi_nc,
    gen_movqi_nc,
    gen_movhi_nc,
    gen_movsi_nc,
    gen_movdi_nc,
    gen_movsf_nc,
    gen_movdf_nc,
    gen_movxf_nc,
    gen_movti_nc,
    gen_zero_extendqidi2_nc,
    gen_zero_extendhidi2_nc,
    gen_zero_extendsidi2_nc,
  };
  static gen_func_t gen_chk_a_clr[] = {
    gen_advanced_load_check_clr_bi,
    gen_advanced_load_check_clr_qi,
    gen_advanced_load_check_clr_hi,
    gen_advanced_load_check_clr_si,
    gen_advanced_load_check_clr_di,
    gen_advanced_load_check_clr_sf,
    gen_advanced_load_check_clr_df,
    gen_advanced_load_check_clr_xf,
    gen_advanced_load_check_clr_ti,
    gen_advanced_load_check_clr_di,
    gen_advanced_load_check_clr_di,
    gen_advanced_load_check_clr_di,
  };
  static gen_func_t gen_chk_a_nc[] = {
    gen_advanced_load_check_nc_bi,
    gen_advanced_load_check_nc_qi,
    gen_advanced_load_check_nc_hi,
    gen_advanced_load_check_nc_si,
    gen_advanced_load_check_nc_di,
    gen_advanced_load_check_nc_sf,
    gen_advanced_load_check_nc_df,
    gen_advanced_load_check_nc_xf,
    gen_advanced_load_check_nc_ti,
    gen_advanced_load_check_nc_di,
    gen_advanced_load_check_nc_di,
    gen_advanced_load_check_nc_di,
  };
  static gen_func_t gen_chk_s[] = {
    gen_speculation_check_bi,
    gen_speculation_check_qi,
    gen_speculation_check_hi,
    gen_speculation_check_si,
    gen_speculation_check_di,
    gen_speculation_check_sf,
    gen_speculation_check_df,
    gen_speculation_check_xf,
    gen_speculation_check_ti,
    gen_speculation_check_di,
    gen_speculation_check_di,
    gen_speculation_check_di,
  };

  gen_func_t *gen_check;

  if (ts & BEGIN_DATA)
    {
      /* We don't need recovery because even if this is ld.sa
	 ALAT entry will be allocated only if NAT bit is set to zero.
	 So it is enough to use ld.c here.  */

      if (simple_check_p)
	{
	  gcc_assert (mflag_sched_spec_ldc);

	  if (clearing_check_p)
	    gen_check = gen_ld_c_clr;
	  else
	    gen_check = gen_ld_c_nc;
	}
      else
	{
	  if (clearing_check_p)
	    gen_check = gen_chk_a_clr;
	  else
	    gen_check = gen_chk_a_nc;
	}
    }
  else if (ts & BEGIN_CONTROL)
    {
      if (simple_check_p)
	/* We might want to use ld.sa -> ld.c instead of
	   ld.s -> chk.s.  */
	{
	  gcc_assert (!ia64_needs_block_p (ts));

	  if (clearing_check_p)
	    gen_check = gen_ld_c_clr;
	  else
	    gen_check = gen_ld_c_nc;
	}
      else
	{
	  gen_check = gen_chk_s;
	}
    }
  else
    gcc_unreachable ();

  gcc_assert (mode_no >= 0);
  return gen_check[mode_no];
}

/* Return nonzero, if INSN needs branchy recovery check.  */
static bool
ia64_needs_block_p (ds_t ts)
{
  if (ts & BEGIN_DATA)
    return !mflag_sched_spec_ldc;

  gcc_assert ((ts & BEGIN_CONTROL) != 0);

  return !(mflag_sched_spec_control_ldc && mflag_sched_spec_ldc);
}

/* Generate (or regenerate) a recovery check for INSN.  */
static rtx
ia64_gen_spec_check (rtx_insn *insn, rtx_insn *label, ds_t ds)
{
  rtx op1, pat, check_pat;
  gen_func_t gen_check;
  int mode_no;

  mode_no = get_mode_no_for_insn (insn);
  gcc_assert (mode_no >= 0);

  if (label)
    op1 = label;
  else
    {
      gcc_assert (!ia64_needs_block_p (ds));
      op1 = copy_rtx (recog_data.operand[1]);
    }
      
  gen_check = get_spec_check_gen_function (ds, mode_no, label == NULL_RTX,
					   true);

  check_pat = gen_check (copy_rtx (recog_data.operand[0]), op1);
    
  pat = PATTERN (insn);
  if (GET_CODE (pat) == COND_EXEC)
    check_pat = gen_rtx_COND_EXEC (VOIDmode, copy_rtx (COND_EXEC_TEST (pat)),
				   check_pat);

  return check_pat;
}

/* Return nonzero, if X is branchy recovery check.  */
static int
ia64_spec_check_p (rtx x)
{
  x = PATTERN (x);
  if (GET_CODE (x) == COND_EXEC)
    x = COND_EXEC_CODE (x);
  if (GET_CODE (x) == SET)
    return ia64_spec_check_src_p (SET_SRC (x));
  return 0;
}

/* Return nonzero, if SRC belongs to recovery check.  */
static int
ia64_spec_check_src_p (rtx src)
{
  if (GET_CODE (src) == IF_THEN_ELSE)
    {
      rtx t;

      t = XEXP (src, 0);
      if (GET_CODE (t) == NE)
	{
	  t = XEXP (t, 0);	    

	  if (GET_CODE (t) == UNSPEC)
	    {
	      int code;
	      
	      code = XINT (t, 1);
	     
	      if (code == UNSPEC_LDCCLR
		  || code == UNSPEC_LDCNC
		  || code == UNSPEC_CHKACLR
		  || code == UNSPEC_CHKANC
		  || code == UNSPEC_CHKS)
		{
		  gcc_assert (code != 0);
		  return code;
		}
	    }
	}
    }
  return 0;
}


/* The following page contains abstract data `bundle states' which are
   used for bundling insns (inserting nops and template generation).  */

/* The following describes state of insn bundling.  */

struct bundle_state
{
  /* Unique bundle state number to identify them in the debugging
     output  */
  int unique_num;
  rtx_insn *insn; /* corresponding insn, NULL for the 1st and the last state  */
  /* number nops before and after the insn  */
  short before_nops_num, after_nops_num;
  int insn_num; /* insn number (0 - for initial state, 1 - for the 1st
                   insn */
  int cost;     /* cost of the state in cycles */
  int accumulated_insns_num; /* number of all previous insns including
				nops.  L is considered as 2 insns */
  int branch_deviation; /* deviation of previous branches from 3rd slots  */
  int middle_bundle_stops; /* number of stop bits in the middle of bundles */
  struct bundle_state *next;  /* next state with the same insn_num  */
  struct bundle_state *originator; /* originator (previous insn state)  */
  /* All bundle states are in the following chain.  */
  struct bundle_state *allocated_states_chain;
  /* The DFA State after issuing the insn and the nops.  */
  state_t dfa_state;
};

/* The following is map insn number to the corresponding bundle state.  */

static struct bundle_state **index_to_bundle_states;

/* The unique number of next bundle state.  */

static int bundle_states_num;

/* All allocated bundle states are in the following chain.  */

static struct bundle_state *allocated_bundle_states_chain;

/* All allocated but not used bundle states are in the following
   chain.  */

static struct bundle_state *free_bundle_state_chain;


/* The following function returns a free bundle state.  */

static struct bundle_state *
get_free_bundle_state (void)
{
  struct bundle_state *result;

  if (free_bundle_state_chain != NULL)
    {
      result = free_bundle_state_chain;
      free_bundle_state_chain = result->next;
    }
  else
    {
      result = XNEW (struct bundle_state);
      result->dfa_state = xmalloc (dfa_state_size);
      result->allocated_states_chain = allocated_bundle_states_chain;
      allocated_bundle_states_chain = result;
    }
  result->unique_num = bundle_states_num++;
  return result;

}

/* The following function frees given bundle state.  */

static void
free_bundle_state (struct bundle_state *state)
{
  state->next = free_bundle_state_chain;
  free_bundle_state_chain = state;
}

/* Start work with abstract data `bundle states'.  */

static void
initiate_bundle_states (void)
{
  bundle_states_num = 0;
  free_bundle_state_chain = NULL;
  allocated_bundle_states_chain = NULL;
}

/* Finish work with abstract data `bundle states'.  */

static void
finish_bundle_states (void)
{
  struct bundle_state *curr_state, *next_state;

  for (curr_state = allocated_bundle_states_chain;
       curr_state != NULL;
       curr_state = next_state)
    {
      next_state = curr_state->allocated_states_chain;
      free (curr_state->dfa_state);
      free (curr_state);
    }
}

/* Hashtable helpers.  */

struct bundle_state_hasher : nofree_ptr_hash <bundle_state>
{
  static inline hashval_t hash (const bundle_state *);
  static inline bool equal (const bundle_state *, const bundle_state *);
};

/* The function returns hash of BUNDLE_STATE.  */

inline hashval_t
bundle_state_hasher::hash (const bundle_state *state)
{
  unsigned result, i;

  for (result = i = 0; i < dfa_state_size; i++)
    result += (((unsigned char *) state->dfa_state) [i]
	       << ((i % CHAR_BIT) * 3 + CHAR_BIT));
  return result + state->insn_num;
}

/* The function returns nonzero if the bundle state keys are equal.  */

inline bool
bundle_state_hasher::equal (const bundle_state *state1,
			    const bundle_state *state2)
{
  return (state1->insn_num == state2->insn_num
	  && memcmp (state1->dfa_state, state2->dfa_state,
		     dfa_state_size) == 0);
}

/* Hash table of the bundle states.  The key is dfa_state and insn_num
   of the bundle states.  */

static hash_table<bundle_state_hasher> *bundle_state_table;

/* The function inserts the BUNDLE_STATE into the hash table.  The
   function returns nonzero if the bundle has been inserted into the
   table.  The table contains the best bundle state with given key.  */

static int
insert_bundle_state (struct bundle_state *bundle_state)
{
  struct bundle_state **entry_ptr;

  entry_ptr = bundle_state_table->find_slot (bundle_state, INSERT);
  if (*entry_ptr == NULL)
    {
      bundle_state->next = index_to_bundle_states [bundle_state->insn_num];
      index_to_bundle_states [bundle_state->insn_num] = bundle_state;
      *entry_ptr = bundle_state;
      return TRUE;
    }
  else if (bundle_state->cost < (*entry_ptr)->cost
	   || (bundle_state->cost == (*entry_ptr)->cost
	       && ((*entry_ptr)->accumulated_insns_num
		   > bundle_state->accumulated_insns_num
		   || ((*entry_ptr)->accumulated_insns_num
		       == bundle_state->accumulated_insns_num
		       && ((*entry_ptr)->branch_deviation
			   > bundle_state->branch_deviation
			   || ((*entry_ptr)->branch_deviation
			       == bundle_state->branch_deviation
			       && (*entry_ptr)->middle_bundle_stops
			       > bundle_state->middle_bundle_stops))))))

    {
      struct bundle_state temp;

      temp = **entry_ptr;
      **entry_ptr = *bundle_state;
      (*entry_ptr)->next = temp.next;
      *bundle_state = temp;
    }
  return FALSE;
}

/* Start work with the hash table.  */

static void
initiate_bundle_state_table (void)
{
  bundle_state_table = new hash_table<bundle_state_hasher> (50);
}

/* Finish work with the hash table.  */

static void
finish_bundle_state_table (void)
{
  delete bundle_state_table;
  bundle_state_table = NULL;
}



/* The following variable is a insn `nop' used to check bundle states
   with different number of inserted nops.  */

static rtx_insn *ia64_nop;

/* The following function tries to issue NOPS_NUM nops for the current
   state without advancing processor cycle.  If it failed, the
   function returns FALSE and frees the current state.  */

static int
try_issue_nops (struct bundle_state *curr_state, int nops_num)
{
  int i;

  for (i = 0; i < nops_num; i++)
    if (state_transition (curr_state->dfa_state, ia64_nop) >= 0)
      {
	free_bundle_state (curr_state);
	return FALSE;
      }
  return TRUE;
}

/* The following function tries to issue INSN for the current
   state without advancing processor cycle.  If it failed, the
   function returns FALSE and frees the current state.  */

static int
try_issue_insn (struct bundle_state *curr_state, rtx insn)
{
  if (insn && state_transition (curr_state->dfa_state, insn) >= 0)
    {
      free_bundle_state (curr_state);
      return FALSE;
    }
  return TRUE;
}

/* The following function tries to issue BEFORE_NOPS_NUM nops and INSN
   starting with ORIGINATOR without advancing processor cycle.  If
   TRY_BUNDLE_END_P is TRUE, the function also/only (if
   ONLY_BUNDLE_END_P is TRUE) tries to issue nops to fill all bundle.
   If it was successful, the function creates new bundle state and
   insert into the hash table and into `index_to_bundle_states'.  */

static void
issue_nops_and_insn (struct bundle_state *originator, int before_nops_num,
		     rtx_insn *insn, int try_bundle_end_p,
		     int only_bundle_end_p)
{
  struct bundle_state *curr_state;

  curr_state = get_free_bundle_state ();
  memcpy (curr_state->dfa_state, originator->dfa_state, dfa_state_size);
  curr_state->insn = insn;
  curr_state->insn_num = originator->insn_num + 1;
  curr_state->cost = originator->cost;
  curr_state->originator = originator;
  curr_state->before_nops_num = before_nops_num;
  curr_state->after_nops_num = 0;
  curr_state->accumulated_insns_num
    = originator->accumulated_insns_num + before_nops_num;
  curr_state->branch_deviation = originator->branch_deviation;
  curr_state->middle_bundle_stops = originator->middle_bundle_stops;
  gcc_assert (insn);
  if (INSN_CODE (insn) == CODE_FOR_insn_group_barrier)
    {
      gcc_assert (GET_MODE (insn) != TImode);
      if (!try_issue_nops (curr_state, before_nops_num))
	return;
      if (!try_issue_insn (curr_state, insn))
	return;
      memcpy (temp_dfa_state, curr_state->dfa_state, dfa_state_size);
      if (curr_state->accumulated_insns_num % 3 != 0)
	curr_state->middle_bundle_stops++;
      if (state_transition (temp_dfa_state, dfa_pre_cycle_insn) >= 0
	  && curr_state->accumulated_insns_num % 3 != 0)
	{
	  free_bundle_state (curr_state);
	  return;
	}
    }
  else if (GET_MODE (insn) != TImode)
    {
      if (!try_issue_nops (curr_state, before_nops_num))
	return;
      if (!try_issue_insn (curr_state, insn))
	return;
      curr_state->accumulated_insns_num++;
      gcc_assert (!unknown_for_bundling_p (insn));

      if (ia64_safe_type (insn) == TYPE_L)
	curr_state->accumulated_insns_num++;
    }
  else
    {
      /* If this is an insn that must be first in a group, then don't allow
	 nops to be emitted before it.  Currently, alloc is the only such
	 supported instruction.  */
      /* ??? The bundling automatons should handle this for us, but they do
	 not yet have support for the first_insn attribute.  */
      if (before_nops_num > 0 && get_attr_first_insn (insn) == FIRST_INSN_YES)
	{
	  free_bundle_state (curr_state);
	  return;
	}

      state_transition (curr_state->dfa_state, dfa_pre_cycle_insn);
      state_transition (curr_state->dfa_state, NULL);
      curr_state->cost++;
      if (!try_issue_nops (curr_state, before_nops_num))
	return;
      if (!try_issue_insn (curr_state, insn))
	return;
      curr_state->accumulated_insns_num++;
      if (unknown_for_bundling_p (insn))
	{
	  /* Finish bundle containing asm insn.  */
	  curr_state->after_nops_num
	    = 3 - curr_state->accumulated_insns_num % 3;
	  curr_state->accumulated_insns_num
	    += 3 - curr_state->accumulated_insns_num % 3;
	}
      else if (ia64_safe_type (insn) == TYPE_L)
	curr_state->accumulated_insns_num++;
    }
  if (ia64_safe_type (insn) == TYPE_B)
    curr_state->branch_deviation
      += 2 - (curr_state->accumulated_insns_num - 1) % 3;
  if (try_bundle_end_p && curr_state->accumulated_insns_num % 3 != 0)
    {
      if (!only_bundle_end_p && insert_bundle_state (curr_state))
	{
	  state_t dfa_state;
	  struct bundle_state *curr_state1;
	  struct bundle_state *allocated_states_chain;

	  curr_state1 = get_free_bundle_state ();
	  dfa_state = curr_state1->dfa_state;
	  allocated_states_chain = curr_state1->allocated_states_chain;
	  *curr_state1 = *curr_state;
	  curr_state1->dfa_state = dfa_state;
	  curr_state1->allocated_states_chain = allocated_states_chain;
	  memcpy (curr_state1->dfa_state, curr_state->dfa_state,
		  dfa_state_size);
	  curr_state = curr_state1;
	}
      if (!try_issue_nops (curr_state,
			   3 - curr_state->accumulated_insns_num % 3))
	return;
      curr_state->after_nops_num
	= 3 - curr_state->accumulated_insns_num % 3;
      curr_state->accumulated_insns_num
	+= 3 - curr_state->accumulated_insns_num % 3;
    }
  if (!insert_bundle_state (curr_state))
    free_bundle_state (curr_state);
  return;
}

/* The following function returns position in the two window bundle
   for given STATE.  */

static int
get_max_pos (state_t state)
{
  if (cpu_unit_reservation_p (state, pos_6))
    return 6;
  else if (cpu_unit_reservation_p (state, pos_5))
    return 5;
  else if (cpu_unit_reservation_p (state, pos_4))
    return 4;
  else if (cpu_unit_reservation_p (state, pos_3))
    return 3;
  else if (cpu_unit_reservation_p (state, pos_2))
    return 2;
  else if (cpu_unit_reservation_p (state, pos_1))
    return 1;
  else
    return 0;
}

/* The function returns code of a possible template for given position
   and state.  The function should be called only with 2 values of
   position equal to 3 or 6.  We avoid generating F NOPs by putting
   templates containing F insns at the end of the template search
   because undocumented anomaly in McKinley derived cores which can
   cause stalls if an F-unit insn (including a NOP) is issued within a
   six-cycle window after reading certain application registers (such
   as ar.bsp).  Furthermore, power-considerations also argue against
   the use of F-unit instructions unless they're really needed.  */

static int
get_template (state_t state, int pos)
{
  switch (pos)
    {
    case 3:
      if (cpu_unit_reservation_p (state, _0mmi_))
	return 1;
      else if (cpu_unit_reservation_p (state, _0mii_))
	return 0;
      else if (cpu_unit_reservation_p (state, _0mmb_))
	return 7;
      else if (cpu_unit_reservation_p (state, _0mib_))
	return 6;
      else if (cpu_unit_reservation_p (state, _0mbb_))
	return 5;
      else if (cpu_unit_reservation_p (state, _0bbb_))
	return 4;
      else if (cpu_unit_reservation_p (state, _0mmf_))
	return 3;
      else if (cpu_unit_reservation_p (state, _0mfi_))
	return 2;
      else if (cpu_unit_reservation_p (state, _0mfb_))
	return 8;
      else if (cpu_unit_reservation_p (state, _0mlx_))
	return 9;
      else
	gcc_unreachable ();
    case 6:
      if (cpu_unit_reservation_p (state, _1mmi_))
	return 1;
      else if (cpu_unit_reservation_p (state, _1mii_))
	return 0;
      else if (cpu_unit_reservation_p (state, _1mmb_))
	return 7;
      else if (cpu_unit_reservation_p (state, _1mib_))
	return 6;
      else if (cpu_unit_reservation_p (state, _1mbb_))
	return 5;
      else if (cpu_unit_reservation_p (state, _1bbb_))
	return 4;
      else if (_1mmf_ >= 0 && cpu_unit_reservation_p (state, _1mmf_))
	return 3;
      else if (cpu_unit_reservation_p (state, _1mfi_))
	return 2;
      else if (cpu_unit_reservation_p (state, _1mfb_))
	return 8;
      else if (cpu_unit_reservation_p (state, _1mlx_))
	return 9;
      else
	gcc_unreachable ();
    default:
      gcc_unreachable ();
    }
}

/* True when INSN is important for bundling.  */

static bool
important_for_bundling_p (rtx_insn *insn)
{
  return (INSN_P (insn)
	  && ia64_safe_itanium_class (insn) != ITANIUM_CLASS_IGNORE
	  && GET_CODE (PATTERN (insn)) != USE
	  && GET_CODE (PATTERN (insn)) != CLOBBER);
}

/* The following function returns an insn important for insn bundling
   followed by INSN and before TAIL.  */

static rtx_insn *
get_next_important_insn (rtx_insn *insn, rtx_insn *tail)
{
  for (; insn && insn != tail; insn = NEXT_INSN (insn))
    if (important_for_bundling_p (insn))
      return insn;
  return NULL;
}

/* True when INSN is unknown, but important, for bundling.  */

static bool
unknown_for_bundling_p (rtx_insn *insn)
{
  return (INSN_P (insn)
	  && ia64_safe_itanium_class (insn) == ITANIUM_CLASS_UNKNOWN
	  && GET_CODE (PATTERN (insn)) != USE
	  && GET_CODE (PATTERN (insn)) != CLOBBER);
}

/* Add a bundle selector TEMPLATE0 before INSN.  */

static void
ia64_add_bundle_selector_before (int template0, rtx_insn *insn)
{
  rtx b = gen_bundle_selector (GEN_INT (template0));

  ia64_emit_insn_before (b, insn);
#if NR_BUNDLES == 10
  if ((template0 == 4 || template0 == 5)
      && ia64_except_unwind_info (&global_options) == UI_TARGET)
    {
      int i;
      rtx note = NULL_RTX;

      /* In .mbb and .bbb bundles, check if CALL_INSN isn't in the
	 first or second slot.  If it is and has REG_EH_NOTE set, copy it
	 to following nops, as br.call sets rp to the address of following
	 bundle and therefore an EH region end must be on a bundle
	 boundary.  */
      insn = PREV_INSN (insn);
      for (i = 0; i < 3; i++)
	{
	  do
	    insn = next_active_insn (insn);
	  while (NONJUMP_INSN_P (insn)
		 && get_attr_empty (insn) == EMPTY_YES);
	  if (CALL_P (insn))
	    note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
	  else if (note)
	    {
	      int code;

	      gcc_assert ((code = recog_memoized (insn)) == CODE_FOR_nop
			  || code == CODE_FOR_nop_b);
	      if (find_reg_note (insn, REG_EH_REGION, NULL_RTX))
		note = NULL_RTX;
	      else
		add_reg_note (insn, REG_EH_REGION, XEXP (note, 0));
	    }
	}
    }
#endif
}

/* The following function does insn bundling.  Bundling means
   inserting templates and nop insns to fit insn groups into permitted
   templates.  Instruction scheduling uses NDFA (non-deterministic
   finite automata) encoding informations about the templates and the
   inserted nops.  Nondeterminism of the automata permits follows
   all possible insn sequences very fast.

   Unfortunately it is not possible to get information about inserting
   nop insns and used templates from the automata states.  The
   automata only says that we can issue an insn possibly inserting
   some nops before it and using some template.  Therefore insn
   bundling in this function is implemented by using DFA
   (deterministic finite automata).  We follow all possible insn
   sequences by inserting 0-2 nops (that is what the NDFA describe for
   insn scheduling) before/after each insn being bundled.  We know the
   start of simulated processor cycle from insn scheduling (insn
   starting a new cycle has TImode).

   Simple implementation of insn bundling would create enormous
   number of possible insn sequences satisfying information about new
   cycle ticks taken from the insn scheduling.  To make the algorithm
   practical we use dynamic programming.  Each decision (about
   inserting nops and implicitly about previous decisions) is described
   by structure bundle_state (see above).  If we generate the same
   bundle state (key is automaton state after issuing the insns and
   nops for it), we reuse already generated one.  As consequence we
   reject some decisions which cannot improve the solution and
   reduce memory for the algorithm.

   When we reach the end of EBB (extended basic block), we choose the
   best sequence and then, moving back in EBB, insert templates for
   the best alternative.  The templates are taken from querying
   automaton state for each insn in chosen bundle states.

   So the algorithm makes two (forward and backward) passes through
   EBB.  */

static void
bundling (FILE *dump, int verbose, rtx_insn *prev_head_insn, rtx_insn *tail)
{
  struct bundle_state *curr_state, *next_state, *best_state;
  rtx_insn *insn, *next_insn;
  int insn_num;
  int i, bundle_end_p, only_bundle_end_p, asm_p;
  int pos = 0, max_pos, template0, template1;
  rtx_insn *b;
  enum attr_type type;

  insn_num = 0;
  /* Count insns in the EBB.  */
  for (insn = NEXT_INSN (prev_head_insn);
       insn && insn != tail;
       insn = NEXT_INSN (insn))
    if (INSN_P (insn))
      insn_num++;
  if (insn_num == 0)
    return;
  bundling_p = 1;
  dfa_clean_insn_cache ();
  initiate_bundle_state_table ();
  index_to_bundle_states = XNEWVEC (struct bundle_state *, insn_num + 2);
  /* First (forward) pass -- generation of bundle states.  */
  curr_state = get_free_bundle_state ();
  curr_state->insn = NULL;
  curr_state->before_nops_num = 0;
  curr_state->after_nops_num = 0;
  curr_state->insn_num = 0;
  curr_state->cost = 0;
  curr_state->accumulated_insns_num = 0;
  curr_state->branch_deviation = 0;
  curr_state->middle_bundle_stops = 0;
  curr_state->next = NULL;
  curr_state->originator = NULL;
  state_reset (curr_state->dfa_state);
  index_to_bundle_states [0] = curr_state;
  insn_num = 0;
  /* Shift cycle mark if it is put on insn which could be ignored.  */
  for (insn = NEXT_INSN (prev_head_insn);
       insn != tail;
       insn = NEXT_INSN (insn))
    if (INSN_P (insn)
	&& !important_for_bundling_p (insn)
	&& GET_MODE (insn) == TImode)
      {
	PUT_MODE (insn, VOIDmode);
	for (next_insn = NEXT_INSN (insn);
	     next_insn != tail;
	     next_insn = NEXT_INSN (next_insn))
	  if (important_for_bundling_p (next_insn)
	      && INSN_CODE (next_insn) != CODE_FOR_insn_group_barrier)
	    {
	      PUT_MODE (next_insn, TImode);
	      break;
	    }
      }
  /* Forward pass: generation of bundle states.  */
  for (insn = get_next_important_insn (NEXT_INSN (prev_head_insn), tail);
       insn != NULL_RTX;
       insn = next_insn)
    {
      gcc_assert (important_for_bundling_p (insn));
      type = ia64_safe_type (insn);
      next_insn = get_next_important_insn (NEXT_INSN (insn), tail);
      insn_num++;
      index_to_bundle_states [insn_num] = NULL;
      for (curr_state = index_to_bundle_states [insn_num - 1];
	   curr_state != NULL;
	   curr_state = next_state)
	{
	  pos = curr_state->accumulated_insns_num % 3;
	  next_state = curr_state->next;
	  /* We must fill up the current bundle in order to start a
	     subsequent asm insn in a new bundle.  Asm insn is always
	     placed in a separate bundle.  */
	  only_bundle_end_p
	    = (next_insn != NULL_RTX
	       && INSN_CODE (insn) == CODE_FOR_insn_group_barrier
	       && unknown_for_bundling_p (next_insn));
	  /* We may fill up the current bundle if it is the cycle end
	     without a group barrier.  */
	  bundle_end_p
	    = (only_bundle_end_p || next_insn == NULL_RTX
	       || (GET_MODE (next_insn) == TImode
		   && INSN_CODE (insn) != CODE_FOR_insn_group_barrier));
	  if (type == TYPE_F || type == TYPE_B || type == TYPE_L
	      || type == TYPE_S)
	    issue_nops_and_insn (curr_state, 2, insn, bundle_end_p,
				 only_bundle_end_p);
	  issue_nops_and_insn (curr_state, 1, insn, bundle_end_p,
			       only_bundle_end_p);
	  issue_nops_and_insn (curr_state, 0, insn, bundle_end_p,
			       only_bundle_end_p);
	}
      gcc_assert (index_to_bundle_states [insn_num]);
      for (curr_state = index_to_bundle_states [insn_num];
	   curr_state != NULL;
	   curr_state = curr_state->next)
	if (verbose >= 2 && dump)
	  {
	    /* This structure is taken from generated code of the
	       pipeline hazard recognizer (see file insn-attrtab.cc).
	       Please don't forget to change the structure if a new
	       automaton is added to .md file.  */
	    struct DFA_chip
	    {
	      unsigned short one_automaton_state;
	      unsigned short oneb_automaton_state;
	      unsigned short two_automaton_state;
	      unsigned short twob_automaton_state;
	    };

	    fprintf
	      (dump,
	       "//    Bundle state %d (orig %d, cost %d, nops %d/%d, insns %d, branch %d, mid.stops %d state %d) for %d\n",
	       curr_state->unique_num,
	       (curr_state->originator == NULL
		? -1 : curr_state->originator->unique_num),
	       curr_state->cost,
	       curr_state->before_nops_num, curr_state->after_nops_num,
	       curr_state->accumulated_insns_num, curr_state->branch_deviation,
	       curr_state->middle_bundle_stops,
	       ((struct DFA_chip *) curr_state->dfa_state)->twob_automaton_state,
	       INSN_UID (insn));
	  }
    }
  
  /* We should find a solution because the 2nd insn scheduling has
     found one.  */
  gcc_assert (index_to_bundle_states [insn_num]);
  /* Find a state corresponding to the best insn sequence.  */
  best_state = NULL;
  for (curr_state = index_to_bundle_states [insn_num];
       curr_state != NULL;
       curr_state = curr_state->next)
    /* We are just looking at the states with fully filled up last
       bundle.  The first we prefer insn sequences with minimal cost
       then with minimal inserted nops and finally with branch insns
       placed in the 3rd slots.  */
    if (curr_state->accumulated_insns_num % 3 == 0
	&& (best_state == NULL || best_state->cost > curr_state->cost
	    || (best_state->cost == curr_state->cost
		&& (curr_state->accumulated_insns_num
		    < best_state->accumulated_insns_num
		    || (curr_state->accumulated_insns_num
			== best_state->accumulated_insns_num
			&& (curr_state->branch_deviation
			    < best_state->branch_deviation
			    || (curr_state->branch_deviation
				== best_state->branch_deviation
				&& curr_state->middle_bundle_stops
				< best_state->middle_bundle_stops)))))))
      best_state = curr_state;
  /* Second (backward) pass: adding nops and templates.  */
  gcc_assert (best_state);
  insn_num = best_state->before_nops_num;
  template0 = template1 = -1;
  for (curr_state = best_state;
       curr_state->originator != NULL;
       curr_state = curr_state->originator)
    {
      insn = curr_state->insn;
      asm_p = unknown_for_bundling_p (insn);
      insn_num++;
      if (verbose >= 2 && dump)
	{
	  struct DFA_chip
	  {
	    unsigned short one_automaton_state;
	    unsigned short oneb_automaton_state;
	    unsigned short two_automaton_state;
	    unsigned short twob_automaton_state;
	  };

	  fprintf
	    (dump,
	     "//    Best %d (orig %d, cost %d, nops %d/%d, insns %d, branch %d, mid.stops %d, state %d) for %d\n",
	     curr_state->unique_num,
	     (curr_state->originator == NULL
	      ? -1 : curr_state->originator->unique_num),
	     curr_state->cost,
	     curr_state->before_nops_num, curr_state->after_nops_num,
	     curr_state->accumulated_insns_num, curr_state->branch_deviation,
	     curr_state->middle_bundle_stops,
	     ((struct DFA_chip *) curr_state->dfa_state)->twob_automaton_state,
	     INSN_UID (insn));
	}
      /* Find the position in the current bundle window.  The window can
	 contain at most two bundles.  Two bundle window means that
	 the processor will make two bundle rotation.  */
      max_pos = get_max_pos (curr_state->dfa_state);
      if (max_pos == 6
	  /* The following (negative template number) means that the
	     processor did one bundle rotation.  */
	  || (max_pos == 3 && template0 < 0))
	{
	  /* We are at the end of the window -- find template(s) for
	     its bundle(s).  */
	  pos = max_pos;
	  if (max_pos == 3)
	    template0 = get_template (curr_state->dfa_state, 3);
	  else
	    {
	      template1 = get_template (curr_state->dfa_state, 3);
	      template0 = get_template (curr_state->dfa_state, 6);
	    }
	}
      if (max_pos > 3 && template1 < 0)
	/* It may happen when we have the stop inside a bundle.  */
	{
	  gcc_assert (pos <= 3);
	  template1 = get_template (curr_state->dfa_state, 3);
	  pos += 3;
	}
      if (!asm_p)
	/* Emit nops after the current insn.  */
	for (i = 0; i < curr_state->after_nops_num; i++)
	  {
	    rtx nop_pat = gen_nop ();
	    rtx_insn *nop = emit_insn_after (nop_pat, insn);
	    pos--;
	    gcc_assert (pos >= 0);
	    if (pos % 3 == 0)
	      {
		/* We are at the start of a bundle: emit the template
		   (it should be defined).  */
		gcc_assert (template0 >= 0);
		ia64_add_bundle_selector_before (template0, nop);
		/* If we have two bundle window, we make one bundle
		   rotation.  Otherwise template0 will be undefined
		   (negative value).  */
		template0 = template1;
		template1 = -1;
	      }
	  }
      /* Move the position backward in the window.  Group barrier has
	 no slot.  Asm insn takes all bundle.  */
      if (INSN_CODE (insn) != CODE_FOR_insn_group_barrier
	  && !unknown_for_bundling_p (insn))
	pos--;
      /* Long insn takes 2 slots.  */
      if (ia64_safe_type (insn) == TYPE_L)
	pos--;
      gcc_assert (pos >= 0);
      if (pos % 3 == 0
	  && INSN_CODE (insn) != CODE_FOR_insn_group_barrier
	  && !unknown_for_bundling_p (insn))
	{
	  /* The current insn is at the bundle start: emit the
	     template.  */
	  gcc_assert (template0 >= 0);
	  ia64_add_bundle_selector_before (template0, insn);
	  b = PREV_INSN (insn);
	  insn = b;
	  /* See comment above in analogous place for emitting nops
	     after the insn.  */
	  template0 = template1;
	  template1 = -1;
	}
      /* Emit nops after the current insn.  */
      for (i = 0; i < curr_state->before_nops_num; i++)
	{
	  rtx nop_pat = gen_nop ();
	  ia64_emit_insn_before (nop_pat, insn);
	  rtx_insn *nop = PREV_INSN (insn);
	  insn = nop;
	  pos--;
	  gcc_assert (pos >= 0);
	  if (pos % 3 == 0)
	    {
	      /* See comment above in analogous place for emitting nops
		 after the insn.  */
	      gcc_assert (template0 >= 0);
	      ia64_add_bundle_selector_before (template0, insn);
	      b = PREV_INSN (insn);
	      insn = b;
	      template0 = template1;
	      template1 = -1;
	    }
	}
    }

  if (flag_checking)
    {
      /* Assert right calculation of middle_bundle_stops.  */
      int num = best_state->middle_bundle_stops;
      bool start_bundle = true, end_bundle = false;

      for (insn = NEXT_INSN (prev_head_insn);
	   insn && insn != tail;
	   insn = NEXT_INSN (insn))
	{
	  if (!INSN_P (insn))
	    continue;
	  if (recog_memoized (insn) == CODE_FOR_bundle_selector)
	    start_bundle = true;
	  else
	    {
	      rtx_insn *next_insn;

	      for (next_insn = NEXT_INSN (insn);
		   next_insn && next_insn != tail;
		   next_insn = NEXT_INSN (next_insn))
		if (INSN_P (next_insn)
		    && (ia64_safe_itanium_class (next_insn)
			!= ITANIUM_CLASS_IGNORE
			|| recog_memoized (next_insn)
			== CODE_FOR_bundle_selector)
		    && GET_CODE (PATTERN (next_insn)) != USE
		    && GET_CODE (PATTERN (next_insn)) != CLOBBER)
		  break;

	      end_bundle = next_insn == NULL_RTX
		|| next_insn == tail
		|| (INSN_P (next_insn)
		    && recog_memoized (next_insn) == CODE_FOR_bundle_selector);
	      if (recog_memoized (insn) == CODE_FOR_insn_group_barrier
		  && !start_bundle && !end_bundle
		  && next_insn
		  && !unknown_for_bundling_p (next_insn))
		num--;

	      start_bundle = false;
	    }
	}

      gcc_assert (num == 0);
    }

  free (index_to_bundle_states);
  finish_bundle_state_table ();
  bundling_p = 0;
  dfa_clean_insn_cache ();
}

/* The following function is called at the end of scheduling BB or
   EBB.  After reload, it inserts stop bits and does insn bundling.  */

static void
ia64_sched_finish (FILE *dump, int sched_verbose)
{
  if (sched_verbose)
    fprintf (dump, "// Finishing schedule.\n");
  if (!reload_completed)
    return;
  if (reload_completed)
    {
      final_emit_insn_group_barriers (dump);
      bundling (dump, sched_verbose, current_sched_info->prev_head,
		current_sched_info->next_tail);
      if (sched_verbose && dump)
	fprintf (dump, "//    finishing %d-%d\n",
		 INSN_UID (NEXT_INSN (current_sched_info->prev_head)),
		 INSN_UID (PREV_INSN (current_sched_info->next_tail)));

      return;
    }
}

/* The following function inserts stop bits in scheduled BB or EBB.  */

static void
final_emit_insn_group_barriers (FILE *dump ATTRIBUTE_UNUSED)
{
  rtx_insn *insn;
  int need_barrier_p = 0;
  int seen_good_insn = 0;

  init_insn_group_barriers ();

  for (insn = NEXT_INSN (current_sched_info->prev_head);
       insn != current_sched_info->next_tail;
       insn = NEXT_INSN (insn))
    {
      if (BARRIER_P (insn))
	{
	  rtx_insn *last = prev_active_insn (insn);

	  if (! last)
	    continue;
	  if (JUMP_TABLE_DATA_P (last))
	    last = prev_active_insn (last);
	  if (recog_memoized (last) != CODE_FOR_insn_group_barrier)
	    emit_insn_after (gen_insn_group_barrier (GEN_INT (3)), last);

	  init_insn_group_barriers ();
	  seen_good_insn = 0;
	  need_barrier_p = 0;
	}
      else if (NONDEBUG_INSN_P (insn))
	{
	  if (recog_memoized (insn) == CODE_FOR_insn_group_barrier)
	    {
	      init_insn_group_barriers ();
	      seen_good_insn = 0;
	      need_barrier_p = 0;
	    }
	  else if (need_barrier_p || group_barrier_needed (insn)
		   || (mflag_sched_stop_bits_after_every_cycle
		       && GET_MODE (insn) == TImode
		       && seen_good_insn))
	    {
	      if (TARGET_EARLY_STOP_BITS)
		{
		  rtx_insn *last;

		  for (last = insn;
		       last != current_sched_info->prev_head;
		       last = PREV_INSN (last))
		    if (INSN_P (last) && GET_MODE (last) == TImode
			&& stops_p [INSN_UID (last)])
		      break;
		  if (last == current_sched_info->prev_head)
		    last = insn;
		  last = prev_active_insn (last);
		  if (last
		      && recog_memoized (last) != CODE_FOR_insn_group_barrier)
		    emit_insn_after (gen_insn_group_barrier (GEN_INT (3)),
				     last);
		  init_insn_group_barriers ();
		  for (last = NEXT_INSN (last);
		       last != insn;
		       last = NEXT_INSN (last))
		    if (INSN_P (last))
		      {
			group_barrier_needed (last);
			if (recog_memoized (last) >= 0
			    && important_for_bundling_p (last))
			  seen_good_insn = 1;
		      }
		}
	      else
		{
		  emit_insn_before (gen_insn_group_barrier (GEN_INT (3)),
				    insn);
		  init_insn_group_barriers ();
		  seen_good_insn = 0;
		}
	      group_barrier_needed (insn);
	      if (recog_memoized (insn) >= 0
		  && important_for_bundling_p (insn))
		seen_good_insn = 1;
	    }
	  else if (recog_memoized (insn) >= 0
		   && important_for_bundling_p (insn))
	    seen_good_insn = 1;
	  need_barrier_p = (CALL_P (insn) || unknown_for_bundling_p (insn));
	}
    }
}



/* If the following function returns TRUE, we will use the DFA
   insn scheduler.  */

static int
ia64_first_cycle_multipass_dfa_lookahead (void)
{
  return (reload_completed ? 6 : 4);
}

/* The following function initiates variable `dfa_pre_cycle_insn'.  */

static void
ia64_init_dfa_pre_cycle_insn (void)
{
  if (temp_dfa_state == NULL)
    {
      dfa_state_size = state_size ();
      temp_dfa_state = xmalloc (dfa_state_size);
      prev_cycle_state = xmalloc (dfa_state_size);
    }
  dfa_pre_cycle_insn = make_insn_raw (gen_pre_cycle ());
  SET_PREV_INSN (dfa_pre_cycle_insn) = SET_NEXT_INSN (dfa_pre_cycle_insn) = NULL_RTX;
  recog_memoized (dfa_pre_cycle_insn);
  dfa_stop_insn = make_insn_raw (gen_insn_group_barrier (GEN_INT (3)));
  SET_PREV_INSN (dfa_stop_insn) = SET_NEXT_INSN (dfa_stop_insn) = NULL_RTX;
  recog_memoized (dfa_stop_insn);
}

/* The following function returns the pseudo insn DFA_PRE_CYCLE_INSN
   used by the DFA insn scheduler.  */

static rtx
ia64_dfa_pre_cycle_insn (void)
{
  return dfa_pre_cycle_insn;
}

/* The following function returns TRUE if PRODUCER (of type ilog or
   ld) produces address for CONSUMER (of type st or stf). */

int
ia64_st_address_bypass_p (rtx_insn *producer, rtx_insn *consumer)
{
  rtx dest, reg, mem;

  gcc_assert (producer && consumer);
  dest = ia64_single_set (producer);
  gcc_assert (dest);
  reg = SET_DEST (dest);
  gcc_assert (reg);
  if (GET_CODE (reg) == SUBREG)
    reg = SUBREG_REG (reg);
  gcc_assert (GET_CODE (reg) == REG);
  
  dest = ia64_single_set (consumer);
  gcc_assert (dest);
  mem = SET_DEST (dest);
  gcc_assert (mem && GET_CODE (mem) == MEM);
  return reg_mentioned_p (reg, mem);
}

/* The following function returns TRUE if PRODUCER (of type ilog or
   ld) produces address for CONSUMER (of type ld or fld). */

int
ia64_ld_address_bypass_p (rtx_insn *producer, rtx_insn *consumer)
{
  rtx dest, src, reg, mem;

  gcc_assert (producer && consumer);
  dest = ia64_single_set (producer);
  gcc_assert (dest);
  reg = SET_DEST (dest);
  gcc_assert (reg);
  if (GET_CODE (reg) == SUBREG)
    reg = SUBREG_REG (reg);
  gcc_assert (GET_CODE (reg) == REG);
  
  src = ia64_single_set (consumer);
  gcc_assert (src);
  mem = SET_SRC (src);
  gcc_assert (mem);
 
  if (GET_CODE (mem) == UNSPEC && XVECLEN (mem, 0) > 0)
    mem = XVECEXP (mem, 0, 0);
  else if (GET_CODE (mem) == IF_THEN_ELSE)
    /* ??? Is this bypass necessary for ld.c?  */
    {
      gcc_assert (XINT (XEXP (XEXP (mem, 0), 0), 1) == UNSPEC_LDCCLR);
      mem = XEXP (mem, 1);
    }
     
  while (GET_CODE (mem) == SUBREG || GET_CODE (mem) == ZERO_EXTEND)
    mem = XEXP (mem, 0);

  if (GET_CODE (mem) == UNSPEC)
    {
      int c = XINT (mem, 1);

      gcc_assert (c == UNSPEC_LDA || c == UNSPEC_LDS || c == UNSPEC_LDS_A
		  || c == UNSPEC_LDSA);
      mem = XVECEXP (mem, 0, 0);
    }

  /* Note that LO_SUM is used for GOT loads.  */
  gcc_assert (GET_CODE (mem) == LO_SUM || GET_CODE (mem) == MEM);

  return reg_mentioned_p (reg, mem);
}

/* The following function returns TRUE if INSN produces address for a
   load/store insn.  We will place such insns into M slot because it
   decreases its latency time.  */

int
ia64_produce_address_p (rtx insn)
{
  return insn->call;
}


/* Emit pseudo-ops for the assembler to describe predicate relations.
   At present this assumes that we only consider predicate pairs to
   be mutex, and that the assembler can deduce proper values from
   straight-line code.  */

static void
emit_predicate_relation_info (void)
{
  basic_block bb;

  FOR_EACH_BB_REVERSE_FN (bb, cfun)
    {
      int r;
      rtx_insn *head = BB_HEAD (bb);

      /* We only need such notes at code labels.  */
      if (! LABEL_P (head))
	continue;
      if (NOTE_INSN_BASIC_BLOCK_P (NEXT_INSN (head)))
	head = NEXT_INSN (head);

      /* Skip p0, which may be thought to be live due to (reg:DI p0)
	 grabbing the entire block of predicate registers.  */
      for (r = PR_REG (2); r < PR_REG (64); r += 2)
	if (REGNO_REG_SET_P (df_get_live_in (bb), r))
	  {
	    rtx p = gen_rtx_REG (BImode, r);
	    rtx_insn *n = emit_insn_after (gen_pred_rel_mutex (p), head);
	    if (head == BB_END (bb))
	      BB_END (bb) = n;
	    head = n;
	  }
    }

  /* Look for conditional calls that do not return, and protect predicate
     relations around them.  Otherwise the assembler will assume the call
     returns, and complain about uses of call-clobbered predicates after
     the call.  */
  FOR_EACH_BB_REVERSE_FN (bb, cfun)
    {
      rtx_insn *insn = BB_HEAD (bb);

      while (1)
	{
	  if (CALL_P (insn)
	      && GET_CODE (PATTERN (insn)) == COND_EXEC
	      && find_reg_note (insn, REG_NORETURN, NULL_RTX))
	    {
	      rtx_insn *b =
		emit_insn_before (gen_safe_across_calls_all (), insn);
	      rtx_insn *a = emit_insn_after (gen_safe_across_calls_normal (), insn);
	      if (BB_HEAD (bb) == insn)
		BB_HEAD (bb) = b;
	      if (BB_END (bb) == insn)
		BB_END (bb) = a;
	    }

	  if (insn == BB_END (bb))
	    break;
	  insn = NEXT_INSN (insn);
	}
    }
}

/* Perform machine dependent operations on the rtl chain INSNS.  */

static void
ia64_reorg (void)
{
  /* We are freeing block_for_insn in the toplev to keep compatibility
     with old MDEP_REORGS that are not CFG based.  Recompute it now.  */
  compute_bb_for_insn ();

  /* If optimizing, we'll have split before scheduling.  */
  if (optimize == 0)
    split_all_insns ();

  if (optimize && flag_schedule_insns_after_reload
      && dbg_cnt (ia64_sched2))
    {
      basic_block bb;
      timevar_push (TV_SCHED2);
      ia64_final_schedule = 1;

      /* We can't let modulo-sched prevent us from scheduling any bbs,
	 since we need the final schedule to produce bundle information.  */
      FOR_EACH_BB_FN (bb, cfun)
	bb->flags &= ~BB_DISABLE_SCHEDULE;

      initiate_bundle_states ();
      ia64_nop = make_insn_raw (gen_nop ());
      SET_PREV_INSN (ia64_nop) = SET_NEXT_INSN (ia64_nop) = NULL_RTX;
      recog_memoized (ia64_nop);
      clocks_length = get_max_uid () + 1;
      stops_p = XCNEWVEC (char, clocks_length);

      if (ia64_tune == PROCESSOR_ITANIUM2)
	{
	  pos_1 = get_cpu_unit_code ("2_1");
	  pos_2 = get_cpu_unit_code ("2_2");
	  pos_3 = get_cpu_unit_code ("2_3");
	  pos_4 = get_cpu_unit_code ("2_4");
	  pos_5 = get_cpu_unit_code ("2_5");
	  pos_6 = get_cpu_unit_code ("2_6");
	  _0mii_ = get_cpu_unit_code ("2b_0mii.");
	  _0mmi_ = get_cpu_unit_code ("2b_0mmi.");
	  _0mfi_ = get_cpu_unit_code ("2b_0mfi.");
	  _0mmf_ = get_cpu_unit_code ("2b_0mmf.");
	  _0bbb_ = get_cpu_unit_code ("2b_0bbb.");
	  _0mbb_ = get_cpu_unit_code ("2b_0mbb.");
	  _0mib_ = get_cpu_unit_code ("2b_0mib.");
	  _0mmb_ = get_cpu_unit_code ("2b_0mmb.");
	  _0mfb_ = get_cpu_unit_code ("2b_0mfb.");
	  _0mlx_ = get_cpu_unit_code ("2b_0mlx.");
	  _1mii_ = get_cpu_unit_code ("2b_1mii.");
	  _1mmi_ = get_cpu_unit_code ("2b_1mmi.");
	  _1mfi_ = get_cpu_unit_code ("2b_1mfi.");
	  _1mmf_ = get_cpu_unit_code ("2b_1mmf.");
	  _1bbb_ = get_cpu_unit_code ("2b_1bbb.");
	  _1mbb_ = get_cpu_unit_code ("2b_1mbb.");
	  _1mib_ = get_cpu_unit_code ("2b_1mib.");
	  _1mmb_ = get_cpu_unit_code ("2b_1mmb.");
	  _1mfb_ = get_cpu_unit_code ("2b_1mfb.");
	  _1mlx_ = get_cpu_unit_code ("2b_1mlx.");
	}
      else
	{
	  pos_1 = get_cpu_unit_code ("1_1");
	  pos_2 = get_cpu_unit_code ("1_2");
	  pos_3 = get_cpu_unit_code ("1_3");
	  pos_4 = get_cpu_unit_code ("1_4");
	  pos_5 = get_cpu_unit_code ("1_5");
	  pos_6 = get_cpu_unit_code ("1_6");
	  _0mii_ = get_cpu_unit_code ("1b_0mii.");
	  _0mmi_ = get_cpu_unit_code ("1b_0mmi.");
	  _0mfi_ = get_cpu_unit_code ("1b_0mfi.");
	  _0mmf_ = get_cpu_unit_code ("1b_0mmf.");
	  _0bbb_ = get_cpu_unit_code ("1b_0bbb.");
	  _0mbb_ = get_cpu_unit_code ("1b_0mbb.");
	  _0mib_ = get_cpu_unit_code ("1b_0mib.");
	  _0mmb_ = get_cpu_unit_code ("1b_0mmb.");
	  _0mfb_ = get_cpu_unit_code ("1b_0mfb.");
	  _0mlx_ = get_cpu_unit_code ("1b_0mlx.");
	  _1mii_ = get_cpu_unit_code ("1b_1mii.");
	  _1mmi_ = get_cpu_unit_code ("1b_1mmi.");
	  _1mfi_ = get_cpu_unit_code ("1b_1mfi.");
	  _1mmf_ = get_cpu_unit_code ("1b_1mmf.");
	  _1bbb_ = get_cpu_unit_code ("1b_1bbb.");
	  _1mbb_ = get_cpu_unit_code ("1b_1mbb.");
	  _1mib_ = get_cpu_unit_code ("1b_1mib.");
	  _1mmb_ = get_cpu_unit_code ("1b_1mmb.");
	  _1mfb_ = get_cpu_unit_code ("1b_1mfb.");
	  _1mlx_ = get_cpu_unit_code ("1b_1mlx.");
	}

      if (flag_selective_scheduling2
	  && !maybe_skip_selective_scheduling ())
        run_selective_scheduling ();
      else
	schedule_ebbs ();

      /* Redo alignment computation, as it might gone wrong.  */
      compute_alignments ();

      /* We cannot reuse this one because it has been corrupted by the
	 evil glat.  */
      finish_bundle_states ();
      free (stops_p);
      stops_p = NULL;
      emit_insn_group_barriers (dump_file);

      ia64_final_schedule = 0;
      timevar_pop (TV_SCHED2);
    }
  else
    emit_all_insn_group_barriers (dump_file);

  df_analyze ();
 
  /* A call must not be the last instruction in a function, so that the
     return address is still within the function, so that unwinding works
     properly.  Note that IA-64 differs from dwarf2 on this point.  */
  if (ia64_except_unwind_info (&global_options) == UI_TARGET)
    {
      rtx_insn *insn;
      int saw_stop = 0;

      insn = get_last_insn ();
      if (! INSN_P (insn))
        insn = prev_active_insn (insn);
      if (insn)
	{
	  /* Skip over insns that expand to nothing.  */
	  while (NONJUMP_INSN_P (insn)
		 && get_attr_empty (insn) == EMPTY_YES)
	    {
	      if (GET_CODE (PATTERN (insn)) == UNSPEC_VOLATILE
		  && XINT (PATTERN (insn), 1) == UNSPECV_INSN_GROUP_BARRIER)
		saw_stop = 1;
	      insn = prev_active_insn (insn);
	    }
	  if (CALL_P (insn))
	    {
	      if (! saw_stop)
		emit_insn (gen_insn_group_barrier (GEN_INT (3)));
	      emit_insn (gen_break_f ());
	      emit_insn (gen_insn_group_barrier (GEN_INT (3)));
	    }
	}
    }

  emit_predicate_relation_info ();

  if (flag_var_tracking)
    {
      timevar_push (TV_VAR_TRACKING);
      variable_tracking_main ();
      timevar_pop (TV_VAR_TRACKING);
    }
  df_finish_pass (false);
}

/* Return true if REGNO is used by the epilogue.  */

int
ia64_epilogue_uses (int regno)
{
  switch (regno)
    {
    case R_GR (1):
      /* With a call to a function in another module, we will write a new
	 value to "gp".  After returning from such a call, we need to make
	 sure the function restores the original gp-value, even if the
	 function itself does not use the gp anymore.  */
      return !(TARGET_AUTO_PIC || TARGET_NO_PIC);

    case IN_REG (0): case IN_REG (1): case IN_REG (2): case IN_REG (3):
    case IN_REG (4): case IN_REG (5): case IN_REG (6): case IN_REG (7):
      /* For functions defined with the syscall_linkage attribute, all
	 input registers are marked as live at all function exits.  This
	 prevents the register allocator from using the input registers,
	 which in turn makes it possible to restart a system call after
	 an interrupt without having to save/restore the input registers.
	 This also prevents kernel data from leaking to application code.  */
      return lookup_attribute ("syscall_linkage",
	   TYPE_ATTRIBUTES (TREE_TYPE (current_function_decl))) != NULL;

    case R_BR (0):
      /* Conditional return patterns can't represent the use of `b0' as
         the return address, so we force the value live this way.  */
      return 1;

    case AR_PFS_REGNUM:
      /* Likewise for ar.pfs, which is used by br.ret.  */
      return 1;

    default:
      return 0;
    }
}

/* Return true if REGNO is used by the frame unwinder.  */

int
ia64_eh_uses (int regno)
{
  unsigned int r;

  if (! reload_completed)
    return 0;

  if (regno == 0)
    return 0;

  for (r = reg_save_b0; r <= reg_save_ar_lc; r++)
    if (regno == current_frame_info.r[r]
       || regno == emitted_frame_related_regs[r])
      return 1;

  return 0;
}

/* Return true if this goes in small data/bss.  */

/* ??? We could also support own long data here.  Generating movl/add/ld8
   instead of addl,ld8/ld8.  This makes the code bigger, but should make the
   code faster because there is one less load.  This also includes incomplete
   types which can't go in sdata/sbss.  */

static bool
ia64_in_small_data_p (const_tree exp)
{
  if (TARGET_NO_SDATA)
    return false;

  /* We want to merge strings, so we never consider them small data.  */
  if (TREE_CODE (exp) == STRING_CST)
    return false;

  /* Functions are never small data.  */
  if (TREE_CODE (exp) == FUNCTION_DECL)
    return false;

  if (TREE_CODE (exp) == VAR_DECL && DECL_SECTION_NAME (exp))
    {
      const char *section = DECL_SECTION_NAME (exp);

      if (strcmp (section, ".sdata") == 0
	  || startswith (section, ".sdata.")
	  || startswith (section, ".gnu.linkonce.s.")
	  || strcmp (section, ".sbss") == 0
	  || startswith (section, ".sbss.")
	  || startswith (section, ".gnu.linkonce.sb."))
	return true;
    }
  else
    {
      HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (exp));

      /* If this is an incomplete type with size 0, then we can't put it
	 in sdata because it might be too big when completed.  */
      if (size > 0 && size <= ia64_section_threshold)
	return true;
    }

  return false;
}

/* Output assembly directives for prologue regions.  */

/* The current basic block number.  */

static bool last_block;

/* True if we need a copy_state command at the start of the next block.  */

static bool need_copy_state;

#ifndef MAX_ARTIFICIAL_LABEL_BYTES
# define MAX_ARTIFICIAL_LABEL_BYTES 30
#endif

/* The function emits unwind directives for the start of an epilogue.  */

static void
process_epilogue (FILE *out_file, rtx insn ATTRIBUTE_UNUSED,
		  bool unwind, bool frame ATTRIBUTE_UNUSED)
{
  /* If this isn't the last block of the function, then we need to label the
     current state, and copy it back in at the start of the next block.  */

  if (!last_block)
    {
      if (unwind)
	fprintf (out_file, "\t.label_state %d\n",
		 ++cfun->machine->state_num);
      need_copy_state = true;
    }

  if (unwind)
    fprintf (out_file, "\t.restore sp\n");
}

/* This function processes a SET pattern for REG_CFA_ADJUST_CFA.  */

static void
process_cfa_adjust_cfa (FILE *out_file, rtx pat, rtx insn,
			bool unwind, bool frame)
{
  rtx dest = SET_DEST (pat);
  rtx src = SET_SRC (pat);

  if (dest == stack_pointer_rtx)
    {
      if (GET_CODE (src) == PLUS)
	{
	  rtx op0 = XEXP (src, 0);
	  rtx op1 = XEXP (src, 1);
	  
	  gcc_assert (op0 == dest && GET_CODE (op1) == CONST_INT);
	  
	  if (INTVAL (op1) < 0)
	    {
	      gcc_assert (!frame_pointer_needed);
	      if (unwind)
		fprintf (out_file,
			 "\t.fframe " HOST_WIDE_INT_PRINT_DEC"\n",
			 -INTVAL (op1));
	    }
	  else
	    process_epilogue (out_file, insn, unwind, frame);
	}
      else
	{
	  gcc_assert (src == hard_frame_pointer_rtx);
	  process_epilogue (out_file, insn, unwind, frame);
	}
    }
  else if (dest == hard_frame_pointer_rtx)
    {
      gcc_assert (src == stack_pointer_rtx);
      gcc_assert (frame_pointer_needed);

      if (unwind)
	fprintf (out_file, "\t.vframe r%d\n",
		 ia64_debugger_regno (REGNO (dest)));
    }
  else
    gcc_unreachable ();
}

/* This function processes a SET pattern for REG_CFA_REGISTER.  */

static void
process_cfa_register (FILE *out_file, rtx pat, bool unwind)
{
  rtx dest = SET_DEST (pat);
  rtx src = SET_SRC (pat);
  int dest_regno = REGNO (dest);
  int src_regno;

  if (src == pc_rtx)
    {
      /* Saving return address pointer.  */
      if (unwind)
	fprintf (out_file, "\t.save rp, r%d\n",
		 ia64_debugger_regno (dest_regno));
      return;
    }

  src_regno = REGNO (src);

  switch (src_regno)
    {
    case PR_REG (0):
      gcc_assert (dest_regno == current_frame_info.r[reg_save_pr]);
      if (unwind)
	fprintf (out_file, "\t.save pr, r%d\n",
		 ia64_debugger_regno (dest_regno));
      break;

    case AR_UNAT_REGNUM:
      gcc_assert (dest_regno == current_frame_info.r[reg_save_ar_unat]);
      if (unwind)
	fprintf (out_file, "\t.save ar.unat, r%d\n",
		 ia64_debugger_regno (dest_regno));
      break;

    case AR_LC_REGNUM:
      gcc_assert (dest_regno == current_frame_info.r[reg_save_ar_lc]);
      if (unwind)
	fprintf (out_file, "\t.save ar.lc, r%d\n",
		 ia64_debugger_regno (dest_regno));
      break;

    default:
      /* Everything else should indicate being stored to memory.  */
      gcc_unreachable ();
    }
}

/* This function processes a SET pattern for REG_CFA_OFFSET.  */

static void
process_cfa_offset (FILE *out_file, rtx pat, bool unwind)
{
  rtx dest = SET_DEST (pat);
  rtx src = SET_SRC (pat);
  int src_regno = REGNO (src);
  const char *saveop;
  HOST_WIDE_INT off;
  rtx base;

  gcc_assert (MEM_P (dest));
  if (GET_CODE (XEXP (dest, 0)) == REG)
    {
      base = XEXP (dest, 0);
      off = 0;
    }
  else
    {
      gcc_assert (GET_CODE (XEXP (dest, 0)) == PLUS
		  && GET_CODE (XEXP (XEXP (dest, 0), 1)) == CONST_INT);
      base = XEXP (XEXP (dest, 0), 0);
      off = INTVAL (XEXP (XEXP (dest, 0), 1));
    }

  if (base == hard_frame_pointer_rtx)
    {
      saveop = ".savepsp";
      off = - off;
    }
  else
    {
      gcc_assert (base == stack_pointer_rtx);
      saveop = ".savesp";
    }

  src_regno = REGNO (src);
  switch (src_regno)
    {
    case BR_REG (0):
      gcc_assert (!current_frame_info.r[reg_save_b0]);
      if (unwind)
	fprintf (out_file, "\t%s rp, " HOST_WIDE_INT_PRINT_DEC "\n",
		 saveop, off);
      break;

    case PR_REG (0):
      gcc_assert (!current_frame_info.r[reg_save_pr]);
      if (unwind)
	fprintf (out_file, "\t%s pr, " HOST_WIDE_INT_PRINT_DEC "\n",
		 saveop, off);
      break;

    case AR_LC_REGNUM:
      gcc_assert (!current_frame_info.r[reg_save_ar_lc]);
      if (unwind)
	fprintf (out_file, "\t%s ar.lc, " HOST_WIDE_INT_PRINT_DEC "\n",
		 saveop, off);
      break;

    case AR_PFS_REGNUM:
      gcc_assert (!current_frame_info.r[reg_save_ar_pfs]);
      if (unwind)
	fprintf (out_file, "\t%s ar.pfs, " HOST_WIDE_INT_PRINT_DEC "\n",
		 saveop, off);
      break;

    case AR_UNAT_REGNUM:
      gcc_assert (!current_frame_info.r[reg_save_ar_unat]);
      if (unwind)
	fprintf (out_file, "\t%s ar.unat, " HOST_WIDE_INT_PRINT_DEC "\n",
		 saveop, off);
      break;

    case GR_REG (4):
    case GR_REG (5):
    case GR_REG (6):
    case GR_REG (7):
      if (unwind)
	fprintf (out_file, "\t.save.g 0x%x\n",
		 1 << (src_regno - GR_REG (4)));
      break;

    case BR_REG (1):
    case BR_REG (2):
    case BR_REG (3):
    case BR_REG (4):
    case BR_REG (5):
      if (unwind)
	fprintf (out_file, "\t.save.b 0x%x\n",
		 1 << (src_regno - BR_REG (1)));
      break;

    case FR_REG (2):
    case FR_REG (3):
    case FR_REG (4):
    case FR_REG (5):
      if (unwind)
	fprintf (out_file, "\t.save.f 0x%x\n",
		 1 << (src_regno - FR_REG (2)));
      break;

    case FR_REG (16): case FR_REG (17): case FR_REG (18): case FR_REG (19):
    case FR_REG (20): case FR_REG (21): case FR_REG (22): case FR_REG (23):
    case FR_REG (24): case FR_REG (25): case FR_REG (26): case FR_REG (27):
    case FR_REG (28): case FR_REG (29): case FR_REG (30): case FR_REG (31):
      if (unwind)
	fprintf (out_file, "\t.save.gf 0x0, 0x%x\n",
		 1 << (src_regno - FR_REG (12)));
      break;

    default:
      /* ??? For some reason we mark other general registers, even those
	 we can't represent in the unwind info.  Ignore them.  */
      break;
    }
}

/* This function looks at a single insn and emits any directives
   required to unwind this insn.  */

static void
ia64_asm_unwind_emit (FILE *out_file, rtx_insn *insn)
{
  bool unwind = ia64_except_unwind_info (&global_options) == UI_TARGET;
  bool frame = dwarf2out_do_frame ();
  rtx note, pat;
  bool handled_one;

  if (!unwind && !frame)
    return;

  if (NOTE_INSN_BASIC_BLOCK_P (insn))
    {
      last_block = NOTE_BASIC_BLOCK (insn)->next_bb
     == EXIT_BLOCK_PTR_FOR_FN (cfun);

      /* Restore unwind state from immediately before the epilogue.  */
      if (need_copy_state)
	{
	  if (unwind)
	    {
	      fprintf (out_file, "\t.body\n");
	      fprintf (out_file, "\t.copy_state %d\n",
		       cfun->machine->state_num);
	    }
	  need_copy_state = false;
	}
    }

  if (NOTE_P (insn) || ! RTX_FRAME_RELATED_P (insn))
    return;

  /* Look for the ALLOC insn.  */
  if (INSN_CODE (insn) == CODE_FOR_alloc)
    {
      rtx dest = SET_DEST (XVECEXP (PATTERN (insn), 0, 0));
      int dest_regno = REGNO (dest);

      /* If this is the final destination for ar.pfs, then this must
	 be the alloc in the prologue.  */
      if (dest_regno == current_frame_info.r[reg_save_ar_pfs])
	{
	  if (unwind)
	    fprintf (out_file, "\t.save ar.pfs, r%d\n",
		     ia64_debugger_regno (dest_regno));
	}
      else
	{
	  /* This must be an alloc before a sibcall.  We must drop the
	     old frame info.  The easiest way to drop the old frame
	     info is to ensure we had a ".restore sp" directive
	     followed by a new prologue.  If the procedure doesn't
	     have a memory-stack frame, we'll issue a dummy ".restore
	     sp" now.  */
	  if (current_frame_info.total_size == 0 && !frame_pointer_needed)
	    /* if haven't done process_epilogue() yet, do it now */
	    process_epilogue (out_file, insn, unwind, frame);
	  if (unwind)
	    fprintf (out_file, "\t.prologue\n");
	}
      return;
    }

  handled_one = false;
  for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
    switch (REG_NOTE_KIND (note))
      {
      case REG_CFA_ADJUST_CFA:
	pat = XEXP (note, 0);
	if (pat == NULL)
	  pat = PATTERN (insn);
	process_cfa_adjust_cfa (out_file, pat, insn, unwind, frame);
	handled_one = true;
	break;

      case REG_CFA_OFFSET:
	pat = XEXP (note, 0);
	if (pat == NULL)
	  pat = PATTERN (insn);
	process_cfa_offset (out_file, pat, unwind);
	handled_one = true;
	break;

      case REG_CFA_REGISTER:
	pat = XEXP (note, 0);
	if (pat == NULL)
	  pat = PATTERN (insn);
	process_cfa_register (out_file, pat, unwind);
	handled_one = true;
	break;

      case REG_FRAME_RELATED_EXPR:
      case REG_CFA_DEF_CFA:
      case REG_CFA_EXPRESSION:
      case REG_CFA_RESTORE:
      case REG_CFA_SET_VDRAP:
	/* Not used in the ia64 port.  */
	gcc_unreachable ();

      default:
	/* Not a frame-related note.  */
	break;
      }

  /* All REG_FRAME_RELATED_P insns, besides ALLOC, are marked with the
     explicit action to take.  No guessing required.  */
  gcc_assert (handled_one);
}

/* Implement TARGET_ASM_EMIT_EXCEPT_PERSONALITY.  */

static void
ia64_asm_emit_except_personality (rtx personality)
{
  fputs ("\t.personality\t", asm_out_file);
  output_addr_const (asm_out_file, personality);
  fputc ('\n', asm_out_file);
}

/* Implement TARGET_ASM_INITIALIZE_SECTIONS.  */

static void
ia64_asm_init_sections (void)
{
  exception_section = get_unnamed_section (0, output_section_asm_op,
					   "\t.handlerdata");
}

/* Implement TARGET_DEBUG_UNWIND_INFO.  */

static enum unwind_info_type
ia64_debug_unwind_info (void)
{
  return UI_TARGET;
}

enum ia64_builtins
{
  IA64_BUILTIN_BSP,
  IA64_BUILTIN_COPYSIGNQ,
  IA64_BUILTIN_FABSQ,
  IA64_BUILTIN_FLUSHRS,
  IA64_BUILTIN_INFQ,
  IA64_BUILTIN_HUGE_VALQ,
  IA64_BUILTIN_NANQ,
  IA64_BUILTIN_NANSQ,
  IA64_BUILTIN_max
};

static GTY(()) tree ia64_builtins[(int) IA64_BUILTIN_max];

void
ia64_init_builtins (void)
{
  tree fpreg_type;
  tree float80_type;
  tree decl;

  /* The __fpreg type.  */
  fpreg_type = make_node (REAL_TYPE);
  TYPE_PRECISION (fpreg_type) = 82;
  layout_type (fpreg_type);
  (*lang_hooks.types.register_builtin_type) (fpreg_type, "__fpreg");

  /* The __float80 type.  */
  if (float64x_type_node != NULL_TREE
      && TYPE_MODE (float64x_type_node) == XFmode)
    float80_type = float64x_type_node;
  else
    {
      float80_type = make_node (REAL_TYPE);
      TYPE_PRECISION (float80_type) = 80;
      layout_type (float80_type);
    }
  (*lang_hooks.types.register_builtin_type) (float80_type, "__float80");

  /* The __float128 type.  */
  if (!TARGET_HPUX)
    {
      tree ftype;
      tree const_string_type
	= build_pointer_type (build_qualified_type
			      (char_type_node, TYPE_QUAL_CONST));

      if (float128t_type_node == NULL_TREE)
	{
	  float128t_type_node = make_node (REAL_TYPE);
	  TYPE_PRECISION (float128t_type_node)
	    = TYPE_PRECISION (float128_type_node);
	  layout_type (float128t_type_node);
	  SET_TYPE_MODE (float128t_type_node, TYPE_MODE (float128_type_node));
	}
      (*lang_hooks.types.register_builtin_type) (float128t_type_node,
						 "__float128");

      /* TFmode support builtins.  */
      ftype = build_function_type_list (float128t_type_node, NULL_TREE);
      decl = add_builtin_function ("__builtin_infq", ftype,
				   IA64_BUILTIN_INFQ, BUILT_IN_MD,
				   NULL, NULL_TREE);
      ia64_builtins[IA64_BUILTIN_INFQ] = decl;

      decl = add_builtin_function ("__builtin_huge_valq", ftype,
				   IA64_BUILTIN_HUGE_VALQ, BUILT_IN_MD,
				   NULL, NULL_TREE);
      ia64_builtins[IA64_BUILTIN_HUGE_VALQ] = decl;

      ftype = build_function_type_list (float128t_type_node,
					const_string_type,
					NULL_TREE);
      decl = add_builtin_function ("__builtin_nanq", ftype,
				   IA64_BUILTIN_NANQ, BUILT_IN_MD,
				   "nanq", NULL_TREE);
      TREE_READONLY (decl) = 1;
      ia64_builtins[IA64_BUILTIN_NANQ] = decl;

      decl = add_builtin_function ("__builtin_nansq", ftype,
				   IA64_BUILTIN_NANSQ, BUILT_IN_MD,
				   "nansq", NULL_TREE);
      TREE_READONLY (decl) = 1;
      ia64_builtins[IA64_BUILTIN_NANSQ] = decl;

      ftype = build_function_type_list (float128t_type_node,
					float128t_type_node,
					NULL_TREE);
      decl = add_builtin_function ("__builtin_fabsq", ftype,
				   IA64_BUILTIN_FABSQ, BUILT_IN_MD,
				   "__fabstf2", NULL_TREE);
      TREE_READONLY (decl) = 1;
      ia64_builtins[IA64_BUILTIN_FABSQ] = decl;

      ftype = build_function_type_list (float128t_type_node,
					float128t_type_node,
					float128t_type_node,
					NULL_TREE);
      decl = add_builtin_function ("__builtin_copysignq", ftype,
				   IA64_BUILTIN_COPYSIGNQ, BUILT_IN_MD,
				   "__copysigntf3", NULL_TREE);
      TREE_READONLY (decl) = 1;
      ia64_builtins[IA64_BUILTIN_COPYSIGNQ] = decl;
    }
  else
    /* Under HPUX, this is a synonym for "long double".  */
    (*lang_hooks.types.register_builtin_type) (long_double_type_node,
					       "__float128");

  /* Fwrite on VMS is non-standard.  */
#if TARGET_ABI_OPEN_VMS
  vms_patch_builtins ();
#endif

#define def_builtin(name, type, code)					\
  add_builtin_function ((name), (type), (code), BUILT_IN_MD,	\
		       NULL, NULL_TREE)

  decl = def_builtin ("__builtin_ia64_bsp",
		      build_function_type_list (ptr_type_node, NULL_TREE),
		      IA64_BUILTIN_BSP);
  ia64_builtins[IA64_BUILTIN_BSP] = decl;

  decl = def_builtin ("__builtin_ia64_flushrs",
		      build_function_type_list (void_type_node, NULL_TREE),
		      IA64_BUILTIN_FLUSHRS);
  ia64_builtins[IA64_BUILTIN_FLUSHRS] = decl;

#undef def_builtin

  if (TARGET_HPUX)
    {
      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");
      if ((decl = builtin_decl_explicit (BUILT_IN_FINITEL)) != NULL_TREE)
	set_user_assembler_name (decl, "_Isfinitef128");
    }
}

static tree
ia64_fold_builtin (tree fndecl, int n_args ATTRIBUTE_UNUSED,
		   tree *args, bool ignore ATTRIBUTE_UNUSED)
{
  if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
    {
      enum ia64_builtins fn_code
	= (enum ia64_builtins) DECL_MD_FUNCTION_CODE (fndecl);
      switch (fn_code)
	{
	case IA64_BUILTIN_NANQ:
	case IA64_BUILTIN_NANSQ:
	  {
	    tree type = TREE_TYPE (TREE_TYPE (fndecl));
	    const char *str = c_getstr (*args);
	    int quiet = fn_code == IA64_BUILTIN_NANQ;
	    REAL_VALUE_TYPE real;

	    if (str && real_nan (&real, str, quiet, TYPE_MODE (type)))
	      return build_real (type, real);
	    return NULL_TREE;
	  }

	default:
	  break;
	}
    }

#ifdef SUBTARGET_FOLD_BUILTIN
  return SUBTARGET_FOLD_BUILTIN (fndecl, n_args, args, ignore);
#endif

  return NULL_TREE;
}

rtx
ia64_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 IA64_BUILTIN_BSP:
      if (! target || ! register_operand (target, DImode))
	target = gen_reg_rtx (DImode);
      emit_insn (gen_bsp_value (target));
#ifdef POINTERS_EXTEND_UNSIGNED
      target = convert_memory_address (ptr_mode, target);
#endif
      return target;

    case IA64_BUILTIN_FLUSHRS:
      emit_insn (gen_flushrs ());
      return const0_rtx;

    case IA64_BUILTIN_INFQ:
    case IA64_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;
      }

    case IA64_BUILTIN_NANQ:
    case IA64_BUILTIN_NANSQ:
    case IA64_BUILTIN_FABSQ:
    case IA64_BUILTIN_COPYSIGNQ:
      return expand_call (exp, target, ignore);

    default:
      gcc_unreachable ();
    }

  return NULL_RTX;
}

/* Return the ia64 builtin for CODE.  */

static tree
ia64_builtin_decl (unsigned code, bool initialize_p ATTRIBUTE_UNUSED)
{
  if (code >= IA64_BUILTIN_max)
    return error_mark_node;

  return ia64_builtins[code];
}

/* Implement TARGET_FUNCTION_ARG_PADDING.

   For the HP-UX IA64 aggregate parameters are passed stored in the
   most significant bits of the stack slot.  */

static pad_direction
ia64_function_arg_padding (machine_mode mode, const_tree type)
{
  /* Exception to normal case for structures/unions/etc.  */
  if (TARGET_HPUX
      && type
      && AGGREGATE_TYPE_P (type)
      && int_size_in_bytes (type) < UNITS_PER_WORD)
    return PAD_UPWARD;

  /* Fall back to the default.  */
  return default_function_arg_padding (mode, type);
}

/* Emit text to declare externally defined variables and functions, because
   the Intel assembler does not support undefined externals.  */

void
ia64_asm_output_external (FILE *file, tree decl, const char *name)
{
  /* We output the name if and only if TREE_SYMBOL_REFERENCED is
     set in order to avoid putting out names that are never really
     used. */
  if (TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)))
    {
      /* maybe_assemble_visibility will return 1 if the assembler
	 visibility directive is output.  */
      int need_visibility = ((*targetm.binds_local_p) (decl)
			     && maybe_assemble_visibility (decl));

      /* GNU as does not need anything here, but the HP linker does
	 need something for external functions.  */
      if ((TARGET_HPUX_LD || !TARGET_GNU_AS)
	  && TREE_CODE (decl) == FUNCTION_DECL)
	  (*targetm.asm_out.globalize_decl_name) (file, decl);
      else if (need_visibility && !TARGET_GNU_AS)
	(*targetm.asm_out.globalize_label) (file, name);
    }
}

/* Set SImode div/mod functions, init_integral_libfuncs only initializes
   modes of word_mode and larger.  Rename the TFmode libfuncs using the
   HPUX conventions. __divtf3 is used for XFmode. We need to keep it for
   backward compatibility. */

static void
ia64_init_libfuncs (void)
{
  set_optab_libfunc (sdiv_optab, SImode, "__divsi3");
  set_optab_libfunc (udiv_optab, SImode, "__udivsi3");
  set_optab_libfunc (smod_optab, SImode, "__modsi3");
  set_optab_libfunc (umod_optab, SImode, "__umodsi3");

  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 (neg_optab, TFmode, "_U_Qfneg");

  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 (sext_optab, TFmode, XFmode, "_U_Qfcnvff_f80_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 (trunc_optab, XFmode, TFmode, "_U_Qfcnvff_quad_to_f80");

  set_conv_libfunc (sfix_optab, SImode, TFmode, "_U_Qfcnvfxt_quad_to_sgl");
  set_conv_libfunc (sfix_optab, DImode, TFmode, "_U_Qfcnvfxt_quad_to_dbl");
  set_conv_libfunc (sfix_optab, TImode, TFmode, "_U_Qfcnvfxt_quad_to_quad");
  set_conv_libfunc (ufix_optab, SImode, TFmode, "_U_Qfcnvfxut_quad_to_sgl");
  set_conv_libfunc (ufix_optab, DImode, TFmode, "_U_Qfcnvfxut_quad_to_dbl");

  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 (sfloat_optab, TFmode, TImode, "_U_Qfcnvxf_quad_to_quad");
  /* HP-UX 11.23 libc does not have a function for unsigned
     SImode-to-TFmode conversion.  */
  set_conv_libfunc (ufloat_optab, TFmode, DImode, "_U_Qfcnvxuf_dbl_to_quad");
}

/* Rename all the TFmode libfuncs using the HPUX conventions.  */

static void
ia64_hpux_init_libfuncs (void)
{
  ia64_init_libfuncs ();

  /* The HP SI millicode division and mod functions expect DI arguments.
     By turning them off completely we avoid using both libgcc and the
     non-standard millicode routines and use the HP DI millicode routines
     instead.  */

  set_optab_libfunc (sdiv_optab, SImode, 0);
  set_optab_libfunc (udiv_optab, SImode, 0);
  set_optab_libfunc (smod_optab, SImode, 0);
  set_optab_libfunc (umod_optab, SImode, 0);

  set_optab_libfunc (sdiv_optab, DImode, "__milli_divI");
  set_optab_libfunc (udiv_optab, DImode, "__milli_divU");
  set_optab_libfunc (smod_optab, DImode, "__milli_remI");
  set_optab_libfunc (umod_optab, DImode, "__milli_remU");

  /* HP-UX libc has TF min/max/abs routines in it.  */
  set_optab_libfunc (smin_optab, TFmode, "_U_Qfmin");
  set_optab_libfunc (smax_optab, TFmode, "_U_Qfmax");
  set_optab_libfunc (abs_optab, TFmode, "_U_Qfabs");

  /* ia64_expand_compare uses this.  */
  cmptf_libfunc = init_one_libfunc ("_U_Qfcmp");

  /* These should never be used.  */
  set_optab_libfunc (eq_optab, TFmode, 0);
  set_optab_libfunc (ne_optab, TFmode, 0);
  set_optab_libfunc (gt_optab, TFmode, 0);
  set_optab_libfunc (ge_optab, TFmode, 0);
  set_optab_libfunc (lt_optab, TFmode, 0);
  set_optab_libfunc (le_optab, TFmode, 0);
}

/* Rename the division and modulus functions in VMS.  */

static void
ia64_vms_init_libfuncs (void)
{
  set_optab_libfunc (sdiv_optab, SImode, "OTS$DIV_I");
  set_optab_libfunc (sdiv_optab, DImode, "OTS$DIV_L");
  set_optab_libfunc (udiv_optab, SImode, "OTS$DIV_UI");
  set_optab_libfunc (udiv_optab, DImode, "OTS$DIV_UL");
  set_optab_libfunc (smod_optab, SImode, "OTS$REM_I");
  set_optab_libfunc (smod_optab, DImode, "OTS$REM_L");
  set_optab_libfunc (umod_optab, SImode, "OTS$REM_UI");
  set_optab_libfunc (umod_optab, DImode, "OTS$REM_UL");
#ifdef MEM_LIBFUNCS_INIT
  MEM_LIBFUNCS_INIT;
#endif
}

/* Rename the TFmode libfuncs available from soft-fp in glibc using
   the HPUX conventions.  */

static void
ia64_sysv4_init_libfuncs (void)
{
  ia64_init_libfuncs ();

  /* These functions are not part of the HPUX TFmode interface.  We
     use them instead of _U_Qfcmp, which doesn't work the way we
     expect.  */
  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");

  /* We leave out _U_Qfmin, _U_Qfmax and _U_Qfabs since soft-fp in
     glibc doesn't have them.  */
}

/* Use soft-fp.  */

static void
ia64_soft_fp_init_libfuncs (void)
{
}

static bool
ia64_vms_valid_pointer_mode (scalar_int_mode mode)
{
  return (mode == SImode || mode == DImode);
}

/* For HPUX, it is illegal to have relocations in shared segments.  */

static int
ia64_hpux_reloc_rw_mask (void)
{
  return 3;
}

/* For others, relax this so that relocations to local data goes in
   read-only segments, but we still cannot allow global relocations
   in read-only segments.  */

static int
ia64_reloc_rw_mask (void)
{
  return flag_pic ? 3 : 2;
}

/* Return the section to use for X.  The only special thing we do here
   is to honor small data.  */

static section *
ia64_select_rtx_section (machine_mode mode, rtx x,
			 unsigned HOST_WIDE_INT align)
{
  if (GET_MODE_SIZE (mode) > 0
      && GET_MODE_SIZE (mode) <= ia64_section_threshold
      && !TARGET_NO_SDATA)
    return sdata_section;
  else
    return default_elf_select_rtx_section (mode, x, align);
}

static unsigned int
ia64_section_type_flags (tree decl, const char *name, int reloc)
{
  unsigned int flags = 0;

  if (strcmp (name, ".sdata") == 0
      || startswith (name, ".sdata.")
      || startswith (name, ".gnu.linkonce.s.")
      || startswith (name, ".sdata2.")
      || startswith (name, ".gnu.linkonce.s2.")
      || strcmp (name, ".sbss") == 0
      || startswith (name, ".sbss.")
      || startswith (name, ".gnu.linkonce.sb."))
    flags = SECTION_SMALL;

  flags |= default_section_type_flags (decl, name, reloc);
  return flags;
}

/* Returns true if FNTYPE (a FUNCTION_TYPE or a METHOD_TYPE) returns a
   structure type and that the address of that type should be passed
   in out0, rather than in r8.  */

static bool
ia64_struct_retval_addr_is_first_parm_p (tree fntype)
{
  tree ret_type = TREE_TYPE (fntype);

  /* The Itanium C++ ABI requires that out0, rather than r8, be used
     as the structure return address parameter, if the return value
     type has a non-trivial copy constructor or destructor.  It is not
     clear if this same convention should be used for other
     programming languages.  Until G++ 3.4, we incorrectly used r8 for
     these return values.  */
  return (abi_version_at_least (2)
	  && ret_type
	  && TYPE_MODE (ret_type) == BLKmode 
	  && TREE_ADDRESSABLE (ret_type)
	  && lang_GNU_CXX ());
}

/* 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
ia64_output_mi_thunk (FILE *file, tree thunk ATTRIBUTE_UNUSED,
		      HOST_WIDE_INT delta, HOST_WIDE_INT vcall_offset,
		      tree function)
{
  const char *fnname = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (thunk));
  rtx this_rtx, funexp;
  rtx_insn *insn;
  unsigned int this_parmno;
  unsigned int this_regno;
  rtx delta_rtx;

  reload_completed = 1;
  epilogue_completed = 1;

  /* Set things up as ia64_expand_prologue might.  */
  last_scratch_gr_reg = 15;

  memset (&current_frame_info, 0, sizeof (current_frame_info));
  current_frame_info.spill_cfa_off = -16;
  current_frame_info.n_input_regs = 1;
  current_frame_info.need_regstk = (TARGET_REG_NAMES != 0);

  /* Mark the end of the (empty) prologue.  */
  emit_note (NOTE_INSN_PROLOGUE_END);

  /* Figure out whether "this" will be the first parameter (the
     typical case) or the second parameter (as happens when the
     virtual function returns certain class objects).  */
  this_parmno
    = (ia64_struct_retval_addr_is_first_parm_p (TREE_TYPE (thunk))
       ? 1 : 0);
  this_regno = IN_REG (this_parmno);
  if (!TARGET_REG_NAMES)
    reg_names[this_regno] = ia64_reg_numbers[this_parmno];

  this_rtx = gen_rtx_REG (Pmode, this_regno);

  /* Apply the constant offset, if required.  */
  delta_rtx = GEN_INT (delta);
  if (TARGET_ILP32)
    {
      rtx tmp = gen_rtx_REG (ptr_mode, this_regno);
      REG_POINTER (tmp) = 1;
      if (delta && satisfies_constraint_I (delta_rtx))
	{
	  emit_insn (gen_ptr_extend_plus_imm (this_rtx, tmp, delta_rtx));
	  delta = 0;
	}
      else
	emit_insn (gen_ptr_extend (this_rtx, tmp));
    }
  if (delta)
    {
      if (!satisfies_constraint_I (delta_rtx))
	{
	  rtx tmp = gen_rtx_REG (Pmode, 2);
	  emit_move_insn (tmp, delta_rtx);
	  delta_rtx = tmp;
	}
      emit_insn (gen_adddi3 (this_rtx, this_rtx, delta_rtx));
    }

  /* Apply the offset from the vtable, if required.  */
  if (vcall_offset)
    {
      rtx vcall_offset_rtx = GEN_INT (vcall_offset);
      rtx tmp = gen_rtx_REG (Pmode, 2);

      if (TARGET_ILP32)
	{
	  rtx t = gen_rtx_REG (ptr_mode, 2);
	  REG_POINTER (t) = 1;
	  emit_move_insn (t, gen_rtx_MEM (ptr_mode, this_rtx));
	  if (satisfies_constraint_I (vcall_offset_rtx))
	    {
	      emit_insn (gen_ptr_extend_plus_imm (tmp, t, vcall_offset_rtx));
	      vcall_offset = 0;
	    }
	  else
	    emit_insn (gen_ptr_extend (tmp, t));
	}
      else
	emit_move_insn (tmp, gen_rtx_MEM (Pmode, this_rtx));

      if (vcall_offset)
	{
	  if (!satisfies_constraint_J (vcall_offset_rtx))
	    {
	      rtx tmp2 = gen_rtx_REG (Pmode, next_scratch_gr_reg ());
	      emit_move_insn (tmp2, vcall_offset_rtx);
	      vcall_offset_rtx = tmp2;
	    }
	  emit_insn (gen_adddi3 (tmp, tmp, vcall_offset_rtx));
	}

      if (TARGET_ILP32)
	emit_insn (gen_zero_extendsidi2 (tmp, gen_rtx_MEM (ptr_mode, tmp)));
      else
	emit_move_insn (tmp, gen_rtx_MEM (Pmode, tmp));

      emit_insn (gen_adddi3 (this_rtx, this_rtx, tmp));
    }

  /* Generate a tail call to the target function.  */
  if (! TREE_USED (function))
    {
      assemble_external (function);
      TREE_USED (function) = 1;
    }
  funexp = XEXP (DECL_RTL (function), 0);
  funexp = gen_rtx_MEM (FUNCTION_MODE, funexp);
  ia64_expand_call (NULL_RTX, funexp, NULL_RTX, 1);
  insn = get_last_insn ();
  SIBLING_CALL_P (insn) = 1;

  /* Code generation for calls relies on splitting.  */
  reload_completed = 1;
  epilogue_completed = 1;
  try_split (PATTERN (insn), insn, 0);

  emit_barrier ();

  /* Run just enough of rest_of_compilation to get the insns emitted.
     There's not really enough bulk here to make other passes such as
     instruction scheduling worth while.  */

  emit_all_insn_group_barriers (NULL);
  insn = get_insns ();
  shorten_branches (insn);
  assemble_start_function (thunk, fnname);
  final_start_function (insn, file, 1);
  final (insn, file, 1);
  final_end_function ();
  assemble_end_function (thunk, fnname);

  reload_completed = 0;
  epilogue_completed = 0;
}

/* Worker function for TARGET_STRUCT_VALUE_RTX.  */

static rtx
ia64_struct_value_rtx (tree fntype,
		       int incoming ATTRIBUTE_UNUSED)
{
  if (TARGET_ABI_OPEN_VMS ||
      (fntype && ia64_struct_retval_addr_is_first_parm_p (fntype)))
    return NULL_RTX;
  return gen_rtx_REG (Pmode, GR_REG (8));
}

static bool
ia64_scalar_mode_supported_p (scalar_mode mode)
{
  switch (mode)
    {
    case E_QImode:
    case E_HImode:
    case E_SImode:
    case E_DImode:
    case E_TImode:
      return true;

    case E_SFmode:
    case E_DFmode:
    case E_XFmode:
    case E_RFmode:
      return true;

    case E_TFmode:
      return true;

    default:
      return false;
    }
}

static bool
ia64_vector_mode_supported_p (machine_mode mode)
{
  switch (mode)
    {
    case E_V8QImode:
    case E_V4HImode:
    case E_V2SImode:
      return true;

    case E_V2SFmode:
      return true;

    default:
      return false;
    }
}

/* Implement the FUNCTION_PROFILER macro.  */

void
ia64_output_function_profiler (FILE *file, int labelno)
{
  bool indirect_call;

  /* If the function needs a static chain and the static chain
     register is r15, we use an indirect call so as to bypass
     the PLT stub in case the executable is dynamically linked,
     because the stub clobbers r15 as per 5.3.6 of the psABI.
     We don't need to do that in non canonical PIC mode.  */

  if (cfun->static_chain_decl && !TARGET_NO_PIC && !TARGET_AUTO_PIC)
    {
      gcc_assert (STATIC_CHAIN_REGNUM == 15);
      indirect_call = true;
    }
  else
    indirect_call = false;

  if (TARGET_GNU_AS)
    fputs ("\t.prologue 4, r40\n", file);
  else
    fputs ("\t.prologue\n\t.save ar.pfs, r40\n", file);
  fputs ("\talloc out0 = ar.pfs, 8, 0, 4, 0\n", file);

  if (NO_PROFILE_COUNTERS)
    fputs ("\tmov out3 = r0\n", file);
  else
    {
      char buf[20];
      ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);

      if (TARGET_AUTO_PIC)
	fputs ("\tmovl out3 = @gprel(", file);
      else
	fputs ("\taddl out3 = @ltoff(", file);
      assemble_name (file, buf);
      if (TARGET_AUTO_PIC)
	fputs (")\n", file);
      else
	fputs ("), r1\n", file);
    }

  if (indirect_call)
    fputs ("\taddl r14 = @ltoff(@fptr(_mcount)), r1\n", file);
  fputs ("\t;;\n", file);

  fputs ("\t.save rp, r42\n", file);
  fputs ("\tmov out2 = b0\n", file);
  if (indirect_call)
    fputs ("\tld8 r14 = [r14]\n\t;;\n", file);
  fputs ("\t.body\n", file);
  fputs ("\tmov out1 = r1\n", file);
  if (indirect_call)
    {
      fputs ("\tld8 r16 = [r14], 8\n\t;;\n", file);
      fputs ("\tmov b6 = r16\n", file);
      fputs ("\tld8 r1 = [r14]\n", file);
      fputs ("\tbr.call.sptk.many b0 = b6\n\t;;\n", file);
    }
  else
    fputs ("\tbr.call.sptk.many b0 = _mcount\n\t;;\n", file);
}

static GTY(()) rtx mcount_func_rtx;
static rtx
gen_mcount_func_rtx (void)
{
  if (!mcount_func_rtx)
    mcount_func_rtx = init_one_libfunc ("_mcount");
  return mcount_func_rtx;
}

void
ia64_profile_hook (int labelno)
{
  rtx label, ip;

  if (NO_PROFILE_COUNTERS)
    label = const0_rtx;
  else
    {
      char buf[30];
      const char *label_name;
      ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
      label_name = ggc_strdup ((*targetm.strip_name_encoding) (buf));
      label = gen_rtx_SYMBOL_REF (Pmode, label_name);
      SYMBOL_REF_FLAGS (label) = SYMBOL_FLAG_LOCAL;
    }
  ip = gen_reg_rtx (Pmode);
  emit_insn (gen_ip_value (ip));
  emit_library_call (gen_mcount_func_rtx (), LCT_NORMAL,
                     VOIDmode,
		     gen_rtx_REG (Pmode, BR_REG (0)), Pmode,
		     ip, Pmode,
		     label, Pmode);
}

/* Return the mangling of TYPE if it is an extended fundamental type.  */

static const char *
ia64_mangle_type (const_tree type)
{
  type = TYPE_MAIN_VARIANT (type);

  if (TREE_CODE (type) != VOID_TYPE && TREE_CODE (type) != BOOLEAN_TYPE
      && TREE_CODE (type) != INTEGER_TYPE && TREE_CODE (type) != REAL_TYPE)
    return NULL;

  if (type == float128_type_node || type == float64x_type_node)
    return NULL;

  /* On HP-UX, "long double" is mangled as "e" so __float128 is
     mangled as "e".  */
  if (!TARGET_HPUX && TYPE_MODE (type) == TFmode)
    return "g";
  /* On HP-UX, "e" is not available as a mangling of __float80 so use
     an extended mangling.  Elsewhere, "e" is available since long
     double is 80 bits.  */
  if (TYPE_MODE (type) == XFmode)
    return TARGET_HPUX ? "u9__float80" : "e";
  if (TYPE_MODE (type) == RFmode)
    return "u7__fpreg";
  return NULL;
}

/* Return the diagnostic message string if conversion from FROMTYPE to
   TOTYPE is not allowed, NULL otherwise.  */
static const char *
ia64_invalid_conversion (const_tree fromtype, const_tree totype)
{
  /* Reject nontrivial conversion to or from __fpreg.  */
  if (TYPE_MODE (fromtype) == RFmode
      && TYPE_MODE (totype) != RFmode
      && TYPE_MODE (totype) != VOIDmode)
    return N_("invalid conversion from %<__fpreg%>");
  if (TYPE_MODE (totype) == RFmode
      && TYPE_MODE (fromtype) != RFmode)
    return N_("invalid conversion to %<__fpreg%>");
  return NULL;
}

/* Return the diagnostic message string if the unary operation OP is
   not permitted on TYPE, NULL otherwise.  */
static const char *
ia64_invalid_unary_op (int op, const_tree type)
{
  /* Reject operations on __fpreg other than unary + or &.  */
  if (TYPE_MODE (type) == RFmode
      && op != CONVERT_EXPR
      && op != ADDR_EXPR)
    return N_("invalid operation on %<__fpreg%>");
  return NULL;
}

/* Return the diagnostic message string if the binary operation OP is
   not permitted on TYPE1 and TYPE2, NULL otherwise.  */
static const char *
ia64_invalid_binary_op (int op ATTRIBUTE_UNUSED, const_tree type1, const_tree type2)
{
  /* Reject operations on __fpreg.  */
  if (TYPE_MODE (type1) == RFmode || TYPE_MODE (type2) == RFmode)
    return N_("invalid operation on %<__fpreg%>");
  return NULL;
}

/* HP-UX version_id attribute.
   For object foo, if the version_id is set to 1234 put out an alias
   of '.alias foo "foo{1234}"  We can't use "foo{1234}" in anything
   other than an alias statement because it is an illegal symbol name.  */

static tree
ia64_handle_version_id_attribute (tree *node ATTRIBUTE_UNUSED,
                                 tree name ATTRIBUTE_UNUSED,
                                 tree args,
                                 int flags ATTRIBUTE_UNUSED,
                                 bool *no_add_attrs)
{
  tree arg = TREE_VALUE (args);

  if (TREE_CODE (arg) != STRING_CST)
    {
      error("version attribute is not a string");
      *no_add_attrs = true;
      return NULL_TREE;
    }
  return NULL_TREE;
}

/* Target hook for c_mode_for_suffix.  */

static machine_mode
ia64_c_mode_for_suffix (char suffix)
{
  if (suffix == 'q')
    return TFmode;
  if (suffix == 'w')
    return XFmode;

  return VOIDmode;
}

static GTY(()) rtx ia64_dconst_0_5_rtx;

rtx
ia64_dconst_0_5 (void)
{
  if (! ia64_dconst_0_5_rtx)
    {
      REAL_VALUE_TYPE rv;
      real_from_string (&rv, "0.5");
      ia64_dconst_0_5_rtx = const_double_from_real_value (rv, DFmode);
    }
  return ia64_dconst_0_5_rtx;
}

static GTY(()) rtx ia64_dconst_0_375_rtx;

rtx
ia64_dconst_0_375 (void)
{
  if (! ia64_dconst_0_375_rtx)
    {
      REAL_VALUE_TYPE rv;
      real_from_string (&rv, "0.375");
      ia64_dconst_0_375_rtx = const_double_from_real_value (rv, DFmode);
    }
  return ia64_dconst_0_375_rtx;
}

static fixed_size_mode
ia64_get_reg_raw_mode (int regno)
{
  if (FR_REGNO_P (regno))
    return XFmode;
  return default_get_reg_raw_mode(regno);
}

/* Implement TARGET_MEMBER_TYPE_FORCES_BLK.  ??? Might not be needed
   anymore.  */

bool
ia64_member_type_forces_blk (const_tree, machine_mode mode)
{
  return TARGET_HPUX && mode == TFmode;
}

/* Always default to .text section until HP-UX linker is fixed.  */

ATTRIBUTE_UNUSED static section *
ia64_hpux_function_section (tree decl ATTRIBUTE_UNUSED,
			    enum node_frequency freq ATTRIBUTE_UNUSED,
			    bool startup ATTRIBUTE_UNUSED,
			    bool exit ATTRIBUTE_UNUSED)
{
  return NULL;
}

/* Construct (set target (vec_select op0 (parallel perm))) and
   return true if that's a valid instruction in the active ISA.  */

static bool
expand_vselect (rtx target, rtx op0, const unsigned char *perm, unsigned nelt)
{
  rtx rperm[MAX_VECT_LEN], x;
  unsigned i;

  for (i = 0; i < nelt; ++i)
    rperm[i] = GEN_INT (perm[i]);

  x = gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (nelt, rperm));
  x = gen_rtx_VEC_SELECT (GET_MODE (target), op0, x);
  x = gen_rtx_SET (target, x);

  rtx_insn *insn = emit_insn (x);
  if (recog_memoized (insn) < 0)
    {
      remove_insn (insn);
      return false;
    }
  return true;
}

/* Similar, but generate a vec_concat from op0 and op1 as well.  */

static bool
expand_vselect_vconcat (rtx target, rtx op0, rtx op1,
			const unsigned char *perm, unsigned nelt)
{
  machine_mode v2mode;
  rtx x;

  if (!GET_MODE_2XWIDER_MODE (GET_MODE (op0)).exists (&v2mode))
    return false;
  x = gen_rtx_VEC_CONCAT (v2mode, op0, op1);
  return expand_vselect (target, x, perm, nelt);
}

/* Try to expand a no-op permutation.  */

static bool
expand_vec_perm_identity (struct expand_vec_perm_d *d)
{
  unsigned i, nelt = d->nelt;

  for (i = 0; i < nelt; ++i)
    if (d->perm[i] != i)
      return false;

  if (!d->testing_p)
    emit_move_insn (d->target, d->op0);

  return true;
}

/* Try to expand D via a shrp instruction.  */

static bool
expand_vec_perm_shrp (struct expand_vec_perm_d *d)
{
  unsigned i, nelt = d->nelt, shift, mask;
  rtx tmp, hi, lo;

  /* ??? Don't force V2SFmode into the integer registers.  */
  if (d->vmode == V2SFmode)
    return false;

  mask = (d->one_operand_p ? nelt - 1 : 2 * nelt - 1);

  shift = d->perm[0];
  if (BYTES_BIG_ENDIAN && shift > nelt)
    return false;

  for (i = 1; i < nelt; ++i)
    if (d->perm[i] != ((shift + i) & mask))
      return false;

  if (d->testing_p)
    return true;

  hi = shift < nelt ? d->op1 : d->op0;
  lo = shift < nelt ? d->op0 : d->op1;

  shift %= nelt;

  shift *= GET_MODE_UNIT_SIZE (d->vmode) * BITS_PER_UNIT;

  /* We've eliminated the shift 0 case via expand_vec_perm_identity.  */
  gcc_assert (IN_RANGE (shift, 1, 63));

  /* Recall that big-endian elements are numbered starting at the top of
     the register.  Ideally we'd have a shift-left-pair.  But since we
     don't, convert to a shift the other direction.  */
  if (BYTES_BIG_ENDIAN)
    shift = 64 - shift;

  tmp = gen_reg_rtx (DImode);
  hi = gen_lowpart (DImode, hi);
  lo = gen_lowpart (DImode, lo);
  emit_insn (gen_shrp (tmp, hi, lo, GEN_INT (shift)));

  emit_move_insn (d->target, gen_lowpart (d->vmode, tmp));
  return true;
}

/* Try to instantiate D in a single instruction.  */

static bool
expand_vec_perm_1 (struct expand_vec_perm_d *d)
{     
  unsigned i, nelt = d->nelt;
  unsigned char perm2[MAX_VECT_LEN];

  /* Try single-operand selections.  */
  if (d->one_operand_p)
    {
      if (expand_vec_perm_identity (d))
	return true;
      if (expand_vselect (d->target, d->op0, d->perm, nelt))
	return true;
    }

  /* Try two operand selections.  */
  if (expand_vselect_vconcat (d->target, d->op0, d->op1, d->perm, nelt))
    return true;

  /* Recognize interleave style patterns with reversed operands.  */
  if (!d->one_operand_p)
    {
      for (i = 0; i < nelt; ++i)
	{
	  unsigned e = d->perm[i];
	  if (e >= nelt)
	    e -= nelt;
	  else
	    e += nelt;
	  perm2[i] = e;
	}

      if (expand_vselect_vconcat (d->target, d->op1, d->op0, perm2, nelt))
	return true;
    }

  if (expand_vec_perm_shrp (d))
    return true;

  /* ??? Look for deposit-like permutations where most of the result 
     comes from one vector unchanged and the rest comes from a 
     sequential hunk of the other vector.  */

  return false;
}

/* Pattern match broadcast permutations.  */

static bool
expand_vec_perm_broadcast (struct expand_vec_perm_d *d)
{
  unsigned i, elt, nelt = d->nelt;
  unsigned char perm2[2];
  rtx temp;
  bool ok;

  if (!d->one_operand_p)
    return false;

  elt = d->perm[0];
  for (i = 1; i < nelt; ++i)
    if (d->perm[i] != elt)
      return false;

  switch (d->vmode)
    {
    case E_V2SImode:
    case E_V2SFmode:
      /* Implementable by interleave.  */
      perm2[0] = elt;
      perm2[1] = elt + 2;
      ok = expand_vselect_vconcat (d->target, d->op0, d->op0, perm2, 2);
      gcc_assert (ok);
      break;

    case E_V8QImode:
      /* Implementable by extract + broadcast.  */
      if (BYTES_BIG_ENDIAN)
	elt = 7 - elt;
      elt *= BITS_PER_UNIT;
      temp = gen_reg_rtx (DImode);
      emit_insn (gen_extzv (temp, gen_lowpart (DImode, d->op0),
			    GEN_INT (8), GEN_INT (elt)));
      emit_insn (gen_mux1_brcst_qi (d->target, gen_lowpart (QImode, temp)));
      break;

    case E_V4HImode:
      /* Should have been matched directly by vec_select.  */
    default:
      gcc_unreachable ();
    }

  return true;
}

/* A subroutine of ia64_expand_vec_perm_const_1.  Try to simplify a
   two vector permutation into a single vector permutation by using
   an interleave operation to merge the vectors.  */

static bool
expand_vec_perm_interleave_2 (struct expand_vec_perm_d *d)
{
  struct expand_vec_perm_d dremap, dfinal;
  unsigned char remap[2 * MAX_VECT_LEN];
  unsigned contents, i, nelt, nelt2;
  unsigned h0, h1, h2, h3;
  rtx_insn *seq;
  bool ok;

  if (d->one_operand_p)
    return false;

  nelt = d->nelt;
  nelt2 = nelt / 2;

  /* Examine from whence the elements come.  */
  contents = 0;
  for (i = 0; i < nelt; ++i)
    contents |= 1u << d->perm[i];

  memset (remap, 0xff, sizeof (remap));
  dremap = *d;

  h0 = (1u << nelt2) - 1;
  h1 = h0 << nelt2;
  h2 = h0 << nelt;
  h3 = h0 << (nelt + nelt2);
  
  if ((contents & (h0 | h2)) == contents)	/* punpck even halves */
    {
      for (i = 0; i < nelt; ++i)
	{
	  unsigned which = i / 2 + (i & 1 ? nelt : 0);
	  remap[which] = i;
	  dremap.perm[i] = which;
	}
    }
  else if ((contents & (h1 | h3)) == contents)	/* punpck odd halves */
    {
      for (i = 0; i < nelt; ++i)
	{
	  unsigned which = i / 2 + nelt2 + (i & 1 ? nelt : 0);
	  remap[which] = i;
	  dremap.perm[i] = which;
	}
    }
  else if ((contents & 0x5555) == contents)	/* mix even elements */
    {
      for (i = 0; i < nelt; ++i)
	{
	  unsigned which = (i & ~1) + (i & 1 ? nelt : 0);
	  remap[which] = i;
	  dremap.perm[i] = which;
	}
    }
  else if ((contents & 0xaaaa) == contents)	/* mix odd elements */
    {
      for (i = 0; i < nelt; ++i)
	{
	  unsigned which = (i | 1) + (i & 1 ? nelt : 0);
	  remap[which] = i;
	  dremap.perm[i] = which;
	}
    }
  else if (floor_log2 (contents) - ctz_hwi (contents) < (int)nelt) /* shrp */
    {
      unsigned shift = ctz_hwi (contents);
      for (i = 0; i < nelt; ++i)
	{
	  unsigned which = (i + shift) & (2 * nelt - 1);
	  remap[which] = i;
	  dremap.perm[i] = which;
	}
    }
  else
    return false;

  /* Use the remapping array set up above to move the elements from their
     swizzled locations into their final destinations.  */
  dfinal = *d;
  for (i = 0; i < nelt; ++i)
    {
      unsigned e = remap[d->perm[i]];
      gcc_assert (e < nelt);
      dfinal.perm[i] = e;
    }
  if (d->testing_p)
    dfinal.op0 = gen_raw_REG (dfinal.vmode, LAST_VIRTUAL_REGISTER + 1);
  else
    dfinal.op0 = gen_reg_rtx (dfinal.vmode);
  dfinal.op1 = dfinal.op0;
  dfinal.one_operand_p = true;
  dremap.target = dfinal.op0;

  /* Test if the final remap can be done with a single insn.  For V4HImode
     this *will* succeed.  For V8QImode or V2SImode it may not.  */
  start_sequence ();
  ok = expand_vec_perm_1 (&dfinal);
  seq = get_insns ();
  end_sequence ();
  if (!ok)
    return false;
  if (d->testing_p)
    return true;

  ok = expand_vec_perm_1 (&dremap);
  gcc_assert (ok);

  emit_insn (seq);
  return true;
}

/* A subroutine of ia64_expand_vec_perm_const_1.  Emit a full V4HImode
   constant permutation via two mux2 and a merge.  */

static bool
expand_vec_perm_v4hi_5 (struct expand_vec_perm_d *d)
{
  unsigned char perm2[4];
  rtx rmask[4];
  unsigned i;
  rtx t0, t1, mask, x;
  bool ok;

  if (d->vmode != V4HImode || d->one_operand_p)
    return false;
  if (d->testing_p)
    return true;

  for (i = 0; i < 4; ++i)
    {
      perm2[i] = d->perm[i] & 3;
      rmask[i] = (d->perm[i] & 4 ? const0_rtx : constm1_rtx);
    }
  mask = gen_rtx_CONST_VECTOR (V4HImode, gen_rtvec_v (4, rmask));
  mask = force_reg (V4HImode, mask);

  t0 = gen_reg_rtx (V4HImode);
  t1 = gen_reg_rtx (V4HImode);

  ok = expand_vselect (t0, d->op0, perm2, 4);
  gcc_assert (ok);
  ok = expand_vselect (t1, d->op1, perm2, 4);
  gcc_assert (ok);

  x = gen_rtx_AND (V4HImode, mask, t0);
  emit_insn (gen_rtx_SET (t0, x));

  x = gen_rtx_NOT (V4HImode, mask);
  x = gen_rtx_AND (V4HImode, x, t1);
  emit_insn (gen_rtx_SET (t1, x));

  x = gen_rtx_IOR (V4HImode, t0, t1);
  emit_insn (gen_rtx_SET (d->target, x));

  return true;
}

/* The guts of ia64_expand_vec_perm_const, also used by the ok hook.
   With all of the interface bits taken care of, perform the expansion
   in D and return true on success.  */

static bool
ia64_expand_vec_perm_const_1 (struct expand_vec_perm_d *d)
{
  if (expand_vec_perm_1 (d))
    return true;
  if (expand_vec_perm_broadcast (d))
    return true;
  if (expand_vec_perm_interleave_2 (d))
    return true;
  if (expand_vec_perm_v4hi_5 (d))
    return true;
  return false;
}

/* Implement TARGET_VECTORIZE_VEC_PERM_CONST.  */

static bool
ia64_vectorize_vec_perm_const (machine_mode vmode, machine_mode op_mode,
			       rtx target, rtx op0, rtx op1,
			       const vec_perm_indices &sel)
{
  if (vmode != op_mode)
    return false;

  struct expand_vec_perm_d d;
  unsigned char perm[MAX_VECT_LEN];
  unsigned int i, nelt, which;

  d.target = target;
  if (op0)
    {
      rtx nop0 = force_reg (vmode, op0);
      if (op0 == op1)
        op1 = nop0;
      op0 = nop0;
    }
  if (op1)
    op1 = force_reg (vmode, op1);
  d.op0 = op0;
  d.op1 = op1;

  d.vmode = vmode;
  gcc_assert (VECTOR_MODE_P (d.vmode));
  d.nelt = nelt = GET_MODE_NUNITS (d.vmode);
  d.testing_p = !target;

  gcc_assert (sel.length () == nelt);
  gcc_checking_assert (sizeof (d.perm) == sizeof (perm));

  for (i = which = 0; i < nelt; ++i)
    {
      unsigned int ei = sel[i] & (2 * nelt - 1);

      which |= (ei < nelt ? 1 : 2);
      d.perm[i] = ei;
      perm[i] = ei;
    }

  switch (which)
    {
    default:
      gcc_unreachable();

    case 3:
      if (d.testing_p || !rtx_equal_p (d.op0, d.op1))
	{
	  d.one_operand_p = false;
	  break;
	}

      /* The elements of PERM do not suggest that only the first operand
	 is used, but both operands are identical.  Allow easier matching
	 of the permutation by folding the permutation into the single
	 input vector.  */
      for (i = 0; i < nelt; ++i)
	if (d.perm[i] >= nelt)
	  d.perm[i] -= nelt;
      /* FALLTHRU */

    case 1:
      d.op1 = d.op0;
      d.one_operand_p = true;
      break;

    case 2:
      for (i = 0; i < nelt; ++i)
        d.perm[i] -= nelt;
      d.op0 = d.op1;
      d.one_operand_p = true;
      break;
    }

  if (d.testing_p)
    {
      /* We have to go through the motions and see if we can
	 figure out how to generate the requested permutation.  */
      d.target = gen_raw_REG (d.vmode, LAST_VIRTUAL_REGISTER + 1);
      d.op1 = d.op0 = gen_raw_REG (d.vmode, LAST_VIRTUAL_REGISTER + 2);
      if (!d.one_operand_p)
	d.op1 = gen_raw_REG (d.vmode, LAST_VIRTUAL_REGISTER + 3);

      start_sequence ();
      bool ret = ia64_expand_vec_perm_const_1 (&d);
      end_sequence ();

      return ret;
    }

  if (ia64_expand_vec_perm_const_1 (&d))
    return true;

  /* If the mask says both arguments are needed, but they are the same,
     the above tried to expand with one_operand_p true.  If that didn't
     work, retry with one_operand_p false, as that's what we used in _ok.  */
  if (which == 3 && d.one_operand_p)
    {
      memcpy (d.perm, perm, sizeof (perm));
      d.one_operand_p = false;
      return ia64_expand_vec_perm_const_1 (&d);
    }

  return false;
}

void
ia64_expand_vec_setv2sf (rtx operands[3])
{
  struct expand_vec_perm_d d;
  unsigned int which;
  bool ok;
  
  d.target = operands[0];
  d.op0 = operands[0];
  d.op1 = gen_reg_rtx (V2SFmode);
  d.vmode = V2SFmode;
  d.nelt = 2;
  d.one_operand_p = false;
  d.testing_p = false;

  which = INTVAL (operands[2]);
  gcc_assert (which <= 1);
  d.perm[0] = 1 - which;
  d.perm[1] = which + 2;

  emit_insn (gen_fpack (d.op1, operands[1], CONST0_RTX (SFmode)));

  ok = ia64_expand_vec_perm_const_1 (&d);
  gcc_assert (ok);
}

void
ia64_expand_vec_perm_even_odd (rtx target, rtx op0, rtx op1, int odd)
{
  struct expand_vec_perm_d d;
  machine_mode vmode = GET_MODE (target);
  unsigned int i, nelt = GET_MODE_NUNITS (vmode);
  bool ok;

  d.target = target;
  d.op0 = op0;
  d.op1 = op1;
  d.vmode = vmode;
  d.nelt = nelt;
  d.one_operand_p = false;
  d.testing_p = false;

  for (i = 0; i < nelt; ++i)
    d.perm[i] = i * 2 + odd;

  ok = ia64_expand_vec_perm_const_1 (&d);
  gcc_assert (ok);
}

/* Implement TARGET_CAN_CHANGE_MODE_CLASS.

   In BR regs, we can't change the DImode at all.
   In FP regs, we can't change FP values to integer values and vice versa,
   but we can change e.g. DImode to SImode, and V2SFmode into DImode.  */

static bool
ia64_can_change_mode_class (machine_mode from, machine_mode to,
			    reg_class_t rclass)
{
  if (reg_classes_intersect_p (rclass, BR_REGS))
    return from == to;
  if (SCALAR_FLOAT_MODE_P (from) != SCALAR_FLOAT_MODE_P (to))
    return !reg_classes_intersect_p (rclass, FR_REGS);
  return true;
}

#include "gt-ia64.h"
