/* Subroutines used for code generation on the Argonaut ARC cpu.
   Copyright (C) 1994, 1995, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
   2004, 2005, 2006, 2007, 2008 Free Software Foundation, 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/>.  */

/* ??? This is an old port, and is undoubtedly suffering from bit rot.  */

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "tm.h"
#include "tree.h"
#include "rtl.h"
#include "regs.h"
#include "hard-reg-set.h"
#include "real.h"
#include "insn-config.h"
#include "conditions.h"
#include "output.h"
#include "insn-attr.h"
#include "flags.h"
#include "function.h"
#include "expr.h"
#include "recog.h"
#include "toplev.h"
#include "tm_p.h"
#include "target.h"
#include "target-def.h"

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

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

/* Save the operands last given to a compare for use when we
   generate a scc or bcc insn.  */
rtx arc_compare_op0, arc_compare_op1;

/* Name of text, data, and rodata sections used in varasm.c.  */
const char *arc_text_section;
const char *arc_data_section;
const char *arc_rodata_section;

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

/* Variables used by arc_final_prescan_insn to implement conditional
   execution.  */
static int arc_ccfsm_state;
static int arc_ccfsm_current_cc;
static rtx arc_ccfsm_target_insn;
static int arc_ccfsm_target_label;

/* The maximum number of insns skipped which will be conditionalised if
   possible.  */
#define MAX_INSNS_SKIPPED 3

/* A nop is needed between a 4 byte insn that sets the condition codes and
   a branch that uses them (the same isn't true for an 8 byte insn that sets
   the condition codes).  Set by arc_final_prescan_insn.  Used by
   arc_print_operand.  */
static int last_insn_set_cc_p;
static int current_insn_set_cc_p;
static bool arc_handle_option (size_t, const char *, int);
static void record_cc_ref (rtx);
static void arc_init_reg_tables (void);
static int get_arc_condition_code (rtx);
const struct attribute_spec arc_attribute_table[];
static tree arc_handle_interrupt_attribute (tree *, tree, tree, int, bool *);
static bool arc_assemble_integer (rtx, unsigned int, int);
static void arc_output_function_prologue (FILE *, HOST_WIDE_INT);
static void arc_output_function_epilogue (FILE *, HOST_WIDE_INT);
static void arc_file_start (void);
static void arc_internal_label (FILE *, const char *, unsigned long);
static void arc_va_start (tree, rtx);
static void arc_setup_incoming_varargs (CUMULATIVE_ARGS *, enum machine_mode,
					tree, int *, int);
static bool arc_rtx_costs (rtx, int, int, int *, bool);
static int arc_address_cost (rtx, bool);
static void arc_external_libcall (rtx);
static bool arc_return_in_memory (const_tree, const_tree);
static bool arc_pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode,
				   const_tree, bool);

/* Initialize the GCC target structure.  */
#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_ASM_INTEGER
#define TARGET_ASM_INTEGER arc_assemble_integer

#undef TARGET_ASM_FUNCTION_PROLOGUE
#define TARGET_ASM_FUNCTION_PROLOGUE arc_output_function_prologue
#undef TARGET_ASM_FUNCTION_EPILOGUE
#define TARGET_ASM_FUNCTION_EPILOGUE arc_output_function_epilogue
#undef TARGET_ASM_FILE_START
#define TARGET_ASM_FILE_START arc_file_start
#undef TARGET_ATTRIBUTE_TABLE
#define TARGET_ATTRIBUTE_TABLE arc_attribute_table
#undef TARGET_ASM_INTERNAL_LABEL
#define TARGET_ASM_INTERNAL_LABEL arc_internal_label
#undef TARGET_ASM_EXTERNAL_LIBCALL
#define TARGET_ASM_EXTERNAL_LIBCALL arc_external_libcall

#undef TARGET_HANDLE_OPTION
#define TARGET_HANDLE_OPTION arc_handle_option

#undef TARGET_RTX_COSTS
#define TARGET_RTX_COSTS arc_rtx_costs
#undef TARGET_ADDRESS_COST
#define TARGET_ADDRESS_COST arc_address_cost

#undef TARGET_PROMOTE_FUNCTION_ARGS
#define TARGET_PROMOTE_FUNCTION_ARGS hook_bool_const_tree_true
#undef TARGET_PROMOTE_FUNCTION_RETURN
#define TARGET_PROMOTE_FUNCTION_RETURN hook_bool_const_tree_true
#undef TARGET_PROMOTE_PROTOTYPES
#define TARGET_PROMOTE_PROTOTYPES hook_bool_const_tree_true

#undef TARGET_RETURN_IN_MEMORY
#define TARGET_RETURN_IN_MEMORY arc_return_in_memory
#undef TARGET_PASS_BY_REFERENCE
#define TARGET_PASS_BY_REFERENCE arc_pass_by_reference
#undef TARGET_CALLEE_COPIES
#define TARGET_CALLEE_COPIES hook_bool_CUMULATIVE_ARGS_mode_tree_bool_true

#undef TARGET_SETUP_INCOMING_VARARGS
#define TARGET_SETUP_INCOMING_VARARGS arc_setup_incoming_varargs

#undef TARGET_EXPAND_BUILTIN_VA_START
#define TARGET_EXPAND_BUILTIN_VA_START arc_va_start

struct gcc_target targetm = TARGET_INITIALIZER;

/* Implement TARGET_HANDLE_OPTION.  */

static bool
arc_handle_option (size_t code, const char *arg, int value ATTRIBUTE_UNUSED)
{
  switch (code)
    {
    case OPT_mcpu_:
      return strcmp (arg, "base") == 0 || ARC_EXTENSION_CPU (arg);

    default:
      return true;
    }
}

/* Called by OVERRIDE_OPTIONS to initialize various things.  */

void
arc_init (void)
{
  char *tmp;
  
  /* Set the pseudo-ops for the various standard sections.  */
  arc_text_section = tmp = XNEWVEC (char, strlen (arc_text_string) + sizeof (ARC_SECTION_FORMAT) + 1);
  sprintf (tmp, ARC_SECTION_FORMAT, arc_text_string);
  arc_data_section = tmp = XNEWVEC (char, strlen (arc_data_string) + sizeof (ARC_SECTION_FORMAT) + 1);
  sprintf (tmp, ARC_SECTION_FORMAT, arc_data_string);
  arc_rodata_section = tmp = XNEWVEC (char, strlen (arc_rodata_string) + sizeof (ARC_SECTION_FORMAT) + 1);
  sprintf (tmp, ARC_SECTION_FORMAT, arc_rodata_string);

  arc_init_reg_tables ();

  /* Initialize array for PRINT_OPERAND_PUNCT_VALID_P.  */
  memset (arc_punct_chars, 0, sizeof (arc_punct_chars));
  arc_punct_chars['#'] = 1;
  arc_punct_chars['*'] = 1;
  arc_punct_chars['?'] = 1;
  arc_punct_chars['!'] = 1;
  arc_punct_chars['~'] = 1;
}

/* The condition codes of the ARC, and the inverse function.  */
static const char *const arc_condition_codes[] =
{
  "al", 0, "eq", "ne", "p", "n", "c", "nc", "v", "nv",
  "gt", "le", "ge", "lt", "hi", "ls", "pnz", 0
};

#define ARC_INVERSE_CONDITION_CODE(X)  ((X) ^ 1)

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

static int
get_arc_condition_code (rtx comparison)
{
  switch (GET_CODE (comparison))
    {
    case EQ : return 2;
    case NE : return 3;
    case GT : return 10;
    case LE : return 11;
    case GE : return 12;
    case LT : return 13;
    case GTU : return 14;
    case LEU : return 15;
    case LTU : return 6;
    case GEU : return 7;
    default : gcc_unreachable ();
    }
  /*NOTREACHED*/
  return (42);
}

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

enum machine_mode
arc_select_cc_mode (enum rtx_code op,
	            rtx x ATTRIBUTE_UNUSED,
                    rtx y ATTRIBUTE_UNUSED)
{
  switch (op)
    {
    case EQ :
    case NE :
      return CCZNmode;
    default :
      switch (GET_CODE (x))
	{
	case AND :
	case IOR :
	case XOR :
	case SIGN_EXTEND :
	case ZERO_EXTEND :
	  return CCZNmode;
	case ASHIFT :
	case ASHIFTRT :
	case LSHIFTRT :
	  return CCZNCmode;
	default:
	  break;
	}
    }
  return CCmode;
}

/* Vectors to keep interesting information about registers where it can easily
   be got.  We use to use the actual mode value as the bit number, but there
   is (or may be) more than 32 modes now.  Instead we use two tables: one
   indexed by hard register number, and one indexed by mode.  */

/* The purpose of arc_mode_class is to shrink the range of modes so that
   they all fit (as bit numbers) in a 32-bit word (again).  Each real mode is
   mapped into one arc_mode_class mode.  */

enum arc_mode_class {
  C_MODE,
  S_MODE, D_MODE, T_MODE, O_MODE,
  SF_MODE, DF_MODE, TF_MODE, OF_MODE
};

/* Modes for condition codes.  */
#define C_MODES (1 << (int) C_MODE)

