/* Subroutines used for code generation on the EPIPHANY cpu.
   Copyright (C) 1994-2019 Free Software Foundation, Inc.
   Contributed by Embecosm on behalf of Adapteva, Inc.

This file is part of GCC.

GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 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 "df.h"
#include "memmodel.h"
#include "tm_p.h"
#include "stringpool.h"
#include "attribs.h"
#include "optabs.h"
#include "emit-rtl.h"
#include "recog.h"
#include "diagnostic-core.h"
#include "alias.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 "tm-constrs.h"
#include "tree-pass.h"	/* for current_pass */
#include "context.h"
#include "pass_manager.h"
#include "builtins.h"

/* Which cpu we're compiling for.  */
int epiphany_cpu_type;

/* Name of mangle string to add to symbols to separate code compiled for each
   cpu (or NULL).  */
const char *epiphany_mangle_cpu;

/* Array of valid operand punctuation characters.  */
char epiphany_punct_chars[256];

/* The rounding mode that we generally use for floating point.  */
int epiphany_normal_fp_rounding;

/* The pass instance, for use in epiphany_optimize_mode_switching. */
static opt_pass *pass_mode_switch_use;

static void epiphany_init_reg_tables (void);
static int get_epiphany_condition_code (rtx);
static tree epiphany_handle_interrupt_attribute (tree *, tree, tree, int, bool *);
static tree epiphany_handle_forwarder_attribute (tree *, tree, tree, int,
						 bool *);
static bool epiphany_pass_by_reference (cumulative_args_t, machine_mode,
					const_tree, bool);
static rtx_insn *frame_insn (rtx);

/* defines for the initialization of the GCC target structure.  */
#define TARGET_ATTRIBUTE_TABLE epiphany_attribute_table

#define TARGET_PRINT_OPERAND epiphany_print_operand
#define TARGET_PRINT_OPERAND_ADDRESS epiphany_print_operand_address

#define TARGET_RTX_COSTS epiphany_rtx_costs
#define TARGET_ADDRESS_COST epiphany_address_cost
#define TARGET_MEMORY_MOVE_COST epiphany_memory_move_cost

#define TARGET_PROMOTE_FUNCTION_MODE epiphany_promote_function_mode
#define TARGET_PROMOTE_PROTOTYPES hook_bool_const_tree_true

#define TARGET_RETURN_IN_MEMORY epiphany_return_in_memory
#define TARGET_PASS_BY_REFERENCE epiphany_pass_by_reference
#define TARGET_CALLEE_COPIES hook_bool_CUMULATIVE_ARGS_mode_tree_bool_true
#define TARGET_FUNCTION_VALUE epiphany_function_value
#define TARGET_LIBCALL_VALUE epiphany_libcall_value
#define TARGET_FUNCTION_VALUE_REGNO_P epiphany_function_value_regno_p

#define TARGET_SETUP_INCOMING_VARARGS epiphany_setup_incoming_varargs

/* Using the simplistic varags handling forces us to do partial reg/stack
   argument passing for types with larger size (> 4 bytes) than alignment.  */
#define TARGET_ARG_PARTIAL_BYTES epiphany_arg_partial_bytes

#define TARGET_FUNCTION_OK_FOR_SIBCALL epiphany_function_ok_for_sibcall

#define TARGET_SCHED_ISSUE_RATE epiphany_issue_rate
#define TARGET_SCHED_ADJUST_COST epiphany_adjust_cost

#define TARGET_LRA_P hook_bool_void_false

#define TARGET_LEGITIMATE_ADDRESS_P epiphany_legitimate_address_p

#define TARGET_SECONDARY_RELOAD epiphany_secondary_reload

#define TARGET_OPTION_OVERRIDE epiphany_override_options

#define TARGET_CONDITIONAL_REGISTER_USAGE epiphany_conditional_register_usage

#define TARGET_FUNCTION_ARG epiphany_function_arg

#define TARGET_FUNCTION_ARG_ADVANCE epiphany_function_arg_advance

#define TARGET_FUNCTION_ARG_BOUNDARY epiphany_function_arg_boundary

#define TARGET_TRAMPOLINE_INIT epiphany_trampoline_init

/* Nonzero if the constant rtx value is a legitimate general operand.
   We can handle any 32- or 64-bit constant.  */
#define TARGET_LEGITIMATE_CONSTANT_P hook_bool_mode_rtx_true

#define TARGET_MIN_DIVISIONS_FOR_RECIP_MUL \
  epiphany_min_divisions_for_recip_mul

#define TARGET_VECTORIZE_PREFERRED_SIMD_MODE epiphany_preferred_simd_mode

#define TARGET_VECTOR_MODE_SUPPORTED_P epiphany_vector_mode_supported_p

#define TARGET_VECTORIZE_VECTOR_ALIGNMENT_REACHABLE \
  epiphany_vector_alignment_reachable

#define TARGET_VECTORIZE_SUPPORT_VECTOR_MISALIGNMENT \
  epiphany_support_vector_misalignment

#define TARGET_ASM_CAN_OUTPUT_MI_THUNK \
  hook_bool_const_tree_hwi_hwi_const_tree_true
#define TARGET_ASM_OUTPUT_MI_THUNK epiphany_output_mi_thunk

/* ??? we can use larger offsets for wider-mode sized accesses, but there
   is no concept of anchors being dependent on the modes that they are used
   for, so we can only use an offset range that would suit all modes.  */
#define TARGET_MAX_ANCHOR_OFFSET (optimize_size ? 31 : 2047)
/* We further restrict the minimum to be a multiple of eight.  */
#define TARGET_MIN_ANCHOR_OFFSET (optimize_size ? 0 : -2040)

/* Mode switching hooks.  */

#define TARGET_MODE_EMIT emit_set_fp_mode

#define TARGET_MODE_NEEDED epiphany_mode_needed

#define TARGET_MODE_PRIORITY epiphany_mode_priority

#define TARGET_MODE_ENTRY epiphany_mode_entry

#define TARGET_MODE_EXIT epiphany_mode_exit

#define TARGET_MODE_AFTER epiphany_mode_after

#include "target-def.h"

#undef TARGET_ASM_ALIGNED_HI_OP
#define TARGET_ASM_ALIGNED_HI_OP "\t.hword\t"
#undef TARGET_ASM_ALIGNED_SI_OP
#define TARGET_ASM_ALIGNED_SI_OP "\t.word\t"

#undef TARGET_HARD_REGNO_MODE_OK
#define TARGET_HARD_REGNO_MODE_OK epiphany_hard_regno_mode_ok

#undef TARGET_CONSTANT_ALIGNMENT
#define TARGET_CONSTANT_ALIGNMENT epiphany_constant_alignment

#undef TARGET_STARTING_FRAME_OFFSET
#define TARGET_STARTING_FRAME_OFFSET epiphany_starting_frame_offset

bool
epiphany_is_interrupt_p (tree decl)
{
  tree attrs;

  attrs = DECL_ATTRIBUTES (decl);
  if (lookup_attribute ("interrupt", attrs))
    return true;
  else
    return false;
}

/* Called from epiphany_override_options.
   We use this to initialize various things.  */

