/* Target Code for TI C6X
   Copyright (C) 2010-2021 Free Software Foundation, Inc.
   Contributed by Andrew Jenner <andrew@codesourcery.com>
   Contributed by Bernd Schmidt <bernds@codesourcery.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 "gimple-expr.h"
#include "cfghooks.h"
#include "df.h"
#include "memmodel.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 "cgraph.h"
#include "diagnostic-core.h"
#include "stor-layout.h"
#include "varasm.h"
#include "calls.h"
#include "output.h"
#include "insn-attr.h"
#include "explow.h"
#include "expr.h"
#include "cfgrtl.h"
#include "sched-int.h"
#include "tm-constrs.h"
#include "langhooks.h"
#include "sel-sched.h"
#include "debug.h"
#include "hw-doloop.h"
#include "function-abi.h"
#include "regrename.h"
#include "dumpfile.h"
#include "builtins.h"
#include "flags.h"

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

/* Table of supported architecture variants.  */
typedef struct
{
  const char *arch;
  enum c6x_cpu_type type;
  unsigned short features;
} c6x_arch_table;

/* A list of all ISAs, mapping each one to a representative device.
   Used for -march selection.  */
static const c6x_arch_table all_isas[] =
{
#define C6X_ISA(NAME,DEVICE,FLAGS) \
  { NAME, DEVICE, FLAGS },
#include "c6x-isas.def"
#undef C6X_ISA
  { NULL, C6X_CPU_C62X, 0 }
};

/* This is the parsed result of the "-march=" option, if given.  */
enum c6x_cpu_type c6x_arch = C6X_DEFAULT_ARCH;

/* A mask of insn types that are allowed by the architecture selected by
   the -march option.  */
unsigned long c6x_insn_mask = C6X_DEFAULT_INSN_MASK;

/* The instruction that is being output (as obtained from FINAL_PRESCAN_INSN).
 */
static rtx_insn *c6x_current_insn = NULL;

/* A decl we build to access __c6xabi_DSBT_base.  */
static GTY(()) tree dsbt_decl;

/* Determines whether we run our final scheduling pass or not.  We always
   avoid the normal second scheduling pass.  */
static int c6x_flag_schedule_insns2;

/* Determines whether we run variable tracking in machine dependent
   reorganization.  */
static int c6x_flag_var_tracking;

/* Determines whether we use modulo scheduling.  */
static int c6x_flag_modulo_sched;

/* Record the state of flag_pic before we set it to 1 for DSBT.  */
int c6x_initial_flag_pic;

typedef struct
{
  /* We record the clock cycle for every insn during scheduling.  */
  int clock;
  /* After scheduling, we run assign_reservations to choose unit
     reservations for all insns.  These are recorded here.  */
  int reservation;
  /* Records the new condition for insns which must be made
     conditional after scheduling.  An entry of NULL_RTX means no such
     change is necessary.  */
  rtx new_cond;
  /* True for the first insn that was scheduled in an ebb.  */
  bool ebb_start;
  /* The scheduler state after the insn, transformed into a mask of UNIT_QID
     bits rather than storing the state.  Meaningful only for the last
     insn in a cycle.  */
  unsigned int unit_mask;
} c6x_sched_insn_info;


/* Record a c6x_sched_insn_info structure for every insn in the function.  */
static vec<c6x_sched_insn_info> insn_info;

#define INSN_INFO_LENGTH (insn_info).length ()
#define INSN_INFO_ENTRY(N) (insn_info[(N)])

static bool done_cfi_sections;

#define RESERVATION_FLAG_D 1
#define RESERVATION_FLAG_L 2
#define RESERVATION_FLAG_S 4
#define RESERVATION_FLAG_M 8
#define RESERVATION_FLAG_DL (RESERVATION_FLAG_D | RESERVATION_FLAG_L)
#define RESERVATION_FLAG_DS (RESERVATION_FLAG_D | RESERVATION_FLAG_S)
#define RESERVATION_FLAG_LS (RESERVATION_FLAG_L | RESERVATION_FLAG_S)
#define RESERVATION_FLAG_DLS (RESERVATION_FLAG_D | RESERVATION_FLAG_LS)

/* The DFA names of the units.  */
static const char *const c6x_unit_names[] =
{
  "d1", "l1", "s1", "m1", "fps1", "fpl1", "adddps1", "adddpl1",
  "d2", "l2", "s2", "m2", "fps2", "fpl2", "adddps2", "adddpl2"
};

/* The DFA unit number for each unit in c6x_unit_names[].  */
static int c6x_unit_codes[ARRAY_SIZE (c6x_unit_names)];

/* Unit query IDs.  */
#define UNIT_QID_D1 0
#define UNIT_QID_L1 1
#define UNIT_QID_S1 2
#define UNIT_QID_M1 3
#define UNIT_QID_FPS1 4
#define UNIT_QID_FPL1 5
#define UNIT_QID_ADDDPS1 6
#define UNIT_QID_ADDDPL1 7
#define UNIT_QID_SIDE_OFFSET 8

#define RESERVATION_S1 2
#define RESERVATION_S2 10

/* An enum for the unit requirements we count in the UNIT_REQS table.  */
enum unitreqs
{
  UNIT_REQ_D,
  UNIT_REQ_L,
  UNIT_REQ_S,
  UNIT_REQ_M,
  UNIT_REQ_DL,
  UNIT_REQ_DS,
  UNIT_REQ_LS,
  UNIT_REQ_DLS,
  UNIT_REQ_T,
  UNIT_REQ_X,
  UNIT_REQ_MAX
};

/* A table used to count unit requirements.  Used when computing minimum
   iteration intervals.  */
typedef int unit_req_table[2][UNIT_REQ_MAX];
static unit_req_table unit_reqs;

/* Register map for debugging.  */
unsigned const dbx_register_map[FIRST_PSEUDO_REGISTER] =
{
  0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,	/* A0 - A15.  */
  37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49,	/* A16 - A32.  */
  50, 51, 52,
  16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28,	/* B0 - B15.  */
  29, 30, 31,
  53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65,	/* B16 - B32.  */
  66, 67, 68,
  -1, -1, -1						/* FP, ARGP, ILC.  */
};

/* Allocate a new, cleared machine_function structure.  */

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

/* Implement TARGET_OPTION_OVERRIDE.  */

static void
c6x_option_override (void)
{
  unsigned i;

  if (global_options_set.x_c6x_arch_option)
    {
      c6x_arch = all_isas[c6x_arch_option].type;
      c6x_insn_mask &= ~C6X_INSNS_ALL_CPU_BITS;
      c6x_insn_mask |= all_isas[c6x_arch_option].features;
    }

  c6x_flag_schedule_insns2 = flag_schedule_insns_after_reload;
  flag_schedule_insns_after_reload = 0;

  c6x_flag_modulo_sched = flag_modulo_sched;
  flag_modulo_sched = 0;

  init_machine_status = c6x_init_machine_status;

  for (i = 0; i < ARRAY_SIZE (c6x_unit_names); i++)
    c6x_unit_codes[i] = get_cpu_unit_code (c6x_unit_names[i]);

  if (flag_pic && !TARGET_DSBT)
    {
      error ("%<-fpic%> and %<-fPIC%> not supported without %<-mdsbt%> "
	     "on this target");
      flag_pic = 0;
    }
  c6x_initial_flag_pic = flag_pic;
  if (TARGET_DSBT && !flag_pic)
    flag_pic = 1;
}


/* Implement the TARGET_CONDITIONAL_REGISTER_USAGE hook.  */

static void
c6x_conditional_register_usage (void)
{
  int i;
  if (c6x_arch == C6X_CPU_C62X || c6x_arch == C6X_CPU_C67X)
    for (i = 16; i < 32; i++)
      {
	fixed_regs[i] = 1;
	fixed_regs[32 + i] = 1;
      }
  if (TARGET_INSNS_64)
    {
      SET_HARD_REG_BIT (reg_class_contents[(int)PREDICATE_A_REGS],
			REG_A0);
      SET_HARD_REG_BIT (reg_class_contents[(int)PREDICATE_REGS],
			REG_A0);
      CLEAR_HARD_REG_BIT (reg_class_contents[(int)NONPREDICATE_A_REGS],
			  REG_A0);
      CLEAR_HARD_REG_BIT (reg_class_contents[(int)NONPREDICATE_REGS],
			  REG_A0);
    }
}

static GTY(()) rtx eqdf_libfunc;
static GTY(()) rtx nedf_libfunc;
static GTY(()) rtx ledf_libfunc;
static GTY(()) rtx ltdf_libfunc;
static GTY(()) rtx gedf_libfunc;
static GTY(()) rtx gtdf_libfunc;
static GTY(()) rtx eqsf_libfunc;
static GTY(()) rtx nesf_libfunc;
static GTY(()) rtx lesf_libfunc;
static GTY(()) rtx ltsf_libfunc;
static GTY(()) rtx gesf_libfunc;
static GTY(()) rtx gtsf_libfunc;
static GTY(()) rtx strasgi_libfunc;
static GTY(()) rtx strasgi64p_libfunc;

/* Implement the TARGET_INIT_LIBFUNCS macro.  We use this to rename library
   functions to match the C6x ABI.  */

static void
c6x_init_libfuncs (void)
{
  /* Double-precision floating-point arithmetic.  */
  set_optab_libfunc (add_optab, DFmode, "__c6xabi_addd");
  set_optab_libfunc (sdiv_optab, DFmode, "__c6xabi_divd");
  set_optab_libfunc (smul_optab, DFmode, "__c6xabi_mpyd");
  set_optab_libfunc (neg_optab, DFmode, "__c6xabi_negd");
  set_optab_libfunc (sub_optab, DFmode, "__c6xabi_subd");

  /* Single-precision floating-point arithmetic.  */
  set_optab_libfunc (add_optab, SFmode, "__c6xabi_addf");
  set_optab_libfunc (sdiv_optab, SFmode, "__c6xabi_divf");
  set_optab_libfunc (smul_optab, SFmode, "__c6xabi_mpyf");
  set_optab_libfunc (neg_optab, SFmode, "__c6xabi_negf");
  set_optab_libfunc (sub_optab, SFmode, "__c6xabi_subf");

  /* Floating-point comparisons.  */
  eqsf_libfunc = init_one_libfunc ("__c6xabi_eqf");
  nesf_libfunc = init_one_libfunc ("__c6xabi_neqf");
  lesf_libfunc = init_one_libfunc ("__c6xabi_lef");
  ltsf_libfunc = init_one_libfunc ("__c6xabi_ltf");
  gesf_libfunc = init_one_libfunc ("__c6xabi_gef");
  gtsf_libfunc = init_one_libfunc ("__c6xabi_gtf");
  eqdf_libfunc = init_one_libfunc ("__c6xabi_eqd");
  nedf_libfunc = init_one_libfunc ("__c6xabi_neqd");
  ledf_libfunc = init_one_libfunc ("__c6xabi_led");
  ltdf_libfunc = init_one_libfunc ("__c6xabi_ltd");
  gedf_libfunc = init_one_libfunc ("__c6xabi_ged");
  gtdf_libfunc = init_one_libfunc ("__c6xabi_gtd");

  set_optab_libfunc (eq_optab, SFmode, NULL);
  set_optab_libfunc (ne_optab, SFmode, "__c6xabi_neqf");
  set_optab_libfunc (gt_optab, SFmode, NULL);
  set_optab_libfunc (ge_optab, SFmode, NULL);
  set_optab_libfunc (lt_optab, SFmode, NULL);
  set_optab_libfunc (le_optab, SFmode, NULL);
  set_optab_libfunc (unord_optab, SFmode, "__c6xabi_unordf");
  set_optab_libfunc (eq_optab, DFmode, NULL);
  set_optab_libfunc (ne_optab, DFmode, "__c6xabi_neqd");
  set_optab_libfunc (gt_optab, DFmode, NULL);
  set_optab_libfunc (ge_optab, DFmode, NULL);
  set_optab_libfunc (lt_optab, DFmode, NULL);
  set_optab_libfunc (le_optab, DFmode, NULL);
  set_optab_libfunc (unord_optab, DFmode, "__c6xabi_unordd");

  /* Floating-point to integer conversions.  */
  set_conv_libfunc (sfix_optab, SImode, DFmode, "__c6xabi_fixdi");
  set_conv_libfunc (ufix_optab, SImode, DFmode, "__c6xabi_fixdu");
  set_conv_libfunc (sfix_optab, DImode, DFmode, "__c6xabi_fixdlli");
  set_conv_libfunc (ufix_optab, DImode, DFmode, "__c6xabi_fixdull");
  set_conv_libfunc (sfix_optab, SImode, SFmode, "__c6xabi_fixfi");
  set_conv_libfunc (ufix_optab, SImode, SFmode, "__c6xabi_fixfu");
  set_conv_libfunc (sfix_optab, DImode, SFmode, "__c6xabi_fixflli");
  set_conv_libfunc (ufix_optab, DImode, SFmode, "__c6xabi_fixfull");

  /* Conversions between floating types.  */
  set_conv_libfunc (trunc_optab, SFmode, DFmode, "__c6xabi_cvtdf");
  set_conv_libfunc (sext_optab, DFmode, SFmode, "__c6xabi_cvtfd");

  /* Integer to floating-point conversions.  */
  set_conv_libfunc (sfloat_optab, DFmode, SImode, "__c6xabi_fltid");
  set_conv_libfunc (ufloat_optab, DFmode, SImode, "__c6xabi_fltud");
  set_conv_libfunc (sfloat_optab, DFmode, DImode, "__c6xabi_fltllid");
  set_conv_libfunc (ufloat_optab, DFmode, DImode, "__c6xabi_fltulld");
  set_conv_libfunc (sfloat_optab, SFmode, SImode, "__c6xabi_fltif");
  set_conv_libfunc (ufloat_optab, SFmode, SImode, "__c6xabi_fltuf");
  set_conv_libfunc (sfloat_optab, SFmode, DImode, "__c6xabi_fltllif");
  set_conv_libfunc (ufloat_optab, SFmode, DImode, "__c6xabi_fltullf");

  /* Long long.  */
  set_optab_libfunc (smul_optab, DImode, "__c6xabi_mpyll");
  set_optab_libfunc (ashl_optab, DImode, "__c6xabi_llshl");
  set_optab_libfunc (lshr_optab, DImode, "__c6xabi_llshru");
  set_optab_libfunc (ashr_optab, DImode, "__c6xabi_llshr");

  set_optab_libfunc (sdiv_optab, SImode, "__c6xabi_divi");
  set_optab_libfunc (udiv_optab, SImode, "__c6xabi_divu");
  set_optab_libfunc (smod_optab, SImode, "__c6xabi_remi");
  set_optab_libfunc (umod_optab, SImode, "__c6xabi_remu");
  set_optab_libfunc (sdivmod_optab, SImode, "__c6xabi_divremi");
  set_optab_libfunc (udivmod_optab, SImode, "__c6xabi_divremu");
  set_optab_libfunc (sdiv_optab, DImode, "__c6xabi_divlli");
  set_optab_libfunc (udiv_optab, DImode, "__c6xabi_divull");
  set_optab_libfunc (smod_optab, DImode, "__c6xabi_remlli");
  set_optab_libfunc (umod_optab, DImode, "__c6xabi_remull");
  set_optab_libfunc (udivmod_optab, DImode, "__c6xabi_divremull");

  /* Block move.  */
  strasgi_libfunc = init_one_libfunc ("__c6xabi_strasgi");
  strasgi64p_libfunc = init_one_libfunc ("__c6xabi_strasgi_64plus");
}

/* Begin the assembly file.  */

static void
c6x_file_start (void)
{
  /* Variable tracking should be run after all optimizations which change order
     of insns.  It also needs a valid CFG.  This can't be done in
     c6x_override_options, because flag_var_tracking is finalized after
     that.  */
  c6x_flag_var_tracking = flag_var_tracking;
  flag_var_tracking = 0;

  done_cfi_sections = false;
  default_file_start ();

  /* Arrays are aligned to 8-byte boundaries.  */
  asm_fprintf (asm_out_file,
	       "\t.c6xabi_attribute Tag_ABI_array_object_alignment, 0\n");
  asm_fprintf (asm_out_file,
	       "\t.c6xabi_attribute Tag_ABI_array_object_align_expected, 0\n");

  /* Stack alignment is 8 bytes.  */
  asm_fprintf (asm_out_file,
	       "\t.c6xabi_attribute Tag_ABI_stack_align_needed, 0\n");
  asm_fprintf (asm_out_file,
	       "\t.c6xabi_attribute Tag_ABI_stack_align_preserved, 0\n");

#if 0 /* FIXME: Reenable when TI's tools are fixed.  */
  /* ??? Ideally we'd check flag_short_wchar somehow.  */
  asm_fprintf (asm_out_file, "\t.c6xabi_attribute Tag_ABI_wchar_t, %d\n", 2);
#endif

  /* We conform to version 1.0 of the ABI.  */
  asm_fprintf (asm_out_file,
	       "\t.c6xabi_attribute Tag_ABI_conformance, \"1.0\"\n");

}

/* The LTO frontend only enables exceptions when it sees a function that
   uses it.  This changes the return value of dwarf2out_do_frame, so we
   have to check before every function.  */

void
c6x_output_file_unwind (FILE * f)
{
  if (done_cfi_sections)
    return;

  /* Output a .cfi_sections directive.  */
  if (dwarf2out_do_frame ())
    {
      if (flag_unwind_tables || flag_exceptions)
	{
	  if (dwarf_debuginfo_p ())
	    asm_fprintf (f, "\t.cfi_sections .debug_frame, .c6xabi.exidx\n");
	  else
	    asm_fprintf (f, "\t.cfi_sections .c6xabi.exidx\n");
	}
      else
	asm_fprintf (f, "\t.cfi_sections .debug_frame\n");
      done_cfi_sections = true;
    }
}

/* Output unwind directives at the end of a function.  */

static void
c6x_output_fn_unwind (FILE * f)
{
  /* Return immediately if we are not generating unwinding tables.  */
  if (! (flag_unwind_tables || flag_exceptions))
    return;

  /* If this function will never be unwound, then mark it as such.  */
  if (!(flag_unwind_tables || crtl->uses_eh_lsda)
      && (TREE_NOTHROW (current_function_decl)
	  || crtl->all_throwers_are_sibcalls))
    fputs("\t.cantunwind\n", f);

  fputs ("\t.endp\n", f);
}


/* Stack and Calling.  */

int argument_registers[10] =
{
  REG_A4, REG_B4,
  REG_A6, REG_B6,
  REG_A8, REG_B8,
  REG_A10, REG_B10,
  REG_A12, REG_B12
};

/* Implements the macro INIT_CUMULATIVE_ARGS defined in c6x.h.  */

void
c6x_init_cumulative_args (CUMULATIVE_ARGS *cum, const_tree fntype, rtx libname,
			  int n_named_args ATTRIBUTE_UNUSED)
{
  cum->count = 0;
  cum->nregs = 10;
  if (!libname && fntype)
    {
      /* We need to find out the number of named arguments.  Unfortunately,
	 for incoming arguments, N_NAMED_ARGS is set to -1.  */
      if (stdarg_p (fntype))
	cum->nregs = type_num_arguments (fntype) - 1;
      if (cum->nregs > 10)
	cum->nregs = 10;
    }
}

/* Implement TARGET_FUNCTION_ARG.  */

static rtx
c6x_function_arg (cumulative_args_t cum_v, const function_arg_info &arg)
{
  CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
  if (cum->count >= cum->nregs)
    return NULL_RTX;
  if (tree type = arg.type)
    {
      HOST_WIDE_INT size = int_size_in_bytes (type);
      if (TARGET_BIG_ENDIAN && AGGREGATE_TYPE_P (type))
	{
	  if (size > 4)
	    {
	      rtx reg1 = gen_rtx_REG (SImode, argument_registers[cum->count] + 1);
	      rtx reg2 = gen_rtx_REG (SImode, argument_registers[cum->count]);
	      rtvec vec = gen_rtvec (2, gen_rtx_EXPR_LIST (VOIDmode, reg1, const0_rtx),
				     gen_rtx_EXPR_LIST (VOIDmode, reg2, GEN_INT (4)));
	      return gen_rtx_PARALLEL (arg.mode, vec);
	    }
	}
    }
  return gen_rtx_REG (arg.mode, argument_registers[cum->count]);
}

static void
c6x_function_arg_advance (cumulative_args_t cum_v, const function_arg_info &)
{
  CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
  cum->count++;
}


/* Return true if BLOCK_REG_PADDING (MODE, TYPE, FIRST) should return
   upward rather than downward.  */

bool
c6x_block_reg_pad_upward (machine_mode mode ATTRIBUTE_UNUSED,
			  const_tree type, bool first)
{
  HOST_WIDE_INT size;

  if (!TARGET_BIG_ENDIAN)
    return true;
  if (!first)
    return true;
  if (!type)
    return true;
  size = int_size_in_bytes (type);
  return size == 3;
}

/* Implement TARGET_FUNCTION_ARG_BOUNDARY.  */

static unsigned int
c6x_function_arg_boundary (machine_mode mode, const_tree type)
{
  unsigned int boundary = type ? TYPE_ALIGN (type) : GET_MODE_BITSIZE (mode);

  if (boundary > BITS_PER_WORD)
    return 2 * BITS_PER_WORD;

  if (mode == BLKmode)
    {
      HOST_WIDE_INT size = int_size_in_bytes (type);
      if (size > 4)
	return 2 * BITS_PER_WORD;
      if (boundary < BITS_PER_WORD)
	{
	  if (size >= 3)
	    return BITS_PER_WORD;
	  if (size >= 2)
	    return 2 * BITS_PER_UNIT;
	}
    }
  return boundary;
}

/* Implement TARGET_FUNCTION_ARG_ROUND_BOUNDARY.  */
static unsigned int
c6x_function_arg_round_boundary (machine_mode mode, const_tree type)
{
  return c6x_function_arg_boundary (mode, type);
}

/* TARGET_FUNCTION_VALUE implementation.  Returns an RTX representing the place
   where function FUNC returns or receives a value of data type TYPE.  */

static rtx
c6x_function_value (const_tree type, const_tree func ATTRIBUTE_UNUSED,
		    bool outgoing ATTRIBUTE_UNUSED)
{
  /* Functions return values in register A4.  When returning aggregates, we may
     have to adjust for endianness.  */
  if (TARGET_BIG_ENDIAN && type && AGGREGATE_TYPE_P (type))
    {
      HOST_WIDE_INT size = int_size_in_bytes (type);
      if (size > 4)
	{

	  rtx reg1 = gen_rtx_REG (SImode, REG_A4 + 1);
	  rtx reg2 = gen_rtx_REG (SImode, REG_A4);
	  rtvec vec = gen_rtvec (2, gen_rtx_EXPR_LIST (VOIDmode, reg1, const0_rtx),
				 gen_rtx_EXPR_LIST (VOIDmode, reg2, GEN_INT (4)));
	  return gen_rtx_PARALLEL (TYPE_MODE (type), vec);
	}
    }
  return gen_rtx_REG (TYPE_MODE (type), REG_A4);
}

/* Implement TARGET_LIBCALL_VALUE.  */

static rtx
c6x_libcall_value (machine_mode mode, const_rtx fun ATTRIBUTE_UNUSED)
{
  return gen_rtx_REG (mode, REG_A4);
}

/* TARGET_STRUCT_VALUE_RTX implementation.  */

static rtx
c6x_struct_value_rtx (tree type ATTRIBUTE_UNUSED, int incoming ATTRIBUTE_UNUSED)
{
  return gen_rtx_REG (Pmode, REG_A3);
}

/* Implement TARGET_FUNCTION_VALUE_REGNO_P.  */

static bool
c6x_function_value_regno_p (const unsigned int regno)
{
  return regno == REG_A4;
}

/* Types larger than 64 bit, and variable sized types, are passed by
   reference.  The callee must copy them; see TARGET_CALLEE_COPIES.  */

static bool
c6x_pass_by_reference (cumulative_args_t, const function_arg_info &arg)
{
  int size = -1;
  if (arg.type)
    size = int_size_in_bytes (arg.type);
  else if (arg.mode != VOIDmode)
    size = GET_MODE_SIZE (arg.mode);
  return size > 2 * UNITS_PER_WORD || size == -1;
}

/* Decide whether a type should be returned in memory (true)
   or in a register (false).  This is called by the macro
   TARGET_RETURN_IN_MEMORY.  */

static bool
c6x_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
{
  int size = int_size_in_bytes (type);
  return size > 2 * UNITS_PER_WORD || size == -1;
}

/* Values which must be returned in the most-significant end of the return
   register.  */

static bool
c6x_return_in_msb (const_tree valtype)
{
  HOST_WIDE_INT size = int_size_in_bytes (valtype);
  return TARGET_BIG_ENDIAN && AGGREGATE_TYPE_P (valtype) && size == 3;
}

/* Return the type to use as __builtin_va_list.  */
static tree
c6x_build_builtin_va_list (void)
{
  return build_pointer_type (char_type_node);
}

static void
c6x_asm_trampoline_template (FILE *f)
{
  fprintf (f, "\t.long\t0x0000002b\n"); /* mvkl .s2 fnlow,B0 */
  fprintf (f, "\t.long\t0x01000028\n"); /* || mvkl .s1 sclow,A2 */
  fprintf (f, "\t.long\t0x0000006b\n"); /* mvkh .s2 fnhigh,B0 */
  fprintf (f, "\t.long\t0x01000068\n"); /* || mvkh .s1 schigh,A2 */
  fprintf (f, "\t.long\t0x00000362\n"); /* b .s2 B0 */
  fprintf (f, "\t.long\t0x00008000\n"); /* nop 5 */
  fprintf (f, "\t.long\t0x00000000\n"); /* nop */
  fprintf (f, "\t.long\t0x00000000\n"); /* nop */
}

/* Emit RTL insns to initialize the variable parts of a trampoline at
   TRAMP. FNADDR is an RTX for the address of the function's pure
   code.  CXT is an RTX for the static chain value for the function.  */

static void
c6x_initialize_trampoline (rtx tramp, tree fndecl, rtx cxt)
{
  rtx fnaddr = XEXP (DECL_RTL (fndecl), 0);
  rtx t1 = copy_to_reg (fnaddr);
  rtx t2 = copy_to_reg (cxt);
  rtx mask = gen_reg_rtx (SImode);
  int i;

  emit_block_move (tramp, assemble_trampoline_template (),
		   GEN_INT (TRAMPOLINE_SIZE), BLOCK_OP_NORMAL);

  emit_move_insn (mask, GEN_INT (0xffff << 7));

  for (i = 0; i < 4; i++)
    {
      rtx mem = adjust_address (tramp, SImode, i * 4);
      rtx t = (i & 1) ? t2 : t1;
      rtx v1 = gen_reg_rtx (SImode);
      rtx v2 = gen_reg_rtx (SImode);
      emit_move_insn (v1, mem);
      if (i < 2)
	emit_insn (gen_ashlsi3 (v2, t, GEN_INT (7)));
      else
	emit_insn (gen_lshrsi3 (v2, t, GEN_INT (9)));
      emit_insn (gen_andsi3 (v2, v2, mask));
      emit_insn (gen_iorsi3 (v2, v2, v1));
      emit_move_insn (mem, v2);
    }
#ifdef CLEAR_INSN_CACHE
  tramp = XEXP (tramp, 0);
  maybe_emit_call_builtin___clear_cache (tramp,
					 plus_constant (Pmode,
							tramp,
							TRAMPOLINE_SIZE));
#endif
}

/* Determine whether c6x_output_mi_thunk can succeed.  */

static bool
c6x_can_output_mi_thunk (const_tree thunk ATTRIBUTE_UNUSED,
			 HOST_WIDE_INT delta ATTRIBUTE_UNUSED,
			 HOST_WIDE_INT vcall_offset ATTRIBUTE_UNUSED,
			 const_tree function ATTRIBUTE_UNUSED)
{
  return !TARGET_LONG_CALLS;
}