/* Modes for single-word and smaller quantities.  */
#define S_MODES ((1 << (int) S_MODE) | (1 << (int) SF_MODE))

/* Modes for double-word and smaller quantities.  */
#define D_MODES (S_MODES | (1 << (int) D_MODE) | (1 << DF_MODE))

/* Modes for quad-word and smaller quantities.  */
#define T_MODES (D_MODES | (1 << (int) T_MODE) | (1 << (int) TF_MODE))

/* Value is 1 if register/mode pair is acceptable on arc.  */

const unsigned int arc_hard_regno_mode_ok[] = {
  T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, T_MODES,
  T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, T_MODES,
  T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, D_MODES,
  D_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES,

  /* ??? Leave these as S_MODES for now.  */
  S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES,
  S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES,
  S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES,
  S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, C_MODES
};

unsigned int arc_mode_class [NUM_MACHINE_MODES];

enum reg_class arc_regno_reg_class[FIRST_PSEUDO_REGISTER];

static void
arc_init_reg_tables (void)
{
  int i;

  for (i = 0; i < NUM_MACHINE_MODES; i++)
    {
      switch (GET_MODE_CLASS (i))
	{
	case MODE_INT:
	case MODE_PARTIAL_INT:
	case MODE_COMPLEX_INT:
	  if (GET_MODE_SIZE (i) <= 4)
	    arc_mode_class[i] = 1 << (int) S_MODE;
	  else if (GET_MODE_SIZE (i) == 8)
	    arc_mode_class[i] = 1 << (int) D_MODE;
	  else if (GET_MODE_SIZE (i) == 16)
	    arc_mode_class[i] = 1 << (int) T_MODE;
	  else if (GET_MODE_SIZE (i) == 32)
	    arc_mode_class[i] = 1 << (int) O_MODE;
	  else 
	    arc_mode_class[i] = 0;
	  break;
	case MODE_FLOAT:
	case MODE_COMPLEX_FLOAT:
	  if (GET_MODE_SIZE (i) <= 4)
	    arc_mode_class[i] = 1 << (int) SF_MODE;
	  else if (GET_MODE_SIZE (i) == 8)
	    arc_mode_class[i] = 1 << (int) DF_MODE;
	  else if (GET_MODE_SIZE (i) == 16)
	    arc_mode_class[i] = 1 << (int) TF_MODE;
	  else if (GET_MODE_SIZE (i) == 32)
	    arc_mode_class[i] = 1 << (int) OF_MODE;
	  else 
	    arc_mode_class[i] = 0;
	  break;
	case MODE_CC:
	  arc_mode_class[i] = 1 << (int) C_MODE;
	  break;
	default:
	  arc_mode_class[i] = 0;
	  break;
	}
    }

  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
    {
      if (i < 60)
	arc_regno_reg_class[i] = GENERAL_REGS;
      else if (i == 60)
	arc_regno_reg_class[i] = LPCOUNT_REG;
      else if (i == 61)
	arc_regno_reg_class[i] = NO_REGS /* CC_REG: must be NO_REGS */;
      else
	arc_regno_reg_class[i] = NO_REGS;
    }
}

/* ARC specific attribute support.

   The ARC has these attributes:
   interrupt - for interrupt functions
*/

const struct attribute_spec arc_attribute_table[] =
{
  /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
  { "interrupt", 1, 1, true,  false, false, arc_handle_interrupt_attribute },
  { NULL,        0, 0, false, false, false, NULL }
};

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

  if (TREE_CODE (value) != STRING_CST)
    {
      warning (OPT_Wattributes,
	       "argument of %qs attribute is not a string constant",
	       IDENTIFIER_POINTER (name));
      *no_add_attrs = true;
    }
  else if (strcmp (TREE_STRING_POINTER (value), "ilink1")
	   && strcmp (TREE_STRING_POINTER (value), "ilink2"))
    {
      warning (OPT_Wattributes,
	       "argument of %qs attribute is not \"ilink1\" or \"ilink2\"",
	       IDENTIFIER_POINTER (name));
      *no_add_attrs = true;
    }

  return NULL_TREE;
}


/* Acceptable arguments to the call insn.  */

int
call_address_operand (rtx op, enum machine_mode mode)
{
  return (symbolic_operand (op, mode)
	  || (GET_CODE (op) == CONST_INT && LEGITIMATE_CONSTANT_P (op))
	  || (GET_CODE (op) == REG));
}

int
call_operand (rtx op, enum machine_mode mode)
{
  if (GET_CODE (op) != MEM)
    return 0;
  op = XEXP (op, 0);
  return call_address_operand (op, mode);
}

/* Returns 1 if OP is a symbol reference.  */

int
symbolic_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
  switch (GET_CODE (op))
    {
    case SYMBOL_REF:
    case LABEL_REF:
    case CONST :
      return 1;
    default:
      return 0;
    }
}

/* Return truth value of statement that OP is a symbolic memory
   operand of mode MODE.  */

int
symbolic_memory_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
  if (GET_CODE (op) == SUBREG)
    op = SUBREG_REG (op);
  if (GET_CODE (op) != MEM)
    return 0;
  op = XEXP (op, 0);
  return (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == CONST
	  || GET_CODE (op) == LABEL_REF);
}

/* Return true if OP is a short immediate (shimm) value.  */

int
short_immediate_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
  if (GET_CODE (op) != CONST_INT)
    return 0;
  return SMALL_INT (INTVAL (op));
}

/* Return true if OP will require a long immediate (limm) value.
   This is currently only used when calculating length attributes.  */

int
long_immediate_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
  switch (GET_CODE (op))
    {
    case SYMBOL_REF :
    case LABEL_REF :
    case CONST :
      return 1;
    case CONST_INT :
      return !SMALL_INT (INTVAL (op));
    case CONST_DOUBLE :
      /* These can happen because large unsigned 32-bit constants are
	 represented this way (the multiplication patterns can cause these
	 to be generated).  They also occur for SFmode values.  */
      return 1;
    default:
      break;
    }
  return 0;
}

/* Return true if OP is a MEM that when used as a load or store address will
   require an 8 byte insn.
   Load and store instructions don't allow the same possibilities but they're
   similar enough that this one function will do.
   This is currently only used when calculating length attributes.  */

int
long_immediate_loadstore_operand (rtx op,
                                  enum machine_mode mode ATTRIBUTE_UNUSED)
{
  if (GET_CODE (op) != MEM)
    return 0;

  op = XEXP (op, 0);
  switch (GET_CODE (op))
    {
    case SYMBOL_REF :
    case LABEL_REF :
    case CONST :
      return 1;
    case CONST_INT :
      /* This must be handled as "st c,[limm]".  Ditto for load.
	 Technically, the assembler could translate some possibilities to
	 "st c,[limm/2 + limm/2]" if limm/2 will fit in a shimm, but we don't
	 assume that it does.  */
      return 1;
    case CONST_DOUBLE :
      /* These can happen because large unsigned 32-bit constants are
	 represented this way (the multiplication patterns can cause these
	 to be generated).  They also occur for SFmode values.  */
      return 1;
    case REG :
      return 0;
    case PLUS :
      if (GET_CODE (XEXP (op, 1)) == CONST_INT
	  && !SMALL_INT (INTVAL (XEXP (op, 1))))
	return 1;
      return 0;
    default:
      break;
    }
  return 0;
}

/* Return true if OP is an acceptable argument for a single word
   move source.  */

int
move_src_operand (rtx op, enum machine_mode mode)
{
  switch (GET_CODE (op))
    {
    case SYMBOL_REF :
    case LABEL_REF :
    case CONST :
      return 1;
    case CONST_INT :
      return (LARGE_INT (INTVAL (op)));
    case CONST_DOUBLE :
      /* We can handle DImode integer constants in SImode if the value
	 (signed or unsigned) will fit in 32 bits.  This is needed because
	 large unsigned 32-bit constants are represented as CONST_DOUBLEs.  */
      if (mode == SImode)
	return arc_double_limm_p (op);
      /* We can handle 32-bit floating point constants.  */
      if (mode == SFmode)
	return GET_MODE (op) == SFmode;
      return 0;
    case REG :
      return register_operand (op, mode);
    case SUBREG :
      /* (subreg (mem ...) ...) can occur here if the inner part was once a
	 pseudo-reg and is now a stack slot.  */
      if (GET_CODE (SUBREG_REG (op)) == MEM)
	return address_operand (XEXP (SUBREG_REG (op), 0), mode);
      else
	return register_operand (op, mode);
    case MEM :
      return address_operand (XEXP (op, 0), mode);
    default :
      return 0;
    }
}

/* Return true if OP is an acceptable argument for a double word
   move source.  */