static void
epiphany_init (void)
{
  /* N.B. this pass must not run before the first optimize_mode_switching
     pass because of the side offect of epiphany_mode_needed on
     MACHINE_FUNCTION(cfun)->unknown_mode_uses.  But it must run before
     pass_resolve_sw_modes.  */
  pass_mode_switch_use = make_pass_mode_switch_use (g);
  struct register_pass_info insert_use_info
    = { pass_mode_switch_use, "mode_sw",
	1, PASS_POS_INSERT_AFTER
      };
  opt_pass *mode_sw2
    = g->get_passes()->get_pass_mode_switching ()->clone ();
  struct register_pass_info mode_sw2_info
    = { mode_sw2, "mode_sw",
	1, PASS_POS_INSERT_AFTER
      };
  opt_pass *mode_sw3 = make_pass_resolve_sw_modes (g);
  struct register_pass_info mode_sw3_info
    = { mode_sw3, "mode_sw",
	1, PASS_POS_INSERT_AFTER
      };
  opt_pass *mode_sw4
    = g->get_passes()->get_pass_split_all_insns ()->clone ();
  struct register_pass_info mode_sw4_info
    = { mode_sw4, "mode_sw",
	1, PASS_POS_INSERT_AFTER
      };
  static const int num_modes[] = NUM_MODES_FOR_MODE_SWITCHING;
#define N_ENTITIES ARRAY_SIZE (num_modes)

  epiphany_init_reg_tables ();

  /* Initialize array for PRINT_OPERAND_PUNCT_VALID_P.  */
  memset (epiphany_punct_chars, 0, sizeof (epiphany_punct_chars));
  epiphany_punct_chars['-'] = 1;

  epiphany_normal_fp_rounding
    = (epiphany_normal_fp_mode == FP_MODE_ROUND_TRUNC
       ? FP_MODE_ROUND_TRUNC : FP_MODE_ROUND_NEAREST);
  register_pass (&mode_sw4_info);
  register_pass (&mode_sw2_info);
  register_pass (&mode_sw3_info);
  register_pass (&insert_use_info);
  register_pass (&mode_sw2_info);
  /* Verify that NUM_MODES_FOR_MODE_SWITCHING has one value per entity.  */
  gcc_assert (N_ENTITIES == EPIPHANY_MSW_ENTITY_NUM);

#if 1 /* As long as peep2_rescan is not implemented,
         (see http://gcc.gnu.org/ml/gcc-patches/2011-10/msg02819.html,)
         we need a second peephole2 pass to get reasonable code.  */
  {
    opt_pass *extra_peephole2
      = g->get_passes ()->get_pass_peephole2 ()->clone ();
    struct register_pass_info peep2_2_info
      = { extra_peephole2, "peephole2",
	  1, PASS_POS_INSERT_AFTER
	};

    register_pass (&peep2_2_info);
  }
#endif
}

/* The condition codes of the EPIPHANY, and the inverse function.  */
static const char *const epiphany_condition_codes[] =
{ /* 0    1      2      3      4      5      6     7      8      9   */
   "eq", "ne", "ltu", "gteu", "gt", "lte", "gte", "lt", "gtu", "lteu",
  /* 10   11    12     13  */
   "beq","bne","blt", "blte",
};

#define EPIPHANY_INVERSE_CONDITION_CODE(X)  ((X) ^ 1)

/* Returns the index of the EPIPHANY condition code string in
   `epiphany_condition_codes'.  COMPARISON should be an rtx like
   `(eq (...) (...))'.  */

static int
get_epiphany_condition_code (rtx comparison)
{
  switch (GET_MODE (XEXP (comparison, 0)))
    {
    case E_CCmode:
      switch (GET_CODE (comparison))
	{
	case EQ  : return 0;
	case NE  : return 1;
	case LTU : return 2;
	case GEU : return 3;
	case GT  : return 4;
	case LE  : return 5;
	case GE  : return 6;
	case LT  : return 7;
	case GTU : return 8;
	case LEU : return 9;

	default : gcc_unreachable ();
	}
    case E_CC_N_NEmode:
      switch (GET_CODE (comparison))
	{
	case EQ: return 6;
	case NE: return 7;
	default: gcc_unreachable ();
	}
    case E_CC_C_LTUmode:
      switch (GET_CODE (comparison))
	{
	case GEU: return 2;
	case LTU: return 3;
	default: gcc_unreachable ();
	}
    case E_CC_C_GTUmode:
      switch (GET_CODE (comparison))
	{
	case LEU: return 3;
	case GTU: return 2;
	default: gcc_unreachable ();
	}
    case E_CC_FPmode:
      switch (GET_CODE (comparison))
	{
	case EQ: return 10;
	case NE: return 11;
	case LT: return 12;
	case LE: return 13;
	default: gcc_unreachable ();
	}
    case E_CC_FP_EQmode:
      switch (GET_CODE (comparison))
	{
	case EQ: return 0;
	case NE: return 1;
	default: gcc_unreachable ();
	}
    case E_CC_FP_GTEmode:
      switch (GET_CODE (comparison))
	{
	case EQ: return 0;
	case NE: return 1;
	case GT : return 4;
	case GE : return 6;
	case UNLE : return 5;
	case UNLT : return 7;
	default: gcc_unreachable ();
	}
    case E_CC_FP_ORDmode:
      switch (GET_CODE (comparison))
	{
	case ORDERED: return 9;
	case UNORDERED: return 8;
	default: gcc_unreachable ();
	}
    case E_CC_FP_UNEQmode:
      switch (GET_CODE (comparison))
	{
	case UNEQ: return 9;
	case LTGT: return 8;
	default: gcc_unreachable ();
	}
    default: gcc_unreachable ();
    }
  /*NOTREACHED*/
  return (42);
}


/* Implement TARGET_HARD_REGNO_MODE_OK.  */

static bool
epiphany_hard_regno_mode_ok (unsigned int regno, machine_mode mode)
{
  if (GET_MODE_SIZE (mode) > UNITS_PER_WORD)
    return (regno & 1) == 0 && GPR_P (regno);
  else
    return true;
}

/* Given a comparison code (EQ, NE, etc.) and the first operand of a COMPARE,
   return the mode to be used for the comparison.  */

machine_mode
epiphany_select_cc_mode (enum rtx_code op,
			 rtx x ATTRIBUTE_UNUSED,
			 rtx y ATTRIBUTE_UNUSED)
{
  if (GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT)
    {
      if (TARGET_SOFT_CMPSF
	  || op == ORDERED || op == UNORDERED)
	{
	  if (op == EQ || op == NE)
	    return CC_FP_EQmode;
	  if (op == ORDERED || op == UNORDERED)
	    return CC_FP_ORDmode;
	  if (op == UNEQ || op == LTGT)
	    return CC_FP_UNEQmode;
	  return CC_FP_GTEmode;
	}
      return CC_FPmode;
    }
  /* recognize combiner pattern ashlsi_btst:
     (parallel [
	    (set (reg:N_NE 65 cc1)
		(compare:N_NE (zero_extract:SI (reg/v:SI 75 [ a ])
			(const_int 1 [0x1])
			(const_int 0 [0x0]))
		    (const_int 0 [0x0])))
	    (clobber (scratch:SI))  */
  else if ((op == EQ || op == NE)
	   && GET_CODE (x) == ZERO_EXTRACT
	   && XEXP (x, 1) == const1_rtx
	   && CONST_INT_P (XEXP (x, 2)))
    return CC_N_NEmode;
  else if ((op == GEU || op == LTU) && GET_CODE (x) == PLUS)
    return CC_C_LTUmode;
  else if ((op == LEU || op == GTU) && GET_CODE (x) == MINUS)
    return CC_C_GTUmode;
  else
    return CCmode;
}

enum reg_class epiphany_regno_reg_class[FIRST_PSEUDO_REGISTER];

static void
epiphany_init_reg_tables (void)
{
  int i;

  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
    {
      if (i == GPR_LR)
	epiphany_regno_reg_class[i] = LR_REGS;
      else if (i <= 7 && TARGET_PREFER_SHORT_INSN_REGS)
	epiphany_regno_reg_class[i] = SHORT_INSN_REGS;
      else if (call_used_regs[i]
	       && TEST_HARD_REG_BIT (reg_class_contents[GENERAL_REGS], i))
	epiphany_regno_reg_class[i] = SIBCALL_REGS;
      else if (i >= CORE_CONTROL_FIRST && i <= CORE_CONTROL_LAST)
	epiphany_regno_reg_class[i] = CORE_CONTROL_REGS;
      else if (i < (GPR_LAST+1)
	       || i == ARG_POINTER_REGNUM || i == FRAME_POINTER_REGNUM)
	epiphany_regno_reg_class[i] = GENERAL_REGS;
      else if (i == CC_REGNUM)
	epiphany_regno_reg_class[i] = NO_REGS /* CC_REG: must be NO_REGS */;
      else
	epiphany_regno_reg_class[i] = NO_REGS;
    }
}

/* EPIPHANY specific attribute support.

   The EPIPHANY has these attributes:
   interrupt - for interrupt functions.
   short_call - the function is assumed to be reachable with the b / bl
		instructions.
   long_call - the function address is loaded into a register before use.
   disinterrupt - functions which mask interrupts throughout.
                     They unmask them while calling an interruptible
		     function, though.  */

static const struct attribute_spec epiphany_attribute_table[] =
{
  /* { name, min_len, max_len, decl_req, type_req, fn_type_req,
       affects_type_identity, handler, exclude } */
  { "interrupt",  0, 9, true,  false, false, true,
    epiphany_handle_interrupt_attribute, NULL },
  { "forwarder_section", 1, 1, true, false, false, false,
    epiphany_handle_forwarder_attribute, NULL },
  { "long_call",  0, 0, false, true, true, false, NULL, NULL },
  { "short_call", 0, 0, false, true, true, false, NULL, NULL },
  { "disinterrupt", 0, 0, false, true, true, true, NULL, NULL },
  { NULL,         0, 0, false, false, false, false, NULL, NULL }
};

/* Handle an "interrupt" attribute; arguments as in
   struct attribute_spec.handler.  */
static tree
epiphany_handle_interrupt_attribute (tree *node, tree name, tree args,
				     int flags ATTRIBUTE_UNUSED,
				     bool *no_add_attrs)
{
  tree value;

  if (!args)
    {
      gcc_assert (DECL_P (*node));
      tree t = TREE_TYPE (*node);
      if (TREE_CODE (t) != FUNCTION_TYPE)
	warning (OPT_Wattributes, "%qE attribute only applies to functions",
		 name);
      /* Argument handling and the stack layout for interrupt handlers
	 don't mix.  It makes no sense in the first place, so emit an
	 error for this.  */
      else if (TYPE_ARG_TYPES (t)
	       && TREE_VALUE (TYPE_ARG_TYPES (t)) != void_type_node)
	error_at (DECL_SOURCE_LOCATION (*node),
		  "interrupt handlers cannot have arguments");
      return NULL_TREE;
    }

  value = TREE_VALUE (args);

  if (TREE_CODE (value) != STRING_CST)
    {
      warning (OPT_Wattributes,
	       "argument of %qE attribute is not a string constant", name);
      *no_add_attrs = true;
    }
  else if (strcmp (TREE_STRING_POINTER (value), "reset")
	   && strcmp (TREE_STRING_POINTER (value), "software_exception")
	   && strcmp (TREE_STRING_POINTER (value), "page_miss")
	   && strcmp (TREE_STRING_POINTER (value), "timer0")
	   && strcmp (TREE_STRING_POINTER (value), "timer1")
	   && strcmp (TREE_STRING_POINTER (value), "message")
	   && strcmp (TREE_STRING_POINTER (value), "dma0")
	   && strcmp (TREE_STRING_POINTER (value), "dma1")
	   && strcmp (TREE_STRING_POINTER (value), "wand")
	   && strcmp (TREE_STRING_POINTER (value), "swi"))
    {
      warning (OPT_Wattributes,
	       "argument of %qE attribute is not \"reset\", \"software_exception\", \"page_miss\", \"timer0\", \"timer1\", \"message\", \"dma0\", \"dma1\", \"wand\" or \"swi\"",
	       name);
      *no_add_attrs = true;
      return NULL_TREE;
    }

  return epiphany_handle_interrupt_attribute (node, name, TREE_CHAIN (args),
					      flags, no_add_attrs);
}

/* Handle a "forwarder_section" attribute; arguments as in
   struct attribute_spec.handler.  */
static tree
epiphany_handle_forwarder_attribute (tree *node ATTRIBUTE_UNUSED,
				     tree name, tree args,
				     int flags ATTRIBUTE_UNUSED,
				     bool *no_add_attrs)
{
  tree value;

  value = TREE_VALUE (args);

  if (TREE_CODE (value) != STRING_CST)
    {
      warning (OPT_Wattributes,
	       "argument of %qE attribute is not a string constant", name);
      *no_add_attrs = true;
    }
  return NULL_TREE;
}


/* Misc. utilities.  */

/* Generate a SYMBOL_REF for the special function NAME.  When the address
   can't be placed directly into a call instruction, and if possible, copy
   it to a register so that cse / code hoisting is possible.  */
rtx
sfunc_symbol (const char *name)
{
  rtx sym = gen_rtx_SYMBOL_REF (Pmode, name);

  /* These sfuncs should be hidden, and every dso should get a copy.  */
  SYMBOL_REF_FLAGS (sym) = SYMBOL_FLAG_FUNCTION | SYMBOL_FLAG_LOCAL;
  if (TARGET_SHORT_CALLS)
    ; /* Nothing to be done.  */
  else if (can_create_pseudo_p ())
    sym = copy_to_mode_reg (Pmode, sym);
  else /* We rely on reload to fix this up.  */
    gcc_assert (!reload_in_progress || reload_completed);
  return sym;
}

/* X and Y are two things to compare using CODE in IN_MODE.
   Emit the compare insn, construct the proper cc reg in the proper
   mode, and return the rtx for the cc reg comparison in CMODE.  */

rtx
gen_compare_reg (machine_mode cmode, enum rtx_code code,
		 machine_mode in_mode, rtx x, rtx y)
{
  machine_mode mode = SELECT_CC_MODE (code, x, y);
  rtx cc_reg, pat, clob0, clob1, clob2;

  if (in_mode == VOIDmode)
    in_mode = GET_MODE (x);
  if (in_mode == VOIDmode)
    in_mode = GET_MODE (y);

  if (mode == CC_FPmode)
    {
      /* The epiphany has only EQ / NE / LT / LE conditions for
	 hardware floating point.  */
      if (code == GT || code == GE || code == UNLE || code == UNLT)
	{
	  rtx tmp = x; x = y; y = tmp;
	  code = swap_condition (code);
	}
      cc_reg = gen_rtx_REG (mode, CCFP_REGNUM);
      y = force_reg (in_mode, y);
    }
  else
    {
      if (mode == CC_FP_GTEmode
	  && (code == LE || code == LT || code == UNGT || code == UNGE))
	{
	  if (flag_finite_math_only
	      && ((REG_P (x) && REGNO (x) == GPR_0)
		  || (REG_P (y) && REGNO (y) == GPR_1)))
	    switch (code)
	      {
	      case LE: code = UNLE; break;
	      case LT: code = UNLT; break;
	      case UNGT: code = GT; break;
	      case UNGE: code = GE; break;
	      default: gcc_unreachable ();
	      }
	  else
	    {
	      rtx tmp = x; x = y; y = tmp;
	      code = swap_condition (code);
	    }
	}
      cc_reg = gen_rtx_REG (mode, CC_REGNUM);
    }
  if ((mode == CC_FP_EQmode || mode == CC_FP_GTEmode
       || mode == CC_FP_ORDmode || mode == CC_FP_UNEQmode)
      /* mov<mode>cc might want to re-emit a comparison during ifcvt.  */
      && (!REG_P (x) || REGNO (x) != GPR_0
	  || !REG_P (y) || REGNO (y) != GPR_1))
    {
      rtx reg;

#if 0
      /* ??? We should really do the r0/r1 clobber only during rtl expansion,
	 but just like the flag clobber of movsicc, we have to allow
	 this for ifcvt to work, on the assumption that we'll only want
	 to do this if these registers have been used before by the
	 pre-ifcvt  code.  */
      gcc_assert (currently_expanding_to_rtl);
#endif
      reg = gen_rtx_REG (in_mode, GPR_0);
      if (reg_overlap_mentioned_p (reg, y))
	return 0;
      emit_move_insn (reg, x);
      x = reg;
      reg = gen_rtx_REG (in_mode, GPR_1);
      emit_move_insn (reg, y);
      y = reg;
    }
  else
    x = force_reg (in_mode, x);

  pat = gen_rtx_SET (cc_reg, gen_rtx_COMPARE (mode, x, y));
  if (mode == CC_FP_EQmode || mode == CC_FP_GTEmode)
    {
      const char *name = mode == CC_FP_EQmode ? "__eqsf2" : "__gtesf2";
      rtx use = gen_rtx_USE (VOIDmode, sfunc_symbol (name));

      clob0 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, GPR_IP));
      clob1 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, GPR_LR));
      pat = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (4, pat, use, clob0, clob1));
    }
  else if (mode == CC_FP_ORDmode || mode == CC_FP_UNEQmode)
    {
      const char *name = mode == CC_FP_ORDmode ? "__ordsf2" : "__uneqsf2";
      rtx use = gen_rtx_USE (VOIDmode, sfunc_symbol (name));

      clob0 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, GPR_IP));
      clob1 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, GPR_16));
      clob2 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, GPR_LR));
      pat = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (5, pat, use,
						   clob0, clob1, clob2));
    }
  else
    {
      clob0 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (in_mode));
      pat = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob0));
    }
  emit_insn (pat);
  return gen_rtx_fmt_ee (code, cmode, cc_reg, const0_rtx);
}

/* The ROUND_ADVANCE* macros are local to this file.  */
/* Round SIZE up to a word boundary.  */
#define ROUND_ADVANCE(SIZE) \
  (((SIZE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)

/* Round arg MODE/TYPE up to the next word boundary.  */
#define ROUND_ADVANCE_ARG(MODE, TYPE) \
  ((MODE) == BLKmode \
   ? ROUND_ADVANCE (int_size_in_bytes (TYPE)) \
   : ROUND_ADVANCE (GET_MODE_SIZE (MODE)))

/* Round CUM up to the necessary point for argument MODE/TYPE.  */
#define ROUND_ADVANCE_CUM(CUM, MODE, TYPE) \
  (epiphany_function_arg_boundary ((MODE), (TYPE)) > BITS_PER_WORD \
   ? (((CUM) + 1) & ~1)	\
   : (CUM))

static unsigned int
epiphany_function_arg_boundary (machine_mode mode, const_tree type)
{
  if ((type ? TYPE_ALIGN (type) : GET_MODE_BITSIZE (mode)) <= PARM_BOUNDARY)
    return PARM_BOUNDARY;
  return 2 * PARM_BOUNDARY;
}

/* Do any needed setup for a variadic function.  For the EPIPHANY, we
   actually emit the code in epiphany_expand_prologue.

   CUM has not been updated for the last named argument which has type TYPE
   and mode MODE, and we rely on this fact.  */


static void
epiphany_setup_incoming_varargs (cumulative_args_t cum, machine_mode mode,
				 tree type, int *pretend_size, int no_rtl)
{
  int first_anon_arg;
  CUMULATIVE_ARGS next_cum;
  machine_function_t *mf = MACHINE_FUNCTION (cfun);

  /* All BLKmode values are passed by reference.  */
  gcc_assert (mode != BLKmode);

  next_cum = *get_cumulative_args (cum);
  next_cum
    = ROUND_ADVANCE_CUM (next_cum, mode, type) + ROUND_ADVANCE_ARG (mode, type);
  first_anon_arg = next_cum;

  if (first_anon_arg < MAX_EPIPHANY_PARM_REGS && !no_rtl)
    {
      /* Note that first_reg_offset < MAX_EPIPHANY_PARM_REGS.  */
      int first_reg_offset = first_anon_arg;

      *pretend_size = ((MAX_EPIPHANY_PARM_REGS - first_reg_offset)
		       * UNITS_PER_WORD);
    }
  mf->args_parsed = 1;
  mf->pretend_args_odd = ((*pretend_size & UNITS_PER_WORD) ? 1 : 0);
}

static int
epiphany_arg_partial_bytes (cumulative_args_t cum, machine_mode mode,
			    tree type, bool named ATTRIBUTE_UNUSED)
{
  int words = 0, rounded_cum;

  gcc_assert (!epiphany_pass_by_reference (cum, mode, type, /* named */ true));

  rounded_cum = ROUND_ADVANCE_CUM (*get_cumulative_args (cum), mode, type);
  if (rounded_cum < MAX_EPIPHANY_PARM_REGS)
    {
      words = MAX_EPIPHANY_PARM_REGS - rounded_cum;
      if (words >= ROUND_ADVANCE_ARG (mode, type))
	words = 0;
    }
  return words * UNITS_PER_WORD;
}

/* Cost functions.  */

/* 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
epiphany_rtx_costs (rtx x, machine_mode mode, int outer_code,
		    int opno ATTRIBUTE_UNUSED,
		    int *total, bool speed ATTRIBUTE_UNUSED)
{
  int code = GET_CODE (x);

  switch (code)
    {
      /* Small integers in the right context are as cheap as registers.  */
    case CONST_INT:
      if ((outer_code == PLUS || outer_code == MINUS)
	  && SIMM11 (INTVAL (x)))
	{
	  *total = 0;
	  return true;
	}
      if (IMM16 (INTVAL (x)))
	{
	  *total = outer_code == SET ? 0 : COSTS_N_INSNS (1);
	  return true;
	}
      /* FALLTHRU */

    case CONST:
    case LABEL_REF:
    case SYMBOL_REF:
      *total = COSTS_N_INSNS ((epiphany_small16 (x) ? 0 : 1)
			      + (outer_code == SET ? 0 : 1));
      return true;

    case CONST_DOUBLE:
      {
	rtx high, low;
	split_double (x, &high, &low);
	*total = COSTS_N_INSNS (!IMM16 (INTVAL (high))
				+ !IMM16 (INTVAL (low)));
	return true;
      }

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

    case COMPARE:
      switch (mode)
	{
	/* There are a number of single-insn combiner patterns that use
	   the flag side effects of arithmetic.  */
	case E_CC_N_NEmode:
	case E_CC_C_LTUmode:
	case E_CC_C_GTUmode:
	  return true;
	default:
	  return false;
	}

	
    case SET:
      {
	rtx src = SET_SRC (x);
	if (BINARY_P (src))
	  *total = 0;
	return false;
      }

    default:
      return false;
    }
}