/* Output the assembler code for a thunk function.  THUNK 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
c6x_output_mi_thunk (FILE *file ATTRIBUTE_UNUSED,
		     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 xops[5];
  /* The this parameter is passed as the first argument.  */
  rtx this_rtx = gen_rtx_REG (Pmode, REG_A4);

  assemble_start_function (thunk, fnname);
  c6x_current_insn = NULL;

  xops[4] = XEXP (DECL_RTL (function), 0);
  if (!vcall_offset)
    {
      output_asm_insn ("b .s2 \t%4", xops);
      if (!delta)
	output_asm_insn ("nop 5", xops);
    }

  /* Adjust the this parameter by a fixed constant.  */
  if (delta)
    {
      xops[0] = GEN_INT (delta);
      xops[1] = this_rtx;
      if (delta >= -16 && delta <= 15)
	{
	  output_asm_insn ("add .s1 %0, %1, %1", xops);
	  if (!vcall_offset)
	    output_asm_insn ("nop 4", xops);
	}
      else if (delta >= 16 && delta < 32)
	{
	  output_asm_insn ("add .d1 %0, %1, %1", xops);
	  if (!vcall_offset)
	    output_asm_insn ("nop 4", xops);
	}
      else if (delta >= -32768 && delta < 32768)
	{
	  output_asm_insn ("mvk .s1 %0, A0", xops);
	  output_asm_insn ("add .d1 %1, A0, %1", xops);
	  if (!vcall_offset)
	    output_asm_insn ("nop 3", xops);
	}
      else
	{
	  output_asm_insn ("mvkl .s1 %0, A0", xops);
	  output_asm_insn ("mvkh .s1 %0, A0", xops);
	  output_asm_insn ("add .d1 %1, A0, %1", xops);
	  if (!vcall_offset)
	    output_asm_insn ("nop 3", xops);
	}
    }

  /* Adjust the this parameter by a value stored in the vtable.  */
  if (vcall_offset)
    {
      rtx a0tmp = gen_rtx_REG (Pmode, REG_A0);
      rtx a3tmp = gen_rtx_REG (Pmode, REG_A3);

      xops[1] = a3tmp;
      xops[2] = a0tmp;
      xops[3] = gen_rtx_MEM (Pmode, a0tmp);
      output_asm_insn ("mv .s1 a4, %2", xops);
      output_asm_insn ("ldw .d1t1 %3, %2", xops);

      /* Adjust the this parameter.  */
      xops[0] = gen_rtx_MEM (Pmode, plus_constant (Pmode, a0tmp,
						   vcall_offset));
      if (!memory_operand (xops[0], Pmode))
	{
	  rtx tmp2 = gen_rtx_REG (Pmode, REG_A1);
	  xops[0] = GEN_INT (vcall_offset);
	  xops[1] = tmp2;
	  output_asm_insn ("mvkl .s1 %0, %1", xops);
	  output_asm_insn ("mvkh .s1 %0, %1", xops);
	  output_asm_insn ("nop 2", xops);
	  output_asm_insn ("add .d1 %2, %1, %2", xops);
	  xops[0] = gen_rtx_MEM (Pmode, a0tmp);
	}
      else
	output_asm_insn ("nop 4", xops);
      xops[2] = this_rtx;
      output_asm_insn ("ldw .d1t1 %0, %1", xops);
      output_asm_insn ("|| b .s2 \t%4", xops);
      output_asm_insn ("nop 4", xops);
      output_asm_insn ("add .d1 %2, %1, %2", xops);
    }
  assemble_end_function (thunk, fnname);
}

/* Return true if EXP goes in small data/bss.  */

static bool
c6x_in_small_data_p (const_tree exp)
{
  /* 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_WEAK (exp))
    return false;

  if (TREE_CODE (exp) == VAR_DECL && DECL_SECTION_NAME (exp))
    {
      const char *section = DECL_SECTION_NAME (exp);

      if (strcmp (section, ".neardata") == 0
	  || startswith (section, ".neardata.")
	  || startswith (section, ".gnu.linkonce.s.")
	  || strcmp (section, ".bss") == 0
	  || startswith (section, ".bss.")
	  || startswith (section, ".gnu.linkonce.sb.")
	  || strcmp (section, ".rodata") == 0
	  || startswith (section, ".rodata.")
	  || startswith (section, ".gnu.linkonce.s2."))
	return true;
    }
  else
    return PLACE_IN_SDATA_P (exp);

  return false;
}

/* Return a section for X.  The only special thing we do here is to
   honor small data.  We don't have a tree type, so we can't use the
   PLACE_IN_SDATA_P macro we use everywhere else; we choose to place
   everything sized 8 bytes or smaller into small data.  */

static section *
c6x_select_rtx_section (machine_mode mode, rtx x,
			unsigned HOST_WIDE_INT align)
{
  if (c6x_sdata_mode == C6X_SDATA_ALL
      || (c6x_sdata_mode != C6X_SDATA_NONE && GET_MODE_SIZE (mode) <= 8))
    /* ??? Consider using mergeable sdata sections.  */
    return sdata_section;
  else
    return default_elf_select_rtx_section (mode, x, align);
}

static section *
c6x_elf_select_section (tree decl, int reloc,
			unsigned HOST_WIDE_INT align)
{
  const char *sname = NULL;
  unsigned int flags = SECTION_WRITE;
  if (c6x_in_small_data_p (decl))
    {
      switch (categorize_decl_for_section (decl, reloc))
	{
	case SECCAT_SRODATA:
	  sname = ".rodata";
	  flags = 0;
	  break;
	case SECCAT_SDATA:
	  sname = ".neardata";
	  break;
	case SECCAT_SBSS:
	  sname = ".bss";
	  flags |= SECTION_BSS;
	default:
	  break;
	}
    }
  else
    {
      switch (categorize_decl_for_section (decl, reloc))
	{
	case SECCAT_DATA:
	  sname = ".fardata";
	  break;
	case SECCAT_DATA_REL:
	  sname = ".fardata.rel";
	  break;
	case SECCAT_DATA_REL_LOCAL:
	  sname = ".fardata.rel.local";
	  break;
	case SECCAT_DATA_REL_RO:
	  sname = ".fardata.rel.ro";
	  break;
	case SECCAT_DATA_REL_RO_LOCAL:
	  sname = ".fardata.rel.ro.local";
	  break;
	case SECCAT_BSS:
	  sname = ".far";
	  flags |= SECTION_BSS;
	  break;
	case SECCAT_RODATA:
	  sname = ".const";
	  flags = 0;
	  break;
	case SECCAT_SRODATA:
	case SECCAT_SDATA:
	case SECCAT_SBSS:
	  gcc_unreachable ();
	default:
	  break;
	}
    }
  if (sname)
    {
      /* We might get called with string constants, but get_named_section
	 doesn't like them as they are not DECLs.  Also, we need to set
	 flags in that case.  */
      if (!DECL_P (decl))
	return get_section (sname, flags, NULL);
      return get_named_section (decl, sname, reloc);
    }

  return default_elf_select_section (decl, reloc, align);
}

/* Build up a unique section name, expressed as a
   STRING_CST node, and assign it to DECL_SECTION_NAME (decl).
   RELOC indicates whether the initial value of EXP requires
   link-time relocations.  */

static void ATTRIBUTE_UNUSED
c6x_elf_unique_section (tree decl, int reloc)
{
  const char *prefix = NULL;
  /* We only need to use .gnu.linkonce if we don't have COMDAT groups.  */
  bool one_only = DECL_COMDAT_GROUP (decl) && !HAVE_COMDAT_GROUP;

  if (c6x_in_small_data_p (decl))
    {
      switch (categorize_decl_for_section (decl, reloc))
	{
	case SECCAT_SDATA:
          prefix = one_only ? ".s" : ".neardata";
	  break;
	case SECCAT_SBSS:
          prefix = one_only ? ".sb" : ".bss";
	  break;
	case SECCAT_SRODATA:
          prefix = one_only ? ".s2" : ".rodata";
	  break;
	case SECCAT_RODATA_MERGE_STR:
	case SECCAT_RODATA_MERGE_STR_INIT:
	case SECCAT_RODATA_MERGE_CONST:
	case SECCAT_RODATA:
	case SECCAT_DATA:
	case SECCAT_DATA_REL:
	case SECCAT_DATA_REL_LOCAL:
	case SECCAT_DATA_REL_RO:
	case SECCAT_DATA_REL_RO_LOCAL:
	  gcc_unreachable ();
	default:
	  /* Everything else we place into default sections and hope for the
	     best.  */
	  break;
	}
    }
  else
    {
      switch (categorize_decl_for_section (decl, reloc))
	{
	case SECCAT_DATA:
	case SECCAT_DATA_REL:
	case SECCAT_DATA_REL_LOCAL:
	case SECCAT_DATA_REL_RO:
	case SECCAT_DATA_REL_RO_LOCAL:
          prefix = one_only ? ".fd" : ".fardata";
	  break;
	case SECCAT_BSS:
          prefix = one_only ? ".fb" : ".far";
	  break;
	case SECCAT_RODATA:
	case SECCAT_RODATA_MERGE_STR:
	case SECCAT_RODATA_MERGE_STR_INIT:
	case SECCAT_RODATA_MERGE_CONST:
          prefix = one_only ? ".fr" : ".const";
	  break;
	case SECCAT_SRODATA:
	case SECCAT_SDATA:
	case SECCAT_SBSS:
	  gcc_unreachable ();
	default:
	  break;
	}
    }

  if (prefix)
    {
      const char *name, *linkonce;
      char *string;

      name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
      name = targetm.strip_name_encoding (name);

      /* If we're using one_only, then there needs to be a .gnu.linkonce
	 prefix to the section name.  */
      linkonce = one_only ? ".gnu.linkonce" : "";

      string = ACONCAT ((linkonce, prefix, ".", name, NULL));

      set_decl_section_name (decl, string);
      return;
    }
  default_unique_section (decl, reloc);
}

static unsigned int
c6x_section_type_flags (tree decl, const char *name, int reloc)
{
  unsigned int flags = 0;

  if (strcmp (name, ".far") == 0
      || startswith (name, ".far."))
    flags |= SECTION_BSS;

  flags |= default_section_type_flags (decl, name, reloc);

  /* The ".far" section will be declared with @nobits elsewhere.
     But when declared via this path it will not have the @nobits
     flag because of SECTION_NOTYPE.  This causes linker warnings
     due to the mismatched attribute.  Clearing SECTION_NOTYPE
     for the ".far" section is sufficient to fix this problem.  */
  if (strcmp (name, ".far") == 0)
    flags &= ~SECTION_NOTYPE;

  return flags;
}

/* Checks whether the given CALL_EXPR would use a caller saved
   register.  This is used to decide whether sibling call optimization
   could be performed on the respective function call.  */

static bool
c6x_call_saved_register_used (tree call_expr)
{
  CUMULATIVE_ARGS cum_v;
  cumulative_args_t cum;
  HARD_REG_SET call_saved_regset;
  tree parameter;
  rtx parm_rtx;
  int i;

  INIT_CUMULATIVE_ARGS (cum_v, NULL, NULL, 0, 0);
  cum = pack_cumulative_args (&cum_v);

  call_saved_regset = ~call_used_or_fixed_regs;
  for (i = 0; i < call_expr_nargs (call_expr); i++)
    {
      parameter = CALL_EXPR_ARG (call_expr, i);
      gcc_assert (parameter);

      /* For an undeclared variable passed as parameter we will get
	 an ERROR_MARK node here.  */
      if (TREE_CODE (parameter) == ERROR_MARK)
	return true;

      function_arg_info arg (TREE_TYPE (parameter), /*named=*/true);
      apply_pass_by_reference_rules (&cum_v, arg);

       parm_rtx = c6x_function_arg (cum, arg);

       c6x_function_arg_advance (cum, arg);

       if (!parm_rtx)
	 continue;

       if (REG_P (parm_rtx)
	   && overlaps_hard_reg_set_p (call_saved_regset, GET_MODE (parm_rtx),
				       REGNO (parm_rtx)))
	 return true;
       if (GET_CODE (parm_rtx) == PARALLEL)
	 {
	   int n = XVECLEN (parm_rtx, 0);
	   while (n-- > 0)
	     {
	       rtx x = XEXP (XVECEXP (parm_rtx, 0, n), 0);
	       if (REG_P (x)
		   && overlaps_hard_reg_set_p (call_saved_regset,
					       GET_MODE (x), REGNO (x)))
		 return true;
	     }
	 }
    }
  return false;
}

/* Decide whether we can make a sibling call to a function.  DECL is the
   declaration of the function being targeted by the call and EXP is the
   CALL_EXPR representing the call.  */

static bool
c6x_function_ok_for_sibcall (tree decl, tree exp)
{
  /* Registers A10, A12, B10 and B12 are available as arguments
     register but unfortunately caller saved. This makes functions
     needing these registers for arguments not suitable for
     sibcalls.  */
  if (c6x_call_saved_register_used (exp))
    return false;

  if (!flag_pic)
    return true;

  if (TARGET_DSBT)
    {
      /* When compiling for DSBT, the calling function must be local,
	 so that when we reload B14 in the sibcall epilogue, it will
	 not change its value.  */

      if (!decl)
	/* Not enough information.  */
	return false;

      cgraph_node *this_func
	= cgraph_node::local_info_node (current_function_decl);
      return this_func->local;
    }

  return true;
}

/* Return true if DECL is known to be linked into section SECTION.  */

static bool
c6x_function_in_section_p (tree decl, section *section)
{
  /* We can only be certain about functions defined in the same
     compilation unit.  */
  if (!TREE_STATIC (decl))
    return false;

  /* Make sure that SYMBOL always binds to the definition in this
     compilation unit.  */
  if (!targetm.binds_local_p (decl))
    return false;

  /* If DECL_SECTION_NAME is set, assume it is trustworthy.  */
  if (!DECL_SECTION_NAME (decl))
    {
      /* Make sure that we will not create a unique section for DECL.  */
      if (flag_function_sections || DECL_COMDAT_GROUP (decl))
	return false;
    }

  return function_section (decl) == section;
}

/* Return true if a call to OP, which is a SYMBOL_REF, must be expanded
   as a long call.  */
bool
c6x_long_call_p (rtx op)
{
  tree decl;

  if (!TARGET_LONG_CALLS)
    return false;

  decl = SYMBOL_REF_DECL (op);

  /* Try to determine whether the symbol is in the same section as the current
     function.  Be conservative, and only cater for cases in which the
     whole of the current function is placed in the same section.  */
  if (decl != NULL_TREE
      && !flag_reorder_blocks_and_partition
      && TREE_CODE (decl) == FUNCTION_DECL
      && c6x_function_in_section_p (decl, current_function_section ()))
    return false;

  return true;
}

/* Emit the sequence for a call.  */
void
c6x_expand_call (rtx retval, rtx address, bool sibcall)
{
  rtx callee = XEXP (address, 0);
  rtx call_insn;

  if (!c6x_call_operand (callee, Pmode))
    {
      callee = force_reg (Pmode, callee);
      address = change_address (address, Pmode, callee);
    }
  call_insn = gen_rtx_CALL (VOIDmode, address, const0_rtx);
  if (sibcall)
    {
      call_insn = emit_call_insn (call_insn);
      use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn),
	       gen_rtx_REG (Pmode, REG_B3));
    }
  else
    {
      if (retval == NULL_RTX)
	call_insn = emit_call_insn (call_insn);
      else
	call_insn = emit_call_insn (gen_rtx_SET (retval, call_insn));
    }
  if (flag_pic)
    use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), pic_offset_table_rtx);
}

/* Legitimize PIC addresses.  If the address is already position-independent,
   we return ORIG.  Newly generated position-independent addresses go into a
   reg.  This is REG if nonzero, otherwise we allocate register(s) as
   necessary.  PICREG is the register holding the pointer to the PIC offset
   table.  */

static rtx
legitimize_pic_address (rtx orig, rtx reg, rtx picreg)
{
  rtx addr = orig;
  rtx new_rtx = orig;

  if (GET_CODE (addr) == SYMBOL_REF || GET_CODE (addr) == LABEL_REF)
    {
      int unspec = UNSPEC_LOAD_GOT;
      rtx tmp;

      if (reg == 0)
	{
	  gcc_assert (can_create_pseudo_p ());
	  reg = gen_reg_rtx (Pmode);
	}
      if (flag_pic == 2)
	{
	  if (can_create_pseudo_p ())
	    tmp = gen_reg_rtx (Pmode);
	  else
	    tmp = reg;
	  emit_insn (gen_movsi_gotoff_high (tmp, addr));
	  emit_insn (gen_movsi_gotoff_lo_sum (tmp, tmp, addr));
	  emit_insn (gen_load_got_gotoff (reg, picreg, tmp));
	}
      else
	{
	  tmp = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), unspec);
	  new_rtx = gen_const_mem (Pmode, gen_rtx_PLUS (Pmode, picreg, tmp));

	  emit_move_insn (reg, new_rtx);
	}
      if (picreg == pic_offset_table_rtx)
	crtl->uses_pic_offset_table = 1;
      return reg;
    }

  else if (GET_CODE (addr) == CONST || GET_CODE (addr) == PLUS)
    {
      rtx base;

      if (GET_CODE (addr) == CONST)
	{
	  addr = XEXP (addr, 0);
	  gcc_assert (GET_CODE (addr) == PLUS);
	}

      if (XEXP (addr, 0) == picreg)
	return orig;

      if (reg == 0)
	{
	  gcc_assert (can_create_pseudo_p ());
	  reg = gen_reg_rtx (Pmode);
	}

      base = legitimize_pic_address (XEXP (addr, 0), reg, picreg);
      addr = legitimize_pic_address (XEXP (addr, 1),
				     base == reg ? NULL_RTX : reg,
				     picreg);

      if (GET_CODE (addr) == CONST_INT)
	{
	  gcc_assert (! reload_in_progress && ! reload_completed);
	  addr = force_reg (Pmode, addr);
	}

      if (GET_CODE (addr) == PLUS && CONSTANT_P (XEXP (addr, 1)))
	{
	  base = gen_rtx_PLUS (Pmode, base, XEXP (addr, 0));
	  addr = XEXP (addr, 1);
	}

      return gen_rtx_PLUS (Pmode, base, addr);
    }

  return new_rtx;
}

/* Expand a move operation in mode MODE.  The operands are in OPERANDS.
   Returns true if no further code must be generated, false if the caller
   should generate an insn to move OPERANDS[1] to OPERANDS[0].  */

bool
expand_move (rtx *operands, machine_mode mode)
{
  rtx dest = operands[0];
  rtx op = operands[1];

  if ((reload_in_progress | reload_completed) == 0
      && GET_CODE (dest) == MEM && GET_CODE (op) != REG)
    operands[1] = force_reg (mode, op);
  else if (mode == SImode && symbolic_operand (op, SImode))
    {
      if (flag_pic)
	{
	  if (sdata_symbolic_operand (op, SImode))
	    {
	      emit_insn (gen_load_sdata_pic (dest, pic_offset_table_rtx, op));
	      crtl->uses_pic_offset_table = 1;
	      return true;
	    }
	  else
	    {
	      rtx temp = (reload_completed || reload_in_progress
			  ? dest : gen_reg_rtx (Pmode));

	      operands[1] = legitimize_pic_address (op, temp,
						    pic_offset_table_rtx);
	    }
	}
      else if (reload_completed
	       && !sdata_symbolic_operand (op, SImode))
	{
	  emit_insn (gen_movsi_high (dest, op));
	  emit_insn (gen_movsi_lo_sum (dest, dest, op));
	  return true;
	}
    }
  return false;
}

/* This function is called when we're about to expand an integer compare
   operation which performs COMPARISON.  It examines the second operand,
   and if it is an integer constant that cannot be used directly on the
   current machine in a comparison insn, it returns true.  */
bool
c6x_force_op_for_comparison_p (enum rtx_code code, rtx op)
{
  if (!CONST_INT_P (op) || satisfies_constraint_Iu4 (op))
    return false;

  if ((code == EQ || code == LT || code == GT)
       && !satisfies_constraint_Is5 (op))
    return true;
  if ((code == GTU || code == LTU)
      && (!TARGET_INSNS_64 || !satisfies_constraint_Iu5 (op)))
    return true;

  return false;
}

/* Emit comparison instruction if necessary, returning the expression
   that holds the compare result in the proper mode.  Return the comparison
   that should be used in the jump insn.  */

rtx
c6x_expand_compare (rtx comparison, machine_mode mode)
{
  enum rtx_code code = GET_CODE (comparison);
  rtx op0 = XEXP (comparison, 0);
  rtx op1 = XEXP (comparison, 1);
  rtx cmp;
  enum rtx_code jump_code = code;
  machine_mode op_mode = GET_MODE (op0);

  if (op_mode == DImode && (code == NE || code == EQ) && op1 == const0_rtx)
    {
      rtx t = gen_reg_rtx (SImode);
      emit_insn (gen_iorsi3 (t, gen_lowpart (SImode, op0),
			     gen_highpart (SImode, op0)));
      op_mode = SImode;
      cmp = t;
    }
  else if (op_mode == DImode)
    {
      rtx lo[2], high[2];
      rtx cmp1, cmp2;

      if (code == NE || code == GEU || code == LEU || code == GE || code == LE)
	{
	  code = reverse_condition (code);
	  jump_code = EQ;
	}
      else
	jump_code = NE;

      split_di (&op0, 1, lo, high);
      split_di (&op1, 1, lo + 1, high + 1);

      if (c6x_force_op_for_comparison_p (code, high[1])
	  || c6x_force_op_for_comparison_p (EQ, high[1]))
	high[1] = force_reg (SImode, high[1]);

      cmp1 = gen_reg_rtx (SImode);
      cmp2 = gen_reg_rtx (SImode);
      emit_insn (gen_rtx_SET (cmp1, gen_rtx_fmt_ee (code, SImode,
						    high[0], high[1])));
      if (code == EQ)
	{
	  if (c6x_force_op_for_comparison_p (code, lo[1]))
	    lo[1] = force_reg (SImode, lo[1]);
	  emit_insn (gen_rtx_SET (cmp2, gen_rtx_fmt_ee (code, SImode,
							lo[0], lo[1])));
	  emit_insn (gen_andsi3 (cmp1, cmp1, cmp2));
	}
      else
	{
	  emit_insn (gen_rtx_SET (cmp2, gen_rtx_EQ (SImode, high[0],
						    high[1])));
	  if (code == GT)
	    code = GTU;
	  else if (code == LT)
	    code = LTU;
	  if (c6x_force_op_for_comparison_p (code, lo[1]))
	    lo[1] = force_reg (SImode, lo[1]);
	  emit_insn (gen_cmpsi_and (cmp2, gen_rtx_fmt_ee (code, SImode,
							  lo[0], lo[1]),
				    lo[0], lo[1], cmp2));
	  emit_insn (gen_iorsi3 (cmp1, cmp1, cmp2));
	}
      cmp = cmp1;
    }
  else if (TARGET_FP && !flag_finite_math_only
	   && (op_mode == DFmode || op_mode == SFmode)
	   && code != EQ && code != NE && code != LT && code != GT
	   && code != UNLE && code != UNGE)
    {
      enum rtx_code code1, code2, code3;
      rtx (*fn) (rtx, rtx, rtx, rtx, rtx);

      jump_code = NE;
      code3 = UNKNOWN;
      switch (code)
	{
	case UNLT:
	case UNGT:
	  jump_code = EQ;
	  /* fall through */
	case LE:
	case GE:
	  code1 = code == LE || code == UNGT ? LT : GT;
	  code2 = EQ;
	  break;

	case UNORDERED:
	  jump_code = EQ;
	  /* fall through */
	case ORDERED:
	  code3 = EQ;
	  /* fall through */
	case LTGT:
	  code1 = LT;
	  code2 = GT;
	  break;

	case UNEQ:
	  code1 = LT;
	  code2 = GT;
	  jump_code = EQ;
	  break;

	default:
	  gcc_unreachable ();
	}

      cmp = gen_reg_rtx (SImode);
      emit_insn (gen_rtx_SET (cmp, gen_rtx_fmt_ee (code1, SImode, op0, op1)));
      fn = op_mode == DFmode ? gen_cmpdf_ior : gen_cmpsf_ior;
      emit_insn (fn (cmp, gen_rtx_fmt_ee (code2, SImode, op0, op1),
		     op0, op1, cmp));
      if (code3 != UNKNOWN)
	emit_insn (fn (cmp, gen_rtx_fmt_ee (code3, SImode, op0, op1),
		       op0, op1, cmp));
    }
  else if (op_mode == SImode && (code == NE || code == EQ) && op1 == const0_rtx)
    cmp = op0;
  else
    {
      bool is_fp_libfunc;
      is_fp_libfunc = !TARGET_FP && (op_mode == DFmode || op_mode == SFmode);

      if ((code == NE || code == GEU || code == LEU || code == GE || code == LE)
	  && !is_fp_libfunc)
	{
	  code = reverse_condition (code);
	  jump_code = EQ;
	}
      else if (code == UNGE)
	{
	  code = LT;
	  jump_code = EQ;
	}
      else if (code == UNLE)
	{
	  code = GT;
	  jump_code = EQ;
	}
      else
	jump_code = NE;

      if (is_fp_libfunc)
	{
	  rtx_insn *insns;
	  rtx libfunc;
	  switch (code)
	    {
	    case EQ:
	      libfunc = op_mode == DFmode ? eqdf_libfunc : eqsf_libfunc;
	      break;
	    case NE:
	      libfunc = op_mode == DFmode ? nedf_libfunc : nesf_libfunc;
	      break;
	    case GT:
	      libfunc = op_mode == DFmode ? gtdf_libfunc : gtsf_libfunc;
	      break;
	    case GE:
	      libfunc = op_mode == DFmode ? gedf_libfunc : gesf_libfunc;
	      break;
	    case LT:
	      libfunc = op_mode == DFmode ? ltdf_libfunc : ltsf_libfunc;
	      break;
	    case LE:
	      libfunc = op_mode == DFmode ? ledf_libfunc : lesf_libfunc;
	      break;
	    default:
	      gcc_unreachable ();
	    }
	  start_sequence ();

	  cmp = emit_library_call_value (libfunc, 0, LCT_CONST, SImode,
					 op0, op_mode, op1, op_mode);
	  insns = get_insns ();
	  end_sequence ();

	  emit_libcall_block (insns, cmp, cmp,
			      gen_rtx_fmt_ee (code, SImode, op0, op1));
	}
      else
	{
	  cmp = gen_reg_rtx (SImode);
	  if (c6x_force_op_for_comparison_p (code, op1))
	    op1 = force_reg (SImode, op1);
	  emit_insn (gen_rtx_SET (cmp, gen_rtx_fmt_ee (code, SImode,
						       op0, op1)));
	}
    }

  return gen_rtx_fmt_ee (jump_code, mode, cmp, const0_rtx);
}

/* Return one word of double-word value OP.  HIGH_P is true to select the
   high part, false to select the low part.  When encountering auto-increment
   addressing, we make the assumption that the low part is going to be accessed
   first.  */

rtx
c6x_subword (rtx op, bool high_p)
{
  unsigned int byte;
  machine_mode mode;

  mode = GET_MODE (op);
  if (mode == VOIDmode)
    mode = DImode;

  if (TARGET_BIG_ENDIAN ? !high_p : high_p)
    byte = UNITS_PER_WORD;
  else
    byte = 0;

  if (MEM_P (op))
    {
      rtx addr = XEXP (op, 0);
      if (GET_CODE (addr) == PLUS || REG_P (addr))
	return adjust_address (op, word_mode, byte);
      /* FIXME: should really support autoincrement addressing for
	 multi-word modes.  */
      gcc_unreachable ();
    }

  return simplify_gen_subreg (word_mode, op, mode, byte);
}

/* Split one or more DImode RTL references into pairs of SImode
   references.  The RTL can be REG, offsettable MEM, integer constant, or
   CONST_DOUBLE.  "operands" is a pointer to an array of DImode RTL to
   split and "num" is its length.  lo_half and hi_half are output arrays
   that parallel "operands".  */

void
split_di (rtx operands[], int num, rtx lo_half[], rtx hi_half[])
{
  while (num--)
    {
      rtx op = operands[num];

      lo_half[num] = c6x_subword (op, false);
      hi_half[num] = c6x_subword (op, true);
    }
}

/* Return true if VAL is a mask valid for a clr instruction.  */
bool
c6x_valid_mask_p (HOST_WIDE_INT val)
{
  int i;
  for (i = 0; i < 32; i++)
    if (!(val & ((unsigned HOST_WIDE_INT)1 << i)))
      break;
  for (; i < 32; i++)
    if (val & ((unsigned HOST_WIDE_INT)1 << i))
      break;
  for (; i < 32; i++)
    if (!(val & ((unsigned HOST_WIDE_INT)1 << i)))
      return false;
  return true;
}

/* Expand a block move for a cpymemM pattern.  */

