/* Subroutines used for code generation for RISC-V.
   Copyright (C) 2011-2022 Free Software Foundation, Inc.
   Contributed by Andrew Waterman (andrew@sifive.com).
   Based on MIPS target for GNU compiler.

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

#define INCLUDE_STRING
#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "target.h"
#include "backend.h"
#include "tm.h"
#include "rtl.h"
#include "regs.h"
#include "insn-config.h"
#include "insn-attr.h"
#include "recog.h"
#include "output.h"
#include "alias.h"
#include "tree.h"
#include "stringpool.h"
#include "attribs.h"
#include "varasm.h"
#include "stor-layout.h"
#include "calls.h"
#include "function.h"
#include "explow.h"
#include "memmodel.h"
#include "emit-rtl.h"
#include "reload.h"
#include "tm_p.h"
#include "basic-block.h"
#include "expr.h"
#include "optabs.h"
#include "bitmap.h"
#include "df.h"
#include "function-abi.h"
#include "diagnostic.h"
#include "builtins.h"
#include "predict.h"
#include "tree-pass.h"
#include "opts.h"
#include "tm-constrs.h"
#include "rtl-iter.h"

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

/* True if X is an UNSPEC wrapper around a SYMBOL_REF or LABEL_REF.  */
#define UNSPEC_ADDRESS_P(X)					\
  (GET_CODE (X) == UNSPEC					\
   && XINT (X, 1) >= UNSPEC_ADDRESS_FIRST			\
   && XINT (X, 1) < UNSPEC_ADDRESS_FIRST + NUM_SYMBOL_TYPES)

/* Extract the symbol or label from UNSPEC wrapper X.  */
#define UNSPEC_ADDRESS(X) \
  XVECEXP (X, 0, 0)

/* Extract the symbol type from UNSPEC wrapper X.  */
#define UNSPEC_ADDRESS_TYPE(X) \
  ((enum riscv_symbol_type) (XINT (X, 1) - UNSPEC_ADDRESS_FIRST))

/* True if bit BIT is set in VALUE.  */
#define BITSET_P(VALUE, BIT) (((VALUE) & (1ULL << (BIT))) != 0)

/* Classifies an address.

   ADDRESS_REG
       A natural register + offset address.  The register satisfies
       riscv_valid_base_register_p and the offset is a const_arith_operand.

   ADDRESS_LO_SUM
       A LO_SUM rtx.  The first operand is a valid base register and
       the second operand is a symbolic address.

   ADDRESS_CONST_INT
       A signed 16-bit constant address.

   ADDRESS_SYMBOLIC:
       A constant symbolic address.  */
enum riscv_address_type {
  ADDRESS_REG,
  ADDRESS_LO_SUM,
  ADDRESS_CONST_INT,
  ADDRESS_SYMBOLIC
};

/* Information about a function's frame layout.  */
struct GTY(())  riscv_frame_info {
  /* The size of the frame in bytes.  */
  poly_int64 total_size;

  /* Bit X is set if the function saves or restores GPR X.  */
  unsigned int mask;

  /* Likewise FPR X.  */
  unsigned int fmask;

  /* How much the GPR save/restore routines adjust sp (or 0 if unused).  */
  unsigned save_libcall_adjustment;

  /* Offsets of fixed-point and floating-point save areas from frame bottom */
  poly_int64 gp_sp_offset;
  poly_int64 fp_sp_offset;

  /* Offset of virtual frame pointer from stack pointer/frame bottom */
  poly_int64 frame_pointer_offset;

  /* Offset of hard frame pointer from stack pointer/frame bottom */
  poly_int64 hard_frame_pointer_offset;

  /* The offset of arg_pointer_rtx from the bottom of the frame.  */
  poly_int64 arg_pointer_offset;

  /* Reset this struct, clean all field to zero.  */
  void reset(void);
};

enum riscv_privilege_levels {
  UNKNOWN_MODE, USER_MODE, SUPERVISOR_MODE, MACHINE_MODE
};

struct GTY(())  machine_function {
  /* The number of extra stack bytes taken up by register varargs.
     This area is allocated by the callee at the very top of the frame.  */
  int varargs_size;

  /* True if current function is a naked function.  */
  bool naked_p;

  /* True if current function is an interrupt function.  */
  bool interrupt_handler_p;
  /* For an interrupt handler, indicates the privilege level.  */
  enum riscv_privilege_levels interrupt_mode;

  /* True if attributes on current function have been checked.  */
  bool attributes_checked_p;

  /* The current frame information, calculated by riscv_compute_frame_info.  */
  struct riscv_frame_info frame;

  /* The components already handled by separate shrink-wrapping, which should
     not be considered by the prologue and epilogue.  */
  bool reg_is_wrapped_separately[FIRST_PSEUDO_REGISTER];

};

/* Information about a single argument.  */
struct riscv_arg_info {
  /* True if the argument is at least partially passed on the stack.  */
  bool stack_p;

  /* The number of integer registers allocated to this argument.  */
  unsigned int num_gprs;

  /* The offset of the first register used, provided num_gprs is nonzero.
     If passed entirely on the stack, the value is MAX_ARGS_IN_REGISTERS.  */
  unsigned int gpr_offset;

  /* The number of floating-point registers allocated to this argument.  */
  unsigned int num_fprs;

  /* The offset of the first register used, provided num_fprs is nonzero.  */
  unsigned int fpr_offset;
};

/* Information about an address described by riscv_address_type.

   ADDRESS_CONST_INT
       No fields are used.

   ADDRESS_REG
       REG is the base register and OFFSET is the constant offset.

   ADDRESS_LO_SUM
       REG and OFFSET are the operands to the LO_SUM and SYMBOL_TYPE
       is the type of symbol it references.

   ADDRESS_SYMBOLIC
       SYMBOL_TYPE is the type of symbol that the address references.  */
struct riscv_address_info {
  enum riscv_address_type type;
  rtx reg;
  rtx offset;
  enum riscv_symbol_type symbol_type;
};

/* One stage in a constant building sequence.  These sequences have
   the form:

	A = VALUE[0]
	A = A CODE[1] VALUE[1]
	A = A CODE[2] VALUE[2]
	...

   where A is an accumulator, each CODE[i] is a binary rtl operation
   and each VALUE[i] is a constant integer.  CODE[0] is undefined.  */
struct riscv_integer_op {
  enum rtx_code code;
  unsigned HOST_WIDE_INT value;
};

/* The largest number of operations needed to load an integer constant.
   The worst case is LUI, ADDI, SLLI, ADDI, SLLI, ADDI, SLLI, ADDI.  */
#define RISCV_MAX_INTEGER_OPS 8

/* Costs of various operations on the different architectures.  */

struct riscv_tune_param
{
  unsigned short fp_add[2];
  unsigned short fp_mul[2];
  unsigned short fp_div[2];
  unsigned short int_mul[2];
  unsigned short int_div[2];
  unsigned short issue_rate;
  unsigned short branch_cost;
  unsigned short memory_cost;
  unsigned short fmv_cost;
  bool slow_unaligned_access;
};

/* Information about one micro-arch we know about.  */
struct riscv_tune_info {
  /* This micro-arch canonical name.  */
  const char *name;

  /* Which automaton to use for tuning.  */
  enum riscv_microarchitecture_type microarchitecture;

  /* Tuning parameters for this micro-arch.  */
  const struct riscv_tune_param *tune_param;
};

/* Global variables for machine-dependent things.  */

/* Whether unaligned accesses execute very slowly.  */
bool riscv_slow_unaligned_access_p;

/* Stack alignment to assume/maintain.  */
unsigned riscv_stack_boundary;

/* If non-zero, this is an offset to be added to SP to redefine the CFA
   when restoring the FP register from the stack.  Only valid when generating
   the epilogue.  */
static int epilogue_cfa_sp_offset;

/* Which tuning parameters to use.  */
static const struct riscv_tune_param *tune_param;

/* Which automaton to use for tuning.  */
enum riscv_microarchitecture_type riscv_microarchitecture;

/* The number of chunks in a single vector register.  */
poly_uint16 riscv_vector_chunks;

/* The number of bytes in a vector chunk.  */
unsigned riscv_bytes_per_vector_chunk;

/* Index R is the smallest register class that contains register R.  */
const enum reg_class riscv_regno_to_class[FIRST_PSEUDO_REGISTER] = {
  GR_REGS,	GR_REGS,	GR_REGS,	GR_REGS,
  GR_REGS,	GR_REGS,	SIBCALL_REGS,	SIBCALL_REGS,
  JALR_REGS,	JALR_REGS,	SIBCALL_REGS,	SIBCALL_REGS,
  SIBCALL_REGS,	SIBCALL_REGS,	SIBCALL_REGS,	SIBCALL_REGS,
  SIBCALL_REGS,	SIBCALL_REGS,	JALR_REGS,	JALR_REGS,
  JALR_REGS,	JALR_REGS,	JALR_REGS,	JALR_REGS,
  JALR_REGS,	JALR_REGS,	JALR_REGS,	JALR_REGS,
  SIBCALL_REGS,	SIBCALL_REGS,	SIBCALL_REGS,	SIBCALL_REGS,
  FP_REGS,	FP_REGS,	FP_REGS,	FP_REGS,
  FP_REGS,	FP_REGS,	FP_REGS,	FP_REGS,
  FP_REGS,	FP_REGS,	FP_REGS,	FP_REGS,
  FP_REGS,	FP_REGS,	FP_REGS,	FP_REGS,
  FP_REGS,	FP_REGS,	FP_REGS,	FP_REGS,
  FP_REGS,	FP_REGS,	FP_REGS,	FP_REGS,
  FP_REGS,	FP_REGS,	FP_REGS,	FP_REGS,
  FP_REGS,	FP_REGS,	FP_REGS,	FP_REGS,
  FRAME_REGS,	FRAME_REGS,	VL_REGS,	VTYPE_REGS,
  NO_REGS,	NO_REGS,	NO_REGS,	NO_REGS,
  NO_REGS,	NO_REGS,	NO_REGS,	NO_REGS,
  NO_REGS,	NO_REGS,	NO_REGS,	NO_REGS,
  NO_REGS,	NO_REGS,	NO_REGS,	NO_REGS,
  NO_REGS,	NO_REGS,	NO_REGS,	NO_REGS,
  NO_REGS,	NO_REGS,	NO_REGS,	NO_REGS,
  NO_REGS,	NO_REGS,	NO_REGS,	NO_REGS,
  VM_REGS,	VD_REGS,	VD_REGS,	VD_REGS,
  VD_REGS,	VD_REGS,	VD_REGS,	VD_REGS,
  VD_REGS,	VD_REGS,	VD_REGS,	VD_REGS,
  VD_REGS,	VD_REGS,	VD_REGS,	VD_REGS,
  VD_REGS,	VD_REGS,	VD_REGS,	VD_REGS,
  VD_REGS,	VD_REGS,	VD_REGS,	VD_REGS,
  VD_REGS,	VD_REGS,	VD_REGS,	VD_REGS,
  VD_REGS,	VD_REGS,	VD_REGS,	VD_REGS,
};

/* Costs to use when optimizing for rocket.  */
static const struct riscv_tune_param rocket_tune_info = {
  {COSTS_N_INSNS (4), COSTS_N_INSNS (5)},	/* fp_add */
  {COSTS_N_INSNS (4), COSTS_N_INSNS (5)},	/* fp_mul */
  {COSTS_N_INSNS (20), COSTS_N_INSNS (20)},	/* fp_div */
  {COSTS_N_INSNS (4), COSTS_N_INSNS (4)},	/* int_mul */
  {COSTS_N_INSNS (6), COSTS_N_INSNS (6)},	/* int_div */
  1,						/* issue_rate */
  3,						/* branch_cost */
  5,						/* memory_cost */
  8,						/* fmv_cost */
  true,						/* slow_unaligned_access */
};

/* Costs to use when optimizing for Sifive 7 Series.  */
static const struct riscv_tune_param sifive_7_tune_info = {
  {COSTS_N_INSNS (4), COSTS_N_INSNS (5)},	/* fp_add */
  {COSTS_N_INSNS (4), COSTS_N_INSNS (5)},	/* fp_mul */
  {COSTS_N_INSNS (20), COSTS_N_INSNS (20)},	/* fp_div */
  {COSTS_N_INSNS (4), COSTS_N_INSNS (4)},	/* int_mul */
  {COSTS_N_INSNS (6), COSTS_N_INSNS (6)},	/* int_div */
  2,						/* issue_rate */
  4,						/* branch_cost */
  3,						/* memory_cost */
  8,						/* fmv_cost */
  true,						/* slow_unaligned_access */
};

/* Costs to use when optimizing for T-HEAD c906.  */
static const struct riscv_tune_param thead_c906_tune_info = {
  {COSTS_N_INSNS (4), COSTS_N_INSNS (5)}, /* fp_add */
  {COSTS_N_INSNS (4), COSTS_N_INSNS (5)}, /* fp_mul */
  {COSTS_N_INSNS (20), COSTS_N_INSNS (20)}, /* fp_div */
  {COSTS_N_INSNS (4), COSTS_N_INSNS (4)}, /* int_mul */
  {COSTS_N_INSNS (6), COSTS_N_INSNS (6)}, /* int_div */
  1,            /* issue_rate */
  3,            /* branch_cost */
  5,            /* memory_cost */
  8,		/* fmv_cost */
  false,            /* slow_unaligned_access */
};

/* Costs to use when optimizing for size.  */
static const struct riscv_tune_param optimize_size_tune_info = {
  {COSTS_N_INSNS (1), COSTS_N_INSNS (1)},	/* fp_add */
  {COSTS_N_INSNS (1), COSTS_N_INSNS (1)},	/* fp_mul */
  {COSTS_N_INSNS (1), COSTS_N_INSNS (1)},	/* fp_div */
  {COSTS_N_INSNS (1), COSTS_N_INSNS (1)},	/* int_mul */
  {COSTS_N_INSNS (1), COSTS_N_INSNS (1)},	/* int_div */
  1,						/* issue_rate */
  1,						/* branch_cost */
  2,						/* memory_cost */
  8,						/* fmv_cost */
  false,					/* slow_unaligned_access */
};

static tree riscv_handle_fndecl_attribute (tree *, tree, tree, int, bool *);
static tree riscv_handle_type_attribute (tree *, tree, tree, int, bool *);

/* Defining target-specific uses of __attribute__.  */
static const struct attribute_spec riscv_attribute_table[] =
{
  /* Syntax: { name, min_len, max_len, decl_required, type_required,
	       function_type_required, affects_type_identity, handler,
	       exclude } */

  /* The attribute telling no prologue/epilogue.  */
  { "naked",	0,  0, true, false, false, false,
    riscv_handle_fndecl_attribute, NULL },
  /* This attribute generates prologue/epilogue for interrupt handlers.  */
  { "interrupt", 0, 1, false, true, true, false,
    riscv_handle_type_attribute, NULL },

  /* The following two are used for the built-in properties of the Vector type
     and are not used externally */
  {"RVV sizeless type", 4, 4, false, true, false, true, NULL, NULL},
  {"RVV type", 0, 0, false, true, false, true, NULL, NULL},

  /* The last attribute spec is set to be NULL.  */
  { NULL,	0,  0, false, false, false, false, NULL, NULL }
};

/* Order for the CLOBBERs/USEs of gpr_save.  */
static const unsigned gpr_save_reg_order[] = {
  INVALID_REGNUM, T0_REGNUM, T1_REGNUM, RETURN_ADDR_REGNUM,
  S0_REGNUM, S1_REGNUM, S2_REGNUM, S3_REGNUM, S4_REGNUM,
  S5_REGNUM, S6_REGNUM, S7_REGNUM, S8_REGNUM, S9_REGNUM,
  S10_REGNUM, S11_REGNUM
};

/* A table describing all the processors GCC knows about.  */
static const struct riscv_tune_info riscv_tune_info_table[] = {
#define RISCV_TUNE(TUNE_NAME, PIPELINE_MODEL, TUNE_INFO)	\
  { TUNE_NAME, PIPELINE_MODEL, & TUNE_INFO},
#include "riscv-cores.def"
};

void riscv_frame_info::reset(void)
{
  total_size = 0;
  mask = 0;
  fmask = 0;
  save_libcall_adjustment = 0;

  gp_sp_offset = 0;
  fp_sp_offset = 0;

  frame_pointer_offset = 0;

  hard_frame_pointer_offset = 0;

  arg_pointer_offset = 0;
}

/* Implement TARGET_MIN_ARITHMETIC_PRECISION.  */

static unsigned int
riscv_min_arithmetic_precision (void)
{
  return 32;
}

/* Return the riscv_tune_info entry for the given name string.  */

static const struct riscv_tune_info *
riscv_parse_tune (const char *tune_string)
{
  const riscv_cpu_info *cpu = riscv_find_cpu (tune_string);

  if (cpu)
    tune_string = cpu->tune;

  for (unsigned i = 0; i < ARRAY_SIZE (riscv_tune_info_table); i++)
    if (strcmp (riscv_tune_info_table[i].name, tune_string) == 0)
      return riscv_tune_info_table + i;

  error ("unknown cpu %qs for %<-mtune%>", tune_string);
  return riscv_tune_info_table;
}

/* Helper function for riscv_build_integer; arguments are as for
   riscv_build_integer.  */

static int
riscv_build_integer_1 (struct riscv_integer_op codes[RISCV_MAX_INTEGER_OPS],
		       HOST_WIDE_INT value, machine_mode mode)
{
  HOST_WIDE_INT low_part = CONST_LOW_PART (value);
  int cost = RISCV_MAX_INTEGER_OPS + 1, alt_cost;
  struct riscv_integer_op alt_codes[RISCV_MAX_INTEGER_OPS];

  if (SMALL_OPERAND (value) || LUI_OPERAND (value))
    {
      /* Simply ADDI or LUI.  */
      codes[0].code = UNKNOWN;
      codes[0].value = value;
      return 1;
    }
  if (TARGET_ZBS && SINGLE_BIT_MASK_OPERAND (value))
    {
      /* Simply BSETI.  */
      codes[0].code = UNKNOWN;
      codes[0].value = value;

      /* RISC-V sign-extends all 32bit values that live in a 32bit
	 register.  To avoid paradoxes, we thus need to use the
	 sign-extended (negative) representation (-1 << 31) for the
	 value, if we want to build (1 << 31) in SImode.  This will
	 then expand to an LUI instruction.  */
      if (TARGET_64BIT && mode == SImode && value == (HOST_WIDE_INT_1U << 31))
	codes[0].value = (HOST_WIDE_INT_M1U << 31);

      return 1;
    }

  /* End with ADDI.  When constructing HImode constants, do not generate any
     intermediate value that is not itself a valid HImode constant.  The
     XORI case below will handle those remaining HImode constants.  */
  if (low_part != 0
      && (mode != HImode
	  || value - low_part <= ((1 << (GET_MODE_BITSIZE (HImode) - 1)) - 1)))
    {
      HOST_WIDE_INT upper_part = value - low_part;
      if (mode != VOIDmode)
	upper_part = trunc_int_for_mode (value - low_part, mode);

      alt_cost = 1 + riscv_build_integer_1 (alt_codes, upper_part, mode);
      if (alt_cost < cost)
	{
	  alt_codes[alt_cost-1].code = PLUS;
	  alt_codes[alt_cost-1].value = low_part;
	  memcpy (codes, alt_codes, sizeof (alt_codes));
	  cost = alt_cost;
	}
    }

  /* End with XORI.  */
  if (cost > 2 && (low_part < 0 || mode == HImode))
    {
      alt_cost = 1 + riscv_build_integer_1 (alt_codes, value ^ low_part, mode);
      if (alt_cost < cost)
	{
	  alt_codes[alt_cost-1].code = XOR;
	  alt_codes[alt_cost-1].value = low_part;
	  memcpy (codes, alt_codes, sizeof (alt_codes));
	  cost = alt_cost;
	}
    }

  /* Eliminate trailing zeros and end with SLLI.  */
  if (cost > 2 && (value & 1) == 0)
    {
      int shift = ctz_hwi (value);
      unsigned HOST_WIDE_INT x = value;
      x = sext_hwi (x >> shift, HOST_BITS_PER_WIDE_INT - shift);

      /* Don't eliminate the lower 12 bits if LUI might apply.  */
      if (shift > IMM_BITS && !SMALL_OPERAND (x) && LUI_OPERAND (x << IMM_BITS))
	shift -= IMM_BITS, x <<= IMM_BITS;

      alt_cost = 1 + riscv_build_integer_1 (alt_codes, x, mode);
      if (alt_cost < cost)
	{
	  alt_codes[alt_cost-1].code = ASHIFT;
	  alt_codes[alt_cost-1].value = shift;
	  memcpy (codes, alt_codes, sizeof (alt_codes));
	  cost = alt_cost;
	}
    }

  if (cost > 2 && TARGET_64BIT && TARGET_ZBB)
    {
      int leading_ones = clz_hwi (~value);
      int trailing_ones = ctz_hwi (~value);

      /* If all bits are one except a few that are zero, and the zero bits
	 are within a range of 11 bits, and at least one of the upper 32-bits
	 is a zero, then we can generate a constant by loading a small
	 negative constant and rotating.  */
      if (leading_ones < 32
	  && ((64 - leading_ones - trailing_ones) < 12))
	{
	  codes[0].code = UNKNOWN;
	  /* The sign-bit might be zero, so just rotate to be safe.  */
	  codes[0].value = (((unsigned HOST_WIDE_INT) value >> trailing_ones)
			    | (value << (64 - trailing_ones)));
	  codes[1].code = ROTATERT;
	  codes[1].value = 64 - trailing_ones;
	  cost = 2;
	}
      /* Handle the case where the 11 bit range of zero bits wraps around.  */
      else
	{
	  int upper_trailing_ones = ctz_hwi (~value >> 32);
	  int lower_leading_ones = clz_hwi (~value << 32);

	  if (upper_trailing_ones < 32 && lower_leading_ones < 32
	      && ((64 - upper_trailing_ones - lower_leading_ones) < 12))
	    {
	      codes[0].code = UNKNOWN;
	      /* The sign-bit might be zero, so just rotate to be safe.  */
	      codes[0].value = ((value << (32 - upper_trailing_ones))
				| ((unsigned HOST_WIDE_INT) value
				   >> (32 + upper_trailing_ones)));
	      codes[1].code = ROTATERT;
	      codes[1].value = 32 - upper_trailing_ones;
	      cost = 2;
	    }
	}
    }

  gcc_assert (cost <= RISCV_MAX_INTEGER_OPS);
  return cost;
}

/* Fill CODES with a sequence of rtl operations to load VALUE.
   Return the number of operations needed.  */

static int
riscv_build_integer (struct riscv_integer_op *codes, HOST_WIDE_INT value,
		     machine_mode mode)
{
  int cost = riscv_build_integer_1 (codes, value, mode);

  /* Eliminate leading zeros and end with SRLI.  */
  if (value > 0 && cost > 2)
    {
      struct riscv_integer_op alt_codes[RISCV_MAX_INTEGER_OPS];
      int alt_cost, shift = clz_hwi (value);
      HOST_WIDE_INT shifted_val;

      /* Try filling trailing bits with 1s.  */
      shifted_val = (value << shift) | ((((HOST_WIDE_INT) 1) << shift) - 1);
      alt_cost = 1 + riscv_build_integer_1 (alt_codes, shifted_val, mode);
      if (alt_cost < cost)
	{
	  alt_codes[alt_cost-1].code = LSHIFTRT;
	  alt_codes[alt_cost-1].value = shift;
	  memcpy (codes, alt_codes, sizeof (alt_codes));
	  cost = alt_cost;
	}

      /* Try filling trailing bits with 0s.  */
      shifted_val = value << shift;
      alt_cost = 1 + riscv_build_integer_1 (alt_codes, shifted_val, mode);
      if (alt_cost < cost)
	{
	  alt_codes[alt_cost-1].code = LSHIFTRT;
	  alt_codes[alt_cost-1].value = shift;
	  memcpy (codes, alt_codes, sizeof (alt_codes));
	  cost = alt_cost;
	}
    }

  return cost;
}

/* Return the cost of constructing VAL in the event that a scratch
   register is available.  */

static int
riscv_split_integer_cost (HOST_WIDE_INT val)
{
  int cost;
  unsigned HOST_WIDE_INT loval = sext_hwi (val, 32);
  unsigned HOST_WIDE_INT hival = sext_hwi ((val - loval) >> 32, 32);
  struct riscv_integer_op codes[RISCV_MAX_INTEGER_OPS];

  cost = 2 + riscv_build_integer (codes, loval, VOIDmode);
  if (loval != hival)
    cost += riscv_build_integer (codes, hival, VOIDmode);

  return cost;
}

/* Return the cost of constructing the integer constant VAL.  */

static int
riscv_integer_cost (HOST_WIDE_INT val)
{
  struct riscv_integer_op codes[RISCV_MAX_INTEGER_OPS];
  return MIN (riscv_build_integer (codes, val, VOIDmode),
	      riscv_split_integer_cost (val));
}

/* Try to split a 64b integer into 32b parts, then reassemble.  */

static rtx
riscv_split_integer (HOST_WIDE_INT val, machine_mode mode)
{
  unsigned HOST_WIDE_INT loval = sext_hwi (val, 32);
  unsigned HOST_WIDE_INT hival = sext_hwi ((val - loval) >> 32, 32);
  rtx hi = gen_reg_rtx (mode), lo = gen_reg_rtx (mode);

  riscv_move_integer (hi, hi, hival, mode, FALSE);
  riscv_move_integer (lo, lo, loval, mode, FALSE);

  hi = gen_rtx_fmt_ee (ASHIFT, mode, hi, GEN_INT (32));
  hi = force_reg (mode, hi);

  return gen_rtx_fmt_ee (PLUS, mode, hi, lo);
}

/* Return true if X is a thread-local symbol.  */

static bool
riscv_tls_symbol_p (const_rtx x)
{
  return SYMBOL_REF_P (x) && SYMBOL_REF_TLS_MODEL (x) != 0;
}

/* Return true if symbol X binds locally.  */

static bool
riscv_symbol_binds_local_p (const_rtx x)
{
  if (SYMBOL_REF_P (x))
    return (SYMBOL_REF_DECL (x)
	    ? targetm.binds_local_p (SYMBOL_REF_DECL (x))
	    : SYMBOL_REF_LOCAL_P (x));
  else
    return false;
}

/* Return the method that should be used to access SYMBOL_REF or
   LABEL_REF X.  */

static enum riscv_symbol_type
riscv_classify_symbol (const_rtx x)
{
  if (riscv_tls_symbol_p (x))
    return SYMBOL_TLS;

  if (GET_CODE (x) == SYMBOL_REF && flag_pic && !riscv_symbol_binds_local_p (x))
    return SYMBOL_GOT_DISP;

  return riscv_cmodel == CM_MEDLOW ? SYMBOL_ABSOLUTE : SYMBOL_PCREL;
}

/* Classify the base of symbolic expression X.  */

enum riscv_symbol_type
riscv_classify_symbolic_expression (rtx x)
{
  rtx offset;

  split_const (x, &x, &offset);
  if (UNSPEC_ADDRESS_P (x))
    return UNSPEC_ADDRESS_TYPE (x);

  return riscv_classify_symbol (x);
}

/* Return true if X is a symbolic constant.  If it is, store the type of
   the symbol in *SYMBOL_TYPE.  */

bool
riscv_symbolic_constant_p (rtx x, enum riscv_symbol_type *symbol_type)
{
  rtx offset;

  split_const (x, &x, &offset);
  if (UNSPEC_ADDRESS_P (x))
    {
      *symbol_type = UNSPEC_ADDRESS_TYPE (x);
      x = UNSPEC_ADDRESS (x);
    }
  else if (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == LABEL_REF)
    *symbol_type = riscv_classify_symbol (x);
  else
    return false;

  if (offset == const0_rtx)
    return true;

  /* Nonzero offsets are only valid for references that don't use the GOT.  */
  switch (*symbol_type)
    {
    case SYMBOL_ABSOLUTE:
    case SYMBOL_PCREL:
    case SYMBOL_TLS_LE:
      /* GAS rejects offsets outside the range [-2^31, 2^31-1].  */
      return sext_hwi (INTVAL (offset), 32) == INTVAL (offset);

    default:
      return false;
    }
}

/* Returns the number of instructions necessary to reference a symbol. */

static int riscv_symbol_insns (enum riscv_symbol_type type)
{
  switch (type)
    {
    case SYMBOL_TLS: return 0; /* Depends on the TLS model.  */
    case SYMBOL_ABSOLUTE: return 2; /* LUI + the reference.  */
    case SYMBOL_PCREL: return 2; /* AUIPC + the reference.  */
    case SYMBOL_TLS_LE: return 3; /* LUI + ADD TP + the reference.  */
    case SYMBOL_GOT_DISP: return 3; /* AUIPC + LD GOT + the reference.  */
    default: gcc_unreachable ();
    }
}

/* Implement TARGET_LEGITIMATE_CONSTANT_P.  */

static bool
riscv_legitimate_constant_p (machine_mode mode ATTRIBUTE_UNUSED, rtx x)
{
  return riscv_const_insns (x) > 0;
}

/* Implement TARGET_CANNOT_FORCE_CONST_MEM.  */

static bool
riscv_cannot_force_const_mem (machine_mode mode ATTRIBUTE_UNUSED, rtx x)
{
  enum riscv_symbol_type type;
  rtx base, offset;

  /* There's no way to calculate VL-based values using relocations.  */
  subrtx_iterator::array_type array;
  FOR_EACH_SUBRTX (iter, array, x, ALL)
    if (GET_CODE (*iter) == CONST_POLY_INT)
      return true;

  /* There is no assembler syntax for expressing an address-sized
     high part.  */
  if (GET_CODE (x) == HIGH)
    return true;

  split_const (x, &base, &offset);
  if (riscv_symbolic_constant_p (base, &type))
    {
      /* As an optimization, don't spill symbolic constants that are as
	 cheap to rematerialize as to access in the constant pool.  */
      if (SMALL_OPERAND (INTVAL (offset)) && riscv_symbol_insns (type) > 0)
	return true;

      /* As an optimization, avoid needlessly generate dynamic relocations.  */
      if (flag_pic)
	return true;
    }

  /* TLS symbols must be computed by riscv_legitimize_move.  */
  if (tls_referenced_p (x))
    return true;

  return false;
}

/* Return true if register REGNO is a valid base register for mode MODE.
   STRICT_P is true if REG_OK_STRICT is in effect.  */

int
riscv_regno_mode_ok_for_base_p (int regno,
				machine_mode mode ATTRIBUTE_UNUSED,
				bool strict_p)
{
  if (!HARD_REGISTER_NUM_P (regno))
    {
      if (!strict_p)
	return true;
      regno = reg_renumber[regno];
    }

  /* These fake registers will be eliminated to either the stack or
     hard frame pointer, both of which are usually valid base registers.
     Reload deals with the cases where the eliminated form isn't valid.  */
  if (regno == ARG_POINTER_REGNUM || regno == FRAME_POINTER_REGNUM)
    return true;

  return GP_REG_P (regno);
}

/* Return true if X is a valid base register for mode MODE.
   STRICT_P is true if REG_OK_STRICT is in effect.  */

static bool
riscv_valid_base_register_p (rtx x, machine_mode mode, bool strict_p)
{
  if (!strict_p && GET_CODE (x) == SUBREG)
    x = SUBREG_REG (x);

  return (REG_P (x)
	  && riscv_regno_mode_ok_for_base_p (REGNO (x), mode, strict_p));
}

/* Return true if, for every base register BASE_REG, (plus BASE_REG X)
   can address a value of mode MODE.  */