/* Provide the costs of an addressing mode that contains ADDR.
   If ADDR is not a valid address, its cost is irrelevant.  */

static int
epiphany_address_cost (rtx addr, machine_mode mode,
		       addr_space_t as ATTRIBUTE_UNUSED, bool speed)
{
  rtx reg;
  rtx off = const0_rtx;
  int i;

  if (speed)
    return 0;
  /* Return 0 for addresses valid in short insns, 1 for addresses only valid
     in long insns.  */
  switch (GET_CODE (addr))
    {
    case PLUS :
      reg = XEXP (addr, 0);
      off = XEXP (addr, 1);
      break;
    case POST_MODIFY:
      reg = XEXP (addr, 0);
      off = XEXP (addr, 1);
      gcc_assert (GET_CODE (off) == PLUS && rtx_equal_p (reg, XEXP (off, 0)));
      off = XEXP (off, 1);
      if (satisfies_constraint_Rgs (reg) && satisfies_constraint_Rgs (off))
	return 0;
      return 1;
    case REG:
    default:
      reg = addr;
      break;
    }
  if (!satisfies_constraint_Rgs (reg))
    return 1;
  /* The offset range available for short instructions depends on the mode
     of the memory access.  */
  /* First, make sure we have a valid integer.  */
  if (!satisfies_constraint_L (off))
    return 1;
  i = INTVAL (off);
  switch (GET_MODE_SIZE (mode))
    {
      default:
      case 4:
	if (i & 1)
	  return 1;
	i >>= 1;
	/* Fall through.  */
      case 2:
	if (i & 1)
	  return 1;
	i >>= 1;
	/* Fall through.  */
      case 1:
	return i < -7 || i > 7;
    }
}

/* Compute the cost of moving data between registers and memory.
   For integer, load latency is twice as long as register-register moves,
   but issue pich is the same.  For floating point, load latency is three
   times as much as a reg-reg move.  */
static int
epiphany_memory_move_cost (machine_mode mode,
                          reg_class_t rclass ATTRIBUTE_UNUSED,
                          bool in ATTRIBUTE_UNUSED)
{
  return GET_MODE_CLASS (mode) == MODE_INT ? 3 : 4;
}

/* Function prologue/epilogue handlers.  */

/* EPIPHANY stack frames look like:

	     Before call                       After call
	+-----------------------+       +-----------------------+
	|                       |       |                       |
   high |  local variables,     |       |  local variables,     |
   mem  |  reg save area, etc.  |       |  reg save area, etc.  |
	|                       |       |                       |
	+-----------------------+       +-----------------------+
	|                       |       |                       |
	|  arguments on stack.  |       |  arguments on stack.  |
	|                       |       |                       |
  SP+8->+-----------------------+FP+8m->+-----------------------+
	| 2 word save area for  |       |  reg parm save area,  |
	| leaf funcs / flags    |       |  only created for     |
  SP+0->+-----------------------+       |  variable argument    |
					|  functions            |
				 FP+8n->+-----------------------+
					|                       |
					|  register save area   |
					|                       |
					+-----------------------+
					|                       |
					|  local variables      |
					|                       |
				  FP+0->+-----------------------+
					|                       |
					|  alloca allocations   |
					|                       |
					+-----------------------+
					|                       |
					|  arguments on stack   |
					|                       |
				  SP+8->+-----------------------+
   low                                  | 2 word save area for  |
   memory                               | leaf funcs / flags    |
				  SP+0->+-----------------------+

Notes:
1) The "reg parm save area" does not exist for non variable argument fns.
   The "reg parm save area" could be eliminated if we created our
   own TARGET_GIMPLIFY_VA_ARG_EXPR, but that has tradeoffs as well
   (so it's not done).  */

/* Structure to be filled in by epiphany_compute_frame_size with register
   save masks, and offsets for the current function.  */
struct epiphany_frame_info
{
  unsigned int total_size;	/* # bytes that the entire frame takes up.  */
  unsigned int pretend_size;	/* # bytes we push and pretend caller did.  */
  unsigned int args_size;	/* # bytes that outgoing arguments take up.  */
  unsigned int reg_size;	/* # bytes needed to store regs.  */
  unsigned int var_size;	/* # bytes that variables take up.  */
  HARD_REG_SET gmask;		/* Set of saved gp registers.  */
  int          initialized;	/* Nonzero if frame size already calculated.  */
  int      stld_sz;             /* Current load/store data size for offset
				   adjustment. */
  int      need_fp;             /* value to override "frame_pointer_needed */
  /* FIRST_SLOT is the slot that is saved first, at the very start of
     the frame, with a POST_MODIFY to allocate the frame, if the size fits,
     or at least the parm and register save areas, otherwise.
     In the case of a large frame, LAST_SLOT is the slot that is saved last,
     with a POST_MODIFY to allocate the rest of the frame.  */
  int first_slot, last_slot, first_slot_offset, last_slot_offset;
  int first_slot_size;
  int small_threshold;
};

/* Current frame information calculated by epiphany_compute_frame_size.  */
static struct epiphany_frame_info current_frame_info;

/* Zero structure to initialize current_frame_info.  */
static struct epiphany_frame_info zero_frame_info;

/* The usual; we set up our machine_function data.  */
static struct machine_function *
epiphany_init_machine_status (void)
{
  struct machine_function *machine;

  /* Reset state info for each function.  */
  current_frame_info = zero_frame_info;

  machine = ggc_cleared_alloc<machine_function_t> ();

  return machine;
}

/* Implements INIT_EXPANDERS.  We just set up to call the above
 *    function.  */
void
epiphany_init_expanders (void)
{
  init_machine_status = epiphany_init_machine_status;
}

/* Type of function DECL.

   The result is cached.  To reset the cache at the end of a function,
   call with DECL = NULL_TREE.  */

static enum epiphany_function_type
epiphany_compute_function_type (tree decl)
{
  tree a;
  /* Cached value.  */
  static enum epiphany_function_type fn_type = EPIPHANY_FUNCTION_UNKNOWN;
  /* Last function we were called for.  */
  static tree last_fn = NULL_TREE;

  /* Resetting the cached value?  */
  if (decl == NULL_TREE)
    {
      fn_type = EPIPHANY_FUNCTION_UNKNOWN;
      last_fn = NULL_TREE;
      return fn_type;
    }

  if (decl == last_fn && fn_type != EPIPHANY_FUNCTION_UNKNOWN)
    return fn_type;

  /* Assume we have a normal function (not an interrupt handler).  */
  fn_type = EPIPHANY_FUNCTION_NORMAL;

  /* Now see if this is an interrupt handler.  */
  for (a = DECL_ATTRIBUTES (decl);
       a;
       a = TREE_CHAIN (a))
    {
      tree name = TREE_PURPOSE (a);

      if (name == get_identifier ("interrupt"))
	fn_type = EPIPHANY_FUNCTION_INTERRUPT;
    }

  last_fn = decl;
  return fn_type;
}

#define RETURN_ADDR_REGNUM GPR_LR
#define FRAME_POINTER_MASK (1 << (FRAME_POINTER_REGNUM))
#define RETURN_ADDR_MASK (1 << (RETURN_ADDR_REGNUM))

/* Tell prologue and epilogue if register REGNO should be saved / restored.
   The return address and frame pointer are treated separately.
   Don't consider them here.  */
#define MUST_SAVE_REGISTER(regno, interrupt_p) \
  ((df_regs_ever_live_p (regno) \
    || (interrupt_p && !crtl->is_leaf \
	&& call_used_regs[regno] && !fixed_regs[regno])) \
   && (!call_used_regs[regno] || regno == GPR_LR \
       || (interrupt_p && regno != GPR_SP)))

#define MUST_SAVE_RETURN_ADDR 0

/* Return the bytes needed to compute the frame pointer from the current
   stack pointer.

   SIZE is the size needed for local variables.  */