bool
c6x_expand_cpymem (rtx dst, rtx src, rtx count_exp, rtx align_exp,
		   rtx expected_align_exp ATTRIBUTE_UNUSED,
		   rtx expected_size_exp ATTRIBUTE_UNUSED)
{
  unsigned HOST_WIDE_INT align = 1;
  unsigned HOST_WIDE_INT src_mem_align, dst_mem_align, min_mem_align;
  unsigned HOST_WIDE_INT count = 0, offset = 0;
  unsigned int biggest_move = TARGET_STDW ? 8 : 4;

  if (CONST_INT_P (align_exp))
    align = INTVAL (align_exp);

  src_mem_align = MEM_ALIGN (src) / BITS_PER_UNIT;
  dst_mem_align = MEM_ALIGN (dst) / BITS_PER_UNIT;
  min_mem_align = MIN (src_mem_align, dst_mem_align);

  if (min_mem_align > align)
    align = min_mem_align / BITS_PER_UNIT;
  if (src_mem_align < align)
    src_mem_align = align;
  if (dst_mem_align < align)
    dst_mem_align = align;

  if (CONST_INT_P (count_exp))
    count = INTVAL (count_exp);
  else
    return false;

  /* Make sure we don't need to care about overflow later on.  */
  if (count > ((unsigned HOST_WIDE_INT) 1 << 30))
    return false;

  if (count >= 28 && (count & 3) == 0 && align >= 4)
    {
      tree dst_expr = MEM_EXPR (dst);
      tree src_expr = MEM_EXPR (src);
      rtx fn = TARGET_INSNS_64PLUS ? strasgi64p_libfunc : strasgi_libfunc;
      rtx srcreg = force_reg (Pmode, XEXP (src, 0));
      rtx dstreg = force_reg (Pmode, XEXP (dst, 0));

      if (src_expr)
	mark_addressable (src_expr);
      if (dst_expr)
	mark_addressable (dst_expr);
      emit_library_call (fn, LCT_NORMAL, VOIDmode,
			 dstreg, Pmode, srcreg, Pmode, count_exp, SImode);
      return true;
    }

  if (biggest_move > align && !TARGET_INSNS_64)
    biggest_move = align;

  if (count / biggest_move > 7)
    return false;

  while (count > 0)
    {
      rtx reg, reg_lowpart;
      machine_mode srcmode, dstmode;
      unsigned HOST_WIDE_INT src_size, dst_size, src_left;
      int shift;
      rtx srcmem, dstmem;

      while (biggest_move > count)
	biggest_move /= 2;

      src_size = dst_size = biggest_move;
      if (src_size > src_mem_align && src_size == 2)
	src_size = 1;
      if (dst_size > dst_mem_align && dst_size == 2)
	dst_size = 1;

      if (dst_size > src_size)
	dst_size = src_size;

      srcmode = int_mode_for_size (src_size * BITS_PER_UNIT, 0).require ();
      dstmode = int_mode_for_size (dst_size * BITS_PER_UNIT, 0).require ();
      if (src_size >= 4)
	reg_lowpart = reg = gen_reg_rtx (srcmode);
      else
	{
	  reg = gen_reg_rtx (SImode);
	  reg_lowpart = gen_lowpart (srcmode, reg);
	}

      srcmem = adjust_address (copy_rtx (src), srcmode, offset);

      if (src_size > src_mem_align)
	{
	  enum insn_code icode = (srcmode == SImode ? CODE_FOR_movmisalignsi
				  : CODE_FOR_movmisaligndi);
	  emit_insn (GEN_FCN (icode) (reg_lowpart, srcmem));
	}
      else
	emit_move_insn (reg_lowpart, srcmem);

      src_left = src_size;
      shift = TARGET_BIG_ENDIAN ? (src_size - dst_size) * BITS_PER_UNIT  : 0;
      while (src_left > 0)
	{
	  rtx dstreg = reg_lowpart;

	  if (src_size > dst_size)
	    {
	      rtx srcword = reg;
	      int shift_amount = shift & (BITS_PER_WORD - 1);
	      if (src_size > 4)
		srcword = operand_subword_force (srcword, src_left >= 4 ? 0 : 4,
						 SImode);
	      if (shift_amount > 0)
		{
		  dstreg = gen_reg_rtx (SImode);
		  emit_insn (gen_lshrsi3 (dstreg, srcword,
					  GEN_INT (shift_amount)));
		}
	      else
		dstreg = srcword;
	      dstreg = gen_lowpart (dstmode, dstreg);
	    }

	  dstmem = adjust_address (copy_rtx (dst), dstmode, offset);
	  if (dst_size > dst_mem_align)
	    {
	      enum insn_code icode = (dstmode == SImode ? CODE_FOR_movmisalignsi
				      : CODE_FOR_movmisaligndi);
	      emit_insn (GEN_FCN (icode) (dstmem, dstreg));
	    }
	  else
	    emit_move_insn (dstmem, dstreg);

	  if (TARGET_BIG_ENDIAN)
	    shift -= dst_size * BITS_PER_UNIT;
	  else
	    shift += dst_size * BITS_PER_UNIT;
	  offset += dst_size;
	  src_left -= dst_size;
	}
      count -= src_size;
    }
  return true;
}

/* Subroutine of print_address_operand, print a single address offset OFF for
   a memory access of mode MEM_MODE, choosing between normal form and scaled
   form depending on the type of the insn.  Misaligned memory references must
   use the scaled form.  */

static void
print_address_offset (FILE *file, rtx off, machine_mode mem_mode)
{
  rtx pat;

  if (c6x_current_insn != NULL_RTX)
    {
      pat = PATTERN (c6x_current_insn);
      if (GET_CODE (pat) == COND_EXEC)
	pat = COND_EXEC_CODE (pat);
      if (GET_CODE (pat) == PARALLEL)
	pat = XVECEXP (pat, 0, 0);

      if (GET_CODE (pat) == SET
	  && GET_CODE (SET_SRC (pat)) == UNSPEC
	  && XINT (SET_SRC (pat), 1) == UNSPEC_MISALIGNED_ACCESS)
	{
	  gcc_assert (CONST_INT_P (off)
		      && (INTVAL (off) & (GET_MODE_SIZE (mem_mode) - 1)) == 0);
	  fprintf (file, "[" HOST_WIDE_INT_PRINT_DEC "]",
		   INTVAL (off) / GET_MODE_SIZE (mem_mode));
	  return;
	}
    }
  fputs ("(", file);
  output_address (mem_mode, off);
  fputs (")", file);
}

static bool
c6x_print_operand_punct_valid_p (unsigned char c)
{
  return c == '$' || c == '.' || c == '|';
}

static void c6x_print_operand (FILE *, rtx, int);

/* Subroutine of c6x_print_operand; used to print a memory reference X to FILE.  */

static void
c6x_print_address_operand (FILE *file, rtx x, machine_mode mem_mode)
{
  rtx off;
  switch (GET_CODE (x))
    {
    case PRE_MODIFY:
    case POST_MODIFY:
      if (GET_CODE (x) == POST_MODIFY)
	output_address (mem_mode, XEXP (x, 0));
      off = XEXP (XEXP (x, 1), 1);
      if (XEXP (x, 0) == stack_pointer_rtx)
	{
	  if (GET_CODE (x) == PRE_MODIFY)
	    gcc_assert (INTVAL (off) > 0);
	  else
	    gcc_assert (INTVAL (off) < 0);
	}
      if (CONST_INT_P (off) && INTVAL (off) < 0)
	{
	  fprintf (file, "--");
	  off = GEN_INT (-INTVAL (off));
	}
      else
	fprintf (file, "++");
      if (GET_CODE (x) == PRE_MODIFY)
	output_address (mem_mode, XEXP (x, 0));
      print_address_offset (file, off, mem_mode);
      break;

    case PLUS:
      off = XEXP (x, 1);
      if (CONST_INT_P (off) && INTVAL (off) < 0)
	{
	  fprintf (file, "-");
	  off = GEN_INT (-INTVAL (off));
	}
      else
	fprintf (file, "+");
      output_address (mem_mode, XEXP (x, 0));
      print_address_offset (file, off, mem_mode);
      break;

    case PRE_DEC:
      gcc_assert (XEXP (x, 0) != stack_pointer_rtx);
      fprintf (file, "--");
      output_address (mem_mode, XEXP (x, 0));
      fprintf (file, "[1]");
      break;
    case PRE_INC:
      fprintf (file, "++");
      output_address (mem_mode, XEXP (x, 0));
      fprintf (file, "[1]");
      break;
    case POST_INC:
      gcc_assert (XEXP (x, 0) != stack_pointer_rtx);
      output_address (mem_mode, XEXP (x, 0));
      fprintf (file, "++[1]");
      break;
    case POST_DEC:
      output_address (mem_mode, XEXP (x, 0));
      fprintf (file, "--[1]");
      break;

    case SYMBOL_REF:
    case CONST:
    case LABEL_REF:
      gcc_assert (sdata_symbolic_operand (x, Pmode));
      fprintf (file, "+B14(");
      output_addr_const (file, x);
      fprintf (file, ")");
      break;

    case UNSPEC:
      switch (XINT (x, 1))
	{
	case UNSPEC_LOAD_GOT:
	  fputs ("$GOT(", file);
	  output_addr_const (file, XVECEXP (x, 0, 0));
	  fputs (")", file);
	  break;
	case UNSPEC_LOAD_SDATA:
	  output_addr_const (file, XVECEXP (x, 0, 0));
	  break;
	default:
	  gcc_unreachable ();
	}
      break;

    default:
      gcc_assert (GET_CODE (x) != MEM);
      c6x_print_operand (file, x, 0);
      break;
    }
}

/* Return a single character, which is either 'l', 's', 'd' or 'm', which
   specifies the functional unit used by INSN.  */

char
c6x_get_unit_specifier (rtx_insn *insn)
{
  enum attr_units units;

  if (insn_info.exists ())
    {
      int unit = INSN_INFO_ENTRY (INSN_UID (insn)).reservation;
      return c6x_unit_names[unit][0];
    }

  units = get_attr_units (insn);
  switch (units)
    {
    case UNITS_D:
    case UNITS_DL:
    case UNITS_DS:
    case UNITS_DLS:
    case UNITS_D_ADDR:
      return 'd';
    case UNITS_L:
    case UNITS_LS:
      return 'l';
    case UNITS_S:
      return 's';
    case UNITS_M:
      return 'm';
    default:
      gcc_unreachable ();
    }
}

/* Prints the unit specifier field.  */
static void
c6x_print_unit_specifier_field (FILE *file, rtx_insn *insn)
{
  enum attr_units units = get_attr_units (insn);
  enum attr_cross cross = get_attr_cross (insn);
  enum attr_dest_regfile rf = get_attr_dest_regfile (insn);
  int half;
  char unitspec;

  if (units == UNITS_D_ADDR)
    {
      enum attr_addr_regfile arf = get_attr_addr_regfile (insn);
      int t_half;
      gcc_assert (arf != ADDR_REGFILE_UNKNOWN);
      half = arf == ADDR_REGFILE_A ? 1 : 2;
      t_half = rf == DEST_REGFILE_A ? 1 : 2;
      fprintf (file, ".d%dt%d", half, t_half);
      return;
    }

  if (insn_info.exists ())
    {
      int unit = INSN_INFO_ENTRY (INSN_UID (insn)).reservation;
      fputs (".", file);
      fputs (c6x_unit_names[unit], file);
      if (cross == CROSS_Y)
	fputs ("x", file);
      return;
    }

  gcc_assert (rf != DEST_REGFILE_UNKNOWN);
  unitspec = c6x_get_unit_specifier (insn);
  half = rf == DEST_REGFILE_A ? 1 : 2;
  fprintf (file, ".%c%d%s", unitspec, half, cross == CROSS_Y ? "x" : "");
}

/* Output assembly language output for the address ADDR to FILE.  */
static void
c6x_print_operand_address (FILE *file, machine_mode mode, rtx addr)
{
  c6x_print_address_operand (file, addr, mode);
}

/* Print an operand, X, to FILE, with an optional modifier in CODE.

   Meaning of CODE:
   $ -- print the unit specifier field for the instruction.
   . -- print the predicate for the instruction or an emptry string for an
        unconditional one.
   | -- print "||" if the insn should be issued in parallel with the previous
        one.

   C -- print an opcode suffix for a reversed condition
   d -- H, W or D as a suffix for ADDA, based on the factor given by the
        operand
   D -- print either B, H, W or D as a suffix for ADDA, based on the size of
        the operand
   J -- print a predicate
   j -- like J, but use reverse predicate
   k -- treat a CONST_INT as a register number and print it as a register
   k -- like k, but print out a doubleword register
   n -- print an integer operand, negated
   p -- print the low part of a DImode register
   P -- print the high part of a DImode register
   r -- print the absolute value of an integer operand, shifted right by 1
   R -- print the absolute value of an integer operand, shifted right by 2
   f -- the first clear bit in an integer operand assumed to be a mask for
        a clr instruction
   F -- the last clear bit in such a mask
   s -- the first set bit in an integer operand assumed to be a mask for
        a set instruction
   S -- the last set bit in such a mask
   U -- print either 1 or 2, depending on the side of the machine used by
        the operand  */

static void
c6x_print_operand (FILE *file, rtx x, int code)
{
  int i;
  HOST_WIDE_INT v;
  tree t;
  machine_mode mode;

  if (code == '|')
    {
      if (GET_MODE (c6x_current_insn) != TImode)
	fputs ("||", file);
      return;
    }
  if (code == '$')
    {
      c6x_print_unit_specifier_field (file, c6x_current_insn);
      return;
    }

  if (code == '.')
    {
      x = current_insn_predicate;
      if (x)
	{
	  unsigned int regno = REGNO (XEXP (x, 0));
	  fputs ("[", file);
 	  if (GET_CODE (x) == EQ)
	    fputs ("!", file);
	  fputs (reg_names [regno], file);
	  fputs ("]", file);
	}
      return;
    }

  mode = GET_MODE (x);

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

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

    case 'k':
      gcc_assert (GET_CODE (x) == CONST_INT);
      v = INTVAL (x);
      fprintf (file, "%s", reg_names[v]);
      return;
    case 'K':
      gcc_assert (GET_CODE (x) == CONST_INT);
      v = INTVAL (x);
      gcc_assert ((v & 1) == 0);
      fprintf (file, "%s:%s", reg_names[v + 1], reg_names[v]);
      return;

    case 's':
    case 'S':
    case 'f':
    case 'F':
      gcc_assert (GET_CODE (x) == CONST_INT);
      v = INTVAL (x);
      for (i = 0; i < 32; i++)
	{
	  HOST_WIDE_INT tst = v & 1;
	  if (((code == 'f' || code == 'F') && !tst)
	      || ((code == 's' || code == 'S') && tst))
	    break;
	  v >>= 1;
	}
      if (code == 'f' || code == 's')
	{
	  fprintf (file, "%d", i);
	  return;
	}
      for (;i < 32; i++)
	{
	  HOST_WIDE_INT tst = v & 1;
	  if ((code == 'F' && tst) || (code == 'S' && !tst))
	    break;
	  v >>= 1;
	}
      fprintf (file, "%d", i - 1);
      return;

    case 'n':
      gcc_assert (GET_CODE (x) == CONST_INT);
      output_addr_const (file, GEN_INT (-INTVAL (x)));
      return;

    case 'r':
      gcc_assert (GET_CODE (x) == CONST_INT);
      v = INTVAL (x);
      if (v < 0)
	v = -v;
      output_addr_const (file, GEN_INT (v >> 1));
      return;

    case 'R':
      gcc_assert (GET_CODE (x) == CONST_INT);
      v = INTVAL (x);
      if (v < 0)
	v = -v;
      output_addr_const (file, GEN_INT (v >> 2));
      return;

    case 'd':
      gcc_assert (GET_CODE (x) == CONST_INT);
      v = INTVAL (x);
      fputs (v == 2 ? "h" : v == 4 ? "w" : "d", file);
      return;

    case 'p':
    case 'P':
      gcc_assert (GET_CODE (x) == REG);
      v = REGNO (x);
      if (code == 'P')
	v++;
      fputs (reg_names[v], file);
      return;

    case 'D':
      v = 0;
      if (GET_CODE (x) == CONST)
	{
	  x = XEXP (x, 0);
	  gcc_assert (GET_CODE (x) == PLUS);
	  gcc_assert (GET_CODE (XEXP (x, 1)) == CONST_INT);
	  v = INTVAL (XEXP (x, 1));
	  x = XEXP (x, 0);

	}
      gcc_assert (GET_CODE (x) == SYMBOL_REF);

      t = SYMBOL_REF_DECL (x);
      if (DECL_P (t))
	v |= DECL_ALIGN_UNIT (t);
      else
	v |= TYPE_ALIGN_UNIT (TREE_TYPE (t));
      if (v & 1)
	fputs ("b", file);
      else if (v & 2)
	fputs ("h", file);
      else
	fputs ("w", file);
      return;

    case 'U':
      if (MEM_P (x))
	{
	  x = XEXP (x, 0);
	  if (GET_CODE (x) == PLUS
	      || GET_RTX_CLASS (GET_CODE (x)) == RTX_AUTOINC)
	    x = XEXP (x, 0);
	  if (GET_CODE (x) == CONST || GET_CODE (x) == SYMBOL_REF)
	    {
	      gcc_assert (sdata_symbolic_operand (x, Pmode));
	      fputs ("2", file);
	      return;
	    }
	}
      gcc_assert (REG_P (x));
      if (A_REGNO_P (REGNO (x)))
	fputs ("1", file);
      if (B_REGNO_P (REGNO (x)))
	fputs ("2", file);
      return;

    default:
      switch (GET_CODE (x))
	{
	case REG:
	  if (GET_MODE_SIZE (mode) == 8)
	    fprintf (file, "%s:%s", reg_names[REGNO (x) + 1],
		     reg_names[REGNO (x)]);
	  else
	    fprintf (file, "%s", reg_names[REGNO (x)]);
	  break;

	case MEM:
	  fputc ('*', file);
	  gcc_assert (XEXP (x, 0) != stack_pointer_rtx);
	  c6x_print_address_operand (file, XEXP (x, 0), GET_MODE (x));
	  break;

	case SYMBOL_REF:
	  fputc ('(', file);
	  output_addr_const (file, x);
	  fputc (')', file);
	  break;

	case CONST_INT:
	  output_addr_const (file, x);
	  break;

	case CONST_DOUBLE:
	  output_operand_lossage ("invalid const_double operand");
	  break;

	default:
	  output_addr_const (file, x);
	}
    }
}

/* Return TRUE if OP is a valid memory address with a base register of
   class C.  If SMALL_OFFSET is true, we disallow memory references which would
   require a long offset with B14/B15.  */

bool
c6x_mem_operand (rtx op, enum reg_class c, bool small_offset)
{
  machine_mode mode = GET_MODE (op);
  rtx base = XEXP (op, 0);
  switch (GET_CODE (base))
    {
    case REG:
      break;
    case PLUS:
      if (small_offset
	  && (XEXP (base, 0) == stack_pointer_rtx
	      || XEXP (base, 0) == pic_offset_table_rtx))
	{
	  if (!c6x_legitimate_address_p_1 (mode, base, true, true))
	    return false;
	}

      /* fall through */
    case PRE_INC:
    case PRE_DEC:
    case PRE_MODIFY:
    case POST_INC:
    case POST_DEC:
    case POST_MODIFY:
      base = XEXP (base, 0);
      break;

    case CONST:
    case LABEL_REF:
    case SYMBOL_REF:
      gcc_assert (sdata_symbolic_operand (base, Pmode));
      return !small_offset && c == B_REGS;

    default:
      return false;
    }
  return TEST_HARD_REG_BIT (reg_class_contents[ (int) (c)], REGNO (base));
}

/* Returns true if X is a valid address for use in a memory reference
   of mode MODE.  If STRICT is true, we do not allow pseudo registers
   in the address.  NO_LARGE_OFFSET is true if we are examining an
   address for use in a load or store misaligned instruction, or
   recursively examining an operand inside a PRE/POST_MODIFY.  */

bool
c6x_legitimate_address_p_1 (machine_mode mode, rtx x, bool strict,
			    bool no_large_offset)
{
  int size, size1;
  HOST_WIDE_INT off;
  enum rtx_code code = GET_CODE (x);

  switch (code)
    {
    case PRE_MODIFY:
    case POST_MODIFY:
      /* We can't split these into word-sized pieces yet.  */
      if (!TARGET_STDW && GET_MODE_SIZE (mode) > UNITS_PER_WORD)
	return false;
      if (GET_CODE (XEXP (x, 1)) != PLUS)
	return false;
      if (!c6x_legitimate_address_p_1 (mode, XEXP (x, 1), strict, true))
	return false;
      if (!rtx_equal_p (XEXP (x, 0), XEXP (XEXP (x, 1), 0)))
	return false;

      /* fall through */
    case PRE_INC:
    case PRE_DEC:
    case POST_INC:
    case POST_DEC:
      /* We can't split these into word-sized pieces yet.  */
      if (!TARGET_STDW && GET_MODE_SIZE (mode) > UNITS_PER_WORD)
	return false;
      x = XEXP (x, 0);
      if (!REG_P (x))
	return false;

      /* fall through */
    case REG:
      if (strict)
	return REGNO_OK_FOR_BASE_STRICT_P (REGNO (x));
      else
	return REGNO_OK_FOR_BASE_NONSTRICT_P (REGNO (x));

    case PLUS:
      if (!REG_P (XEXP (x, 0))
	  || !c6x_legitimate_address_p_1 (mode, XEXP (x, 0), strict, false))
	return false;
      /* We cannot ensure currently that both registers end up in the
	 same register file.  */
      if (REG_P (XEXP (x, 1)))
	return false;

      if (mode == BLKmode)
	size = 4;
      else if (mode == VOIDmode)
	/* ??? This can happen during ivopts.  */
	size = 1;
      else
	size = GET_MODE_SIZE (mode);

      if (flag_pic
	  && GET_CODE (XEXP (x, 1)) == UNSPEC
	  && XINT (XEXP (x, 1), 1) == UNSPEC_LOAD_SDATA
	  && XEXP (x, 0) == pic_offset_table_rtx
	  && sdata_symbolic_operand (XVECEXP (XEXP (x, 1), 0, 0), SImode))
	return !no_large_offset && size <= 4;
      if (flag_pic == 1
	  && mode == Pmode
	  && GET_CODE (XEXP (x, 1)) == UNSPEC
	  && XINT (XEXP (x, 1), 1) == UNSPEC_LOAD_GOT
	  && XEXP (x, 0) == pic_offset_table_rtx
	  && (GET_CODE (XVECEXP (XEXP (x, 1), 0, 0)) == SYMBOL_REF
	      || GET_CODE (XVECEXP (XEXP (x, 1), 0, 0)) == LABEL_REF))
	return !no_large_offset;
      if (GET_CODE (XEXP (x, 1)) != CONST_INT)
	return false;

      off = INTVAL (XEXP (x, 1));

      /* If the machine does not have doubleword load/stores, we'll use
	 word size accesses.  */
      size1 = size;
      if (size == 2 * UNITS_PER_WORD && !TARGET_STDW)
	size = UNITS_PER_WORD;

      if (((HOST_WIDE_INT)size1 - 1) & off)
	return false;
      off /= size;
      if (off > -32 && off < (size1 == size ? 32 : 28))
	return true;
      if (no_large_offset || code != PLUS || XEXP (x, 0) != stack_pointer_rtx
	  || size1 > UNITS_PER_WORD)
	return false;
      return off >= 0 && off < 32768;

    case CONST:
    case SYMBOL_REF:
    case LABEL_REF:
      return (!no_large_offset
	      /* With -fpic, we must wrap it in an unspec to show the B14
		 dependency.  */
	      && !flag_pic
	      && GET_MODE_SIZE (mode) <= UNITS_PER_WORD
	      && sdata_symbolic_operand (x, Pmode));

    default:
      return false;
    }
}

static bool
c6x_legitimate_address_p (machine_mode mode, rtx x, bool strict)
{
  return c6x_legitimate_address_p_1 (mode, x, strict, false);
}

static bool
c6x_legitimate_constant_p (machine_mode mode ATTRIBUTE_UNUSED,
			   rtx x ATTRIBUTE_UNUSED)
{
  return true;
}

/* Implements TARGET_PREFERRED_RENAME_CLASS.  */
static reg_class_t
c6x_preferred_rename_class (reg_class_t cl)
{
  if (cl == A_REGS)
    return NONPREDICATE_A_REGS;
  if (cl == B_REGS)
    return NONPREDICATE_B_REGS;
  if (cl == ALL_REGS || cl == GENERAL_REGS)
    return NONPREDICATE_REGS;
  return NO_REGS;
}

/* Implements FINAL_PRESCAN_INSN.  */
void
c6x_final_prescan_insn (rtx_insn *insn, rtx *opvec ATTRIBUTE_UNUSED,
			int noperands ATTRIBUTE_UNUSED)
{
  c6x_current_insn = insn;
}

/* A structure to describe the stack layout of a function.  The layout is
   as follows:

   [saved frame pointer (or possibly padding0)]
   --> incoming stack pointer, new hard frame pointer
   [saved call-used regs]
   [optional padding1]
   --> soft frame pointer
   [frame]
   [outgoing arguments]
   [optional padding2]

  The structure members are laid out in this order.  */

struct c6x_frame
{
  int padding0;
  /* Number of registers to save.  */
  int nregs;
  int padding1;
  HOST_WIDE_INT frame;
  int outgoing_arguments_size;
  int padding2;

  HOST_WIDE_INT to_allocate;
  /* The offsets relative to the incoming stack pointer (which
     becomes HARD_FRAME_POINTER).  */
  HOST_WIDE_INT frame_pointer_offset;
  HOST_WIDE_INT b3_offset;

  /* True if we should call push_rts/pop_rts to save and restore
     registers.  */
  bool push_rts;
};

/* Return true if we need to save and modify the PIC register in the
   prologue.  */

static bool
must_reload_pic_reg_p (void)
{
  if (!TARGET_DSBT)
    return false;

  cgraph_node *local_info_node
    = cgraph_node::local_info_node (current_function_decl);
  if ((crtl->uses_pic_offset_table || !crtl->is_leaf)
      && !local_info_node->local)
    return true;
  return false;
}

/* Return 1 if we need to save REGNO.  */
static int
c6x_save_reg (unsigned int regno)
{
  return ((df_regs_ever_live_p (regno)
	   && !call_used_or_fixed_reg_p (regno))
	  || (regno == RETURN_ADDR_REGNO
	      && (df_regs_ever_live_p (regno)
		  || !crtl->is_leaf))
	  || (regno == PIC_OFFSET_TABLE_REGNUM && must_reload_pic_reg_p ()));
}

/* Examine the number of regs NREGS we've determined we must save.
   Return true if we should use __c6xabi_push_rts/__c6xabi_pop_rts for
   prologue and epilogue.  */

static bool
use_push_rts_p (int nregs)
{
  if (TARGET_INSNS_64PLUS && optimize_function_for_size_p (cfun)
      && !cfun->machine->contains_sibcall
      && !cfun->returns_struct
      && !TARGET_LONG_CALLS
      && nregs >= 6 && !frame_pointer_needed)
    return true;
  return false;
}

/* Return number of saved general prupose registers.  */

int
c6x_nsaved_regs (void)
{
  int nregs = 0;
  int regno;

  for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
    if (c6x_save_reg (regno))
      nregs++;
  return nregs;
}

/* The safe debug order mandated by the ABI.  */
static unsigned reg_save_order[] =
{
  REG_A10, REG_A11, REG_A12, REG_A13,
  REG_A14, REG_B3,
  REG_B10, REG_B11, REG_B12, REG_B13,
  REG_B14, REG_A15
};

#define N_SAVE_ORDER (sizeof reg_save_order / sizeof *reg_save_order)

/* Compute the layout of the stack frame and store it in FRAME.  */

static void
c6x_compute_frame_layout (struct c6x_frame *frame)
{
  HOST_WIDE_INT size = get_frame_size ();
  HOST_WIDE_INT offset;
  int nregs;

  /* We use the four bytes which are technically inside the caller's frame,
     usually to save the frame pointer.  */
  offset = -4;
  frame->padding0 = 0;
  nregs = c6x_nsaved_regs ();
  frame->push_rts = false;
  frame->b3_offset = 0;
  if (use_push_rts_p (nregs))
    {
      frame->push_rts = true;
      frame->b3_offset = (TARGET_BIG_ENDIAN ? -12 : -13) * 4;
      nregs = 14;
    }
  else if (c6x_save_reg (REG_B3))
    {
      int idx;
      for (idx = N_SAVE_ORDER - 1; reg_save_order[idx] != REG_B3; idx--)
	{
	  if (c6x_save_reg (reg_save_order[idx]))
	    frame->b3_offset -= 4;
	}
    }
  frame->nregs = nregs;

  if (size == 0 && nregs == 0)
    {
      frame->padding0 = 4;
      frame->padding1 = frame->padding2 = 0;
      frame->frame_pointer_offset = frame->to_allocate = 0;
      frame->outgoing_arguments_size = 0;
      return;
    }

  if (!frame->push_rts)
    offset += frame->nregs * 4;

  if (offset == 0 && size == 0 && crtl->outgoing_args_size == 0
      && !crtl->is_leaf)
    /* Don't use the bottom of the caller's frame if we have no
       allocation of our own and call other functions.  */
    frame->padding0 = frame->padding1 = 4;
  else if (offset & 4)
    frame->padding1 = 4;
  else
    frame->padding1 = 0;

  offset += frame->padding0 + frame->padding1;
  frame->frame_pointer_offset = offset;
  offset += size;

  frame->outgoing_arguments_size = crtl->outgoing_args_size;
  offset += frame->outgoing_arguments_size;

  if ((offset & 4) == 0)
    frame->padding2 = 8;
  else
    frame->padding2 = 4;
  frame->to_allocate = offset + frame->padding2;
}

/* Return the offset between two registers, one to be eliminated, and the other
   its replacement, at the start of a routine.  */

HOST_WIDE_INT
c6x_initial_elimination_offset (int from, int to)
{
  struct c6x_frame frame;
  c6x_compute_frame_layout (&frame);

  if (from == ARG_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
    return 0;
  else if (from == FRAME_POINTER_REGNUM
	   && to == HARD_FRAME_POINTER_REGNUM)
    return -frame.frame_pointer_offset;
  else
    {
      gcc_assert (to == STACK_POINTER_REGNUM);

      if (from == ARG_POINTER_REGNUM)
	return frame.to_allocate + (frame.push_rts ? 56 : 0);

      gcc_assert (from == FRAME_POINTER_REGNUM);
      return frame.to_allocate - frame.frame_pointer_offset;
    }
}

/* Given FROM and TO register numbers, say whether this elimination is
   allowed.  Frame pointer elimination is automatically handled.  */

static bool
c6x_can_eliminate (const int from ATTRIBUTE_UNUSED, const int to)
{
  if (to == STACK_POINTER_REGNUM)
    return !frame_pointer_needed;
  return true;
}

/* Emit insns to increment the stack pointer by OFFSET.  If
   FRAME_RELATED_P, set the RTX_FRAME_RELATED_P flag on the insns.
   Does nothing if the offset is zero.  */

static void
emit_add_sp_const (HOST_WIDE_INT offset, bool frame_related_p)
{
  rtx to_add = GEN_INT (offset);
  rtx orig_to_add = to_add;
  rtx_insn *insn;

  if (offset == 0)
    return;

  if (offset < -32768 || offset > 32767)
    {
      rtx reg = gen_rtx_REG (SImode, REG_A0);
      rtx low = GEN_INT (trunc_int_for_mode (offset, HImode));

      insn = emit_insn (gen_movsi_high (reg, low));
      if (frame_related_p)
	RTX_FRAME_RELATED_P (insn) = 1;
      insn = emit_insn (gen_movsi_lo_sum (reg, reg, to_add));
      if (frame_related_p)
	RTX_FRAME_RELATED_P (insn) = 1;
      to_add = reg;
    }
  insn = emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
				to_add));
  if (frame_related_p)
    {
      if (REG_P (to_add))
	add_reg_note (insn, REG_FRAME_RELATED_EXPR,
		      gen_rtx_SET (stack_pointer_rtx,
				   gen_rtx_PLUS (Pmode, stack_pointer_rtx,
						 orig_to_add)));

      RTX_FRAME_RELATED_P (insn) = 1;
    }
}