static bool
riscv_valid_offset_p (rtx x, machine_mode mode)
{
  /* Check that X is a signed 12-bit number.  */
  if (!const_arith_operand (x, Pmode))
    return false;

  /* We may need to split multiword moves, so make sure that every word
     is accessible.  */
  if (GET_MODE_SIZE (mode).to_constant () > UNITS_PER_WORD
      && !SMALL_OPERAND (INTVAL (x) + GET_MODE_SIZE (mode).to_constant () - UNITS_PER_WORD))
    return false;

  return true;
}

/* Should a symbol of type SYMBOL_TYPE should be split in two?  */

bool
riscv_split_symbol_type (enum riscv_symbol_type symbol_type)
{
  if (symbol_type == SYMBOL_TLS_LE)
    return true;

  if (!TARGET_EXPLICIT_RELOCS)
    return false;

  return symbol_type == SYMBOL_ABSOLUTE || symbol_type == SYMBOL_PCREL;
}

/* Return true if a LO_SUM can address a value of mode MODE when the
   LO_SUM symbol has type SYM_TYPE.  X is the LO_SUM second operand, which
   is used when the mode is BLKmode.  */

static bool
riscv_valid_lo_sum_p (enum riscv_symbol_type sym_type, machine_mode mode,
		      rtx x)
{
  int align, size;

  /* Check that symbols of type SYMBOL_TYPE can be used to access values
     of mode MODE.  */
  if (riscv_symbol_insns (sym_type) == 0)
    return false;

  /* Check that there is a known low-part relocation.  */
  if (!riscv_split_symbol_type (sym_type))
    return false;

  /* We can't tell size or alignment when we have BLKmode, so try extracing a
     decl from the symbol if possible.  */
  if (mode == BLKmode)
    {
      rtx offset;

      /* Extract the symbol from the LO_SUM operand, if any.  */
      split_const (x, &x, &offset);

      /* Might be a CODE_LABEL.  We can compute align but not size for that,
	 so don't bother trying to handle it.  */
      if (!SYMBOL_REF_P (x))
	return false;

      /* Use worst case assumptions if we don't have a SYMBOL_REF_DECL.  */
      align = (SYMBOL_REF_DECL (x)
	       ? DECL_ALIGN (SYMBOL_REF_DECL (x))
	       : 1);
      size = (SYMBOL_REF_DECL (x) && DECL_SIZE (SYMBOL_REF_DECL (x))
	      ? tree_to_uhwi (DECL_SIZE (SYMBOL_REF_DECL (x)))
	      : 2*BITS_PER_WORD);
    }
  else
    {
      align = GET_MODE_ALIGNMENT (mode);
      size = GET_MODE_BITSIZE (mode).to_constant ();
    }

  /* We may need to split multiword moves, so make sure that each word
     can be accessed without inducing a carry.  */
  if (size > BITS_PER_WORD
      && (!TARGET_STRICT_ALIGN || size > align))
    return false;

  return true;
}

/* Return true if mode is the RVV enabled mode.
   For example: 'VNx1DI' mode is disabled if MIN_VLEN == 32.
   'VNx1SI' mode is enabled if MIN_VLEN == 32.  */

bool
riscv_v_ext_vector_mode_p (machine_mode mode)
{
#define ENTRY(MODE, REQUIREMENT)                                               \
  case MODE##mode:                                                             \
    return REQUIREMENT;
  switch (mode)
    {
#include "riscv-vector-switch.def"
    default:
      return false;
    }

  return false;
}

/* Call from ADJUST_NUNITS in riscv-modes.def. Return the correct
   NUNITS size for corresponding machine_mode.  */

poly_int64
riscv_v_adjust_nunits (machine_mode mode, int scale)
{
  if (riscv_v_ext_vector_mode_p (mode))
    return riscv_vector_chunks * scale;
  return scale;
}

/* Return true if X is a valid address for machine mode MODE.  If it is,
   fill in INFO appropriately.  STRICT_P is true if REG_OK_STRICT is in
   effect.  */

static bool
riscv_classify_address (struct riscv_address_info *info, rtx x,
			machine_mode mode, bool strict_p)
{
  switch (GET_CODE (x))
    {
    case REG:
    case SUBREG:
      info->type = ADDRESS_REG;
      info->reg = x;
      info->offset = const0_rtx;
      return riscv_valid_base_register_p (info->reg, mode, strict_p);

    case PLUS:
      /* RVV load/store disallow any offset.  */
      if (riscv_v_ext_vector_mode_p (mode))
	return false;

      info->type = ADDRESS_REG;
      info->reg = XEXP (x, 0);
      info->offset = XEXP (x, 1);
      return (riscv_valid_base_register_p (info->reg, mode, strict_p)
	      && riscv_valid_offset_p (info->offset, mode));

    case LO_SUM:
      /* RVV load/store disallow LO_SUM.  */
      if (riscv_v_ext_vector_mode_p (mode))
	return false;

      info->type = ADDRESS_LO_SUM;
      info->reg = XEXP (x, 0);
      info->offset = XEXP (x, 1);
      /* We have to trust the creator of the LO_SUM to do something vaguely
	 sane.  Target-independent code that creates a LO_SUM should also
	 create and verify the matching HIGH.  Target-independent code that
	 adds an offset to a LO_SUM must prove that the offset will not
	 induce a carry.  Failure to do either of these things would be
	 a bug, and we are not required to check for it here.  The RISC-V
	 backend itself should only create LO_SUMs for valid symbolic
	 constants, with the high part being either a HIGH or a copy
	 of _gp. */
      info->symbol_type
	= riscv_classify_symbolic_expression (info->offset);
      return (riscv_valid_base_register_p (info->reg, mode, strict_p)
	      && riscv_valid_lo_sum_p (info->symbol_type, mode, info->offset));

    case CONST_INT:
      /* RVV load/store disallow CONST_INT.  */
      if (riscv_v_ext_vector_mode_p (mode))
	return false;

      /* Small-integer addresses don't occur very often, but they
	 are legitimate if x0 is a valid base register.  */
      info->type = ADDRESS_CONST_INT;
      return SMALL_OPERAND (INTVAL (x));

    default:
      return false;
    }
}

/* Implement TARGET_LEGITIMATE_ADDRESS_P.  */

static bool
riscv_legitimate_address_p (machine_mode mode, rtx x, bool strict_p)
{
  struct riscv_address_info addr;

  return riscv_classify_address (&addr, x, mode, strict_p);
}

/* Return true if hard reg REGNO can be used in compressed instructions.  */

static bool
riscv_compressed_reg_p (int regno)
{
  /* x8-x15/f8-f15 are compressible registers.  */
  return (TARGET_RVC && (IN_RANGE (regno, GP_REG_FIRST + 8, GP_REG_FIRST + 15)
	  || IN_RANGE (regno, FP_REG_FIRST + 8, FP_REG_FIRST + 15)));
}

/* Return true if x is an unsigned 5-bit immediate scaled by 4.  */

static bool
riscv_compressed_lw_offset_p (rtx x)
{
  return (CONST_INT_P (x)
	  && (INTVAL (x) & 3) == 0
	  && IN_RANGE (INTVAL (x), 0, CSW_MAX_OFFSET));
}

/* Return true if load/store from/to address x can be compressed.  */

static bool
riscv_compressed_lw_address_p (rtx x)
{
  struct riscv_address_info addr;
  bool result = riscv_classify_address (&addr, x, GET_MODE (x),
					reload_completed);

  /* Return false if address is not compressed_reg + small_offset.  */
  if (!result
      || addr.type != ADDRESS_REG
      /* Before reload, assume all registers are OK.  */
      || (reload_completed
	  && !riscv_compressed_reg_p (REGNO (addr.reg))
	  && addr.reg != stack_pointer_rtx)
      || !riscv_compressed_lw_offset_p (addr.offset))
    return false;

  return result;
}

/* Return the number of instructions needed to load or store a value
   of mode MODE at address X.  Return 0 if X isn't valid for MODE.
   Assume that multiword moves may need to be split into word moves
   if MIGHT_SPLIT_P, otherwise assume that a single load or store is
   enough. */

int
riscv_address_insns (rtx x, machine_mode mode, bool might_split_p)
{
  struct riscv_address_info addr = {};
  int n = 1;

  if (!riscv_classify_address (&addr, x, mode, false))
    {
      /* This could be a pattern from the pic.md file.  In which case we want
	 this address to always have a cost of 3 to make it as expensive as the
	 most expensive symbol.  This prevents constant propagation from
	 preferring symbols over register plus offset.  */
      return 3;
    }

  /* BLKmode is used for single unaligned loads and stores and should
     not count as a multiword mode. */
  if (!riscv_v_ext_vector_mode_p (mode) && mode != BLKmode && might_split_p)
    n += (GET_MODE_SIZE (mode).to_constant () + UNITS_PER_WORD - 1) / UNITS_PER_WORD;

  if (addr.type == ADDRESS_LO_SUM)
    n += riscv_symbol_insns (addr.symbol_type) - 1;

  return n;
}

/* Return the number of instructions needed to load constant X.
   Return 0 if X isn't a valid constant.  */

int
riscv_const_insns (rtx x)
{
  enum riscv_symbol_type symbol_type;
  rtx offset;

  switch (GET_CODE (x))
    {
    case HIGH:
      if (!riscv_symbolic_constant_p (XEXP (x, 0), &symbol_type)
	  || !riscv_split_symbol_type (symbol_type))
	return 0;

      /* This is simply an LUI.  */
      return 1;

    case CONST_INT:
      {
	int cost = riscv_integer_cost (INTVAL (x));
	/* Force complicated constants to memory.  */
	return cost < 4 ? cost : 0;
      }

    case CONST_DOUBLE:
    case CONST_VECTOR:
      /* We can use x0 to load floating-point zero.  */
      return x == CONST0_RTX (GET_MODE (x)) ? 1 : 0;

    case CONST:
      /* See if we can refer to X directly.  */
      if (riscv_symbolic_constant_p (x, &symbol_type))
	return riscv_symbol_insns (symbol_type);

      /* Otherwise try splitting the constant into a base and offset.  */
      split_const (x, &x, &offset);
      if (offset != 0)
	{
	  int n = riscv_const_insns (x);
	  if (n != 0)
	    return n + riscv_integer_cost (INTVAL (offset));
	}
      return 0;

    case SYMBOL_REF:
    case LABEL_REF:
      return riscv_symbol_insns (riscv_classify_symbol (x));

    /* TODO: In RVV, we get CONST_POLY_INT by using csrr VLENB
       instruction and several scalar shift or mult instructions,
       it is so far unknown. We set it to 4 temporarily.  */
    case CONST_POLY_INT:
      return 4;

    default:
      return 0;
    }
}

/* X is a doubleword constant that can be handled by splitting it into
   two words and loading each word separately.  Return the number of
   instructions required to do this.  */

int
riscv_split_const_insns (rtx x)
{
  unsigned int low, high;

  low = riscv_const_insns (riscv_subword (x, false));
  high = riscv_const_insns (riscv_subword (x, true));
  gcc_assert (low > 0 && high > 0);
  return low + high;
}

/* Return the number of instructions needed to implement INSN,
   given that it loads from or stores to MEM. */

int
riscv_load_store_insns (rtx mem, rtx_insn *insn)
{
  machine_mode mode;
  bool might_split_p;
  rtx set;

  gcc_assert (MEM_P (mem));
  mode = GET_MODE (mem);

  /* Try to prove that INSN does not need to be split.  */
  might_split_p = true;
  if (GET_MODE_BITSIZE (mode).to_constant () <= 32)
    might_split_p = false;
  else if (GET_MODE_BITSIZE (mode).to_constant () == 64)
    {
      set = single_set (insn);
      if (set && !riscv_split_64bit_move_p (SET_DEST (set), SET_SRC (set)))
	might_split_p = false;
    }

  return riscv_address_insns (XEXP (mem, 0), mode, might_split_p);
}

/* Emit a move from SRC to DEST.  Assume that the move expanders can
   handle all moves if !can_create_pseudo_p ().  The distinction is
   important because, unlike emit_move_insn, the move expanders know
   how to force Pmode objects into the constant pool even when the
   constant pool address is not itself legitimate.  */

rtx
riscv_emit_move (rtx dest, rtx src)
{
  return (can_create_pseudo_p ()
	  ? emit_move_insn (dest, src)
	  : emit_move_insn_1 (dest, src));
}

/* Emit an instruction of the form (set TARGET SRC).  */

static rtx
riscv_emit_set (rtx target, rtx src)
{
  emit_insn (gen_rtx_SET (target, src));
  return target;
}

/* Emit an instruction of the form (set DEST (CODE X Y)).  */

static rtx
riscv_emit_binary (enum rtx_code code, rtx dest, rtx x, rtx y)
{
  return riscv_emit_set (dest, gen_rtx_fmt_ee (code, GET_MODE (dest), x, y));
}

/* Compute (CODE X Y) and store the result in a new register
   of mode MODE.  Return that new register.  */

static rtx
riscv_force_binary (machine_mode mode, enum rtx_code code, rtx x, rtx y)
{
  return riscv_emit_binary (code, gen_reg_rtx (mode), x, y);
}

static rtx
riscv_swap_instruction (rtx inst)
{
  gcc_assert (GET_MODE (inst) == SImode);
  if (BYTES_BIG_ENDIAN)
    inst = expand_unop (SImode, bswap_optab, inst, gen_reg_rtx (SImode), 1);
  return inst;
}

/* Copy VALUE to a register and return that register.  If new pseudos
   are allowed, copy it into a new register, otherwise use DEST.  */

static rtx
riscv_force_temporary (rtx dest, rtx value, bool in_splitter)
{
  /* We can't call gen_reg_rtx from a splitter, because this might realloc
     the regno_reg_rtx array, which would invalidate reg rtx pointers in the
     combine undo buffer.  */
  if (can_create_pseudo_p () && !in_splitter)
    return force_reg (Pmode, value);
  else
    {
      riscv_emit_move (dest, value);
      return dest;
    }
}

/* Wrap symbol or label BASE in an UNSPEC address of type SYMBOL_TYPE,
   then add CONST_INT OFFSET to the result.  */

static rtx
riscv_unspec_address_offset (rtx base, rtx offset,
			     enum riscv_symbol_type symbol_type)
{
  base = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, base),
			 UNSPEC_ADDRESS_FIRST + symbol_type);
  if (offset != const0_rtx)
    base = gen_rtx_PLUS (Pmode, base, offset);
  return gen_rtx_CONST (Pmode, base);
}

/* Return an UNSPEC address with underlying address ADDRESS and symbol
   type SYMBOL_TYPE.  */

rtx
riscv_unspec_address (rtx address, enum riscv_symbol_type symbol_type)
{
  rtx base, offset;

  split_const (address, &base, &offset);
  return riscv_unspec_address_offset (base, offset, symbol_type);
}

/* If OP is an UNSPEC address, return the address to which it refers,
   otherwise return OP itself.  */

static rtx
riscv_strip_unspec_address (rtx op)
{
  rtx base, offset;

  split_const (op, &base, &offset);
  if (UNSPEC_ADDRESS_P (base))
    op = plus_constant (Pmode, UNSPEC_ADDRESS (base), INTVAL (offset));
  return op;
}

/* If riscv_unspec_address (ADDR, SYMBOL_TYPE) is a 32-bit value, add the
   high part to BASE and return the result.  Just return BASE otherwise.
   TEMP is as for riscv_force_temporary.

   The returned expression can be used as the first operand to a LO_SUM.  */

static rtx
riscv_unspec_offset_high (rtx temp, rtx addr, enum riscv_symbol_type symbol_type)
{
  addr = gen_rtx_HIGH (Pmode, riscv_unspec_address (addr, symbol_type));
  return riscv_force_temporary (temp, addr, FALSE);
}

/* Load an entry from the GOT for a TLS GD access.  */

static rtx riscv_got_load_tls_gd (rtx dest, rtx sym)
{
  if (Pmode == DImode)
    return gen_got_load_tls_gddi (dest, sym);
  else
    return gen_got_load_tls_gdsi (dest, sym);
}

/* Load an entry from the GOT for a TLS IE access.  */

static rtx riscv_got_load_tls_ie (rtx dest, rtx sym)
{
  if (Pmode == DImode)
    return gen_got_load_tls_iedi (dest, sym);
  else
    return gen_got_load_tls_iesi (dest, sym);
}

/* Add in the thread pointer for a TLS LE access.  */

static rtx riscv_tls_add_tp_le (rtx dest, rtx base, rtx sym)
{
  rtx tp = gen_rtx_REG (Pmode, THREAD_POINTER_REGNUM);
  if (Pmode == DImode)
    return gen_tls_add_tp_ledi (dest, base, tp, sym);
  else
    return gen_tls_add_tp_lesi (dest, base, tp, sym);
}

/* If MODE is MAX_MACHINE_MODE, ADDR appears as a move operand, otherwise
   it appears in a MEM of that mode.  Return true if ADDR is a legitimate
   constant in that context and can be split into high and low parts.
   If so, and if LOW_OUT is nonnull, emit the high part and store the
   low part in *LOW_OUT.  Leave *LOW_OUT unchanged otherwise.

   TEMP is as for riscv_force_temporary and is used to load the high
   part into a register.

   When MODE is MAX_MACHINE_MODE, the low part is guaranteed to be
   a legitimize SET_SRC for an .md pattern, otherwise the low part
   is guaranteed to be a legitimate address for mode MODE.  */

bool
riscv_split_symbol (rtx temp, rtx addr, machine_mode mode, rtx *low_out,
		    bool in_splitter)
{
  enum riscv_symbol_type symbol_type;

  if ((GET_CODE (addr) == HIGH && mode == MAX_MACHINE_MODE)
      || !riscv_symbolic_constant_p (addr, &symbol_type)
      || riscv_symbol_insns (symbol_type) == 0
      || !riscv_split_symbol_type (symbol_type))
    return false;

  if (low_out)
    switch (symbol_type)
      {
      case SYMBOL_ABSOLUTE:
	{
	  rtx high = gen_rtx_HIGH (Pmode, copy_rtx (addr));
	  high = riscv_force_temporary (temp, high, in_splitter);
	  *low_out = gen_rtx_LO_SUM (Pmode, high, addr);
	}
	break;

      case SYMBOL_PCREL:
	{
	  static unsigned seqno;
	  char buf[32];
	  rtx label;

	  ssize_t bytes = snprintf (buf, sizeof (buf), ".LA%u", seqno);
	  gcc_assert ((size_t) bytes < sizeof (buf));

	  label = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
	  SYMBOL_REF_FLAGS (label) |= SYMBOL_FLAG_LOCAL;
	  /* ??? Ugly hack to make weak symbols work.  May need to change the
	     RTL for the auipc and/or low patterns to get a better fix for
	     this.  */
	  if (! nonzero_address_p (addr))
	    SYMBOL_REF_WEAK (label) = 1;

	  if (temp == NULL)
	    temp = gen_reg_rtx (Pmode);

	  if (Pmode == DImode)
	    emit_insn (gen_auipcdi (temp, copy_rtx (addr), GEN_INT (seqno)));
	  else
	    emit_insn (gen_auipcsi (temp, copy_rtx (addr), GEN_INT (seqno)));

	  *low_out = gen_rtx_LO_SUM (Pmode, temp, label);

	  seqno++;
	}
	break;

      default:
	gcc_unreachable ();
      }

  return true;
}

/* Return a legitimate address for REG + OFFSET.  TEMP is as for
   riscv_force_temporary; it is only needed when OFFSET is not a
   SMALL_OPERAND.  */

static rtx
riscv_add_offset (rtx temp, rtx reg, HOST_WIDE_INT offset)
{
  if (!SMALL_OPERAND (offset))
    {
      rtx high;

      /* Leave OFFSET as a 16-bit offset and put the excess in HIGH.
	 The addition inside the macro CONST_HIGH_PART may cause an
	 overflow, so we need to force a sign-extension check.  */
      high = gen_int_mode (CONST_HIGH_PART (offset), Pmode);
      offset = CONST_LOW_PART (offset);
      high = riscv_force_temporary (temp, high, FALSE);
      reg = riscv_force_temporary (temp, gen_rtx_PLUS (Pmode, high, reg),
				   FALSE);
    }
  return plus_constant (Pmode, reg, offset);
}

/* The __tls_get_attr symbol.  */
static GTY(()) rtx riscv_tls_symbol;

/* Return an instruction sequence that calls __tls_get_addr.  SYM is
   the TLS symbol we are referencing and TYPE is the symbol type to use
   (either global dynamic or local dynamic).  RESULT is an RTX for the
   return value location.  */

static rtx_insn *
riscv_call_tls_get_addr (rtx sym, rtx result)
{
  rtx a0 = gen_rtx_REG (Pmode, GP_ARG_FIRST), func;
  rtx_insn *insn;

  if (!riscv_tls_symbol)
    riscv_tls_symbol = init_one_libfunc ("__tls_get_addr");
  func = gen_rtx_MEM (FUNCTION_MODE, riscv_tls_symbol);

  start_sequence ();

  emit_insn (riscv_got_load_tls_gd (a0, sym));
  insn = emit_call_insn (gen_call_value (result, func, const0_rtx, NULL));
  RTL_CONST_CALL_P (insn) = 1;
  use_reg (&CALL_INSN_FUNCTION_USAGE (insn), a0);
  insn = get_insns ();

  end_sequence ();

  return insn;
}

/* Generate the code to access LOC, a thread-local SYMBOL_REF, and return
   its address.  The return value will be both a valid address and a valid
   SET_SRC (either a REG or a LO_SUM).  */

static rtx
riscv_legitimize_tls_address (rtx loc)
{
  rtx dest, tp, tmp;
  enum tls_model model = SYMBOL_REF_TLS_MODEL (loc);

#if 0
  /* TLS copy relocs are now deprecated and should not be used.  */
  /* Since we support TLS copy relocs, non-PIC TLS accesses may all use LE.  */
  if (!flag_pic)
    model = TLS_MODEL_LOCAL_EXEC;
#endif

  switch (model)
    {
    case TLS_MODEL_LOCAL_DYNAMIC:
      /* Rely on section anchors for the optimization that LDM TLS
	 provides.  The anchor's address is loaded with GD TLS. */
    case TLS_MODEL_GLOBAL_DYNAMIC:
      tmp = gen_rtx_REG (Pmode, GP_RETURN);
      dest = gen_reg_rtx (Pmode);
      emit_libcall_block (riscv_call_tls_get_addr (loc, tmp), dest, tmp, loc);
      break;

    case TLS_MODEL_INITIAL_EXEC:
      /* la.tls.ie; tp-relative add */
      tp = gen_rtx_REG (Pmode, THREAD_POINTER_REGNUM);
      tmp = gen_reg_rtx (Pmode);
      emit_insn (riscv_got_load_tls_ie (tmp, loc));
      dest = gen_reg_rtx (Pmode);
      emit_insn (gen_add3_insn (dest, tmp, tp));
      break;

    case TLS_MODEL_LOCAL_EXEC:
      tmp = riscv_unspec_offset_high (NULL, loc, SYMBOL_TLS_LE);
      dest = gen_reg_rtx (Pmode);
      emit_insn (riscv_tls_add_tp_le (dest, tmp, loc));
      dest = gen_rtx_LO_SUM (Pmode, dest,
			     riscv_unspec_address (loc, SYMBOL_TLS_LE));
      break;

    default:
      gcc_unreachable ();
    }
  return dest;
}

/* If X is not a valid address for mode MODE, force it into a register.  */

static rtx
riscv_force_address (rtx x, machine_mode mode)
{
  if (!riscv_legitimate_address_p (mode, x, false))
    x = force_reg (Pmode, x);
  return x;
}

/* Modify base + offset so that offset fits within a compressed load/store insn
   and the excess is added to base.  */

static rtx
riscv_shorten_lw_offset (rtx base, HOST_WIDE_INT offset)
{
  rtx addr, high;
  /* Leave OFFSET as an unsigned 5-bit offset scaled by 4 and put the excess
     into HIGH.  */
  high = GEN_INT (offset & ~CSW_MAX_OFFSET);
  offset &= CSW_MAX_OFFSET;
  if (!SMALL_OPERAND (INTVAL (high)))
    high = force_reg (Pmode, high);
  base = force_reg (Pmode, gen_rtx_PLUS (Pmode, high, base));
  addr = plus_constant (Pmode, base, offset);
  return addr;
}

/* This function is used to implement LEGITIMIZE_ADDRESS.  If X can
   be legitimized in a way that the generic machinery might not expect,
   return a new address, otherwise return NULL.  MODE is the mode of
   the memory being accessed.  */

static rtx
riscv_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
			  machine_mode mode)
{
  rtx addr;

  if (riscv_tls_symbol_p (x))
    return riscv_legitimize_tls_address (x);

  /* See if the address can split into a high part and a LO_SUM.  */
  if (riscv_split_symbol (NULL, x, mode, &addr, FALSE))
    return riscv_force_address (addr, mode);

  /* Handle BASE + OFFSET.  */
  if (GET_CODE (x) == PLUS && CONST_INT_P (XEXP (x, 1))
      && INTVAL (XEXP (x, 1)) != 0)
    {
      rtx base = XEXP (x, 0);
      HOST_WIDE_INT offset = INTVAL (XEXP (x, 1));

      if (!riscv_valid_base_register_p (base, mode, false))
	base = copy_to_mode_reg (Pmode, base);
      if (optimize_function_for_size_p (cfun)
	  && (strcmp (current_pass->name, "shorten_memrefs") == 0)
	  && mode == SImode)
	/* Convert BASE + LARGE_OFFSET into NEW_BASE + SMALL_OFFSET to allow
	   possible compressed load/store.  */
	addr = riscv_shorten_lw_offset (base, offset);
      else
	addr = riscv_add_offset (NULL, base, offset);
      return riscv_force_address (addr, mode);
    }

  return x;
}

/* Load VALUE into DEST.  TEMP is as for riscv_force_temporary.  ORIG_MODE
   is the original src mode before promotion.  */

void
riscv_move_integer (rtx temp, rtx dest, HOST_WIDE_INT value,
		    machine_mode orig_mode, bool in_splitter)
{
  struct riscv_integer_op codes[RISCV_MAX_INTEGER_OPS];
  machine_mode mode;
  int i, num_ops;
  rtx x;

  /* We can't call gen_reg_rtx from a splitter, because this might realloc
     the regno_reg_rtx array, which would invalidate reg rtx pointers in the
     combine undo buffer.  */
  bool can_create_pseudo = can_create_pseudo_p () && ! in_splitter;

  mode = GET_MODE (dest);
  /* We use the original mode for the riscv_build_integer call, because HImode
     values are given special treatment.  */
  num_ops = riscv_build_integer (codes, value, orig_mode);

  if (can_create_pseudo && num_ops > 2 /* not a simple constant */
      && num_ops >= riscv_split_integer_cost (value))
    x = riscv_split_integer (value, mode);
  else
    {
      codes[0].value = trunc_int_for_mode (codes[0].value, mode);
      /* Apply each binary operation to X. */
      x = GEN_INT (codes[0].value);

      for (i = 1; i < num_ops; i++)
	{
	  if (!can_create_pseudo)
	    x = riscv_emit_set (temp, x);
	  else
	    x = force_reg (mode, x);
	  codes[i].value = trunc_int_for_mode (codes[i].value, mode);
	  x = gen_rtx_fmt_ee (codes[i].code, mode, x, GEN_INT (codes[i].value));
	}
    }

  riscv_emit_set (dest, x);
}

/* Subroutine of riscv_legitimize_move.  Move constant SRC into register
   DEST given that SRC satisfies immediate_operand but doesn't satisfy
   move_operand.  */

static void
riscv_legitimize_const_move (machine_mode mode, rtx dest, rtx src)
{
  rtx base, offset;

  /* Split moves of big integers into smaller pieces.  */
  if (splittable_const_int_operand (src, mode))
    {
      riscv_move_integer (dest, dest, INTVAL (src), mode, FALSE);
      return;
    }

  /* Split moves of symbolic constants into high/low pairs.  */
  if (riscv_split_symbol (dest, src, MAX_MACHINE_MODE, &src, FALSE))
    {
      riscv_emit_set (dest, src);
      return;
    }

  /* Generate the appropriate access sequences for TLS symbols.  */
  if (riscv_tls_symbol_p (src))
    {
      riscv_emit_move (dest, riscv_legitimize_tls_address (src));
      return;
    }

  /* If we have (const (plus symbol offset)), and that expression cannot
     be forced into memory, load the symbol first and add in the offset.  Also
     prefer to do this even if the constant _can_ be forced into memory, as it
     usually produces better code.  */
  split_const (src, &base, &offset);
  if (offset != const0_rtx
      && (targetm.cannot_force_const_mem (mode, src) || can_create_pseudo_p ()))
    {
      base = riscv_force_temporary (dest, base, FALSE);
      riscv_emit_move (dest, riscv_add_offset (NULL, base, INTVAL (offset)));
      return;
    }

  src = force_const_mem (mode, src);

  /* When using explicit relocs, constant pool references are sometimes
     not legitimate addresses.  */
  riscv_split_symbol (dest, XEXP (src, 0), mode, &XEXP (src, 0), FALSE);
  riscv_emit_move (dest, src);
}

/* Report when we try to do something that requires vector when vector is
   disabled. This is an error of last resort and isn't very high-quality.  It
   usually involves attempts to measure the vector length in some way.  */

static void
riscv_report_v_required (void)
{
  static bool reported_p = false;

  /* Avoid reporting a slew of messages for a single oversight.  */
  if (reported_p)
    return;

  error ("this operation requires the RVV ISA extension");
  inform (input_location, "you can enable RVV using the command-line"
			  " option %<-march%>, or by using the %<target%>"
			  " attribute or pragma");
  reported_p = true;
}

/* Helper function to operation for rtx_code CODE.  */
static void
riscv_expand_op (enum rtx_code code, machine_mode mode, rtx op0, rtx op1,
		 rtx op2)
{
  if (can_create_pseudo_p ())
    {
      rtx result;
      if (GET_RTX_CLASS (code) == RTX_UNARY)
	result = expand_simple_unop (mode, code, op1, NULL_RTX, false);
      else
	result = expand_simple_binop (mode, code, op1, op2, NULL_RTX, false,
				      OPTAB_DIRECT);
      riscv_emit_move (op0, result);
    }
  else
    {
      rtx pat;
      /* The following implementation is for prologue and epilogue.
	 Because prologue and epilogue can not use pseudo register.
	 We can't using expand_simple_binop or expand_simple_unop.  */
      if (GET_RTX_CLASS (code) == RTX_UNARY)
	pat = gen_rtx_fmt_e (code, mode, op1);
      else
	pat = gen_rtx_fmt_ee (code, mode, op1, op2);
      emit_insn (gen_rtx_SET (op0, pat));
    }
}

/* Expand mult operation with constant integer, multiplicand also used as a
 * temporary register.  */