static unsigned int
epiphany_compute_frame_size (int size /* # of var. bytes allocated.  */)
{
  int regno;
  unsigned int total_size, var_size, args_size, pretend_size, reg_size;
  HARD_REG_SET gmask;
  enum epiphany_function_type fn_type;
  int interrupt_p;
  int first_slot, last_slot, first_slot_offset, last_slot_offset;
  int first_slot_size;
  int small_slots = 0;

  var_size	= size;
  args_size	= crtl->outgoing_args_size;
  pretend_size	= crtl->args.pretend_args_size;
  total_size	= args_size + var_size;
  reg_size	= 0;
  CLEAR_HARD_REG_SET (gmask);
  first_slot = -1;
  first_slot_offset = 0;
  last_slot = -1;
  last_slot_offset = 0;
  first_slot_size = UNITS_PER_WORD;

  /* See if this is an interrupt handler.  Call used registers must be saved
     for them too.  */
  fn_type = epiphany_compute_function_type (current_function_decl);
  interrupt_p = EPIPHANY_INTERRUPT_P (fn_type);

  /* Calculate space needed for registers.  */

  for (regno = MAX_EPIPHANY_PARM_REGS - 1; pretend_size > reg_size; regno--)
    {
      reg_size += UNITS_PER_WORD;
      SET_HARD_REG_BIT (gmask, regno);
      if (epiphany_stack_offset - reg_size == 0)
	first_slot = regno;
    }

  if (interrupt_p)
    reg_size += 2 * UNITS_PER_WORD;
  else
    small_slots = epiphany_stack_offset / UNITS_PER_WORD;

  if (frame_pointer_needed)
    {
      current_frame_info.need_fp = 1;
      if (!interrupt_p && first_slot < 0)
	first_slot = GPR_FP;
    }
  else
    current_frame_info.need_fp = 0;
  for (regno = 0; regno <= GPR_LAST; regno++)
    {
      if (MUST_SAVE_REGISTER (regno, interrupt_p))
	{
	  gcc_assert (!TEST_HARD_REG_BIT (gmask, regno));
	  reg_size += UNITS_PER_WORD;
	  SET_HARD_REG_BIT (gmask, regno);
	  /* FIXME: when optimizing for speed, take schedling into account
	     when selecting these registers.  */
	  if (regno == first_slot)
	    gcc_assert (regno == GPR_FP && frame_pointer_needed);
	  else if (!interrupt_p && first_slot < 0)
	    first_slot = regno;
	  else if (last_slot < 0
		   && (first_slot ^ regno) != 1
		   && (!interrupt_p || regno > GPR_1))
	    last_slot = regno;
	}
    }
  if (TEST_HARD_REG_BIT (gmask, GPR_LR))
    MACHINE_FUNCTION (cfun)->lr_clobbered = 1;
  /* ??? Could sometimes do better than that.  */
  current_frame_info.small_threshold
    = (optimize >= 3 || interrupt_p ? 0
       : pretend_size ? small_slots
       : 4 + small_slots - (first_slot == GPR_FP));

  /* If there might be variables with 64-bit alignment requirement, align the
     start of the variables.  */
  if (var_size >= 2 * UNITS_PER_WORD
      /* We don't want to split a double reg save/restore across two unpaired
	 stack slots when optimizing.  This rounding could be avoided with
	 more complex reordering of the register saves, but that would seem
	 to be a lot of code complexity for little gain.  */
      || (reg_size > 8 && optimize))
    reg_size = EPIPHANY_STACK_ALIGN (reg_size);
  if (((total_size + reg_size
	/* Reserve space for UNKNOWN_REGNUM.  */
	+ EPIPHANY_STACK_ALIGN (4))
       <= (unsigned) epiphany_stack_offset)
      && !interrupt_p
      && crtl->is_leaf && !frame_pointer_needed)
    {
      first_slot = -1;
      last_slot = -1;
      goto alloc_done;
    }
  else if (reg_size
	   && !interrupt_p
	   && reg_size < (unsigned HOST_WIDE_INT) epiphany_stack_offset)
    reg_size = epiphany_stack_offset;
  if (interrupt_p)
    {
      if (total_size + reg_size < 0x3fc)
	{
	  first_slot_offset = EPIPHANY_STACK_ALIGN (total_size + reg_size);
	  first_slot_offset += EPIPHANY_STACK_ALIGN (epiphany_stack_offset);
	  last_slot = -1;
	}
      else
	{
	  first_slot_offset = EPIPHANY_STACK_ALIGN (reg_size);
	  last_slot_offset = EPIPHANY_STACK_ALIGN (total_size);
	  last_slot_offset += EPIPHANY_STACK_ALIGN (epiphany_stack_offset);
	  if (last_slot >= 0)
	    CLEAR_HARD_REG_BIT (gmask, last_slot);
	}
    }
  else if (total_size + reg_size < 0x1ffc && first_slot >= 0)
    {
      first_slot_offset = EPIPHANY_STACK_ALIGN (total_size + reg_size);
      last_slot = -1;
    }
  else
    {
      if (total_size + reg_size <= (unsigned) epiphany_stack_offset)
	{
	  gcc_assert (first_slot < 0);
	  gcc_assert (reg_size == 0 || (int) reg_size == epiphany_stack_offset);
	  last_slot_offset = EPIPHANY_STACK_ALIGN (total_size + reg_size);
	}
      else
	{
	  first_slot_offset
	    = (reg_size
	       ? EPIPHANY_STACK_ALIGN (reg_size - epiphany_stack_offset) : 0);
	  if (!first_slot_offset)
	    {
	      if (first_slot != GPR_FP || !current_frame_info.need_fp)
		last_slot = first_slot;
	      first_slot = -1;
	    }
	  last_slot_offset = EPIPHANY_STACK_ALIGN (total_size);
	  if (reg_size)
	    last_slot_offset += EPIPHANY_STACK_ALIGN (epiphany_stack_offset);
	}
      if (last_slot >= 0)
	CLEAR_HARD_REG_BIT (gmask, last_slot);
    }
 alloc_done:
  if (first_slot >= 0)
    {
      CLEAR_HARD_REG_BIT (gmask, first_slot);
      if (TEST_HARD_REG_BIT (gmask, first_slot ^ 1)
	  && epiphany_stack_offset - pretend_size >= 2 * UNITS_PER_WORD)
	{
	  CLEAR_HARD_REG_BIT (gmask, first_slot ^ 1);
	  first_slot_size = 2 * UNITS_PER_WORD;
	  first_slot &= ~1;
	}
    }
  total_size = first_slot_offset + last_slot_offset;

  /* Save computed information.  */
  current_frame_info.total_size   = total_size;
  current_frame_info.pretend_size = pretend_size;
  current_frame_info.var_size     = var_size;
  current_frame_info.args_size    = args_size;
  current_frame_info.reg_size	  = reg_size;
  COPY_HARD_REG_SET (current_frame_info.gmask, gmask);
  current_frame_info.first_slot		= first_slot;
  current_frame_info.last_slot		= last_slot;
  current_frame_info.first_slot_offset	= first_slot_offset;
  current_frame_info.first_slot_size	= first_slot_size;
  current_frame_info.last_slot_offset	= last_slot_offset;

  current_frame_info.initialized  = reload_completed;

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

static void
epiphany_print_operand (FILE *file, rtx x, int code)
{
  switch (code)
    {
    case 'd':
      fputs (epiphany_condition_codes[get_epiphany_condition_code (x)], file);
      return;
    case 'D':
     fputs (epiphany_condition_codes[EPIPHANY_INVERSE_CONDITION_CODE
				 (get_epiphany_condition_code (x))],
	     file);
      return;

    case 'X':
      current_frame_info.stld_sz = 8;
      break;

    case 'C' :
      current_frame_info.stld_sz = 4;
      break;

    case 'c' :
      current_frame_info.stld_sz = 2;
      break;

    case 'f':
     fputs (REG_P (x) ? "jalr " : "bl ", file);
     break;

    case '-':
    fprintf (file, "r%d", epiphany_m1reg);
    return;

    case 0 :
      /* Do nothing special.  */
      break;
    default :
      /* Unknown flag.  */
      output_operand_lossage ("invalid operand output code");
    }

  switch (GET_CODE (x))
    {
      rtx addr;
      rtx offset;

    case REG :
      fputs (reg_names[REGNO (x)], file);
      break;
    case MEM :
      if (code == 0)
	current_frame_info.stld_sz = 1;
      fputc ('[', file);
      addr = XEXP (x, 0);
      switch (GET_CODE (addr))
	{
	  case POST_INC:
	    offset = GEN_INT (GET_MODE_SIZE (GET_MODE (x)));
	    addr = XEXP (addr, 0);
	    break;
	  case POST_DEC:
	    offset = GEN_INT (-GET_MODE_SIZE (GET_MODE (x)));
	    addr = XEXP (addr, 0);
	    break;
	  case POST_MODIFY:
	    offset = XEXP (XEXP (addr, 1), 1);
	    addr = XEXP (addr, 0);
	    break;
	  default:
	    offset = 0;
	    break;
	}
      output_address (GET_MODE (x), addr);
      fputc (']', file);
      if (offset)
	{
	  fputc (',', file);
	  if (CONST_INT_P (offset)) switch (GET_MODE_SIZE (GET_MODE (x)))
	    {
	      default:
		gcc_unreachable ();
	      case 8:
		offset = GEN_INT (INTVAL (offset) >> 3);
		break;
	      case 4:
		offset = GEN_INT (INTVAL (offset) >> 2);
		break;
	      case 2:
		offset = GEN_INT (INTVAL (offset) >> 1);
		break;
	      case 1:
		break;
	    }
	  output_address (GET_MODE (x), offset);
	}
      break;
    case CONST_DOUBLE :
      /* We handle SFmode constants here as output_addr_const doesn't.  */
      if (GET_MODE (x) == SFmode)
	{
	  long l;

	  REAL_VALUE_TO_TARGET_SINGLE (*CONST_DOUBLE_REAL_VALUE (x), l);
	  fprintf (file, "%s0x%08lx", IMMEDIATE_PREFIX, l);
	  break;
	}
      /* FALLTHRU */
      /* Let output_addr_const deal with it.  */
    case CONST_INT:
      fprintf(file,"%s",IMMEDIATE_PREFIX);
      if (code == 'C' || code == 'X')
	{
	  fprintf (file, "%ld",
		   (long) (INTVAL (x) / current_frame_info.stld_sz));
	  break;
	}
      /* Fall through */
    default :
      output_addr_const (file, x);
      break;
    }
}

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

static void
epiphany_print_operand_address (FILE *file, machine_mode /*mode*/, rtx addr)
{
  register rtx base, index = 0;
  int offset = 0;

  switch (GET_CODE (addr))
    {
    case REG :
      fputs (reg_names[REGNO (addr)], file);
      break;
    case SYMBOL_REF :
      if (/*???*/ 0 && SYMBOL_REF_FUNCTION_P (addr))
	{
	  output_addr_const (file, addr);
	}
      else
	{
	  output_addr_const (file, addr);
	}
      break;
    case PLUS :
      if (GET_CODE (XEXP (addr, 0)) == CONST_INT)
	offset = INTVAL (XEXP (addr, 0)), base = XEXP (addr, 1);
      else if (GET_CODE (XEXP (addr, 1)) == CONST_INT)
	offset = INTVAL (XEXP (addr, 1)), base = XEXP (addr, 0);
      else
	base = XEXP (addr, 0), index = XEXP (addr, 1);
      gcc_assert (GET_CODE (base) == REG);
      fputs (reg_names[REGNO (base)], file);
      if (index == 0)
	{
	  /*
	  ** ++rk quirky method to scale offset for ld/str.......
	  */
	  fprintf (file, ",%s%d", IMMEDIATE_PREFIX,
		   offset/current_frame_info.stld_sz);
	}
      else
	{
	  switch (GET_CODE (index))
	    {
	    case REG:
	      fprintf (file, ",%s", reg_names[REGNO (index)]);
	      break;
	    case SYMBOL_REF:
	      fputc (',', file), output_addr_const (file, index);
	      break;
	    default:
	      gcc_unreachable ();
	    }
	}
      break;
    case PRE_INC: case PRE_DEC: case POST_INC: case POST_DEC: case POST_MODIFY:
      /* We shouldn't get here as we've lost the mode of the memory object
	 (which says how much to inc/dec by.
	 FIXME: We have the mode now, address printing can be moved into this
	 function.  */
      gcc_unreachable ();
      break;
    default:
      output_addr_const (file, addr);
      break;
    }
}

void
epiphany_final_prescan_insn (rtx_insn *insn ATTRIBUTE_UNUSED,
			     rtx *opvec ATTRIBUTE_UNUSED,
			     int noperands ATTRIBUTE_UNUSED)
{
  int i = epiphany_n_nops;
  rtx pat ATTRIBUTE_UNUSED;

  while (i--)
    fputs ("\tnop\n", asm_out_file);
}


/* Worker function for TARGET_RETURN_IN_MEMORY.  */

static bool
epiphany_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
{
  HOST_WIDE_INT size = int_size_in_bytes (type);

  if (AGGREGATE_TYPE_P (type)
      && (TYPE_MODE (type) == BLKmode || TYPE_NEEDS_CONSTRUCTING (type)))
    return true;
  return (size == -1 || size > 8);
}

/* For EPIPHANY, All aggregates and arguments greater than 8 bytes are
   passed by reference.  */

static bool
epiphany_pass_by_reference (cumulative_args_t ca ATTRIBUTE_UNUSED,
		       machine_mode mode, const_tree type,
		       bool named ATTRIBUTE_UNUSED)
{
  if (type)
    {
      if (AGGREGATE_TYPE_P (type)
	  && (mode == BLKmode || TYPE_NEEDS_CONSTRUCTING (type)))
	return true;
    }
  return false;
}


static rtx
epiphany_function_value (const_tree ret_type,
			 const_tree fn_decl_or_type ATTRIBUTE_UNUSED,
			 bool outgoing ATTRIBUTE_UNUSED)
{
  machine_mode mode;

  mode = TYPE_MODE (ret_type);
  /* We must change the mode like PROMOTE_MODE does.
     ??? PROMOTE_MODE is ignored for non-scalar types.
     The set of types tested here has to be kept in sync
     with the one in explow.c:promote_mode.  */
  if (GET_MODE_CLASS (mode) == MODE_INT
      && GET_MODE_SIZE (mode) < 4
      && (TREE_CODE (ret_type) == INTEGER_TYPE
          || TREE_CODE (ret_type) == ENUMERAL_TYPE
          || TREE_CODE (ret_type) == BOOLEAN_TYPE
          || TREE_CODE (ret_type) == OFFSET_TYPE))
    mode = SImode;
  return gen_rtx_REG (mode, 0);
}

static rtx
epiphany_libcall_value (machine_mode mode, const_rtx fun ATTRIBUTE_UNUSED)
{
  return gen_rtx_REG (mode, 0);
}

static bool
epiphany_function_value_regno_p (const unsigned int regno ATTRIBUTE_UNUSED)
{
  return regno == 0;
}

/* Fix up invalid option settings.  */
static void
epiphany_override_options (void)
{
  if (epiphany_stack_offset < 4)
    error ("stack_offset must be at least 4");
  if (epiphany_stack_offset & 3)
    error ("stack_offset must be a multiple of 4");
  epiphany_stack_offset = (epiphany_stack_offset + 3) & -4;
 if (!TARGET_SOFT_CMPSF)
   flag_finite_math_only = 1;

  /* This needs to be done at start up.  It's convenient to do it here.  */
  epiphany_init ();
}

/* For a DImode load / store SET, make a SImode set for a
   REG_FRAME_RELATED_EXPR note, using OFFSET to create a high or lowpart
   subreg.  */
static rtx
frame_subreg_note (rtx set, int offset)
{
  rtx src = simplify_gen_subreg (SImode, SET_SRC (set), DImode, offset);
  rtx dst = simplify_gen_subreg (SImode, SET_DEST (set), DImode, offset);

  set = gen_rtx_SET (dst ,src);
  RTX_FRAME_RELATED_P (set) = 1;
  return set;
}

static rtx_insn *
frame_insn (rtx x)
{
  int i;
  rtx note = NULL_RTX;
  rtx_insn *insn;

  if (GET_CODE (x) == PARALLEL)
    {
      rtx part = XVECEXP (x, 0, 0);

      if (GET_MODE (SET_DEST (part)) == DImode)
	{
	  note = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (XVECLEN (x, 0) + 1));
	  XVECEXP (note, 0, 0) = frame_subreg_note (part, 0);
	  XVECEXP (note, 0, 1) = frame_subreg_note (part, UNITS_PER_WORD);
	  for (i = XVECLEN (x, 0) - 1; i >= 1; i--)
	    {
	      part = copy_rtx (XVECEXP (x, 0, i));

	      if (GET_CODE (part) == SET)
		RTX_FRAME_RELATED_P (part) = 1;
	      XVECEXP (note, 0, i + 1) = part;
	    }
	}
      else
	{
	  for (i = XVECLEN (x, 0) - 1; i >= 0; i--)
	    {
	      part = XVECEXP (x, 0, i);

	      if (GET_CODE (part) == SET)
		RTX_FRAME_RELATED_P (part) = 1;
	    }
	}
    }
  else if (GET_CODE (x) == SET && GET_MODE (SET_DEST (x)) == DImode)
    note = gen_rtx_PARALLEL (VOIDmode,
			     gen_rtvec (2, frame_subreg_note (x, 0),
					frame_subreg_note (x, UNITS_PER_WORD)));
  insn = emit_insn (x);
  RTX_FRAME_RELATED_P (insn) = 1;
  if (note)
    add_reg_note (insn, REG_FRAME_RELATED_EXPR, note);
  return insn;
}

static rtx_insn *
frame_move_insn (rtx to, rtx from)
{
  return frame_insn (gen_rtx_SET (to, from));
}

/* Generate a MEM referring to a varargs argument slot.  */

static rtx
gen_varargs_mem (machine_mode mode, rtx addr)
{
  rtx mem = gen_rtx_MEM (mode, addr);
  MEM_NOTRAP_P (mem) = 1;
  set_mem_alias_set (mem, get_varargs_alias_set ());
  return mem;
}

/* Emit instructions to save or restore registers in the range [MIN..LIMIT) .
   If EPILOGUE_P is 0, save; if it is one, restore.
   ADDR is the stack slot to save the first register to; subsequent
   registers are written to lower addresses.
   However, the order of register pairs can be reversed in order to
   use double-word load-store instructions.  Likewise, an unpaired single
   word save slot can be skipped while double saves are carried out, and
   reused when a single register is to be saved.  */