/* Prologue and epilogue.  */
void
c6x_expand_prologue (void)
{
  struct c6x_frame frame;
  rtx_insn *insn;
  rtx mem;
  int nsaved = 0;
  HOST_WIDE_INT initial_offset, off, added_already;

  c6x_compute_frame_layout (&frame);

  if (flag_stack_usage_info)
    current_function_static_stack_size = frame.to_allocate;

  initial_offset = -frame.to_allocate;
  if (frame.push_rts)
    {
      emit_insn (gen_push_rts ());
      nsaved = frame.nregs;
    }

  /* If the offsets would be too large for the memory references we will
     create to save registers, do the stack allocation in two parts.
     Ensure by subtracting 8 that we don't store to the word pointed to
     by the stack pointer.  */
  if (initial_offset < -32768)
    initial_offset = -frame.frame_pointer_offset - 8;

  if (frame.to_allocate > 0)
    gcc_assert (initial_offset != 0);

  off = -initial_offset + 4 - frame.padding0;

  mem = gen_frame_mem (Pmode, stack_pointer_rtx);

  added_already = 0;
  if (frame_pointer_needed)
    {
      rtx fp_reg = gen_rtx_REG (SImode, REG_A15);
      /* We go through some contortions here to both follow the ABI's
	 recommendation that FP == incoming SP, and to avoid writing or
	 reading the word pointed to by the stack pointer.  */
      rtx addr = gen_rtx_POST_MODIFY (Pmode, stack_pointer_rtx,
				      gen_rtx_PLUS (Pmode, stack_pointer_rtx,
						    GEN_INT (-8)));
      insn = emit_move_insn (gen_frame_mem (Pmode, addr), fp_reg);
      RTX_FRAME_RELATED_P (insn) = 1;
      nsaved++;
      insn = emit_insn (gen_addsi3 (hard_frame_pointer_rtx, stack_pointer_rtx,
				    GEN_INT (8)));
      RTX_FRAME_RELATED_P (insn) = 1;
      off -= 4;
      added_already = -8;
    }

  emit_add_sp_const (initial_offset - added_already, true);

  if (nsaved < frame.nregs)
    {
      unsigned i;

      for (i = 0; i < N_SAVE_ORDER; i++)
	{
	  int idx = N_SAVE_ORDER - i - 1;
	  unsigned regno = reg_save_order[idx];
	  rtx reg;
	  machine_mode save_mode = SImode;

	  if (regno == REG_A15 && frame_pointer_needed)
	    /* Already saved.  */
	    continue;
	  if (!c6x_save_reg (regno))
	    continue;

	  if (TARGET_STDW && (off & 4) == 0 && off <= 256
	      && (regno & 1) == 1
	      && i + 1 < N_SAVE_ORDER
	      && reg_save_order[idx - 1] == regno - 1
	      && c6x_save_reg (regno - 1))
	    {
	      save_mode = DImode;
	      regno--;
	      i++;
	    }
	  reg = gen_rtx_REG (save_mode, regno);
	  off -= GET_MODE_SIZE (save_mode);

	  insn = emit_move_insn (adjust_address (mem, save_mode, off),
				 reg);
	  RTX_FRAME_RELATED_P (insn) = 1;

	  nsaved += hard_regno_nregs (regno, save_mode);
	}
    }
  gcc_assert (nsaved == frame.nregs);
  emit_add_sp_const (-frame.to_allocate - initial_offset, true);
  if (must_reload_pic_reg_p ())
    {
      if (dsbt_decl == NULL)
	{
	  tree t;

	  t = build_index_type (integer_one_node);
	  t = build_array_type (integer_type_node, t);
	  t = build_decl (BUILTINS_LOCATION, VAR_DECL,
			  get_identifier ("__c6xabi_DSBT_BASE"), t);
	  DECL_ARTIFICIAL (t) = 1;
	  DECL_IGNORED_P (t) = 1;
	  DECL_EXTERNAL (t) = 1;
	  TREE_STATIC (t) = 1;
	  TREE_PUBLIC (t) = 1;
	  TREE_USED (t) = 1;

	  dsbt_decl = t;
	}
      emit_insn (gen_setup_dsbt (pic_offset_table_rtx,
				 XEXP (DECL_RTL (dsbt_decl), 0)));
    }
}

void
c6x_expand_epilogue (bool sibcall)
{
  unsigned i;
  struct c6x_frame frame;
  rtx mem;
  HOST_WIDE_INT off;
  int nsaved = 0;

  c6x_compute_frame_layout (&frame);

  mem = gen_frame_mem (Pmode, stack_pointer_rtx);

  /* Insert a dummy set/use of the stack pointer.  This creates a
     scheduler barrier between the prologue saves and epilogue restores. */
  emit_insn (gen_epilogue_barrier (stack_pointer_rtx, stack_pointer_rtx));

  /* If the offsets would be too large for the memory references we will
     create to restore registers, do a preliminary stack adjustment here.  */
  off = frame.to_allocate - frame.frame_pointer_offset + frame.padding1;
  if (frame.push_rts)
    {
      nsaved = frame.nregs;
    }
  else
    {
      if (frame.to_allocate > 32768)
	{
	  /* Don't add the entire offset so that we leave an unused word
	     above the stack pointer.  */
	  emit_add_sp_const ((off - 16) & ~7, false);
	  off &= 7;
	  off += 16;
	}
      for (i = 0; i < N_SAVE_ORDER; i++)
	{
	  unsigned regno = reg_save_order[i];
	  rtx reg;
	  machine_mode save_mode = SImode;

	  if (!c6x_save_reg (regno))
	    continue;
	  if (regno == REG_A15 && frame_pointer_needed)
	    continue;

	  if (TARGET_STDW && (off & 4) == 0 && off < 256
	      && (regno & 1) == 0
	      && i + 1 < N_SAVE_ORDER
	      && reg_save_order[i + 1] == regno + 1
	      && c6x_save_reg (regno + 1))
	    {
	      save_mode = DImode;
	      i++;
	    }
	  reg = gen_rtx_REG (save_mode, regno);

	  emit_move_insn (reg, adjust_address (mem, save_mode, off));

	  off += GET_MODE_SIZE (save_mode);
	  nsaved += hard_regno_nregs (regno, save_mode);
	}
    }
  if (!frame_pointer_needed)
    emit_add_sp_const (off + frame.padding0 - 4, false);
  else
    {
      rtx fp_reg = gen_rtx_REG (SImode, REG_A15);
      rtx addr = gen_rtx_PRE_MODIFY (Pmode, stack_pointer_rtx,
				      gen_rtx_PLUS (Pmode, stack_pointer_rtx,
						    GEN_INT (8)));
      emit_insn (gen_addsi3 (stack_pointer_rtx, hard_frame_pointer_rtx,
			     GEN_INT (-8)));
      emit_move_insn (fp_reg, gen_frame_mem (Pmode, addr));
      nsaved++;
    }
  gcc_assert (nsaved == frame.nregs);
  if (!sibcall)
    {
      if (frame.push_rts)
	emit_jump_insn (gen_pop_rts ());
      else
	emit_jump_insn (gen_return_internal (gen_rtx_REG (SImode,
							  RETURN_ADDR_REGNO)));
    }
}

/* Return the value of the return address for the frame COUNT steps up
   from the current frame, after the prologue.
   We punt for everything but the current frame by returning const0_rtx.  */

rtx
c6x_return_addr_rtx (int count)
{
  if (count != 0)
    return const0_rtx;

  return get_hard_reg_initial_val (Pmode, RETURN_ADDR_REGNO);
}

/* Return true iff TYPE is one of the shadow types.  */
static bool
shadow_type_p (enum attr_type type)
{
  return (type == TYPE_SHADOW || type == TYPE_LOAD_SHADOW
	  || type == TYPE_MULT_SHADOW);
}

/* Return true iff INSN is a shadow pattern.  */
static bool
shadow_p (rtx_insn *insn)
{
  if (!NONDEBUG_INSN_P (insn) || recog_memoized (insn) < 0)
    return false;
  return shadow_type_p (get_attr_type (insn));
}

/* Return true iff INSN is a shadow or blockage pattern.  */
static bool
shadow_or_blockage_p (rtx_insn *insn)
{
  enum attr_type type;
  if (!NONDEBUG_INSN_P (insn) || recog_memoized (insn) < 0)
    return false;
  type = get_attr_type (insn);
  return shadow_type_p (type) || type == TYPE_BLOCKAGE;
}

/* Translate UNITS into a bitmask of units we can reserve for this
   insn.  */
static int
get_reservation_flags (enum attr_units units)
{
  switch (units)
    {
    case UNITS_D:
    case UNITS_D_ADDR:
      return RESERVATION_FLAG_D;
    case UNITS_L:
      return RESERVATION_FLAG_L;
    case UNITS_S:
      return RESERVATION_FLAG_S;
    case UNITS_M:
      return RESERVATION_FLAG_M;
    case UNITS_LS:
      return RESERVATION_FLAG_LS;
    case UNITS_DL:
      return RESERVATION_FLAG_DL;
    case UNITS_DS:
      return RESERVATION_FLAG_DS;
    case UNITS_DLS:
      return RESERVATION_FLAG_DLS;
    default:
      return 0;
    }
}

/* Compute the side of the machine used by INSN, which reserves UNITS.
   This must match the reservations in the scheduling description.  */
static int
get_insn_side (rtx_insn *insn, enum attr_units units)
{
  if (units == UNITS_D_ADDR)
    return (get_attr_addr_regfile (insn) == ADDR_REGFILE_A ? 0 : 1);
  else
    {
      enum attr_dest_regfile rf = get_attr_dest_regfile (insn);
      if (rf == DEST_REGFILE_ANY)
	return get_attr_type (insn) == TYPE_BRANCH ? 0 : 1;
      else
	return rf == DEST_REGFILE_A ? 0 : 1;
    }
}

/* After scheduling, walk the insns between HEAD and END and assign unit
   reservations.  */
static void
assign_reservations (rtx_insn *head, rtx_insn *end)
{
  rtx_insn *insn;
  for (insn = head; insn != NEXT_INSN (end); insn = NEXT_INSN (insn))
    {
      unsigned int sched_mask, reserved;
      rtx_insn *within, *last;
      int pass;
      int rsrv[2];
      int rsrv_count[2][4];
      int i;

      if (GET_MODE (insn) != TImode)
	continue;

      reserved = 0;
      last = NULL;
      /* Find the last insn in the packet.  It has a state recorded for it,
	 which we can use to determine the units we should be using.  */
      for (within = insn;
	   (within != NEXT_INSN (end)
	    && (within == insn || GET_MODE (within) != TImode));
	   within = NEXT_INSN (within))
	{
	  int icode;
	  if (!NONDEBUG_INSN_P (within))
	    continue;
	  icode = recog_memoized (within);
	  if (icode < 0)
	    continue;
	  if (shadow_p (within))
	    continue;
	  if (INSN_INFO_ENTRY (INSN_UID (within)).reservation != 0)
	    reserved |= 1 << INSN_INFO_ENTRY (INSN_UID (within)).reservation;
	  last = within;
	}
      if (last == NULL_RTX)
	continue;

      sched_mask = INSN_INFO_ENTRY (INSN_UID (last)).unit_mask;
      sched_mask &= ~reserved;

      memset (rsrv_count, 0, sizeof rsrv_count);
      rsrv[0] = rsrv[1] = ~0;
      for (i = 0; i < 8; i++)
	{
	  int side = i / 4;
	  int unit = i & 3;
	  unsigned unit_bit = 1 << (unit + side * UNIT_QID_SIDE_OFFSET);
	  /* Clear the bits which we expect to reserve in the following loop,
	     leaving the ones set which aren't present in the scheduler's
	     state and shouldn't be reserved.  */
	  if (sched_mask & unit_bit)
	    rsrv[i / 4] &= ~(1 << unit);
	}

      /* Walk through the insns that occur in the same cycle.  We use multiple
	 passes to assign units, assigning for insns with the most specific
	 requirements first.  */
      for (pass = 0; pass < 4; pass++)
	for (within = insn;
	     (within != NEXT_INSN (end)
	      && (within == insn || GET_MODE (within) != TImode));
	     within = NEXT_INSN (within))
	  {
	    int uid = INSN_UID (within);
	    int this_rsrv, side;
	    int icode;
	    enum attr_units units;
	    enum attr_type type;
	    int j;

	    if (!NONDEBUG_INSN_P (within))
	      continue;
	    icode = recog_memoized (within);
	    if (icode < 0)
	      continue;
	    if (INSN_INFO_ENTRY (uid).reservation != 0)
	      continue;
	    units = get_attr_units (within);
	    type = get_attr_type (within);
	    this_rsrv = get_reservation_flags (units);
	    if (this_rsrv == 0)
	      continue;
	    side = get_insn_side (within, units);

	    /* Certain floating point instructions are treated specially.  If
	       an insn can choose between units it can reserve, and its
	       reservation spans more than one cycle, the reservation contains
	       special markers in the first cycle to help us reconstruct what
	       the automaton chose.  */
	    if ((type == TYPE_ADDDP || type == TYPE_FP4)
		&& units == UNITS_LS)
	      {
		int test1_code = ((type == TYPE_FP4 ? UNIT_QID_FPL1 : UNIT_QID_ADDDPL1)
				  + side * UNIT_QID_SIDE_OFFSET);
		int test2_code = ((type == TYPE_FP4 ? UNIT_QID_FPS1 : UNIT_QID_ADDDPS1)
				  + side * UNIT_QID_SIDE_OFFSET);
		if ((sched_mask & (1 << test1_code)) != 0)
		  {
		    this_rsrv = RESERVATION_FLAG_L;
		    sched_mask &= ~(1 << test1_code);
		  }
		else if ((sched_mask & (1 << test2_code)) != 0)
		  {
		    this_rsrv = RESERVATION_FLAG_S;
		    sched_mask &= ~(1 << test2_code);
		  }
	      }

	    if ((this_rsrv & (this_rsrv - 1)) == 0)
	      {
		int t = exact_log2 (this_rsrv) + side * UNIT_QID_SIDE_OFFSET;
		rsrv[side] |= this_rsrv;
		INSN_INFO_ENTRY (uid).reservation = t;
		continue;
	      }

	    if (pass == 1)
	      {
		for (j = 0; j < 4; j++)
		  if (this_rsrv & (1 << j))
		    rsrv_count[side][j]++;
		continue;
	      }
	    if ((pass == 2 && this_rsrv != RESERVATION_FLAG_DLS)
		|| (pass == 3 && this_rsrv == RESERVATION_FLAG_DLS))
	      {
		int best = -1, best_cost = INT_MAX;
		for (j = 0; j < 4; j++)
		  if ((this_rsrv & (1 << j))
		      && !(rsrv[side] & (1 << j))
		      && rsrv_count[side][j] < best_cost)
		    {
		      best_cost = rsrv_count[side][j];
		      best = j;
		    }
		gcc_assert (best != -1);
		rsrv[side] |= 1 << best;
		for (j = 0; j < 4; j++)
		  if ((this_rsrv & (1 << j)) && j != best)
		    rsrv_count[side][j]--;

		INSN_INFO_ENTRY (uid).reservation
		  = best + side * UNIT_QID_SIDE_OFFSET;
	      }
	  }
    }
}

/* Return a factor by which to weight unit imbalances for a reservation
   R.  */
static int
unit_req_factor (enum unitreqs r)
{
  switch (r)
    {
    case UNIT_REQ_D:
    case UNIT_REQ_L:
    case UNIT_REQ_S:
    case UNIT_REQ_M:
    case UNIT_REQ_X:
    case UNIT_REQ_T:
      return 1;
    case UNIT_REQ_DL:
    case UNIT_REQ_LS:
    case UNIT_REQ_DS:
      return 2;
    case UNIT_REQ_DLS:
      return 3;
    default:
      gcc_unreachable ();
    }
}

/* Examine INSN, and store in REQ1/SIDE1 and REQ2/SIDE2 the unit
   requirements.  Returns zero if INSN can't be handled, otherwise
   either one or two to show how many of the two pairs are in use.
   REQ1 is always used, it holds what is normally thought of as the
   instructions reservation, e.g. UNIT_REQ_DL.  REQ2 is used to either
   describe a cross path, or for loads/stores, the T unit.  */
static int
get_unit_reqs (rtx_insn *insn, int *req1, int *side1, int *req2, int *side2)
{
  enum attr_units units;
  enum attr_cross cross;
  int side, req;

  if (!NONDEBUG_INSN_P (insn) || recog_memoized (insn) < 0)
    return 0;
  units = get_attr_units (insn);
  if (units == UNITS_UNKNOWN)
    return 0;
  side = get_insn_side (insn, units);
  cross = get_attr_cross (insn);

  req = (units == UNITS_D ? UNIT_REQ_D
	 : units == UNITS_D_ADDR ? UNIT_REQ_D
	 : units == UNITS_DL ? UNIT_REQ_DL
	 : units == UNITS_DS ? UNIT_REQ_DS
	 : units == UNITS_L ? UNIT_REQ_L
	 : units == UNITS_LS ? UNIT_REQ_LS
	 : units == UNITS_S ? UNIT_REQ_S
	 : units == UNITS_M ? UNIT_REQ_M
	 : units == UNITS_DLS ? UNIT_REQ_DLS
	 : -1);
  gcc_assert (req != -1);
  *req1 = req;
  *side1 = side;
  if (units == UNITS_D_ADDR)
    {
      *req2 = UNIT_REQ_T;
      *side2 = side ^ (cross == CROSS_Y ? 1 : 0);
      return 2;
    }
  else if (cross == CROSS_Y)
    {
      *req2 = UNIT_REQ_X;
      *side2 = side;
      return 2;
    }
  return 1;
}

/* Walk the insns between and including HEAD and TAIL, and mark the
   resource requirements in the unit_reqs table.  */
static void
count_unit_reqs (unit_req_table reqs, rtx_insn *head, rtx_insn *tail)
{
  rtx_insn *insn;

  memset (reqs, 0, sizeof (unit_req_table));

  for (insn = head; insn != NEXT_INSN (tail); insn = NEXT_INSN (insn))
    {
      int side1, side2, req1, req2;

      switch (get_unit_reqs (insn, &req1, &side1, &req2, &side2))
	{
	case 2:
	  reqs[side2][req2]++;
	  /* fall through */
	case 1:
	  reqs[side1][req1]++;
	  break;
	}
    }
}

/* Update the table REQS by merging more specific unit reservations into
   more general ones, i.e. counting (for example) UNIT_REQ_D also in
   UNIT_REQ_DL, DS, and DLS.  */
static void
merge_unit_reqs (unit_req_table reqs)
{
  int side;
  for (side = 0; side < 2; side++)
    {
      int d = reqs[side][UNIT_REQ_D];
      int l = reqs[side][UNIT_REQ_L];
      int s = reqs[side][UNIT_REQ_S];
      int dl = reqs[side][UNIT_REQ_DL];
      int ls = reqs[side][UNIT_REQ_LS];
      int ds = reqs[side][UNIT_REQ_DS];

      reqs[side][UNIT_REQ_DL] += d;
      reqs[side][UNIT_REQ_DL] += l;
      reqs[side][UNIT_REQ_DS] += d;
      reqs[side][UNIT_REQ_DS] += s;
      reqs[side][UNIT_REQ_LS] += l;
      reqs[side][UNIT_REQ_LS] += s;
      reqs[side][UNIT_REQ_DLS] += ds + dl + ls + d + l + s;
    }
}

/* Examine the table REQS and return a measure of unit imbalance by comparing
   the two sides of the machine.  If, for example, D1 is used twice and D2
   used not at all, the return value should be 1 in the absence of other
   imbalances.  */
static int
unit_req_imbalance (unit_req_table reqs)
{
  int val = 0;
  int i;

  for (i = 0; i < UNIT_REQ_MAX; i++)
    {
      int factor = unit_req_factor ((enum unitreqs) i);
      int diff = abs (reqs[0][i] - reqs[1][i]);
      val += (diff + factor - 1) / factor / 2;
    }
  return val;
}

/* Return the resource-constrained minimum iteration interval given the
   data in the REQS table.  This must have been processed with
   merge_unit_reqs already.  */
static int
res_mii (unit_req_table reqs)
{
  int side, req;
  int worst = 1;
  for (side = 0; side < 2; side++)
    for (req = 0; req < UNIT_REQ_MAX; req++)
      {
	int factor = unit_req_factor ((enum unitreqs) req);
	worst = MAX ((reqs[side][UNIT_REQ_D] + factor - 1) / factor, worst);
      }

  return worst;
}

/* Examine INSN, and store in PMASK1 and PMASK2 bitmasks that represent
   the operands that are involved in the (up to) two reservations, as
   found by get_unit_reqs.  Return true if we did this successfully, false
   if we couldn't identify what to do with INSN.  */
static bool
get_unit_operand_masks (rtx_insn *insn, unsigned int *pmask1,
			unsigned int *pmask2)
{
  enum attr_op_pattern op_pat;

  if (recog_memoized (insn) < 0)
    return 0;
  if (GET_CODE (PATTERN (insn)) == COND_EXEC)
    return false;
  extract_insn (insn);
  op_pat = get_attr_op_pattern (insn);
  if (op_pat == OP_PATTERN_DT)
    {
      gcc_assert (recog_data.n_operands == 2);
      *pmask1 = 1 << 0;
      *pmask2 = 1 << 1;
      return true;
    }
  else if (op_pat == OP_PATTERN_TD)
    {
      gcc_assert (recog_data.n_operands == 2);
      *pmask1 = 1 << 1;
      *pmask2 = 1 << 0;
      return true;
    }
  else if (op_pat == OP_PATTERN_SXS)
    {
      gcc_assert (recog_data.n_operands == 3);
      *pmask1 = (1 << 0) | (1 << 2);
      *pmask2 = 1 << 1;
      return true;
    }
  else if (op_pat == OP_PATTERN_SX)
    {
      gcc_assert (recog_data.n_operands == 2);
      *pmask1 = 1 << 0;
      *pmask2 = 1 << 1;
      return true;
    }
  else if (op_pat == OP_PATTERN_SSX)
    {
      gcc_assert (recog_data.n_operands == 3);
      *pmask1 = (1 << 0) | (1 << 1);
      *pmask2 = 1 << 2;
      return true;
    }
  return false;
}

/* Try to replace a register in INSN, which has corresponding rename info
   from regrename_analyze in INFO.  OP_MASK and ORIG_SIDE provide information
   about the operands that must be renamed and the side they are on.
   REQS is the table of unit reservations in the loop between HEAD and TAIL.
   We recompute this information locally after our transformation, and keep
   it only if we managed to improve the balance.  */
static void
try_rename_operands (rtx_insn *head, rtx_insn *tail, unit_req_table reqs,
		     rtx insn,
		     insn_rr_info *info, unsigned int op_mask, int orig_side)
{
  enum reg_class super_class = orig_side == 0 ? B_REGS : A_REGS;
  HARD_REG_SET unavailable;
  du_head_p this_head;
  struct du_chain *chain;
  int i;
  unsigned tmp_mask;
  int best_reg, old_reg;
  vec<du_head_p> involved_chains = vNULL;
  unit_req_table new_reqs;
  bool ok;

  for (i = 0, tmp_mask = op_mask; tmp_mask; i++)
    {
      du_head_p op_chain;
      if ((tmp_mask & (1 << i)) == 0)
	continue;
      if (info->op_info[i].n_chains != 1)
	goto out_fail;
      op_chain = regrename_chain_from_id (info->op_info[i].heads[0]->id);
      involved_chains.safe_push (op_chain);
      tmp_mask &= ~(1 << i);
    }

  if (involved_chains.length () > 1)
    goto out_fail;

  this_head = involved_chains[0];
  if (this_head->cannot_rename)
    goto out_fail;

  for (chain = this_head->first; chain; chain = chain->next_use)
    {
      unsigned int mask1, mask2, mask_changed;
      int count, side1, side2, req1, req2;
      insn_rr_info *this_rr = &insn_rr[INSN_UID (chain->insn)];

      count = get_unit_reqs (chain->insn, &req1, &side1, &req2, &side2);

      if (count == 0)
	goto out_fail;

      if (!get_unit_operand_masks (chain->insn, &mask1, &mask2))
	goto out_fail;

      extract_insn (chain->insn);

      mask_changed = 0;
      for (i = 0; i < recog_data.n_operands; i++)
	{
	  int j;
	  int n_this_op = this_rr->op_info[i].n_chains;
	  for (j = 0; j < n_this_op; j++)
	    {
	      du_head_p other = this_rr->op_info[i].heads[j];
	      if (regrename_chain_from_id (other->id) == this_head)
		break;
	    }
	  if (j == n_this_op)
	    continue;

	  if (n_this_op != 1)
	    goto out_fail;
	  mask_changed |= 1 << i;
	}
      gcc_assert (mask_changed != 0);
      if (mask_changed != mask1 && mask_changed != mask2)
	goto out_fail;
    }

  /* If we get here, we can do the renaming.  */
  unavailable = ~reg_class_contents[super_class];

  old_reg = this_head->regno;
  best_reg =
    find_rename_reg (this_head, super_class, &unavailable, old_reg, true);

  ok = regrename_do_replace (this_head, best_reg);
  gcc_assert (ok);

  count_unit_reqs (new_reqs, head, PREV_INSN (tail));
  merge_unit_reqs (new_reqs);
  if (dump_file)
    {
      fprintf (dump_file, "reshuffle for insn %d, op_mask %x, "
	       "original side %d, new reg %d\n",
	       INSN_UID (insn), op_mask, orig_side, best_reg);
      fprintf (dump_file, "  imbalance %d -> %d\n",
	       unit_req_imbalance (reqs), unit_req_imbalance (new_reqs));
    }
  if (unit_req_imbalance (new_reqs) > unit_req_imbalance (reqs))
    {
      ok = regrename_do_replace (this_head, old_reg);
      gcc_assert (ok);
    }
  else
    memcpy (reqs, new_reqs, sizeof (unit_req_table));

 out_fail:
  involved_chains.release ();
}

/* Find insns in LOOP which would, if shifted to the other side
   of the machine, reduce an imbalance in the unit reservations.  */
static void
reshuffle_units (basic_block loop)
{
  rtx_insn *head = BB_HEAD (loop);
  rtx_insn *tail = BB_END (loop);
  rtx_insn *insn;
  unit_req_table reqs;
  edge e;
  edge_iterator ei;
  bitmap_head bbs;

  count_unit_reqs (reqs, head, PREV_INSN (tail));
  merge_unit_reqs (reqs);

  regrename_init (true);

  bitmap_initialize (&bbs, &bitmap_default_obstack);

  FOR_EACH_EDGE (e, ei, loop->preds)
    bitmap_set_bit (&bbs, e->src->index);

  bitmap_set_bit (&bbs, loop->index);
  regrename_analyze (&bbs);

  for (insn = head; insn != NEXT_INSN (tail); insn = NEXT_INSN (insn))
    {
      enum attr_units units;
      int count, side1, side2, req1, req2;
      unsigned int mask1, mask2;
      insn_rr_info *info;

      if (!NONDEBUG_INSN_P (insn))
	continue;

      count = get_unit_reqs (insn, &req1, &side1, &req2, &side2);

      if (count == 0)
	continue;

      if (!get_unit_operand_masks (insn, &mask1, &mask2))
	continue;

      info = &insn_rr[INSN_UID (insn)];
      if (info->op_info == NULL)
	continue;

      if (reqs[side1][req1] > 1
	  && reqs[side1][req1] > 2 * reqs[side1 ^ 1][req1])
	{
	  try_rename_operands (head, tail, reqs, insn, info, mask1, side1);
	}

      units = get_attr_units (insn);
      if (units == UNITS_D_ADDR)
	{
	  gcc_assert (count == 2);
	  if (reqs[side2][req2] > 1
	      && reqs[side2][req2] > 2 * reqs[side2 ^ 1][req2])
	    {
	      try_rename_operands (head, tail, reqs, insn, info, mask2, side2);
	    }
	}
    }
  regrename_finish ();
}

