summaryrefslogtreecommitdiff
path: root/gcc/config/nds32/nds32.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/config/nds32/nds32.c')
-rw-r--r--gcc/config/nds32/nds32.c65
1 files changed, 65 insertions, 0 deletions
diff --git a/gcc/config/nds32/nds32.c b/gcc/config/nds32/nds32.c
index da8af4c6f1a8..50eb709aa489 100644
--- a/gcc/config/nds32/nds32.c
+++ b/gcc/config/nds32/nds32.c
@@ -1987,6 +1987,16 @@ nds32_function_arg_boundary (machine_mode mode, const_tree type)
: PARM_BOUNDARY);
}
+bool
+nds32_vector_mode_supported_p (machine_mode mode)
+{
+ if (mode == V4QImode
+ || mode == V2HImode)
+ return NDS32_EXT_DSP_P ();
+
+ return false;
+}
+
/* -- How Scalar Function Values Are Returned. */
static rtx
@@ -2688,6 +2698,23 @@ nds32_legitimate_address_p (machine_mode mode, rtx x, bool strict)
}
}
+static machine_mode
+nds32_vectorize_preferred_simd_mode (scalar_mode mode)
+{
+ if (!NDS32_EXT_DSP_P ())
+ return word_mode;
+
+ switch (mode)
+ {
+ case E_QImode:
+ return V4QImode;
+ case E_HImode:
+ return V2HImode;
+ default:
+ return word_mode;
+ }
+}
+
/* Condition Code Status. */
@@ -2978,6 +3005,18 @@ nds32_print_operand (FILE *stream, rtx x, int code)
/* No need to handle following process, so return immediately. */
return;
+
+ case 'v':
+ gcc_assert (CONST_INT_P (x)
+ && (INTVAL (x) == 0
+ || INTVAL (x) == 8
+ || INTVAL (x) == 16
+ || INTVAL (x) == 24));
+ fprintf (stream, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) / 8);
+
+ /* No need to handle following process, so return immediately. */
+ return;
+
case 'B':
/* Use exact_log2() to search the 1-bit position. */
gcc_assert (CONST_INT_P (x));
@@ -3168,6 +3207,10 @@ nds32_print_operand (FILE *stream, rtx x, int code)
output_addr_const (stream, x);
break;
+ case CONST_VECTOR:
+ fprintf (stream, HOST_WIDE_INT_PRINT_HEX, const_vector_to_hwint (x));
+ break;
+
default:
/* Generally, output_addr_const () is able to handle most cases.
We want to see what CODE could appear,
@@ -3260,6 +3303,20 @@ nds32_print_operand_address (FILE *stream, machine_mode /*mode*/, rtx x)
reg_names[REGNO (XEXP (op0, 0))],
sv);
}
+ else if (GET_CODE (op0) == ASHIFT && REG_P (op1))
+ {
+ /* [Ra + Rb << sv]
+ In normal, ASHIFT can be converted to MULT like above case.
+ But when the address rtx does not go through canonicalize_address
+ defined in fwprop, we'll need this case. */
+ int sv = INTVAL (XEXP (op0, 1));
+ gcc_assert (sv <= 3 && sv >=0);
+
+ fprintf (stream, "[%s + %s << %d]",
+ reg_names[REGNO (op1)],
+ reg_names[REGNO (XEXP (op0, 0))],
+ sv);
+ }
else
{
/* The control flow is not supposed to be here. */
@@ -3770,6 +3827,8 @@ nds32_cpu_cpp_builtins(struct cpp_reader *pfile)
builtin_define ("__NDS32_GP_DIRECT__");
if (TARGET_VH)
builtin_define ("__NDS32_VH__");
+ if (NDS32_EXT_DSP_P ())
+ builtin_define ("__NDS32_EXT_DSP__");
if (TARGET_BIG_ENDIAN)
builtin_define ("__big_endian__");
@@ -5010,6 +5069,9 @@ nds32_use_blocks_for_constant_p (machine_mode mode,
#undef TARGET_FUNCTION_ARG_BOUNDARY
#define TARGET_FUNCTION_ARG_BOUNDARY nds32_function_arg_boundary
+#undef TARGET_VECTOR_MODE_SUPPORTED_P
+#define TARGET_VECTOR_MODE_SUPPORTED_P nds32_vector_mode_supported_p
+
/* -- How Scalar Function Values Are Returned. */
#undef TARGET_FUNCTION_VALUE
@@ -5087,6 +5149,9 @@ nds32_use_blocks_for_constant_p (machine_mode mode,
#undef TARGET_LEGITIMATE_ADDRESS_P
#define TARGET_LEGITIMATE_ADDRESS_P nds32_legitimate_address_p
+#undef TARGET_VECTORIZE_PREFERRED_SIMD_MODE
+#define TARGET_VECTORIZE_PREFERRED_SIMD_MODE nds32_vectorize_preferred_simd_mode
+
/* Anchored Addresses. */