@@ -71,7 +71,7 @@
{
/* Don't handle multi-word moves this way; we don't want to introduce
the individual word-mode moves until after reload. */
- if (GET_MODE_SIZE (mode) > UNITS_PER_WORD)
+ if (GET_MODE_SIZE (mode).to_constant () > UNITS_PER_WORD)
return false;
/* Check whether the constant can be loaded in a single
@@ -21,3 +21,15 @@ along with GCC; see the file COPYING3. If not see
FLOAT_MODE (HF, 2, ieee_half_format);
FLOAT_MODE (TF, 16, ieee_quad_format);
+
+/* TODO:According to RISC-V 'V' ISA spec, the maximun vector length can
+ be 65536 for a single vector register which means the vector mode in
+ GCC can be maximum = 65536 * 8 bits (LMUL=8). However, 'GET_MODE_SIZE'
+ is using poly_uint16/unsigned short which will overflow if we specify
+ vector-length = 65536. To support this feature, we need to change the
+ codes outside the RISC-V port. We will support it in the future. */
+#define MAX_BITSIZE_MODE_ANY_MODE (4096 * 8)
+
+/* Coefficient 1 is multiplied by the number of 64-bit/32-bit chunks in a vector
+ * minus one. */
+#define NUM_POLY_INT_COEFFS 2
\ No newline at end of file
@@ -64,7 +64,7 @@ extern rtx riscv_legitimize_call_address (rtx);
extern void riscv_set_return_address (rtx, rtx);
extern bool riscv_expand_block_move (rtx, rtx, rtx);
extern rtx riscv_return_addr (int, rtx);
-extern HOST_WIDE_INT riscv_initial_elimination_offset (int, int);
+extern poly_int64 riscv_initial_elimination_offset (int, int);
extern void riscv_expand_prologue (void);
extern void riscv_expand_epilogue (int);
extern bool riscv_epilogue_uses (unsigned int);
@@ -247,7 +247,7 @@ riscv_remove_unneeded_save_restore_calls (void)
/* We'll adjust stack size after this optimization, that require update every
sp use site, which could be unsafe, so we decide to turn off this
optimization if there are any arguments put on stack. */
- if (crtl->args.size != 0)
+ if (known_ne (crtl->args.size, 0))
return;
/* Will point to the first instruction of the function body, after the
@@ -100,7 +100,7 @@ enum riscv_address_type {
/* Information about a function's frame layout. */
struct GTY(()) riscv_frame_info {
/* The size of the frame in bytes. */
- HOST_WIDE_INT total_size;
+ poly_int64 total_size;
/* Bit X is set if the function saves or restores GPR X. */
unsigned int mask;
@@ -112,17 +112,17 @@ struct GTY(()) riscv_frame_info {
unsigned save_libcall_adjustment;
/* Offsets of fixed-point and floating-point save areas from frame bottom */
- HOST_WIDE_INT gp_sp_offset;
- HOST_WIDE_INT fp_sp_offset;
+ poly_int64 gp_sp_offset;
+ poly_int64 fp_sp_offset;
/* Offset of virtual frame pointer from stack pointer/frame bottom */
- HOST_WIDE_INT frame_pointer_offset;
+ poly_int64 frame_pointer_offset;
/* Offset of hard frame pointer from stack pointer/frame bottom */
- HOST_WIDE_INT hard_frame_pointer_offset;
+ poly_int64 hard_frame_pointer_offset;
/* The offset of arg_pointer_rtx from the bottom of the frame. */
- HOST_WIDE_INT arg_pointer_offset;
+ poly_int64 arg_pointer_offset;
};
enum riscv_privilege_levels {
@@ -255,6 +255,12 @@ 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,
@@ -807,8 +813,8 @@ riscv_valid_offset_p (rtx x, machine_mode mode)
/* We may need to split multiword moves, so make sure that every word
is accessible. */
- if (GET_MODE_SIZE (mode) > UNITS_PER_WORD
- && !SMALL_OPERAND (INTVAL (x) + GET_MODE_SIZE (mode) - UNITS_PER_WORD))
+ 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;
@@ -872,7 +878,7 @@ riscv_valid_lo_sum_p (enum riscv_symbol_type sym_type, machine_mode mode,
else
{
align = GET_MODE_ALIGNMENT (mode);
- size = GET_MODE_BITSIZE (mode);
+ size = GET_MODE_BITSIZE (mode).to_constant ();
}
/* We may need to split multiword moves, so make sure that each word
@@ -1013,7 +1019,7 @@ riscv_address_insns (rtx x, machine_mode mode, bool might_split_p)
/* BLKmode is used for single unaligned loads and stores and should
not count as a multiword mode. */
if (mode != BLKmode && might_split_p)
- n += (GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
+ 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;
@@ -1106,9 +1112,9 @@ riscv_load_store_insns (rtx mem, rtx_insn *insn)
/* Try to prove that INSN does not need to be split. */
might_split_p = true;
- if (GET_MODE_BITSIZE (mode) <= 32)
+ if (GET_MODE_BITSIZE (mode).to_constant () <= 32)
might_split_p = false;
- else if (GET_MODE_BITSIZE (mode) == 64)
+ 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)))
@@ -1625,7 +1631,7 @@ riscv_legitimize_move (machine_mode mode, rtx dest, rtx src)
(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) < UNITS_PER_WORD
+ && GET_MODE_SIZE (mode).to_constant () < UNITS_PER_WORD
&& can_create_pseudo_p ()
&& MEM_P (src))
{
@@ -1650,7 +1656,7 @@ riscv_legitimize_move (machine_mode mode, rtx dest, rtx src)
improve cse. */
machine_mode promoted_mode = mode;
if (GET_MODE_CLASS (mode) == MODE_INT
- && GET_MODE_SIZE (mode) < UNITS_PER_WORD)
+ && GET_MODE_SIZE (mode).to_constant () < UNITS_PER_WORD)
promoted_mode = word_mode;
if (splittable_const_int_operand (src, mode))
@@ -1748,7 +1754,7 @@ riscv_immediate_operand_p (int code, HOST_WIDE_INT x)
static int
riscv_binary_cost (rtx x, int single_insns, int double_insns)
{
- if (GET_MODE_SIZE (GET_MODE (x)) == UNITS_PER_WORD * 2)
+ if (GET_MODE_SIZE (GET_MODE (x)).to_constant () == UNITS_PER_WORD * 2)
return COSTS_N_INSNS (double_insns);
return COSTS_N_INSNS (single_insns);
}
@@ -1881,7 +1887,7 @@ riscv_rtx_costs (rtx x, machine_mode mode, int outer_code, int opno ATTRIBUTE_UN
return false;
case NOT:
- *total = COSTS_N_INSNS (GET_MODE_SIZE (mode) > UNITS_PER_WORD ? 2 : 1);
+ *total = COSTS_N_INSNS (GET_MODE_SIZE (mode).to_constant () > UNITS_PER_WORD ? 2 : 1);
return false;
case AND:
@@ -2128,7 +2134,7 @@ riscv_rtx_costs (rtx x, machine_mode mode, int outer_code, int opno ATTRIBUTE_UN
if (float_mode_p)
*total = tune_param->fp_add[mode == DFmode];
else
- *total = COSTS_N_INSNS (GET_MODE_SIZE (mode) > UNITS_PER_WORD ? 4 : 1);
+ *total = COSTS_N_INSNS (GET_MODE_SIZE (mode).to_constant () > UNITS_PER_WORD ? 4 : 1);
return false;
case MULT:
@@ -2137,7 +2143,7 @@ riscv_rtx_costs (rtx x, machine_mode mode, int outer_code, int opno ATTRIBUTE_UN
else if (!TARGET_MUL)
/* Estimate the cost of a library call. */
*total = COSTS_N_INSNS (speed ? 32 : 6);
- else if (GET_MODE_SIZE (mode) > UNITS_PER_WORD)
+ 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);
@@ -2301,8 +2307,8 @@ riscv_output_move (rtx dest, rtx src)
dest_code = GET_CODE (dest);
src_code = GET_CODE (src);
mode = GET_MODE (dest);
- dbl_p = (GET_MODE_SIZE (mode) == 8);
- width = GET_MODE_SIZE (mode);
+ 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 "#";
@@ -2578,7 +2584,7 @@ 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)))
+ 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
@@ -2941,7 +2947,7 @@ riscv_flatten_aggregate_field (const_tree type,
if (n != 0)
return -1;
- HOST_WIDE_INT elt_size = GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (type)));
+ HOST_WIDE_INT elt_size = GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (type))).to_constant ();
if (elt_size <= UNITS_PER_FP_ARG)
{
@@ -2959,9 +2965,9 @@ riscv_flatten_aggregate_field (const_tree type,
default:
if (n < 2
&& ((SCALAR_FLOAT_TYPE_P (type)
- && GET_MODE_SIZE (TYPE_MODE (type)) <= UNITS_PER_FP_ARG)
+ && GET_MODE_SIZE (TYPE_MODE (type)).to_constant () <= UNITS_PER_FP_ARG)
|| (INTEGRAL_TYPE_P (type)
- && GET_MODE_SIZE (TYPE_MODE (type)) <= UNITS_PER_WORD)))
+ && GET_MODE_SIZE (TYPE_MODE (type)).to_constant () <= UNITS_PER_WORD)))
{
fields[n].type = type;
fields[n].offset = offset;
@@ -3197,7 +3203,7 @@ riscv_get_arg_info (struct riscv_arg_info *info, const CUMULATIVE_ARGS *cum,
}
/* Work out the size of the argument. */
- num_bytes = type ? int_size_in_bytes (type) : GET_MODE_SIZE (mode);
+ 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. */
@@ -3291,7 +3297,7 @@ riscv_function_value (const_tree type, const_tree func, machine_mode mode)
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 ();
+ HOST_WIDE_INT size = arg.type_size_in_bytes ().to_constant ();;
struct riscv_arg_info info;
CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
@@ -3920,7 +3926,7 @@ riscv_elf_select_rtx_section (machine_mode mode, rtx x,
{
section *s = default_elf_select_rtx_section (mode, x, align);
- if (riscv_size_ok_for_small_data_p (GET_MODE_SIZE (mode)))
+ if (riscv_size_ok_for_small_data_p (GET_MODE_SIZE (mode).to_constant ()))
{
if (startswith (s->named.name, ".rodata.cst"))
{
@@ -4072,11 +4078,24 @@ riscv_save_libcall_count (unsigned mask)
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;
- HOST_WIDE_INT offset;
+ poly_int64 offset;
bool interrupt_save_prologue_temp = false;
unsigned int regno, i, num_x_saved = 0, num_f_saved = 0;
@@ -4087,7 +4106,7 @@ riscv_compute_frame_info (void)
if (cfun->machine->interrupt_handler_p)
{
HOST_WIDE_INT step1 = riscv_first_stack_step (frame);
- if (! SMALL_OPERAND (frame->total_size - step1))
+ if (! POLY_SMALL_OPERAND_P ((frame->total_size - step1)))
interrupt_save_prologue_temp = true;
}
@@ -4117,23 +4136,23 @@ riscv_compute_frame_info (void)
}
/* At the bottom of the frame are any outgoing stack arguments. */
- offset = RISCV_STACK_ALIGN (crtl->outgoing_args_size);
+ offset = riscv_stack_align (crtl->outgoing_args_size);
/* Next are local stack variables. */
- offset += RISCV_STACK_ALIGN (get_frame_size ());
+ 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);
+ 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 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)
+ 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. */
@@ -4149,9 +4168,9 @@ riscv_compute_frame_info (void)
/* 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);
+ 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);
+ 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;
@@ -4159,7 +4178,7 @@ riscv_compute_frame_info (void)
/* Next points the incoming stack pointer and any incoming arguments. */
/* Only use save/restore routines when the GPRs are atop the frame. */
- if (frame->hard_frame_pointer_offset != frame->total_size)
+ if (known_ne (frame->hard_frame_pointer_offset, frame->total_size))
frame->save_libcall_adjustment = 0;
}
@@ -4176,10 +4195,10 @@ riscv_can_eliminate (const int from ATTRIBUTE_UNUSED, const int to)
or argument pointer. TO is either the stack pointer or hard frame
pointer. */
-HOST_WIDE_INT
+poly_int64
riscv_initial_elimination_offset (int from, int to)
{
- HOST_WIDE_INT src, dest;
+ poly_int64 src, dest;
riscv_compute_frame_info ();
@@ -4223,7 +4242,7 @@ riscv_set_return_address (rtx address, rtx scratch)
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);
+ cfun->machine->frame.gp_sp_offset.to_constant());
riscv_emit_move (gen_frame_mem (GET_MODE (address), slot_address), address);
}
@@ -4250,13 +4269,13 @@ riscv_save_restore_reg (machine_mode mode, int regno,
of the frame. */
static void
-riscv_for_each_saved_reg (HOST_WIDE_INT sp_offset, riscv_save_restore_fn fn,
+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;
+ 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))
{
@@ -4287,14 +4306,14 @@ riscv_for_each_saved_reg (HOST_WIDE_INT sp_offset, riscv_save_restore_fn fn,
/* 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;
+ 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))
{
machine_mode mode = TARGET_DOUBLE_FLOAT ? DFmode : SFmode;
riscv_save_restore_reg (mode, regno, offset, fn);
- offset -= GET_MODE_SIZE (mode);
+ offset -= GET_MODE_SIZE (mode).to_constant ();
}
}
@@ -4336,21 +4355,21 @@ riscv_restore_reg (rtx reg, rtx mem)
static HOST_WIDE_INT
riscv_first_stack_step (struct riscv_frame_info *frame)
{
- if (SMALL_OPERAND (frame->total_size))
- return frame->total_size;
+ if (SMALL_OPERAND (frame->total_size.to_constant()))
+ return frame->total_size.to_constant();
HOST_WIDE_INT min_first_step =
- RISCV_STACK_ALIGN (frame->total_size - frame->fp_sp_offset);
+ 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_size - max_first_step;
+ HOST_WIDE_INT min_second_step = frame->total_size.to_constant() - 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_size % IMM_REACH < IMM_REACH / 2
- && frame->total_size % IMM_REACH >= min_first_step)
- return frame->total_size % IMM_REACH;
+ && frame->total_size.to_constant() % IMM_REACH < IMM_REACH / 2
+ && frame->total_size.to_constant() % IMM_REACH >= min_first_step)
+ return frame->total_size.to_constant() % IMM_REACH;
if (TARGET_RVC)
{
@@ -4423,7 +4442,7 @@ void
riscv_expand_prologue (void)
{
struct riscv_frame_info *frame = &cfun->machine->frame;
- HOST_WIDE_INT size = frame->total_size;
+ HOST_WIDE_INT size = frame->total_size.to_constant ();
unsigned mask = frame->mask;
rtx insn;
@@ -4466,7 +4485,7 @@ riscv_expand_prologue (void)
if (frame_pointer_needed)
{
insn = gen_add3_insn (hard_frame_pointer_rtx, stack_pointer_rtx,
- GEN_INT (frame->hard_frame_pointer_offset - size));
+ GEN_INT ((frame->hard_frame_pointer_offset - size).to_constant ()));
RTX_FRAME_RELATED_P (emit_insn (insn)) = 1;
riscv_emit_stack_tie ();
@@ -4532,7 +4551,7 @@ riscv_expand_epilogue (int style)
Start off by assuming that no registers need to be restored. */
struct riscv_frame_info *frame = &cfun->machine->frame;
unsigned mask = frame->mask;
- HOST_WIDE_INT step1 = frame->total_size;
+ HOST_WIDE_INT step1 = frame->total_size.to_constant ();
HOST_WIDE_INT step2 = 0;
bool use_restore_libcall = ((style == NORMAL_RETURN)
&& riscv_use_save_libcall (frame));
@@ -4540,8 +4559,8 @@ riscv_expand_epilogue (int style)
rtx insn;
/* We need to add memory barrier to prevent read from deallocated stack. */
- bool need_barrier_p = (get_frame_size ()
- + cfun->machine->frame.arg_pointer_offset) != 0;
+ bool need_barrier_p
+ = known_ne (get_frame_size (), cfun->machine->frame.arg_pointer_offset);
if (cfun->machine->naked_p)
{
@@ -4568,7 +4587,7 @@ riscv_expand_epilogue (int style)
riscv_emit_stack_tie ();
need_barrier_p = false;
- rtx adjust = GEN_INT (-frame->hard_frame_pointer_offset);
+ rtx adjust = GEN_INT (-frame->hard_frame_pointer_offset.to_constant ());
if (!SMALL_OPERAND (INTVAL (adjust)))
{
riscv_emit_move (RISCV_PROLOGUE_TEMP (Pmode), adjust);
@@ -4582,7 +4601,7 @@ riscv_expand_epilogue (int style)
rtx dwarf = NULL_RTX;
rtx cfa_adjust_value = gen_rtx_PLUS (
Pmode, hard_frame_pointer_rtx,
- GEN_INT (-frame->hard_frame_pointer_offset));
+ GEN_INT (-frame->hard_frame_pointer_offset.to_constant ()));
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;
@@ -4599,7 +4618,7 @@ riscv_expand_epilogue (int style)
}
/* Set TARGET to BASE + STEP1. */
- if (step1 > 0)
+ if (known_gt (step1, 0))
{
/* Emit a barrier to prevent loads from a deallocated stack. */
riscv_emit_stack_tie ();
@@ -4725,7 +4744,7 @@ riscv_epilogue_uses (unsigned int regno)
bool
riscv_can_use_return_insn (void)
{
- return (reload_completed && cfun->machine->frame.total_size == 0
+ return (reload_completed && known_eq (cfun->machine->frame.total_size, 0)
&& ! cfun->machine->interrupt_handler_p);
}
@@ -4825,7 +4844,7 @@ static bool
riscv_secondary_memory_needed (machine_mode mode, reg_class_t class1,
reg_class_t class2)
{
- return (GET_MODE_SIZE (mode) > UNITS_PER_WORD
+ return (GET_MODE_SIZE (mode).to_constant () > UNITS_PER_WORD
&& (class1 == FP_REGS) != (class2 == FP_REGS));
}
@@ -4848,10 +4867,10 @@ static unsigned int
riscv_hard_regno_nregs (unsigned int regno, machine_mode mode)
{
if (FP_REG_P (regno))
- return (GET_MODE_SIZE (mode) + UNITS_PER_FP_REG - 1) / UNITS_PER_FP_REG;
+ 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) + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
+ return (GET_MODE_SIZE (mode).to_constant () + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
}
/* Implement TARGET_HARD_REGNO_MODE_OK. */
@@ -5058,6 +5077,38 @@ 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)
+{
+ /* The runtime invariant is only meaningful when vector is enabled. */
+ if (!TARGET_VECTOR)
+ return 0;
+
+ if (TARGET_VECTOR_ELEN_64 || TARGET_VECTOR_ELEN_FP_64)
+ {
+ /* When targetting Zve64* (ELEN = 64) extensions, we should use 64-bit
+ chunk size. 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 Zve32* (ELEN = 32) extensions, 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;
+ }
+
+ return poly_uint16 (1, 1);
+}
+
/* Implement TARGET_OPTION_OVERRIDE. */
static void
@@ -5204,6 +5255,8 @@ riscv_option_override (void)
riscv_stack_protector_guard_offset = offs;
}
+ /* Convert -march to a chunks count. */
+ riscv_vector_chunks = riscv_convert_vector_bits ();
}
/* Implement TARGET_CONDITIONAL_REGISTER_USAGE. */
@@ -5561,7 +5614,7 @@ riscv_promote_function_mode (const_tree type ATTRIBUTE_UNUSED,
return promote_mode (type, mode, punsignedp);
unsignedp = *punsignedp;
- PROMOTE_MODE (mode, unsignedp, type);
+ PROMOTE_MODE (as_a <scalar_mode> (mode), unsignedp, type);
*punsignedp = unsignedp;
return mode;
}
@@ -522,6 +522,10 @@ enum reg_class
#define SMALL_OPERAND(VALUE) \
((unsigned HOST_WIDE_INT) (VALUE) + IMM_REACH/2 < IMM_REACH)
+#define POLY_SMALL_OPERAND_P(POLY_VALUE) \
+ (POLY_VALUE.is_constant () ? \
+ SMALL_OPERAND (POLY_VALUE.to_constant ()) : false)
+
/* True if VALUE can be loaded into a register using LUI. */
#define LUI_OPERAND(VALUE) \
@@ -952,6 +956,11 @@ while (0)
extern const enum reg_class riscv_regno_to_class[];
extern bool riscv_slow_unaligned_access_p;
extern unsigned riscv_stack_boundary;
+extern unsigned riscv_bytes_per_vector_chunk;
+extern poly_uint16 riscv_vector_chunks;
+/* The number of bits and bytes in a RVV vector. */
+#define BITS_PER_RISCV_VECTOR (poly_uint16 (riscv_vector_chunks * riscv_bytes_per_vector_chunk * 8))
+#define BYTES_PER_RISCV_VECTOR (poly_uint16 (riscv_vector_chunks * riscv_bytes_per_vector_chunk))
#endif
#define ASM_PREFERRED_EH_DATA_FORMAT(CODE,GLOBAL) \
@@ -2162,7 +2162,7 @@
(lshiftrt:GPR (match_dup 3) (match_dup 2)))]
{
/* Op2 is a VOIDmode constant, so get the mode size from op1. */
- operands[2] = GEN_INT (GET_MODE_BITSIZE (GET_MODE (operands[1]))
+ operands[2] = GEN_INT (GET_MODE_BITSIZE (GET_MODE (operands[1])).to_constant ()
- exact_log2 (INTVAL (operands[2]) + 1));
})