/* Backend scheduling state.  */
typedef struct c6x_sched_context
{
  /* The current scheduler clock, saved in the sched_reorder hook.  */
  int curr_sched_clock;

  /* Number of insns issued so far in this cycle.  */
  int issued_this_cycle;

  /* We record the time at which each jump occurs in JUMP_CYCLES.  The
     theoretical maximum for number of jumps in flight is 12: 2 every
     cycle, with a latency of 6 cycles each.  This is a circular
     buffer; JUMP_CYCLE_INDEX is the pointer to the start.  Earlier
     jumps have a higher index.  This array should be accessed through
     the jump_cycle function.  */
  int jump_cycles[12];
  int jump_cycle_index;

  /* In parallel with jump_cycles, this array records the opposite of
     the condition used in each pending jump.  This is used to
     predicate insns that are scheduled in the jump's delay slots.  If
     this is NULL_RTX no such predication happens.  */
  rtx jump_cond[12];

  /* Similar to the jump_cycles mechanism, but here we take into
     account all insns with delay slots, to avoid scheduling asms into
     the delay slots.  */
  int delays_finished_at;

  /* The following variable value is the last issued insn.  */
  rtx_insn *last_scheduled_insn;
  /* The last issued insn that isn't a shadow of another.  */
  rtx_insn *last_scheduled_iter0;

  /* The following variable value is DFA state before issuing the
     first insn in the current clock cycle.  We do not use this member
     of the structure directly; we copy the data in and out of
     prev_cycle_state.  */
  state_t prev_cycle_state_ctx;

  int reg_n_accesses[FIRST_PSEUDO_REGISTER];
  int reg_n_xaccesses[FIRST_PSEUDO_REGISTER];
  int reg_set_in_cycle[FIRST_PSEUDO_REGISTER];

  int tmp_reg_n_accesses[FIRST_PSEUDO_REGISTER];
  int tmp_reg_n_xaccesses[FIRST_PSEUDO_REGISTER];
} *c6x_sched_context_t;

/* The current scheduling state.  */
static struct c6x_sched_context ss;

/* The following variable value is DFA state before issuing the first insn
   in the current clock cycle.  This is used in c6x_variable_issue for
   comparison with the state after issuing the last insn in a cycle.  */
static state_t prev_cycle_state;

/* Set when we discover while processing an insn that it would lead to too
   many accesses of the same register.  */
static bool reg_access_stall;

/* The highest insn uid after delayed insns were split, but before loop bodies
   were copied by the modulo scheduling code.  */
static int sploop_max_uid_iter0;

/* Look up the jump cycle with index N.  For an out-of-bounds N, we return 0,
   so the caller does not specifically have to test for it.  */
static int
get_jump_cycle (int n)
{
  if (n >= 12)
    return 0;
  n += ss.jump_cycle_index;
  if (n >= 12)
    n -= 12;
  return ss.jump_cycles[n];
}

/* Look up the jump condition with index N.  */
static rtx
get_jump_cond (int n)
{
  if (n >= 12)
    return NULL_RTX;
  n += ss.jump_cycle_index;
  if (n >= 12)
    n -= 12;
  return ss.jump_cond[n];
}

/* Return the index of the first jump that occurs after CLOCK_VAR.  If no jump
   has delay slots beyond CLOCK_VAR, return -1.  */
static int
first_jump_index (int clock_var)
{
  int retval = -1;
  int n = 0;
  for (;;)
    {
      int t = get_jump_cycle (n);
      if (t <= clock_var)
	break;
      retval = n;
      n++;
    }
  return retval;
}

/* Add a new entry in our scheduling state for a jump that occurs in CYCLE
   and has the opposite condition of COND.  */
static void
record_jump (int cycle, rtx cond)
{
  if (ss.jump_cycle_index == 0)
    ss.jump_cycle_index = 11;
  else
    ss.jump_cycle_index--;
  ss.jump_cycles[ss.jump_cycle_index] = cycle;
  ss.jump_cond[ss.jump_cycle_index] = cond;
}

/* Set the clock cycle of INSN to CYCLE.  Also clears the insn's entry in
   new_conditions.  */
static void
insn_set_clock (rtx insn, int cycle)
{
  unsigned uid = INSN_UID (insn);

  if (uid >= INSN_INFO_LENGTH)
    insn_info.safe_grow (uid * 5 / 4 + 10, true);

  INSN_INFO_ENTRY (uid).clock = cycle;
  INSN_INFO_ENTRY (uid).new_cond = NULL;
  INSN_INFO_ENTRY (uid).reservation = 0;
  INSN_INFO_ENTRY (uid).ebb_start = false;
}

/* Return the clock cycle we set for the insn with uid UID.  */
static int
insn_uid_get_clock (int uid)
{
  return INSN_INFO_ENTRY (uid).clock;
}

/* Return the clock cycle we set for INSN.  */
static int
insn_get_clock (rtx insn)
{
  return insn_uid_get_clock (INSN_UID (insn));
}

/* Examine INSN, and if it is a conditional jump of any kind, return
   the opposite of the condition in which it branches.  Otherwise,
   return NULL_RTX.  */
static rtx
condjump_opposite_condition (rtx insn)
{
  rtx pat = PATTERN (insn);
  int icode = INSN_CODE (insn);
  rtx x = NULL;

  if (icode == CODE_FOR_br_true || icode == CODE_FOR_br_false)
    {
      x = XEXP (SET_SRC (pat), 0);
      if (icode == CODE_FOR_br_false)
	return x;
    }
  if (GET_CODE (pat) == COND_EXEC)
    {
      rtx t = COND_EXEC_CODE (pat);
      if ((GET_CODE (t) == PARALLEL
	   && GET_CODE (XVECEXP (t, 0, 0)) == RETURN)
	  || (GET_CODE (t) == UNSPEC && XINT (t, 1) == UNSPEC_REAL_JUMP)
	  || (GET_CODE (t) == SET && SET_DEST (t) == pc_rtx))
	x = COND_EXEC_TEST (pat);
    }

  if (x != NULL_RTX)
    {
      enum rtx_code code = GET_CODE (x);
      x = gen_rtx_fmt_ee (code == EQ ? NE : EQ,
			  GET_MODE (x), XEXP (x, 0),
			  XEXP (x, 1));
    }
  return x;
}

/* Return true iff COND1 and COND2 are exactly opposite conditions
   one of them NE and the other EQ.  */
static bool
conditions_opposite_p (rtx cond1, rtx cond2)
{
  return (rtx_equal_p (XEXP (cond1, 0), XEXP (cond2, 0))
	  && rtx_equal_p (XEXP (cond1, 1), XEXP (cond2, 1))
	  && GET_CODE (cond1) == reverse_condition (GET_CODE (cond2)));
}

/* Return true if we can add a predicate COND to INSN, or if INSN
   already has that predicate.  If DOIT is true, also perform the
   modification.  */
static bool
predicate_insn (rtx_insn *insn, rtx cond, bool doit)
{
  int icode;
  if (cond == NULL_RTX)
    {
      gcc_assert (!doit);
      return false;
    }

  if (get_attr_predicable (insn) == PREDICABLE_YES
      && GET_CODE (PATTERN (insn)) != COND_EXEC)
    {
      if (doit)
	{
	  cond = copy_rtx (cond);
	  rtx newpat = gen_rtx_COND_EXEC (VOIDmode, cond, PATTERN (insn));
	  PATTERN (insn) = newpat;
	  INSN_CODE (insn) = -1;
	}
      return true;
    }
  if (GET_CODE (PATTERN (insn)) == COND_EXEC
      && rtx_equal_p (COND_EXEC_TEST (PATTERN (insn)), cond))
    return true;
  icode = INSN_CODE (insn);
  if (icode == CODE_FOR_real_jump
      || icode == CODE_FOR_jump
      || icode == CODE_FOR_indirect_jump)
    {
      rtx pat = PATTERN (insn);
      rtx dest = (icode == CODE_FOR_real_jump ? XVECEXP (pat, 0, 0)
		  : icode == CODE_FOR_jump ? XEXP (SET_SRC (pat), 0)
		  : SET_SRC (pat));
      if (doit)
	{
	  rtx newpat;
	  if (REG_P (dest))
	    newpat = gen_rtx_COND_EXEC (VOIDmode, cond, PATTERN (insn));
	  else
	    newpat = gen_br_true (cond, XEXP (cond, 0), dest);
	  PATTERN (insn) = newpat;
	  INSN_CODE (insn) = -1;
	}
      return true;
    }
  if (INSN_CODE (insn) == CODE_FOR_br_true)
    {
      rtx br_cond = XEXP (SET_SRC (PATTERN (insn)), 0);
      return rtx_equal_p (br_cond, cond);
    }
  if (INSN_CODE (insn) == CODE_FOR_br_false)
    {
      rtx br_cond = XEXP (SET_SRC (PATTERN (insn)), 0);
      return conditions_opposite_p (br_cond, cond);
    }
  return false;
}

/* Initialize SC.  Used by c6x_init_sched_context and c6x_sched_init.  */
static void
init_sched_state (c6x_sched_context_t sc)
{
  sc->last_scheduled_insn = NULL;
  sc->last_scheduled_iter0 = NULL;
  sc->issued_this_cycle = 0;
  memset (sc->jump_cycles, 0, sizeof sc->jump_cycles);
  memset (sc->jump_cond, 0, sizeof sc->jump_cond);
  sc->jump_cycle_index = 0;
  sc->delays_finished_at = 0;
  sc->curr_sched_clock = 0;

  sc->prev_cycle_state_ctx = xmalloc (dfa_state_size);

  memset (sc->reg_n_accesses, 0, sizeof sc->reg_n_accesses);
  memset (sc->reg_n_xaccesses, 0, sizeof sc->reg_n_xaccesses);
  memset (sc->reg_set_in_cycle, 0, sizeof sc->reg_set_in_cycle);

  state_reset (sc->prev_cycle_state_ctx);
}

/* Allocate store for new scheduling context.  */
static void *
c6x_alloc_sched_context (void)
{
  return xmalloc (sizeof (struct c6x_sched_context));
}

/* If CLEAN_P is true then initializes _SC with clean data,
   and from the global context otherwise.  */
static void
c6x_init_sched_context (void *_sc, bool clean_p)
{
  c6x_sched_context_t sc = (c6x_sched_context_t) _sc;

  if (clean_p)
    {
      init_sched_state (sc);
    }
  else
    {
      *sc = ss;
      sc->prev_cycle_state_ctx = xmalloc (dfa_state_size);
      memcpy (sc->prev_cycle_state_ctx, prev_cycle_state, dfa_state_size);
    }
}

/* Sets the global scheduling context to the one pointed to by _SC.  */
static void
c6x_set_sched_context (void *_sc)
{
  c6x_sched_context_t sc = (c6x_sched_context_t) _sc;

  gcc_assert (sc != NULL);
  ss = *sc;
  memcpy (prev_cycle_state, sc->prev_cycle_state_ctx, dfa_state_size);
}

/* Clear data in _SC.  */
static void
c6x_clear_sched_context (void *_sc)
{
  c6x_sched_context_t sc = (c6x_sched_context_t) _sc;
  gcc_assert (_sc != NULL);

  free (sc->prev_cycle_state_ctx);
}

/* Free _SC.  */
static void
c6x_free_sched_context (void *_sc)
{
  free (_sc);
}

/* True if we are currently performing a preliminary scheduling
   pass before modulo scheduling; we can't allow the scheduler to
   modify instruction patterns using packetization assumptions,
   since there will be another scheduling pass later if modulo
   scheduling fails.  */
static bool in_hwloop;

/* Provide information about speculation capabilities, and set the
   DO_BACKTRACKING flag.  */
static void
c6x_set_sched_flags (spec_info_t spec_info)
{
  unsigned int *flags = &(current_sched_info->flags);

  if (*flags & SCHED_EBB)
    {
      *flags |= DO_BACKTRACKING | DO_PREDICATION;
    }
  if (in_hwloop)
    *flags |= DONT_BREAK_DEPENDENCIES;

  spec_info->mask = 0;
}

/* Implement the TARGET_SCHED_ISSUE_RATE hook.  */

static int
c6x_issue_rate (void)
{
  return 8;
}

/* Used together with the collapse_ndfa option, this ensures that we reach a
   deterministic automaton state before trying to advance a cycle.
   With collapse_ndfa, genautomata creates advance cycle arcs only for
   such deterministic states.  */

static rtx
c6x_sched_dfa_pre_cycle_insn (void)
{
  return const0_rtx;
}

/* We're beginning a new block.  Initialize data structures as necessary.  */

static void
c6x_sched_init (FILE *dump ATTRIBUTE_UNUSED,
		int sched_verbose ATTRIBUTE_UNUSED,
		int max_ready ATTRIBUTE_UNUSED)
{
  if (prev_cycle_state == NULL)
    {
      prev_cycle_state = xmalloc (dfa_state_size);
    }
  init_sched_state (&ss);
  state_reset (prev_cycle_state);
}

/* 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.
   For C6X, we use this function just to copy the previous DFA state
   for comparison purposes.  */

static int
c6x_dfa_new_cycle (FILE *dump ATTRIBUTE_UNUSED, int verbose ATTRIBUTE_UNUSED,
		   rtx_insn *insn ATTRIBUTE_UNUSED,
		   int last_clock ATTRIBUTE_UNUSED,
		   int clock ATTRIBUTE_UNUSED, int *sort_p ATTRIBUTE_UNUSED)
{
  if (clock != last_clock)
    memcpy (prev_cycle_state, curr_state, dfa_state_size);
  return 0;
}

static void
c6x_mark_regno_read (int regno, bool cross)
{
  int t = ++ss.tmp_reg_n_accesses[regno];

  if (t > 4)
    reg_access_stall = true;

  if (cross)
    {
      int set_cycle = ss.reg_set_in_cycle[regno];
      /* This must be done in this way rather than by tweaking things in
	 adjust_cost, since the stall occurs even for insns with opposite
	 predicates, and the scheduler may not even see a dependency.  */
      if (set_cycle > 0 && set_cycle == ss.curr_sched_clock)
	reg_access_stall = true;
      /* This doesn't quite do anything yet as we're only modeling one
	 x unit.  */
      ++ss.tmp_reg_n_xaccesses[regno];
    }
}

/* Note that REG is read in the insn being examined.  If CROSS, it
   means the access is through a cross path.  Update the temporary reg
   access arrays, and set REG_ACCESS_STALL if the insn can't be issued
   in the current cycle.  */

static void
c6x_mark_reg_read (rtx reg, bool cross)
{
  unsigned regno = REGNO (reg);
  unsigned nregs = REG_NREGS (reg);

  while (nregs-- > 0)
    c6x_mark_regno_read (regno + nregs, cross);
}

/* Note that register REG is written in cycle CYCLES.  */

static void
c6x_mark_reg_written (rtx reg, int cycles)
{
  unsigned regno = REGNO (reg);
  unsigned nregs = REG_NREGS (reg);

  while (nregs-- > 0)
    ss.reg_set_in_cycle[regno + nregs] = cycles;
}

/* Update the register state information for an instruction whose
   body is X.  Return true if the instruction has to be delayed until the
   next cycle.  */

static bool
c6x_registers_update (rtx_insn *insn)
{
  enum attr_cross cross;
  enum attr_dest_regfile destrf;
  int i, nops;
  rtx x;

  if (!reload_completed || recog_memoized (insn) < 0)
    return false;

  reg_access_stall = false;
  memcpy (ss.tmp_reg_n_accesses, ss.reg_n_accesses,
	  sizeof ss.tmp_reg_n_accesses);
  memcpy (ss.tmp_reg_n_xaccesses, ss.reg_n_xaccesses,
	  sizeof ss.tmp_reg_n_xaccesses);

  extract_insn (insn);

  cross = get_attr_cross (insn);
  destrf = get_attr_dest_regfile (insn);

  nops = recog_data.n_operands;
  x = PATTERN (insn);
  if (GET_CODE (x) == COND_EXEC)
    {
      c6x_mark_reg_read (XEXP (XEXP (x, 0), 0), false);
      nops -= 2;
    }

  for (i = 0; i < nops; i++)
    {
      rtx op = recog_data.operand[i];
      if (recog_data.operand_type[i] == OP_OUT)
	continue;
      if (REG_P (op))
	{
	  bool this_cross = cross;
	  if (destrf == DEST_REGFILE_A && A_REGNO_P (REGNO (op)))
	    this_cross = false;
	  if (destrf == DEST_REGFILE_B && B_REGNO_P (REGNO (op)))
	    this_cross = false;
	  c6x_mark_reg_read (op, this_cross);
	}
      else if (MEM_P (op))
	{
	  op = XEXP (op, 0);
	  switch (GET_CODE (op))
	    {
	    case POST_INC:
	    case PRE_INC:
	    case POST_DEC:
	    case PRE_DEC:
	      op = XEXP (op, 0);
	      /* fall through */
	    case REG:
	      c6x_mark_reg_read (op, false);
	      break;
	    case POST_MODIFY:
	    case PRE_MODIFY:
	      op = XEXP (op, 1);
	      gcc_assert (GET_CODE (op) == PLUS);
	      /* fall through */
	    case PLUS:
	      c6x_mark_reg_read (XEXP (op, 0), false);
	      if (REG_P (XEXP (op, 1)))
		c6x_mark_reg_read (XEXP (op, 1), false);
	      break;
	    case SYMBOL_REF:
	    case LABEL_REF:
	    case CONST:
	      c6x_mark_regno_read (REG_B14, false);
	      break;
	    default:
	      gcc_unreachable ();
	    }
	}
      else if (!CONSTANT_P (op) && strlen (recog_data.constraints[i]) > 0)
	gcc_unreachable ();
    }
  return reg_access_stall;
}

/* Helper function for the TARGET_SCHED_REORDER and
   TARGET_SCHED_REORDER2 hooks.  If scheduling an insn would be unsafe
   in the current cycle, move it down in the ready list and return the
   number of non-unsafe insns.  */

static int
c6x_sched_reorder_1 (rtx_insn **ready, int *pn_ready, int clock_var)
{
  int n_ready = *pn_ready;
  rtx_insn **e_ready = ready + n_ready;
  rtx_insn **insnp;
  int first_jump;

  /* Keep track of conflicts due to a limit number of register accesses,
     and due to stalls incurred by too early accesses of registers using
     cross paths.  */

  for (insnp = ready; insnp < e_ready; insnp++)
    {
      rtx_insn *insn = *insnp;
      int icode = recog_memoized (insn);
      bool is_asm = (icode < 0
		     && (GET_CODE (PATTERN (insn)) == ASM_INPUT
			 || asm_noperands (PATTERN (insn)) >= 0));
      bool no_parallel = (is_asm || icode == CODE_FOR_sploop
			  || (icode >= 0
			      && get_attr_type (insn) == TYPE_ATOMIC));

      /* We delay asm insns until all delay slots are exhausted.  We can't
	 accurately tell how many cycles an asm takes, and the main scheduling
	 code always assumes at least 1 cycle, which may be wrong.  */
      if ((no_parallel
	   && (ss.issued_this_cycle > 0 || clock_var < ss.delays_finished_at))
	  || c6x_registers_update (insn)
	  || (ss.issued_this_cycle > 0 && icode == CODE_FOR_sploop))
	{
	  memmove (ready + 1, ready, (insnp - ready) * sizeof (rtx));
	  *ready = insn;
	  n_ready--;
	  ready++;
	}
      else if (shadow_p (insn))
	{
	  memmove (ready + 1, ready, (insnp - ready) * sizeof (rtx));
	  *ready = insn;
	}
    }

  /* Ensure that no other jump is scheduled in jump delay slots, since
     it would put the machine into the wrong state.  Also, we must
     avoid scheduling insns that have a latency longer than the
     remaining jump delay slots, as the code at the jump destination
     won't be prepared for it.

     However, we can relax this condition somewhat.  The rest of the
     scheduler will automatically avoid scheduling an insn on which
     the jump shadow depends so late that its side effect happens
     after the jump.  This means that if we see an insn with a longer
     latency here, it can safely be scheduled if we can ensure that it
     has a predicate opposite of the previous jump: the side effect
     will happen in what we think of as the same basic block.  In
     c6x_variable_issue, we will record the necessary predicate in
     new_conditions, and after scheduling is finished, we will modify
     the insn.

     Special care must be taken whenever there is more than one jump
     in flight.  */

  first_jump = first_jump_index (clock_var);
  if (first_jump != -1)
    {
      int first_cycle = get_jump_cycle (first_jump);
      rtx first_cond = get_jump_cond (first_jump);
      int second_cycle = 0;

      if (first_jump > 0)
	second_cycle = get_jump_cycle (first_jump - 1);

      for (insnp = ready; insnp < e_ready; insnp++)
	{
	  rtx_insn *insn = *insnp;
	  int icode = recog_memoized (insn);
	  bool is_asm = (icode < 0
			 && (GET_CODE (PATTERN (insn)) == ASM_INPUT
			     || asm_noperands (PATTERN (insn)) >= 0));
	  int this_cycles, rsrv_cycles;
	  enum attr_type type;

	  gcc_assert (!is_asm);
	  if (icode < 0)
	    continue;
	  this_cycles = get_attr_cycles (insn);
	  rsrv_cycles = get_attr_reserve_cycles (insn);
	  type = get_attr_type (insn);
	  /* Treat branches specially; there is also a hazard if two jumps
	     end at the same cycle.  */
	  if (type == TYPE_BRANCH || type == TYPE_CALL)
	    this_cycles++;
	  if (clock_var + this_cycles <= first_cycle)
	    continue;
	  if ((first_jump > 0 && clock_var + this_cycles > second_cycle)
	      || clock_var + rsrv_cycles > first_cycle
	      || !predicate_insn (insn, first_cond, false))
	    {
	      memmove (ready + 1, ready, (insnp - ready) * sizeof (rtx));
	      *ready = insn;
	      n_ready--;
	      ready++;
	    }
	}
    }

  return n_ready;
}

/* Implement the TARGET_SCHED_REORDER hook.  We save the current clock
   for later and clear the register access information for the new
   cycle.  We also move asm statements out of the way if they would be
   scheduled in a delay slot.  */

static int
c6x_sched_reorder (FILE *dump ATTRIBUTE_UNUSED,
		   int sched_verbose ATTRIBUTE_UNUSED,
		   rtx_insn **ready ATTRIBUTE_UNUSED,
		   int *pn_ready ATTRIBUTE_UNUSED, int clock_var)
{
  ss.curr_sched_clock = clock_var;
  ss.issued_this_cycle = 0;
  memset (ss.reg_n_accesses, 0, sizeof ss.reg_n_accesses);
  memset (ss.reg_n_xaccesses, 0, sizeof ss.reg_n_xaccesses);

  if (ready == NULL)
    return 0;

  return c6x_sched_reorder_1 (ready, pn_ready, clock_var);
}

/* Implement the TARGET_SCHED_REORDER2 hook.  We use this to record the clock
   cycle for every insn.  */

static int
c6x_sched_reorder2 (FILE *dump ATTRIBUTE_UNUSED,
		    int sched_verbose ATTRIBUTE_UNUSED,
		    rtx_insn **ready ATTRIBUTE_UNUSED,
		    int *pn_ready ATTRIBUTE_UNUSED, int clock_var)
{
  /* FIXME: the assembler rejects labels inside an execute packet.
     This can occur if prologue insns are scheduled in parallel with
     others, so we avoid this here.  Also make sure that nothing is
     scheduled in parallel with a TYPE_ATOMIC insn or after a jump.  */
  if (RTX_FRAME_RELATED_P (ss.last_scheduled_insn)
      || JUMP_P (ss.last_scheduled_insn)
      || (recog_memoized (ss.last_scheduled_insn) >= 0
	  && get_attr_type (ss.last_scheduled_insn) == TYPE_ATOMIC))
    {
      int n_ready = *pn_ready;
      rtx_insn **e_ready = ready + n_ready;
      rtx_insn **insnp;

      for (insnp = ready; insnp < e_ready; insnp++)
	{
	  rtx_insn *insn = *insnp;
	  if (!shadow_p (insn))
	    {
	      memmove (ready + 1, ready, (insnp - ready) * sizeof (rtx));
	      *ready = insn;
	      n_ready--;
	      ready++;
	    }
	}
      return n_ready;
    }

  return c6x_sched_reorder_1 (ready, pn_ready, clock_var);
}

/* Subroutine of maybe_clobber_cond, called through note_stores.  */

static void
clobber_cond_1 (rtx x, const_rtx pat ATTRIBUTE_UNUSED, void *data1)
{
  rtx *cond = (rtx *)data1;
  if (*cond != NULL_RTX && reg_overlap_mentioned_p (x, *cond))
    *cond = NULL_RTX;
}

/* Examine INSN, and if it destroys the conditions have recorded for
   any of the jumps in flight, clear that condition so that we don't
   predicate any more insns.  CLOCK_VAR helps us limit the search to
   only those jumps which are still in flight.  */

static void
maybe_clobber_cond (rtx_insn *insn, int clock_var)
{
  int n, idx;
  idx = ss.jump_cycle_index;
  for (n = 0; n < 12; n++, idx++)
    {
      rtx cond, link;
      int cycle;

      if (idx >= 12)
	idx -= 12;
      cycle = ss.jump_cycles[idx];
      if (cycle <= clock_var)
	return;

      cond = ss.jump_cond[idx];
      if (cond == NULL_RTX)
	continue;

      if (CALL_P (insn))
	{
	  ss.jump_cond[idx] = NULL_RTX;
	  continue;
	}

      note_stores (insn, clobber_cond_1, ss.jump_cond + idx);
      for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
	if (REG_NOTE_KIND (link) == REG_INC)
	  clobber_cond_1 (XEXP (link, 0), NULL_RTX, ss.jump_cond + idx);
    }
}

/* Implement the TARGET_SCHED_VARIABLE_ISSUE hook.  We are about to
   issue INSN.  Return the number of insns left on the ready queue
   that can be issued this cycle.
   We use this hook to record clock cycles and reservations for every insn.  */

static int
c6x_variable_issue (FILE *dump ATTRIBUTE_UNUSED,
		    int sched_verbose ATTRIBUTE_UNUSED,
		    rtx_insn *insn, int can_issue_more ATTRIBUTE_UNUSED)
{
  ss.last_scheduled_insn = insn;
  if (INSN_UID (insn) < sploop_max_uid_iter0 && !JUMP_P (insn))
    ss.last_scheduled_iter0 = insn;
  if (GET_CODE (PATTERN (insn)) != USE && GET_CODE (PATTERN (insn)) != CLOBBER)
    ss.issued_this_cycle++;
  if (insn_info.exists ())
    {
      state_t st_after = alloca (dfa_state_size);
      int curr_clock = ss.curr_sched_clock;
      int uid = INSN_UID (insn);
      int icode = recog_memoized (insn);
      rtx first_cond;
      int first, first_cycle;
      unsigned int mask;
      int i;

      insn_set_clock (insn, curr_clock);
      INSN_INFO_ENTRY (uid).ebb_start
	= curr_clock == 0 && ss.issued_this_cycle == 1;

      first = first_jump_index (ss.curr_sched_clock);
      if (first == -1)
	{
	  first_cycle = 0;
	  first_cond = NULL_RTX;
	}
      else
	{
	  first_cycle = get_jump_cycle (first);
	  first_cond = get_jump_cond (first);
	}
      if (icode >= 0
	  && first_cycle > curr_clock
	  && first_cond != NULL_RTX
	  && (curr_clock + get_attr_cycles (insn) > first_cycle
	      || get_attr_type (insn) == TYPE_BRANCH
	      || get_attr_type (insn) == TYPE_CALL))
	INSN_INFO_ENTRY (uid).new_cond = first_cond;

      memcpy (st_after, curr_state, dfa_state_size);
      state_transition (st_after, const0_rtx);

      mask = 0;
      for (i = 0; i < 2 * UNIT_QID_SIDE_OFFSET; i++)
	if (cpu_unit_reservation_p (st_after, c6x_unit_codes[i])
	    && !cpu_unit_reservation_p (prev_cycle_state, c6x_unit_codes[i]))
	  mask |= 1 << i;
      INSN_INFO_ENTRY (uid).unit_mask = mask;

      maybe_clobber_cond (insn, curr_clock);

      if (icode >= 0)
	{
	  int i, cycles;

	  c6x_registers_update (insn);
	  memcpy (ss.reg_n_accesses, ss.tmp_reg_n_accesses,
		  sizeof ss.reg_n_accesses);
	  memcpy (ss.reg_n_xaccesses, ss.tmp_reg_n_accesses,
		  sizeof ss.reg_n_xaccesses);

	  cycles = get_attr_cycles (insn);
	  if (ss.delays_finished_at < ss.curr_sched_clock + cycles)
	    ss.delays_finished_at = ss.curr_sched_clock + cycles;
	  if (get_attr_type (insn) == TYPE_BRANCH
	      || get_attr_type (insn) == TYPE_CALL)
	    {
	      rtx opposite = condjump_opposite_condition (insn);
	      record_jump (ss.curr_sched_clock + cycles, opposite);
	    }

	  /* Mark the cycles in which the destination registers are written.
	     This is used for calculating stalls when using cross units.  */
	  extract_insn (insn);
	  /* Cross-path stalls don't apply to results of load insns.  */
	  if (get_attr_type (insn) == TYPE_LOAD
	      || get_attr_type (insn) == TYPE_LOADN
	      || get_attr_type (insn) == TYPE_LOAD_SHADOW)
	    cycles--;
	  for (i = 0; i < recog_data.n_operands; i++)
	    {
	      rtx op = recog_data.operand[i];
	      if (MEM_P (op))
		{
		  rtx addr = XEXP (op, 0);
		  if (GET_RTX_CLASS (GET_CODE (addr)) == RTX_AUTOINC)
		    c6x_mark_reg_written (XEXP (addr, 0),
					  insn_uid_get_clock (uid) + 1);
		}
	      if (recog_data.operand_type[i] != OP_IN
		  && REG_P (op))
		{
		  c6x_mark_reg_written (op,
					insn_uid_get_clock (uid) + cycles);
		}
	    }
	}
    }
  return can_issue_more;
}

/* Implement the TARGET_SCHED_ADJUST_COST hook.  We need special handling for
   anti- and output dependencies.  */