static void
epiphany_emit_save_restore (int min, int limit, rtx addr, int epilogue_p)
{
  int i;
  int stack_offset
    = current_frame_info.first_slot >= 0 ? epiphany_stack_offset : 0;
  rtx skipped_mem = NULL_RTX;
  int last_saved = limit - 1;

  if (!optimize)
    while (last_saved >= 0
	   && !TEST_HARD_REG_BIT (current_frame_info.gmask, last_saved))
      last_saved--;
  for (i = 0; i < limit; i++)
    {
      machine_mode mode = word_mode;
      rtx mem, reg;
      int n = i;
      rtx (*gen_mem) (machine_mode, rtx) = gen_frame_mem;

      /* Make sure we push the arguments in the right order.  */
      if (n < MAX_EPIPHANY_PARM_REGS && crtl->args.pretend_args_size)
	{
	  n = MAX_EPIPHANY_PARM_REGS - 1 - n;
	  gen_mem = gen_varargs_mem;
	}
      if (stack_offset == current_frame_info.first_slot_size
	  && current_frame_info.first_slot >= 0)
	{
	  if (current_frame_info.first_slot_size > UNITS_PER_WORD)
	    {
	      mode = DImode;
	      addr = plus_constant (Pmode, addr,
				    - (HOST_WIDE_INT) UNITS_PER_WORD);
	    }
	  if (i-- < min || !epilogue_p)
	    goto next_slot;
	  n = current_frame_info.first_slot;
	  gen_mem = gen_frame_mem;
	}
      else if (n == UNKNOWN_REGNUM
	       && stack_offset > current_frame_info.first_slot_size)
	{
	  i--;
	  goto next_slot;
	}
      else if (!TEST_HARD_REG_BIT (current_frame_info.gmask, n))
	continue;
      else if (i < min)
	goto next_slot;

      /* Check for a register pair to save.  */
      if (n == i
	  && (n >= MAX_EPIPHANY_PARM_REGS || crtl->args.pretend_args_size == 0)
	  && (n & 1) == 0 && n+1 < limit
	  && TEST_HARD_REG_BIT (current_frame_info.gmask, n+1))
	{
	  /* If it fits in the current stack slot pair, place it there.  */
	  if (GET_CODE (addr) == PLUS && (stack_offset & 7) == 0
	      && stack_offset != 2 * UNITS_PER_WORD
	      && (current_frame_info.last_slot < 0
		  || INTVAL (XEXP (addr, 1)) != UNITS_PER_WORD)
	      && (n+1 != last_saved || !skipped_mem))
	    {
	      mode = DImode;
	      i++;
	      addr = plus_constant (Pmode, addr,
				    - (HOST_WIDE_INT) UNITS_PER_WORD);
	    }
	  /* If it fits in the following stack slot pair, that's fine, too.  */
	  else if (GET_CODE (addr) == PLUS && (stack_offset & 7) == 4
		   && stack_offset != 2 * UNITS_PER_WORD
		   && stack_offset != 3 * UNITS_PER_WORD
		   && (current_frame_info.last_slot < 0
		       || INTVAL (XEXP (addr, 1)) != 2 * UNITS_PER_WORD)
		   && n + 1 != last_saved)
	    {
	      gcc_assert (!skipped_mem);
	      stack_offset -= GET_MODE_SIZE (mode);
	      skipped_mem = gen_mem (mode, addr);
	      mode = DImode;
	      i++;
	      addr = plus_constant (Pmode, addr,
				    - (HOST_WIDE_INT) 2 * UNITS_PER_WORD);
	    }
	}
      reg = gen_rtx_REG (mode, n);
      if (mode != DImode && skipped_mem)
	mem = skipped_mem;
      else
	mem = gen_mem (mode, addr);

      /* If we are loading / storing LR, note the offset that
	 gen_reload_insi_ra requires.  Since GPR_LR is even,
	 we only need to test n, even if mode is DImode.  */
      gcc_assert ((GPR_LR & 1) == 0);
      if (n == GPR_LR)
	{
	  long lr_slot_offset = 0;
	  rtx m_addr = XEXP (mem, 0);

	  if (GET_CODE (m_addr) == PLUS)
	    lr_slot_offset = INTVAL (XEXP (m_addr, 1));
	  if (frame_pointer_needed)
	    lr_slot_offset += (current_frame_info.first_slot_offset
			       - current_frame_info.total_size);
	  if (MACHINE_FUNCTION (cfun)->lr_slot_known)
	    gcc_assert (MACHINE_FUNCTION (cfun)->lr_slot_offset
			== lr_slot_offset);
	  MACHINE_FUNCTION (cfun)->lr_slot_offset = lr_slot_offset;
	  MACHINE_FUNCTION (cfun)->lr_slot_known = 1;
	}

      if (!epilogue_p)
	frame_move_insn (mem, reg);
      else if (n >= MAX_EPIPHANY_PARM_REGS || !crtl->args.pretend_args_size)
	emit_move_insn (reg, mem);
      if (mem == skipped_mem)
	{
	  skipped_mem = NULL_RTX;
	  continue;
	}
    next_slot:
      addr = plus_constant (Pmode, addr, -(HOST_WIDE_INT) UNITS_PER_WORD);
      stack_offset -= GET_MODE_SIZE (mode);
    }
}

void
epiphany_expand_prologue (void)
{
  int interrupt_p;
  enum epiphany_function_type fn_type;
  rtx addr, mem, off, reg;

  if (!current_frame_info.initialized)
    epiphany_compute_frame_size (get_frame_size ());

  /* It is debatable if we should adjust this by epiphany_stack_offset.  */
  if (flag_stack_usage_info)
    current_function_static_stack_size = current_frame_info.total_size;

  fn_type = epiphany_compute_function_type (current_function_decl);
  interrupt_p = EPIPHANY_INTERRUPT_P (fn_type);

  if (interrupt_p)
    {
      addr = plus_constant (Pmode, stack_pointer_rtx,
			    - (HOST_WIDE_INT) 2 * UNITS_PER_WORD);
      if (!lookup_attribute ("forwarder_section",
			    DECL_ATTRIBUTES (current_function_decl))
	  || !epiphany_is_long_call_p (XEXP (DECL_RTL (current_function_decl),
					     0)))
        frame_move_insn (gen_frame_mem (DImode, addr),
			 gen_rtx_REG (DImode, GPR_0));
      frame_move_insn (gen_rtx_REG (SImode, GPR_0),
		       gen_rtx_REG (word_mode, STATUS_REGNUM));
      frame_move_insn (gen_rtx_REG (SImode, GPR_1),
		       gen_rtx_REG (word_mode, IRET_REGNUM));
      mem = gen_frame_mem (BLKmode, stack_pointer_rtx);
      off = GEN_INT (-current_frame_info.first_slot_offset);
      frame_insn (gen_stack_adjust_add (off, mem));
      if (!epiphany_uninterruptible_p (current_function_decl))
	emit_insn (gen_gie ());
      addr = plus_constant (Pmode, stack_pointer_rtx,
			    current_frame_info.first_slot_offset
			    - (HOST_WIDE_INT) 3 * UNITS_PER_WORD);
    }
  else
    {
      addr = plus_constant (Pmode, stack_pointer_rtx,
			    epiphany_stack_offset
			    - (HOST_WIDE_INT) UNITS_PER_WORD);
      epiphany_emit_save_restore (0, current_frame_info.small_threshold,
				  addr, 0);
      /* Allocate register save area; for small to medium size frames,
	 allocate the entire frame; this is joint with one register save.  */
      if (current_frame_info.first_slot >= 0)
	{
	  machine_mode mode
	= (current_frame_info.first_slot_size == UNITS_PER_WORD
	   ? word_mode : DImode);

	  off = GEN_INT (-current_frame_info.first_slot_offset);
	  mem = gen_frame_mem (BLKmode,
			       gen_rtx_PLUS (Pmode, stack_pointer_rtx, off));
	  frame_insn (gen_stack_adjust_str
		       (gen_frame_mem (mode, stack_pointer_rtx),
			gen_rtx_REG (mode, current_frame_info.first_slot),
			off, mem));
	  addr = plus_constant (Pmode, addr,
				current_frame_info.first_slot_offset);
	}
    }
  epiphany_emit_save_restore (current_frame_info.small_threshold,
			      FIRST_PSEUDO_REGISTER, addr, 0);
  if (current_frame_info.need_fp)
    frame_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx);
  /* For large frames, allocate bulk of frame.  This is usually joint with one
     register save.  */
  if (current_frame_info.last_slot >= 0)
    {
      rtx ip, mem2, note;
      rtx_insn *insn;

      gcc_assert (current_frame_info.last_slot != GPR_FP
		  || (!current_frame_info.need_fp
		      && current_frame_info.first_slot < 0));
      off = GEN_INT (-current_frame_info.last_slot_offset);
      mem = gen_frame_mem (BLKmode,
			   gen_rtx_PLUS (Pmode, stack_pointer_rtx, off));
      ip = gen_rtx_REG (Pmode, GPR_IP);
      frame_move_insn (ip, off);
      reg = gen_rtx_REG (word_mode, current_frame_info.last_slot),
      mem2 = gen_frame_mem (word_mode, stack_pointer_rtx),
      insn = frame_insn (gen_stack_adjust_str (mem2, reg, ip, mem));
      /* Instruction scheduling can separate the instruction setting IP from
	 INSN so that dwarf2out_frame_debug_expr becomes confused what the
	 temporary register is.  Example: _gcov.o  */
      note = gen_rtx_SET (stack_pointer_rtx,
			  gen_rtx_PLUS (Pmode, stack_pointer_rtx, off));
      note = gen_rtx_PARALLEL (VOIDmode,
			       gen_rtvec (2, gen_rtx_SET (mem2, reg), note));
      add_reg_note (insn, REG_FRAME_RELATED_EXPR, note);
    }
  /* If there is only one or no register to save, yet we have a large frame,
     use an add.  */
  else if (current_frame_info.last_slot_offset)
    {
      mem = gen_frame_mem (BLKmode,
			   plus_constant (Pmode, stack_pointer_rtx,
					  current_frame_info.last_slot_offset));
      off = GEN_INT (-current_frame_info.last_slot_offset);
      if (!SIMM11 (INTVAL (off)))
	{
	  reg = gen_rtx_REG (Pmode, GPR_IP);
	  frame_move_insn (reg, off);
	  off = reg;
	}
      frame_insn (gen_stack_adjust_add (off, mem));
    }
}

void
epiphany_expand_epilogue (int sibcall_p)
{
  int interrupt_p;
  enum epiphany_function_type fn_type;
  rtx mem, addr, reg, off;
  HOST_WIDE_INT restore_offset;

  fn_type = epiphany_compute_function_type( current_function_decl);
  interrupt_p = EPIPHANY_INTERRUPT_P (fn_type);

  /* For variable frames, deallocate bulk of frame.  */
  if (current_frame_info.need_fp)
    {
      mem = gen_frame_mem (BLKmode, stack_pointer_rtx);
      emit_insn (gen_stack_adjust_mov (mem));
    }
  /* Else for large static frames, deallocate bulk of frame.  */
  else if (current_frame_info.last_slot_offset)
    {
      mem = gen_frame_mem (BLKmode, stack_pointer_rtx);
      reg = gen_rtx_REG (Pmode, GPR_IP);
      emit_move_insn (reg, GEN_INT (current_frame_info.last_slot_offset));
      emit_insn (gen_stack_adjust_add (reg, mem));
    }
  restore_offset = (interrupt_p
		    ? - 3 * UNITS_PER_WORD
		    : epiphany_stack_offset - (HOST_WIDE_INT) UNITS_PER_WORD);
  addr = plus_constant (Pmode, stack_pointer_rtx,
			(current_frame_info.first_slot_offset
			 + restore_offset));
  epiphany_emit_save_restore (current_frame_info.small_threshold,
			   FIRST_PSEUDO_REGISTER, addr, 1);

  if (interrupt_p && !epiphany_uninterruptible_p (current_function_decl))
    emit_insn (gen_gid ());

  off = GEN_INT (current_frame_info.first_slot_offset);
  mem = gen_frame_mem (BLKmode, stack_pointer_rtx);
  /* For large / variable size frames, deallocating the register save area is
     joint with one register restore; for medium size frames, we use a
     dummy post-increment load to dealloacte the whole frame.  */
  if (!SIMM11 (INTVAL (off)) || current_frame_info.last_slot >= 0)
    {
      emit_insn (gen_stack_adjust_ldr
		  (gen_rtx_REG (word_mode,
				(current_frame_info.last_slot >= 0
				 ? current_frame_info.last_slot : GPR_IP)),
		   gen_frame_mem (word_mode, stack_pointer_rtx),
		   off,
		   mem));
    }
  /* While for small frames, we deallocate the entire frame with one add.  */
  else if (INTVAL (off))
    {
      emit_insn (gen_stack_adjust_add (off, mem));
    }
  if (interrupt_p)
    {
      emit_move_insn (gen_rtx_REG (word_mode, STATUS_REGNUM),
		      gen_rtx_REG (SImode, GPR_0));
      emit_move_insn (gen_rtx_REG (word_mode, IRET_REGNUM),
		      gen_rtx_REG (SImode, GPR_1));
      addr = plus_constant (Pmode, stack_pointer_rtx,
			    - (HOST_WIDE_INT) 2 * UNITS_PER_WORD);
      emit_move_insn (gen_rtx_REG (DImode, GPR_0),
		      gen_frame_mem (DImode, addr));
    }
  addr = plus_constant (Pmode, stack_pointer_rtx,
			epiphany_stack_offset - (HOST_WIDE_INT) UNITS_PER_WORD);
  epiphany_emit_save_restore (0, current_frame_info.small_threshold, addr, 1);
  if (!sibcall_p)
    {
      if (interrupt_p)
	emit_jump_insn (gen_return_internal_interrupt());
      else
	emit_jump_insn (gen_return_i ());
    }
}