static void
riscv_expand_mult_with_const_int (machine_mode mode, rtx dest, rtx multiplicand,
				  int multiplier)
{
  if (multiplier == 0)
    {
      riscv_emit_move (dest, GEN_INT (0));
      return;
    }

  bool neg_p = multiplier < 0;
  int multiplier_abs = abs (multiplier);

  if (multiplier_abs == 1)
    {
      if (neg_p)
	riscv_expand_op (NEG, mode, dest, multiplicand, NULL_RTX);
      else
	riscv_emit_move (dest, multiplicand);
    }
  else
    {
      if (pow2p_hwi (multiplier_abs))
	{
	  /*
	    multiplicand = [BYTES_PER_RISCV_VECTOR].
	     1. const_poly_int:P [BYTES_PER_RISCV_VECTOR * 8].
	    Sequence:
		    csrr a5, vlenb
		    slli a5, a5, 3
	    2. const_poly_int:P [-BYTES_PER_RISCV_VECTOR * 8].
	    Sequence:
		    csrr a5, vlenb
		    slli a5, a5, 3
		    neg a5, a5
	  */
	  riscv_expand_op (ASHIFT, mode, dest, multiplicand,
			   gen_int_mode (exact_log2 (multiplier_abs), QImode));
	  if (neg_p)
	    riscv_expand_op (NEG, mode, dest, dest, NULL_RTX);
	}
      else if (pow2p_hwi (multiplier_abs + 1))
	{
	  /*
	    multiplicand = [BYTES_PER_RISCV_VECTOR].
	     1. const_poly_int:P [BYTES_PER_RISCV_VECTOR * 7].
	    Sequence:
		    csrr a5, vlenb
		    slli a4, a5, 3
		    sub a5, a4, a5
	     2. const_poly_int:P [-BYTES_PER_RISCV_VECTOR * 7].
	    Sequence:
		    csrr a5, vlenb
		    slli a4, a5, 3
		    sub a5, a4, a5 + neg a5, a5 => sub a5, a5, a4
	  */
	  riscv_expand_op (ASHIFT, mode, dest, multiplicand,
			   gen_int_mode (exact_log2 (multiplier_abs + 1),
					 QImode));
	  if (neg_p)
	    riscv_expand_op (MINUS, mode, dest, multiplicand, dest);
	  else
	    riscv_expand_op (MINUS, mode, dest, dest, multiplicand);
	}
      else if (pow2p_hwi (multiplier - 1))
	{
	  /*
	    multiplicand = [BYTES_PER_RISCV_VECTOR].
	     1. const_poly_int:P [BYTES_PER_RISCV_VECTOR * 9].
	    Sequence:
		    csrr a5, vlenb
		    slli a4, a5, 3
		    add a5, a4, a5
	     2. const_poly_int:P [-BYTES_PER_RISCV_VECTOR * 9].
	    Sequence:
		    csrr a5, vlenb
		    slli a4, a5, 3
		    add a5, a4, a5
		    neg a5, a5
	  */
	  riscv_expand_op (ASHIFT, mode, dest, multiplicand,
			   gen_int_mode (exact_log2 (multiplier_abs - 1),
					 QImode));
	  riscv_expand_op (PLUS, mode, dest, dest, multiplicand);
	  if (neg_p)
	    riscv_expand_op (NEG, mode, dest, dest, NULL_RTX);
	}
      else
	{
	  /* We use multiplication for remaining cases.  */
	  gcc_assert (
	    TARGET_MUL
	    && "M-extension must be enabled to calculate the poly_int "
	       "size/offset.");
	  riscv_emit_move (dest, gen_int_mode (multiplier, mode));
	  riscv_expand_op (MULT, mode, dest, dest, multiplicand);
	}
    }
}

/* Analyze src and emit const_poly_int mov sequence.  */

static void
riscv_legitimize_poly_move (machine_mode mode, rtx dest, rtx tmp, rtx src)
{
  poly_int64 value = rtx_to_poly_int64 (src);
  int offset = value.coeffs[0];
  int factor = value.coeffs[1];
  int vlenb = BYTES_PER_RISCV_VECTOR.coeffs[1];
  int div_factor = 0;
  /* Calculate (const_poly_int:MODE [m, n]) using scalar instructions.
     For any (const_poly_int:MODE [m, n]), the calculation formula is as
     follows.
     constant = m - n.
     When minimum VLEN = 32, poly of VLENB = (4, 4).
     base = vlenb(4, 4) or vlenb/2(2, 2) or vlenb/4(1, 1).
     When minimum VLEN > 32, poly of VLENB = (8, 8).
     base = vlenb(8, 8) or vlenb/2(4, 4) or vlenb/4(2, 2) or vlenb/8(1, 1).
     magn = (n, n) / base.
     (m, n) = base * magn + constant.
     This calculation doesn't need div operation.  */

  emit_move_insn (tmp, gen_int_mode (BYTES_PER_RISCV_VECTOR, mode));

  if (BYTES_PER_RISCV_VECTOR.is_constant ())
    {
      gcc_assert (value.is_constant ());
      riscv_emit_move (dest, GEN_INT (value.to_constant ()));
      return;
    }
  else if ((factor % vlenb) == 0)
    div_factor = 1;
  else if ((factor % (vlenb / 2)) == 0)
    div_factor = 2;
  else if ((factor % (vlenb / 4)) == 0)
    div_factor = 4;
  else if ((factor % (vlenb / 8)) == 0)
    div_factor = 8;
  else
    gcc_unreachable ();

  if (div_factor != 1)
    riscv_expand_op (LSHIFTRT, mode, tmp, tmp,
		     gen_int_mode (exact_log2 (div_factor), QImode));

  riscv_expand_mult_with_const_int (mode, dest, tmp,
				    factor / (vlenb / div_factor));
  HOST_WIDE_INT constant = offset - factor;

  if (constant == 0)
    return;
  else if (SMALL_OPERAND (constant))
    riscv_expand_op (PLUS, mode, dest, dest, gen_int_mode (constant, mode));
  else
    {
      /* Handle the constant value is not a 12-bit value.  */
      rtx high;

      /* Leave OFFSET as a 16-bit offset and put the excess in HIGH.
	 The addition inside the macro CONST_HIGH_PART may cause an
	 overflow, so we need to force a sign-extension check.  */
      high = gen_int_mode (CONST_HIGH_PART (constant), mode);
      constant = CONST_LOW_PART (constant);
      riscv_emit_move (tmp, high);
      riscv_expand_op (PLUS, mode, dest, tmp, dest);
      riscv_expand_op (PLUS, mode, dest, dest, gen_int_mode (constant, mode));
    }
}

/* Adjust scalable frame of vector for prologue && epilogue. */

static void
riscv_v_adjust_scalable_frame (rtx target, poly_int64 offset, bool epilogue)
{
  rtx tmp = RISCV_PROLOGUE_TEMP (Pmode);
  rtx adjust_size = RISCV_PROLOGUE_TEMP2 (Pmode);
  rtx insn, dwarf, adjust_frame_rtx;

  riscv_legitimize_poly_move (Pmode, adjust_size, tmp,
			      gen_int_mode (offset, Pmode));

  if (epilogue)
    insn = gen_add3_insn (target, target, adjust_size);
  else
    insn = gen_sub3_insn (target, target, adjust_size);

  insn = emit_insn (insn);

  RTX_FRAME_RELATED_P (insn) = 1;

  adjust_frame_rtx
    = gen_rtx_SET (target,
		   plus_constant (Pmode, target, epilogue ? offset : -offset));

  dwarf = alloc_reg_note (REG_FRAME_RELATED_EXPR, copy_rtx (adjust_frame_rtx),
			  NULL_RTX);

  REG_NOTES (insn) = dwarf;
}

/* If (set DEST SRC) is not a valid move instruction, emit an equivalent
   sequence that is valid.  */

bool
riscv_legitimize_move (machine_mode mode, rtx dest, rtx src)
{
  if (CONST_POLY_INT_P (src))
    {
      /*
	Handle:
	  (insn 183 182 184 6 (set (mem:QI (plus:DI (reg/f:DI 156)
		  (const_int 96 [0x60])) [0  S1 A8])
	  (const_poly_int:QI [8, 8]))
	"../../../../riscv-gcc/libgcc/unwind-dw2.c":1579:3 -1 (nil))
      */
      if (MEM_P (dest))
	{
	  emit_move_insn (dest, force_reg (mode, src));
	  return true;
	}
      poly_int64 value = rtx_to_poly_int64 (src);
      if (!value.is_constant () && !TARGET_VECTOR)
	{
	  riscv_report_v_required ();
	  return false;
	}

      if (satisfies_constraint_vp (src))
	return false;

      if (GET_MODE_SIZE (mode).to_constant () < GET_MODE_SIZE (Pmode))
	{
	  /* In RV32 system, handle (const_poly_int:QI [m, n])
				    (const_poly_int:HI [m, n]).
	     In RV64 system, handle (const_poly_int:QI [m, n])
				    (const_poly_int:HI [m, n])
				    (const_poly_int:SI [m, n]).  */
	  rtx tmp = gen_reg_rtx (Pmode);
	  riscv_legitimize_poly_move (Pmode, gen_lowpart (Pmode, dest), tmp,
				      src);
	}
      else
	{
	  /* In RV32 system, handle (const_poly_int:SI [m, n])
				    (const_poly_int:DI [m, n]).
	     In RV64 system, handle (const_poly_int:DI [m, n]).
       FIXME: Maybe we could gen SImode in RV32 and then sign-extend to DImode,
       the offset should not exceed 4GiB in general.  */
	  rtx tmp = gen_reg_rtx (mode);
	  riscv_legitimize_poly_move (mode, dest, tmp, src);
	}
      return true;
    }
  /* Expand 
       (set (reg:QI target) (mem:QI (address))) 
     to
       (set (reg:DI temp) (zero_extend:DI (mem:QI (address))))
       (set (reg:QI target) (subreg:QI (reg:DI temp) 0))
     with auto-sign/zero extend.  */
  if (GET_MODE_CLASS (mode) == MODE_INT
      && GET_MODE_SIZE (mode).to_constant () < UNITS_PER_WORD
      && can_create_pseudo_p ()
      && MEM_P (src))
    {
      rtx temp_reg;
      int zero_extend_p;

      temp_reg = gen_reg_rtx (word_mode);
      zero_extend_p = (LOAD_EXTEND_OP (mode) == ZERO_EXTEND);
      emit_insn (gen_extend_insn (temp_reg, src, word_mode, mode, 
				  zero_extend_p));
      riscv_emit_move (dest, gen_lowpart (mode, temp_reg));
      return true;
    }

  if (!register_operand (dest, mode) && !reg_or_0_operand (src, mode))
    {
      rtx reg;

      if (GET_CODE (src) == CONST_INT)
	{
	  /* Apply the equivalent of PROMOTE_MODE here for constants to
	     improve cse.  */
	  machine_mode promoted_mode = mode;
	  if (GET_MODE_CLASS (mode) == MODE_INT
	      && GET_MODE_SIZE (mode).to_constant () < UNITS_PER_WORD)
	    promoted_mode = word_mode;

	  if (splittable_const_int_operand (src, mode))
	    {
	      reg = gen_reg_rtx (promoted_mode);
	      riscv_move_integer (reg, reg, INTVAL (src), mode, FALSE);
	    }
	  else
	    reg = force_reg (promoted_mode, src);

	  if (promoted_mode != mode)
	    reg = gen_lowpart (mode, reg);
	}
      else
	reg = force_reg (mode, src);
      riscv_emit_move (dest, reg);
      return true;
    }

  /* We need to deal with constants that would be legitimate
     immediate_operands but aren't legitimate move_operands.  */
  if (CONSTANT_P (src) && !move_operand (src, mode))
    {
      riscv_legitimize_const_move (mode, dest, src);
      set_unique_reg_note (get_last_insn (), REG_EQUAL, copy_rtx (src));
      return true;
    }

  /* RISC-V GCC may generate non-legitimate address due to we provide some
     pattern for optimize access PIC local symbol and it's make GCC generate
     unrecognizable instruction during optmizing.  */

  if (MEM_P (dest) && !riscv_legitimate_address_p (mode, XEXP (dest, 0),
						   reload_completed))
    {
      XEXP (dest, 0) = riscv_force_address (XEXP (dest, 0), mode);
    }

  if (MEM_P (src) && !riscv_legitimate_address_p (mode, XEXP (src, 0),
						  reload_completed))
    {
      XEXP (src, 0) = riscv_force_address (XEXP (src, 0), mode);
    }

  return false;
}

/* Return true if there is an instruction that implements CODE and accepts
   X as an immediate operand. */

static int
riscv_immediate_operand_p (int code, HOST_WIDE_INT x)
{
  switch (code)
    {
    case ASHIFT:
    case ASHIFTRT:
    case LSHIFTRT:
      /* All shift counts are truncated to a valid constant.  */
      return true;

    case AND:
    case IOR:
    case XOR:
    case PLUS:
    case LT:
    case LTU:
      /* These instructions take 12-bit signed immediates.  */
      return SMALL_OPERAND (x);

    case LE:
      /* We add 1 to the immediate and use SLT.  */
      return SMALL_OPERAND (x + 1);

    case LEU:
      /* Likewise SLTU, but reject the always-true case.  */
      return SMALL_OPERAND (x + 1) && x + 1 != 0;

    case GE:
    case GEU:
      /* We can emulate an immediate of 1 by using GT/GTU against x0.  */
      return x == 1;

    default:
      /* By default assume that x0 can be used for 0.  */
      return x == 0;
    }
}

/* Return the cost of binary operation X, given that the instruction
   sequence for a word-sized or smaller operation takes SIGNLE_INSNS
   instructions and that the sequence of a double-word operation takes
   DOUBLE_INSNS instructions.  */

static int
riscv_binary_cost (rtx x, int single_insns, int double_insns)
{
  if (!riscv_v_ext_vector_mode_p (GET_MODE (x))
      && GET_MODE_SIZE (GET_MODE (x)).to_constant () == UNITS_PER_WORD * 2)
    return COSTS_N_INSNS (double_insns);
  return COSTS_N_INSNS (single_insns);
}

/* Return the cost of sign- or zero-extending OP.  */

static int
riscv_extend_cost (rtx op, bool unsigned_p)
{
  if (MEM_P (op))
    return 0;

  if (unsigned_p && GET_MODE (op) == QImode)
    /* We can use ANDI.  */
    return COSTS_N_INSNS (1);

  /* ZBA provide zext.w.  */
  if (TARGET_ZBA && TARGET_64BIT && unsigned_p && GET_MODE (op) == SImode)
    return COSTS_N_INSNS (1);

  /* ZBB provide zext.h, sext.b and sext.h.  */
  if (TARGET_ZBB)
    {
      if (!unsigned_p && GET_MODE (op) == QImode)
	return COSTS_N_INSNS (1);

      if (GET_MODE (op) == HImode)
	return COSTS_N_INSNS (1);
    }

  if (!unsigned_p && GET_MODE (op) == SImode)
    /* We can use SEXT.W.  */
    return COSTS_N_INSNS (1);

  /* We need to use a shift left and a shift right.  */
  return COSTS_N_INSNS (2);
}

/* Implement TARGET_RTX_COSTS.  */

#define SINGLE_SHIFT_COST 1

static bool
riscv_rtx_costs (rtx x, machine_mode mode, int outer_code, int opno ATTRIBUTE_UNUSED,
		 int *total, bool speed)
{
  /* TODO: We set RVV instruction cost as 1 by default.
     Cost Model need to be well analyzed and supported in the future. */
  if (riscv_v_ext_vector_mode_p (mode))
    {
      *total = COSTS_N_INSNS (1);
      return true;
    }

  bool float_mode_p = FLOAT_MODE_P (mode);
  int cost;

  switch (GET_CODE (x))
    {
    case CONST_INT:
      if (riscv_immediate_operand_p (outer_code, INTVAL (x)))
	{
	  *total = 0;
	  return true;
	}
      /* Fall through.  */

    case SYMBOL_REF:
    case LABEL_REF:
    case CONST_DOUBLE:
      /* With TARGET_SUPPORTS_WIDE_INT const int can't be in CONST_DOUBLE
	 rtl object. Weird recheck due to switch-case fall through above.  */
      if (GET_CODE (x) == CONST_DOUBLE)
	gcc_assert (GET_MODE (x) != VOIDmode);
      /* Fall through.  */

    case CONST:
      if ((cost = riscv_const_insns (x)) > 0)
	{
	  /* If the constant is likely to be stored in a GPR, SETs of
	     single-insn constants are as cheap as register sets; we
	     never want to CSE them.  */
	  if (cost == 1 && outer_code == SET)
	    *total = 0;
	  /* When we load a constant more than once, it usually is better
	     to duplicate the last operation in the sequence than to CSE
	     the constant itself.  */
	  else if (outer_code == SET || GET_MODE (x) == VOIDmode)
	    *total = COSTS_N_INSNS (1);
	}
      else /* The instruction will be fetched from the constant pool.  */
	*total = COSTS_N_INSNS (riscv_symbol_insns (SYMBOL_ABSOLUTE));
      return true;

    case MEM:
      /* If the address is legitimate, return the number of
	 instructions it needs.  */
      if ((cost = riscv_address_insns (XEXP (x, 0), mode, true)) > 0)
	{
	  /* When optimizing for size, make uncompressible 32-bit addresses
	     more expensive so that compressible 32-bit addresses are
	     preferred.  */
	  if (TARGET_RVC && !speed && riscv_mshorten_memrefs && mode == SImode
	      && !riscv_compressed_lw_address_p (XEXP (x, 0)))
	    cost++;

	  *total = COSTS_N_INSNS (cost + tune_param->memory_cost);
	  return true;
	}
      /* Otherwise use the default handling.  */
      return false;

    case IF_THEN_ELSE:
      if (TARGET_SFB_ALU
	  && register_operand (XEXP (x, 1), mode)
	  && sfb_alu_operand (XEXP (x, 2), mode)
	  && comparison_operator (XEXP (x, 0), VOIDmode))
	{
	  /* For predicated conditional-move operations we assume the cost
	     of a single instruction even though there are actually two.  */
	  *total = COSTS_N_INSNS (1);
	  return true;
	}
      else if (LABEL_REF_P (XEXP (x, 1)) && XEXP (x, 2) == pc_rtx)
	{
	  if (equality_operator (XEXP (x, 0), mode)
	      && GET_CODE (XEXP (XEXP (x, 0), 0)) == ZERO_EXTRACT)
	    {
	      *total = COSTS_N_INSNS (SINGLE_SHIFT_COST + 1);
	      return true;
	    }
	  if (order_operator (XEXP (x, 0), mode))
	    {
	      *total = COSTS_N_INSNS (1);
	      return true;
	    }
	}
      return false;

    case NOT:
      *total = COSTS_N_INSNS (GET_MODE_SIZE (mode).to_constant () > UNITS_PER_WORD ? 2 : 1);
      return false;

    case AND:
      /* slli.uw pattern for zba.  */
      if (TARGET_ZBA && TARGET_64BIT && mode == DImode
	  && GET_CODE (XEXP (x, 0)) == ASHIFT)
	{
	  rtx and_rhs = XEXP (x, 1);
	  rtx ashift_lhs = XEXP (XEXP (x, 0), 0);
	  rtx ashift_rhs = XEXP (XEXP (x, 0), 1);
	  if (REG_P (ashift_lhs)
	      && CONST_INT_P (ashift_rhs)
	      && CONST_INT_P (and_rhs)
	      && ((INTVAL (and_rhs) >> INTVAL (ashift_rhs)) == 0xffffffff))
	    *total = COSTS_N_INSNS (1);
	    return true;
	}
      /* bclri pattern for zbs.  */
      if (TARGET_ZBS
	  && not_single_bit_mask_operand (XEXP (x, 1), VOIDmode))
	{
	  *total = COSTS_N_INSNS (1);
	  return true;
	}
      /* bclr pattern for zbs.  */
      if (TARGET_ZBS
	  && REG_P (XEXP (x, 1))
	  && GET_CODE (XEXP (x, 0)) == ROTATE
	  && CONST_INT_P (XEXP ((XEXP (x, 0)), 0))
	  && INTVAL (XEXP ((XEXP (x, 0)), 0)) == -2)
	{
	  *total = COSTS_N_INSNS (1);
	  return true;
	}

      gcc_fallthrough ();
    case IOR:
    case XOR:
      /* orn, andn and xorn pattern for zbb.  */
      if (TARGET_ZBB
	  && GET_CODE (XEXP (x, 0)) == NOT)
	{
	  *total = riscv_binary_cost (x, 1, 2);
	  return true;
	}

      /* bset[i] and binv[i] pattern for zbs.  */
      if ((GET_CODE (x) == IOR || GET_CODE (x) == XOR)
	  && TARGET_ZBS
	  && ((GET_CODE (XEXP (x, 0)) == ASHIFT
	      && CONST_INT_P (XEXP (XEXP (x, 0), 0)))
	      || single_bit_mask_operand (XEXP (x, 1), VOIDmode)))
	{
	  *total = COSTS_N_INSNS (1);
	  return true;
	}

      /* Double-word operations use two single-word operations.  */
      *total = riscv_binary_cost (x, 1, 2);
      return false;

    case ZERO_EXTRACT:
      /* This is an SImode shift.  */
      if (outer_code == SET
	  && CONST_INT_P (XEXP (x, 1))
	  && CONST_INT_P (XEXP (x, 2))
	  && (INTVAL (XEXP (x, 2)) > 0)
	  && (INTVAL (XEXP (x, 1)) + INTVAL (XEXP (x, 2)) == 32))
	{
	  *total = COSTS_N_INSNS (SINGLE_SHIFT_COST);
	  return true;
	}
      /* bext pattern for zbs.  */
      if (TARGET_ZBS && outer_code == SET
	  && GET_CODE (XEXP (x, 1)) == CONST_INT
	  && INTVAL (XEXP (x, 1)) == 1)
	{
	  *total = COSTS_N_INSNS (SINGLE_SHIFT_COST);
	  return true;
	}
      return false;

    case ASHIFT:
      /* bset pattern for zbs.  */
      if (TARGET_ZBS
	  && CONST_INT_P (XEXP (x, 0))
	  && INTVAL (XEXP (x, 0)) == 1)
	{
	  *total = COSTS_N_INSNS (1);
	  return true;
	}
      gcc_fallthrough ();
    case ASHIFTRT:
    case LSHIFTRT:
      *total = riscv_binary_cost (x, SINGLE_SHIFT_COST,
				  CONSTANT_P (XEXP (x, 1)) ? 4 : 9);
      return false;

    case ABS:
      *total = COSTS_N_INSNS (float_mode_p ? 1 : 3);
      return false;

    case LO_SUM:
      *total = set_src_cost (XEXP (x, 0), mode, speed);
      return true;

    case LT:
      /* This is an SImode shift.  */
      if (outer_code == SET && GET_MODE (x) == DImode
	  && GET_MODE (XEXP (x, 0)) == SImode)
	{
	  *total = COSTS_N_INSNS (SINGLE_SHIFT_COST);
	  return true;
	}
      /* Fall through.  */
    case LTU:
    case LE:
    case LEU:
    case GT:
    case GTU:
    case GE:
    case GEU:
    case EQ:
    case NE:
      /* Branch comparisons have VOIDmode, so use the first operand's
	 mode instead.  */
      mode = GET_MODE (XEXP (x, 0));
      if (float_mode_p)
	*total = tune_param->fp_add[mode == DFmode];
      else
	*total = riscv_binary_cost (x, 1, 3);
      return false;

    case UNORDERED:
    case ORDERED:
      /* (FEQ(A, A) & FEQ(B, B)) compared against 0.  */
      mode = GET_MODE (XEXP (x, 0));
      *total = tune_param->fp_add[mode == DFmode] + COSTS_N_INSNS (2);
      return false;

    case UNEQ:
      /* (FEQ(A, A) & FEQ(B, B)) compared against FEQ(A, B).  */
      mode = GET_MODE (XEXP (x, 0));
      *total = tune_param->fp_add[mode == DFmode] + COSTS_N_INSNS (3);
      return false;

    case LTGT:
      /* (FLT(A, A) || FGT(B, B)).  */
      mode = GET_MODE (XEXP (x, 0));
      *total = tune_param->fp_add[mode == DFmode] + COSTS_N_INSNS (2);
      return false;

    case UNGE:
    case UNGT:
    case UNLE:
    case UNLT:
      /* FLT or FLE, but guarded by an FFLAGS read and write.  */
      mode = GET_MODE (XEXP (x, 0));
      *total = tune_param->fp_add[mode == DFmode] + COSTS_N_INSNS (4);
      return false;

    case MINUS:
      if (float_mode_p)
	*total = tune_param->fp_add[mode == DFmode];
      else
	*total = riscv_binary_cost (x, 1, 4);
      return false;

    case PLUS:
      /* add.uw pattern for zba.  */
      if (TARGET_ZBA
	  && (TARGET_64BIT && (mode == DImode))
	  && GET_CODE (XEXP (x, 0)) == ZERO_EXTEND
	  && REG_P (XEXP (XEXP (x, 0), 0))
	  && GET_MODE (XEXP (XEXP (x, 0), 0)) == SImode)
	{
	  *total = COSTS_N_INSNS (1);
	  return true;
	}
      /* shNadd pattern for zba.  */
      if (TARGET_ZBA
	  && ((!TARGET_64BIT && (mode == SImode)) ||
	      (TARGET_64BIT && (mode == DImode)))
	  && (GET_CODE (XEXP (x, 0)) == ASHIFT)
	  && REG_P (XEXP (XEXP (x, 0), 0))
	  && CONST_INT_P (XEXP (XEXP (x, 0), 1))
	  && IN_RANGE (INTVAL (XEXP (XEXP (x, 0), 1)), 1, 3))
	{
	  *total = COSTS_N_INSNS (1);
	  return true;
	}
      /* Before strength-reduction, the shNadd can be expressed as the addition
	 of a multiplication with a power-of-two.  If this case is not handled,
	 the strength-reduction in expmed.c will calculate an inflated cost. */
      if (TARGET_ZBA
	  && mode == word_mode
	  && GET_CODE (XEXP (x, 0)) == MULT
	  && REG_P (XEXP (XEXP (x, 0), 0))
	  && CONST_INT_P (XEXP (XEXP (x, 0), 1))
	  && IN_RANGE (pow2p_hwi (INTVAL (XEXP (XEXP (x, 0), 1))), 1, 3))
	{
	  *total = COSTS_N_INSNS (1);
	  return true;
	}
      /* shNadd.uw pattern for zba.
	 [(set (match_operand:DI 0 "register_operand" "=r")
	       (plus:DI
		 (and:DI (ashift:DI (match_operand:DI 1 "register_operand" "r")
				    (match_operand:QI 2 "immediate_operand" "I"))
			 (match_operand 3 "immediate_operand" ""))
		 (match_operand:DI 4 "register_operand" "r")))]
	 "TARGET_64BIT && TARGET_ZBA
	  && (INTVAL (operands[2]) >= 1) && (INTVAL (operands[2]) <= 3)
	  && (INTVAL (operands[3]) >> INTVAL (operands[2])) == 0xffffffff"
      */
      if (TARGET_ZBA
	  && (TARGET_64BIT && (mode == DImode))
	  && (GET_CODE (XEXP (x, 0)) == AND)
	  && (REG_P (XEXP (x, 1))))
	{
	  do {
	    rtx and_lhs = XEXP (XEXP (x, 0), 0);
	    rtx and_rhs = XEXP (XEXP (x, 0), 1);
	    if (GET_CODE (and_lhs) != ASHIFT)
	      break;
	    if (!CONST_INT_P (and_rhs))
	      break;

	    rtx ashift_rhs = XEXP (and_lhs, 1);

	    if (!CONST_INT_P (ashift_rhs)
		|| !IN_RANGE (INTVAL (ashift_rhs), 1, 3))
	      break;

	    if (CONST_INT_P (and_rhs)
		&& ((INTVAL (and_rhs) >> INTVAL (ashift_rhs)) == 0xffffffff))
	      {
		*total = COSTS_N_INSNS (1);
		return true;
	      }
	  } while (false);
	}

      if (float_mode_p)
	*total = tune_param->fp_add[mode == DFmode];
      else
	*total = riscv_binary_cost (x, 1, 4);
      return false;

    case NEG:
      {
	rtx op = XEXP (x, 0);
	if (GET_CODE (op) == FMA && !HONOR_SIGNED_ZEROS (mode))
	  {
	    *total = (tune_param->fp_mul[mode == DFmode]
		      + set_src_cost (XEXP (op, 0), mode, speed)
		      + set_src_cost (XEXP (op, 1), mode, speed)
		      + set_src_cost (XEXP (op, 2), mode, speed));
	    return true;
	  }
      }

      if (float_mode_p)
	*total = tune_param->fp_add[mode == DFmode];
      else
	*total = COSTS_N_INSNS (GET_MODE_SIZE (mode).to_constant () > UNITS_PER_WORD ? 4 : 1);
      return false;

    case MULT:
      if (float_mode_p)
	*total = tune_param->fp_mul[mode == DFmode];
      else if (!TARGET_MUL)
	/* Estimate the cost of a library call.  */
	*total = COSTS_N_INSNS (speed ? 32 : 6);
      else if (GET_MODE_SIZE (mode).to_constant () > UNITS_PER_WORD)
	*total = 3 * tune_param->int_mul[0] + COSTS_N_INSNS (2);
      else if (!speed)
	*total = COSTS_N_INSNS (1);
      else
	*total = tune_param->int_mul[mode == DImode];
      return false;

    case DIV:
    case SQRT:
    case MOD:
      if (float_mode_p)
	{
	  *total = tune_param->fp_div[mode == DFmode];
	  return false;
	}
      /* Fall through.  */

    case UDIV:
    case UMOD:
      if (!TARGET_DIV)
	/* Estimate the cost of a library call.  */
	*total = COSTS_N_INSNS (speed ? 32 : 6);
      else if (speed)
	*total = tune_param->int_div[mode == DImode];
      else
	*total = COSTS_N_INSNS (1);
      return false;

    case ZERO_EXTEND:
      /* This is an SImode shift.  */
      if (GET_CODE (XEXP (x, 0)) == LSHIFTRT)
	{
	  *total = COSTS_N_INSNS (SINGLE_SHIFT_COST);
	  return true;
	}
      /* Fall through.  */
    case SIGN_EXTEND:
      *total = riscv_extend_cost (XEXP (x, 0), GET_CODE (x) == ZERO_EXTEND);
      return false;

    case BSWAP:
      if (TARGET_ZBB)
	{
	  /* RISC-V only defines rev8 for XLEN, so we will need an extra
	     shift-right instruction for smaller modes. */
	  *total = COSTS_N_INSNS (mode == word_mode ? 1 : 2);
	  return true;
	}
      return false;

    case FLOAT:
    case UNSIGNED_FLOAT:
    case FIX:
    case FLOAT_EXTEND:
    case FLOAT_TRUNCATE:
      *total = tune_param->fp_add[mode == DFmode];
      return false;

    case FMA:
      *total = (tune_param->fp_mul[mode == DFmode]
		+ set_src_cost (XEXP (x, 0), mode, speed)
		+ set_src_cost (XEXP (x, 1), mode, speed)
		+ set_src_cost (XEXP (x, 2), mode, speed));
      return true;

    case UNSPEC:
      if (XINT (x, 1) == UNSPEC_AUIPC)
	{
	  /* Make AUIPC cheap to avoid spilling its result to the stack.  */
	  *total = 1;
	  return true;
	}
      return false;

    default:
      return false;
    }
}

/* Implement TARGET_ADDRESS_COST.  */

static int
riscv_address_cost (rtx addr, machine_mode mode,
		    addr_space_t as ATTRIBUTE_UNUSED,
		    bool speed ATTRIBUTE_UNUSED)
{
  /* When optimizing for size, make uncompressible 32-bit addresses more
   * expensive so that compressible 32-bit addresses are preferred.  */
  if (TARGET_RVC && !speed && riscv_mshorten_memrefs && mode == SImode
      && !riscv_compressed_lw_address_p (addr))
    return riscv_address_insns (addr, mode, false) + 1;
  return riscv_address_insns (addr, mode, false);
}

/* Return one word of double-word value OP.  HIGH_P is true to select the
   high part or false to select the low part. */