static int
c6x_adjust_cost (rtx_insn *insn, int dep_type, rtx_insn *dep_insn, int cost,
		 unsigned int)
{
  enum attr_type insn_type = TYPE_UNKNOWN, dep_insn_type = TYPE_UNKNOWN;
  int dep_insn_code_number, insn_code_number;
  int shadow_bonus = 0;
  enum reg_note kind;
  dep_insn_code_number = recog_memoized (dep_insn);
  insn_code_number = recog_memoized (insn);

  if (dep_insn_code_number >= 0)
    dep_insn_type = get_attr_type (dep_insn);

  if (insn_code_number >= 0)
    insn_type = get_attr_type (insn);

  kind = (reg_note) dep_type;
  if (kind == 0)
    {
      /* If we have a dependency on a load, and it's not for the result of
	 the load, it must be for an autoincrement.  Reduce the cost in that
	 case.  */
      if (dep_insn_type == TYPE_LOAD)
	{
	  rtx set = PATTERN (dep_insn);
	  if (GET_CODE (set) == COND_EXEC)
	    set = COND_EXEC_CODE (set);
	  if (GET_CODE (set) == UNSPEC)
	    cost = 1;
	  else
	    {
	      gcc_assert (GET_CODE (set) == SET);
	      if (!reg_overlap_mentioned_p (SET_DEST (set), PATTERN (insn)))
		cost = 1;
	    }
	}
    }

  /* A jump shadow needs to have its latency decreased by one.  Conceptually,
     it occurs in between two cycles, but we schedule it at the end of the
     first cycle.  */
  if (shadow_type_p (insn_type))
    shadow_bonus = 1;

  /* Anti and output dependencies usually have zero cost, but we want
     to insert a stall after a jump, and after certain floating point
     insns that take more than one cycle to read their inputs.  In the
     future, we should try to find a better algorithm for scheduling
     jumps.  */
  if (kind != 0)
    {
      /* We can get anti-dependencies against shadow insns.  Treat these
	 like output dependencies, so that the insn is entirely finished
	 before the branch takes place.  */
      if (kind == REG_DEP_ANTI && insn_type == TYPE_SHADOW)
	kind = REG_DEP_OUTPUT;
      switch (dep_insn_type)
	{
	case TYPE_CALLP:
	  return 1;
	case TYPE_BRANCH:
	case TYPE_CALL:
	  if (get_attr_has_shadow (dep_insn) == HAS_SHADOW_Y)
	    /* This is a real_jump/real_call insn.  These don't have
	       outputs, and ensuring the validity of scheduling things
	       in the delay slot is the job of
	       c6x_sched_reorder_1.  */
	    return 0;
	  /* Unsplit calls can happen - e.g. for divide insns.  */
	  return 6;
	case TYPE_LOAD:
	case TYPE_LOADN:
	case TYPE_INTDP:
	  if (kind == REG_DEP_OUTPUT)
	    return 5 - shadow_bonus;
	  return 0;
	case TYPE_MPY4:
	case TYPE_FP4:
	  if (kind == REG_DEP_OUTPUT)
	    return 4 - shadow_bonus;
	  return 0;
	case TYPE_MPY2:
	  if (kind == REG_DEP_OUTPUT)
	    return 2 - shadow_bonus;
	  return 0;
	case TYPE_CMPDP:
	  if (kind == REG_DEP_OUTPUT)
	    return 2 - shadow_bonus;
	  return 2;
	case TYPE_ADDDP:
	case TYPE_MPYSPDP:
	  if (kind == REG_DEP_OUTPUT)
	    return 7 - shadow_bonus;
	  return 2;
	case TYPE_MPYSP2DP:
	  if (kind == REG_DEP_OUTPUT)
	    return 5 - shadow_bonus;
	  return 2;
	case TYPE_MPYI:
	  if (kind == REG_DEP_OUTPUT)
	    return 9 - shadow_bonus;
	  return 4;
	case TYPE_MPYID:
	case TYPE_MPYDP:
	  if (kind == REG_DEP_OUTPUT)
	    return 10 - shadow_bonus;
	  return 4;

	default:
	  if (insn_type == TYPE_SPKERNEL)
	    return 0;
	  if (kind == REG_DEP_OUTPUT)
	    return 1 - shadow_bonus;

	  return 0;
	}
    }

  return cost - shadow_bonus;
}

/* Create a SEQUENCE rtx to replace the instructions in SLOT, of which there
   are N_FILLED.  REAL_FIRST identifies the slot if the insn that appears
   first in the original stream.  */

static void
gen_one_bundle (rtx_insn **slot, int n_filled, int real_first)
{
  rtx seq;
  rtx_insn *bundle;
  rtx_insn *t;
  int i;

  seq = gen_rtx_SEQUENCE (VOIDmode, gen_rtvec_v (n_filled, slot));
  bundle = make_insn_raw (seq);
  BLOCK_FOR_INSN (bundle) = BLOCK_FOR_INSN (slot[0]);
  INSN_LOCATION (bundle) = INSN_LOCATION (slot[0]);
  SET_PREV_INSN (bundle) = SET_PREV_INSN (slot[real_first]);

  t = NULL;

  for (i = 0; i < n_filled; i++)
    {
      rtx_insn *insn = slot[i];
      remove_insn (insn);
      SET_PREV_INSN (insn) = t ? t : PREV_INSN (bundle);
      if (t != NULL_RTX)
	SET_NEXT_INSN (t) = insn;
      t = insn;
      if (i > 0)
	INSN_LOCATION (slot[i]) = INSN_LOCATION (bundle);
    }

  SET_NEXT_INSN (bundle) = NEXT_INSN (PREV_INSN (bundle));
  SET_NEXT_INSN (t) = NEXT_INSN (bundle);
  SET_NEXT_INSN (PREV_INSN (bundle)) = bundle;
  SET_PREV_INSN (NEXT_INSN (bundle)) = bundle;
}

/* Move all parallel instructions into SEQUENCEs, so that no subsequent passes
   try to insert labels in the middle.  */

static void
c6x_gen_bundles (void)
{
  basic_block bb;

  FOR_EACH_BB_FN (bb, cfun)
    {
      rtx_insn *insn, *next;
      /* The machine is eight insns wide.  We can have up to six shadow
	 insns, plus an extra slot for merging the jump shadow.  */
      rtx_insn *slot[15];
      int n_filled = 0;
      int first_slot = 0;

      for (insn = BB_HEAD (bb);; insn = next)
	{
	  int at_end;
	  rtx delete_this = NULL_RTX;

	  if (NONDEBUG_INSN_P (insn))
	    {
	      /* Put calls at the start of the sequence.  */
	      if (CALL_P (insn))
		{
		  first_slot++;
		  if (n_filled)
		    {
		      memmove (&slot[1], &slot[0],
			       n_filled * sizeof (slot[0]));
		    }
		  if (!shadow_p (insn))
		    {
		      PUT_MODE (insn, TImode);
		      if (n_filled)
			PUT_MODE (slot[1], VOIDmode);
		    }
		  n_filled++;
		  slot[0] = insn;
		}
	      else
		{
		  slot[n_filled++] = insn;
		}
	    }

	  next = NEXT_INSN (insn);
	  while (next && insn != BB_END (bb)
		 && !(NONDEBUG_INSN_P (next)
		      && GET_CODE (PATTERN (next)) != USE
		      && GET_CODE (PATTERN (next)) != CLOBBER))
	    {
	      insn = next;
	      next = NEXT_INSN (insn);
	    }

	  at_end = insn == BB_END (bb);
	  if (delete_this == NULL_RTX
	      && (at_end || (GET_MODE (next) == TImode
			     && !(shadow_p (next) && CALL_P (next)))))
	    {
	      if (n_filled >= 2)
		gen_one_bundle (slot, n_filled, first_slot);

	      n_filled = 0;
	      first_slot = 0;
	    }
	  if (at_end)
	    break;
	}
    }
}

/* Emit a NOP instruction for CYCLES cycles after insn AFTER.  Return it.  */

static rtx_insn *
emit_nop_after (int cycles, rtx_insn *after)
{
  rtx_insn *insn;

  /* mpydp has 9 delay slots, and we may schedule a stall for a cross-path
     operation.  We don't need the extra NOP since in this case, the hardware
     will automatically insert the required stall.  */
  if (cycles == 10)
    cycles--;

  gcc_assert (cycles < 10);

  insn = emit_insn_after (gen_nop_count (GEN_INT (cycles)), after);
  PUT_MODE (insn, TImode);

  return insn;
}

/* Determine whether INSN is a call that needs to have a return label
   placed.  */

static bool
returning_call_p (rtx_insn *insn)
{
  if (CALL_P (insn))
    return (!SIBLING_CALL_P (insn)
	    && get_attr_type (insn) != TYPE_CALLP
	    && get_attr_type (insn) != TYPE_SHADOW);
  if (recog_memoized (insn) < 0)
    return false;
  if (get_attr_type (insn) == TYPE_CALL)
    return true;
  return false;
}

/* Determine whether INSN's pattern can be converted to use callp.  */
static bool
can_use_callp (rtx_insn *insn)
{
  int icode = recog_memoized (insn);
  if (!TARGET_INSNS_64PLUS
      || icode < 0
      || GET_CODE (PATTERN (insn)) == COND_EXEC)
    return false;

  return ((icode == CODE_FOR_real_call
	   || icode == CODE_FOR_call_internal
	   || icode == CODE_FOR_call_value_internal)
	  && get_attr_dest_regfile (insn) == DEST_REGFILE_ANY);
}

/* Convert the pattern of INSN, which must be a CALL_INSN, into a callp.  */
static void
convert_to_callp (rtx_insn *insn)
{
  rtx lab;
  extract_insn (insn);
  if (GET_CODE (PATTERN (insn)) == SET)
    {
      rtx dest = recog_data.operand[0];
      lab = recog_data.operand[1];
      PATTERN (insn) = gen_callp_value (dest, lab);
      INSN_CODE (insn) = CODE_FOR_callp_value;
    }
  else
    {
      lab = recog_data.operand[0];
      PATTERN (insn) = gen_callp (lab);
      INSN_CODE (insn) = CODE_FOR_callp;
    }
}

/* Scan forwards from INSN until we find the next insn that has mode TImode
   (indicating it starts a new cycle), and occurs in cycle CLOCK.
   Return it if we find such an insn, NULL_RTX otherwise.  */
static rtx_insn *
find_next_cycle_insn (rtx_insn *insn, int clock)
{
  rtx_insn *t = insn;
  if (GET_MODE (t) == TImode)
    t = next_real_insn (t);
  while (t && GET_MODE (t) != TImode)
    t = next_real_insn (t);

  if (t && insn_get_clock (t) == clock)
    return t;
  return NULL;
}

/* If COND_INSN has a COND_EXEC condition, wrap the same condition
   around PAT.  Return PAT either unchanged or modified in this
   way.  */
static rtx
duplicate_cond (rtx pat, rtx cond_insn)
{
  rtx cond_pat = PATTERN (cond_insn);
  if (GET_CODE (cond_pat) == COND_EXEC)
    pat = gen_rtx_COND_EXEC (VOIDmode, copy_rtx (COND_EXEC_TEST (cond_pat)),
			     pat);
  return pat;
}

/* Walk forward from INSN to find the last insn that issues in the same clock
   cycle.  */
static rtx_insn *
find_last_same_clock (rtx_insn *insn)
{
  rtx_insn *retval = insn;
  rtx_insn *t = next_real_insn (insn);

  while (t && GET_MODE (t) != TImode)
    {
      if (!DEBUG_INSN_P (t) && recog_memoized (t) >= 0)
	retval = t;
      t = next_real_insn (t);
    }
  return retval;
}

/* For every call insn in the function, emit code to load the return
   address.  For each call we create a return label and store it in
   CALL_LABELS.  If are not scheduling, we emit the labels here,
   otherwise the caller will do it later.
   This function is called after final insn scheduling, but before creating
   the SEQUENCEs that represent execute packets.  */

static void
reorg_split_calls (rtx_code_label **call_labels)
{
  unsigned int reservation_mask = 0;
  rtx_insn *insn = get_insns ();
  gcc_assert (NOTE_P (insn));
  insn = next_real_insn (insn);
  while (insn)
    {
      int uid;
      rtx_insn *next = next_real_insn (insn);

      if (DEBUG_INSN_P (insn))
	goto done;

      if (GET_MODE (insn) == TImode)
	reservation_mask = 0;
      uid = INSN_UID (insn);
      if (c6x_flag_schedule_insns2 && recog_memoized (insn) >= 0)
	reservation_mask |= 1 << INSN_INFO_ENTRY (uid).reservation;

      if (returning_call_p (insn))
	{
	  rtx_code_label *label = gen_label_rtx ();
	  rtx labelref = gen_rtx_LABEL_REF (Pmode, label);
	  rtx reg = gen_rtx_REG (SImode, RETURN_ADDR_REGNO);

	  LABEL_NUSES (label) = 2;
	  if (!c6x_flag_schedule_insns2)
	    {
	      if (can_use_callp (insn))
		convert_to_callp (insn);
	      else
		{
		  rtx t;
		  rtx_insn *slot[4];
		  emit_label_after (label, insn);

		  /* Bundle the call and its delay slots into a single
		     SEQUENCE.  While these do not issue in parallel
		     we need to group them into a single EH region.  */
		  slot[0] = insn;
		  PUT_MODE (insn, TImode);
		  if (TARGET_INSNS_64)
		    {
		      t = gen_addkpc (reg, labelref, GEN_INT (4));
		      slot[1] = emit_insn_after (duplicate_cond (t, insn),
						 insn);
		      PUT_MODE (slot[1], TImode);
		      gen_one_bundle (slot, 2, 0);
		    }
		  else
		    {
		      slot[3] = emit_insn_after (gen_nop_count (GEN_INT (3)),
						 insn);
		      PUT_MODE (slot[3], TImode);
		      t = gen_movsi_lo_sum (reg, reg, labelref);
		      slot[2] = emit_insn_after (duplicate_cond (t, insn),
						  insn);
		      PUT_MODE (slot[2], TImode);
		      t = gen_movsi_high (reg, labelref);
		      slot[1] = emit_insn_after (duplicate_cond (t, insn),
						 insn);
		      PUT_MODE (slot[1], TImode);
		      gen_one_bundle (slot, 4, 0);
		    }
		}
	    }
	  else
	    {
	      /* If we scheduled, we reserved the .S2 unit for one or two
		 cycles after the call.  Emit the insns in these slots,
		 unless it's possible to create a CALLP insn.
		 Note that this works because the dependencies ensure that
		 no insn setting/using B3 is scheduled in the delay slots of
		 a call.  */
	      int this_clock = insn_get_clock (insn);
	      rtx_insn *after1;

	      call_labels[INSN_UID (insn)] = label;

	      rtx_insn *last_same_clock = find_last_same_clock (insn);

	      if (can_use_callp (insn))
		{
		  /* Find the first insn of the next execute packet.  If it
		     is the shadow insn corresponding to this call, we may
		     use a CALLP insn.  */
		  rtx_insn *shadow =
		    next_nonnote_nondebug_insn (last_same_clock);

		  if (CALL_P (shadow)
		      && insn_get_clock (shadow) == this_clock + 5)
		    {
		      convert_to_callp (shadow);
		      insn_set_clock (shadow, this_clock);
		      INSN_INFO_ENTRY (INSN_UID (shadow)).reservation
			= RESERVATION_S2;
		      INSN_INFO_ENTRY (INSN_UID (shadow)).unit_mask
			= INSN_INFO_ENTRY (INSN_UID (last_same_clock)).unit_mask;
		      if (GET_MODE (insn) == TImode)
			{
			  rtx_insn *new_cycle_first = NEXT_INSN (insn);
			  while (!NONDEBUG_INSN_P (new_cycle_first)
				 || GET_CODE (PATTERN (new_cycle_first)) == USE
				 || GET_CODE (PATTERN (new_cycle_first)) == CLOBBER)
			    new_cycle_first = NEXT_INSN (new_cycle_first);
			  PUT_MODE (new_cycle_first, TImode);
			  if (new_cycle_first != shadow)
			    PUT_MODE (shadow, VOIDmode);
			  INSN_INFO_ENTRY (INSN_UID (new_cycle_first)).ebb_start
			    = INSN_INFO_ENTRY (INSN_UID (insn)).ebb_start;
			}
		      else
			PUT_MODE (shadow, VOIDmode);
		      delete_insn (insn);
		      goto done;
		    }
		}
	      after1 = find_next_cycle_insn (last_same_clock, this_clock + 1);
	      if (after1 == NULL_RTX)
		after1 = last_same_clock;
	      else
		after1 = find_last_same_clock (after1);
	      if (TARGET_INSNS_64)
		{
		  rtx x1 = gen_addkpc (reg, labelref, const0_rtx);
		  x1 = emit_insn_after (duplicate_cond (x1, insn), after1);
		  insn_set_clock (x1, this_clock + 1);
		  INSN_INFO_ENTRY (INSN_UID (x1)).reservation = RESERVATION_S2;
		  if (after1 == last_same_clock)
		    PUT_MODE (x1, TImode);
		  else
		    INSN_INFO_ENTRY (INSN_UID (x1)).unit_mask
		      = INSN_INFO_ENTRY (INSN_UID (after1)).unit_mask;
		}
	      else
		{
		  rtx x1, x2;
		  rtx_insn *after2 = find_next_cycle_insn (after1,
							   this_clock + 2);
		  if (after2 == NULL_RTX)
		    after2 = after1;
		  x2 = gen_movsi_lo_sum (reg, reg, labelref);
		  x2 = emit_insn_after (duplicate_cond (x2, insn), after2);
		  x1 = gen_movsi_high (reg, labelref);
		  x1 = emit_insn_after (duplicate_cond (x1, insn), after1);
		  insn_set_clock (x1, this_clock + 1);
		  insn_set_clock (x2, this_clock + 2);
		  INSN_INFO_ENTRY (INSN_UID (x1)).reservation = RESERVATION_S2;
		  INSN_INFO_ENTRY (INSN_UID (x2)).reservation = RESERVATION_S2;
		  if (after1 == last_same_clock)
		    PUT_MODE (x1, TImode);
		  else
		    INSN_INFO_ENTRY (INSN_UID (x1)).unit_mask
		      = INSN_INFO_ENTRY (INSN_UID (after1)).unit_mask;
		  if (after1 == after2)
		    PUT_MODE (x2, TImode);
		  else
		    INSN_INFO_ENTRY (INSN_UID (x2)).unit_mask
		      = INSN_INFO_ENTRY (INSN_UID (after2)).unit_mask;
		}
	    }
	}
    done:
      insn = next;
    }
}

/* Called as part of c6x_reorg.  This function emits multi-cycle NOP
   insns as required for correctness.  CALL_LABELS is the array that
   holds the return labels for call insns; we emit these here if
   scheduling was run earlier.  */

static void
reorg_emit_nops (rtx_code_label **call_labels)
{
  bool first;
  rtx last_call;
  rtx_insn *prev;
  int prev_clock, earliest_bb_end;
  int prev_implicit_nops;
  rtx_insn *insn = get_insns ();

  /* We look at one insn (or bundle inside a sequence) in each iteration, storing
     its issue time in PREV_CLOCK for the next iteration.  If there is a gap in
     clocks, we must insert a NOP.
     EARLIEST_BB_END tracks in which cycle all insns that have been issued in the
     current basic block will finish.  We must not allow the next basic block to
     begin before this cycle.
     PREV_IMPLICIT_NOPS tells us whether we've seen an insn that implicitly contains
     a multi-cycle nop.  The code is scheduled such that subsequent insns will
     show the cycle gap, but we needn't insert a real NOP instruction.  */
  insn = next_real_insn (insn);
  last_call = prev = NULL;
  prev_clock = -1;
  earliest_bb_end = 0;
  prev_implicit_nops = 0;
  first = true;
  while (insn)
    {
      int this_clock = -1;
      rtx_insn *next;
      int max_cycles = 0;

      next = next_real_insn (insn);

      if (DEBUG_INSN_P (insn)
	  || GET_CODE (PATTERN (insn)) == USE
	  || GET_CODE (PATTERN (insn)) == CLOBBER
	  || shadow_or_blockage_p (insn)
	  || JUMP_TABLE_DATA_P (insn))
	goto next_insn;

      if (!c6x_flag_schedule_insns2)
	/* No scheduling; ensure that no parallel issue happens.  */
	PUT_MODE (insn, TImode);
      else
	{
	  int cycles;

	  this_clock = insn_get_clock (insn);
	  if (this_clock != prev_clock)
	    {
	      PUT_MODE (insn, TImode);

	      if (!first)
		{
		  cycles = this_clock - prev_clock;

		  cycles -= prev_implicit_nops;
		  if (cycles > 1)
		    {
		      rtx nop = emit_nop_after (cycles - 1, prev);
		      insn_set_clock (nop, prev_clock + prev_implicit_nops + 1);
		    }
		}
	      prev_clock = this_clock;

	      if (last_call
		  && insn_get_clock (last_call) + 6 <= this_clock)
		{
		  emit_label_before (call_labels[INSN_UID (last_call)], insn);
		  last_call = NULL_RTX;
		}
	      prev_implicit_nops = 0;
	    }
	}

      /* Examine how many cycles the current insn takes, and adjust
	 LAST_CALL, EARLIEST_BB_END and PREV_IMPLICIT_NOPS.  */
      if (recog_memoized (insn) >= 0
	  /* If not scheduling, we've emitted NOPs after calls already.  */
	  && (c6x_flag_schedule_insns2 || !returning_call_p (insn)))
	{
	  max_cycles = get_attr_cycles (insn);
	  if (get_attr_type (insn) == TYPE_CALLP)
	    prev_implicit_nops = 5;
	}
      else
	max_cycles = 1;
      if (returning_call_p (insn))
	last_call = insn;

      if (c6x_flag_schedule_insns2)
	{
	  gcc_assert (this_clock >= 0);
	  if (earliest_bb_end < this_clock + max_cycles)
	    earliest_bb_end = this_clock + max_cycles;
	}
      else if (max_cycles > 1)
	emit_nop_after (max_cycles - 1, insn);

      prev = insn;
      first = false;

    next_insn:
      if (c6x_flag_schedule_insns2
	  && (next == NULL_RTX
	      || (GET_MODE (next) == TImode
		  && INSN_INFO_ENTRY (INSN_UID (next)).ebb_start))
	  && earliest_bb_end > 0)
	{
	  int cycles = earliest_bb_end - prev_clock;
	  if (cycles > 1)
	    {
	      prev = emit_nop_after (cycles - 1, prev);
	      insn_set_clock (prev, prev_clock + prev_implicit_nops + 1);
	    }
	  earliest_bb_end = 0;
	  prev_clock = -1;
	  first = true;

	  if (last_call)
	    emit_label_after (call_labels[INSN_UID (last_call)], prev);
	  last_call = NULL_RTX;
	}
      insn = next;
    }
}

/* If possible, split INSN, which we know is either a jump or a call, into a real
   insn and its shadow.  */
static void
split_delayed_branch (rtx_insn *insn)
{
  int code = recog_memoized (insn);
  rtx_insn *i1;
  rtx newpat;
  rtx pat = PATTERN (insn);

  if (GET_CODE (pat) == COND_EXEC)
    pat = COND_EXEC_CODE (pat);

  if (CALL_P (insn))
    {
      rtx src = pat, dest = NULL_RTX;
      rtx callee;
      if (GET_CODE (pat) == SET)
	{
	  dest = SET_DEST (pat);
	  src = SET_SRC (pat);
	}
      callee = XEXP (XEXP (src, 0), 0);
      if (SIBLING_CALL_P (insn))
	{
	  if (REG_P (callee))
	    newpat = gen_indirect_sibcall_shadow ();
	  else
	    newpat = gen_sibcall_shadow (callee);
	  pat = gen_real_jump (callee);
	}
      else if (dest != NULL_RTX)
	{
	  if (REG_P (callee))
	    newpat = gen_indirect_call_value_shadow (dest);
	  else
	    newpat = gen_call_value_shadow (dest, callee);
	  pat = gen_real_call (callee);
	}
      else
	{
	  if (REG_P (callee))
	    newpat = gen_indirect_call_shadow ();
	  else
	    newpat = gen_call_shadow (callee);
	  pat = gen_real_call (callee);
	}
      pat = duplicate_cond (pat, insn);
      newpat = duplicate_cond (newpat, insn);
    }
  else
    {
      rtx src, op;
      if (GET_CODE (pat) == PARALLEL
	  && GET_CODE (XVECEXP (pat, 0, 0)) == RETURN)
	{
	  newpat = gen_return_shadow ();
	  pat = gen_real_ret (XEXP (XVECEXP (pat, 0, 1), 0));
	  newpat = duplicate_cond (newpat, insn);
	}
      else
	switch (code)
	  {
	  case CODE_FOR_br_true:
	  case CODE_FOR_br_false:
	    src = SET_SRC (pat);
	    op = XEXP (src, code == CODE_FOR_br_true ? 1 : 2);
	    newpat = gen_condjump_shadow (op);
	    pat = gen_real_jump (op);
	    if (code == CODE_FOR_br_true)
	      pat = gen_rtx_COND_EXEC (VOIDmode, XEXP (src, 0), pat);
	    else
	      pat = gen_rtx_COND_EXEC (VOIDmode,
				       reversed_comparison (XEXP (src, 0),
							    VOIDmode),
				       pat);
	    break;

	  case CODE_FOR_jump:
	    op = SET_SRC (pat);
	    newpat = gen_jump_shadow (op);
	    break;

	  case CODE_FOR_indirect_jump:
	    newpat = gen_indirect_jump_shadow ();
	    break;

	  case CODE_FOR_return_internal:
	    newpat = gen_return_shadow ();
	    pat = gen_real_ret (XEXP (XVECEXP (pat, 0, 1), 0));
	    break;

	  default:
	    return;
	  }
    }
  i1 = emit_insn_before (pat, insn);
  PATTERN (insn) = newpat;
  INSN_CODE (insn) = -1;
  record_delay_slot_pair (i1, insn, 5, 0);
}

/* If INSN is a multi-cycle insn that should be handled properly in
   modulo-scheduling, split it into a real insn and a shadow.
   Return true if we made a change.

   It is valid for us to fail to split an insn; the caller has to deal
   with the possibility.  Currently we handle loads and most mpy2 and
   mpy4 insns.  */
static bool
split_delayed_nonbranch (rtx_insn *insn)
{
  int code = recog_memoized (insn);
  enum attr_type type;
  rtx_insn *i1;
  rtx newpat, src, dest;
  rtx pat = PATTERN (insn);
  rtvec rtv;
  int delay;

  if (GET_CODE (pat) == COND_EXEC)
    pat = COND_EXEC_CODE (pat);

  if (code < 0 || GET_CODE (pat) != SET)
    return false;
  src = SET_SRC (pat);
  dest = SET_DEST (pat);
  if (!REG_P (dest))
    return false;

  type = get_attr_type (insn);
  if (code >= 0
      && (type == TYPE_LOAD
	  || type == TYPE_LOADN))
    {
      if (!MEM_P (src)
	  && (GET_CODE (src) != ZERO_EXTEND
	      || !MEM_P (XEXP (src, 0))))
	return false;

      if (GET_MODE_SIZE (GET_MODE (dest)) > 4
	  && (GET_MODE_SIZE (GET_MODE (dest)) != 8 || !TARGET_LDDW))
	return false;

      rtv = gen_rtvec (2, GEN_INT (REGNO (SET_DEST (pat))),
		       SET_SRC (pat));
      newpat = gen_load_shadow (SET_DEST (pat));
      pat = gen_rtx_UNSPEC (VOIDmode, rtv, UNSPEC_REAL_LOAD);
      delay = 4;
    }
  else if (code >= 0
	   && (type == TYPE_MPY2
	       || type == TYPE_MPY4))
    {
      /* We don't handle floating point multiplies yet.  */
      if (GET_MODE (dest) == SFmode)
	return false;

      rtv = gen_rtvec (2, GEN_INT (REGNO (SET_DEST (pat))),
		       SET_SRC (pat));
      newpat = gen_mult_shadow (SET_DEST (pat));
      pat = gen_rtx_UNSPEC (VOIDmode, rtv, UNSPEC_REAL_MULT);
      delay = type == TYPE_MPY2 ? 1 : 3;
    }
  else
    return false;

  pat = duplicate_cond (pat, insn);
  newpat = duplicate_cond (newpat, insn);
  i1 = emit_insn_before (pat, insn);
  PATTERN (insn) = newpat;
  INSN_CODE (insn) = -1;
  recog_memoized (insn);
  recog_memoized (i1);
  record_delay_slot_pair (i1, insn, delay, 0);
  return true;
}

/* Examine if INSN is the result of splitting a load into a real load and a
   shadow, and if so, undo the transformation.  */
static void
undo_split_delayed_nonbranch (rtx_insn *insn)
{
  int icode = recog_memoized (insn);
  enum attr_type type;
  rtx prev_pat, insn_pat;
  rtx_insn *prev;

  if (icode < 0)
    return;
  type = get_attr_type (insn);
  if (type != TYPE_LOAD_SHADOW && type != TYPE_MULT_SHADOW)
    return;
  prev = PREV_INSN (insn);
  prev_pat = PATTERN (prev);
  insn_pat = PATTERN (insn);
  if (GET_CODE (prev_pat) == COND_EXEC)
    {
      prev_pat = COND_EXEC_CODE (prev_pat);
      insn_pat = COND_EXEC_CODE (insn_pat);
    }

  gcc_assert (GET_CODE (prev_pat) == UNSPEC
	      && ((XINT (prev_pat, 1) == UNSPEC_REAL_LOAD
		   && type == TYPE_LOAD_SHADOW)
		  || (XINT (prev_pat, 1) == UNSPEC_REAL_MULT
		      && type == TYPE_MULT_SHADOW)));
  insn_pat = gen_rtx_SET (SET_DEST (insn_pat),
			  XVECEXP (prev_pat, 0, 1));
  insn_pat = duplicate_cond (insn_pat, prev);
  PATTERN (insn) = insn_pat;
  INSN_CODE (insn) = -1;
  delete_insn (prev);
}