int
epiphany_initial_elimination_offset (int from, int to)
{
  epiphany_compute_frame_size (get_frame_size ());
  if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
    return current_frame_info.total_size - current_frame_info.reg_size;
  if (from == FRAME_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
    return current_frame_info.first_slot_offset - current_frame_info.reg_size;
  if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
    return (current_frame_info.total_size
	    - ((current_frame_info.pretend_size + 4) & -8));
  if (from == ARG_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
    return (current_frame_info.first_slot_offset
	    - ((current_frame_info.pretend_size + 4) & -8));
  gcc_unreachable ();
}

bool
epiphany_regno_rename_ok (unsigned, unsigned dst)
{
  enum epiphany_function_type fn_type;

  fn_type = epiphany_compute_function_type (current_function_decl);
  if (!EPIPHANY_INTERRUPT_P (fn_type))
    return true;
  if (df_regs_ever_live_p (dst))
    return true;
  return false;
}

static int
epiphany_issue_rate (void)
{
  return 2;
}

/* Function to update the integer COST
   based on the relationship between INSN that is dependent on
   DEP_INSN through the dependence LINK.  The default is to make no
   adjustment to COST.  This can be used for example to specify to
   the scheduler that an output- or anti-dependence does not incur
   the same cost as a data-dependence.  The return value should be
   the new value for COST.  */
static int
epiphany_adjust_cost (rtx_insn *insn, int dep_type, rtx_insn *dep_insn,
		      int cost, unsigned int)
{
  if (dep_type == 0)
    {
      rtx dep_set;

      if (recog_memoized (insn) < 0
	  || recog_memoized (dep_insn) < 0)
	return cost;

      dep_set = single_set (dep_insn);

      /* The latency that we specify in the scheduling description refers
	 to the actual output, not to an auto-increment register; for that,
	 the latency is one.  */
      if (dep_set && MEM_P (SET_SRC (dep_set)) && cost > 1)
	{
	  rtx set = single_set (insn);

	  if (set
	      && !reg_overlap_mentioned_p (SET_DEST (dep_set), SET_SRC (set))
	      && (!MEM_P (SET_DEST (set))
		  || !reg_overlap_mentioned_p (SET_DEST (dep_set),
					       XEXP (SET_DEST (set), 0))))
	    cost = 1;
	}
    }
  return cost;
}

#define REG_OK_FOR_INDEX_P(X) REG_OK_FOR_BASE_P (X)

#define RTX_OK_FOR_BASE_P(X) \
  (REG_P (X) && REG_OK_FOR_BASE_P (X))

#define RTX_OK_FOR_INDEX_P(MODE, X) \
  ((GET_MODE_CLASS (MODE) != MODE_VECTOR_INT \
    || epiphany_vect_align >= GET_MODE_SIZE (MODE)) \
   && (REG_P (X) && REG_OK_FOR_INDEX_P (X)))

#define LEGITIMATE_OFFSET_ADDRESS_P(MODE, X) \
(GET_CODE (X) == PLUS \
 && RTX_OK_FOR_BASE_P (XEXP (X, 0)) \
 && (RTX_OK_FOR_INDEX_P (MODE, XEXP (X, 1)) \
     || RTX_OK_FOR_OFFSET_P (MODE, XEXP (X, 1))))

static bool
epiphany_legitimate_address_p (machine_mode mode, rtx x, bool strict)
{
#define REG_OK_FOR_BASE_P(X) \
  (strict ? GPR_P (REGNO (X)) : GPR_AP_OR_PSEUDO_P (REGNO (X)))
  if (RTX_OK_FOR_BASE_P (x))
    return true;
  if (RTX_FRAME_OFFSET_P (x))
    return true;
  if (LEGITIMATE_OFFSET_ADDRESS_P (mode, x))
    return true;
  /* If this is a misaligned stack access, don't force it to reg+index.  */
  if (GET_MODE_SIZE (mode) == 8
      && GET_CODE (x) == PLUS && XEXP (x, 0) == stack_pointer_rtx
      /* Decomposed to SImode; GET_MODE_SIZE (SImode) == 4 */
      && !(INTVAL (XEXP (x, 1)) & 3)
      && INTVAL (XEXP (x, 1)) >= -2047 * 4
      && INTVAL (XEXP (x, 1)) <=  2046 * 4)
    return true;
  if (TARGET_POST_INC
      && (GET_CODE (x) == POST_DEC || GET_CODE (x) == POST_INC)
      && RTX_OK_FOR_BASE_P (XEXP ((x), 0)))
    return true;
  if ((TARGET_POST_MODIFY || reload_completed)
      && GET_CODE (x) == POST_MODIFY
      && GET_CODE (XEXP ((x), 1)) == PLUS
      && rtx_equal_p (XEXP ((x), 0), XEXP (XEXP ((x), 1), 0))
      && LEGITIMATE_OFFSET_ADDRESS_P (mode, XEXP ((x), 1)))
    return true;
  if (mode == BLKmode)
    return epiphany_legitimate_address_p (SImode, x, strict);
  return false;
}

static reg_class_t
epiphany_secondary_reload (bool in_p, rtx x, reg_class_t rclass,
			machine_mode mode ATTRIBUTE_UNUSED,
			secondary_reload_info *sri)
{
  /* This could give more reload inheritance, but we are missing some
     reload infrastructure.  */
 if (0)
  if (in_p && GET_CODE (x) == UNSPEC
      && satisfies_constraint_Sra (x) && !satisfies_constraint_Rra (x))
    {
      gcc_assert (rclass == GENERAL_REGS);
      sri->icode = CODE_FOR_reload_insi_ra;
      return NO_REGS;
    }
  return NO_REGS;
}

bool
epiphany_is_long_call_p (rtx x)
{
  tree decl = SYMBOL_REF_DECL (x);
  bool ret_val = !TARGET_SHORT_CALLS;
  tree attrs;

  /* ??? Is it safe to default to ret_val if decl is NULL?  We should
     probably encode information via encode_section_info, and also
     have (an) option(s) to take SYMBOL_FLAG_LOCAL and/or SYMBOL_FLAG_EXTERNAL
     into account.  */
  if (decl)
    {
      attrs = TYPE_ATTRIBUTES (TREE_TYPE (decl));
      if (lookup_attribute ("long_call", attrs))
	ret_val = true;
      else if (lookup_attribute ("short_call", attrs))
	ret_val = false;
    }
  return ret_val;
}

bool
epiphany_small16 (rtx x)
{
  rtx base = x;
  rtx offs ATTRIBUTE_UNUSED = const0_rtx;

  if (GET_CODE (x) == CONST && GET_CODE (XEXP (x, 0)) == PLUS)
    {
      base = XEXP (XEXP (x, 0), 0);
      offs = XEXP (XEXP (x, 0), 1);
    }
  if (GET_CODE (base) == SYMBOL_REF && SYMBOL_REF_FUNCTION_P (base)
      && epiphany_is_long_call_p (base))
    return false;
  return TARGET_SMALL16 != 0;
}

/* Return nonzero if it is ok to make a tail-call to DECL.  */
static bool
epiphany_function_ok_for_sibcall (tree decl, tree exp)
{
  bool cfun_interrupt_p, call_interrupt_p;

  cfun_interrupt_p = EPIPHANY_INTERRUPT_P (epiphany_compute_function_type
					(current_function_decl));
  if (decl)
    call_interrupt_p = EPIPHANY_INTERRUPT_P (epiphany_compute_function_type (decl));
  else
    {
      tree fn_type = TREE_TYPE (CALL_EXPR_FN (exp));

      gcc_assert (POINTER_TYPE_P (fn_type));
      fn_type = TREE_TYPE (fn_type);
      gcc_assert (TREE_CODE (fn_type) == FUNCTION_TYPE
		  || TREE_CODE (fn_type) == METHOD_TYPE);
      call_interrupt_p
	= lookup_attribute ("interrupt", TYPE_ATTRIBUTES (fn_type)) != NULL;
    }

  /* Don't tailcall from or to an ISR routine - although we could in
     principle tailcall from one ISR routine to another, we'd need to
     handle this in sibcall_epilogue to make it work.  */
  if (cfun_interrupt_p || call_interrupt_p)
    return false;

  /* Everything else is ok.  */
  return true;
}

/* T is a function declaration or the MEM_EXPR of a MEM passed to a call
   expander.
   Return true iff the type of T has the uninterruptible attribute.
   If T is NULL, return false.  */
bool
epiphany_uninterruptible_p (tree t)
{
  tree attrs;

  if (t)
    {
      attrs = TYPE_ATTRIBUTES (TREE_TYPE (t));
      if (lookup_attribute ("disinterrupt", attrs))
	return true;
    }
  return false;
}

bool
epiphany_call_uninterruptible_p (rtx mem)
{
  rtx addr = XEXP (mem, 0);
  tree t = NULL_TREE;

  if (GET_CODE (addr) == SYMBOL_REF)
    t = SYMBOL_REF_DECL (addr);
  if (!t)
    t = MEM_EXPR (mem);
  return epiphany_uninterruptible_p (t);
}

static machine_mode
epiphany_promote_function_mode (const_tree type, machine_mode mode,
				int *punsignedp ATTRIBUTE_UNUSED,
				const_tree funtype ATTRIBUTE_UNUSED,
				int for_return ATTRIBUTE_UNUSED)
{
  int dummy;

  return promote_mode (type, mode, &dummy);
}

static void
epiphany_conditional_register_usage (void)
{
  int i;

  if (PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM)
    {
      fixed_regs[PIC_OFFSET_TABLE_REGNUM] = 1;
      call_used_regs[PIC_OFFSET_TABLE_REGNUM] = 1;
    }
  if (TARGET_HALF_REG_FILE)
    {
      for (i = 32; i <= 63; i++)
	{
	  fixed_regs[i] = 1;
	  call_used_regs[i] = 1;
	}
    }
  if (epiphany_m1reg >= 0)
    {
      fixed_regs[epiphany_m1reg] = 1;
      call_used_regs[epiphany_m1reg] = 1;
    }
  if (!TARGET_PREFER_SHORT_INSN_REGS)
    CLEAR_HARD_REG_SET (reg_class_contents[SHORT_INSN_REGS]);
  COPY_HARD_REG_SET (reg_class_contents[SIBCALL_REGS],
		     reg_class_contents[GENERAL_REGS]);
  /* It would be simpler and quicker if we could just use
     AND_COMPL_HARD_REG_SET, alas, call_used_reg_set is yet uninitialized;
     it is set up later by our caller.  */
  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
    if (!call_used_regs[i])
      CLEAR_HARD_REG_BIT (reg_class_contents[SIBCALL_REGS], i);
}

/* Determine where to put an argument to a function.
   Value is zero to push the argument on the stack,
   or a hard register in which to store the argument.

   MODE is the argument's machine mode.
   TYPE is the data type of the argument (as a tree).
    This is null for libcalls where that information may
    not be available.
   CUM is a variable of type CUMULATIVE_ARGS which gives info about
    the preceding args and about the function being called.
   NAMED is nonzero if this argument is a named parameter
    (otherwise it is an extra parameter matching an ellipsis).  */
/* On the EPIPHANY the first MAX_EPIPHANY_PARM_REGS args are normally in
   registers and the rest are pushed.  */
static rtx
epiphany_function_arg (cumulative_args_t cum_v, machine_mode mode,
		       const_tree type, bool named ATTRIBUTE_UNUSED)
{
  CUMULATIVE_ARGS cum = *get_cumulative_args (cum_v);

  if (PASS_IN_REG_P (cum, mode, type))
    return gen_rtx_REG (mode, ROUND_ADVANCE_CUM (cum, mode, type));
  return 0;
}

/* Update the data in CUM to advance over an argument
   of mode MODE and data type TYPE.
   (TYPE is null for libcalls where that information may not be available.)  */
static void
epiphany_function_arg_advance (cumulative_args_t cum_v, machine_mode mode,
			       const_tree type, bool named ATTRIBUTE_UNUSED)
{
  CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);

  *cum = ROUND_ADVANCE_CUM (*cum, mode, type) + ROUND_ADVANCE_ARG (mode, type);
}

/* Nested function support.
   An epiphany trampoline looks like this:
   mov r16,%low(fnaddr)
   movt r16,%high(fnaddr)
   mov ip,%low(cxt)
   movt ip,%high(cxt)
   jr r16  */

#define EPIPHANY_LOW_RTX(X) \
  (gen_rtx_IOR (SImode, \
    gen_rtx_ASHIFT (SImode, \
		    gen_rtx_AND (SImode, (X), GEN_INT (0xff)), GEN_INT (5)), \
    gen_rtx_ASHIFT (SImode, \
		    gen_rtx_AND (SImode, (X), GEN_INT (0xff00)), GEN_INT (12))))
#define EPIPHANY_HIGH_RTX(X) \
  EPIPHANY_LOW_RTX (gen_rtx_LSHIFTRT (SImode, (X), GEN_INT (16)))

/* Emit RTL insns to initialize the variable parts of a trampoline.
   FNADDR is an RTX for the address of the function's pure code.
   CXT is an RTX for the static chain value for the function.  */
static void
epiphany_trampoline_init (rtx tramp_mem, tree fndecl, rtx cxt)
{
  rtx fnaddr = XEXP (DECL_RTL (fndecl), 0);
  rtx tramp = force_reg (Pmode, XEXP (tramp_mem, 0));

  emit_move_insn (gen_rtx_MEM (SImode, plus_constant (Pmode, tramp, 0)),
		  gen_rtx_IOR (SImode, GEN_INT (0x4002000b),
			       EPIPHANY_LOW_RTX (fnaddr)));
  emit_move_insn (gen_rtx_MEM (SImode, plus_constant (Pmode, tramp, 4)),
		  gen_rtx_IOR (SImode, GEN_INT (0x5002000b),
			       EPIPHANY_HIGH_RTX (fnaddr)));
  emit_move_insn (gen_rtx_MEM (SImode, plus_constant (Pmode, tramp, 8)),
		  gen_rtx_IOR (SImode, GEN_INT (0x2002800b),
			       EPIPHANY_LOW_RTX (cxt)));
  emit_move_insn (gen_rtx_MEM (SImode, plus_constant (Pmode, tramp, 12)),
		  gen_rtx_IOR (SImode, GEN_INT (0x3002800b),
			       EPIPHANY_HIGH_RTX (cxt)));
  emit_move_insn (gen_rtx_MEM (SImode, plus_constant (Pmode, tramp, 16)),
		  GEN_INT (0x0802014f));
}

bool
epiphany_optimize_mode_switching (int entity)
{
  if (MACHINE_FUNCTION (cfun)->sw_entities_processed & (1 << entity))
    return false;
  switch (entity)
    {
    case EPIPHANY_MSW_ENTITY_AND:
    case EPIPHANY_MSW_ENTITY_OR:
    case EPIPHANY_MSW_ENTITY_CONFIG:
      return true;
    case EPIPHANY_MSW_ENTITY_NEAREST:
    case EPIPHANY_MSW_ENTITY_TRUNC:
      return optimize > 0;
    case EPIPHANY_MSW_ENTITY_ROUND_UNKNOWN:
      return MACHINE_FUNCTION (cfun)->unknown_mode_uses != 0;
    case EPIPHANY_MSW_ENTITY_ROUND_KNOWN:
      return (MACHINE_FUNCTION (cfun)->sw_entities_processed
	      & (1 << EPIPHANY_MSW_ENTITY_ROUND_UNKNOWN)) != 0;
    case EPIPHANY_MSW_ENTITY_FPU_OMNIBUS:
      return optimize == 0 || current_pass == pass_mode_switch_use;
    }
  gcc_unreachable ();
}

static int
epiphany_mode_priority (int entity, int priority)
{
  if (entity == EPIPHANY_MSW_ENTITY_AND || entity == EPIPHANY_MSW_ENTITY_OR
      || entity== EPIPHANY_MSW_ENTITY_CONFIG)
    return priority;
  if (priority > 3)
    switch (priority)
      {
      case 4: return FP_MODE_ROUND_UNKNOWN;
      case 5: return FP_MODE_NONE;
      default: gcc_unreachable ();
      }
  switch ((enum attr_fp_mode) epiphany_normal_fp_mode)
    {
      case FP_MODE_INT:
	switch (priority)
	  {
	  case 0: return FP_MODE_INT;
	  case 1: return epiphany_normal_fp_rounding;
	  case 2: return (epiphany_normal_fp_rounding == FP_MODE_ROUND_NEAREST
			  ? FP_MODE_ROUND_TRUNC : FP_MODE_ROUND_NEAREST);
	  case 3: return FP_MODE_CALLER;
	  }
      case FP_MODE_ROUND_NEAREST:
      case FP_MODE_CALLER:
	switch (priority)
	  {
	  case 0: return FP_MODE_ROUND_NEAREST;
	  case 1: return FP_MODE_ROUND_TRUNC;
	  case 2: return FP_MODE_INT;
	  case 3: return FP_MODE_CALLER;
	  }
      case FP_MODE_ROUND_TRUNC:
	switch (priority)
	  {
	  case 0: return FP_MODE_ROUND_TRUNC;
	  case 1: return FP_MODE_ROUND_NEAREST;
	  case 2: return FP_MODE_INT;
	  case 3: return FP_MODE_CALLER;
	  }
      case FP_MODE_ROUND_UNKNOWN:
      case FP_MODE_NONE:
	gcc_unreachable ();
    }
  gcc_unreachable ();
}

int
epiphany_mode_needed (int entity, rtx_insn *insn)
{
  enum attr_fp_mode mode;

  if (recog_memoized (insn) < 0)
    {
      if (entity == EPIPHANY_MSW_ENTITY_AND
	  || entity == EPIPHANY_MSW_ENTITY_OR
	  || entity == EPIPHANY_MSW_ENTITY_CONFIG)
	return 2;
      return FP_MODE_NONE;
    }
  mode = get_attr_fp_mode (insn);

  switch (entity)
  {
  case EPIPHANY_MSW_ENTITY_AND:
    return mode != FP_MODE_NONE && mode != FP_MODE_INT ? 1 : 2;
  case EPIPHANY_MSW_ENTITY_OR:
    return mode == FP_MODE_INT ? 1 : 2;
  case EPIPHANY_MSW_ENTITY_CONFIG:
    /* We must know/save config before we set it to something else.
       Where we need the original value, we are fine with having it
       just unchanged from the function start.
       Because of the nature of the mode switching optimization,
       a restore will be dominated by a clobber.  */
    if (mode != FP_MODE_NONE && mode != FP_MODE_CALLER)
      return 1;
    /* A cpecial case are abnormal edges, which are deemed to clobber
       the mode as well.  We need to pin this effect on a actually
       dominating insn, and one where the frame can be accessed, too, in
       case the pseudo used to save CONFIG doesn't get a hard register.  */
    if (CALL_P (insn) && find_reg_note (insn, REG_EH_REGION, NULL_RTX))
      return 1;
    return 2;
  case EPIPHANY_MSW_ENTITY_ROUND_KNOWN:
    if (recog_memoized (insn) == CODE_FOR_set_fp_mode)
      mode = (enum attr_fp_mode) epiphany_mode_after (entity, mode, insn);
    /* Fall through.  */
  case EPIPHANY_MSW_ENTITY_NEAREST:
  case EPIPHANY_MSW_ENTITY_TRUNC:
    if (mode == FP_MODE_ROUND_UNKNOWN)
      {
	MACHINE_FUNCTION (cfun)->unknown_mode_uses++;
	return FP_MODE_NONE;
      }
    return mode;
  case EPIPHANY_MSW_ENTITY_ROUND_UNKNOWN:
    if (mode == FP_MODE_ROUND_NEAREST || mode == FP_MODE_ROUND_TRUNC)
	return FP_MODE_ROUND_UNKNOWN;
    return mode;
  case EPIPHANY_MSW_ENTITY_FPU_OMNIBUS:
    if (mode == FP_MODE_ROUND_UNKNOWN)
      return epiphany_normal_fp_rounding;
    return mode;
  default:
    gcc_unreachable ();
  }
}

static int
epiphany_mode_entry_exit (int entity, bool exit)
{
  int normal_mode = epiphany_normal_fp_mode ;

  MACHINE_FUNCTION (cfun)->sw_entities_processed |= (1 << entity);
  if (epiphany_is_interrupt_p (current_function_decl))
    normal_mode = FP_MODE_CALLER;
  switch (entity)
    {
    case EPIPHANY_MSW_ENTITY_AND:
      if (exit)
	return normal_mode != FP_MODE_INT ? 1 : 2;
      return 0;
    case EPIPHANY_MSW_ENTITY_OR:
      if (exit)
	return normal_mode == FP_MODE_INT ? 1 : 2;
      return 0;
    case EPIPHANY_MSW_ENTITY_CONFIG:
      if (exit)
	return 2;
      return normal_mode == FP_MODE_CALLER ? 0 : 1;
    case EPIPHANY_MSW_ENTITY_ROUND_UNKNOWN:
      if (normal_mode == FP_MODE_ROUND_NEAREST
	  || normal_mode == FP_MODE_ROUND_TRUNC)
      return FP_MODE_ROUND_UNKNOWN;
      /* Fall through.  */
    case EPIPHANY_MSW_ENTITY_NEAREST:
    case EPIPHANY_MSW_ENTITY_TRUNC:
    case EPIPHANY_MSW_ENTITY_ROUND_KNOWN:
    case EPIPHANY_MSW_ENTITY_FPU_OMNIBUS:
      return normal_mode;
    default:
      gcc_unreachable ();
    }
}

int
epiphany_mode_after (int entity, int last_mode, rtx_insn *insn)
{
  /* We have too few call-saved registers to hope to keep the masks across
     calls.  */
  if (entity == EPIPHANY_MSW_ENTITY_AND || entity == EPIPHANY_MSW_ENTITY_OR)
    {
      if (CALL_P (insn))
	return 0;
      return last_mode;
    }
  /* If there is an abnormal edge, we don't want the config register to
     be 'saved' again at the destination.
     The frame pointer adjustment is inside a PARALLEL because of the
     flags clobber.  */
  if (entity == EPIPHANY_MSW_ENTITY_CONFIG && NONJUMP_INSN_P (insn)
      && GET_CODE (PATTERN (insn)) == PARALLEL
      && GET_CODE (XVECEXP (PATTERN (insn), 0, 0)) == SET
      && SET_DEST (XVECEXP (PATTERN (insn), 0, 0)) == frame_pointer_rtx)
    {
      gcc_assert (cfun->has_nonlocal_label);
      return 1;
    }
  if (recog_memoized (insn) < 0)
    return last_mode;
  if (get_attr_fp_mode (insn) == FP_MODE_ROUND_UNKNOWN
      && last_mode != FP_MODE_ROUND_NEAREST && last_mode != FP_MODE_ROUND_TRUNC)
    {
      if (entity == EPIPHANY_MSW_ENTITY_NEAREST)
	return FP_MODE_ROUND_NEAREST;
      if (entity == EPIPHANY_MSW_ENTITY_TRUNC)
	return FP_MODE_ROUND_TRUNC;
    }
  if (recog_memoized (insn) == CODE_FOR_set_fp_mode)
    {
      rtx src = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
      int fp_mode;

      if (REG_P (src))
	return FP_MODE_CALLER;
      fp_mode = INTVAL (XVECEXP (XEXP (src, 0), 0, 0));
      if (entity == EPIPHANY_MSW_ENTITY_ROUND_UNKNOWN
	  && (fp_mode == FP_MODE_ROUND_NEAREST
	      || fp_mode == EPIPHANY_MSW_ENTITY_TRUNC))
	return FP_MODE_ROUND_UNKNOWN;
      return fp_mode;
    }
  return last_mode;
}

static int
epiphany_mode_entry (int entity)
{
  return epiphany_mode_entry_exit (entity, false);
}

static int
epiphany_mode_exit (int entity)
{
  return epiphany_mode_entry_exit (entity, true);
}

void
emit_set_fp_mode (int entity, int mode, int prev_mode ATTRIBUTE_UNUSED,
		  HARD_REG_SET regs_live ATTRIBUTE_UNUSED)
{
  rtx save_cc, cc_reg, mask, src, src2;
  enum attr_fp_mode fp_mode;

  if (!MACHINE_FUNCTION (cfun)->and_mask)
    {
      MACHINE_FUNCTION (cfun)->and_mask = gen_reg_rtx (SImode);
      MACHINE_FUNCTION (cfun)->or_mask = gen_reg_rtx (SImode);
    }
  if (entity == EPIPHANY_MSW_ENTITY_AND)
    {
      gcc_assert (mode >= 0 && mode <= 2);
      if (mode == 1)
	emit_move_insn (MACHINE_FUNCTION (cfun)->and_mask,
			gen_int_mode (0xfff1fffe, SImode));
      return;
    }
  else if (entity == EPIPHANY_MSW_ENTITY_OR)
    {
      gcc_assert (mode >= 0 && mode <= 2);
      if (mode == 1)
	emit_move_insn (MACHINE_FUNCTION (cfun)->or_mask, GEN_INT(0x00080000));
      return;
    }
  else if (entity == EPIPHANY_MSW_ENTITY_CONFIG)
    {
      /* Mode switching optimization is done after emit_initial_value_sets,
	 so we have to take care of CONFIG_REGNUM here.  */
      gcc_assert (mode >= 0 && mode <= 2);
      rtx save = get_hard_reg_initial_val (SImode, CONFIG_REGNUM);
      if (mode == 1)
	emit_insn (gen_save_config (save));
      return;
    }
  fp_mode = (enum attr_fp_mode) mode;
  src = NULL_RTX;

  switch (fp_mode)
    {
      case FP_MODE_CALLER:
	/* The EPIPHANY_MSW_ENTITY_CONFIG processing must come later
	   so that the config save gets inserted before the first use.  */
	gcc_assert (entity > EPIPHANY_MSW_ENTITY_CONFIG);
	src = get_hard_reg_initial_val (SImode, CONFIG_REGNUM);
	mask = MACHINE_FUNCTION (cfun)->and_mask;
	break;
      case FP_MODE_ROUND_UNKNOWN:
	MACHINE_FUNCTION (cfun)->unknown_mode_sets++;
	mask = MACHINE_FUNCTION (cfun)->and_mask;
	break;
      case FP_MODE_ROUND_NEAREST:
	if (entity == EPIPHANY_MSW_ENTITY_TRUNC)
	  return;
	mask = MACHINE_FUNCTION (cfun)->and_mask;
	break;
      case FP_MODE_ROUND_TRUNC:
	if (entity == EPIPHANY_MSW_ENTITY_NEAREST)
	  return;
	mask = MACHINE_FUNCTION (cfun)->and_mask;
	break;
      case FP_MODE_INT:
	mask = MACHINE_FUNCTION (cfun)->or_mask;
	break;
      case FP_MODE_NONE:
      default:
	gcc_unreachable ();
    }
  save_cc = gen_reg_rtx (CCmode);
  cc_reg = gen_rtx_REG (CCmode, CC_REGNUM);
  emit_move_insn (save_cc, cc_reg);
  mask = force_reg (SImode, mask);
  if (!src)
    {
      rtvec v = gen_rtvec (1, GEN_INT (fp_mode));

      src = gen_rtx_CONST (SImode, gen_rtx_UNSPEC (SImode, v, UNSPEC_FP_MODE));
    }
  if (entity == EPIPHANY_MSW_ENTITY_ROUND_KNOWN
      || entity == EPIPHANY_MSW_ENTITY_FPU_OMNIBUS)
    src2 = copy_rtx (src);
  else
    {
      rtvec v = gen_rtvec (1, GEN_INT (FP_MODE_ROUND_UNKNOWN));

      src2 = gen_rtx_CONST (SImode, gen_rtx_UNSPEC (SImode, v, UNSPEC_FP_MODE));
    }
  emit_insn (gen_set_fp_mode (src, src2, mask));
  emit_move_insn (cc_reg, save_cc);
}

void
epiphany_expand_set_fp_mode (rtx *operands)
{
  rtx ctrl = gen_rtx_REG (SImode, CONFIG_REGNUM);
  rtx src = operands[0];
  rtx mask_reg = operands[2];
  rtx scratch = operands[3];
  enum attr_fp_mode fp_mode;


  gcc_assert (rtx_equal_p (src, operands[1])
	      /* Sometimes reload gets silly and reloads the same pseudo
		 into different registers.  */
	      || (REG_P (src) && REG_P (operands[1])));

  if (!epiphany_uninterruptible_p (current_function_decl))
    emit_insn (gen_gid ());
  emit_move_insn (scratch, ctrl);

  if (GET_CODE (src) == REG)
    {
      /* FP_MODE_CALLER */
      emit_insn (gen_xorsi3 (scratch, scratch, src));
      emit_insn (gen_andsi3 (scratch, scratch, mask_reg));
      emit_insn (gen_xorsi3 (scratch, scratch, src));
    }
  else
    {
      gcc_assert (GET_CODE (src) == CONST);
      src = XEXP (src, 0);
      fp_mode = (enum attr_fp_mode) INTVAL (XVECEXP (src, 0, 0));
      switch (fp_mode)
	{
	case FP_MODE_ROUND_NEAREST:
	  emit_insn (gen_andsi3 (scratch, scratch, mask_reg));
	  break;
	case FP_MODE_ROUND_TRUNC:
	  emit_insn (gen_andsi3 (scratch, scratch, mask_reg));
	  emit_insn (gen_add2_insn (scratch, const1_rtx));
	  break;
	case FP_MODE_INT:
	  emit_insn (gen_iorsi3 (scratch, scratch, mask_reg));
	  break;
	case FP_MODE_CALLER:
	case FP_MODE_ROUND_UNKNOWN:
	case FP_MODE_NONE:
	  gcc_unreachable ();
	}
    }
  emit_move_insn (ctrl, scratch);
  if (!epiphany_uninterruptible_p (current_function_decl))
    emit_insn (gen_gie ());
}

void
epiphany_insert_mode_switch_use (rtx_insn *insn,
				 int entity ATTRIBUTE_UNUSED,
				 int mode ATTRIBUTE_UNUSED)
{
  rtx pat = PATTERN (insn);
  rtvec v;
  int len, i;
  rtx near = gen_rtx_REG (SImode, FP_NEAREST_REGNUM);
  rtx trunc = gen_rtx_REG (SImode, FP_TRUNCATE_REGNUM);

  if (entity != EPIPHANY_MSW_ENTITY_FPU_OMNIBUS)
    return;
  switch ((enum attr_fp_mode) get_attr_fp_mode (insn))
    {
      case FP_MODE_ROUND_NEAREST:
	near = gen_rtx_USE (VOIDmode, near);
	trunc = gen_rtx_CLOBBER (VOIDmode, trunc);
	break;
      case FP_MODE_ROUND_TRUNC:
	near = gen_rtx_CLOBBER (VOIDmode, near);
	trunc = gen_rtx_USE (VOIDmode, trunc);
	break;
      case FP_MODE_ROUND_UNKNOWN:
	near = gen_rtx_USE (VOIDmode, gen_rtx_REG (SImode, FP_ANYFP_REGNUM));
	trunc = copy_rtx (near);
	/* Fall through.  */
      case FP_MODE_INT:
      case FP_MODE_CALLER:
	near = gen_rtx_USE (VOIDmode, near);
	trunc = gen_rtx_USE (VOIDmode, trunc);
	break;
      case FP_MODE_NONE:
	gcc_unreachable ();
    }
  gcc_assert (GET_CODE (pat) == PARALLEL);
  len = XVECLEN (pat, 0);
  v = rtvec_alloc (len + 2);
  for (i = 0; i < len; i++)
    RTVEC_ELT (v, i) = XVECEXP (pat, 0, i);
  RTVEC_ELT (v, len) = near;
  RTVEC_ELT (v, len + 1) = trunc;
  pat = gen_rtx_PARALLEL (VOIDmode, v);
  PATTERN (insn) = pat;
  MACHINE_FUNCTION (cfun)->control_use_inserted = true;
}

bool
epiphany_epilogue_uses (int regno)
{
  if (regno == GPR_LR)
    return true;
  if (reload_completed && epiphany_is_interrupt_p (current_function_decl))
    {
      if (fixed_regs[regno]
	  && regno != STATUS_REGNUM && regno != IRET_REGNUM
	  && regno != FP_NEAREST_REGNUM && regno != FP_TRUNCATE_REGNUM)
	return false;
      return true;
    }
  if (regno == FP_NEAREST_REGNUM
      && epiphany_normal_fp_mode != FP_MODE_ROUND_TRUNC)
    return true;
  if (regno == FP_TRUNCATE_REGNUM
      && epiphany_normal_fp_mode != FP_MODE_ROUND_NEAREST)
    return true;
  return false;
}

static unsigned int
epiphany_min_divisions_for_recip_mul (machine_mode mode)
{
  if (flag_reciprocal_math && mode == SFmode)
    /* We'll expand into a multiply-by-reciprocal anyway, so we might a well do
       it already at the tree level and expose it to further optimizations.  */
    return 1;
  return default_min_divisions_for_recip_mul (mode);
}

static machine_mode
epiphany_preferred_simd_mode (scalar_mode mode ATTRIBUTE_UNUSED)
{
  return TARGET_VECT_DOUBLE ? DImode : SImode;
}

static bool
epiphany_vector_mode_supported_p (machine_mode mode)
{
  if (mode == V2SFmode)
    return true;
  if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT
      && (GET_MODE_SIZE (mode) == 4 || GET_MODE_SIZE (mode) == 8))
    return true;
  return false;
}