int
move_double_src_operand (rtx op, enum machine_mode mode)
{
  switch (GET_CODE (op))
    {
    case REG :
      return register_operand (op, mode);
    case SUBREG :
      /* (subreg (mem ...) ...) can occur here if the inner part was once a
	 pseudo-reg and is now a stack slot.  */
      if (GET_CODE (SUBREG_REG (op)) == MEM)
	return move_double_src_operand (SUBREG_REG (op), mode);
      else
	return register_operand (op, mode);
    case MEM :
      /* Disallow auto inc/dec for now.  */
      if (GET_CODE (XEXP (op, 0)) == PRE_DEC
	  || GET_CODE (XEXP (op, 0)) == PRE_INC)
	return 0;
      return address_operand (XEXP (op, 0), mode);
    case CONST_INT :
    case CONST_DOUBLE :
      return 1;
    default :
      return 0;
    }
}

/* Return true if OP is an acceptable argument for a move destination.  */

int
move_dest_operand (rtx op, enum machine_mode mode)
{
  switch (GET_CODE (op))
    {
    case REG :
      return register_operand (op, mode);
    case SUBREG :
      /* (subreg (mem ...) ...) can occur here if the inner part was once a
	 pseudo-reg and is now a stack slot.  */
      if (GET_CODE (SUBREG_REG (op)) == MEM)
	return address_operand (XEXP (SUBREG_REG (op), 0), mode);
      else
	return register_operand (op, mode);
    case MEM :
      return address_operand (XEXP (op, 0), mode);
    default :
      return 0;
    }
}

/* Return true if OP is valid load with update operand.  */

int
load_update_operand (rtx op, enum machine_mode mode)
{
  if (GET_CODE (op) != MEM
      || GET_MODE (op) != mode)
    return 0;
  op = XEXP (op, 0);
  if (GET_CODE (op) != PLUS
      || GET_MODE (op) != Pmode
      || !register_operand (XEXP (op, 0), Pmode)
      || !nonmemory_operand (XEXP (op, 1), Pmode))
    return 0;
  return 1;
}

/* Return true if OP is valid store with update operand.  */

int
store_update_operand (rtx op, enum machine_mode mode)
{
  if (GET_CODE (op) != MEM
      || GET_MODE (op) != mode)
    return 0;
  op = XEXP (op, 0);
  if (GET_CODE (op) != PLUS
      || GET_MODE (op) != Pmode
      || !register_operand (XEXP (op, 0), Pmode)
      || !(GET_CODE (XEXP (op, 1)) == CONST_INT
	   && SMALL_INT (INTVAL (XEXP (op, 1)))))
    return 0;
  return 1;
}

/* Return true if OP is a non-volatile non-immediate operand.
   Volatile memory refs require a special "cache-bypass" instruction
   and only the standard movXX patterns are set up to handle them.  */

int
nonvol_nonimm_operand (rtx op, enum machine_mode mode)
{
  if (GET_CODE (op) == MEM && MEM_VOLATILE_P (op))
    return 0;
  return nonimmediate_operand (op, mode);
}

/* Accept integer operands in the range -0x80000000..0x7fffffff.  We have
   to check the range carefully since this predicate is used in DImode
   contexts.  */

int
const_sint32_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
  /* All allowed constants will fit a CONST_INT.  */
  return (GET_CODE (op) == CONST_INT
	  && (INTVAL (op) >= (-0x7fffffff - 1) && INTVAL (op) <= 0x7fffffff));
}

/* Accept integer operands in the range 0..0xffffffff.  We have to check the
   range carefully since this predicate is used in DImode contexts.  Also, we
   need some extra crud to make it work when hosted on 64-bit machines.  */

int
const_uint32_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
#if HOST_BITS_PER_WIDE_INT > 32
  /* All allowed constants will fit a CONST_INT.  */
  return (GET_CODE (op) == CONST_INT
	  && (INTVAL (op) >= 0 && INTVAL (op) <= 0xffffffffL));
#else
  return ((GET_CODE (op) == CONST_INT && INTVAL (op) >= 0)
	  || (GET_CODE (op) == CONST_DOUBLE && CONST_DOUBLE_HIGH (op) == 0));
#endif
}

/* Return 1 if OP is a comparison operator valid for the mode of CC.
   This allows the use of MATCH_OPERATOR to recognize all the branch insns.

   Some insns only set a few bits in the condition code.  So only allow those
   comparisons that use the bits that are valid.  */

int
proper_comparison_operator (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
  enum rtx_code code;
  if (!COMPARISON_P (op))
    return 0;

  code = GET_CODE (op);
  if (GET_MODE (XEXP (op, 0)) == CCZNmode)
    return (code == EQ || code == NE);
  if (GET_MODE (XEXP (op, 0)) == CCZNCmode)
    return (code == EQ || code == NE
	    || code == LTU || code == GEU || code == GTU || code == LEU);
  return 1;
}

/* Misc. utilities.  */

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

rtx
gen_compare_reg (enum rtx_code code, rtx x, rtx y)
{
  enum machine_mode mode = SELECT_CC_MODE (code, x, y);
  rtx cc_reg;

  cc_reg = gen_rtx_REG (mode, 61);

  emit_insn (gen_rtx_SET (VOIDmode, cc_reg,
			  gen_rtx_COMPARE (mode, x, y)));

  return cc_reg;
}

/* Return 1 if VALUE, a const_double, will fit in a limm (4 byte number).
   We assume the value can be either signed or unsigned.  */

int
arc_double_limm_p (rtx value)
{
  HOST_WIDE_INT low, high;

  gcc_assert (GET_CODE (value) == CONST_DOUBLE);

  low = CONST_DOUBLE_LOW (value);
  high = CONST_DOUBLE_HIGH (value);

  if (low & 0x80000000)
    {
      return (((unsigned HOST_WIDE_INT) low <= 0xffffffff && high == 0)
	      || (((low & - (unsigned HOST_WIDE_INT) 0x80000000)
		   == - (unsigned HOST_WIDE_INT) 0x80000000)
		  && high == -1));
    }
  else
    {
      return (unsigned HOST_WIDE_INT) low <= 0x7fffffff && high == 0;
    }
}

/* Do any needed setup for a variadic function.  For the ARC, we must
   create a register parameter block, and then copy any anonymous arguments
   in registers to memory.

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

   We do things a little weird here.  We're supposed to only allocate space
   for the anonymous arguments.  However we need to keep the stack eight byte
   aligned.  So we round the space up if necessary, and leave it to va_start
   to compensate.  */