/* Split every insn (i.e. jumps and calls) which can have delay slots into
   two parts: the first one is scheduled normally and emits the instruction,
   while the second one is a shadow insn which shows the side effect taking
   place. The second one is placed in the right cycle by the scheduler, but
   not emitted as an assembly instruction.  */

static void
split_delayed_insns (void)
{
  rtx_insn *insn;
  for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
    {
      if (JUMP_P (insn) || CALL_P (insn))
	split_delayed_branch (insn);
    }
}

/* For every insn that has an entry in the new_conditions vector, give it
   the appropriate predicate.  */
static void
conditionalize_after_sched (void)
{
  basic_block bb;
  rtx_insn *insn;
  FOR_EACH_BB_FN (bb, cfun)
    FOR_BB_INSNS (bb, insn)
      {
	unsigned uid = INSN_UID (insn);
	rtx cond;
	if (!NONDEBUG_INSN_P (insn) || uid >= INSN_INFO_LENGTH)
	  continue;
	cond = INSN_INFO_ENTRY (uid).new_cond;
	if (cond == NULL_RTX)
	  continue;
	if (dump_file)
	  fprintf (dump_file, "Conditionalizing insn %d\n", uid);
	predicate_insn (insn, cond, true);
      }
}

/* A callback for the hw-doloop pass.  This function examines INSN; if
   it is a loop_end pattern we recognize, return the reg rtx for the
   loop counter.  Otherwise, return NULL_RTX.  */

static rtx
hwloop_pattern_reg (rtx_insn *insn)
{
  rtx pat, reg;

  if (!JUMP_P (insn) || recog_memoized (insn) != CODE_FOR_loop_end)
    return NULL_RTX;

  pat = PATTERN (insn);
  reg = SET_DEST (XVECEXP (pat, 0, 1));
  if (!REG_P (reg))
    return NULL_RTX;
  return reg;
}

/* Return the number of cycles taken by BB, as computed by scheduling,
   including the latencies of all insns with delay slots.  IGNORE is
   an insn we should ignore in the calculation, usually the final
   branch.  */
static int
bb_earliest_end_cycle (basic_block bb, rtx ignore)
{
  int earliest = 0;
  rtx_insn *insn;

  FOR_BB_INSNS (bb, insn)
    {
      int cycles, this_clock;

      if (LABEL_P (insn) || NOTE_P (insn) || DEBUG_INSN_P (insn)
	  || GET_CODE (PATTERN (insn)) == USE
	  || GET_CODE (PATTERN (insn)) == CLOBBER
	  || insn == ignore)
	continue;

      this_clock = insn_get_clock (insn);
      cycles = get_attr_cycles (insn);

      if (earliest < this_clock + cycles)
	earliest = this_clock + cycles;
    }
  return earliest;
}

/* Examine the insns in BB and remove all which have a uid greater or
   equal to MAX_UID.  */
static void
filter_insns_above (basic_block bb, int max_uid)
{
  rtx_insn *insn, *next;
  bool prev_ti = false;
  int prev_cycle = -1;

  FOR_BB_INSNS_SAFE (bb, insn, next)
    {
      int this_cycle;
      if (!NONDEBUG_INSN_P (insn))
	continue;
      if (insn == BB_END (bb))
	return;
      this_cycle = insn_get_clock (insn);
      if (prev_ti && this_cycle == prev_cycle)
	{
	  gcc_assert (GET_MODE (insn) != TImode);
	  PUT_MODE (insn, TImode);
	}
      prev_ti = false;
      if (INSN_UID (insn) >= max_uid)
	{
	  if (GET_MODE (insn) == TImode)
	    {
	      prev_ti = true;
	      prev_cycle = this_cycle;
	    }
	  delete_insn (insn);
	}
    }
}

/* Implement TARGET_ASM_EMIT_EXCEPT_PERSONALITY.  */

static void
c6x_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);
}

/* Use a special assembly directive rather than a regular setion for
   unwind table data.  */

static void
c6x_asm_init_sections (void)
{
  exception_section = get_unnamed_section (0, output_section_asm_op,
					   "\t.handlerdata");
}

/* A callback for the hw-doloop pass.  Called to optimize LOOP in a
   machine-specific fashion; returns true if successful and false if
   the hwloop_fail function should be called.  */

static bool
hwloop_optimize (hwloop_info loop)
{
  basic_block entry_bb, bb;
  rtx_insn *seq, *insn, *prev, *entry_after, *end_packet;
  rtx_insn *head_insn, *tail_insn, *new_insns, *last_insn;
  int loop_earliest;
  int n_execute_packets;
  edge entry_edge;
  unsigned ix;
  int max_uid_before, delayed_splits;
  int i, sp_ii, min_ii, max_ii, max_parallel, n_insns, n_real_insns, stages;
  rtx_insn **orig_vec;
  rtx_insn **copies;
  rtx_insn ***insn_copies;

  if (!c6x_flag_modulo_sched || !c6x_flag_schedule_insns2
      || !TARGET_INSNS_64PLUS)
    return false;

  if (loop->iter_reg_used || loop->depth > 1)
    return false;
  if (loop->has_call || loop->has_asm)
    return false;

  if (loop->head != loop->tail)
    return false;

  gcc_assert (loop->incoming_dest == loop->head);

  entry_edge = NULL;
  FOR_EACH_VEC_SAFE_ELT (loop->incoming, i, entry_edge)
    if (entry_edge->flags & EDGE_FALLTHRU)
      break;
  if (entry_edge == NULL)
    return false;

  reshuffle_units (loop->head);

  in_hwloop = true;
  schedule_ebbs_init ();
  schedule_ebb (BB_HEAD (loop->tail), loop->loop_end, true);
  schedule_ebbs_finish ();
  in_hwloop = false;

  bb = loop->head;
  loop_earliest = bb_earliest_end_cycle (bb, loop->loop_end) + 1;

  max_uid_before = get_max_uid ();

  /* Split all multi-cycle operations, such as loads.  For normal
     scheduling, we only do this for branches, as the generated code
     would otherwise not be interrupt-safe.  When using sploop, it is
     safe and beneficial to split them.  If any multi-cycle operations
     remain after splitting (because we don't handle them yet), we
     cannot pipeline the loop.  */
  delayed_splits = 0;
  FOR_BB_INSNS (bb, insn)
    {
      if (NONDEBUG_INSN_P (insn))
	{
	  recog_memoized (insn);
	  if (split_delayed_nonbranch (insn))
	    delayed_splits++;
	  else if (INSN_CODE (insn) >= 0
		   && get_attr_cycles (insn) > 1)
	    goto undo_splits;
	}
    }

  /* Count the number of insns as well as the number real insns, and save
     the original sequence of insns in case we must restore it later.  */
  n_insns = n_real_insns = 0;
  FOR_BB_INSNS (bb, insn)
    {
      n_insns++;
      if (NONDEBUG_INSN_P (insn) && insn != loop->loop_end)
	n_real_insns++;
    }
  orig_vec = XNEWVEC (rtx_insn *, n_insns);
  n_insns = 0;
  FOR_BB_INSNS (bb, insn)
    orig_vec[n_insns++] = insn;

  /* Count the unit reservations, and compute a minimum II from that
     table.  */
  count_unit_reqs (unit_reqs, loop->start_label,
		   PREV_INSN (loop->loop_end));
  merge_unit_reqs (unit_reqs);

  min_ii = res_mii (unit_reqs);
  max_ii = loop_earliest < 15 ? loop_earliest : 14;

  /* Make copies of the loop body, up to a maximum number of stages we want
     to handle.  */
  max_parallel = loop_earliest / min_ii + 1;

  copies = XCNEWVEC (rtx_insn *, (max_parallel + 1) * n_real_insns);
  insn_copies = XNEWVEC (rtx_insn **, max_parallel + 1);
  for (i = 0; i < max_parallel + 1; i++)
    insn_copies[i] = copies + i * n_real_insns;

  head_insn = next_nonnote_nondebug_insn (loop->start_label);
  tail_insn = prev_real_insn (BB_END (bb));

  i = 0;
  FOR_BB_INSNS (bb, insn)
    if (NONDEBUG_INSN_P (insn) && insn != loop->loop_end)
      insn_copies[0][i++] = insn;

  sploop_max_uid_iter0 = get_max_uid ();

  /* Generate the copies of the loop body, and save them in the
     INSN_COPIES array.  */
  start_sequence ();
  for (i = 0; i < max_parallel; i++)
    {
      int j;
      rtx_insn *this_iter;

      copy_bb_data id;
      this_iter = duplicate_insn_chain (head_insn, tail_insn, NULL, &id);
      j = 0;
      while (this_iter)
	{
	  rtx_insn *prev_stage_insn = insn_copies[i][j];
	  gcc_assert (INSN_CODE (this_iter) == INSN_CODE (prev_stage_insn));

	  if (INSN_CODE (this_iter) >= 0
	      && (get_attr_type (this_iter) == TYPE_LOAD_SHADOW
		  || get_attr_type (this_iter) == TYPE_MULT_SHADOW))
	    {
	      rtx_insn *prev = PREV_INSN (this_iter);
	      record_delay_slot_pair (prev, this_iter,
				      get_attr_cycles (prev) - 1, 0);
	    }
	  else
	    record_delay_slot_pair (prev_stage_insn, this_iter, i, 1);

	  insn_copies[i + 1][j] = this_iter;
	  j++;
	  this_iter = next_nonnote_nondebug_insn (this_iter);
	}
    }
  new_insns = get_insns ();
  last_insn = insn_copies[max_parallel][n_real_insns - 1];
  end_sequence ();
  emit_insn_before (new_insns, BB_END (bb));

  /* Try to schedule the loop using varying initiation intervals,
     starting with the smallest possible and incrementing it
     on failure.  */
  for (sp_ii = min_ii; sp_ii <= max_ii; sp_ii++)
    {
      basic_block tmp_bb;
      if (dump_file)
	fprintf (dump_file, "Trying to schedule for II %d\n", sp_ii);

      df_clear_flags (DF_LR_RUN_DCE);

      schedule_ebbs_init ();
      set_modulo_params (sp_ii, max_parallel, n_real_insns,
			 sploop_max_uid_iter0);
      tmp_bb = schedule_ebb (BB_HEAD (bb), last_insn, true);
      schedule_ebbs_finish ();

      if (tmp_bb)
	{
	  if (dump_file)
	    fprintf (dump_file, "Found schedule with II %d\n", sp_ii);
	  break;
	}
    }

  discard_delay_pairs_above (max_uid_before);

  if (sp_ii > max_ii)
    goto restore_loop;

  stages = insn_get_clock (ss.last_scheduled_iter0) / sp_ii + 1;

  if (stages == 1 && sp_ii > 5)
    goto restore_loop;

  /* At this point, we know we've been successful, unless we find later that
     there are too many execute packets for the loop buffer to hold.  */

  /* Assign reservations to the instructions in the loop.  We must find
     the stage that contains the full loop kernel, and transfer the
     reservations of the instructions contained in it to the corresponding
     instructions from iteration 0, which are the only ones we'll keep.  */
  assign_reservations (BB_HEAD (bb), ss.last_scheduled_insn);
  SET_PREV_INSN (BB_END (bb)) = ss.last_scheduled_iter0;
  SET_NEXT_INSN (ss.last_scheduled_iter0) = BB_END (bb);
  filter_insns_above (bb, sploop_max_uid_iter0);

  for (i = 0; i < n_real_insns; i++)
    {
      rtx insn = insn_copies[0][i];
      int uid = INSN_UID (insn);
      int stage = insn_uid_get_clock (uid) / sp_ii;

      if (stage + 1 < stages)
	{
	  int copy_uid;
	  stage = stages - stage - 1;
	  copy_uid = INSN_UID (insn_copies[stage][i]);
	  INSN_INFO_ENTRY (uid).reservation
	    = INSN_INFO_ENTRY (copy_uid).reservation;
	}
    }
  if (stages == 1)
    stages++;

  /* Compute the number of execute packets the pipelined form of the loop will
     require.  */
  prev = NULL;
  n_execute_packets = 0;
  for (insn = loop->start_label;
       insn != loop->loop_end;
       insn = NEXT_INSN (insn))
    {
      if (NONDEBUG_INSN_P (insn) && GET_MODE (insn) == TImode
	  && !shadow_p (insn))
	{
	  n_execute_packets++;
	  if (prev && insn_get_clock (prev) + 1 != insn_get_clock (insn))
	    /* We need an extra NOP instruction.  */
	    n_execute_packets++;

	  prev = insn;
	}
    }

  end_packet = ss.last_scheduled_iter0;
  while (!NONDEBUG_INSN_P (end_packet) || GET_MODE (end_packet) != TImode)
    end_packet = PREV_INSN (end_packet);

  /* The earliest cycle in which we can emit the SPKERNEL instruction.  */
  loop_earliest = (stages - 1) * sp_ii;
  if (loop_earliest > insn_get_clock (end_packet))
    {
      n_execute_packets++;
      end_packet = loop->loop_end;
    }
  else
    loop_earliest = insn_get_clock (end_packet);

  if (n_execute_packets > 14)
    goto restore_loop;

  /* Generate the spkernel instruction, and place it at the appropriate
     spot.  */
  PUT_MODE (end_packet, VOIDmode);

  insn = emit_jump_insn_before (
	   gen_spkernel (GEN_INT (stages - 1),
			 const0_rtx, JUMP_LABEL (loop->loop_end)),
	   end_packet);
  JUMP_LABEL (insn) = JUMP_LABEL (loop->loop_end);
  insn_set_clock (insn, loop_earliest);
  PUT_MODE (insn, TImode);
  INSN_INFO_ENTRY (INSN_UID (insn)).ebb_start = false;
  delete_insn (loop->loop_end);

  /* Place the mvc and sploop instructions before the loop.  */
  entry_bb = entry_edge->src;

  start_sequence ();

  insn = emit_insn (gen_mvilc (loop->iter_reg));
  if (loop->iter_reg_used_outside)
    insn = emit_move_insn (loop->iter_reg, const0_rtx);
  insn = emit_insn (gen_sploop (GEN_INT (sp_ii)));
  seq = get_insns ();

  if (!single_succ_p (entry_bb) || vec_safe_length (loop->incoming) > 1)
    {
      basic_block new_bb;
      edge e;
      edge_iterator ei;

      emit_insn_before (seq, BB_HEAD (loop->head));
      seq = emit_label_before (gen_label_rtx (), seq);

      new_bb = create_basic_block (seq, insn, entry_bb);
      FOR_EACH_EDGE (e, ei, loop->incoming)
	{
	  if (!(e->flags & EDGE_FALLTHRU))
	    redirect_edge_and_branch_force (e, new_bb);
	  else
	    redirect_edge_succ (e, new_bb);
	}
      make_edge (new_bb, loop->head, 0);
    }
  else
    {
      entry_after = BB_END (entry_bb);
      while (DEBUG_INSN_P (entry_after)
	     || (NOTE_P (entry_after)
		 && NOTE_KIND (entry_after) != NOTE_INSN_BASIC_BLOCK))
	entry_after = PREV_INSN (entry_after);
      emit_insn_after (seq, entry_after);
    }

  end_sequence ();

  /* Make sure we don't try to schedule this loop again.  */
  for (ix = 0; loop->blocks.iterate (ix, &bb); ix++)
    bb->flags |= BB_DISABLE_SCHEDULE;

  return true;

 restore_loop:
  if (dump_file)
    fprintf (dump_file, "Unable to pipeline loop.\n");

  for (i = 1; i < n_insns; i++)
    {
      SET_NEXT_INSN (orig_vec[i - 1]) = orig_vec[i];
      SET_PREV_INSN (orig_vec[i]) = orig_vec[i - 1];
    }
  SET_PREV_INSN (orig_vec[0]) = PREV_INSN (BB_HEAD (bb));
  SET_NEXT_INSN (PREV_INSN (BB_HEAD (bb))) = orig_vec[0];
  SET_NEXT_INSN (orig_vec[n_insns - 1]) = NEXT_INSN (BB_END (bb));
  SET_PREV_INSN (NEXT_INSN (BB_END (bb))) = orig_vec[n_insns - 1];
  BB_HEAD (bb) = orig_vec[0];
  BB_END (bb) = orig_vec[n_insns - 1];
 undo_splits:
  free_delay_pairs ();
  FOR_BB_INSNS (bb, insn)
    if (NONDEBUG_INSN_P (insn))
      undo_split_delayed_nonbranch (insn);
  return false;
}

/* A callback for the hw-doloop pass.  Called when a loop we have discovered
   turns out not to be optimizable; we have to split the doloop_end pattern
   into a subtract and a test.  */
static void
hwloop_fail (hwloop_info loop)
{
  rtx insn, test, testreg;

  if (dump_file)
    fprintf (dump_file, "splitting doloop insn %d\n",
	     INSN_UID (loop->loop_end));
  insn = gen_addsi3 (loop->iter_reg, loop->iter_reg, constm1_rtx);
  /* See if we can emit the add at the head of the loop rather than at the
     end.  */
  if (loop->head == NULL
      || loop->iter_reg_used_outside
      || loop->iter_reg_used
      || TEST_HARD_REG_BIT (loop->regs_set_in_loop, REGNO (loop->iter_reg))
      || loop->incoming_dest != loop->head
      || EDGE_COUNT (loop->head->preds) != 2)
    emit_insn_before (insn, loop->loop_end);
  else
    {
      rtx_insn *t = loop->start_label;
      while (!NOTE_P (t) || NOTE_KIND (t) != NOTE_INSN_BASIC_BLOCK)
	t = NEXT_INSN (t);
      emit_insn_after (insn, t);
    }

  testreg = SET_DEST (XVECEXP (PATTERN (loop->loop_end), 0, 2));
  if (GET_CODE (testreg) == SCRATCH)
    testreg = loop->iter_reg;
  else
    emit_insn_before (gen_movsi (testreg, loop->iter_reg), loop->loop_end);

  test = gen_rtx_NE (VOIDmode, testreg, const0_rtx);
  insn = emit_jump_insn_before (gen_cbranchsi4 (test, testreg, const0_rtx,
						loop->start_label),
				loop->loop_end);

  JUMP_LABEL (insn) = loop->start_label;
  LABEL_NUSES (loop->start_label)++;
  delete_insn (loop->loop_end);
}

static struct hw_doloop_hooks c6x_doloop_hooks =
{
  hwloop_pattern_reg,
  hwloop_optimize,
  hwloop_fail
};

/* Run the hw-doloop pass to modulo-schedule hardware loops, or split the
   doloop_end patterns where such optimizations are impossible.  */
static void
c6x_hwloops (void)
{
  if (optimize)
    reorg_loops (true, &c6x_doloop_hooks);
}

/* Implement the TARGET_MACHINE_DEPENDENT_REORG pass.  We split call insns here
   into a sequence that loads the return register and performs the call,
   and emit the return label.
   If scheduling after reload is requested, it happens here.  */

static void
c6x_reorg (void)
{
  basic_block bb;
  bool do_selsched = (c6x_flag_schedule_insns2 && flag_selective_scheduling2
		      && !maybe_skip_selective_scheduling ());

  /* 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 ();

  df_clear_flags (DF_LR_RUN_DCE);
  df_note_add_problem ();

  /* If optimizing, we'll have split before scheduling.  */
  if (optimize == 0)
    split_all_insns ();

  df_analyze ();

  if (c6x_flag_schedule_insns2)
    {
      int sz = get_max_uid () * 3 / 2 + 1;

      insn_info.create (sz);
    }

  /* Make sure the real-jump insns we create are not deleted.  When modulo-
     scheduling, situations where a reg is only stored in a loop can also
     cause dead code when doing the initial unrolling.  */
  sched_no_dce = true;

  c6x_hwloops ();

  if (c6x_flag_schedule_insns2)
    {
      split_delayed_insns ();
      timevar_push (TV_SCHED2);
      if (do_selsched)
	run_selective_scheduling ();
      else
	schedule_ebbs ();
      conditionalize_after_sched ();
      timevar_pop (TV_SCHED2);

      free_delay_pairs ();
    }
  sched_no_dce = false;

  rtx_code_label **call_labels = XCNEWVEC (rtx_code_label *, get_max_uid () + 1);

  reorg_split_calls (call_labels);

  if (c6x_flag_schedule_insns2)
    {
      FOR_EACH_BB_FN (bb, cfun)
	if ((bb->flags & BB_DISABLE_SCHEDULE) == 0)
	  assign_reservations (BB_HEAD (bb), BB_END (bb));
    }

  if (c6x_flag_var_tracking)
    {
      timevar_push (TV_VAR_TRACKING);
      variable_tracking_main ();
      timevar_pop (TV_VAR_TRACKING);
    }

  reorg_emit_nops (call_labels);

  /* Post-process the schedule to move parallel insns into SEQUENCEs.  */
  if (c6x_flag_schedule_insns2)
    {
      free_delay_pairs ();
      c6x_gen_bundles ();
    }

  df_finish_pass (false);
}

/* Called when a function has been assembled.  It should perform all the
   tasks of ASM_DECLARE_FUNCTION_SIZE in elfos.h, plus target-specific
   tasks.
   We free the reservation (and other scheduling) information here now that
   all insns have been output.  */
void
c6x_function_end (FILE *file, const char *fname)
{
  c6x_output_fn_unwind (file);

  insn_info.release ();

  if (!flag_inhibit_size_directive)
    ASM_OUTPUT_MEASURED_SIZE (file, fname);
}

/* Determine whether X is a shift with code CODE and an integer amount
   AMOUNT.  */
static bool
shift_p (rtx x, enum rtx_code code, int amount)
{
  return (GET_CODE (x) == code && GET_CODE (XEXP (x, 1)) == CONST_INT
	  && INTVAL (XEXP (x, 1)) == amount);
}

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

static bool
c6x_rtx_costs (rtx x, machine_mode mode, int outer_code, int opno, int *total,
	       bool speed)
{
  int cost2 = COSTS_N_INSNS (1);
  rtx op0, op1;
  int code = GET_CODE (x);

  switch (code)
    {
    case CONST_INT:
      if (outer_code == SET || outer_code == PLUS)
        *total = satisfies_constraint_IsB (x) ? 0 : cost2;
      else if (outer_code == AND || outer_code == IOR || outer_code == XOR
	       || outer_code == MINUS)
	*total = satisfies_constraint_Is5 (x) ? 0 : cost2;
      else if (GET_RTX_CLASS (outer_code) == RTX_COMPARE
	       || GET_RTX_CLASS (outer_code) == RTX_COMM_COMPARE)
	*total = satisfies_constraint_Iu4 (x) ? 0 : cost2;
      else if (outer_code == ASHIFT || outer_code == ASHIFTRT
	       || outer_code == LSHIFTRT)
	*total = satisfies_constraint_Iu5 (x) ? 0 : cost2;
      else
	*total = cost2;
      return true;

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

    case TRUNCATE:
      /* Recognize a mult_highpart operation.  */
      if ((mode == HImode || mode == SImode)
	  && GET_CODE (XEXP (x, 0)) == LSHIFTRT
	  && GET_MODE (XEXP (x, 0)) == GET_MODE_2XWIDER_MODE (mode).require ()
	  && GET_CODE (XEXP (XEXP (x, 0), 0)) == MULT
	  && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
	  && INTVAL (XEXP (XEXP (x, 0), 1)) == GET_MODE_BITSIZE (mode))
	{
	  rtx mul = XEXP (XEXP (x, 0), 0);
	  rtx op0 = XEXP (mul, 0);
	  rtx op1 = XEXP (mul, 1);
	  enum rtx_code code0 = GET_CODE (op0);
	  enum rtx_code code1 = GET_CODE (op1);

	  if ((code0 == code1
	       && (code0 == SIGN_EXTEND || code0 == ZERO_EXTEND))
	      || (mode == HImode
		  && code0 == ZERO_EXTEND && code1 == SIGN_EXTEND))
	    {
	      if (mode == HImode)
		*total = COSTS_N_INSNS (2);
	      else
		*total = COSTS_N_INSNS (12);
	      mode = GET_MODE (XEXP (op0, 0));
	      *total += rtx_cost (XEXP (op0, 0), mode, code0, 0, speed);
	      *total += rtx_cost (XEXP (op1, 0), mode, code1, 0, speed);
	      return true;
	    }
	}
      return false;

    case ASHIFT:
    case ASHIFTRT:
    case LSHIFTRT:
      if (mode == DImode)
	*total = COSTS_N_INSNS (CONSTANT_P (XEXP (x, 1)) ? 4 : 15);
      else
	*total = COSTS_N_INSNS (1);
      return false;

    case PLUS:
    case MINUS:
      *total = COSTS_N_INSNS (1);
      op0 = code == PLUS ? XEXP (x, 0) : XEXP (x, 1);
      op1 = code == PLUS ? XEXP (x, 1) : XEXP (x, 0);
      if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD
	  && INTEGRAL_MODE_P (mode)
	  && GET_CODE (op0) == MULT
	  && GET_CODE (XEXP (op0, 1)) == CONST_INT
	  && (INTVAL (XEXP (op0, 1)) == 2
	      || INTVAL (XEXP (op0, 1)) == 4
	      || (code == PLUS && INTVAL (XEXP (op0, 1)) == 8)))
	{
	  *total += rtx_cost (XEXP (op0, 0), mode, ASHIFT, 0, speed);
	  *total += rtx_cost (op1, mode, (enum rtx_code) code, 1, speed);
	  return true;
	}
      return false;

    case MULT:
      op0 = XEXP (x, 0);
      op1 = XEXP (x, 1);
      if (mode == DFmode)
	{
	  if (TARGET_FP)
	    *total = COSTS_N_INSNS (speed ? 10 : 1);
	  else
	    *total = COSTS_N_INSNS (speed ? 200 : 4);
	}
      else if (mode == SFmode)
	{
	  if (TARGET_FP)
	    *total = COSTS_N_INSNS (speed ? 4 : 1);
	  else
	    *total = COSTS_N_INSNS (speed ? 100 : 4);
	}
      else if (mode == DImode)
	{
	  if (TARGET_MPY32
	      && GET_CODE (op0) == GET_CODE (op1)
	      && (GET_CODE (op0) == ZERO_EXTEND
		  || GET_CODE (op0) == SIGN_EXTEND))
	    {
	      *total = COSTS_N_INSNS (speed ? 2 : 1);
	      op0 = XEXP (op0, 0);
	      op1 = XEXP (op1, 0);
	    }
	  else
	    /* Maybe improve this laster.  */
	    *total = COSTS_N_INSNS (20);
	}
      else if (mode == SImode)
	{
	  if (((GET_CODE (op0) == ZERO_EXTEND
		|| GET_CODE (op0) == SIGN_EXTEND
		|| shift_p (op0, LSHIFTRT, 16))
	       && (GET_CODE (op1) == SIGN_EXTEND
		   || GET_CODE (op1) == ZERO_EXTEND
		   || scst5_operand (op1, SImode)
		   || shift_p (op1, ASHIFTRT, 16)
		   || shift_p (op1, LSHIFTRT, 16)))
	      || (shift_p (op0, ASHIFTRT, 16)
		  && (GET_CODE (op1) == SIGN_EXTEND
		      || shift_p (op1, ASHIFTRT, 16))))
	    {
	      *total = COSTS_N_INSNS (speed ? 2 : 1);
	      op0 = XEXP (op0, 0);
	      if (scst5_operand (op1, SImode))
		op1 = NULL_RTX;
	      else
		op1 = XEXP (op1, 0);
	    }
	  else if (!speed)
	    *total = COSTS_N_INSNS (1);
	  else if (TARGET_MPY32)
	    *total = COSTS_N_INSNS (4);
	  else
	    *total = COSTS_N_INSNS (6);
	}
      else if (mode == HImode)
	*total = COSTS_N_INSNS (speed ? 2 : 1);

      if (GET_CODE (op0) != REG
	  && (GET_CODE (op0) != SUBREG || GET_CODE (SUBREG_REG (op0)) != REG))
	*total += rtx_cost (op0, mode, MULT, 0, speed);
      if (op1 && GET_CODE (op1) != REG
	  && (GET_CODE (op1) != SUBREG || GET_CODE (SUBREG_REG (op1)) != REG))
	*total += rtx_cost (op1, mode, MULT, 1, speed);
      return true;

    case UDIV:
    case DIV:
      /* This is a bit random; assuming on average there'll be 16 leading
	 zeros.  FIXME: estimate better for constant dividends.  */
      *total = COSTS_N_INSNS (6 + 3 * 16);
      return false;

    case IF_THEN_ELSE:
      /* Recognize the cmp_and/ior patterns.  */
      op0 = XEXP (x, 0);
      if ((GET_CODE (op0) == EQ || GET_CODE (op0) == NE)
	  && REG_P (XEXP (op0, 0))
	  && XEXP (op0, 1) == const0_rtx
	  && rtx_equal_p (XEXP (x, 1), XEXP (op0, 0)))
	{
	  *total = rtx_cost (XEXP (x, 1), VOIDmode, (enum rtx_code) outer_code,
			     opno, speed);
	  return false;
	}
      return false;

    default:
      return false;
    }
}

/* Implements target hook vector_mode_supported_p.  */

static bool
c6x_vector_mode_supported_p (machine_mode mode)
{
  switch (mode)
    {
    case E_V2HImode:
    case E_V4QImode:
    case E_V2SImode:
    case E_V4HImode:
    case E_V8QImode:
      return true;
    default:
      return false;
    }
}

