aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/riscv/riscv.cc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/config/riscv/riscv.cc')
-rw-r--r--gcc/config/riscv/riscv.cc60
1 files changed, 42 insertions, 18 deletions
diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index 3324819..0a9fcef 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -170,7 +170,7 @@ struct GTY(()) riscv_frame_info {
};
enum riscv_privilege_levels {
- UNKNOWN_MODE, USER_MODE, SUPERVISOR_MODE, MACHINE_MODE
+ UNKNOWN_MODE, SUPERVISOR_MODE, MACHINE_MODE, RNMI_MODE
};
struct GTY(()) mode_switching_info {
@@ -4040,6 +4040,7 @@ riscv_rtx_costs (rtx x, machine_mode mode, int outer_code, int opno ATTRIBUTE_UN
switch (XINT (op, 1))
{
case UNSPEC_VAADDU:
+ case UNSPEC_VAADD:
*total
= get_vector_binary_rtx_cost (op, scalar2vr_cost);
break;
@@ -6924,12 +6925,18 @@ riscv_handle_type_attribute (tree *node ATTRIBUTE_UNUSED, tree name, tree args,
}
string = TREE_STRING_POINTER (cst);
- if (strcmp (string, "user") && strcmp (string, "supervisor")
- && strcmp (string, "machine"))
+ if (!strcmp (string, "rnmi") && !TARGET_SMRNMI)
+ {
+ error ("attribute 'rnmi' requires the Smrnmi ISA extension");
+ *no_add_attrs = true;
+ }
+ else if (strcmp (string, "supervisor")
+ && strcmp (string, "machine")
+ && strcmp (string, "rnmi"))
{
warning (OPT_Wattributes,
- "argument to %qE attribute is not %<\"user\"%>, %<\"supervisor\"%>, "
- "or %<\"machine\"%>", name);
+ "argument to %qE attribute is not %<\"supervisor\"%>, "
+ "%<\"machine\"%>, or %<\"rnmi\"%>", name);
*no_add_attrs = true;
}
}
@@ -9710,12 +9717,12 @@ riscv_expand_epilogue (int style)
if (th_int_mask && TH_INT_INTERRUPT (cfun))
emit_jump_insn (gen_th_int_pop ());
- else 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 (mode == RNMI_MODE)
+ emit_jump_insn (gen_riscv_mnret ());
+ else /* Must be MACHINE_MODE. */
+ emit_jump_insn (gen_riscv_mret ());
}
else if (style != SIBCALL_RETURN)
{
@@ -12057,10 +12064,10 @@ riscv_get_interrupt_type (tree decl)
{
const char *string = TREE_STRING_POINTER (TREE_VALUE (attr_args));
- if (!strcmp (string, "user"))
- return USER_MODE;
- else if (!strcmp (string, "supervisor"))
+ if (!strcmp (string, "supervisor"))
return SUPERVISOR_MODE;
+ else if (!strcmp (string, "rnmi"))
+ return RNMI_MODE;
else /* Must be "machine". */
return MACHINE_MODE;
}
@@ -12677,14 +12684,31 @@ riscv_estimated_poly_value (poly_int64 val,
/* Return true if the vector misalignment factor is supported by the
target. */
bool
-riscv_support_vector_misalignment (machine_mode mode,
- const_tree type ATTRIBUTE_UNUSED,
- int misalignment,
- bool is_packed ATTRIBUTE_UNUSED)
+riscv_support_vector_misalignment (machine_mode mode, const_tree type,
+ int misalignment, bool is_packed,
+ bool is_gather_scatter)
{
- /* Depend on movmisalign pattern. */
+ /* IS_PACKED is true if the corresponding scalar element is not naturally
+ aligned. If the misalignment is unknown and the the access is packed
+ we defer to the default hook which will check if movmisalign is present.
+ Movmisalign, in turn, depends on TARGET_VECTOR_MISALIGN_SUPPORTED. */
+ if (misalignment == DR_MISALIGNMENT_UNKNOWN)
+ {
+ if (!is_packed)
+ return true;
+ }
+ else
+ {
+ /* If we know that misalignment is a multiple of the element size, we're
+ good. */
+ if (misalignment % TYPE_ALIGN_UNIT (type) == 0)
+ return true;
+ }
+
+ /* Otherwise fall back to movmisalign again. */
return default_builtin_support_vector_misalignment (mode, type, misalignment,
- is_packed);
+ is_packed,
+ is_gather_scatter);
}
/* Implement TARGET_VECTORIZE_GET_MASK_MODE. */