rtx
riscv_subword (rtx op, bool high_p)
{
  unsigned int byte = (high_p != BYTES_BIG_ENDIAN) ? UNITS_PER_WORD : 0;
  machine_mode mode = GET_MODE (op);

  if (mode == VOIDmode)
    mode = TARGET_64BIT ? TImode : DImode;

  if (MEM_P (op))
    return adjust_address (op, word_mode, byte);

  if (REG_P (op))
    gcc_assert (!FP_REG_RTX_P (op));

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

/* Return true if a 64-bit move from SRC to DEST should be split into two.  */

bool
riscv_split_64bit_move_p (rtx dest, rtx src)
{
  if (TARGET_64BIT)
    return false;

  /* Allow FPR <-> FPR and FPR <-> MEM moves, and permit the special case
     of zeroing an FPR with FCVT.D.W.  */
  if (TARGET_DOUBLE_FLOAT
      && ((FP_REG_RTX_P (src) && FP_REG_RTX_P (dest))
	  || (FP_REG_RTX_P (dest) && MEM_P (src))
	  || (FP_REG_RTX_P (src) && MEM_P (dest))
	  || (FP_REG_RTX_P (dest) && src == CONST0_RTX (GET_MODE (src)))))
    return false;

  return true;
}

/* Split a doubleword move from SRC to DEST.  On 32-bit targets,
   this function handles 64-bit moves for which riscv_split_64bit_move_p
   holds.  For 64-bit targets, this function handles 128-bit moves.  */

void
riscv_split_doubleword_move (rtx dest, rtx src)
{
  rtx low_dest;

   /* The operation can be split into two normal moves.  Decide in
      which order to do them.  */
   low_dest = riscv_subword (dest, false);
   if (REG_P (low_dest) && reg_overlap_mentioned_p (low_dest, src))
     {
       riscv_emit_move (riscv_subword (dest, true), riscv_subword (src, true));
       riscv_emit_move (low_dest, riscv_subword (src, false));
     }
   else
     {
       riscv_emit_move (low_dest, riscv_subword (src, false));
       riscv_emit_move (riscv_subword (dest, true), riscv_subword (src, true));
     }
}

/* Return the appropriate instructions to move SRC into DEST.  Assume
   that SRC is operand 1 and DEST is operand 0.  */

const char *
riscv_output_move (rtx dest, rtx src)
{
  enum rtx_code dest_code, src_code;
  machine_mode mode;
  bool dbl_p;
  unsigned width;

  dest_code = GET_CODE (dest);
  src_code = GET_CODE (src);
  mode = GET_MODE (dest);
  dbl_p = (GET_MODE_SIZE (mode).to_constant () == 8);
  width = GET_MODE_SIZE (mode).to_constant ();

  if (dbl_p && riscv_split_64bit_move_p (dest, src))
    return "#";

  if (dest_code == REG && GP_REG_P (REGNO (dest)))
    {
      if (src_code == REG && FP_REG_P (REGNO (src)))
	switch (width)
	  {
	  case 2:
	    if (TARGET_ZFHMIN)
	      return "fmv.x.h\t%0,%1";
	    /* Using fmv.x.s + sign-extend to emulate fmv.x.h.  */
	    return "fmv.x.s\t%0,%1;slli\t%0,%0,16;srai\t%0,%0,16";
	  case 4:
	    return "fmv.x.s\t%0,%1";
	  case 8:
	    return "fmv.x.d\t%0,%1";
	  }

      if (src_code == MEM)
	switch (width)
	  {
	  case 1: return "lbu\t%0,%1";
	  case 2: return "lhu\t%0,%1";
	  case 4: return "lw\t%0,%1";
	  case 8: return "ld\t%0,%1";
	  }

      if (src_code == CONST_INT)
	{
	  if (SMALL_OPERAND (INTVAL (src)) || LUI_OPERAND (INTVAL (src)))
	    return "li\t%0,%1";

	  if (TARGET_ZBS
	      && SINGLE_BIT_MASK_OPERAND (INTVAL (src)))
	    return "bseti\t%0,zero,%S1";

	  /* Should never reach here.  */
	  abort ();
	}

      if (src_code == HIGH)
	return "lui\t%0,%h1";

      if (symbolic_operand (src, VOIDmode))
	switch (riscv_classify_symbolic_expression (src))
	  {
	  case SYMBOL_GOT_DISP: return "la\t%0,%1";
	  case SYMBOL_ABSOLUTE: return "lla\t%0,%1";
	  case SYMBOL_PCREL: return "lla\t%0,%1";
	  default: gcc_unreachable ();
	  }
    }
  if ((src_code == REG && GP_REG_P (REGNO (src)))
      || (src == CONST0_RTX (mode)))
    {
      if (dest_code == REG)
	{
	  if (GP_REG_P (REGNO (dest)))
	    return "mv\t%0,%z1";

	  if (FP_REG_P (REGNO (dest)))
	    switch (width)
	      {
	      case 2:
		if (TARGET_ZFHMIN)
		  return "fmv.h.x\t%0,%z1";
		/* High 16 bits should be all-1, otherwise HW will treated
		   as a n-bit canonical NaN, but isn't matter for softfloat.  */
		return "fmv.s.x\t%0,%1";
	      case 4:
		return "fmv.s.x\t%0,%z1";
	      case 8:
		if (TARGET_64BIT)
		  return "fmv.d.x\t%0,%z1";
		/* in RV32, we can emulate fmv.d.x %0, x0 using fcvt.d.w */
		gcc_assert (src == CONST0_RTX (mode));
		return "fcvt.d.w\t%0,x0";
	      }
	}
      if (dest_code == MEM)
	switch (width)
	  {
	  case 1: return "sb\t%z1,%0";
	  case 2: return "sh\t%z1,%0";
	  case 4: return "sw\t%z1,%0";
	  case 8: return "sd\t%z1,%0";
	  }
    }
  if (src_code == REG && FP_REG_P (REGNO (src)))
    {
      if (dest_code == REG && FP_REG_P (REGNO (dest)))
	switch (width)
	  {
	  case 2:
	    if (TARGET_ZFH)
	      return "fmv.h\t%0,%1";
	    return "fmv.s\t%0,%1";
	  case 4:
	    return "fmv.s\t%0,%1";
	  case 8:
	    return "fmv.d\t%0,%1";
	  }

      if (dest_code == MEM)
	switch (width)
	  {
	  case 2:
	    return "fsh\t%1,%0";
	  case 4:
	    return "fsw\t%1,%0";
	  case 8:
	    return "fsd\t%1,%0";
	  }
    }
  if (dest_code == REG && FP_REG_P (REGNO (dest)))
    {
      if (src_code == MEM)
	switch (width)
	  {
	  case 2:
	    return "flh\t%0,%1";
	  case 4:
	    return "flw\t%0,%1";
	  case 8:
	    return "fld\t%0,%1";
	  }
    }
  if (dest_code == REG && GP_REG_P (REGNO (dest)) && src_code == CONST_POLY_INT)
    {
      /* We only want a single full vector register VLEN read after reload. */
      gcc_assert (known_eq (rtx_to_poly_int64 (src), BYTES_PER_RISCV_VECTOR));
      return "csrr\t%0,vlenb";
    }
  gcc_unreachable ();
}

const char *
riscv_output_return ()
{
  if (cfun->machine->naked_p)
    return "";

  return "ret";
}


/* Return true if CMP1 is a suitable second operand for integer ordering
   test CODE.  See also the *sCC patterns in riscv.md.  */

static bool
riscv_int_order_operand_ok_p (enum rtx_code code, rtx cmp1)
{
  switch (code)
    {
    case GT:
    case GTU:
      return reg_or_0_operand (cmp1, VOIDmode);

    case GE:
    case GEU:
      return cmp1 == const1_rtx;

    case LT:
    case LTU:
      return arith_operand (cmp1, VOIDmode);

    case LE:
      return sle_operand (cmp1, VOIDmode);

    case LEU:
      return sleu_operand (cmp1, VOIDmode);

    default:
      gcc_unreachable ();
    }
}

/* Return true if *CMP1 (of mode MODE) is a valid second operand for
   integer ordering test *CODE, or if an equivalent combination can
   be formed by adjusting *CODE and *CMP1.  When returning true, update
   *CODE and *CMP1 with the chosen code and operand, otherwise leave
   them alone.  */

static bool
riscv_canonicalize_int_order_test (enum rtx_code *code, rtx *cmp1,
				   machine_mode mode)
{
  HOST_WIDE_INT plus_one;

  if (riscv_int_order_operand_ok_p (*code, *cmp1))
    return true;

  if (CONST_INT_P (*cmp1))
    switch (*code)
      {
      case LE:
	plus_one = trunc_int_for_mode (UINTVAL (*cmp1) + 1, mode);
	if (INTVAL (*cmp1) < plus_one)
	  {
	    *code = LT;
	    *cmp1 = force_reg (mode, GEN_INT (plus_one));
	    return true;
	  }
	break;

      case LEU:
	plus_one = trunc_int_for_mode (UINTVAL (*cmp1) + 1, mode);
	if (plus_one != 0)
	  {
	    *code = LTU;
	    *cmp1 = force_reg (mode, GEN_INT (plus_one));
	    return true;
	  }
	break;

      default:
	break;
      }
  return false;
}

/* Compare CMP0 and CMP1 using ordering test CODE and store the result
   in TARGET.  CMP0 and TARGET are register_operands.  If INVERT_PTR
   is nonnull, it's OK to set TARGET to the inverse of the result and
   flip *INVERT_PTR instead.  */

static void
riscv_emit_int_order_test (enum rtx_code code, bool *invert_ptr,
			  rtx target, rtx cmp0, rtx cmp1)
{
  machine_mode mode;

  /* First see if there is a RISCV instruction that can do this operation.
     If not, try doing the same for the inverse operation.  If that also
     fails, force CMP1 into a register and try again.  */
  mode = GET_MODE (cmp0);
  if (riscv_canonicalize_int_order_test (&code, &cmp1, mode))
    riscv_emit_binary (code, target, cmp0, cmp1);
  else
    {
      enum rtx_code inv_code = reverse_condition (code);
      if (!riscv_canonicalize_int_order_test (&inv_code, &cmp1, mode))
	{
	  cmp1 = force_reg (mode, cmp1);
	  riscv_emit_int_order_test (code, invert_ptr, target, cmp0, cmp1);
	}
      else if (invert_ptr == 0)
	{
	  rtx inv_target = riscv_force_binary (GET_MODE (target),
					       inv_code, cmp0, cmp1);
	  riscv_emit_binary (XOR, target, inv_target, const1_rtx);
	}
      else
	{
	  *invert_ptr = !*invert_ptr;
	  riscv_emit_binary (inv_code, target, cmp0, cmp1);
	}
    }
}

/* Return a register that is zero iff CMP0 and CMP1 are equal.
   The register will have the same mode as CMP0.  */

static rtx
riscv_zero_if_equal (rtx cmp0, rtx cmp1)
{
  if (cmp1 == const0_rtx)
    return cmp0;

  return expand_binop (GET_MODE (cmp0), sub_optab,
		       cmp0, cmp1, 0, 0, OPTAB_DIRECT);
}

/* Sign- or zero-extend OP0 and OP1 for integer comparisons.  */

static void
riscv_extend_comparands (rtx_code code, rtx *op0, rtx *op1)
{
  /* Comparisons consider all XLEN bits, so extend sub-XLEN values.  */
  if (GET_MODE_SIZE (word_mode) > GET_MODE_SIZE (GET_MODE (*op0)).to_constant ())
    {
      /* It is more profitable to zero-extend QImode values.  But not if the
	 first operand has already been sign-extended, and the second one is
	 is a constant or has already been sign-extended also.  */
      if (unsigned_condition (code) == code
	  && (GET_MODE (*op0) == QImode
	      && ! (GET_CODE (*op0) == SUBREG
		    && SUBREG_PROMOTED_VAR_P (*op0)
		    && SUBREG_PROMOTED_SIGNED_P (*op0)
		    && (CONST_INT_P (*op1)
			|| (GET_CODE (*op1) == SUBREG
			    && SUBREG_PROMOTED_VAR_P (*op1)
			    && SUBREG_PROMOTED_SIGNED_P (*op1))))))
	{
	  *op0 = gen_rtx_ZERO_EXTEND (word_mode, *op0);
	  if (CONST_INT_P (*op1))
	    *op1 = GEN_INT ((uint8_t) INTVAL (*op1));
	  else
	    *op1 = gen_rtx_ZERO_EXTEND (word_mode, *op1);
	}
      else
	{
	  *op0 = gen_rtx_SIGN_EXTEND (word_mode, *op0);
	  if (*op1 != const0_rtx)
	    *op1 = gen_rtx_SIGN_EXTEND (word_mode, *op1);
	}
    }
}

/* Convert a comparison into something that can be used in a branch.  On
   entry, *OP0 and *OP1 are the values being compared and *CODE is the code
   used to compare them.  Update them to describe the final comparison.  */

static void
riscv_emit_int_compare (enum rtx_code *code, rtx *op0, rtx *op1)
{
  if (splittable_const_int_operand (*op1, VOIDmode))
    {
      HOST_WIDE_INT rhs = INTVAL (*op1);

      if (*code == EQ || *code == NE)
	{
	  /* Convert e.g. OP0 == 2048 into OP0 - 2048 == 0.  */
	  if (SMALL_OPERAND (-rhs))
	    {
	      *op0 = riscv_force_binary (GET_MODE (*op0), PLUS, *op0,
					 GEN_INT (-rhs));
	      *op1 = const0_rtx;
	    }
	}
      else
	{
	  static const enum rtx_code mag_comparisons[][2] = {
	    {LEU, LTU}, {GTU, GEU}, {LE, LT}, {GT, GE}
	  };

	  /* Convert e.g. (OP0 <= 0xFFF) into (OP0 < 0x1000).  */
	  for (size_t i = 0; i < ARRAY_SIZE (mag_comparisons); i++)
	    {
	      HOST_WIDE_INT new_rhs;
	      bool increment = *code == mag_comparisons[i][0];
	      bool decrement = *code == mag_comparisons[i][1];
	      if (!increment && !decrement)
		continue;

	      new_rhs = rhs + (increment ? 1 : -1);
	      new_rhs = trunc_int_for_mode (new_rhs, GET_MODE (*op0));
	      if (riscv_integer_cost (new_rhs) < riscv_integer_cost (rhs)
		  && (rhs < 0) == (new_rhs < 0))
		{
		  *op1 = GEN_INT (new_rhs);
		  *code = mag_comparisons[i][increment];
		}
	      break;
	    }
	}
    }

  riscv_extend_comparands (*code, op0, op1);

  *op0 = force_reg (word_mode, *op0);
  if (*op1 != const0_rtx)
    *op1 = force_reg (word_mode, *op1);
}

/* Like riscv_emit_int_compare, but for floating-point comparisons.  */

static void
riscv_emit_float_compare (enum rtx_code *code, rtx *op0, rtx *op1)
{
  rtx tmp0, tmp1, cmp_op0 = *op0, cmp_op1 = *op1;
  enum rtx_code fp_code = *code;
  *code = NE;

  switch (fp_code)
    {
    case UNORDERED:
      *code = EQ;
      /* Fall through.  */

    case ORDERED:
      /* a == a && b == b */
      tmp0 = riscv_force_binary (word_mode, EQ, cmp_op0, cmp_op0);
      tmp1 = riscv_force_binary (word_mode, EQ, cmp_op1, cmp_op1);
      *op0 = riscv_force_binary (word_mode, AND, tmp0, tmp1);
      *op1 = const0_rtx;
      break;

    case UNEQ:
      /* ordered(a, b) > (a == b) */
      *code = EQ;
      tmp0 = riscv_force_binary (word_mode, EQ, cmp_op0, cmp_op0);
      tmp1 = riscv_force_binary (word_mode, EQ, cmp_op1, cmp_op1);
      *op0 = riscv_force_binary (word_mode, AND, tmp0, tmp1);
      *op1 = riscv_force_binary (word_mode, EQ, cmp_op0, cmp_op1);
      break;

#define UNORDERED_COMPARISON(CODE, CMP)					\
    case CODE:								\
      *code = EQ;							\
      *op0 = gen_reg_rtx (word_mode);					\
      if (GET_MODE (cmp_op0) == SFmode && TARGET_64BIT)			\
	emit_insn (gen_f##CMP##_quietsfdi4 (*op0, cmp_op0, cmp_op1));	\
      else if (GET_MODE (cmp_op0) == SFmode)				\
	emit_insn (gen_f##CMP##_quietsfsi4 (*op0, cmp_op0, cmp_op1));	\
      else if (GET_MODE (cmp_op0) == DFmode && TARGET_64BIT)		\
	emit_insn (gen_f##CMP##_quietdfdi4 (*op0, cmp_op0, cmp_op1));	\
      else if (GET_MODE (cmp_op0) == DFmode)				\
	emit_insn (gen_f##CMP##_quietdfsi4 (*op0, cmp_op0, cmp_op1));	\
      else if (GET_MODE (cmp_op0) == HFmode && TARGET_64BIT)		\
	emit_insn (gen_f##CMP##_quiethfdi4 (*op0, cmp_op0, cmp_op1));	\
      else if (GET_MODE (cmp_op0) == HFmode)				\
	emit_insn (gen_f##CMP##_quiethfsi4 (*op0, cmp_op0, cmp_op1));	\
      else								\
	gcc_unreachable ();						\
      *op1 = const0_rtx;						\
      break;

    case UNLT:
      std::swap (cmp_op0, cmp_op1);
      gcc_fallthrough ();

    UNORDERED_COMPARISON(UNGT, le)

    case UNLE:
      std::swap (cmp_op0, cmp_op1);
      gcc_fallthrough ();

    UNORDERED_COMPARISON(UNGE, lt)
#undef UNORDERED_COMPARISON

    case NE:
      fp_code = EQ;
      *code = EQ;
      /* Fall through.  */

    case EQ:
    case LE:
    case LT:
    case GE:
    case GT:
      /* We have instructions for these cases.  */
      *op0 = riscv_force_binary (word_mode, fp_code, cmp_op0, cmp_op1);
      *op1 = const0_rtx;
      break;

    case LTGT:
      /* (a < b) | (a > b) */
      tmp0 = riscv_force_binary (word_mode, LT, cmp_op0, cmp_op1);
      tmp1 = riscv_force_binary (word_mode, GT, cmp_op0, cmp_op1);
      *op0 = riscv_force_binary (word_mode, IOR, tmp0, tmp1);
      *op1 = const0_rtx;
      break;

    default:
      gcc_unreachable ();
    }
}

/* CODE-compare OP0 and OP1.  Store the result in TARGET.  */

void
riscv_expand_int_scc (rtx target, enum rtx_code code, rtx op0, rtx op1)
{
  riscv_extend_comparands (code, &op0, &op1);
  op0 = force_reg (word_mode, op0);

  if (code == EQ || code == NE)
    {
      rtx zie = riscv_zero_if_equal (op0, op1);
      riscv_emit_binary (code, target, zie, const0_rtx);
    }
  else
    riscv_emit_int_order_test (code, 0, target, op0, op1);
}

/* Like riscv_expand_int_scc, but for floating-point comparisons.  */

void
riscv_expand_float_scc (rtx target, enum rtx_code code, rtx op0, rtx op1)
{
  riscv_emit_float_compare (&code, &op0, &op1);

  rtx cmp = riscv_force_binary (word_mode, code, op0, op1);
  riscv_emit_set (target, lowpart_subreg (SImode, cmp, word_mode));
}

/* Jump to LABEL if (CODE OP0 OP1) holds.  */

void
riscv_expand_conditional_branch (rtx label, rtx_code code, rtx op0, rtx op1)
{
  if (FLOAT_MODE_P (GET_MODE (op1)))
    riscv_emit_float_compare (&code, &op0, &op1);
  else
    riscv_emit_int_compare (&code, &op0, &op1);

  rtx condition = gen_rtx_fmt_ee (code, VOIDmode, op0, op1);
  emit_jump_insn (gen_condjump (condition, label));
}

/* If (CODE OP0 OP1) holds, move CONS to DEST; else move ALT to DEST.  */

void
riscv_expand_conditional_move (rtx dest, rtx cons, rtx alt, rtx_code code,
			       rtx op0, rtx op1)
{
  riscv_emit_int_compare (&code, &op0, &op1);
  rtx cond = gen_rtx_fmt_ee (code, GET_MODE (op0), op0, op1);
  emit_insn (gen_rtx_SET (dest, gen_rtx_IF_THEN_ELSE (GET_MODE (dest), cond,
						      cons, alt)));
}

/* Implement TARGET_FUNCTION_ARG_BOUNDARY.  Every parameter gets at
   least PARM_BOUNDARY bits of alignment, but will be given anything up
   to PREFERRED_STACK_BOUNDARY bits if the type requires it.  */

static unsigned int
riscv_function_arg_boundary (machine_mode mode, const_tree type)
{
  unsigned int alignment;

  /* Use natural alignment if the type is not aggregate data.  */
  if (type && !AGGREGATE_TYPE_P (type))
    alignment = TYPE_ALIGN (TYPE_MAIN_VARIANT (type));
  else
    alignment = type ? TYPE_ALIGN (type) : GET_MODE_ALIGNMENT (mode);

  return MIN (PREFERRED_STACK_BOUNDARY, MAX (PARM_BOUNDARY, alignment));
}

/* If MODE represents an argument that can be passed or returned in
   floating-point registers, return the number of registers, else 0.  */

static unsigned
riscv_pass_mode_in_fpr_p (machine_mode mode)
{
  if (GET_MODE_UNIT_SIZE (mode) <= UNITS_PER_FP_ARG)
    {
      if (GET_MODE_CLASS (mode) == MODE_FLOAT)
	return 1;

      if (GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT)
	return 2;
    }

  return 0;
}

typedef struct {
  const_tree type;
  HOST_WIDE_INT offset;
} riscv_aggregate_field;

/* Identify subfields of aggregates that are candidates for passing in
   floating-point registers.  */

static int
riscv_flatten_aggregate_field (const_tree type,
			       riscv_aggregate_field fields[2],
			       int n, HOST_WIDE_INT offset,
			       bool ignore_zero_width_bit_field_p)
{
  switch (TREE_CODE (type))
    {
    case RECORD_TYPE:
     /* Can't handle incomplete types nor sizes that are not fixed.  */
     if (!COMPLETE_TYPE_P (type)
	 || TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST
	 || !tree_fits_uhwi_p (TYPE_SIZE (type)))
       return -1;

      for (tree f = TYPE_FIELDS (type); f; f = DECL_CHAIN (f))
	if (TREE_CODE (f) == FIELD_DECL)
	  {
	    if (!TYPE_P (TREE_TYPE (f)))
	      return -1;

	    /* The C++ front end strips zero-length bit-fields from structs.
	       So we need to ignore them in the C front end to make C code
	       compatible with C++ code.  */
	    if (ignore_zero_width_bit_field_p
		&& DECL_BIT_FIELD (f)
		&& (DECL_SIZE (f) == NULL_TREE
		    || integer_zerop (DECL_SIZE (f))))
	      ;
	    else
	      {
		HOST_WIDE_INT pos = offset + int_byte_position (f);
		n = riscv_flatten_aggregate_field (TREE_TYPE (f),
						   fields, n, pos,
						   ignore_zero_width_bit_field_p);
	      }
	    if (n < 0)
	      return -1;
	  }
      return n;

    case ARRAY_TYPE:
      {
	HOST_WIDE_INT n_elts;
	riscv_aggregate_field subfields[2];
	tree index = TYPE_DOMAIN (type);
	tree elt_size = TYPE_SIZE_UNIT (TREE_TYPE (type));
	int n_subfields = riscv_flatten_aggregate_field (TREE_TYPE (type),
							 subfields, 0, offset,
							 ignore_zero_width_bit_field_p);

	/* Can't handle incomplete types nor sizes that are not fixed.  */
	if (n_subfields <= 0
	    || !COMPLETE_TYPE_P (type)
	    || TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST
	    || !index
	    || !TYPE_MAX_VALUE (index)
	    || !tree_fits_uhwi_p (TYPE_MAX_VALUE (index))
	    || !TYPE_MIN_VALUE (index)
	    || !tree_fits_uhwi_p (TYPE_MIN_VALUE (index))
	    || !tree_fits_uhwi_p (elt_size))
	  return -1;

	n_elts = 1 + tree_to_uhwi (TYPE_MAX_VALUE (index))
		   - tree_to_uhwi (TYPE_MIN_VALUE (index));
	gcc_assert (n_elts >= 0);

	for (HOST_WIDE_INT i = 0; i < n_elts; i++)
	  for (int j = 0; j < n_subfields; j++)
	    {
	      if (n >= 2)
		return -1;

	      fields[n] = subfields[j];
	      fields[n++].offset += i * tree_to_uhwi (elt_size);
	    }

	return n;
      }

    case COMPLEX_TYPE:
      {
	/* Complex type need consume 2 field, so n must be 0.  */
	if (n != 0)
	  return -1;

	HOST_WIDE_INT elt_size = GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (type))).to_constant ();

	if (elt_size <= UNITS_PER_FP_ARG)
	  {
	    fields[0].type = TREE_TYPE (type);
	    fields[0].offset = offset;
	    fields[1].type = TREE_TYPE (type);
	    fields[1].offset = offset + elt_size;

	    return 2;
	  }

	return -1;
      }

    default:
      if (n < 2
	  && ((SCALAR_FLOAT_TYPE_P (type)
	       && GET_MODE_SIZE (TYPE_MODE (type)).to_constant () <= UNITS_PER_FP_ARG)
	      || (INTEGRAL_TYPE_P (type)
		  && GET_MODE_SIZE (TYPE_MODE (type)).to_constant () <= UNITS_PER_WORD)))
	{
	  fields[n].type = type;
	  fields[n].offset = offset;
	  return n + 1;
	}
      else
	return -1;
    }
}

/* Identify candidate aggregates for passing in floating-point registers.
   Candidates have at most two fields after flattening.  */

static int
riscv_flatten_aggregate_argument (const_tree type,
				  riscv_aggregate_field fields[2],
				  bool ignore_zero_width_bit_field_p)
{
  if (!type || TREE_CODE (type) != RECORD_TYPE)
    return -1;

  return riscv_flatten_aggregate_field (type, fields, 0, 0,
					ignore_zero_width_bit_field_p);
}

/* See whether TYPE is a record whose fields should be returned in one or
   two floating-point registers.  If so, populate FIELDS accordingly.  */

static unsigned
riscv_pass_aggregate_in_fpr_pair_p (const_tree type,
				    riscv_aggregate_field fields[2])
{
  static int warned = 0;

  /* This is the old ABI, which differs for C++ and C.  */
  int n_old = riscv_flatten_aggregate_argument (type, fields, false);
  for (int i = 0; i < n_old; i++)
    if (!SCALAR_FLOAT_TYPE_P (fields[i].type))
      {
	n_old = -1;
	break;
      }

  /* This is the new ABI, which is the same for C++ and C.  */
  int n_new = riscv_flatten_aggregate_argument (type, fields, true);
  for (int i = 0; i < n_new; i++)
    if (!SCALAR_FLOAT_TYPE_P (fields[i].type))
      {
	n_new = -1;
	break;
      }

  if ((n_old != n_new) && (warned == 0))
    {
      warning (OPT_Wpsabi, "ABI for flattened struct with zero-length "
			   "bit-fields changed in GCC 10");
      warned = 1;
    }

  return n_new > 0 ? n_new : 0;
}

/* See whether TYPE is a record whose fields should be returned in one or
   floating-point register and one integer register.  If so, populate
   FIELDS accordingly.  */

static bool
riscv_pass_aggregate_in_fpr_and_gpr_p (const_tree type,
				       riscv_aggregate_field fields[2])
{
  static int warned = 0;

  /* This is the old ABI, which differs for C++ and C.  */
  unsigned num_int_old = 0, num_float_old = 0;
  int n_old = riscv_flatten_aggregate_argument (type, fields, false);
  for (int i = 0; i < n_old; i++)
    {
      num_float_old += SCALAR_FLOAT_TYPE_P (fields[i].type);
      num_int_old += INTEGRAL_TYPE_P (fields[i].type);
    }

  /* This is the new ABI, which is the same for C++ and C.  */
  unsigned num_int_new = 0, num_float_new = 0;
  int n_new = riscv_flatten_aggregate_argument (type, fields, true);
  for (int i = 0; i < n_new; i++)
    {
      num_float_new += SCALAR_FLOAT_TYPE_P (fields[i].type);
      num_int_new += INTEGRAL_TYPE_P (fields[i].type);
    }

  if (((num_int_old == 1 && num_float_old == 1
	&& (num_int_old != num_int_new || num_float_old != num_float_new))
       || (num_int_new == 1 && num_float_new == 1
	   && (num_int_old != num_int_new || num_float_old != num_float_new)))
      && (warned == 0))
    {
      warning (OPT_Wpsabi, "ABI for flattened struct with zero-length "
			   "bit-fields changed in GCC 10");
      warned = 1;
    }

  return num_int_new == 1 && num_float_new == 1;
}

/* Return the representation of an argument passed or returned in an FPR
   when the value has mode VALUE_MODE and the type has TYPE_MODE.  The
   two modes may be different for structures like:

       struct __attribute__((packed)) foo { float f; }

  where the SFmode value "f" is passed in REGNO but the struct itself
  has mode BLKmode.  */

static rtx
riscv_pass_fpr_single (machine_mode type_mode, unsigned regno,
		       machine_mode value_mode,
		       HOST_WIDE_INT offset)
{
  rtx x = gen_rtx_REG (value_mode, regno);

  if (type_mode != value_mode)
    {
      x = gen_rtx_EXPR_LIST (VOIDmode, x, GEN_INT (offset));
      x = gen_rtx_PARALLEL (type_mode, gen_rtvec (1, x));
    }
  return x;
}

/* Pass or return a composite value in the FPR pair REGNO and REGNO + 1.
   MODE is the mode of the composite.  MODE1 and OFFSET1 are the mode and
   byte offset for the first value, likewise MODE2 and OFFSET2 for the
   second value.  */

static rtx
riscv_pass_fpr_pair (machine_mode mode, unsigned regno1,
		     machine_mode mode1, HOST_WIDE_INT offset1,
		     unsigned regno2, machine_mode mode2,
		     HOST_WIDE_INT offset2)
{
  return gen_rtx_PARALLEL
    (mode,
     gen_rtvec (2,
		gen_rtx_EXPR_LIST (VOIDmode,
				   gen_rtx_REG (mode1, regno1),
				   GEN_INT (offset1)),
		gen_rtx_EXPR_LIST (VOIDmode,
				   gen_rtx_REG (mode2, regno2),
				   GEN_INT (offset2))));
}

/* Fill INFO with information about a single argument, and return an
   RTL pattern to pass or return the argument.  CUM is the cumulative
   state for earlier arguments.  MODE is the mode of this argument and
   TYPE is its type (if known).  NAMED is true if this is a named
   (fixed) argument rather than a variable one.  RETURN_P is true if
   returning the argument, or false if passing the argument.  */

static rtx
riscv_get_arg_info (struct riscv_arg_info *info, const CUMULATIVE_ARGS *cum,
		    machine_mode mode, const_tree type, bool named,
		    bool return_p)
{
  unsigned num_bytes, num_words;
  unsigned fpr_base = return_p ? FP_RETURN : FP_ARG_FIRST;
  unsigned gpr_base = return_p ? GP_RETURN : GP_ARG_FIRST;
  unsigned alignment = riscv_function_arg_boundary (mode, type);

  memset (info, 0, sizeof (*info));
  info->gpr_offset = cum->num_gprs;
  info->fpr_offset = cum->num_fprs;

  if (named)
    {
      riscv_aggregate_field fields[2];
      unsigned fregno = fpr_base + info->fpr_offset;
      unsigned gregno = gpr_base + info->gpr_offset;

      /* Pass one- or two-element floating-point aggregates in FPRs.  */
      if ((info->num_fprs = riscv_pass_aggregate_in_fpr_pair_p (type, fields))
	  && info->fpr_offset + info->num_fprs <= MAX_ARGS_IN_REGISTERS)
	switch (info->num_fprs)
	  {
	  case 1:
	    return riscv_pass_fpr_single (mode, fregno,
					  TYPE_MODE (fields[0].type),
					  fields[0].offset);

	  case 2:
	    return riscv_pass_fpr_pair (mode, fregno,
					TYPE_MODE (fields[0].type),
					fields[0].offset,
					fregno + 1,
					TYPE_MODE (fields[1].type),
					fields[1].offset);

	  default:
	    gcc_unreachable ();
	  }

      /* Pass real and complex floating-point numbers in FPRs.  */
      if ((info->num_fprs = riscv_pass_mode_in_fpr_p (mode))
	  && info->fpr_offset + info->num_fprs <= MAX_ARGS_IN_REGISTERS)
	switch (GET_MODE_CLASS (mode))
	  {
	  case MODE_FLOAT:
	    return gen_rtx_REG (mode, fregno);

	  case MODE_COMPLEX_FLOAT:
	    return riscv_pass_fpr_pair (mode, fregno, GET_MODE_INNER (mode), 0,
					fregno + 1, GET_MODE_INNER (mode),
					GET_MODE_UNIT_SIZE (mode));

	  default:
	    gcc_unreachable ();
	  }

      /* Pass structs with one float and one integer in an FPR and a GPR.  */
      if (riscv_pass_aggregate_in_fpr_and_gpr_p (type, fields)
	  && info->gpr_offset < MAX_ARGS_IN_REGISTERS
	  && info->fpr_offset < MAX_ARGS_IN_REGISTERS)
	{
	  info->num_gprs = 1;
	  info->num_fprs = 1;

	  if (!SCALAR_FLOAT_TYPE_P (fields[0].type))
	    std::swap (fregno, gregno);

	  return riscv_pass_fpr_pair (mode, fregno, TYPE_MODE (fields[0].type),
				      fields[0].offset,
				      gregno, TYPE_MODE (fields[1].type),
				      fields[1].offset);
	}
    }

  /* Work out the size of the argument.  */
  num_bytes = type ? int_size_in_bytes (type) : GET_MODE_SIZE (mode).to_constant ();
  num_words = (num_bytes + UNITS_PER_WORD - 1) / UNITS_PER_WORD;

  /* Doubleword-aligned varargs start on an even register boundary.  */
  if (!named && num_bytes != 0 && alignment > BITS_PER_WORD)
    info->gpr_offset += info->gpr_offset & 1;

  /* Partition the argument between registers and stack.  */
  info->num_fprs = 0;
  info->num_gprs = MIN (num_words, MAX_ARGS_IN_REGISTERS - info->gpr_offset);
  info->stack_p = (num_words - info->num_gprs) != 0;

  if (info->num_gprs || return_p)
    return gen_rtx_REG (mode, gpr_base + info->gpr_offset);

  return NULL_RTX;
}

/* Implement TARGET_FUNCTION_ARG.  */

static rtx
riscv_function_arg (cumulative_args_t cum_v, const function_arg_info &arg)
{
  CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
  struct riscv_arg_info info;

  if (arg.end_marker_p ())
    return NULL;

  return riscv_get_arg_info (&info, cum, arg.mode, arg.type, arg.named, false);
}

/* Implement TARGET_FUNCTION_ARG_ADVANCE.  */

static void
riscv_function_arg_advance (cumulative_args_t cum_v,
			    const function_arg_info &arg)
{
  CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
  struct riscv_arg_info info;

  riscv_get_arg_info (&info, cum, arg.mode, arg.type, arg.named, false);

  /* Advance the register count.  This has the effect of setting
     num_gprs to MAX_ARGS_IN_REGISTERS if a doubleword-aligned
     argument required us to skip the final GPR and pass the whole
     argument on the stack.  */
  cum->num_fprs = info.fpr_offset + info.num_fprs;
  cum->num_gprs = info.gpr_offset + info.num_gprs;
}

/* Implement TARGET_ARG_PARTIAL_BYTES.  */

static int
riscv_arg_partial_bytes (cumulative_args_t cum,
			 const function_arg_info &generic_arg)
{
  struct riscv_arg_info arg;

  riscv_get_arg_info (&arg, get_cumulative_args (cum), generic_arg.mode,
		      generic_arg.type, generic_arg.named, false);
  return arg.stack_p ? arg.num_gprs * UNITS_PER_WORD : 0;
}

/* Implement FUNCTION_VALUE and LIBCALL_VALUE.  For normal calls,
   VALTYPE is the return type and MODE is VOIDmode.  For libcalls,
   VALTYPE is null and MODE is the mode of the return value.  */

rtx
riscv_function_value (const_tree type, const_tree func, machine_mode mode)
{
  struct riscv_arg_info info;
  CUMULATIVE_ARGS args;

  if (type)
    {
      int unsigned_p = TYPE_UNSIGNED (type);

      mode = TYPE_MODE (type);

      /* Since TARGET_PROMOTE_FUNCTION_MODE unconditionally promotes,
	 return values, promote the mode here too.  */
      mode = promote_function_mode (type, mode, &unsigned_p, func, 1);
    }

  memset (&args, 0, sizeof args);
  return riscv_get_arg_info (&info, &args, mode, type, true, true);
}

/* Implement TARGET_PASS_BY_REFERENCE. */

static bool
riscv_pass_by_reference (cumulative_args_t cum_v, const function_arg_info &arg)
{
  HOST_WIDE_INT size = arg.type_size_in_bytes ().to_constant ();;
  struct riscv_arg_info info;
  CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);

  /* ??? std_gimplify_va_arg_expr passes NULL for cum.  Fortunately, we
     never pass variadic arguments in floating-point registers, so we can
     avoid the call to riscv_get_arg_info in this case.  */
  if (cum != NULL)
    {
      /* Don't pass by reference if we can use a floating-point register.  */
      riscv_get_arg_info (&info, cum, arg.mode, arg.type, arg.named, false);
      if (info.num_fprs)
	return false;
    }

  /* Pass by reference if the data do not fit in two integer registers.  */
  return !IN_RANGE (size, 0, 2 * UNITS_PER_WORD);
}

/* Implement TARGET_RETURN_IN_MEMORY.  */

static bool
riscv_return_in_memory (const_tree type, const_tree fndecl ATTRIBUTE_UNUSED)
{
  CUMULATIVE_ARGS args;
  cumulative_args_t cum = pack_cumulative_args (&args);

  /* The rules for returning in memory are the same as for passing the
     first named argument by reference.  */
  memset (&args, 0, sizeof args);
  function_arg_info arg (const_cast<tree> (type), /*named=*/true);
  return riscv_pass_by_reference (cum, arg);
}

/* Implement TARGET_SETUP_INCOMING_VARARGS.  */

static void
riscv_setup_incoming_varargs (cumulative_args_t cum,
			      const function_arg_info &arg,
			      int *pretend_size ATTRIBUTE_UNUSED, int no_rtl)
{
  CUMULATIVE_ARGS local_cum;
  int gp_saved;

  /* The caller has advanced CUM up to, but not beyond, the last named
     argument.  Advance a local copy of CUM past the last "real" named
     argument, to find out how many registers are left over.  */
  local_cum = *get_cumulative_args (cum);
  if (!TYPE_NO_NAMED_ARGS_STDARG_P (TREE_TYPE (current_function_decl)))
    riscv_function_arg_advance (pack_cumulative_args (&local_cum), arg);

  /* Found out how many registers we need to save.  */
  gp_saved = MAX_ARGS_IN_REGISTERS - local_cum.num_gprs;

  if (!no_rtl && gp_saved > 0)
    {
      rtx ptr = plus_constant (Pmode, virtual_incoming_args_rtx,
			       REG_PARM_STACK_SPACE (cfun->decl)
			       - gp_saved * UNITS_PER_WORD);
      rtx mem = gen_frame_mem (BLKmode, ptr);
      set_mem_alias_set (mem, get_varargs_alias_set ());

      move_block_from_reg (local_cum.num_gprs + GP_ARG_FIRST,
			   mem, gp_saved);
    }
  if (REG_PARM_STACK_SPACE (cfun->decl) == 0)
    cfun->machine->varargs_size = gp_saved * UNITS_PER_WORD;
}

/* Handle an attribute requiring a FUNCTION_DECL;
   arguments as in struct attribute_spec.handler.  */
static tree
riscv_handle_fndecl_attribute (tree *node, tree name,
			       tree args ATTRIBUTE_UNUSED,
			       int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
{
  if (TREE_CODE (*node) != FUNCTION_DECL)
    {
      warning (OPT_Wattributes, "%qE attribute only applies to functions",
	       name);
      *no_add_attrs = true;
    }

  return NULL_TREE;
}

/* Verify type based attributes.  NODE is the what the attribute is being
   applied to.  NAME is the attribute name.  ARGS are the attribute args.
   FLAGS gives info about the context.  NO_ADD_ATTRS should be set to true if
   the attribute should be ignored.  */

static tree
riscv_handle_type_attribute (tree *node ATTRIBUTE_UNUSED, tree name, tree args,
			     int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
{
  /* Check for an argument.  */
  if (is_attribute_p ("interrupt", name))
    {
      if (args)
	{
	  tree cst = TREE_VALUE (args);
	  const char *string;

	  if (TREE_CODE (cst) != STRING_CST)
	    {
	      warning (OPT_Wattributes,
		       "%qE attribute requires a string argument",
		       name);
	      *no_add_attrs = true;
	      return NULL_TREE;
	    }

	  string = TREE_STRING_POINTER (cst);
	  if (strcmp (string, "user") && strcmp (string, "supervisor")
	      && strcmp (string, "machine"))
	    {
	      warning (OPT_Wattributes,
		       "argument to %qE attribute is not %<\"user\"%>, %<\"supervisor\"%>, "
		       "or %<\"machine\"%>", name);
	      *no_add_attrs = true;
	    }
	}
    }

  return NULL_TREE;
}

/* Return true if function TYPE is an interrupt function.  */
static bool
riscv_interrupt_type_p (tree type)
{
  return lookup_attribute ("interrupt", TYPE_ATTRIBUTES (type)) != NULL;
}

/* Return true if FUNC is a naked function.  */
static bool
riscv_naked_function_p (tree func)
{
  tree func_decl = func;
  if (func == NULL_TREE)
    func_decl = current_function_decl;
  return NULL_TREE != lookup_attribute ("naked", DECL_ATTRIBUTES (func_decl));
}

/* Implement TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS.  */
static bool
riscv_allocate_stack_slots_for_args ()
{
  /* Naked functions should not allocate stack slots for arguments.  */
  return !riscv_naked_function_p (current_function_decl);
}

/* Implement TARGET_WARN_FUNC_RETURN.  */
static bool
riscv_warn_func_return (tree decl)
{
  /* Naked functions are implemented entirely in assembly, including the
     return sequence, so suppress warnings about this.  */
  return !riscv_naked_function_p (decl);
}

/* Implement TARGET_EXPAND_BUILTIN_VA_START.  */

static void
riscv_va_start (tree valist, rtx nextarg)
{
  nextarg = plus_constant (Pmode, nextarg, -cfun->machine->varargs_size);
  std_expand_builtin_va_start (valist, nextarg);
}

/* Make ADDR suitable for use as a call or sibcall target.  */

rtx
riscv_legitimize_call_address (rtx addr)
{
  if (!call_insn_operand (addr, VOIDmode))
    {
      rtx reg = RISCV_CALL_ADDRESS_TEMP (Pmode);
      riscv_emit_move (reg, addr);
      return reg;
    }
  return addr;
}

/* Emit straight-line code to move LENGTH bytes from SRC to DEST.
   Assume that the areas do not overlap.  */

static void
riscv_block_move_straight (rtx dest, rtx src, unsigned HOST_WIDE_INT length)
{
  unsigned HOST_WIDE_INT offset, delta;
  unsigned HOST_WIDE_INT bits;
  int i;
  enum machine_mode mode;
  rtx *regs;

  bits = MAX (BITS_PER_UNIT,
	      MIN (BITS_PER_WORD, MIN (MEM_ALIGN (src), MEM_ALIGN (dest))));

  mode = mode_for_size (bits, MODE_INT, 0).require ();
  delta = bits / BITS_PER_UNIT;

  /* Allocate a buffer for the temporary registers.  */
  regs = XALLOCAVEC (rtx, length / delta);

  /* Load as many BITS-sized chunks as possible.  Use a normal load if
     the source has enough alignment, otherwise use left/right pairs.  */
  for (offset = 0, i = 0; offset + delta <= length; offset += delta, i++)
    {
      regs[i] = gen_reg_rtx (mode);
      riscv_emit_move (regs[i], adjust_address (src, mode, offset));
    }

  /* Copy the chunks to the destination.  */
  for (offset = 0, i = 0; offset + delta <= length; offset += delta, i++)
    riscv_emit_move (adjust_address (dest, mode, offset), regs[i]);

  /* Mop up any left-over bytes.  */
  if (offset < length)
    {
      src = adjust_address (src, BLKmode, offset);
      dest = adjust_address (dest, BLKmode, offset);
      move_by_pieces (dest, src, length - offset,
		      MIN (MEM_ALIGN (src), MEM_ALIGN (dest)), RETURN_BEGIN);
    }
}

/* Helper function for doing a loop-based block operation on memory
   reference MEM.  Each iteration of the loop will operate on LENGTH
   bytes of MEM.

   Create a new base register for use within the loop and point it to
   the start of MEM.  Create a new memory reference that uses this
   register.  Store them in *LOOP_REG and *LOOP_MEM respectively.  */

static void
riscv_adjust_block_mem (rtx mem, unsigned HOST_WIDE_INT length,
			rtx *loop_reg, rtx *loop_mem)
{
  *loop_reg = copy_addr_to_reg (XEXP (mem, 0));

  /* Although the new mem does not refer to a known location,
     it does keep up to LENGTH bytes of alignment.  */
  *loop_mem = change_address (mem, BLKmode, *loop_reg);
  set_mem_align (*loop_mem, MIN (MEM_ALIGN (mem), length * BITS_PER_UNIT));
}

/* Move LENGTH bytes from SRC to DEST using a loop that moves BYTES_PER_ITER
   bytes at a time.  LENGTH must be at least BYTES_PER_ITER.  Assume that
   the memory regions do not overlap.  */

static void
riscv_block_move_loop (rtx dest, rtx src, unsigned HOST_WIDE_INT length,
		       unsigned HOST_WIDE_INT bytes_per_iter)
{
  rtx label, src_reg, dest_reg, final_src, test;
  unsigned HOST_WIDE_INT leftover;

  leftover = length % bytes_per_iter;
  length -= leftover;

  /* Create registers and memory references for use within the loop.  */
  riscv_adjust_block_mem (src, bytes_per_iter, &src_reg, &src);
  riscv_adjust_block_mem (dest, bytes_per_iter, &dest_reg, &dest);

  /* Calculate the value that SRC_REG should have after the last iteration
     of the loop.  */
  final_src = expand_simple_binop (Pmode, PLUS, src_reg, GEN_INT (length),
				   0, 0, OPTAB_WIDEN);

  /* Emit the start of the loop.  */
  label = gen_label_rtx ();
  emit_label (label);

  /* Emit the loop body.  */
  riscv_block_move_straight (dest, src, bytes_per_iter);

  /* Move on to the next block.  */
  riscv_emit_move (src_reg, plus_constant (Pmode, src_reg, bytes_per_iter));
  riscv_emit_move (dest_reg, plus_constant (Pmode, dest_reg, bytes_per_iter));

  /* Emit the loop condition.  */
  test = gen_rtx_NE (VOIDmode, src_reg, final_src);
  emit_jump_insn (gen_cbranch4 (Pmode, test, src_reg, final_src, label));

  /* Mop up any left-over bytes.  */
  if (leftover)
    riscv_block_move_straight (dest, src, leftover);
  else
    emit_insn(gen_nop ());
}

/* Expand a cpymemsi instruction, which copies LENGTH bytes from
   memory reference SRC to memory reference DEST.  */

bool
riscv_expand_block_move (rtx dest, rtx src, rtx length)
{
  if (CONST_INT_P (length))
    {
      unsigned HOST_WIDE_INT hwi_length = UINTVAL (length);
      unsigned HOST_WIDE_INT factor, align;

      align = MIN (MIN (MEM_ALIGN (src), MEM_ALIGN (dest)), BITS_PER_WORD);
      factor = BITS_PER_WORD / align;

      if (optimize_function_for_size_p (cfun)
	  && hwi_length * factor * UNITS_PER_WORD > MOVE_RATIO (false))
	return false;

      if (hwi_length <= (RISCV_MAX_MOVE_BYTES_STRAIGHT / factor))
	{
	  riscv_block_move_straight (dest, src, INTVAL (length));
	  return true;
	}
      else if (optimize && align >= BITS_PER_WORD)
	{
	  unsigned min_iter_words
	    = RISCV_MAX_MOVE_BYTES_PER_LOOP_ITER / UNITS_PER_WORD;
	  unsigned iter_words = min_iter_words;
	  unsigned HOST_WIDE_INT bytes = hwi_length;
	  unsigned HOST_WIDE_INT words = bytes / UNITS_PER_WORD;

	  /* Lengthen the loop body if it shortens the tail.  */
	  for (unsigned i = min_iter_words; i < min_iter_words * 2 - 1; i++)
	    {
	      unsigned cur_cost = iter_words + words % iter_words;
	      unsigned new_cost = i + words % i;
	      if (new_cost <= cur_cost)
		iter_words = i;
	    }

	  riscv_block_move_loop (dest, src, bytes, iter_words * UNITS_PER_WORD);
	  return true;
	}
    }
  return false;
}

/* Print symbolic operand OP, which is part of a HIGH or LO_SUM
   in context CONTEXT.  HI_RELOC indicates a high-part reloc.  */

static void
riscv_print_operand_reloc (FILE *file, rtx op, bool hi_reloc)
{
  const char *reloc;

  switch (riscv_classify_symbolic_expression (op))
    {
      case SYMBOL_ABSOLUTE:
	reloc = hi_reloc ? "%hi" : "%lo";
	break;

      case SYMBOL_PCREL:
	reloc = hi_reloc ? "%pcrel_hi" : "%pcrel_lo";
	break;

      case SYMBOL_TLS_LE:
	reloc = hi_reloc ? "%tprel_hi" : "%tprel_lo";
	break;

      default:
	output_operand_lossage ("invalid use of '%%%c'", hi_reloc ? 'h' : 'R');
	return;
    }

  fprintf (file, "%s(", reloc);
  output_addr_const (file, riscv_strip_unspec_address (op));
  fputc (')', file);
}

/* Return true if the .AQ suffix should be added to an AMO to implement the
   acquire portion of memory model MODEL.  */

static bool
riscv_memmodel_needs_amo_acquire (enum memmodel model)
{
  switch (model)
    {
      case MEMMODEL_ACQ_REL:
      case MEMMODEL_SEQ_CST:
      case MEMMODEL_SYNC_SEQ_CST:
      case MEMMODEL_ACQUIRE:
      case MEMMODEL_CONSUME:
      case MEMMODEL_SYNC_ACQUIRE:
	return true;

      case MEMMODEL_RELEASE:
      case MEMMODEL_SYNC_RELEASE:
      case MEMMODEL_RELAXED:
	return false;

      default:
	gcc_unreachable ();
    }
}

/* Return true if a FENCE should be emitted to before a memory access to
   implement the release portion of memory model MODEL.  */

static bool
riscv_memmodel_needs_release_fence (enum memmodel model)
{
  switch (model)
    {
      case MEMMODEL_ACQ_REL:
      case MEMMODEL_SEQ_CST:
      case MEMMODEL_SYNC_SEQ_CST:
      case MEMMODEL_RELEASE:
      case MEMMODEL_SYNC_RELEASE:
	return true;

      case MEMMODEL_ACQUIRE:
      case MEMMODEL_CONSUME:
      case MEMMODEL_SYNC_ACQUIRE:
      case MEMMODEL_RELAXED:
	return false;

      default:
	gcc_unreachable ();
    }
}

/* Implement TARGET_PRINT_OPERAND.  The RISCV-specific operand codes are:

   'h'	Print the high-part relocation associated with OP, after stripping
	  any outermost HIGH.
   'R'	Print the low-part relocation associated with OP.
   'C'	Print the integer branch condition for comparison OP.
   'A'	Print the atomic operation suffix for memory model OP.
   'F'	Print a FENCE if the memory model requires a release.
   'z'	Print x0 if OP is zero, otherwise print OP normally.
   'i'	Print i if the operand is not a register.
   'S'	Print shift-index of single-bit mask OP.
   'T'	Print shift-index of inverted single-bit mask OP.
   '~'	Print w if TARGET_64BIT is true; otherwise not print anything.

   Note please keep this list and the list in riscv.md in sync.  */

static void
riscv_print_operand (FILE *file, rtx op, int letter)
{
  /* `~` does not take an operand so op will be null
     Check for before accessing op.
  */
  if (letter == '~')
    {
      if (TARGET_64BIT)
	fputc('w', file);
      return;
    }
  machine_mode mode = GET_MODE (op);
  enum rtx_code code = GET_CODE (op);

  switch (letter)
    {
      case 'm': {
	if (riscv_v_ext_vector_mode_p (mode))
	  {
	    /* Calculate lmul according to mode and print the value.  */
	    poly_int64 size = GET_MODE_SIZE (mode);
	    unsigned int lmul;
	    if (known_lt (size, BYTES_PER_RISCV_VECTOR))
	      lmul = 1;
	    else
	      lmul = exact_div (size, BYTES_PER_RISCV_VECTOR).to_constant ();
	    asm_fprintf (file, "%d", lmul);
	  }
	else if (code == CONST_INT)
	  {
	    /* The value in the operand is the unsigned int value
	       converted from (enum machine_mode).
	       This RTX is generated as follows:

	       machine_mode mode = XXXmode;
	       operand = gen_int_mode ((unsigned int)mode, Pmode);

	       So we convert it back into machine_mode and then calculate
	       the LMUL according to GET_MODE_SIZE.  */

	    machine_mode rvv_mode = (machine_mode) UINTVAL (op);
	    /* For rvv mask modes, we can not calculate LMUL simpily according
	       to BYTES_PER_RISCV_VECTOR. When rvv_mode = VNx4BImode.
	       Set SEW = 8, LMUL = 1 by default if TARGET_MIN_VLEN == 32.
	       Set SEW = 8, LMUL = 1 / 2 by default if TARGET_MIN_VLEN > 32.  */
	    bool bool_p = GET_MODE_CLASS (rvv_mode) == MODE_VECTOR_BOOL;
	    poly_int64 m1_size = BYTES_PER_RISCV_VECTOR;
	    poly_int64 rvv_size
	      = bool_p ? GET_MODE_NUNITS (rvv_mode) : GET_MODE_SIZE (rvv_mode);
	    bool fractional_p = known_lt (rvv_size, BYTES_PER_RISCV_VECTOR);
	    unsigned int factor
	      = fractional_p ? exact_div (m1_size, rvv_size).to_constant ()
			     : exact_div (rvv_size, m1_size).to_constant ();
	    asm_fprintf (file, "%s%d", fractional_p ? "mf" : "m", factor);
	  }
	else
	  output_operand_lossage ("invalid vector constant");
	break;
      }
      case 'p': {
	if (GET_MODE_CLASS (mode) == MODE_VECTOR_BOOL)
	  {
	    /* Print for RVV mask operand.
	       If op is reg, print ",v0.t".
	       Otherwise, don't print anything.  */
	    if (code == REG)
	      fprintf (file, ",%s.t", reg_names[REGNO (op)]);
	  }
	else if (code == CONST_INT)
	  {
	    /* Tail && Mask policy.  */
	    bool agnostic_p = UINTVAL (op) & 0x1;
	    asm_fprintf (file, "%s", agnostic_p ? "a" : "u");
	  }
	else
	  output_operand_lossage ("invalid vector constant");
	break;
      }
    case 'h':
      if (code == HIGH)
	op = XEXP (op, 0);
      riscv_print_operand_reloc (file, op, true);
      break;

    case 'R':
      riscv_print_operand_reloc (file, op, false);
      break;

    case 'C':
      /* The RTL names match the instruction names. */
      fputs (GET_RTX_NAME (code), file);
      break;

    case 'A':
      if (riscv_memmodel_needs_amo_acquire ((enum memmodel) INTVAL (op)))
	fputs (".aq", file);
      break;

    case 'F':
      if (riscv_memmodel_needs_release_fence ((enum memmodel) INTVAL (op)))
	fputs ("fence iorw,ow; ", file);
      break;

    case 'i':
      if (code != REG)
        fputs ("i", file);
      break;

    case 'S':
      {
	rtx newop = GEN_INT (ctz_hwi (INTVAL (op)));
	output_addr_const (file, newop);
	break;
      }
    case 'T':
      {
	rtx newop = GEN_INT (ctz_hwi (~INTVAL (op)));
	output_addr_const (file, newop);
	break;
      }
    default:
      switch (code)
	{
	case REG:
	  if (letter && letter != 'z')
	    output_operand_lossage ("invalid use of '%%%c'", letter);
	  fprintf (file, "%s", reg_names[REGNO (op)]);
	  break;

	case MEM:
	  if (letter && letter != 'z')
	    output_operand_lossage ("invalid use of '%%%c'", letter);
	  else
	    output_address (mode, XEXP (op, 0));
	  break;

	default:
	  if (letter == 'z' && op == CONST0_RTX (GET_MODE (op)))
	    fputs (reg_names[GP_REG_FIRST], file);
	  else if (letter && letter != 'z')
	    output_operand_lossage ("invalid use of '%%%c'", letter);
	  else
	    output_addr_const (file, riscv_strip_unspec_address (op));
	  break;
	}
    }
}

/* Implement TARGET_PRINT_OPERAND_PUNCT_VALID_P */
static bool
riscv_print_operand_punct_valid_p (unsigned char code)
{
  return (code == '~');
}

/* Implement TARGET_PRINT_OPERAND_ADDRESS.  */

static void
riscv_print_operand_address (FILE *file, machine_mode mode ATTRIBUTE_UNUSED, rtx x)
{
  struct riscv_address_info addr;

  if (riscv_classify_address (&addr, x, word_mode, true))
    switch (addr.type)
      {
      case ADDRESS_REG:
	riscv_print_operand (file, addr.offset, 0);
	fprintf (file, "(%s)", reg_names[REGNO (addr.reg)]);
	return;

      case ADDRESS_LO_SUM:
	riscv_print_operand_reloc (file, addr.offset, false);
	fprintf (file, "(%s)", reg_names[REGNO (addr.reg)]);
	return;

      case ADDRESS_CONST_INT:
	output_addr_const (file, x);
	fprintf (file, "(%s)", reg_names[GP_REG_FIRST]);
	return;

      case ADDRESS_SYMBOLIC:
	output_addr_const (file, riscv_strip_unspec_address (x));
	return;
      }
  gcc_unreachable ();
}

static bool
riscv_size_ok_for_small_data_p (int size)
{
  return g_switch_value && IN_RANGE (size, 1, g_switch_value);
}

/* Return true if EXP should be placed in the small data section. */

static bool
riscv_in_small_data_p (const_tree x)
{
  if (TREE_CODE (x) == STRING_CST || TREE_CODE (x) == FUNCTION_DECL)
    return false;

  if (TREE_CODE (x) == VAR_DECL && DECL_SECTION_NAME (x))
    {
      const char *sec = DECL_SECTION_NAME (x);
      return strcmp (sec, ".sdata") == 0 || strcmp (sec, ".sbss") == 0;
    }

  return riscv_size_ok_for_small_data_p (int_size_in_bytes (TREE_TYPE (x)));
}

/* Switch to the appropriate section for output of DECL.  */

static section *
riscv_select_section (tree decl, int reloc,
		      unsigned HOST_WIDE_INT align)
{
  switch (categorize_decl_for_section (decl, reloc))
    {
    case SECCAT_SRODATA:
      return get_named_section (decl, ".srodata", reloc);

    default:
      return default_elf_select_section (decl, reloc, align);
    }
}

/* Switch to the appropriate section for output of DECL.  */

static void
riscv_unique_section (tree decl, int reloc)
{
  const char *prefix = NULL;
  bool one_only = DECL_ONE_ONLY (decl) && !HAVE_COMDAT_GROUP;

  switch (categorize_decl_for_section (decl, reloc))
    {
    case SECCAT_SRODATA:
      prefix = one_only ? ".sr" : ".srodata";
      break;

    default:
      break;
    }
  if (prefix)
    {
      const char *name, *linkonce;
      char *string;

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

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

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

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

/* Return a section for X, handling small data. */

static section *
riscv_elf_select_rtx_section (machine_mode mode, rtx x,
			      unsigned HOST_WIDE_INT align)
{
  section *s = default_elf_select_rtx_section (mode, x, align);

  if (riscv_size_ok_for_small_data_p (GET_MODE_SIZE (mode).to_constant ()))
    {
      if (startswith (s->named.name, ".rodata.cst"))
	{
	  /* Rename .rodata.cst* to .srodata.cst*. */
	  char *name = (char *) alloca (strlen (s->named.name) + 2);
	  sprintf (name, ".s%s", s->named.name + 1);
	  return get_section (name, s->named.common.flags, NULL);
	}

      if (s == data_section)
	return sdata_section;
    }

  return s;
}

/* Make the last instruction frame-related and note that it performs
   the operation described by FRAME_PATTERN.  */

static void
riscv_set_frame_expr (rtx frame_pattern)
{
  rtx insn;

  insn = get_last_insn ();
  RTX_FRAME_RELATED_P (insn) = 1;
  REG_NOTES (insn) = alloc_EXPR_LIST (REG_FRAME_RELATED_EXPR,
				      frame_pattern,
				      REG_NOTES (insn));
}

/* Return a frame-related rtx that stores REG at MEM.
   REG must be a single register.  */

static rtx
riscv_frame_set (rtx mem, rtx reg)
{
  rtx set = gen_rtx_SET (mem, reg);
  RTX_FRAME_RELATED_P (set) = 1;
  return set;
}

/* Return true if the current function must save register REGNO.  */

static bool
riscv_save_reg_p (unsigned int regno)
{
  bool call_saved = !global_regs[regno] && !call_used_or_fixed_reg_p (regno);
  bool might_clobber = crtl->saves_all_registers
		       || df_regs_ever_live_p (regno);

  if (call_saved && might_clobber)
    return true;

  if (regno == HARD_FRAME_POINTER_REGNUM && frame_pointer_needed)
    return true;

  if (regno == RETURN_ADDR_REGNUM && crtl->calls_eh_return)
    return true;

  /* If this is an interrupt handler, then must save extra registers.  */
  if (cfun->machine->interrupt_handler_p)
    {
      /* zero register is always zero.  */
      if (regno == GP_REG_FIRST)
	return false;

      /* The function will return the stack pointer to its original value.  */
      if (regno == STACK_POINTER_REGNUM)
	return false;

      /* By convention, we assume that gp and tp are safe.  */
      if (regno == GP_REGNUM || regno == THREAD_POINTER_REGNUM)
	return false;

      /* We must save every register used in this function.  If this is not a
	 leaf function, then we must save all temporary registers.  */
      if (df_regs_ever_live_p (regno)
	  || (!crtl->is_leaf && call_used_or_fixed_reg_p (regno)))
	return true;
    }

  return false;
}

/* Determine whether to call GPR save/restore routines.  */
static bool
riscv_use_save_libcall (const struct riscv_frame_info *frame)
{
  if (!TARGET_SAVE_RESTORE || crtl->calls_eh_return || frame_pointer_needed
      || cfun->machine->interrupt_handler_p)
    return false;

  return frame->save_libcall_adjustment != 0;
}

/* Determine which GPR save/restore routine to call.  */

static unsigned
riscv_save_libcall_count (unsigned mask)
{
  for (unsigned n = GP_REG_LAST; n > GP_REG_FIRST; n--)
    if (BITSET_P (mask, n))
      return CALLEE_SAVED_REG_NUMBER (n) + 1;
  abort ();
}

/* Populate the current function's riscv_frame_info structure.

   RISC-V stack frames grown downward.  High addresses are at the top.

	+-------------------------------+
	|                               |
	|  incoming stack arguments     |
	|                               |
	+-------------------------------+ <-- incoming stack pointer
	|                               |
	|  callee-allocated save area   |
	|  for arguments that are       |
	|  split between registers and  |
	|  the stack                    |
	|                               |
	+-------------------------------+ <-- arg_pointer_rtx
	|                               |
	|  callee-allocated save area   |
	|  for register varargs         |
	|                               |
	+-------------------------------+ <-- hard_frame_pointer_rtx;
	|                               |     stack_pointer_rtx + gp_sp_offset
	|  GPR save area                |       + UNITS_PER_WORD
	|                               |
	+-------------------------------+ <-- stack_pointer_rtx + fp_sp_offset
	|                               |       + UNITS_PER_HWVALUE
	|  FPR save area                |
	|                               |
	+-------------------------------+ <-- frame_pointer_rtx (virtual)
	|                               |
	|  local variables              |
	|                               |
      P +-------------------------------+
	|                               |
	|  outgoing stack arguments     |
	|                               |
	+-------------------------------+ <-- stack_pointer_rtx

   Dynamic stack allocations such as alloca insert data at point P.
   They decrease stack_pointer_rtx but leave frame_pointer_rtx and
   hard_frame_pointer_rtx unchanged.  */

static HOST_WIDE_INT riscv_first_stack_step (struct riscv_frame_info *frame);

/* Handle stack align for poly_int.  */
static poly_int64
riscv_stack_align (poly_int64 value)
{
  return aligned_upper_bound (value, PREFERRED_STACK_BOUNDARY / 8);
}

static HOST_WIDE_INT
riscv_stack_align (HOST_WIDE_INT value)
{
  return RISCV_STACK_ALIGN (value);
}

static void
riscv_compute_frame_info (void)
{
  struct riscv_frame_info *frame;
  poly_int64 offset;
  bool interrupt_save_prologue_temp = false;
  unsigned int regno, i, num_x_saved = 0, num_f_saved = 0;

  frame = &cfun->machine->frame;

  /* In an interrupt function, if we have a large frame, then we need to
     save/restore t0.  We check for this before clearing the frame struct.  */
  if (cfun->machine->interrupt_handler_p)
    {
      HOST_WIDE_INT step1 = riscv_first_stack_step (frame);
      if (! POLY_SMALL_OPERAND_P ((frame->total_size - step1)))
	interrupt_save_prologue_temp = true;
    }

  frame->reset();

  if (!cfun->machine->naked_p)
    {
      /* Find out which GPRs we need to save.  */
      for (regno = GP_REG_FIRST; regno <= GP_REG_LAST; regno++)
	if (riscv_save_reg_p (regno)
	    || (interrupt_save_prologue_temp
		&& (regno == RISCV_PROLOGUE_TEMP_REGNUM)))
	  frame->mask |= 1 << (regno - GP_REG_FIRST), num_x_saved++;

      /* If this function calls eh_return, we must also save and restore the
	 EH data registers.  */
      if (crtl->calls_eh_return)
	for (i = 0; (regno = EH_RETURN_DATA_REGNO (i)) != INVALID_REGNUM; i++)
	  frame->mask |= 1 << (regno - GP_REG_FIRST), num_x_saved++;

      /* Find out which FPRs we need to save.  This loop must iterate over
	 the same space as its companion in riscv_for_each_saved_reg.  */
      if (TARGET_HARD_FLOAT)
	for (regno = FP_REG_FIRST; regno <= FP_REG_LAST; regno++)
	  if (riscv_save_reg_p (regno))
	    frame->fmask |= 1 << (regno - FP_REG_FIRST), num_f_saved++;
    }

  /* At the bottom of the frame are any outgoing stack arguments. */
  offset = riscv_stack_align (crtl->outgoing_args_size);
  /* Next are local stack variables. */
  offset += riscv_stack_align (get_frame_size ());
  /* The virtual frame pointer points above the local variables. */
  frame->frame_pointer_offset = offset;
  /* Next are the callee-saved FPRs. */
  if (frame->fmask)
    offset += riscv_stack_align (num_f_saved * UNITS_PER_FP_REG);
  frame->fp_sp_offset = offset - UNITS_PER_FP_REG;
  /* Next are the callee-saved GPRs. */
  if (frame->mask)
    {
      unsigned x_save_size = riscv_stack_align (num_x_saved * UNITS_PER_WORD);
      unsigned num_save_restore = 1 + riscv_save_libcall_count (frame->mask);

      /* Only use save/restore routines if they don't alter the stack size.  */
      if (riscv_stack_align (num_save_restore * UNITS_PER_WORD) == x_save_size)
	{
	  /* Libcall saves/restores 3 registers at once, so we need to
	     allocate 12 bytes for callee-saved register.  */
	  if (TARGET_RVE)
	    x_save_size = 3 * UNITS_PER_WORD;

	  frame->save_libcall_adjustment = x_save_size;
	}

      offset += x_save_size;
    }
  frame->gp_sp_offset = offset - UNITS_PER_WORD;
  /* The hard frame pointer points above the callee-saved GPRs. */
  frame->hard_frame_pointer_offset = offset;
  /* Above the hard frame pointer is the callee-allocated varags save area. */
  offset += riscv_stack_align (cfun->machine->varargs_size);
  /* Next is the callee-allocated area for pretend stack arguments.  */
  offset += riscv_stack_align (crtl->args.pretend_args_size);
  /* Arg pointer must be below pretend args, but must be above alignment
     padding.  */
  frame->arg_pointer_offset = offset - crtl->args.pretend_args_size;
  frame->total_size = offset;
  /* Next points the incoming stack pointer and any incoming arguments. */

  /* Only use save/restore routines when the GPRs are atop the frame.  */
  if (known_ne (frame->hard_frame_pointer_offset, frame->total_size))
    frame->save_libcall_adjustment = 0;
}

/* Make sure that we're not trying to eliminate to the wrong hard frame
   pointer.  */

static bool
riscv_can_eliminate (const int from ATTRIBUTE_UNUSED, const int to)
{
  return (to == HARD_FRAME_POINTER_REGNUM || to == STACK_POINTER_REGNUM);
}

/* Implement INITIAL_ELIMINATION_OFFSET.  FROM is either the frame pointer
   or argument pointer.  TO is either the stack pointer or hard frame
   pointer.  */

poly_int64
riscv_initial_elimination_offset (int from, int to)
{
  poly_int64 src, dest;

  riscv_compute_frame_info ();

  if (to == HARD_FRAME_POINTER_REGNUM)
    dest = cfun->machine->frame.hard_frame_pointer_offset;
  else if (to == STACK_POINTER_REGNUM)
    dest = 0; /* The stack pointer is the base of all offsets, hence 0.  */
  else
    gcc_unreachable ();

  if (from == FRAME_POINTER_REGNUM)
    src = cfun->machine->frame.frame_pointer_offset;
  else if (from == ARG_POINTER_REGNUM)
    src = cfun->machine->frame.arg_pointer_offset;
  else
    gcc_unreachable ();

  return src - dest;
}

/* Implement RETURN_ADDR_RTX.  We do not support moving back to a
   previous frame.  */

rtx
riscv_return_addr (int count, rtx frame ATTRIBUTE_UNUSED)
{
  if (count != 0)
    return const0_rtx;

  return get_hard_reg_initial_val (Pmode, RETURN_ADDR_REGNUM);
}

/* Emit code to change the current function's return address to
   ADDRESS.  SCRATCH is available as a scratch register, if needed.
   ADDRESS and SCRATCH are both word-mode GPRs.  */

void
riscv_set_return_address (rtx address, rtx scratch)
{
  rtx slot_address;

  gcc_assert (BITSET_P (cfun->machine->frame.mask, RETURN_ADDR_REGNUM));
  slot_address = riscv_add_offset (scratch, stack_pointer_rtx,
				  cfun->machine->frame.gp_sp_offset.to_constant());
  riscv_emit_move (gen_frame_mem (GET_MODE (address), slot_address), address);
}

/* A function to save or store a register.  The first argument is the
   register and the second is the stack slot.  */
typedef void (*riscv_save_restore_fn) (rtx, rtx);

/* Use FN to save or restore register REGNO.  MODE is the register's
   mode and OFFSET is the offset of its save slot from the current
   stack pointer.  */

static void
riscv_save_restore_reg (machine_mode mode, int regno,
		       HOST_WIDE_INT offset, riscv_save_restore_fn fn)
{
  rtx mem;

  mem = gen_frame_mem (mode, plus_constant (Pmode, stack_pointer_rtx, offset));
  fn (gen_rtx_REG (mode, regno), mem);
}

/* Call FN for each register that is saved by the current function.
   SP_OFFSET is the offset of the current stack pointer from the start
   of the frame.  */

static void
riscv_for_each_saved_reg (poly_int64 sp_offset, riscv_save_restore_fn fn,
			  bool epilogue, bool maybe_eh_return)
{
  HOST_WIDE_INT offset;

  /* Save the link register and s-registers. */
  offset = (cfun->machine->frame.gp_sp_offset - sp_offset).to_constant ();
  for (unsigned int regno = GP_REG_FIRST; regno <= GP_REG_LAST; regno++)
    if (BITSET_P (cfun->machine->frame.mask, regno - GP_REG_FIRST))
      {
	bool handle_reg = !cfun->machine->reg_is_wrapped_separately[regno];

	/* If this is a normal return in a function that calls the eh_return
	   builtin, then do not restore the eh return data registers as that
	   would clobber the return value.  But we do still need to save them
	   in the prologue, and restore them for an exception return, so we
	   need special handling here.  */
	if (epilogue && !maybe_eh_return && crtl->calls_eh_return)
	  {
	    unsigned int i, regnum;

	    for (i = 0; (regnum = EH_RETURN_DATA_REGNO (i)) != INVALID_REGNUM;
		 i++)
	      if (regno == regnum)
		{
		  handle_reg = FALSE;
		  break;
		}
	  }

	if (handle_reg)
	  riscv_save_restore_reg (word_mode, regno, offset, fn);
	offset -= UNITS_PER_WORD;
      }

  /* This loop must iterate over the same space as its companion in
     riscv_compute_frame_info.  */
  offset = (cfun->machine->frame.fp_sp_offset - sp_offset).to_constant ();
  for (unsigned int regno = FP_REG_FIRST; regno <= FP_REG_LAST; regno++)
    if (BITSET_P (cfun->machine->frame.fmask, regno - FP_REG_FIRST))
      {
	bool handle_reg = !cfun->machine->reg_is_wrapped_separately[regno];
	machine_mode mode = TARGET_DOUBLE_FLOAT ? DFmode : SFmode;

	if (handle_reg)
	  riscv_save_restore_reg (mode, regno, offset, fn);
	offset -= GET_MODE_SIZE (mode).to_constant ();
      }
}

/* Save register REG to MEM.  Make the instruction frame-related.  */

static void
riscv_save_reg (rtx reg, rtx mem)
{
  riscv_emit_move (mem, reg);
  riscv_set_frame_expr (riscv_frame_set (mem, reg));
}

/* Restore register REG from MEM.  */

static void
riscv_restore_reg (rtx reg, rtx mem)
{
  rtx insn = riscv_emit_move (reg, mem);
  rtx dwarf = NULL_RTX;
  dwarf = alloc_reg_note (REG_CFA_RESTORE, reg, dwarf);

  if (epilogue_cfa_sp_offset && REGNO (reg) == HARD_FRAME_POINTER_REGNUM)
    {
      rtx cfa_adjust_rtx = gen_rtx_PLUS (Pmode, stack_pointer_rtx,
					 GEN_INT (epilogue_cfa_sp_offset));
      dwarf = alloc_reg_note (REG_CFA_DEF_CFA, cfa_adjust_rtx, dwarf);
    }

  REG_NOTES (insn) = dwarf;
  RTX_FRAME_RELATED_P (insn) = 1;
}

/* For stack frames that can't be allocated with a single ADDI instruction,
   compute the best value to initially allocate.  It must at a minimum
   allocate enough space to spill the callee-saved registers.  If TARGET_RVC,
   try to pick a value that will allow compression of the register saves
   without adding extra instructions.  */

static HOST_WIDE_INT
riscv_first_stack_step (struct riscv_frame_info *frame)
{
  HOST_WIDE_INT frame_total_constant_size;
  if (!frame->total_size.is_constant ())
    frame_total_constant_size
      = riscv_stack_align (frame->total_size.coeffs[0])
	- riscv_stack_align (frame->total_size.coeffs[1]);
  else
    frame_total_constant_size = frame->total_size.to_constant ();

  if (SMALL_OPERAND (frame_total_constant_size))
    return frame_total_constant_size;

  HOST_WIDE_INT min_first_step =
    RISCV_STACK_ALIGN ((frame->total_size - frame->fp_sp_offset).to_constant());
  HOST_WIDE_INT max_first_step = IMM_REACH / 2 - PREFERRED_STACK_BOUNDARY / 8;
  HOST_WIDE_INT min_second_step = frame_total_constant_size - max_first_step;
  gcc_assert (min_first_step <= max_first_step);

  /* As an optimization, use the least-significant bits of the total frame
     size, so that the second adjustment step is just LUI + ADD.  */
  if (!SMALL_OPERAND (min_second_step)
      && frame_total_constant_size % IMM_REACH < IMM_REACH / 2
      && frame_total_constant_size % IMM_REACH >= min_first_step)
    return frame_total_constant_size % IMM_REACH;

  if (TARGET_RVC)
    {
      /* If we need two subtracts, and one is small enough to allow compressed
	 loads and stores, then put that one first.  */
      if (IN_RANGE (min_second_step, 0,
		    (TARGET_64BIT ? SDSP_REACH : SWSP_REACH)))
	return MAX (min_second_step, min_first_step);

      /* If we need LUI + ADDI + ADD for the second adjustment step, then start
	 with the minimum first step, so that we can get compressed loads and
	 stores.  */
      else if (!SMALL_OPERAND (min_second_step))
	return min_first_step;
    }

  return max_first_step;
}

static rtx
riscv_adjust_libcall_cfi_prologue ()
{
  rtx dwarf = NULL_RTX;
  rtx adjust_sp_rtx, reg, mem, insn;
  int saved_size = cfun->machine->frame.save_libcall_adjustment;
  int offset;

  for (int regno = GP_REG_FIRST; regno <= GP_REG_LAST; regno++)
    if (BITSET_P (cfun->machine->frame.mask, regno - GP_REG_FIRST))
      {
	/* The save order is ra, s0, s1, s2 to s11.  */
	if (regno == RETURN_ADDR_REGNUM)
	  offset = saved_size - UNITS_PER_WORD;
	else if (regno == S0_REGNUM)
	  offset = saved_size - UNITS_PER_WORD * 2;
	else if (regno == S1_REGNUM)
	  offset = saved_size - UNITS_PER_WORD * 3;
	else
	  offset = saved_size - ((regno - S2_REGNUM + 4) * UNITS_PER_WORD);

	reg = gen_rtx_REG (SImode, regno);
	mem = gen_frame_mem (SImode, plus_constant (Pmode,
						    stack_pointer_rtx,
						    offset));

	insn = gen_rtx_SET (mem, reg);
	dwarf = alloc_reg_note (REG_CFA_OFFSET, insn, dwarf);
      }

  /* Debug info for adjust sp.  */
  adjust_sp_rtx = gen_add3_insn (stack_pointer_rtx,
				 stack_pointer_rtx, GEN_INT (-saved_size));
  dwarf = alloc_reg_note (REG_CFA_ADJUST_CFA, adjust_sp_rtx,
			  dwarf);
  return dwarf;
}

static void
riscv_emit_stack_tie (void)
{
  if (Pmode == SImode)
    emit_insn (gen_stack_tiesi (stack_pointer_rtx, hard_frame_pointer_rtx));
  else
    emit_insn (gen_stack_tiedi (stack_pointer_rtx, hard_frame_pointer_rtx));
}

/* Expand the "prologue" pattern.  */

void
riscv_expand_prologue (void)
{
  struct riscv_frame_info *frame = &cfun->machine->frame;
  poly_int64 size = frame->total_size;
  unsigned mask = frame->mask;
  rtx insn;

  if (flag_stack_usage_info)
    current_function_static_stack_size = constant_lower_bound (size);

  if (cfun->machine->naked_p)
    return;

  /* When optimizing for size, call a subroutine to save the registers.  */
  if (riscv_use_save_libcall (frame))
    {
      rtx dwarf = NULL_RTX;
      dwarf = riscv_adjust_libcall_cfi_prologue ();

      size -= frame->save_libcall_adjustment;
      insn = emit_insn (riscv_gen_gpr_save_insn (frame));
      frame->mask = 0; /* Temporarily fib that we need not save GPRs.  */

      RTX_FRAME_RELATED_P (insn) = 1;
      REG_NOTES (insn) = dwarf;
    }

  /* Save the registers.  */
  if ((frame->mask | frame->fmask) != 0)
    {
      HOST_WIDE_INT step1 = riscv_first_stack_step (frame);
      if (size.is_constant ())
	step1 = MIN (size.to_constant(), step1);

      insn = gen_add3_insn (stack_pointer_rtx,
			    stack_pointer_rtx,
			    GEN_INT (-step1));
      RTX_FRAME_RELATED_P (emit_insn (insn)) = 1;
      size -= step1;
      riscv_for_each_saved_reg (size, riscv_save_reg, false, false);
    }

  frame->mask = mask; /* Undo the above fib.  */

  /* Set up the frame pointer, if we're using one.  */
  if (frame_pointer_needed)
    {
      insn = gen_add3_insn (hard_frame_pointer_rtx, stack_pointer_rtx,
			    GEN_INT ((frame->hard_frame_pointer_offset - size).to_constant ()));
      RTX_FRAME_RELATED_P (emit_insn (insn)) = 1;

      riscv_emit_stack_tie ();
    }

  /* Allocate the rest of the frame.  */
  if (known_gt (size, 0))
    {
      /* Two step adjustment:
	 1.scalable frame. 2.constant frame.  */
      poly_int64 scalable_frame (0, 0);
      if (!size.is_constant ())
	{
	  /* First for scalable frame.  */
	  poly_int64 scalable_frame = size;
	  scalable_frame.coeffs[0] = size.coeffs[1];
	  riscv_v_adjust_scalable_frame (stack_pointer_rtx, scalable_frame, false);
	  size -= scalable_frame;
	}

      /* Second step for constant frame.  */
      HOST_WIDE_INT constant_frame = size.to_constant ();
      if (constant_frame == 0)
	return;

      if (SMALL_OPERAND (-constant_frame))
	{
	  insn = gen_add3_insn (stack_pointer_rtx, stack_pointer_rtx,
				GEN_INT (-constant_frame));
	  RTX_FRAME_RELATED_P (emit_insn (insn)) = 1;
	}
      else
	{
	  riscv_emit_move (RISCV_PROLOGUE_TEMP (Pmode), GEN_INT (-constant_frame));
	  emit_insn (gen_add3_insn (stack_pointer_rtx,
				    stack_pointer_rtx,
				    RISCV_PROLOGUE_TEMP (Pmode)));

	  /* Describe the effect of the previous instructions.  */
	  insn = plus_constant (Pmode, stack_pointer_rtx, -constant_frame);
	  insn = gen_rtx_SET (stack_pointer_rtx, insn);
	  riscv_set_frame_expr (insn);
	}
    }
}

static rtx
riscv_adjust_libcall_cfi_epilogue ()
{
  rtx dwarf = NULL_RTX;
  rtx adjust_sp_rtx, reg;
  int saved_size = cfun->machine->frame.save_libcall_adjustment;

  /* Debug info for adjust sp.  */
  adjust_sp_rtx = gen_add3_insn (stack_pointer_rtx,
				 stack_pointer_rtx, GEN_INT (saved_size));
  dwarf = alloc_reg_note (REG_CFA_ADJUST_CFA, adjust_sp_rtx,
			  dwarf);

  for (int regno = GP_REG_FIRST; regno <= GP_REG_LAST; regno++)
    if (BITSET_P (cfun->machine->frame.mask, regno - GP_REG_FIRST))
      {
	reg = gen_rtx_REG (SImode, regno);
	dwarf = alloc_reg_note (REG_CFA_RESTORE, reg, dwarf);
      }

  return dwarf;
}

/* Expand an "epilogue", "sibcall_epilogue", or "eh_return_internal" pattern;
   style says which.  */

void
riscv_expand_epilogue (int style)
{
  /* Split the frame into two.  STEP1 is the amount of stack we should
     deallocate before restoring the registers.  STEP2 is the amount we
     should deallocate afterwards.

     Start off by assuming that no registers need to be restored.  */
  struct riscv_frame_info *frame = &cfun->machine->frame;
  unsigned mask = frame->mask;
  poly_int64 step1 = frame->total_size;
  HOST_WIDE_INT step2 = 0;
  bool use_restore_libcall = ((style == NORMAL_RETURN)
			      && riscv_use_save_libcall (frame));
  rtx ra = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM);
  rtx insn;

  /* We need to add memory barrier to prevent read from deallocated stack.  */
  bool need_barrier_p = known_ne (get_frame_size ()
				  + cfun->machine->frame.arg_pointer_offset, 0);

  if (cfun->machine->naked_p)
    {
      gcc_assert (style == NORMAL_RETURN);

      emit_jump_insn (gen_return ());

      return;
    }

  if ((style == NORMAL_RETURN) && riscv_can_use_return_insn ())
    {
      emit_jump_insn (gen_return ());
      return;
    }

  /* Reset the epilogue cfa info before starting to emit the epilogue.  */
  epilogue_cfa_sp_offset = 0;

  /* Move past any dynamic stack allocations.  */
  if (cfun->calls_alloca)
    {
      /* Emit a barrier to prevent loads from a deallocated stack.  */
      riscv_emit_stack_tie ();
      need_barrier_p = false;

      poly_int64 adjust_offset = -frame->hard_frame_pointer_offset;
      rtx adjust = NULL_RTX;

      if (!adjust_offset.is_constant ())
	{
	  rtx tmp1 = RISCV_PROLOGUE_TEMP (Pmode);
	  rtx tmp2 = RISCV_PROLOGUE_TEMP2 (Pmode);
	  riscv_legitimize_poly_move (Pmode, tmp1, tmp2,
				      gen_int_mode (adjust_offset, Pmode));
	  adjust = tmp1;
	}
      else
	{
	  if (!SMALL_OPERAND (adjust_offset.to_constant ()))
	    {
	      riscv_emit_move (RISCV_PROLOGUE_TEMP (Pmode),
			       GEN_INT (adjust_offset.to_constant ()));
	      adjust = RISCV_PROLOGUE_TEMP (Pmode);
	    }
	  else
	    adjust = GEN_INT (adjust_offset.to_constant ());
	}

      insn = emit_insn (
	       gen_add3_insn (stack_pointer_rtx, hard_frame_pointer_rtx,
			      adjust));

      rtx dwarf = NULL_RTX;
      rtx cfa_adjust_value = gen_rtx_PLUS (
			       Pmode, hard_frame_pointer_rtx,
			       gen_int_mode (-frame->hard_frame_pointer_offset, Pmode));
      rtx cfa_adjust_rtx = gen_rtx_SET (stack_pointer_rtx, cfa_adjust_value);
      dwarf = alloc_reg_note (REG_CFA_ADJUST_CFA, cfa_adjust_rtx, dwarf);
      RTX_FRAME_RELATED_P (insn) = 1;

      REG_NOTES (insn) = dwarf;
    }

  /* If we need to restore registers, deallocate as much stack as
     possible in the second step without going out of range.  */
  if ((frame->mask | frame->fmask) != 0)
    {
      step2 = riscv_first_stack_step (frame);
      step1 -= step2;
    }

  /* Set TARGET to BASE + STEP1.  */
  if (known_gt (step1, 0))
    {
      /* Emit a barrier to prevent loads from a deallocated stack.  */
      riscv_emit_stack_tie ();
      need_barrier_p = false;

      /* Restore the scalable frame which is assigned in prologue.  */
      if (!step1.is_constant ())
	{
	  poly_int64 scalable_frame = step1;
	  scalable_frame.coeffs[0] = step1.coeffs[1];
	  riscv_v_adjust_scalable_frame (stack_pointer_rtx, scalable_frame,
					 true);
	  step1 -= scalable_frame;
	}

      /* Get an rtx for STEP1 that we can add to BASE.
	 Skip if adjust equal to zero.  */
      if (step1.to_constant () != 0)
	{
	  rtx adjust = GEN_INT (step1.to_constant ());
	  if (!SMALL_OPERAND (step1.to_constant ()))
	    {
	      riscv_emit_move (RISCV_PROLOGUE_TEMP (Pmode), adjust);
	      adjust = RISCV_PROLOGUE_TEMP (Pmode);
	    }

	  insn = emit_insn (gen_add3_insn (stack_pointer_rtx,
					   stack_pointer_rtx,
					   adjust));
	  rtx dwarf = NULL_RTX;
	  rtx cfa_adjust_rtx = gen_rtx_PLUS (Pmode, stack_pointer_rtx,
					     GEN_INT (step2));

	  dwarf = alloc_reg_note (REG_CFA_DEF_CFA, cfa_adjust_rtx, dwarf);
	  RTX_FRAME_RELATED_P (insn) = 1;

	  REG_NOTES (insn) = dwarf;
	}
    }
  else if (frame_pointer_needed)
    {
      /* Tell riscv_restore_reg to emit dwarf to redefine CFA when restoring
	 old value of FP.  */
      epilogue_cfa_sp_offset = step2;
    }

  if (use_restore_libcall)
    frame->mask = 0; /* Temporarily fib that we need not save GPRs.  */

  /* Restore the registers.  */
  riscv_for_each_saved_reg (frame->total_size - step2, riscv_restore_reg,
			    true, style == EXCEPTION_RETURN);

  if (use_restore_libcall)
    {
      frame->mask = mask; /* Undo the above fib.  */
      gcc_assert (step2 >= frame->save_libcall_adjustment);
      step2 -= frame->save_libcall_adjustment;
    }

  if (need_barrier_p)
    riscv_emit_stack_tie ();

  /* Deallocate the final bit of the frame.  */
  if (step2 > 0)
    {
      insn = emit_insn (gen_add3_insn (stack_pointer_rtx, stack_pointer_rtx,
				       GEN_INT (step2)));

      rtx dwarf = NULL_RTX;
      rtx cfa_adjust_rtx = gen_rtx_PLUS (Pmode, stack_pointer_rtx,
					 const0_rtx);
      dwarf = alloc_reg_note (REG_CFA_DEF_CFA, cfa_adjust_rtx, dwarf);
      RTX_FRAME_RELATED_P (insn) = 1;

      REG_NOTES (insn) = dwarf;
    }

  if (use_restore_libcall)
    {
      rtx dwarf = riscv_adjust_libcall_cfi_epilogue ();
      insn = emit_insn (gen_gpr_restore (GEN_INT (riscv_save_libcall_count (mask))));
      RTX_FRAME_RELATED_P (insn) = 1;
      REG_NOTES (insn) = dwarf;

      emit_jump_insn (gen_gpr_restore_return (ra));
      return;
    }

  /* Add in the __builtin_eh_return stack adjustment. */
  if ((style == EXCEPTION_RETURN) && crtl->calls_eh_return)
    emit_insn (gen_add3_insn (stack_pointer_rtx, stack_pointer_rtx,
			      EH_RETURN_STACKADJ_RTX));

  /* Return from interrupt.  */
  if (cfun->machine->interrupt_handler_p)
    {
      enum riscv_privilege_levels mode = cfun->machine->interrupt_mode;

      gcc_assert (mode != UNKNOWN_MODE);

      if (mode == MACHINE_MODE)
	emit_jump_insn (gen_riscv_mret ());
      else if (mode == SUPERVISOR_MODE)
	emit_jump_insn (gen_riscv_sret ());
      else
	emit_jump_insn (gen_riscv_uret ());
    }
  else if (style != SIBCALL_RETURN)
    emit_jump_insn (gen_simple_return_internal (ra));
}

/* Implement EPILOGUE_USES.  */

bool
riscv_epilogue_uses (unsigned int regno)
{
  if (regno == RETURN_ADDR_REGNUM)
    return true;

  if (epilogue_completed && cfun->machine->interrupt_handler_p)
    {
      /* An interrupt function restores temp regs, so we must indicate that
	 they are live at function end.  */
      if (df_regs_ever_live_p (regno)
	    || (!crtl->is_leaf && call_used_or_fixed_reg_p (regno)))
	return true;
    }

  return false;
}

/* Implement TARGET_SHRINK_WRAP_GET_SEPARATE_COMPONENTS.  */

static sbitmap
riscv_get_separate_components (void)
{
  HOST_WIDE_INT offset;
  sbitmap components = sbitmap_alloc (FIRST_PSEUDO_REGISTER);
  bitmap_clear (components);

  if (riscv_use_save_libcall (&cfun->machine->frame)
      || cfun->machine->interrupt_handler_p)
    return components;

  offset = cfun->machine->frame.gp_sp_offset.to_constant ();
  for (unsigned int regno = GP_REG_FIRST; regno <= GP_REG_LAST; regno++)
    if (BITSET_P (cfun->machine->frame.mask, regno - GP_REG_FIRST))
      {
	/* We can only wrap registers that have small operand offsets.
	   For large offsets a pseudo register might be needed which
	   cannot be created during the shrink wrapping pass.  */
	if (SMALL_OPERAND (offset))
	  bitmap_set_bit (components, regno);

	offset -= UNITS_PER_WORD;
      }

  offset = cfun->machine->frame.fp_sp_offset.to_constant ();
  for (unsigned int regno = FP_REG_FIRST; regno <= FP_REG_LAST; regno++)
    if (BITSET_P (cfun->machine->frame.fmask, regno - FP_REG_FIRST))
      {
	machine_mode mode = TARGET_DOUBLE_FLOAT ? DFmode : SFmode;

	/* We can only wrap registers that have small operand offsets.
	   For large offsets a pseudo register might be needed which
	   cannot be created during the shrink wrapping pass.  */
	if (SMALL_OPERAND (offset))
	  bitmap_set_bit (components, regno);

	offset -= GET_MODE_SIZE (mode).to_constant ();
      }

  /* Don't mess with the hard frame pointer.  */
  if (frame_pointer_needed)
    bitmap_clear_bit (components, HARD_FRAME_POINTER_REGNUM);

  bitmap_clear_bit (components, RETURN_ADDR_REGNUM);

  return components;
}

/* Implement TARGET_SHRINK_WRAP_COMPONENTS_FOR_BB.  */

static sbitmap
riscv_components_for_bb (basic_block bb)
{
  bitmap in = DF_LIVE_IN (bb);
  bitmap gen = &DF_LIVE_BB_INFO (bb)->gen;
  bitmap kill = &DF_LIVE_BB_INFO (bb)->kill;

  sbitmap components = sbitmap_alloc (FIRST_PSEUDO_REGISTER);
  bitmap_clear (components);

  function_abi_aggregator callee_abis;
  rtx_insn *insn;
  FOR_BB_INSNS (bb, insn)
    if (CALL_P (insn))
      callee_abis.note_callee_abi (insn_callee_abi (insn));
  HARD_REG_SET extra_caller_saves = callee_abis.caller_save_regs (*crtl->abi);

  /* GPRs are used in a bb if they are in the IN, GEN, or KILL sets.  */
  for (unsigned int regno = GP_REG_FIRST; regno <= GP_REG_LAST; regno++)
    if (!fixed_regs[regno]
       && !crtl->abi->clobbers_full_reg_p (regno)
       && (TEST_HARD_REG_BIT (extra_caller_saves, regno)
	   || bitmap_bit_p (in, regno)
	   || bitmap_bit_p (gen, regno)
	   || bitmap_bit_p (kill, regno)))
      bitmap_set_bit (components, regno);

  for (unsigned int regno = FP_REG_FIRST; regno <= FP_REG_LAST; regno++)
    if (!fixed_regs[regno]
       && !crtl->abi->clobbers_full_reg_p (regno)
       && (TEST_HARD_REG_BIT (extra_caller_saves, regno)
	   || bitmap_bit_p (in, regno)
	   || bitmap_bit_p (gen, regno)
	   || bitmap_bit_p (kill, regno)))
      bitmap_set_bit (components, regno);

  return components;
}

/* Implement TARGET_SHRINK_WRAP_DISQUALIFY_COMPONENTS.  */

static void
riscv_disqualify_components (sbitmap, edge, sbitmap, bool)
{
  /* Nothing to do for riscv.  */
}

static void
riscv_process_components (sbitmap components, bool prologue_p)
{
  HOST_WIDE_INT offset;
  riscv_save_restore_fn fn = prologue_p? riscv_save_reg : riscv_restore_reg;

  offset = cfun->machine->frame.gp_sp_offset.to_constant ();
  for (unsigned int regno = GP_REG_FIRST; regno <= GP_REG_LAST; regno++)
    if (BITSET_P (cfun->machine->frame.mask, regno - GP_REG_FIRST))
      {
	if (bitmap_bit_p (components, regno))
	  riscv_save_restore_reg (word_mode, regno, offset, fn);

	offset -= UNITS_PER_WORD;
      }

  offset = cfun->machine->frame.fp_sp_offset.to_constant ();
  for (unsigned int regno = FP_REG_FIRST; regno <= FP_REG_LAST; regno++)
    if (BITSET_P (cfun->machine->frame.fmask, regno - FP_REG_FIRST))
      {
	machine_mode mode = TARGET_DOUBLE_FLOAT ? DFmode : SFmode;

	if (bitmap_bit_p (components, regno))
	  riscv_save_restore_reg (mode, regno, offset, fn);

	offset -= GET_MODE_SIZE (mode).to_constant ();
      }
}

/* Implement TARGET_SHRINK_WRAP_EMIT_PROLOGUE_COMPONENTS.  */

static void
riscv_emit_prologue_components (sbitmap components)
{
  riscv_process_components (components, true);
}

/* Implement TARGET_SHRINK_WRAP_EMIT_EPILOGUE_COMPONENTS.  */

static void
riscv_emit_epilogue_components (sbitmap components)
{
  riscv_process_components (components, false);
}

static void
riscv_set_handled_components (sbitmap components)
{
  for (unsigned int regno = GP_REG_FIRST; regno <= GP_REG_LAST; regno++)
    if (bitmap_bit_p (components, regno))
      cfun->machine->reg_is_wrapped_separately[regno] = true;

  for (unsigned int regno = FP_REG_FIRST; regno <= FP_REG_LAST; regno++)
    if (bitmap_bit_p (components, regno))
      cfun->machine->reg_is_wrapped_separately[regno] = true;
}

/* Return nonzero if this function is known to have a null epilogue.
   This allows the optimizer to omit jumps to jumps if no stack
   was created.  */

bool
riscv_can_use_return_insn (void)
{
  return (reload_completed && known_eq (cfun->machine->frame.total_size, 0)
	  && ! cfun->machine->interrupt_handler_p);
}

/* Given that there exists at least one variable that is set (produced)
   by OUT_INSN and read (consumed) by IN_INSN, return true iff
   IN_INSN represents one or more memory store operations and none of
   the variables set by OUT_INSN is used by IN_INSN as the address of a
   store operation.  If either IN_INSN or OUT_INSN does not represent
   a "single" RTL SET expression (as loosely defined by the
   implementation of the single_set function) or a PARALLEL with only
   SETs, CLOBBERs, and USEs inside, this function returns false.

   Borrowed from rs6000, riscv_store_data_bypass_p checks for certain
   conditions that result in assertion failures in the generic
   store_data_bypass_p function and returns FALSE in such cases.

   This is required to make -msave-restore work with the sifive-7
   pipeline description.  */

bool
riscv_store_data_bypass_p (rtx_insn *out_insn, rtx_insn *in_insn)
{
  rtx out_set, in_set;
  rtx out_pat, in_pat;
  rtx out_exp, in_exp;
  int i, j;

  in_set = single_set (in_insn);
  if (in_set)
    {
      if (MEM_P (SET_DEST (in_set)))
	{
	  out_set = single_set (out_insn);
	  if (!out_set)
	    {
	      out_pat = PATTERN (out_insn);
	      if (GET_CODE (out_pat) == PARALLEL)
		{
		  for (i = 0; i < XVECLEN (out_pat, 0); i++)
		    {
		      out_exp = XVECEXP (out_pat, 0, i);
		      if ((GET_CODE (out_exp) == CLOBBER)
			  || (GET_CODE (out_exp) == USE))
			continue;
		      else if (GET_CODE (out_exp) != SET)
			return false;
		    }
		}
	    }
	}
    }
  else
    {
      in_pat = PATTERN (in_insn);
      if (GET_CODE (in_pat) != PARALLEL)
	return false;

      for (i = 0; i < XVECLEN (in_pat, 0); i++)
	{
	  in_exp = XVECEXP (in_pat, 0, i);
	  if ((GET_CODE (in_exp) == CLOBBER) || (GET_CODE (in_exp) == USE))
	    continue;
	  else if (GET_CODE (in_exp) != SET)
	    return false;

	  if (MEM_P (SET_DEST (in_exp)))
	    {
	      out_set = single_set (out_insn);
	      if (!out_set)
		{
		  out_pat = PATTERN (out_insn);
		  if (GET_CODE (out_pat) != PARALLEL)
		    return false;
		  for (j = 0; j < XVECLEN (out_pat, 0); j++)
		    {
		      out_exp = XVECEXP (out_pat, 0, j);
		      if ((GET_CODE (out_exp) == CLOBBER)
			  || (GET_CODE (out_exp) == USE))
			continue;
		      else if (GET_CODE (out_exp) != SET)
			return false;
		    }
		}
	    }
	}
    }

  return store_data_bypass_p (out_insn, in_insn);
}

/* Implement TARGET_SECONDARY_MEMORY_NEEDED.

   When floating-point registers are wider than integer ones, moves between
   them must go through memory.  */

static bool
riscv_secondary_memory_needed (machine_mode mode, reg_class_t class1,
			       reg_class_t class2)
{
  return (!riscv_v_ext_vector_mode_p (mode)
	  && GET_MODE_SIZE (mode).to_constant () > UNITS_PER_WORD
	  && (class1 == FP_REGS) != (class2 == FP_REGS));
}

/* Implement TARGET_REGISTER_MOVE_COST.  */

static int
riscv_register_move_cost (machine_mode mode,
			  reg_class_t from, reg_class_t to)
{
  if ((from == FP_REGS && to == GR_REGS) ||
      (from == GR_REGS && to == FP_REGS))
    return tune_param->fmv_cost;

  return riscv_secondary_memory_needed (mode, from, to) ? 8 : 2;
}

/* Implement TARGET_HARD_REGNO_NREGS.  */

static unsigned int
riscv_hard_regno_nregs (unsigned int regno, machine_mode mode)
{
  if (riscv_v_ext_vector_mode_p (mode))
    {
      /* Handle fractional LMUL, it only occupy part of vector register but
	 still need one vector register to hold.  */
      if (maybe_lt (GET_MODE_SIZE (mode), UNITS_PER_V_REG))
	return 1;

      return exact_div (GET_MODE_SIZE (mode), UNITS_PER_V_REG).to_constant ();
    }

  /* mode for VL or VTYPE are just a marker, not holding value,
     so it always consume one register.  */
  if (regno == VTYPE_REGNUM || regno == VL_REGNUM)
    return 1;

  /* Assume every valid non-vector mode fits in one vector register.  */
  if (V_REG_P (regno))
    return 1;

  if (FP_REG_P (regno))
    return (GET_MODE_SIZE (mode).to_constant () + UNITS_PER_FP_REG - 1) / UNITS_PER_FP_REG;

  /* All other registers are word-sized.  */
  return (GET_MODE_SIZE (mode).to_constant () + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
}

/* Implement TARGET_HARD_REGNO_MODE_OK.  */

static bool
riscv_hard_regno_mode_ok (unsigned int regno, machine_mode mode)
{
  unsigned int nregs = riscv_hard_regno_nregs (regno, mode);

  if (GP_REG_P (regno))
    {
      if (riscv_v_ext_vector_mode_p (mode))
	return false;

      if (!GP_REG_P (regno + nregs - 1))
	return false;
    }
  else if (FP_REG_P (regno))
    {
      if (riscv_v_ext_vector_mode_p (mode))
	return false;

      if (!FP_REG_P (regno + nregs - 1))
	return false;

      if (GET_MODE_CLASS (mode) != MODE_FLOAT
	  && GET_MODE_CLASS (mode) != MODE_COMPLEX_FLOAT)
	return false;

      /* Only use callee-saved registers if a potential callee is guaranteed
	 to spill the requisite width.  */
      if (GET_MODE_UNIT_SIZE (mode) > UNITS_PER_FP_REG
	  || (!call_used_or_fixed_reg_p (regno)
	      && GET_MODE_UNIT_SIZE (mode) > UNITS_PER_FP_ARG))
	return false;
    }
  else if (V_REG_P (regno))
    {
      if (!riscv_v_ext_vector_mode_p (mode))
	return false;

      if (!V_REG_P (regno + nregs - 1))
	return false;

      /* 3.3.2. LMUL = 2,4,8, register numbers should be multiple of 2,4,8.
	 but for mask vector register, register numbers can be any number. */
      int lmul = 1;
      if (known_gt (GET_MODE_SIZE (mode), UNITS_PER_V_REG))
	lmul = exact_div (GET_MODE_SIZE (mode), UNITS_PER_V_REG).to_constant ();
      if (lmul != 1)
	return ((regno % lmul) == 0);
    }
  else if (regno == VL_REGNUM || regno == VTYPE_REGNUM)
    return true;
  else
    return false;

  /* Require same callee-savedness for all registers.  */
  for (unsigned i = 1; i < nregs; i++)
    if (call_used_or_fixed_reg_p (regno)
	!= call_used_or_fixed_reg_p (regno + i))
      return false;

  /* Only use even registers in RV32 ZDINX */
  if (!TARGET_64BIT && TARGET_ZDINX){
    if (GET_MODE_CLASS (mode) == MODE_FLOAT &&
     GET_MODE_UNIT_SIZE (mode) == GET_MODE_SIZE (DFmode))
    return !(regno & 1);
  }

  return true;
}

/* Implement TARGET_MODES_TIEABLE_P.

   Don't allow floating-point modes to be tied, since type punning of
   single-precision and double-precision is implementation defined.  */

static bool
riscv_modes_tieable_p (machine_mode mode1, machine_mode mode2)
{
  return (mode1 == mode2
	  || !(GET_MODE_CLASS (mode1) == MODE_FLOAT
	       && GET_MODE_CLASS (mode2) == MODE_FLOAT));
}

/* Implement CLASS_MAX_NREGS.  */

static unsigned char
riscv_class_max_nregs (reg_class_t rclass, machine_mode mode)
{
  if (reg_class_subset_p (rclass, FP_REGS))
    return riscv_hard_regno_nregs (FP_REG_FIRST, mode);

  if (reg_class_subset_p (rclass, GR_REGS))
    return riscv_hard_regno_nregs (GP_REG_FIRST, mode);

  if (reg_class_subset_p (rclass, V_REGS))
    return riscv_hard_regno_nregs (V_REG_FIRST, mode);

  if (reg_class_subset_p (rclass, VL_REGS))
    return 1;

  if (reg_class_subset_p (rclass, VTYPE_REGS))
    return 1;

  return 0;
}

/* Implement TARGET_MEMORY_MOVE_COST.  */

static int
riscv_memory_move_cost (machine_mode mode, reg_class_t rclass, bool in)
{
  return (tune_param->memory_cost
	  + memory_move_secondary_cost (mode, rclass, in));
}

/* Return the number of instructions that can be issued per cycle.  */

static int
riscv_issue_rate (void)
{
  return tune_param->issue_rate;
}

/* Auxiliary function to emit RISC-V ELF attribute. */
static void
riscv_emit_attribute ()
{
  fprintf (asm_out_file, "\t.attribute arch, \"%s\"\n",
	   riscv_arch_str ().c_str ());

  fprintf (asm_out_file, "\t.attribute unaligned_access, %d\n",
           TARGET_STRICT_ALIGN ? 0 : 1);

  fprintf (asm_out_file, "\t.attribute stack_align, %d\n",
           riscv_stack_boundary / 8);
}

/* Implement TARGET_ASM_FILE_START.  */

static void
riscv_file_start (void)
{
  default_file_start ();

  /* Instruct GAS to generate position-[in]dependent code.  */
  fprintf (asm_out_file, "\t.option %spic\n", (flag_pic ? "" : "no"));

  /* If the user specifies "-mno-relax" on the command line then disable linker
     relaxation in the assembler.  */
  if (! riscv_mrelax)
    fprintf (asm_out_file, "\t.option norelax\n");

  /* If the user specifies "-mcsr-check" on the command line then enable csr
     check in the assembler.  */
  if (riscv_mcsr_check)
    fprintf (asm_out_file, "\t.option csr-check\n");

  if (riscv_emit_attribute_p)
    riscv_emit_attribute ();
}

/* Implement TARGET_ASM_OUTPUT_MI_THUNK.  Generate rtl rather than asm text
   in order to avoid duplicating too much logic from elsewhere.  */

static void
riscv_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
		      HOST_WIDE_INT delta, HOST_WIDE_INT vcall_offset,
		      tree function)
{
  const char *fnname = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (thunk_fndecl));
  rtx this_rtx, temp1, temp2, fnaddr;
  rtx_insn *insn;

  /* Pretend to be a post-reload pass while generating rtl.  */
  reload_completed = 1;

  /* Mark the end of the (empty) prologue.  */
  emit_note (NOTE_INSN_PROLOGUE_END);

  /* Determine if we can use a sibcall to call FUNCTION directly.  */
  fnaddr = gen_rtx_MEM (FUNCTION_MODE, XEXP (DECL_RTL (function), 0));

  /* We need two temporary registers in some cases.  */
  temp1 = gen_rtx_REG (Pmode, RISCV_PROLOGUE_TEMP_REGNUM);
  temp2 = gen_rtx_REG (Pmode, STATIC_CHAIN_REGNUM);

  /* Find out which register contains the "this" pointer.  */
  if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function))
    this_rtx = gen_rtx_REG (Pmode, GP_ARG_FIRST + 1);
  else
    this_rtx = gen_rtx_REG (Pmode, GP_ARG_FIRST);

  /* Add DELTA to THIS_RTX.  */
  if (delta != 0)
    {
      rtx offset = GEN_INT (delta);
      if (!SMALL_OPERAND (delta))
	{
	  riscv_emit_move (temp1, offset);
	  offset = temp1;
	}
      emit_insn (gen_add3_insn (this_rtx, this_rtx, offset));
    }

  /* If needed, add *(*THIS_RTX + VCALL_OFFSET) to THIS_RTX.  */
  if (vcall_offset != 0)
    {
      rtx addr;

      /* Set TEMP1 to *THIS_RTX.  */
      riscv_emit_move (temp1, gen_rtx_MEM (Pmode, this_rtx));

      /* Set ADDR to a legitimate address for *THIS_RTX + VCALL_OFFSET.  */
      addr = riscv_add_offset (temp2, temp1, vcall_offset);

      /* Load the offset and add it to THIS_RTX.  */
      riscv_emit_move (temp1, gen_rtx_MEM (Pmode, addr));
      emit_insn (gen_add3_insn (this_rtx, this_rtx, temp1));
    }

  /* Jump to the target function.  */
  insn = emit_call_insn (gen_sibcall (fnaddr, const0_rtx, NULL, const0_rtx));
  SIBLING_CALL_P (insn) = 1;

  /* Run just enough of rest_of_compilation.  This sequence was
     "borrowed" from alpha.cc.  */
  insn = get_insns ();
  split_all_insns_noflow ();
  shorten_branches (insn);
  assemble_start_function (thunk_fndecl, fnname);
  final_start_function (insn, file, 1);
  final (insn, file, 1);
  final_end_function ();
  assemble_end_function (thunk_fndecl, fnname);

  /* Clean up the vars set above.  Note that final_end_function resets
     the global pointer for us.  */
  reload_completed = 0;
}

/* Allocate a chunk of memory for per-function machine-dependent data.  */

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

/* Return the VLEN value associated with -march.
   TODO: So far we only support length-agnostic value. */
static poly_uint16
riscv_convert_vector_bits (void)
{
  if (TARGET_MIN_VLEN > 32)
    {
      /* When targetting minimum VLEN > 32, we should use 64-bit chunk size.
	 Otherwise we can not include SEW = 64bits.
	 Runtime invariant: The single indeterminate represent the
	 number of 64-bit chunks in a vector beyond minimum length of 64 bits.
	 Thus the number of bytes in a vector is 8 + 8 * x1 which is
	 riscv_vector_chunks * 8 = poly_int (8, 8).  */
      riscv_bytes_per_vector_chunk = 8;
    }
  else
    {
      /* When targetting minimum VLEN = 32, we should use 32-bit
	 chunk size. Runtime invariant: The single indeterminate represent the
	 number of 32-bit chunks in a vector beyond minimum length of 32 bits.
	 Thus the number of bytes in a vector is 4 + 4 * x1 which is
	 riscv_vector_chunks * 4 = poly_int (4, 4).  */
      riscv_bytes_per_vector_chunk = 4;
    }

  /* Set riscv_vector_chunks as poly (1, 1) run-time constant if TARGET_VECTOR
     is enabled. Set riscv_vector_chunks as 1 compile-time constant if
     TARGET_VECTOR is disabled. riscv_vector_chunks is used in "riscv-modes.def"
     to set RVV mode size. The RVV machine modes size are run-time constant if
     TARGET_VECTOR is enabled. The RVV machine modes size remains default
     compile-time constant if TARGET_VECTOR is disabled.  */
  return TARGET_VECTOR ? poly_uint16 (1, 1) : 1;
}

/* Implement TARGET_OPTION_OVERRIDE.  */

static void
riscv_option_override (void)
{
  const struct riscv_tune_info *cpu;

#ifdef SUBTARGET_OVERRIDE_OPTIONS
  SUBTARGET_OVERRIDE_OPTIONS;
#endif

  flag_pcc_struct_return = 0;

  if (flag_pic)
    g_switch_value = 0;

  /* The presence of the M extension implies that division instructions
     are present, so include them unless explicitly disabled.  */
  if (TARGET_MUL && (target_flags_explicit & MASK_DIV) == 0)
    target_flags |= MASK_DIV;
  else if (!TARGET_MUL && TARGET_DIV)
    error ("%<-mdiv%> requires %<-march%> to subsume the %<M%> extension");

  /* Likewise floating-point division and square root.  */
  if ((TARGET_HARD_FLOAT || TARGET_ZFINX) && (target_flags_explicit & MASK_FDIV) == 0)
    target_flags |= MASK_FDIV;

  /* Handle -mtune, use -mcpu if -mtune is not given, and use default -mtune
     if -mtune and -mcpu both not given.  */
  cpu = riscv_parse_tune (riscv_tune_string ? riscv_tune_string :
			  (riscv_cpu_string ? riscv_cpu_string :
			   RISCV_TUNE_STRING_DEFAULT));
  riscv_microarchitecture = cpu->microarchitecture;
  tune_param = optimize_size ? &optimize_size_tune_info : cpu->tune_param;

  /* Use -mtune's setting for slow_unaligned_access, even when optimizing
     for size.  For architectures that trap and emulate unaligned accesses,
     the performance cost is too great, even for -Os.  Similarly, if
     -m[no-]strict-align is left unspecified, heed -mtune's advice.  */
  riscv_slow_unaligned_access_p = (cpu->tune_param->slow_unaligned_access
				   || TARGET_STRICT_ALIGN);
  if ((target_flags_explicit & MASK_STRICT_ALIGN) == 0
      && cpu->tune_param->slow_unaligned_access)
    target_flags |= MASK_STRICT_ALIGN;

  /* If the user hasn't specified a branch cost, use the processor's
     default.  */
  if (riscv_branch_cost == 0)
    riscv_branch_cost = tune_param->branch_cost;

  /* Function to allocate machine-dependent function status.  */
  init_machine_status = &riscv_init_machine_status;

  if (flag_pic)
    riscv_cmodel = CM_PIC;

  /* We get better code with explicit relocs for CM_MEDLOW, but
     worse code for the others (for now).  Pick the best default.  */
  if ((target_flags_explicit & MASK_EXPLICIT_RELOCS) == 0)
    if (riscv_cmodel == CM_MEDLOW)
      target_flags |= MASK_EXPLICIT_RELOCS;

  /* Require that the ISA supports the requested floating-point ABI.  */
  if (UNITS_PER_FP_ARG > (TARGET_HARD_FLOAT ? UNITS_PER_FP_REG : 0))
    error ("requested ABI requires %<-march%> to subsume the %qc extension",
	   UNITS_PER_FP_ARG > 8 ? 'Q' : (UNITS_PER_FP_ARG > 4 ? 'D' : 'F'));

  if (TARGET_RVE && riscv_abi != ABI_ILP32E)
    error ("rv32e requires ilp32e ABI");

  // Zfinx require abi ilp32,ilp32e or lp64.
  if (TARGET_ZFINX && riscv_abi != ABI_ILP32
      && riscv_abi != ABI_LP64 && riscv_abi != ABI_ILP32E)
    error ("z*inx requires ABI ilp32, ilp32e or lp64");

  /* We do not yet support ILP32 on RV64.  */
  if (BITS_PER_WORD != POINTER_SIZE)
    error ("ABI requires %<-march=rv%d%>", POINTER_SIZE);

  /* Validate -mpreferred-stack-boundary= value.  */
  riscv_stack_boundary = ABI_STACK_BOUNDARY;
  if (riscv_preferred_stack_boundary_arg)
    {
      int min = ctz_hwi (STACK_BOUNDARY / 8);
      int max = 8;

      if (!IN_RANGE (riscv_preferred_stack_boundary_arg, min, max))
	error ("%<-mpreferred-stack-boundary=%d%> must be between %d and %d",
	       riscv_preferred_stack_boundary_arg, min, max);

      riscv_stack_boundary = 8 << riscv_preferred_stack_boundary_arg;
    }

  if (riscv_emit_attribute_p < 0)
#ifdef HAVE_AS_RISCV_ATTRIBUTE
    riscv_emit_attribute_p = TARGET_RISCV_ATTRIBUTE;
#else
    riscv_emit_attribute_p = 0;

  if (riscv_emit_attribute_p)
    error ("%<-mriscv-attribute%> RISC-V ELF attribute requires GNU as 2.32"
	   " [%<-mriscv-attribute%>]");
#endif

  if (riscv_stack_protector_guard == SSP_GLOBAL
      && OPTION_SET_P (riscv_stack_protector_guard_offset_str))
    {
      error ("incompatible options %<-mstack-protector-guard=global%> and "
	     "%<-mstack-protector-guard-offset=%s%>",
	     riscv_stack_protector_guard_offset_str);
    }

  if (riscv_stack_protector_guard == SSP_TLS
      && !(OPTION_SET_P (riscv_stack_protector_guard_offset_str)
	   && OPTION_SET_P (riscv_stack_protector_guard_reg_str)))
    {
      error ("both %<-mstack-protector-guard-offset%> and "
	     "%<-mstack-protector-guard-reg%> must be used "
	     "with %<-mstack-protector-guard=sysreg%>");
    }

  if (OPTION_SET_P (riscv_stack_protector_guard_reg_str))
    {
      const char *str = riscv_stack_protector_guard_reg_str;
      int reg = decode_reg_name (str);

      if (!IN_RANGE (reg, GP_REG_FIRST + 1, GP_REG_LAST))
	error ("%qs is not a valid base register in %qs", str,
	       "-mstack-protector-guard-reg=");

      riscv_stack_protector_guard_reg = reg;
    }

  if (OPTION_SET_P (riscv_stack_protector_guard_offset_str))
    {
      char *end;
      const char *str = riscv_stack_protector_guard_offset_str;
      errno = 0;
      long offs = strtol (riscv_stack_protector_guard_offset_str, &end, 0);

      if (!*str || *end || errno)
	error ("%qs is not a valid number in %qs", str,
	       "-mstack-protector-guard-offset=");

      if (!SMALL_OPERAND (offs))
	error ("%qs is not a valid offset in %qs", str,
	       "-mstack-protector-guard-offset=");

      riscv_stack_protector_guard_offset = offs;
    }

  /* Convert -march to a chunks count.  */
  riscv_vector_chunks = riscv_convert_vector_bits ();
}

/* Implement TARGET_CONDITIONAL_REGISTER_USAGE.  */

static void
riscv_conditional_register_usage (void)
{
  /* We have only x0~x15 on RV32E.  */
  if (TARGET_RVE)
    {
      for (int r = 16; r <= 31; r++)
	fixed_regs[r] = 1;
    }

  if (riscv_abi == ABI_ILP32E)
    {
      for (int r = 16; r <= 31; r++)
	call_used_regs[r] = 1;
    }

  if (!TARGET_HARD_FLOAT)
    {
      for (int regno = FP_REG_FIRST; regno <= FP_REG_LAST; regno++)
	fixed_regs[regno] = call_used_regs[regno] = 1;
    }

  /* In the soft-float ABI, there are no callee-saved FP registers.  */
  if (UNITS_PER_FP_ARG == 0)
    {
      for (int regno = FP_REG_FIRST; regno <= FP_REG_LAST; regno++)
	call_used_regs[regno] = 1;
    }

  if (!TARGET_VECTOR)
    {
      for (int regno = V_REG_FIRST; regno <= V_REG_LAST; regno++)
	fixed_regs[regno] = call_used_regs[regno] = 1;

      fixed_regs[VTYPE_REGNUM] = call_used_regs[VTYPE_REGNUM] = 1;
      fixed_regs[VL_REGNUM] = call_used_regs[VL_REGNUM] = 1;
    }
}

/* Return a register priority for hard reg REGNO.  */

static int
riscv_register_priority (int regno)
{
  /* Favor compressed registers to improve the odds of RVC instruction
     selection.  */
  if (riscv_compressed_reg_p (regno))
    return 1;

  return 0;
}

/* Implement TARGET_TRAMPOLINE_INIT.  */

static void
riscv_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value)
{
  rtx addr, end_addr, mem;
  uint32_t trampoline[4];
  unsigned int i;
  HOST_WIDE_INT static_chain_offset, target_function_offset;

  /* Work out the offsets of the pointers from the start of the
     trampoline code.  */
  gcc_assert (ARRAY_SIZE (trampoline) * 4 == TRAMPOLINE_CODE_SIZE);

  /* Get pointers to the beginning and end of the code block.  */
  addr = force_reg (Pmode, XEXP (m_tramp, 0));
  end_addr = riscv_force_binary (Pmode, PLUS, addr,
				 GEN_INT (TRAMPOLINE_CODE_SIZE));


  if (Pmode == SImode)
    {
      chain_value = force_reg (Pmode, chain_value);

      rtx target_function = force_reg (Pmode, XEXP (DECL_RTL (fndecl), 0));
      /* lui     t2, hi(chain)
	 lui     t0, hi(func)
	 addi    t2, t2, lo(chain)
	 jr      t0, lo(func)
      */
      unsigned HOST_WIDE_INT lui_hi_chain_code, lui_hi_func_code;
      unsigned HOST_WIDE_INT lo_chain_code, lo_func_code;

      rtx uimm_mask = force_reg (SImode, gen_int_mode (-IMM_REACH, SImode));

      /* 0xfff.  */
      rtx imm12_mask = gen_reg_rtx (SImode);
      emit_insn (gen_one_cmplsi2 (imm12_mask, uimm_mask));

      rtx fixup_value = force_reg (SImode, gen_int_mode (IMM_REACH/2, SImode));

      /* Gen lui t2, hi(chain).  */
      rtx hi_chain = riscv_force_binary (SImode, PLUS, chain_value,
					 fixup_value);
      hi_chain = riscv_force_binary (SImode, AND, hi_chain,
				     uimm_mask);
      lui_hi_chain_code = OPCODE_LUI | (STATIC_CHAIN_REGNUM << SHIFT_RD);
      rtx lui_hi_chain = riscv_force_binary (SImode, IOR, hi_chain,
					     gen_int_mode (lui_hi_chain_code, SImode));

      mem = adjust_address (m_tramp, SImode, 0);
      riscv_emit_move (mem, riscv_swap_instruction (lui_hi_chain));

      /* Gen lui t0, hi(func).  */
      rtx hi_func = riscv_force_binary (SImode, PLUS, target_function,
					fixup_value);
      hi_func = riscv_force_binary (SImode, AND, hi_func,
				    uimm_mask);
      lui_hi_func_code = OPCODE_LUI | (RISCV_PROLOGUE_TEMP_REGNUM << SHIFT_RD);
      rtx lui_hi_func = riscv_force_binary (SImode, IOR, hi_func,
					    gen_int_mode (lui_hi_func_code, SImode));

      mem = adjust_address (m_tramp, SImode, 1 * GET_MODE_SIZE (SImode));
      riscv_emit_move (mem, riscv_swap_instruction (lui_hi_func));

      /* Gen addi t2, t2, lo(chain).  */
      rtx lo_chain = riscv_force_binary (SImode, AND, chain_value,
					 imm12_mask);
      lo_chain = riscv_force_binary (SImode, ASHIFT, lo_chain, GEN_INT (20));

      lo_chain_code = OPCODE_ADDI
		      | (STATIC_CHAIN_REGNUM << SHIFT_RD)
		      | (STATIC_CHAIN_REGNUM << SHIFT_RS1);

      rtx addi_lo_chain = riscv_force_binary (SImode, IOR, lo_chain,
					      force_reg (SImode, GEN_INT (lo_chain_code)));

      mem = adjust_address (m_tramp, SImode, 2 * GET_MODE_SIZE (SImode));
      riscv_emit_move (mem, riscv_swap_instruction (addi_lo_chain));

      /* Gen jr t0, lo(func).  */
      rtx lo_func = riscv_force_binary (SImode, AND, target_function,
					imm12_mask);
      lo_func = riscv_force_binary (SImode, ASHIFT, lo_func, GEN_INT (20));

      lo_func_code = OPCODE_JALR | (RISCV_PROLOGUE_TEMP_REGNUM << SHIFT_RS1);

      rtx jr_lo_func = riscv_force_binary (SImode, IOR, lo_func,
					   force_reg (SImode, GEN_INT (lo_func_code)));

      mem = adjust_address (m_tramp, SImode, 3 * GET_MODE_SIZE (SImode));
      riscv_emit_move (mem, riscv_swap_instruction (jr_lo_func));
    }
  else
    {
      static_chain_offset = TRAMPOLINE_CODE_SIZE;
      target_function_offset = static_chain_offset + GET_MODE_SIZE (ptr_mode);

      /* auipc   t2, 0
	 l[wd]   t0, target_function_offset(t2)
	 l[wd]   t2, static_chain_offset(t2)
	 jr      t0
      */
      trampoline[0] = OPCODE_AUIPC | (STATIC_CHAIN_REGNUM << SHIFT_RD);
      trampoline[1] = (Pmode == DImode ? OPCODE_LD : OPCODE_LW)
		      | (RISCV_PROLOGUE_TEMP_REGNUM << SHIFT_RD)
		      | (STATIC_CHAIN_REGNUM << SHIFT_RS1)
		      | (target_function_offset << SHIFT_IMM);
      trampoline[2] = (Pmode == DImode ? OPCODE_LD : OPCODE_LW)
		      | (STATIC_CHAIN_REGNUM << SHIFT_RD)
		      | (STATIC_CHAIN_REGNUM << SHIFT_RS1)
		      | (static_chain_offset << SHIFT_IMM);
      trampoline[3] = OPCODE_JALR | (RISCV_PROLOGUE_TEMP_REGNUM << SHIFT_RS1);

      /* Copy the trampoline code.  */
      for (i = 0; i < ARRAY_SIZE (trampoline); i++)
	{
	  if (BYTES_BIG_ENDIAN)
	    trampoline[i] = __builtin_bswap32(trampoline[i]);
	  mem = adjust_address (m_tramp, SImode, i * GET_MODE_SIZE (SImode));
	  riscv_emit_move (mem, gen_int_mode (trampoline[i], SImode));
	}

      /* Set up the static chain pointer field.  */
      mem = adjust_address (m_tramp, ptr_mode, static_chain_offset);
      riscv_emit_move (mem, chain_value);

      /* Set up the target function field.  */
      mem = adjust_address (m_tramp, ptr_mode, target_function_offset);
      riscv_emit_move (mem, XEXP (DECL_RTL (fndecl), 0));
    }

  /* Flush the code part of the trampoline.  */
  emit_insn (gen_add3_insn (end_addr, addr, GEN_INT (TRAMPOLINE_SIZE)));
  emit_insn (gen_clear_cache (addr, end_addr));
}

/* Implement TARGET_FUNCTION_OK_FOR_SIBCALL.  */

static bool
riscv_function_ok_for_sibcall (tree decl ATTRIBUTE_UNUSED,
			       tree exp ATTRIBUTE_UNUSED)
{
  /* Don't use sibcalls when use save-restore routine.  */
  if (TARGET_SAVE_RESTORE)
    return false;

  /* Don't use sibcall for naked functions.  */
  if (cfun->machine->naked_p)
    return false;

  /* Don't use sibcall for interrupt functions.  */
  if (cfun->machine->interrupt_handler_p)
    return false;

  return true;
}

/* Get the interrupt type, return UNKNOWN_MODE if it's not
   interrupt function. */
static enum riscv_privilege_levels
riscv_get_interrupt_type (tree decl)
{
  gcc_assert (decl != NULL_TREE);

  if ((TREE_CODE(decl) != FUNCTION_DECL)
      || (!riscv_interrupt_type_p (TREE_TYPE (decl))))
    return UNKNOWN_MODE;

  tree attr_args
    = TREE_VALUE (lookup_attribute ("interrupt",
				    TYPE_ATTRIBUTES (TREE_TYPE (decl))));

  if (attr_args && TREE_CODE (TREE_VALUE (attr_args)) != VOID_TYPE)
    {
      const char *string = TREE_STRING_POINTER (TREE_VALUE (attr_args));

      if (!strcmp (string, "user"))
	return USER_MODE;
      else if (!strcmp (string, "supervisor"))
	return SUPERVISOR_MODE;
      else /* Must be "machine".  */
	return MACHINE_MODE;
    }
  else
    /* Interrupt attributes are machine mode by default.  */
    return MACHINE_MODE;
}

/* Implement `TARGET_SET_CURRENT_FUNCTION'.  */
/* Sanity cheching for above function attributes.  */
static void
riscv_set_current_function (tree decl)
{
  if (decl == NULL_TREE
      || current_function_decl == NULL_TREE
      || current_function_decl == error_mark_node
      || ! cfun->machine
      || cfun->machine->attributes_checked_p)
    return;

  cfun->machine->naked_p = riscv_naked_function_p (decl);
  cfun->machine->interrupt_handler_p
    = riscv_interrupt_type_p (TREE_TYPE (decl));

  if (cfun->machine->naked_p && cfun->machine->interrupt_handler_p)
    error ("function attributes %qs and %qs are mutually exclusive",
	   "interrupt", "naked");

  if (cfun->machine->interrupt_handler_p)
    {
      tree ret = TREE_TYPE (TREE_TYPE (decl));
      tree args = TYPE_ARG_TYPES (TREE_TYPE (decl));

      if (TREE_CODE (ret) != VOID_TYPE)
	error ("%qs function cannot return a value", "interrupt");

      if (args && TREE_CODE (TREE_VALUE (args)) != VOID_TYPE)
	error ("%qs function cannot have arguments", "interrupt");

      cfun->machine->interrupt_mode = riscv_get_interrupt_type (decl);

      gcc_assert (cfun->machine->interrupt_mode != UNKNOWN_MODE);
    }

  /* Don't print the above diagnostics more than once.  */
  cfun->machine->attributes_checked_p = 1;
}

/* Implement TARGET_MERGE_DECL_ATTRIBUTES. */
static tree
riscv_merge_decl_attributes (tree olddecl, tree newdecl)
{
  tree combined_attrs;

  enum riscv_privilege_levels old_interrupt_type
    = riscv_get_interrupt_type (olddecl);
  enum riscv_privilege_levels new_interrupt_type
    = riscv_get_interrupt_type (newdecl);

  /* Check old and new has same interrupt type. */
  if ((old_interrupt_type != UNKNOWN_MODE)
      && (new_interrupt_type != UNKNOWN_MODE)
      && (old_interrupt_type != new_interrupt_type))
    error ("%qs function cannot have different interrupt type", "interrupt");

  /* Create combined attributes.  */
  combined_attrs = merge_attributes (DECL_ATTRIBUTES (olddecl),
                                     DECL_ATTRIBUTES (newdecl));

  return combined_attrs;
}

/* Implement TARGET_CANNOT_COPY_INSN_P.  */

static bool
riscv_cannot_copy_insn_p (rtx_insn *insn)
{
  return recog_memoized (insn) >= 0 && get_attr_cannot_copy (insn);
}

/* Implement TARGET_SLOW_UNALIGNED_ACCESS.  */

static bool
riscv_slow_unaligned_access (machine_mode, unsigned int)
{
  return riscv_slow_unaligned_access_p;
}

/* Implement TARGET_CAN_CHANGE_MODE_CLASS.  */

static bool
riscv_can_change_mode_class (machine_mode, machine_mode, reg_class_t rclass)
{
  return !reg_classes_intersect_p (FP_REGS, rclass);
}


/* Implement TARGET_CONSTANT_ALIGNMENT.  */

static HOST_WIDE_INT
riscv_constant_alignment (const_tree exp, HOST_WIDE_INT align)
{
  if ((TREE_CODE (exp) == STRING_CST || TREE_CODE (exp) == CONSTRUCTOR)
      && (riscv_align_data_type == riscv_align_data_type_xlen))
    return MAX (align, BITS_PER_WORD);
  return align;
}

/* Implement TARGET_PROMOTE_FUNCTION_MODE.  */

/* This function is equivalent to default_promote_function_mode_always_promote
   except that it returns a promoted mode even if type is NULL_TREE.  This is
   needed by libcalls which have no type (only a mode) such as fixed conversion
   routines that take a signed or unsigned char/short/int argument and convert
   it to a fixed type.  */

static machine_mode
riscv_promote_function_mode (const_tree type ATTRIBUTE_UNUSED,
			     machine_mode mode,
			     int *punsignedp ATTRIBUTE_UNUSED,
			     const_tree fntype ATTRIBUTE_UNUSED,
			     int for_return ATTRIBUTE_UNUSED)
{
  int unsignedp;

  if (type != NULL_TREE)
    return promote_mode (type, mode, punsignedp);

  unsignedp = *punsignedp;
  PROMOTE_MODE (as_a <scalar_mode> (mode), unsignedp, type);
  *punsignedp = unsignedp;
  return mode;
}

/* Implement TARGET_MACHINE_DEPENDENT_REORG.  */

static void
riscv_reorg (void)
{
  /* Do nothing unless we have -msave-restore */
  if (TARGET_SAVE_RESTORE)
    riscv_remove_unneeded_save_restore_calls ();
}

/* Return nonzero if register FROM_REGNO can be renamed to register
   TO_REGNO.  */

bool
riscv_hard_regno_rename_ok (unsigned from_regno ATTRIBUTE_UNUSED,
			    unsigned to_regno)
{
  /* Interrupt functions can only use registers that have already been
     saved by the prologue, even if they would normally be
     call-clobbered.  */
  return !cfun->machine->interrupt_handler_p || df_regs_ever_live_p (to_regno);
}

/* Implement TARGET_NEW_ADDRESS_PROFITABLE_P.  */

bool
riscv_new_address_profitable_p (rtx memref, rtx_insn *insn, rtx new_addr)
{
  /* Prefer old address if it is less expensive.  */
  addr_space_t as = MEM_ADDR_SPACE (memref);
  bool speed = optimize_bb_for_speed_p (BLOCK_FOR_INSN (insn));
  int old_cost = address_cost (XEXP (memref, 0), GET_MODE (memref), as, speed);
  int new_cost = address_cost (new_addr, GET_MODE (memref), as, speed);
  return new_cost <= old_cost;
}

/* Helper function for generating gpr_save pattern.  */

rtx
riscv_gen_gpr_save_insn (struct riscv_frame_info *frame)
{
  unsigned count = riscv_save_libcall_count (frame->mask);
  /* 1 for unspec 2 for clobber t0/t1 and 1 for ra.  */
  unsigned veclen = 1 + 2 + 1 + count;
  rtvec vec = rtvec_alloc (veclen);

  gcc_assert (veclen <= ARRAY_SIZE (gpr_save_reg_order));

  RTVEC_ELT (vec, 0) =
    gen_rtx_UNSPEC_VOLATILE (VOIDmode,
      gen_rtvec (1, GEN_INT (count)), UNSPECV_GPR_SAVE);

  for (unsigned i = 1; i < veclen; ++i)
    {
      unsigned regno = gpr_save_reg_order[i];
      rtx reg = gen_rtx_REG (Pmode, regno);
      rtx elt;

      /* t0 and t1 are CLOBBERs, others are USEs.  */
      if (i < 3)
	elt = gen_rtx_CLOBBER (Pmode, reg);
      else
	elt = gen_rtx_USE (Pmode, reg);

      RTVEC_ELT (vec, i) = elt;
    }

  /* Largest number of caller-save register must set in mask if we are
     not using __riscv_save_0.  */
  gcc_assert ((count == 0) ||
	      BITSET_P (frame->mask, gpr_save_reg_order[veclen - 1]));

  return gen_rtx_PARALLEL (VOIDmode, vec);
}

/* Return true if it's valid gpr_save pattern.  */

bool
riscv_gpr_save_operation_p (rtx op)
{
  unsigned len = XVECLEN (op, 0);

  if (len > ARRAY_SIZE (gpr_save_reg_order))
    return false;

  for (unsigned i = 0; i < len; i++)
    {
      rtx elt = XVECEXP (op, 0, i);
      if (i == 0)
	{
	  /* First element in parallel is unspec.  */
	  if (GET_CODE (elt) != UNSPEC_VOLATILE
	      || GET_CODE (XVECEXP (elt, 0, 0)) != CONST_INT
	      || XINT (elt, 1) != UNSPECV_GPR_SAVE)
	    return false;
	}
      else
	{
	  /* Two CLOBBER and USEs, must check the order.  */
	  unsigned expect_code = i < 3 ? CLOBBER : USE;
	  if (GET_CODE (elt) != expect_code
	      || !REG_P (XEXP (elt, 1))
	      || (REGNO (XEXP (elt, 1)) != gpr_save_reg_order[i]))
	    return false;
	}
	break;
    }
  return true;
}

/* Implement TARGET_ASAN_SHADOW_OFFSET.  */

static unsigned HOST_WIDE_INT
riscv_asan_shadow_offset (void)
{
  /* We only have libsanitizer support for RV64 at present.

     This number must match kRiscv*_ShadowOffset* in the file
     libsanitizer/asan/asan_mapping.h which is currently 1<<29 for rv64,
     even though 1<<36 makes more sense.  */
  return TARGET_64BIT ? (HOST_WIDE_INT_1 << 29) : 0;
}

/* Implement TARGET_MANGLE_TYPE.  */

static const char *
riscv_mangle_type (const_tree type)
{
  /* Half-precision float, _Float16 is "DF16_".  */
  if (TREE_CODE (type) == REAL_TYPE && TYPE_PRECISION (type) == 16)
    return "DF16_";

  /* Mangle all vector type for vector extension.  */
  /* The mangle name follows the rule of RVV LLVM
     that is "u" + length of (abi_name) + abi_name. */
  if (TYPE_NAME (type) != NULL)
    {
      const char *res = riscv_vector::mangle_builtin_type (type);
      if (res)
	return res;
    }

  /* Use the default mangling.  */
  return NULL;
}

/* Implement TARGET_SCALAR_MODE_SUPPORTED_P.  */

static bool
riscv_scalar_mode_supported_p (scalar_mode mode)
{
  if (mode == HFmode)
    return true;
  else
    return default_scalar_mode_supported_p (mode);
}

/* Implement TARGET_LIBGCC_FLOATING_MODE_SUPPORTED_P - return TRUE
   if MODE is HFmode, and punt to the generic implementation otherwise.  */

static bool
riscv_libgcc_floating_mode_supported_p (scalar_float_mode mode)
{
  if (mode == HFmode)
    return true;
  else
    return default_libgcc_floating_mode_supported_p (mode);
}

/* Set the value of FLT_EVAL_METHOD.
   ISO/IEC TS 18661-3 defines two values that we'd like to make use of:

    0: evaluate all operations and constants, whose semantic type has at
       most the range and precision of type float, to the range and
       precision of float; evaluate all other operations and constants to
       the range and precision of the semantic type;

    N, where _FloatN is a supported interchange floating type
       evaluate all operations and constants, whose semantic type has at
       most the range and precision of _FloatN type, to the range and
       precision of the _FloatN type; evaluate all other operations and
       constants to the range and precision of the semantic type;

   If we have the zfh/zhinx extensions then we support _Float16 in native
   precision, so we should set this to 16.  */
static enum flt_eval_method
riscv_excess_precision (enum excess_precision_type type)
{
  switch (type)
    {
    case EXCESS_PRECISION_TYPE_FAST:
    case EXCESS_PRECISION_TYPE_STANDARD:
      return ((TARGET_ZFH || TARGET_ZHINX)
		? FLT_EVAL_METHOD_PROMOTE_TO_FLOAT16
		: FLT_EVAL_METHOD_PROMOTE_TO_FLOAT);
    case EXCESS_PRECISION_TYPE_IMPLICIT:
    case EXCESS_PRECISION_TYPE_FLOAT16:
      return FLT_EVAL_METHOD_PROMOTE_TO_FLOAT16;
    default:
      gcc_unreachable ();
    }
  return FLT_EVAL_METHOD_UNPREDICTABLE;
}

/* Implement TARGET_FLOATN_MODE.  */
static opt_scalar_float_mode
riscv_floatn_mode (int n, bool extended)
{
  if (!extended && n == 16)
    return HFmode;

  return default_floatn_mode (n, extended);
}

static void
riscv_init_libfuncs (void)
{
  /* Half-precision float operations.  The compiler handles all operations
     with NULL libfuncs by converting to SFmode.  */

  /* Arithmetic.  */
  set_optab_libfunc (add_optab, HFmode, NULL);
  set_optab_libfunc (sdiv_optab, HFmode, NULL);
  set_optab_libfunc (smul_optab, HFmode, NULL);
  set_optab_libfunc (neg_optab, HFmode, NULL);
  set_optab_libfunc (sub_optab, HFmode, NULL);

  /* Comparisons.  */
  set_optab_libfunc (eq_optab, HFmode, NULL);
  set_optab_libfunc (ne_optab, HFmode, NULL);
  set_optab_libfunc (lt_optab, HFmode, NULL);
  set_optab_libfunc (le_optab, HFmode, NULL);
  set_optab_libfunc (ge_optab, HFmode, NULL);
  set_optab_libfunc (gt_optab, HFmode, NULL);
  set_optab_libfunc (unord_optab, HFmode, NULL);
}

#if CHECKING_P
void
riscv_reinit (void)
{
  riscv_option_override ();
  init_adjust_machine_modes ();
  init_derived_machine_modes ();
  reinit_regs ();
  init_optabs ();
}
#endif

#if CHECKING_P
#undef TARGET_RUN_TARGET_SELFTESTS
#define TARGET_RUN_TARGET_SELFTESTS selftest::riscv_run_selftests
#endif /* #if CHECKING_P */

/* Implement TARGET_VECTOR_MODE_SUPPORTED_P.  */

static bool
riscv_vector_mode_supported_p (machine_mode mode)
{
  if (TARGET_VECTOR)
    return riscv_v_ext_vector_mode_p (mode);

  return false;
}

/* Implement TARGET_VERIFY_TYPE_CONTEXT.  */

static bool
riscv_verify_type_context (location_t loc, type_context_kind context,
			   const_tree type, bool silent_p)
{
  return riscv_vector::verify_type_context (loc, context, type, silent_p);
}

/* Implement TARGET_VECTOR_ALIGNMENT.  */

static HOST_WIDE_INT
riscv_vector_alignment (const_tree type)
{
  /* ??? Checking the mode isn't ideal, but VECTOR_BOOLEAN_TYPE_P can
     be set for non-predicate vectors of booleans.  Modes are the most
     direct way we have of identifying real RVV predicate types.  */
  /* FIXME: RVV didn't mention the alignment of bool, we uses
     one byte align.  */
  if (GET_MODE_CLASS (TYPE_MODE (type)) == MODE_VECTOR_BOOL)
    return 8;

  widest_int min_size
    = constant_lower_bound (wi::to_poly_widest (TYPE_SIZE (type)));
  return wi::umin (min_size, 128).to_uhwi ();
}

/* Implement REGMODE_NATURAL_SIZE.  */

poly_uint64
riscv_regmode_natural_size (machine_mode mode)
{
  /* The natural size for RVV data modes is one RVV data vector,
     and similarly for predicates.  We can't independently modify
     anything smaller than that.  */
  /* ??? For now, only do this for variable-width RVV registers.
     Doing it for constant-sized registers breaks lower-subreg.c.  */
  if (!riscv_vector_chunks.is_constant () && riscv_v_ext_vector_mode_p (mode))
    return BYTES_PER_RISCV_VECTOR;
  return UNITS_PER_WORD;
}

/* Implement the TARGET_DWARF_POLY_INDETERMINATE_VALUE hook.  */

static unsigned int
riscv_dwarf_poly_indeterminate_value (unsigned int i, unsigned int *factor,
				      int *offset)
{
  /* Polynomial invariant 1 == (VLENB / riscv_bytes_per_vector_chunk) - 1.
     1. TARGET_MIN_VLEN == 32, olynomial invariant 1 == (VLENB / 4) - 1.
     2. TARGET_MIN_VLEN > 32, olynomial invariant 1 == (VLENB / 8) - 1.
  */
  gcc_assert (i == 1);
  *factor = riscv_bytes_per_vector_chunk;
  *offset = 1;
  return RISCV_DWARF_VLENB;
}

/* Return true if a shift-amount matches the trailing cleared bits on
   a bitmask.  */

bool
riscv_shamt_matches_mask_p (int shamt, HOST_WIDE_INT mask)
{
  return shamt == ctz_hwi (mask);
}

/* Initialize the GCC target structure.  */
#undef TARGET_ASM_ALIGNED_HI_OP
#define TARGET_ASM_ALIGNED_HI_OP "\t.half\t"
#undef TARGET_ASM_ALIGNED_SI_OP
#define TARGET_ASM_ALIGNED_SI_OP "\t.word\t"
#undef TARGET_ASM_ALIGNED_DI_OP
#define TARGET_ASM_ALIGNED_DI_OP "\t.dword\t"

#undef TARGET_OPTION_OVERRIDE
#define TARGET_OPTION_OVERRIDE riscv_option_override

#undef TARGET_LEGITIMIZE_ADDRESS
#define TARGET_LEGITIMIZE_ADDRESS riscv_legitimize_address

#undef TARGET_SCHED_ISSUE_RATE
#define TARGET_SCHED_ISSUE_RATE riscv_issue_rate

#undef TARGET_FUNCTION_OK_FOR_SIBCALL
#define TARGET_FUNCTION_OK_FOR_SIBCALL riscv_function_ok_for_sibcall

#undef  TARGET_SET_CURRENT_FUNCTION
#define TARGET_SET_CURRENT_FUNCTION riscv_set_current_function

#undef TARGET_REGISTER_MOVE_COST
#define TARGET_REGISTER_MOVE_COST riscv_register_move_cost
#undef TARGET_MEMORY_MOVE_COST
#define TARGET_MEMORY_MOVE_COST riscv_memory_move_cost
#undef TARGET_RTX_COSTS
#define TARGET_RTX_COSTS riscv_rtx_costs
#undef TARGET_ADDRESS_COST
#define TARGET_ADDRESS_COST riscv_address_cost

#undef TARGET_ASM_FILE_START
#define TARGET_ASM_FILE_START riscv_file_start
#undef TARGET_ASM_FILE_START_FILE_DIRECTIVE
#define TARGET_ASM_FILE_START_FILE_DIRECTIVE true

#undef TARGET_EXPAND_BUILTIN_VA_START
#define TARGET_EXPAND_BUILTIN_VA_START riscv_va_start

#undef  TARGET_PROMOTE_FUNCTION_MODE
#define TARGET_PROMOTE_FUNCTION_MODE riscv_promote_function_mode

#undef TARGET_RETURN_IN_MEMORY
#define TARGET_RETURN_IN_MEMORY riscv_return_in_memory

#undef TARGET_ASM_OUTPUT_MI_THUNK
#define TARGET_ASM_OUTPUT_MI_THUNK riscv_output_mi_thunk
#undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
#define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_const_tree_hwi_hwi_const_tree_true

#undef TARGET_PRINT_OPERAND
#define TARGET_PRINT_OPERAND riscv_print_operand
#undef TARGET_PRINT_OPERAND_ADDRESS
#define TARGET_PRINT_OPERAND_ADDRESS riscv_print_operand_address
#undef TARGET_PRINT_OPERAND_PUNCT_VALID_P
#define TARGET_PRINT_OPERAND_PUNCT_VALID_P riscv_print_operand_punct_valid_p

#undef TARGET_SETUP_INCOMING_VARARGS
#define TARGET_SETUP_INCOMING_VARARGS riscv_setup_incoming_varargs
#undef TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS
#define TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS riscv_allocate_stack_slots_for_args
#undef TARGET_STRICT_ARGUMENT_NAMING
#define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
#undef TARGET_MUST_PASS_IN_STACK
#define TARGET_MUST_PASS_IN_STACK must_pass_in_stack_var_size
#undef TARGET_PASS_BY_REFERENCE
#define TARGET_PASS_BY_REFERENCE riscv_pass_by_reference
#undef TARGET_ARG_PARTIAL_BYTES
#define TARGET_ARG_PARTIAL_BYTES riscv_arg_partial_bytes
#undef TARGET_FUNCTION_ARG
#define TARGET_FUNCTION_ARG riscv_function_arg
#undef TARGET_FUNCTION_ARG_ADVANCE
#define TARGET_FUNCTION_ARG_ADVANCE riscv_function_arg_advance
#undef TARGET_FUNCTION_ARG_BOUNDARY
#define TARGET_FUNCTION_ARG_BOUNDARY riscv_function_arg_boundary

#undef TARGET_SHRINK_WRAP_GET_SEPARATE_COMPONENTS
#define TARGET_SHRINK_WRAP_GET_SEPARATE_COMPONENTS \
  riscv_get_separate_components

#undef TARGET_SHRINK_WRAP_COMPONENTS_FOR_BB
#define TARGET_SHRINK_WRAP_COMPONENTS_FOR_BB \
  riscv_components_for_bb

#undef TARGET_SHRINK_WRAP_DISQUALIFY_COMPONENTS
#define TARGET_SHRINK_WRAP_DISQUALIFY_COMPONENTS \
  riscv_disqualify_components

#undef TARGET_SHRINK_WRAP_EMIT_PROLOGUE_COMPONENTS
#define TARGET_SHRINK_WRAP_EMIT_PROLOGUE_COMPONENTS \
  riscv_emit_prologue_components

#undef TARGET_SHRINK_WRAP_EMIT_EPILOGUE_COMPONENTS
#define TARGET_SHRINK_WRAP_EMIT_EPILOGUE_COMPONENTS \
  riscv_emit_epilogue_components

#undef TARGET_SHRINK_WRAP_SET_HANDLED_COMPONENTS
#define TARGET_SHRINK_WRAP_SET_HANDLED_COMPONENTS \
  riscv_set_handled_components

/* The generic ELF target does not always have TLS support.  */
#ifdef HAVE_AS_TLS
#undef TARGET_HAVE_TLS
#define TARGET_HAVE_TLS true
#endif

#undef TARGET_CANNOT_FORCE_CONST_MEM
#define TARGET_CANNOT_FORCE_CONST_MEM riscv_cannot_force_const_mem

#undef TARGET_LEGITIMATE_CONSTANT_P
#define TARGET_LEGITIMATE_CONSTANT_P riscv_legitimate_constant_p

#undef TARGET_USE_BLOCKS_FOR_CONSTANT_P
#define TARGET_USE_BLOCKS_FOR_CONSTANT_P hook_bool_mode_const_rtx_true

#undef TARGET_LEGITIMATE_ADDRESS_P
#define TARGET_LEGITIMATE_ADDRESS_P	riscv_legitimate_address_p

#undef TARGET_CAN_ELIMINATE
#define TARGET_CAN_ELIMINATE riscv_can_eliminate

#undef TARGET_CONDITIONAL_REGISTER_USAGE
#define TARGET_CONDITIONAL_REGISTER_USAGE riscv_conditional_register_usage

#undef TARGET_CLASS_MAX_NREGS
#define TARGET_CLASS_MAX_NREGS riscv_class_max_nregs

#undef TARGET_TRAMPOLINE_INIT
#define TARGET_TRAMPOLINE_INIT riscv_trampoline_init

#undef TARGET_IN_SMALL_DATA_P
#define TARGET_IN_SMALL_DATA_P riscv_in_small_data_p

#undef TARGET_HAVE_SRODATA_SECTION
#define TARGET_HAVE_SRODATA_SECTION true

#undef TARGET_ASM_SELECT_SECTION
#define TARGET_ASM_SELECT_SECTION riscv_select_section

#undef TARGET_ASM_UNIQUE_SECTION
#define TARGET_ASM_UNIQUE_SECTION riscv_unique_section

#undef TARGET_ASM_SELECT_RTX_SECTION
#define TARGET_ASM_SELECT_RTX_SECTION  riscv_elf_select_rtx_section

#undef TARGET_MIN_ANCHOR_OFFSET
#define TARGET_MIN_ANCHOR_OFFSET (-IMM_REACH/2)

#undef TARGET_MAX_ANCHOR_OFFSET
#define TARGET_MAX_ANCHOR_OFFSET (IMM_REACH/2-1)

#undef TARGET_REGISTER_PRIORITY
#define TARGET_REGISTER_PRIORITY riscv_register_priority

#undef TARGET_CANNOT_COPY_INSN_P
#define TARGET_CANNOT_COPY_INSN_P riscv_cannot_copy_insn_p

#undef TARGET_ATOMIC_ASSIGN_EXPAND_FENV
#define TARGET_ATOMIC_ASSIGN_EXPAND_FENV riscv_atomic_assign_expand_fenv

#undef TARGET_INIT_BUILTINS
#define TARGET_INIT_BUILTINS riscv_init_builtins

#undef TARGET_BUILTIN_DECL
#define TARGET_BUILTIN_DECL riscv_builtin_decl

#undef TARGET_EXPAND_BUILTIN
#define TARGET_EXPAND_BUILTIN riscv_expand_builtin

#undef TARGET_HARD_REGNO_NREGS
#define TARGET_HARD_REGNO_NREGS riscv_hard_regno_nregs
#undef TARGET_HARD_REGNO_MODE_OK
#define TARGET_HARD_REGNO_MODE_OK riscv_hard_regno_mode_ok

#undef TARGET_MODES_TIEABLE_P
#define TARGET_MODES_TIEABLE_P riscv_modes_tieable_p

#undef TARGET_SLOW_UNALIGNED_ACCESS
#define TARGET_SLOW_UNALIGNED_ACCESS riscv_slow_unaligned_access

#undef TARGET_SECONDARY_MEMORY_NEEDED
#define TARGET_SECONDARY_MEMORY_NEEDED riscv_secondary_memory_needed

#undef TARGET_CAN_CHANGE_MODE_CLASS
#define TARGET_CAN_CHANGE_MODE_CLASS riscv_can_change_mode_class

#undef TARGET_CONSTANT_ALIGNMENT
#define TARGET_CONSTANT_ALIGNMENT riscv_constant_alignment

#undef TARGET_MERGE_DECL_ATTRIBUTES
#define TARGET_MERGE_DECL_ATTRIBUTES riscv_merge_decl_attributes

#undef TARGET_ATTRIBUTE_TABLE
#define TARGET_ATTRIBUTE_TABLE riscv_attribute_table

#undef TARGET_WARN_FUNC_RETURN
#define TARGET_WARN_FUNC_RETURN riscv_warn_func_return

/* The low bit is ignored by jump instructions so is safe to use.  */
#undef TARGET_CUSTOM_FUNCTION_DESCRIPTORS
#define TARGET_CUSTOM_FUNCTION_DESCRIPTORS 1

#undef TARGET_MACHINE_DEPENDENT_REORG
#define TARGET_MACHINE_DEPENDENT_REORG riscv_reorg

#undef TARGET_NEW_ADDRESS_PROFITABLE_P
#define TARGET_NEW_ADDRESS_PROFITABLE_P riscv_new_address_profitable_p

#undef TARGET_MANGLE_TYPE
#define TARGET_MANGLE_TYPE riscv_mangle_type

#undef TARGET_SCALAR_MODE_SUPPORTED_P
#define TARGET_SCALAR_MODE_SUPPORTED_P riscv_scalar_mode_supported_p

#undef TARGET_LIBGCC_FLOATING_MODE_SUPPORTED_P
#define TARGET_LIBGCC_FLOATING_MODE_SUPPORTED_P                                \
  riscv_libgcc_floating_mode_supported_p

#undef TARGET_INIT_LIBFUNCS
#define TARGET_INIT_LIBFUNCS riscv_init_libfuncs

#undef TARGET_C_EXCESS_PRECISION
#define TARGET_C_EXCESS_PRECISION riscv_excess_precision

#undef TARGET_FLOATN_MODE
#define TARGET_FLOATN_MODE riscv_floatn_mode

#undef TARGET_ASAN_SHADOW_OFFSET
#define TARGET_ASAN_SHADOW_OFFSET riscv_asan_shadow_offset

#ifdef TARGET_BIG_ENDIAN_DEFAULT
#undef  TARGET_DEFAULT_TARGET_FLAGS
#define TARGET_DEFAULT_TARGET_FLAGS (MASK_BIG_ENDIAN)
#endif

#undef TARGET_VECTOR_MODE_SUPPORTED_P
#define TARGET_VECTOR_MODE_SUPPORTED_P riscv_vector_mode_supported_p

#undef TARGET_VERIFY_TYPE_CONTEXT
#define TARGET_VERIFY_TYPE_CONTEXT riscv_verify_type_context

#undef TARGET_VECTOR_ALIGNMENT
#define TARGET_VECTOR_ALIGNMENT riscv_vector_alignment

#undef TARGET_DWARF_POLY_INDETERMINATE_VALUE
#define TARGET_DWARF_POLY_INDETERMINATE_VALUE riscv_dwarf_poly_indeterminate_value

struct gcc_target targetm = TARGET_INITIALIZER;

#include "gt-riscv.h"