/* Implements TARGET_VECTORIZE_PREFERRED_SIMD_MODE.  */
static machine_mode
c6x_preferred_simd_mode (scalar_mode mode)
{
  switch (mode)
    {
    case E_HImode:
      return V2HImode;
    case E_QImode:
      return V4QImode;

    default:
      return word_mode;
    }
}

/* Implement TARGET_SCALAR_MODE_SUPPORTED_P.  */

static bool
c6x_scalar_mode_supported_p (scalar_mode mode)
{
  if (ALL_FIXED_POINT_MODE_P (mode)
      && GET_MODE_PRECISION (mode) <= 2 * BITS_PER_WORD)
    return true;

  return default_scalar_mode_supported_p (mode);
}

/* Output a reference from a function exception table to the type_info
   object X.  Output these via a special assembly directive.  */

static bool
c6x_output_ttype (rtx x)
{
  /* Use special relocations for symbol references.  */
  if (GET_CODE (x) != CONST_INT)
    fputs ("\t.ehtype\t", asm_out_file);
  else
    fputs ("\t.word\t", asm_out_file);
  output_addr_const (asm_out_file, x);
  fputc ('\n', asm_out_file);

  return TRUE;
}

/* Modify the return address of the current function.  */

void
c6x_set_return_address (rtx source, rtx scratch)
{
  struct c6x_frame frame;
  rtx addr;
  HOST_WIDE_INT offset;

  c6x_compute_frame_layout (&frame);
  if (! c6x_save_reg (RETURN_ADDR_REGNO))
    emit_move_insn (gen_rtx_REG (Pmode, RETURN_ADDR_REGNO), source);
  else
    {

      if (frame_pointer_needed)
	{
	  addr = hard_frame_pointer_rtx;
	  offset = frame.b3_offset;
	}
      else
	{
	  addr = stack_pointer_rtx;
	  offset = frame.to_allocate - frame.b3_offset;
	}

      /* TODO: Use base+offset loads where possible.  */
      if (offset)
	{
	  HOST_WIDE_INT low = trunc_int_for_mode (offset, HImode);

	  emit_insn (gen_movsi_high (scratch, GEN_INT (low)));
	  if (low != offset)
	    emit_insn (gen_movsi_lo_sum (scratch, scratch, GEN_INT(offset)));
	  emit_insn (gen_addsi3 (scratch, addr, scratch));
	  addr = scratch;
	}

      emit_move_insn (gen_frame_mem (Pmode, addr), source);
    }
}

/* We save pairs of registers using a DImode store.  Describe the component
   registers for DWARF generation code.  */

static rtx
c6x_dwarf_register_span (rtx rtl)
{
    unsigned regno;
    unsigned real_regno;
    int nregs;
    int i;
    rtx p;

    regno = REGNO (rtl);
    nregs = REG_NREGS (rtl);
    if (nregs == 1)
      return  NULL_RTX;

    p = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc(nregs));
    for (i = 0; i < nregs; i++)
      {
	if (TARGET_BIG_ENDIAN)
	  real_regno = regno + nregs - (i + 1);
	else
	  real_regno = regno + i;

	XVECEXP (p, 0, i) = gen_rtx_REG (SImode, real_regno);
      }

    return p;
}

/* Codes for all the C6X builtins.  */
enum c6x_builtins
{
  C6X_BUILTIN_SADD,
  C6X_BUILTIN_SSUB,
  C6X_BUILTIN_ADD2,
  C6X_BUILTIN_SUB2,
  C6X_BUILTIN_ADD4,
  C6X_BUILTIN_SUB4,
  C6X_BUILTIN_SADD2,
  C6X_BUILTIN_SSUB2,
  C6X_BUILTIN_SADDU4,

  C6X_BUILTIN_SMPY,
  C6X_BUILTIN_SMPYH,
  C6X_BUILTIN_SMPYHL,
  C6X_BUILTIN_SMPYLH,
  C6X_BUILTIN_MPY2,
  C6X_BUILTIN_SMPY2,

  C6X_BUILTIN_CLRR,
  C6X_BUILTIN_EXTR,
  C6X_BUILTIN_EXTRU,

  C6X_BUILTIN_SSHL,
  C6X_BUILTIN_SUBC,
  C6X_BUILTIN_ABS,
  C6X_BUILTIN_ABS2,
  C6X_BUILTIN_AVG2,
  C6X_BUILTIN_AVGU4,

  C6X_BUILTIN_MAX
};


static GTY(()) tree c6x_builtin_decls[C6X_BUILTIN_MAX];

/* Return the C6X builtin for CODE.  */
static tree
c6x_builtin_decl (unsigned code, bool initialize_p ATTRIBUTE_UNUSED)
{
  if (code >= C6X_BUILTIN_MAX)
    return error_mark_node;

  return c6x_builtin_decls[code];
}

#define def_builtin(NAME, TYPE, CODE)					\
do {									\
  tree bdecl;								\
  bdecl = add_builtin_function ((NAME), (TYPE), (CODE), BUILT_IN_MD,	\
				NULL, NULL_TREE);			\
  c6x_builtin_decls[CODE] = bdecl;					\
} while (0)

/* Set up all builtin functions for this target.  */
static void
c6x_init_builtins (void)
{
  tree V4QI_type_node = build_vector_type (unsigned_intQI_type_node, 4);
  tree V2HI_type_node = build_vector_type (intHI_type_node, 2);
  tree V2SI_type_node = build_vector_type (intSI_type_node, 2);
  tree int_ftype_int
    = build_function_type_list (integer_type_node, integer_type_node,
				NULL_TREE);
  tree int_ftype_int_int
    = build_function_type_list (integer_type_node, integer_type_node,
				integer_type_node, NULL_TREE);
  tree v2hi_ftype_v2hi
    = build_function_type_list (V2HI_type_node, V2HI_type_node, NULL_TREE);
  tree v4qi_ftype_v4qi_v4qi
    = build_function_type_list (V4QI_type_node, V4QI_type_node,
				V4QI_type_node, NULL_TREE);
  tree v2hi_ftype_v2hi_v2hi
    = build_function_type_list (V2HI_type_node, V2HI_type_node,
				V2HI_type_node, NULL_TREE);
  tree v2si_ftype_v2hi_v2hi
    = build_function_type_list (V2SI_type_node, V2HI_type_node,
				V2HI_type_node, NULL_TREE);
  
  def_builtin ("__builtin_c6x_sadd", int_ftype_int_int,
	       C6X_BUILTIN_SADD);
  def_builtin ("__builtin_c6x_ssub", int_ftype_int_int,
	       C6X_BUILTIN_SSUB);
  def_builtin ("__builtin_c6x_add2", v2hi_ftype_v2hi_v2hi,
	       C6X_BUILTIN_ADD2);
  def_builtin ("__builtin_c6x_sub2", v2hi_ftype_v2hi_v2hi,
	       C6X_BUILTIN_SUB2);
  def_builtin ("__builtin_c6x_add4", v4qi_ftype_v4qi_v4qi,
	       C6X_BUILTIN_ADD4);
  def_builtin ("__builtin_c6x_sub4", v4qi_ftype_v4qi_v4qi,
	       C6X_BUILTIN_SUB4);
  def_builtin ("__builtin_c6x_mpy2", v2si_ftype_v2hi_v2hi,
	       C6X_BUILTIN_MPY2);
  def_builtin ("__builtin_c6x_sadd2", v2hi_ftype_v2hi_v2hi,
	       C6X_BUILTIN_SADD2);
  def_builtin ("__builtin_c6x_ssub2", v2hi_ftype_v2hi_v2hi,
	       C6X_BUILTIN_SSUB2);
  def_builtin ("__builtin_c6x_saddu4", v4qi_ftype_v4qi_v4qi,
	       C6X_BUILTIN_SADDU4);
  def_builtin ("__builtin_c6x_smpy2", v2si_ftype_v2hi_v2hi,
	       C6X_BUILTIN_SMPY2);

  def_builtin ("__builtin_c6x_smpy", int_ftype_int_int,
	       C6X_BUILTIN_SMPY);
  def_builtin ("__builtin_c6x_smpyh", int_ftype_int_int,
	       C6X_BUILTIN_SMPYH);
  def_builtin ("__builtin_c6x_smpyhl", int_ftype_int_int,
	       C6X_BUILTIN_SMPYHL);
  def_builtin ("__builtin_c6x_smpylh", int_ftype_int_int,
	       C6X_BUILTIN_SMPYLH);

  def_builtin ("__builtin_c6x_sshl", int_ftype_int_int,
	       C6X_BUILTIN_SSHL);
  def_builtin ("__builtin_c6x_subc", int_ftype_int_int,
	       C6X_BUILTIN_SUBC);

  def_builtin ("__builtin_c6x_avg2", v2hi_ftype_v2hi_v2hi,
	       C6X_BUILTIN_AVG2);
  def_builtin ("__builtin_c6x_avgu4", v4qi_ftype_v4qi_v4qi,
	       C6X_BUILTIN_AVGU4);

  def_builtin ("__builtin_c6x_clrr", int_ftype_int_int,
	       C6X_BUILTIN_CLRR);
  def_builtin ("__builtin_c6x_extr", int_ftype_int_int,
	       C6X_BUILTIN_EXTR);
  def_builtin ("__builtin_c6x_extru", int_ftype_int_int,
	       C6X_BUILTIN_EXTRU);

  def_builtin ("__builtin_c6x_abs", int_ftype_int, C6X_BUILTIN_ABS);
  def_builtin ("__builtin_c6x_abs2", v2hi_ftype_v2hi, C6X_BUILTIN_ABS2);
}


struct builtin_description
{
  const enum insn_code icode;
  const char *const name;
  const enum c6x_builtins code;
};

static const struct builtin_description bdesc_2arg[] =
{
  { CODE_FOR_saddsi3, "__builtin_c6x_sadd", C6X_BUILTIN_SADD },
  { CODE_FOR_ssubsi3, "__builtin_c6x_ssub", C6X_BUILTIN_SSUB },
  { CODE_FOR_addv2hi3, "__builtin_c6x_add2", C6X_BUILTIN_ADD2 },
  { CODE_FOR_subv2hi3, "__builtin_c6x_sub2", C6X_BUILTIN_SUB2 },
  { CODE_FOR_addv4qi3, "__builtin_c6x_add4", C6X_BUILTIN_ADD4 },
  { CODE_FOR_subv4qi3, "__builtin_c6x_sub4", C6X_BUILTIN_SUB4 },
  { CODE_FOR_ss_addv2hi3, "__builtin_c6x_sadd2", C6X_BUILTIN_SADD2 },
  { CODE_FOR_ss_subv2hi3, "__builtin_c6x_ssub2", C6X_BUILTIN_SSUB2 },
  { CODE_FOR_us_addv4qi3, "__builtin_c6x_saddu4", C6X_BUILTIN_SADDU4 },

  { CODE_FOR_subcsi3, "__builtin_c6x_subc", C6X_BUILTIN_SUBC },
  { CODE_FOR_ss_ashlsi3, "__builtin_c6x_sshl", C6X_BUILTIN_SSHL },

  { CODE_FOR_avgv2hi3, "__builtin_c6x_avg2", C6X_BUILTIN_AVG2 },
  { CODE_FOR_uavgv4qi3, "__builtin_c6x_avgu4", C6X_BUILTIN_AVGU4 },

  { CODE_FOR_mulhqsq3, "__builtin_c6x_smpy", C6X_BUILTIN_SMPY },
  { CODE_FOR_mulhqsq3_hh, "__builtin_c6x_smpyh", C6X_BUILTIN_SMPYH },
  { CODE_FOR_mulhqsq3_lh, "__builtin_c6x_smpylh", C6X_BUILTIN_SMPYLH },
  { CODE_FOR_mulhqsq3_hl, "__builtin_c6x_smpyhl", C6X_BUILTIN_SMPYHL },

  { CODE_FOR_mulv2hqv2sq3, "__builtin_c6x_smpy2", C6X_BUILTIN_SMPY2 },

  { CODE_FOR_clrr, "__builtin_c6x_clrr", C6X_BUILTIN_CLRR },
  { CODE_FOR_extr, "__builtin_c6x_extr", C6X_BUILTIN_EXTR },
  { CODE_FOR_extru, "__builtin_c6x_extru", C6X_BUILTIN_EXTRU }
};

static const struct builtin_description bdesc_1arg[] =
{
  { CODE_FOR_ssabssi2, "__builtin_c6x_abs", C6X_BUILTIN_ABS },
  { CODE_FOR_ssabsv2hi2, "__builtin_c6x_abs2", C6X_BUILTIN_ABS2 }
};

/* Errors in the source file can cause expand_expr to return const0_rtx
   where we expect a vector.  To avoid crashing, use one of the vector
   clear instructions.  */
static rtx
safe_vector_operand (rtx x, machine_mode mode)
{
  if (x != const0_rtx)
    return x;
  x = gen_reg_rtx (SImode);

  emit_insn (gen_movsi (x, CONST0_RTX (SImode)));
  return gen_lowpart (mode, x);
}

/* Subroutine of c6x_expand_builtin to take care of binop insns.  MACFLAG is -1
   if this is a normal binary op, or one of the MACFLAG_xxx constants.  */

static rtx
c6x_expand_binop_builtin (enum insn_code icode, tree exp, rtx target,
			  bool match_op)
{
  int offs = match_op ? 1 : 0;
  rtx pat;
  tree arg0 = CALL_EXPR_ARG (exp, 0);
  tree arg1 = CALL_EXPR_ARG (exp, 1);
  rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, EXPAND_NORMAL);
  rtx op1 = expand_expr (arg1, NULL_RTX, VOIDmode, EXPAND_NORMAL);
  machine_mode op0mode = GET_MODE (op0);
  machine_mode op1mode = GET_MODE (op1);
  machine_mode tmode = insn_data[icode].operand[0].mode;
  machine_mode mode0 = insn_data[icode].operand[1 + offs].mode;
  machine_mode mode1 = insn_data[icode].operand[2 + offs].mode;
  rtx ret = target;

  if (VECTOR_MODE_P (mode0))
    op0 = safe_vector_operand (op0, mode0);
  if (VECTOR_MODE_P (mode1))
    op1 = safe_vector_operand (op1, mode1);

  if (! target
      || GET_MODE (target) != tmode
      || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
    {
      if (tmode == SQmode || tmode == V2SQmode)
	{
	  ret = gen_reg_rtx (tmode == SQmode ? SImode : V2SImode);
	  target = gen_lowpart (tmode, ret);
	}
      else
	target = gen_reg_rtx (tmode);
    }

  if ((op0mode == V2HImode || op0mode == SImode || op0mode == VOIDmode)
      && (mode0 == V2HQmode || mode0 == HQmode || mode0 == SQmode))
    {
      op0mode = mode0;
      op0 = gen_lowpart (mode0, op0);
    }
  if ((op1mode == V2HImode || op1mode == SImode || op1mode == VOIDmode)
      && (mode1 == V2HQmode || mode1 == HQmode || mode1 == SQmode))
    {
      op1mode = mode1;
      op1 = gen_lowpart (mode1, op1);
    }
  /* In case the insn wants input operands in modes different from
     the result, abort.  */
  gcc_assert ((op0mode == mode0 || op0mode == VOIDmode)
	      && (op1mode == mode1 || op1mode == VOIDmode));

  if (! (*insn_data[icode].operand[1 + offs].predicate) (op0, mode0))
    op0 = copy_to_mode_reg (mode0, op0);
  if (! (*insn_data[icode].operand[2 + offs].predicate) (op1, mode1))
    op1 = copy_to_mode_reg (mode1, op1);

  if (match_op)
    pat = GEN_FCN (icode) (target, target, op0, op1);
  else
    pat = GEN_FCN (icode) (target, op0, op1);

  if (! pat)
    return 0;

  emit_insn (pat);

  return ret;
}

/* Subroutine of c6x_expand_builtin to take care of unop insns.  */

static rtx
c6x_expand_unop_builtin (enum insn_code icode, tree exp,
			  rtx target)
{
  rtx pat;
  tree arg0 = CALL_EXPR_ARG (exp, 0);
  rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, EXPAND_NORMAL);
  machine_mode op0mode = GET_MODE (op0);
  machine_mode tmode = insn_data[icode].operand[0].mode;
  machine_mode mode0 = insn_data[icode].operand[1].mode;

  if (! target
      || GET_MODE (target) != tmode
      || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
    target = gen_reg_rtx (tmode);

  if (VECTOR_MODE_P (mode0))
    op0 = safe_vector_operand (op0, mode0);

  if (op0mode == SImode && mode0 == HImode)
    {
      op0mode = HImode;
      op0 = gen_lowpart (HImode, op0);
    }
  gcc_assert (op0mode == mode0 || op0mode == VOIDmode);

  if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
    op0 = copy_to_mode_reg (mode0, op0);

  pat = GEN_FCN (icode) (target, op0);
  if (! pat)
    return 0;
  emit_insn (pat);
  return target;
}

/* Expand an expression EXP that calls a built-in function,
   with result going to TARGET if that's convenient
   (and in mode MODE if that's convenient).
   SUBTARGET may be used as the target for computing one of EXP's operands.
   IGNORE is nonzero if the value is to be ignored.  */

static rtx
c6x_expand_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
		     rtx subtarget ATTRIBUTE_UNUSED,
		     machine_mode mode ATTRIBUTE_UNUSED,
		     int ignore ATTRIBUTE_UNUSED)
{
  size_t i;
  const struct builtin_description *d;
  tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
  unsigned int fcode = DECL_MD_FUNCTION_CODE (fndecl);

  for (i = 0, d = bdesc_2arg; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
    if (d->code == fcode)
      return c6x_expand_binop_builtin (d->icode, exp, target,
				       fcode == C6X_BUILTIN_CLRR);

  for (i = 0, d = bdesc_1arg; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
    if (d->code == fcode)
      return c6x_expand_unop_builtin (d->icode, exp, target);

  gcc_unreachable ();
}

/* Target unwind frame info is generated from dwarf CFI directives, so
   always output dwarf2 unwind info.  */

static enum unwind_info_type
c6x_debug_unwind_info (void)
{
  if (flag_unwind_tables || flag_exceptions)
    return UI_DWARF2;

  return default_debug_unwind_info ();
}

/* Implement TARGET_HARD_REGNO_MODE_OK.  */

static bool
c6x_hard_regno_mode_ok (unsigned int regno, machine_mode mode)
{
  return GET_MODE_SIZE (mode) <= UNITS_PER_WORD || (regno & 1) == 0;
}

/* Implement TARGET_MODES_TIEABLE_P.  */

static bool
c6x_modes_tieable_p (machine_mode mode1, machine_mode mode2)
{
  return (mode1 == mode2
	  || (GET_MODE_SIZE (mode1) <= UNITS_PER_WORD
	      && GET_MODE_SIZE (mode2) <= UNITS_PER_WORD));
}

/* Implement REGNO_REG_CLASS.  */

enum reg_class
c6x_regno_reg_class (int reg)
{
  if (reg >= REG_A1 && reg <= REG_A2)
    return PREDICATE_A_REGS;

  if (reg == REG_A0 && TARGET_INSNS_64)
    return PREDICATE_A_REGS;

  if (reg >= REG_B0 && reg <= REG_B2)
    return PREDICATE_B_REGS;

  if (A_REGNO_P (reg))
    return NONPREDICATE_A_REGS;

  if (call_used_or_fixed_reg_p (reg))
    return CALL_USED_B_REGS;

  return B_REGS;
}

/* Target Structure.  */

/* Initialize the GCC target structure.  */
#undef TARGET_FUNCTION_ARG
#define TARGET_FUNCTION_ARG c6x_function_arg
#undef TARGET_FUNCTION_ARG_ADVANCE
#define TARGET_FUNCTION_ARG_ADVANCE c6x_function_arg_advance
#undef TARGET_FUNCTION_ARG_BOUNDARY
#define TARGET_FUNCTION_ARG_BOUNDARY c6x_function_arg_boundary
#undef TARGET_FUNCTION_ARG_ROUND_BOUNDARY
#define TARGET_FUNCTION_ARG_ROUND_BOUNDARY \
  c6x_function_arg_round_boundary
#undef TARGET_FUNCTION_VALUE_REGNO_P
#define TARGET_FUNCTION_VALUE_REGNO_P c6x_function_value_regno_p
#undef TARGET_FUNCTION_VALUE
#define TARGET_FUNCTION_VALUE c6x_function_value
#undef TARGET_LIBCALL_VALUE
#define TARGET_LIBCALL_VALUE c6x_libcall_value
#undef TARGET_RETURN_IN_MEMORY
#define TARGET_RETURN_IN_MEMORY c6x_return_in_memory
#undef TARGET_RETURN_IN_MSB
#define TARGET_RETURN_IN_MSB c6x_return_in_msb
#undef TARGET_PASS_BY_REFERENCE
#define TARGET_PASS_BY_REFERENCE c6x_pass_by_reference
#undef TARGET_CALLEE_COPIES
#define TARGET_CALLEE_COPIES hook_bool_CUMULATIVE_ARGS_arg_info_true
#undef TARGET_STRUCT_VALUE_RTX
#define TARGET_STRUCT_VALUE_RTX c6x_struct_value_rtx
#undef TARGET_FUNCTION_OK_FOR_SIBCALL
#define TARGET_FUNCTION_OK_FOR_SIBCALL c6x_function_ok_for_sibcall

#undef TARGET_ASM_OUTPUT_MI_THUNK
#define TARGET_ASM_OUTPUT_MI_THUNK c6x_output_mi_thunk
#undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
#define TARGET_ASM_CAN_OUTPUT_MI_THUNK c6x_can_output_mi_thunk

#undef TARGET_BUILD_BUILTIN_VA_LIST
#define TARGET_BUILD_BUILTIN_VA_LIST c6x_build_builtin_va_list

#undef TARGET_ASM_TRAMPOLINE_TEMPLATE
#define TARGET_ASM_TRAMPOLINE_TEMPLATE c6x_asm_trampoline_template
#undef TARGET_TRAMPOLINE_INIT
#define TARGET_TRAMPOLINE_INIT c6x_initialize_trampoline

#undef TARGET_LEGITIMATE_CONSTANT_P
#define TARGET_LEGITIMATE_CONSTANT_P c6x_legitimate_constant_p
#undef TARGET_LEGITIMATE_ADDRESS_P
#define TARGET_LEGITIMATE_ADDRESS_P c6x_legitimate_address_p

#undef TARGET_LRA_P
#define TARGET_LRA_P hook_bool_void_false

#undef TARGET_IN_SMALL_DATA_P
#define TARGET_IN_SMALL_DATA_P c6x_in_small_data_p
#undef	TARGET_ASM_SELECT_RTX_SECTION
#define TARGET_ASM_SELECT_RTX_SECTION  c6x_select_rtx_section
#undef TARGET_ASM_SELECT_SECTION
#define TARGET_ASM_SELECT_SECTION  c6x_elf_select_section
#undef TARGET_ASM_UNIQUE_SECTION
#define TARGET_ASM_UNIQUE_SECTION  c6x_elf_unique_section
#undef TARGET_SECTION_TYPE_FLAGS
#define TARGET_SECTION_TYPE_FLAGS  c6x_section_type_flags
#undef TARGET_HAVE_SRODATA_SECTION
#define TARGET_HAVE_SRODATA_SECTION true
#undef TARGET_ASM_MERGEABLE_RODATA_PREFIX
#define TARGET_ASM_MERGEABLE_RODATA_PREFIX ".const"

#undef TARGET_OPTION_OVERRIDE
#define TARGET_OPTION_OVERRIDE c6x_option_override
#undef TARGET_CONDITIONAL_REGISTER_USAGE
#define TARGET_CONDITIONAL_REGISTER_USAGE c6x_conditional_register_usage

#undef TARGET_INIT_LIBFUNCS
#define TARGET_INIT_LIBFUNCS c6x_init_libfuncs
#undef TARGET_LIBFUNC_GNU_PREFIX
#define TARGET_LIBFUNC_GNU_PREFIX true

#undef TARGET_SCALAR_MODE_SUPPORTED_P
#define TARGET_SCALAR_MODE_SUPPORTED_P c6x_scalar_mode_supported_p
#undef TARGET_VECTOR_MODE_SUPPORTED_P
#define TARGET_VECTOR_MODE_SUPPORTED_P c6x_vector_mode_supported_p
#undef TARGET_VECTORIZE_PREFERRED_SIMD_MODE
#define TARGET_VECTORIZE_PREFERRED_SIMD_MODE c6x_preferred_simd_mode

#undef TARGET_RTX_COSTS
#define TARGET_RTX_COSTS c6x_rtx_costs

#undef TARGET_SCHED_INIT
#define TARGET_SCHED_INIT c6x_sched_init
#undef TARGET_SCHED_SET_SCHED_FLAGS
#define TARGET_SCHED_SET_SCHED_FLAGS c6x_set_sched_flags
#undef TARGET_SCHED_ADJUST_COST
#define TARGET_SCHED_ADJUST_COST c6x_adjust_cost
#undef TARGET_SCHED_ISSUE_RATE
#define TARGET_SCHED_ISSUE_RATE c6x_issue_rate
#undef TARGET_SCHED_VARIABLE_ISSUE
#define TARGET_SCHED_VARIABLE_ISSUE c6x_variable_issue
#undef TARGET_SCHED_REORDER
#define TARGET_SCHED_REORDER c6x_sched_reorder
#undef TARGET_SCHED_REORDER2
#define TARGET_SCHED_REORDER2 c6x_sched_reorder2
#undef TARGET_SCHED_DFA_NEW_CYCLE
#define TARGET_SCHED_DFA_NEW_CYCLE c6x_dfa_new_cycle
#undef TARGET_SCHED_DFA_PRE_CYCLE_INSN
#define TARGET_SCHED_DFA_PRE_CYCLE_INSN c6x_sched_dfa_pre_cycle_insn
#undef TARGET_SCHED_EXPOSED_PIPELINE
#define TARGET_SCHED_EXPOSED_PIPELINE true

#undef TARGET_SCHED_ALLOC_SCHED_CONTEXT
#define TARGET_SCHED_ALLOC_SCHED_CONTEXT c6x_alloc_sched_context
#undef TARGET_SCHED_INIT_SCHED_CONTEXT
#define TARGET_SCHED_INIT_SCHED_CONTEXT c6x_init_sched_context
#undef TARGET_SCHED_SET_SCHED_CONTEXT
#define TARGET_SCHED_SET_SCHED_CONTEXT c6x_set_sched_context
#undef TARGET_SCHED_CLEAR_SCHED_CONTEXT
#define TARGET_SCHED_CLEAR_SCHED_CONTEXT c6x_clear_sched_context
#undef TARGET_SCHED_FREE_SCHED_CONTEXT
#define TARGET_SCHED_FREE_SCHED_CONTEXT c6x_free_sched_context

#undef TARGET_CAN_ELIMINATE
#define TARGET_CAN_ELIMINATE c6x_can_eliminate

#undef TARGET_PREFERRED_RENAME_CLASS
#define TARGET_PREFERRED_RENAME_CLASS c6x_preferred_rename_class

#undef TARGET_MACHINE_DEPENDENT_REORG
#define TARGET_MACHINE_DEPENDENT_REORG c6x_reorg

#undef TARGET_ASM_FILE_START
#define TARGET_ASM_FILE_START c6x_file_start

#undef  TARGET_PRINT_OPERAND
#define TARGET_PRINT_OPERAND c6x_print_operand
#undef  TARGET_PRINT_OPERAND_ADDRESS
#define TARGET_PRINT_OPERAND_ADDRESS c6x_print_operand_address
#undef  TARGET_PRINT_OPERAND_PUNCT_VALID_P
#define TARGET_PRINT_OPERAND_PUNCT_VALID_P c6x_print_operand_punct_valid_p

/* C6x unwinding tables use a different format for the typeinfo tables.  */
#undef TARGET_ASM_TTYPE
#define TARGET_ASM_TTYPE c6x_output_ttype

/* The C6x ABI follows the ARM EABI exception handling rules.  */
#undef TARGET_ARM_EABI_UNWINDER
#define TARGET_ARM_EABI_UNWINDER true

#undef TARGET_ASM_EMIT_EXCEPT_PERSONALITY
#define TARGET_ASM_EMIT_EXCEPT_PERSONALITY c6x_asm_emit_except_personality

#undef TARGET_ASM_INIT_SECTIONS
#define TARGET_ASM_INIT_SECTIONS c6x_asm_init_sections

#undef TARGET_DEBUG_UNWIND_INFO
#define TARGET_DEBUG_UNWIND_INFO  c6x_debug_unwind_info

#undef TARGET_DWARF_REGISTER_SPAN
#define TARGET_DWARF_REGISTER_SPAN c6x_dwarf_register_span

#undef TARGET_INIT_BUILTINS
#define TARGET_INIT_BUILTINS c6x_init_builtins
#undef TARGET_EXPAND_BUILTIN
#define TARGET_EXPAND_BUILTIN c6x_expand_builtin
#undef  TARGET_BUILTIN_DECL
#define TARGET_BUILTIN_DECL c6x_builtin_decl

#undef TARGET_HARD_REGNO_MODE_OK
#define TARGET_HARD_REGNO_MODE_OK c6x_hard_regno_mode_ok
#undef TARGET_MODES_TIEABLE_P
#define TARGET_MODES_TIEABLE_P c6x_modes_tieable_p

struct gcc_target targetm = TARGET_INITIALIZER;

#include "gt-c6x.h"