static bool
epiphany_vector_alignment_reachable (const_tree type, bool is_packed)
{
  /* Vectors which aren't in packed structures will not be less aligned than
     the natural alignment of their element type, so this is safe.  */
  if (TYPE_ALIGN_UNIT (type) == 4)
    return !is_packed;

  return default_builtin_vector_alignment_reachable (type, is_packed);
}

static bool
epiphany_support_vector_misalignment (machine_mode mode, const_tree type,
				      int misalignment, bool is_packed)
{
  if (GET_MODE_SIZE (mode) == 8 && misalignment % 4 == 0)
    return true;
  return default_builtin_support_vector_misalignment (mode, type, misalignment,
						      is_packed);
}

/* STRUCTURE_SIZE_BOUNDARY seems a bit crude in how it enlarges small
   structs.  Make structs double-word-aligned it they are a double word or
   (potentially) larger;  failing that, do the same for a size of 32 bits.  */
unsigned
epiphany_special_round_type_align (tree type, unsigned computed,
				   unsigned specified)
{
  unsigned align = MAX (computed, specified);
  tree field;
  HOST_WIDE_INT total, max;
  unsigned try_align = FASTEST_ALIGNMENT;

  if (maximum_field_alignment && try_align > maximum_field_alignment)
    try_align = maximum_field_alignment;
  if (align >= try_align)
    return align;
  for (max = 0, field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
    {
      tree offset, size;

      if (TREE_CODE (field) != FIELD_DECL
	  || TREE_TYPE (field) == error_mark_node)
	continue;
      offset = bit_position (field);
      size = DECL_SIZE (field);
      if (!tree_fits_uhwi_p (offset) || !tree_fits_uhwi_p (size)
	  || tree_to_uhwi (offset) >= try_align
	  || tree_to_uhwi (size) >= try_align)
	return try_align;
      total = tree_to_uhwi (offset) + tree_to_uhwi (size);
      if (total > max)
	max = total;
    }
  if (max >= (HOST_WIDE_INT) try_align)
    align = try_align;
  else if (try_align > 32 && max >= 32)
    align = max > 32 ? 64 : 32;
  return align;
}

/* Upping the alignment of arrays in structs is not only a performance
   enhancement, it also helps preserve assumptions about how
   arrays-at-the-end-of-structs work, like for struct gcov_fn_info in
   libgcov.c .  */
unsigned
epiphany_adjust_field_align (tree type, unsigned computed)
{
  if (computed == 32
      && TREE_CODE (type) == ARRAY_TYPE)
    {
      tree elmsz = TYPE_SIZE (TREE_TYPE (type));

      if (!tree_fits_uhwi_p (elmsz) || tree_to_uhwi (elmsz) >= 32)
	return 64;
    }
  return computed;
}

/* Output code to add DELTA to the first argument, and then jump
   to FUNCTION.  Used for C++ multiple inheritance.  */
static void
epiphany_output_mi_thunk (FILE *file, tree thunk ATTRIBUTE_UNUSED,
			  HOST_WIDE_INT delta,
			  HOST_WIDE_INT vcall_offset,
			  tree function)
{
  const char *fnname = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (thunk));
  int this_regno
    = aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function) ? 1 : 0;
  const char *this_name = reg_names[this_regno];
  const char *fname;

  assemble_start_function (thunk, fnname);
  /* We use IP and R16 as a scratch registers.  */
  gcc_assert (call_used_regs [GPR_IP]);
  gcc_assert (call_used_regs [GPR_16]);

  /* Add DELTA.  When possible use a plain add, otherwise load it into
     a register first. */
  if (delta == 0)
    ; /* Done.  */
  else if (SIMM11 (delta))
    asm_fprintf (file, "\tadd\t%s,%s,%d\n", this_name, this_name, (int) delta);
  else if (delta < 0 && delta >= -0xffff)
    {
      asm_fprintf (file, "\tmov\tip,%d\n", (int) -delta);
      asm_fprintf (file, "\tsub\t%s,%s,ip\n", this_name, this_name);
    }
  else
    {
      asm_fprintf (file, "\tmov\tip,%%low(%ld)\n", (long) delta);
      if (delta & ~0xffff)
	asm_fprintf (file, "\tmovt\tip,%%high(%ld)\n", (long) delta);
      asm_fprintf (file, "\tadd\t%s,%s,ip\n", this_name, this_name);
    }

  /* If needed, add *(*THIS + VCALL_OFFSET) to THIS.  */
  if (vcall_offset != 0)
    {
      /* ldr ip,[this]		--> temp = *this
	 ldr ip,[ip,vcall_offset] > temp = *(*this + vcall_offset)
	 add this,this,ip	--> this+ = *(*this + vcall_offset) */
      asm_fprintf (file, "\tldr\tip, [%s]\n", this_name);
      if (vcall_offset < -0x7ff * 4 || vcall_offset > 0x7ff * 4
	  || (vcall_offset & 3) != 0)
	{
	  asm_fprintf (file, "\tmov\tr16, %%low(%ld)\n", (long) vcall_offset);
	  asm_fprintf (file, "\tmovt\tr16, %%high(%ld)\n", (long) vcall_offset);
	  asm_fprintf (file, "\tldr\tip, [ip,r16]\n");
	}
      else
	asm_fprintf (file, "\tldr\tip, [ip,%d]\n", (int) vcall_offset / 4);
      asm_fprintf (file, "\tadd\t%s, %s, ip\n", this_name, this_name);
    }

  fname = XSTR (XEXP (DECL_RTL (function), 0), 0);
  if (epiphany_is_long_call_p (XEXP (DECL_RTL (function), 0)))
    {
      fputs ("\tmov\tip,%low(", file);
      assemble_name (file, fname);
      fputs (")\n\tmovt\tip,%high(", file);
      assemble_name (file, fname);
      fputs (")\n\tjr ip\n", file);
    }
  else
    {
      fputs ("\tb\t", file);
      assemble_name (file, fname);
      fputc ('\n', file);
    }
  assemble_end_function (thunk, fnname);
}

