/* Subroutines used for code generation on the EPIPHANY cpu.
   Copyright (C) 1994-2021 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,
					const function_arg_info &);
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_arg_info_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_or_fixed_reg_p (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 is given
   by ARG), and we rely on this fact.  */


static void
epiphany_setup_incoming_varargs (cumulative_args_t cum,
				 const function_arg_info &arg,
				 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 (arg.mode != BLKmode);

  next_cum = *get_cumulative_args (cum);
  next_cum = (ROUND_ADVANCE_CUM (next_cum, arg.mode, arg.type)
	      + ROUND_ADVANCE_ARG (arg.mode, arg.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,
			    const function_arg_info &arg)
{
  int words = 0, rounded_cum;

  gcc_assert (!epiphany_pass_by_reference (cum, arg));

  rounded_cum = ROUND_ADVANCE_CUM (*get_cumulative_args (cum),
				   arg.mode, arg.type);
  if (rounded_cum < MAX_EPIPHANY_PARM_REGS)
    {
      words = MAX_EPIPHANY_PARM_REGS - rounded_cum;
      if (words >= ROUND_ADVANCE_ARG (arg.mode, arg.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_or_fixed_reg_p (regno) && !fixed_regs[regno])) \
   && (!call_used_or_fixed_reg_p (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;
  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)
{
  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, const function_arg_info &arg)
{
  if (tree type = arg.type)
    {
      if (AGGREGATE_TYPE_P (type)
	  && (arg.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]);
  reg_class_contents[SIBCALL_REGS] = reg_class_contents[GENERAL_REGS];
  /* It would be simpler and quicker if we could just use
     &~, alas, call_used_or_fixed_regs 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.

   CUM is a variable of type CUMULATIVE_ARGS which gives info about
    the preceding args and about the function being called.
   ARG is a description of the argument.  */
/* 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, const function_arg_info &arg)
{
  CUMULATIVE_ARGS cum = *get_cumulative_args (cum_v);

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

/* Update the data in CUM to advance over argument ARG.  */
static void
epiphany_function_arg_advance (cumulative_args_t cum_v,
			       const function_arg_info &arg)
{
  CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);

  *cum = (ROUND_ADVANCE_CUM (*cum, arg.mode, arg.type)
	  + ROUND_ADVANCE_ARG (arg.mode, arg.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_or_fixed_reg_p (GPR_IP));
  gcc_assert (call_used_or_fixed_reg_p (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_or_fixed_reg_p (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;