static void
arc_setup_incoming_varargs (CUMULATIVE_ARGS *cum,
                            enum machine_mode mode,
                            tree type ATTRIBUTE_UNUSED,
                            int *pretend_size,
                            int no_rtl)
{
  int first_anon_arg;

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

  first_anon_arg = *cum + ((GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1)
			   / UNITS_PER_WORD);

  if (first_anon_arg < MAX_ARC_PARM_REGS && !no_rtl)
    {
      /* Note that first_reg_offset < MAX_ARC_PARM_REGS.  */
      int first_reg_offset = first_anon_arg;
      /* Size in words to "pretend" allocate.  */
      int size = MAX_ARC_PARM_REGS - first_reg_offset;
      /* Extra slop to keep stack eight byte aligned.  */
      int align_slop = size & 1;
      rtx regblock;

      regblock = gen_rtx_MEM (BLKmode,
			      plus_constant (arg_pointer_rtx,
					     FIRST_PARM_OFFSET (0)
					     + align_slop * UNITS_PER_WORD));
      set_mem_alias_set (regblock, get_varargs_alias_set ());
      set_mem_align (regblock, BITS_PER_WORD);
      move_block_from_reg (first_reg_offset, regblock,
			   MAX_ARC_PARM_REGS - first_reg_offset);

      *pretend_size = ((MAX_ARC_PARM_REGS - first_reg_offset + align_slop)
		       * 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
arc_rtx_costs (rtx x, int code, int outer_code ATTRIBUTE_UNUSED, int *total,
	       bool speed ATTRIBUTE_UNUSED)
{
  switch (code)
    {
      /* Small integers are as cheap as registers.  4 byte values can
	 be fetched as immediate constants - let's give that the cost
	 of an extra insn.  */
    case CONST_INT:
      if (SMALL_INT (INTVAL (x)))
	{
	  *total = 0;
	  return true;
	}
      /* FALLTHRU */

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

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

    /* Encourage synth_mult to find a synthetic multiply when reasonable.
       If we need more than 12 insns to do a multiply, then go out-of-line,
       since the call overhead will be < 10% of the cost of the multiply.  */
    case ASHIFT:
    case ASHIFTRT:
    case LSHIFTRT:
      if (TARGET_SHIFTER)
        *total = COSTS_N_INSNS (1);
      else if (GET_CODE (XEXP (x, 1)) != CONST_INT)
        *total = COSTS_N_INSNS (16);
      else
        *total = COSTS_N_INSNS (INTVAL (XEXP ((x), 1)));
      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
arc_address_cost (rtx addr, bool speed ATTRIBUTE_UNUSED)
{
  switch (GET_CODE (addr))
    {
    case REG :
      return 1;

    case LABEL_REF :
    case SYMBOL_REF :
    case CONST :
      return 2;

    case PLUS :
      {
	register rtx plus0 = XEXP (addr, 0);
	register rtx plus1 = XEXP (addr, 1);

	if (GET_CODE (plus0) != REG)
	  break;

	switch (GET_CODE (plus1))
	  {
	  case CONST_INT :
	    return SMALL_INT (plus1) ? 1 : 2;
	  case CONST :
	  case SYMBOL_REF :
	  case LABEL_REF :
	    return 2;
	  default:
	    break;
	  }
	break;
      }
    default:
      break;
    }

  return 4;
}

/* Function prologue/epilogue handlers.  */

/* ARC 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+16->+-----------------------+FP+48->+-----------------------+
        | 4 word save area for  |       |  reg parm save area,  |
        | return addr, prev %fp |       |  only created for     |    
  SP+0->+-----------------------+       |  variable argument    |    
                                        |  functions            |    
                                 FP+16->+-----------------------+    
                                        | 4 word save area for  |    
                                        | return addr, prev %fp |    
                                  FP+0->+-----------------------+    
                                        |                       |    
                                        |  local variables      |    
                                        |                       |    
                                        +-----------------------+    
                                        |                       |    
                                        |  register save area   |    
                                        |                       |    
                                        +-----------------------+    
                                        |                       |    
                                        |  alloca allocations   |    
                                        |                       |    
                                        +-----------------------+    
                                        |                       |    
                                        |  arguments on stack   |    
                                        |                       |    
                                 SP+16->+-----------------------+
   low                                  | 4 word save area for  |    
   memory                               | return addr, prev %fp |    
                                  SP+0->+-----------------------+    

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

/* Structure to be filled in by arc_compute_frame_size with register
   save masks, and offsets for the current function.  */
struct arc_frame_info
{
  unsigned int total_size;	/* # bytes that the entire frame takes up.  */
  unsigned int extra_size;	/* # bytes of extra stuff.  */
  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.  */
  unsigned int reg_offset;	/* Offset from new sp to store regs.  */
  unsigned int gmask;		/* Mask of saved gp registers.  */
  int          initialized;	/* Nonzero if frame size already calculated.  */
};

/* Current frame information calculated by arc_compute_frame_size.  */
static struct arc_frame_info current_frame_info;

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

/* Type of function DECL.

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

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

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

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

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

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

      if (name == get_identifier ("__interrupt__")
	  && list_length (args) == 1
	  && TREE_CODE (TREE_VALUE (args)) == STRING_CST)
	{
	  tree value = TREE_VALUE (args);

	  if (!strcmp (TREE_STRING_POINTER (value), "ilink1"))
	    fn_type = ARC_FUNCTION_ILINK1;
	  else if (!strcmp (TREE_STRING_POINTER (value), "ilink2"))
	    fn_type = ARC_FUNCTION_ILINK2;
	  else
	    gcc_unreachable ();
	  break;
	}
    }

  last_fn = decl;
  return fn_type;
}

#define ILINK1_REGNUM 29
#define ILINK2_REGNUM 30
#define RETURN_ADDR_REGNUM 31
#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) \
((regno) != RETURN_ADDR_REGNUM && (regno) != FRAME_POINTER_REGNUM \
 && (df_regs_ever_live_p (regno) && (!call_used_regs[regno] || interrupt_p)))

#define MUST_SAVE_RETURN_ADDR (df_regs_ever_live_p (RETURN_ADDR_REGNUM))

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

   SIZE is the size needed for local variables.  */

unsigned int
arc_compute_frame_size (int size /* # of var. bytes allocated.  */)
{
  int regno;
  unsigned int total_size, var_size, args_size, pretend_size, extra_size;
  unsigned int reg_size, reg_offset;
  unsigned int gmask;
  enum arc_function_type fn_type;
  int interrupt_p;

  var_size	= size;
  args_size	= crtl->outgoing_args_size;
  pretend_size	= crtl->args.pretend_args_size;
  extra_size	= FIRST_PARM_OFFSET (0);
  total_size	= extra_size + pretend_size + args_size + var_size;
  reg_offset	= FIRST_PARM_OFFSET(0) + crtl->outgoing_args_size;
  reg_size	= 0;
  gmask		= 0;

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

  /* Calculate space needed for registers.
     ??? We ignore the extension registers for now.  */

  for (regno = 0; regno <= 31; regno++)
    {
      if (MUST_SAVE_REGISTER (regno, interrupt_p))
	{
	  reg_size += UNITS_PER_WORD;
	  gmask |= 1 << regno;
	}
    }

  total_size += reg_size;

  /* If the only space to allocate is the fp/blink save area this is an
     empty frame.  However, if we'll be making a function call we need to
     allocate a stack frame for our callee's fp/blink save area.  */
  if (total_size == extra_size
      && !MUST_SAVE_RETURN_ADDR)
    total_size = extra_size = 0;

  total_size = ARC_STACK_ALIGN (total_size);

  /* Save computed information.  */
  current_frame_info.total_size   = total_size;
  current_frame_info.extra_size   = extra_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.reg_offset	  = reg_offset;
  current_frame_info.gmask	  = gmask;
  current_frame_info.initialized  = reload_completed;

  /* Ok, we're done.  */
  return total_size;
}

/* Common code to save/restore registers.  */

void
arc_save_restore (FILE *file,
                  const char *base_reg,
                  unsigned int offset,
                  unsigned int gmask,
                  const char *op)
{
  int regno;

  if (gmask == 0)
    return;

  for (regno = 0; regno <= 31; regno++)
    {
      if ((gmask & (1L << regno)) != 0)
	{
	  fprintf (file, "\t%s %s,[%s,%d]\n",
		     op, reg_names[regno], base_reg, offset);
	  offset += UNITS_PER_WORD;
	}
    }
}

/* Target hook to assemble an integer object.  The ARC version needs to
   emit a special directive for references to labels and function
   symbols.  */

static bool
arc_assemble_integer (rtx x, unsigned int size, int aligned_p)
{
  if (size == UNITS_PER_WORD && aligned_p
      && ((GET_CODE (x) == SYMBOL_REF && SYMBOL_REF_FUNCTION_P (x))
	  || GET_CODE (x) == LABEL_REF))
    {
      fputs ("\t.word\t%st(", asm_out_file);
      output_addr_const (asm_out_file, x);
      fputs (")\n", asm_out_file);
      return true;
    }
  return default_assemble_integer (x, size, aligned_p);
}

/* Set up the stack and frame pointer (if desired) for the function.  */

static void
arc_output_function_prologue (FILE *file, HOST_WIDE_INT size)
{
  const char *sp_str = reg_names[STACK_POINTER_REGNUM];
  const char *fp_str = reg_names[FRAME_POINTER_REGNUM];
  unsigned int gmask = current_frame_info.gmask;
  enum arc_function_type fn_type = arc_compute_function_type (current_function_decl);

  /* If this is an interrupt handler, set up our stack frame.
     ??? Optimize later.  */
  if (ARC_INTERRUPT_P (fn_type))
    {
      fprintf (file, "\t%s interrupt handler\n",
	       ASM_COMMENT_START);
      fprintf (file, "\tsub %s,%s,16\n", sp_str, sp_str);
    }

  /* This is only for the human reader.  */
  fprintf (file, "\t%s BEGIN PROLOGUE %s vars= %d, regs= %d, args= %d, extra= %d\n",
	   ASM_COMMENT_START, ASM_COMMENT_START,
	   current_frame_info.var_size,
	   current_frame_info.reg_size / 4,
	   current_frame_info.args_size,
	   current_frame_info.extra_size);

  size = ARC_STACK_ALIGN (size);
  size = (! current_frame_info.initialized
	   ? arc_compute_frame_size (size)
	   : current_frame_info.total_size);

  /* These cases shouldn't happen.  Catch them now.  */
  gcc_assert (size || !gmask);

  /* Allocate space for register arguments if this is a variadic function.  */
  if (current_frame_info.pretend_size != 0)
    fprintf (file, "\tsub %s,%s,%d\n",
	     sp_str, sp_str, current_frame_info.pretend_size);

  /* The home-grown ABI says link register is saved first.  */
  if (MUST_SAVE_RETURN_ADDR)
    fprintf (file, "\tst %s,[%s,%d]\n",
	     reg_names[RETURN_ADDR_REGNUM], sp_str, UNITS_PER_WORD);

  /* Set up the previous frame pointer next (if we need to).  */
  if (frame_pointer_needed)
    {
      fprintf (file, "\tst %s,[%s]\n", fp_str, sp_str);
      fprintf (file, "\tmov %s,%s\n", fp_str, sp_str);
    }

  /* ??? We don't handle the case where the saved regs are more than 252
     bytes away from sp.  This can be handled by decrementing sp once, saving
     the regs, and then decrementing it again.  The epilogue doesn't have this
     problem as the `ld' insn takes reg+limm values (though it would be more
     efficient to avoid reg+limm).  */

  /* Allocate the stack frame.  */
  if (size - current_frame_info.pretend_size > 0)
    fprintf (file, "\tsub %s,%s," HOST_WIDE_INT_PRINT_DEC "\n",
	     sp_str, sp_str, size - current_frame_info.pretend_size);

  /* Save any needed call-saved regs (and call-used if this is an
     interrupt handler).  */
  arc_save_restore (file, sp_str, current_frame_info.reg_offset,
		    /* The zeroing of these two bits is unnecessary,
		       but leave this in for clarity.  */
		    gmask & ~(FRAME_POINTER_MASK | RETURN_ADDR_MASK),
		    "st");

  fprintf (file, "\t%s END PROLOGUE\n", ASM_COMMENT_START);
}

/* Do any necessary cleanup after a function to restore stack, frame,
   and regs.  */

static void
arc_output_function_epilogue (FILE *file, HOST_WIDE_INT size)
{
  rtx epilogue_delay = crtl->epilogue_delay_list;
  int noepilogue = FALSE;
  enum arc_function_type fn_type = arc_compute_function_type (current_function_decl);

  /* This is only for the human reader.  */
  fprintf (file, "\t%s EPILOGUE\n", ASM_COMMENT_START);

  size = ARC_STACK_ALIGN (size);
  size = (!current_frame_info.initialized
	   ? arc_compute_frame_size (size)
	   : current_frame_info.total_size);

  if (size == 0 && epilogue_delay == 0)
    {
      rtx insn = get_last_insn ();

      /* If the last insn was a BARRIER, we don't have to write any code
	 because a jump (aka return) was put there.  */
      if (GET_CODE (insn) == NOTE)
	insn = prev_nonnote_insn (insn);
      if (insn && GET_CODE (insn) == BARRIER)
	noepilogue = TRUE;
    }

  if (!noepilogue)
    {
      unsigned int pretend_size = current_frame_info.pretend_size;
      unsigned int frame_size = size - pretend_size;
      int restored, fp_restored_p;
      int can_trust_sp_p = !cfun->calls_alloca;
      const char *sp_str = reg_names[STACK_POINTER_REGNUM];
      const char *fp_str = reg_names[FRAME_POINTER_REGNUM];

      /* ??? There are lots of optimizations that can be done here.
	 EG: Use fp to restore regs if it's closer.
	 Maybe in time we'll do them all.  For now, always restore regs from
	 sp, but don't restore sp if we don't have to.  */

      if (!can_trust_sp_p)
	{
	  gcc_assert (frame_pointer_needed);
	  fprintf (file,"\tsub %s,%s,%d\t\t%s sp not trusted here\n",
		   sp_str, fp_str, frame_size, ASM_COMMENT_START);
	}

      /* Restore any saved registers.  */
      arc_save_restore (file, sp_str, current_frame_info.reg_offset,
			/* The zeroing of these two bits is unnecessary,
			   but leave this in for clarity.  */
			current_frame_info.gmask & ~(FRAME_POINTER_MASK | RETURN_ADDR_MASK),
			"ld");

      if (MUST_SAVE_RETURN_ADDR)
	fprintf (file, "\tld %s,[%s,%d]\n",
		 reg_names[RETURN_ADDR_REGNUM],
		 frame_pointer_needed ? fp_str : sp_str,
		 UNITS_PER_WORD + (frame_pointer_needed ? 0 : frame_size));

      /* Keep track of how much of the stack pointer we've restored.
	 It makes the following a lot more readable.  */
      restored = 0;
      fp_restored_p = 0;

      /* We try to emit the epilogue delay slot insn right after the load
	 of the return address register so that it can execute with the
	 stack intact.  Secondly, loads are delayed.  */
      /* ??? If stack intactness is important, always emit now.  */
      if (MUST_SAVE_RETURN_ADDR && epilogue_delay != NULL_RTX)
	{
	  final_scan_insn (XEXP (epilogue_delay, 0), file, 1, 1, NULL);
	  epilogue_delay = NULL_RTX;
	}

      if (frame_pointer_needed)
	{
	  /* Try to restore the frame pointer in the delay slot.  We can't,
	     however, if any of these is true.  */
	  if (epilogue_delay != NULL_RTX
	      || !SMALL_INT (frame_size)
	      || pretend_size
	      || ARC_INTERRUPT_P (fn_type))
	    {
	      /* Note that we restore fp and sp here!  */
	      fprintf (file, "\tld.a %s,[%s,%d]\n", fp_str, sp_str, frame_size);
	      restored += frame_size;
	      fp_restored_p = 1;
	    }
	}
      else if (!SMALL_INT (size /* frame_size + pretend_size */)
	       || ARC_INTERRUPT_P (fn_type))
	{
	  fprintf (file, "\tadd %s,%s,%d\n", sp_str, sp_str, frame_size);
	  restored += frame_size;
	}

      /* These must be done before the return insn because the delay slot
	 does the final stack restore.  */
      if (ARC_INTERRUPT_P (fn_type))
	{
	  if (epilogue_delay)
	    {
	      final_scan_insn (XEXP (epilogue_delay, 0), file, 1, 1, NULL);
	    }
	}

      /* Emit the return instruction.  */
      {
	static const int regs[4] = {
	  0, RETURN_ADDR_REGNUM, ILINK1_REGNUM, ILINK2_REGNUM
	};

	/* Update the flags, if returning from an interrupt handler. */
	if (ARC_INTERRUPT_P (fn_type))
	  fprintf (file, "\tj.d.f %s\n", reg_names[regs[fn_type]]);
	else
	  fprintf (file, "\tj.d %s\n", reg_names[regs[fn_type]]);
	}

      /* If the only register saved is the return address, we need a
	 nop, unless we have an instruction to put into it.  Otherwise
	 we don't since reloading multiple registers doesn't reference
	 the register being loaded.  */

      if (ARC_INTERRUPT_P (fn_type))
	fprintf (file, "\tadd %s,%s,16\n", sp_str, sp_str);
      else if (epilogue_delay != NULL_RTX)
	{
	  gcc_assert (!frame_pointer_needed || fp_restored_p);
	  gcc_assert (restored >= size);
	  final_scan_insn (XEXP (epilogue_delay, 0), file, 1, 1, NULL);
	}
      else if (frame_pointer_needed && !fp_restored_p)
	{
	  gcc_assert (SMALL_INT (frame_size));
	  /* Note that we restore fp and sp here!  */
	  fprintf (file, "\tld.a %s,[%s,%d]\n", fp_str, sp_str, frame_size);
	}
      else if (restored < size)
	{
	  gcc_assert (SMALL_INT (size - restored));
	  fprintf (file, "\tadd %s,%s," HOST_WIDE_INT_PRINT_DEC "\n",
		   sp_str, sp_str, size - restored);
	}
      else
	fprintf (file, "\tnop\n");
    }

  /* Reset state info for each function.  */
  current_frame_info = zero_frame_info;
  arc_compute_function_type (NULL_TREE);
}

/* Define the number of delay slots needed for the function epilogue.

   Interrupt handlers can't have any epilogue delay slots (it's always needed
   for something else, I think).  For normal functions, we have to worry about
   using call-saved regs as they'll be restored before the delay slot insn.
   Functions with non-empty frames already have enough choices for the epilogue
   delay slot so for now we only consider functions with empty frames.  */

int
arc_delay_slots_for_epilogue (void)
{
  if (arc_compute_function_type (current_function_decl) != ARC_FUNCTION_NORMAL)
    return 0;
  if (!current_frame_info.initialized)
    (void) arc_compute_frame_size (get_frame_size ());
  if (current_frame_info.total_size == 0)
    return 1;
  return 0;
}

/* Return true if TRIAL is a valid insn for the epilogue delay slot.
   Any single length instruction which doesn't reference the stack or frame
   pointer or any call-saved register is OK.  SLOT will always be 0.  */

int
arc_eligible_for_epilogue_delay (rtx trial, int slot)
{
  gcc_assert (!slot);

  if (get_attr_length (trial) == 1
      /* If registers where saved, presumably there's more than enough
	 possibilities for the delay slot.  The alternative is something
	 more complicated (of course, if we expanded the epilogue as rtl
	 this problem would go away).  */
      /* ??? Note that this will always be true since only functions with
	 empty frames have epilogue delay slots.  See
	 arc_delay_slots_for_epilogue.  */
      && current_frame_info.gmask == 0
      && ! reg_mentioned_p (stack_pointer_rtx, PATTERN (trial))
      && ! reg_mentioned_p (frame_pointer_rtx, PATTERN (trial)))
    return 1;
  return 0;
}

/* Return true if OP is a shift operator.  */

int
shift_operator (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
  switch (GET_CODE (op))
    {
    case ASHIFTRT:
    case LSHIFTRT:
    case ASHIFT:
      return 1;
    default:
      return 0;
    }
}

/* Output the assembler code for doing a shift.
   We go to a bit of trouble to generate efficient code as the ARC only has
   single bit shifts.  This is taken from the h8300 port.  We only have one
   mode of shifting and can't access individual bytes like the h8300 can, so
   this is greatly simplified (at the expense of not generating hyper-
   efficient code).

   This function is not used if the variable shift insns are present.  */

/* ??? We assume the output operand is the same as operand 1.
   This can be optimized (deleted) in the case of 1 bit shifts.  */
/* ??? We use the loop register here.  We don't use it elsewhere (yet) and
   using it here will give us a chance to play with it.  */

const char *
output_shift (rtx *operands)
{
  rtx shift = operands[3];
  enum machine_mode mode = GET_MODE (shift);
  enum rtx_code code = GET_CODE (shift);
  const char *shift_one;

  gcc_assert (mode == SImode);

  switch (code)
    {
    case ASHIFT:   shift_one = "asl %0,%0"; break;
    case ASHIFTRT: shift_one = "asr %0,%0"; break;
    case LSHIFTRT: shift_one = "lsr %0,%0"; break;
    default:       gcc_unreachable ();
    }

  if (GET_CODE (operands[2]) != CONST_INT)
    {
      if (optimize)
	{
	  output_asm_insn ("sub.f 0,%2,0", operands);
      	  output_asm_insn ("mov lp_count,%2", operands);
	  output_asm_insn ("bz 2f", operands);
	}
      else
	output_asm_insn ("mov %4,%2", operands);
      goto shiftloop;
    }
  else
    {
      int n = INTVAL (operands[2]);

      /* If the count is negative, make it 0.  */
      if (n < 0)
	n = 0;
      /* If the count is too big, truncate it.
         ANSI says shifts of GET_MODE_BITSIZE are undefined - we choose to
	 do the intuitive thing.  */
      else if (n > GET_MODE_BITSIZE (mode))
	n = GET_MODE_BITSIZE (mode);

      /* First see if we can do them inline.  */
      if (n <= 8)
	{
	  while (--n >= 0)
	    output_asm_insn (shift_one, operands);
	}
      /* See if we can use a rotate/and.  */
      else if (n == BITS_PER_WORD - 1)
	{
	  switch (code)
	    {
	    case ASHIFT :
	      output_asm_insn ("and %0,%0,1\n\tror %0,%0", operands);
	      break;
	    case ASHIFTRT :
	      /* The ARC doesn't have a rol insn.  Use something else.  */
	      output_asm_insn ("asl.f 0,%0\n\tsbc %0,0,0", operands);
	      break;
	    case LSHIFTRT :
	      /* The ARC doesn't have a rol insn.  Use something else.  */
	      output_asm_insn ("asl.f 0,%0\n\tadc %0,0,0", operands);
	      break;
	    default:
	      break;
	    }
	}
      /* Must loop.  */
      else
	{
	  char buf[100];

	  if (optimize)
	    output_asm_insn ("mov lp_count,%c2", operands);
	  else
	    output_asm_insn ("mov %4,%c2", operands);
	shiftloop:
	  if (optimize)
	    {
	      if (flag_pic)
		sprintf (buf, "lr %%4,[status]\n\tadd %%4,%%4,6\t%s single insn loop start",
			 ASM_COMMENT_START);
	      else
		sprintf (buf, "mov %%4,%%%%st(1f)\t%s (single insn loop start) >> 2",
			 ASM_COMMENT_START);
	      output_asm_insn (buf, operands);
	      output_asm_insn ("sr %4,[lp_start]", operands);
	      output_asm_insn ("add %4,%4,1", operands);
	      output_asm_insn ("sr %4,[lp_end]", operands);
	      output_asm_insn ("nop\n\tnop", operands);
	      if (flag_pic)
		fprintf (asm_out_file, "\t%s single insn loop\n",
			 ASM_COMMENT_START);
	      else
		fprintf (asm_out_file, "1:\t%s single insn loop\n",
			 ASM_COMMENT_START);
	      output_asm_insn (shift_one, operands);
	      fprintf (asm_out_file, "2:\t%s end single insn loop\n",
		       ASM_COMMENT_START);
	    }
	  else 
	    {
	      fprintf (asm_out_file, "1:\t%s begin shift loop\n",
		       ASM_COMMENT_START);
	      output_asm_insn ("sub.f %4,%4,1", operands);
	      output_asm_insn ("nop", operands);
	      output_asm_insn ("bn.nd 2f", operands);
	      output_asm_insn (shift_one, operands);
	      output_asm_insn ("b.nd 1b", operands);
	      fprintf (asm_out_file, "2:\t%s end shift loop\n",
		       ASM_COMMENT_START);
	    }
	}
    }

  return "";
}

/* Nested function support.  */

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

void
arc_initialize_trampoline (rtx tramp ATTRIBUTE_UNUSED,
                           rtx fnaddr ATTRIBUTE_UNUSED,
                           rtx cxt ATTRIBUTE_UNUSED)
{
}

/* Set the cpu type and print out other fancy things,
   at the top of the file.  */

static void
arc_file_start (void)
{
  default_file_start ();
  fprintf (asm_out_file, "\t.cpu %s\n", arc_cpu_string);
}

/* Print operand X (an rtx) in assembler syntax to file FILE.
   CODE is a letter or dot (`z' in `%z0') or 0 if no letter was specified.
   For `%' followed by punctuation, CODE is the punctuation and X is null.  */

void
arc_print_operand (FILE *file, rtx x, int code)
{
  switch (code)
    {
    case '#' :
      /* Conditional branches.  For now these are equivalent.  */
    case '*' :
      /* Unconditional branches.  Output the appropriate delay slot suffix.  */
      if (!final_sequence || XVECLEN (final_sequence, 0) == 1)
	{
	  /* There's nothing in the delay slot.  */
	  fputs (".nd", file);
	}
      else
	{
	  rtx jump = XVECEXP (final_sequence, 0, 0);
	  rtx delay = XVECEXP (final_sequence, 0, 1);
	  if (INSN_ANNULLED_BRANCH_P (jump))
	    fputs (INSN_FROM_TARGET_P (delay) ? ".jd" : ".nd", file);
	  else
	    fputs (".d", file);
	}
      return;
    case '?' : /* with leading "." */
    case '!' : /* without leading "." */
      /* This insn can be conditionally executed.  See if the ccfsm machinery
	 says it should be conditionalized.  */
      if (arc_ccfsm_state == 3 || arc_ccfsm_state == 4)
	{
	  /* Is this insn in a delay slot?  */
	  if (final_sequence && XVECLEN (final_sequence, 0) == 2)
	    {
	      rtx insn = XVECEXP (final_sequence, 0, 1);

	      /* If the insn is annulled and is from the target path, we need
		 to inverse the condition test.  */
	      if (INSN_ANNULLED_BRANCH_P (insn))
		{
		  if (INSN_FROM_TARGET_P (insn))
		    fprintf (file, "%s%s",
			     code == '?' ? "." : "",
			     arc_condition_codes[ARC_INVERSE_CONDITION_CODE (arc_ccfsm_current_cc)]);
		  else
		    fprintf (file, "%s%s",
			     code == '?' ? "." : "",
			     arc_condition_codes[arc_ccfsm_current_cc]);
		}
	      else
	        {
		  /* This insn is executed for either path, so don't
		     conditionalize it at all.  */
		  ; /* nothing to do */
		}
	    }
	  else
	    {
	      /* This insn isn't in a delay slot.  */
	      fprintf (file, "%s%s",
		       code == '?' ? "." : "",
		       arc_condition_codes[arc_ccfsm_current_cc]);
	    }
	}
      return;
    case '~' :
      /* Output a nop if we're between a set of the condition codes,
	 and a conditional branch.  */
      if (last_insn_set_cc_p)
	fputs ("nop\n\t", file);
      return;
    case 'd' :
      fputs (arc_condition_codes[get_arc_condition_code (x)], file);
      return;
    case 'D' :
      fputs (arc_condition_codes[ARC_INVERSE_CONDITION_CODE
				 (get_arc_condition_code (x))],
	     file);
      return;
    case 'R' :
      /* Write second word of DImode or DFmode reference,
	 register or memory.  */
      if (GET_CODE (x) == REG)
	fputs (reg_names[REGNO (x)+1], file);
      else if (GET_CODE (x) == MEM)
	{
	  fputc ('[', file);
	  /* Handle possible auto-increment.  Since it is pre-increment and
	     we have already done it, we can just use an offset of four.  */
	  /* ??? This is taken from rs6000.c I think.  I don't think it is
	     currently necessary, but keep it around.  */
	  if (GET_CODE (XEXP (x, 0)) == PRE_INC
	      || GET_CODE (XEXP (x, 0)) == PRE_DEC)
	    output_address (plus_constant (XEXP (XEXP (x, 0), 0), 4));
	  else
	    output_address (plus_constant (XEXP (x, 0), 4));
	  fputc (']', file);
	}
      else
	output_operand_lossage ("invalid operand to %%R code");
      return;
    case 'S' :
      if ((GET_CODE (x) == SYMBOL_REF && SYMBOL_REF_FUNCTION_P (x))
	  || GET_CODE (x) == LABEL_REF)
	{
	  fprintf (file, "%%st(");
	  output_addr_const (file, x);
	  fprintf (file, ")");
	  return;
	}
      break;
    case 'H' :
    case 'L' :
      if (GET_CODE (x) == REG)
	{
	  /* L = least significant word, H = most significant word */
	  if ((TARGET_BIG_ENDIAN != 0) ^ (code == 'L'))
	    fputs (reg_names[REGNO (x)], file);
	  else
	    fputs (reg_names[REGNO (x)+1], file);
	}
      else if (GET_CODE (x) == CONST_INT
	       || GET_CODE (x) == CONST_DOUBLE)
	{
	  rtx first, second;

	  split_double (x, &first, &second);
	  fprintf (file, "0x%08lx",
		   (long)(code == 'L' ? INTVAL (first) : INTVAL (second)));
	}
      else
	output_operand_lossage ("invalid operand to %%H/%%L code");
      return;
    case 'A' :
      {
	char str[30];

	gcc_assert (GET_CODE (x) == CONST_DOUBLE
		    && GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT);

	real_to_decimal (str, CONST_DOUBLE_REAL_VALUE (x), sizeof (str), 0, 1);
	fprintf (file, "%s", str);
	return;
      }
    case 'U' :
      /* Output a load/store with update indicator if appropriate.  */
      if (GET_CODE (x) == MEM)
	{
	  if (GET_CODE (XEXP (x, 0)) == PRE_INC
	      || GET_CODE (XEXP (x, 0)) == PRE_DEC)
	    fputs (".a", file);
	}
      else
	output_operand_lossage ("invalid operand to %%U code");
      return;
    case 'V' :
      /* Output cache bypass indicator for a load/store insn.  Volatile memory
	 refs are defined to use the cache bypass mechanism.  */
      if (GET_CODE (x) == MEM)
	{
	  if (MEM_VOLATILE_P (x))
	    fputs (".di", file);
	}
      else
	output_operand_lossage ("invalid operand to %%V code");
      return;
    case 0 :
      /* Do nothing special.  */
      break;
    default :
      /* Unknown flag.  */
      output_operand_lossage ("invalid operand output code");
    }

  switch (GET_CODE (x))
    {
    case REG :
      fputs (reg_names[REGNO (x)], file);
      break;
    case MEM :
      fputc ('[', file);
      if (GET_CODE (XEXP (x, 0)) == PRE_INC)
	output_address (plus_constant (XEXP (XEXP (x, 0), 0),
				       GET_MODE_SIZE (GET_MODE (x))));
      else if (GET_CODE (XEXP (x, 0)) == PRE_DEC)
	output_address (plus_constant (XEXP (XEXP (x, 0), 0),
				       - GET_MODE_SIZE (GET_MODE (x))));
      else
	output_address (XEXP (x, 0));
      fputc (']', file);
      break;
    case CONST_DOUBLE :
      /* We handle SFmode constants here as output_addr_const doesn't.  */
      if (GET_MODE (x) == SFmode)
	{
	  REAL_VALUE_TYPE d;
	  long l;

	  REAL_VALUE_FROM_CONST_DOUBLE (d, x);
	  REAL_VALUE_TO_TARGET_SINGLE (d, l);
	  fprintf (file, "0x%08lx", l);
	  break;
	}
      /* Fall through.  Let output_addr_const deal with it.  */
    default :
      output_addr_const (file, x);
      break;
    }
}

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

void
arc_print_operand_address (FILE *file, rtx addr)
{
  register rtx base, index = 0;
  int offset = 0;

  switch (GET_CODE (addr))
    {
    case REG :
      fputs (reg_names[REGNO (addr)], file);
      break;
    case SYMBOL_REF :
      if (/*???*/ 0 && SYMBOL_REF_FUNCTION_P (addr))
	{
	  fprintf (file, "%%st(");
	  output_addr_const (file, addr);
	  fprintf (file, ")");
	}
      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)
	{
	  if (offset != 0)
	    fprintf (file, ",%d", offset);
	}
      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 :
      /* We shouldn't get here as we've lost the mode of the memory object
	 (which says how much to inc/dec by.  */
      gcc_unreachable ();
      break;
    default :
      output_addr_const (file, addr);
      break;
    }
}

/* Update compare/branch separation marker.  */

static void
record_cc_ref (rtx insn)
{
  last_insn_set_cc_p = current_insn_set_cc_p;

  switch (get_attr_cond (insn))
    {
    case COND_SET :
    case COND_SET_ZN :
    case COND_SET_ZNC :
      if (get_attr_length (insn) == 1)
	current_insn_set_cc_p = 1;
      else
	current_insn_set_cc_p = 0;
      break;
    default :
      current_insn_set_cc_p = 0;
      break;
    }
}

/* Conditional execution support.

   This is based on the ARM port but for now is much simpler.

   A finite state machine takes care of noticing whether or not instructions
   can be conditionally executed, and thus decrease execution time and code
   size by deleting branch instructions.  The fsm is controlled by
   final_prescan_insn, and controls the actions of PRINT_OPERAND.  The patterns
   in the .md file for the branch insns also have a hand in this.  */

/* The state of the fsm controlling condition codes are:
   0: normal, do nothing special
   1: don't output this insn
   2: don't output this insn
   3: make insns conditional
   4: make insns conditional

   State transitions (state->state by whom, under what condition):
   0 -> 1 final_prescan_insn, if insn is conditional branch
   0 -> 2 final_prescan_insn, if the `target' is an unconditional branch
   1 -> 3 branch patterns, after having not output the conditional branch
   2 -> 4 branch patterns, after having not output the conditional branch
   3 -> 0 (*targetm.asm_out.internal_label), if the `target' label is reached
          (the target label has CODE_LABEL_NUMBER equal to
	  arc_ccfsm_target_label).
   4 -> 0 final_prescan_insn, if `target' unconditional branch is reached

   If the jump clobbers the conditions then we use states 2 and 4.

   A similar thing can be done with conditional return insns.

   We also handle separating branches from sets of the condition code.
   This is done here because knowledge of the ccfsm state is required,
   we may not be outputting the branch.  */

void
arc_final_prescan_insn (rtx insn,
                        rtx *opvec ATTRIBUTE_UNUSED,
                        int noperands ATTRIBUTE_UNUSED)
{
  /* BODY will hold the body of INSN.  */
  register rtx body = PATTERN (insn);

  /* This will be 1 if trying to repeat the trick (i.e.: do the `else' part of
     an if/then/else), and things need to be reversed.  */
  int reverse = 0;

  /* If we start with a return insn, we only succeed if we find another one.  */
  int seeking_return = 0;
  
  /* START_INSN will hold the insn from where we start looking.  This is the
     first insn after the following code_label if REVERSE is true.  */
  rtx start_insn = insn;

  /* Update compare/branch separation marker.  */
  record_cc_ref (insn);

  /* Allow -mdebug-ccfsm to turn this off so we can see how well it does.
     We can't do this in macro FINAL_PRESCAN_INSN because its called from
     final_scan_insn which has `optimize' as a local.  */
  if (optimize < 2 || TARGET_NO_COND_EXEC)
    return;

  /* If in state 4, check if the target branch is reached, in order to
     change back to state 0.  */
  if (arc_ccfsm_state == 4)
    {
      if (insn == arc_ccfsm_target_insn)
	{
	  arc_ccfsm_target_insn = NULL;
	  arc_ccfsm_state = 0;
	}
      return;
    }

  /* If in state 3, it is possible to repeat the trick, if this insn is an
     unconditional branch to a label, and immediately following this branch
     is the previous target label which is only used once, and the label this
     branch jumps to is not too far off.  Or in other words "we've done the
     `then' part, see if we can do the `else' part."  */
  if (arc_ccfsm_state == 3)
    {
      if (simplejump_p (insn))
	{
	  start_insn = next_nonnote_insn (start_insn);
	  if (GET_CODE (start_insn) == BARRIER)
	    {
	      /* ??? Isn't this always a barrier?  */
	      start_insn = next_nonnote_insn (start_insn);
	    }
	  if (GET_CODE (start_insn) == CODE_LABEL
	      && CODE_LABEL_NUMBER (start_insn) == arc_ccfsm_target_label
	      && LABEL_NUSES (start_insn) == 1)
	    reverse = TRUE;
	  else
	    return;
	}
      else if (GET_CODE (body) == RETURN)
        {
	  start_insn = next_nonnote_insn (start_insn);
	  if (GET_CODE (start_insn) == BARRIER)
	    start_insn = next_nonnote_insn (start_insn);
	  if (GET_CODE (start_insn) == CODE_LABEL
	      && CODE_LABEL_NUMBER (start_insn) == arc_ccfsm_target_label
	      && LABEL_NUSES (start_insn) == 1)
	    {
	      reverse = TRUE;
	      seeking_return = 1;
	    }
	  else
	    return;
        }
      else
	return;
    }

  if (GET_CODE (insn) != JUMP_INSN)
    return;

  /* This jump might be paralleled with a clobber of the condition codes,
     the jump should always come first.  */
  if (GET_CODE (body) == PARALLEL && XVECLEN (body, 0) > 0)
    body = XVECEXP (body, 0, 0);

  if (reverse
      || (GET_CODE (body) == SET && GET_CODE (SET_DEST (body)) == PC
	  && GET_CODE (SET_SRC (body)) == IF_THEN_ELSE))
    {
      int insns_skipped = 0, fail = FALSE, succeed = FALSE;
      /* Flag which part of the IF_THEN_ELSE is the LABEL_REF.  */
      int then_not_else = TRUE;
      /* Nonzero if next insn must be the target label.  */
      int next_must_be_target_label_p;
      rtx this_insn = start_insn, label = 0;

      /* Register the insn jumped to.  */
      if (reverse)
        {
	  if (!seeking_return)
	    label = XEXP (SET_SRC (body), 0);
        }
      else if (GET_CODE (XEXP (SET_SRC (body), 1)) == LABEL_REF)
	label = XEXP (XEXP (SET_SRC (body), 1), 0);
      else if (GET_CODE (XEXP (SET_SRC (body), 2)) == LABEL_REF)
	{
	  label = XEXP (XEXP (SET_SRC (body), 2), 0);
	  then_not_else = FALSE;
	}
      else if (GET_CODE (XEXP (SET_SRC (body), 1)) == RETURN)
	seeking_return = 1;
      else if (GET_CODE (XEXP (SET_SRC (body), 2)) == RETURN)
        {
	  seeking_return = 1;
	  then_not_else = FALSE;
        }
      else
	gcc_unreachable ();

      /* See how many insns this branch skips, and what kind of insns.  If all
	 insns are okay, and the label or unconditional branch to the same
	 label is not too far away, succeed.  */
      for (insns_skipped = 0, next_must_be_target_label_p = FALSE;
	   !fail && !succeed && insns_skipped < MAX_INSNS_SKIPPED;
	   insns_skipped++)
	{
	  rtx scanbody;

	  this_insn = next_nonnote_insn (this_insn);
	  if (!this_insn)
	    break;

	  if (next_must_be_target_label_p)
	    {
	      if (GET_CODE (this_insn) == BARRIER)
		continue;
	      if (GET_CODE (this_insn) == CODE_LABEL
		  && this_insn == label)
		{
		  arc_ccfsm_state = 1;
		  succeed = TRUE;
		}
	      else
		fail = TRUE;
	      break;
	    }

	  scanbody = PATTERN (this_insn);

	  switch (GET_CODE (this_insn))
	    {
	    case CODE_LABEL:
	      /* Succeed if it is the target label, otherwise fail since
		 control falls in from somewhere else.  */
	      if (this_insn == label)
		{
		  arc_ccfsm_state = 1;
		  succeed = TRUE;
		}
	      else
		fail = TRUE;
	      break;

	    case BARRIER:
	      /* Succeed if the following insn is the target label.
		 Otherwise fail.  
		 If return insns are used then the last insn in a function 
		 will be a barrier.  */
	      next_must_be_target_label_p = TRUE;
	      break;

	    case CALL_INSN:
	      /* Can handle a call insn if there are no insns after it.
		 IE: The next "insn" is the target label.  We don't have to
		 worry about delay slots as such insns are SEQUENCE's inside
		 INSN's.  ??? It is possible to handle such insns though.  */
	      if (get_attr_cond (this_insn) == COND_CANUSE)
		next_must_be_target_label_p = TRUE;
	      else
		fail = TRUE;
	      break;

	    case JUMP_INSN:
      	      /* If this is an unconditional branch to the same label, succeed.
		 If it is to another label, do nothing.  If it is conditional,
		 fail.  */
	      /* ??? Probably, the test for the SET and the PC are unnecessary.  */

	      if (GET_CODE (scanbody) == SET
		  && GET_CODE (SET_DEST (scanbody)) == PC)
		{
		  if (GET_CODE (SET_SRC (scanbody)) == LABEL_REF
		      && XEXP (SET_SRC (scanbody), 0) == label && !reverse)
		    {
		      arc_ccfsm_state = 2;
		      succeed = TRUE;
		    }
		  else if (GET_CODE (SET_SRC (scanbody)) == IF_THEN_ELSE)
		    fail = TRUE;
		}
	      else if (GET_CODE (scanbody) == RETURN
		       && seeking_return)
	        {
		  arc_ccfsm_state = 2;
		  succeed = TRUE;
	        }
	      else if (GET_CODE (scanbody) == PARALLEL)
	        {
		  if (get_attr_cond (this_insn) != COND_CANUSE)
		    fail = TRUE;
		}
	      break;

	    case INSN:
	      /* We can only do this with insns that can use the condition
		 codes (and don't set them).  */
	      if (GET_CODE (scanbody) == SET
		  || GET_CODE (scanbody) == PARALLEL)
		{
		  if (get_attr_cond (this_insn) != COND_CANUSE)
		    fail = TRUE;
		}
	      /* We can't handle other insns like sequences.  */
	      else
		fail = TRUE;
	      break;

	    default:
	      break;
	    }
	}

      if (succeed)
	{
	  if ((!seeking_return) && (arc_ccfsm_state == 1 || reverse))
	    arc_ccfsm_target_label = CODE_LABEL_NUMBER (label);
	  else
	    {
	      gcc_assert (seeking_return || arc_ccfsm_state == 2);
	      while (this_insn && GET_CODE (PATTERN (this_insn)) == USE)
	        {
		  this_insn = next_nonnote_insn (this_insn);
		  gcc_assert (!this_insn
			      || (GET_CODE (this_insn) != BARRIER
				  && GET_CODE (this_insn) != CODE_LABEL));
	        }
	      if (!this_insn)
	        {
		  /* Oh dear! we ran off the end, give up.  */
		  extract_insn_cached (insn);
		  arc_ccfsm_state = 0;
		  arc_ccfsm_target_insn = NULL;
		  return;
	        }
	      arc_ccfsm_target_insn = this_insn;
	    }

	  /* If REVERSE is true, ARM_CURRENT_CC needs to be inverted from
	     what it was.  */
	  if (!reverse)
	    arc_ccfsm_current_cc = get_arc_condition_code (XEXP (SET_SRC (body),
								 0));

	  if (reverse || then_not_else)
	    arc_ccfsm_current_cc = ARC_INVERSE_CONDITION_CODE (arc_ccfsm_current_cc);
	}

      /* Restore recog_data.  Getting the attributes of other insns can
	 destroy this array, but final.c assumes that it remains intact
	 across this call.  */
      extract_insn_cached (insn);
    }
}

/* Record that we are currently outputting label NUM with prefix PREFIX.
   It it's the label we're looking for, reset the ccfsm machinery.

   Called from (*targetm.asm_out.internal_label).  */

void
arc_ccfsm_at_label (const char *prefix, int num)
{
  if (arc_ccfsm_state == 3 && arc_ccfsm_target_label == num
      && !strcmp (prefix, "L"))
    {
      arc_ccfsm_state = 0;
      arc_ccfsm_target_insn = NULL_RTX;
    }
}

/* See if the current insn, which is a conditional branch, is to be
   deleted.  */

int
arc_ccfsm_branch_deleted_p (void)
{
  if (arc_ccfsm_state == 1 || arc_ccfsm_state == 2)
    return 1;
  return 0;
}

/* Record a branch isn't output because subsequent insns can be
   conditionalized.  */

void
arc_ccfsm_record_branch_deleted (void)
{
  /* Indicate we're conditionalizing insns now.  */
  arc_ccfsm_state += 2;

  /* If the next insn is a subroutine call, we still need a nop between the
     cc setter and user.  We need to undo the effect of calling record_cc_ref
     for the just deleted branch.  */
  current_insn_set_cc_p = last_insn_set_cc_p;
}

static void
arc_va_start (tree valist, rtx nextarg)
{
  /* See arc_setup_incoming_varargs for reasons for this oddity.  */
  if (crtl->args.info < 8
      && (crtl->args.info & 1))
    nextarg = plus_constant (nextarg, UNITS_PER_WORD);

  std_expand_builtin_va_start (valist, nextarg);
}

/* This is how to output a definition of an internal numbered label where
   PREFIX is the class of label and NUM is the number within the class.  */

static void
arc_internal_label (FILE *stream, const char *prefix, unsigned long labelno)
{
  arc_ccfsm_at_label (prefix, labelno);
  default_internal_label (stream, prefix, labelno);
}

/* Worker function for TARGET_ASM_EXTERNAL_LIBCALL.  */

static void
arc_external_libcall (rtx fun ATTRIBUTE_UNUSED)
{
#if 0
/* On the ARC we want to have libgcc's for multiple cpus in one binary.
   We can't use `assemble_name' here as that will call ASM_OUTPUT_LABELREF
   and we'll get another suffix added on if -mmangle-cpu.  */
  if (TARGET_MANGLE_CPU_LIBGCC)
    {
      fprintf (FILE, "\t.rename\t_%s, _%s%s\n",
	       XSTR (SYMREF, 0), XSTR (SYMREF, 0),
	       arc_mangle_suffix);
    }
#endif
}

/* Worker function for TARGET_RETURN_IN_MEMORY.  */

static bool
arc_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
{
  if (AGGREGATE_TYPE_P (type))
    return true;
  else
    {
      HOST_WIDE_INT size = int_size_in_bytes (type);
      return (size == -1 || size > 8);
    }
}

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

static bool
arc_pass_by_reference (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED,
		       enum machine_mode mode, const_tree type,
		       bool named ATTRIBUTE_UNUSED)
{
  unsigned HOST_WIDE_INT size;

  if (type)
    {
      if (AGGREGATE_TYPE_P (type))
	return true;
      size = int_size_in_bytes (type);
    }
  else
    size = GET_MODE_SIZE (mode);

  return size > 8;
}