void
epiphany_start_function (FILE *file, const char *name, tree decl)
{
  /* If the function doesn't fit into the on-chip memory, it will have a
     section attribute - or lack of it - that denotes it goes somewhere else.
     But the architecture spec says that an interrupt vector still has to
     point to on-chip memory.  So we must place a jump there to get to the
     actual function implementation.  The forwarder_section attribute
     specifies the section where this jump goes.
     This mechanism can also be useful to have a shortcall destination for
     a function that is actually placed much farther away.  */
  tree attrs, int_attr, int_names, int_name, forwarder_attr;

  attrs = DECL_ATTRIBUTES (decl);
  int_attr = lookup_attribute ("interrupt", attrs);
  if (int_attr)
    for (int_names = TREE_VALUE (int_attr); int_names;
	 int_names = TREE_CHAIN (int_names))
      {
	char buf[99];

	int_name = TREE_VALUE (int_names);
	sprintf (buf, "ivt_entry_%.80s", TREE_STRING_POINTER (int_name));
	switch_to_section (get_section (buf, SECTION_CODE, decl));
	fputs ("\tb\t", file);
	assemble_name (file, name);
	fputc ('\n', file);
      }
  forwarder_attr = lookup_attribute ("forwarder_section", attrs);
  if (forwarder_attr)
    {
      const char *prefix = "__forwarder_dst_";
      char *dst_name = (char *) alloca (strlen (prefix) + strlen (name) + 1);

      strcpy (dst_name, prefix);
      strcat (dst_name, name);
      forwarder_attr = TREE_VALUE (TREE_VALUE (forwarder_attr));
      switch_to_section (get_section (TREE_STRING_POINTER (forwarder_attr),
			 SECTION_CODE, decl));
      ASM_OUTPUT_FUNCTION_LABEL (file, name, decl);
      if (epiphany_is_long_call_p (XEXP (DECL_RTL (decl), 0)))
	{
	  int tmp = GPR_0;

	  if (int_attr)
	    fputs ("\tstrd r0,[sp,-1]\n", file);
	  else
	    tmp = GPR_16;
	  gcc_assert (call_used_regs[tmp]);
	  fprintf (file, "\tmov r%d,%%low(", tmp);
	  assemble_name (file, dst_name);
	  fprintf (file, ")\n"
		   "\tmovt r%d,%%high(", tmp);
	  assemble_name (file, dst_name);
	  fprintf (file, ")\n"
		 "\tjr r%d\n", tmp);
	}
      else
	{
	  fputs ("\tb\t", file);
	  assemble_name (file, dst_name);
	  fputc ('\n', file);
	}
      name = dst_name;
    }
  switch_to_section (function_section (decl));
  ASM_OUTPUT_FUNCTION_LABEL (file, name, decl);
}


/* Implement TARGET_CONSTANT_ALIGNMENT.  */

static HOST_WIDE_INT
epiphany_constant_alignment (const_tree exp, HOST_WIDE_INT align)
{
  if (TREE_CODE (exp) == STRING_CST)
    return MAX (align, FASTEST_ALIGNMENT);
  return align;
}

/* Implement TARGET_STARTING_FRAME_OFFSET.  */

static HOST_WIDE_INT
epiphany_starting_frame_offset (void)
{
  return epiphany_stack_offset;
}

struct gcc_target targetm = TARGET_INITIALIZER;
