summaryrefslogtreecommitdiff
path: root/gcc/config/nds32/nds32-predicates.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/config/nds32/nds32-predicates.c')
-rw-r--r--gcc/config/nds32/nds32-predicates.c77
1 files changed, 77 insertions, 0 deletions
diff --git a/gcc/config/nds32/nds32-predicates.c b/gcc/config/nds32/nds32-predicates.c
index a670623bf9a1..2363b9679766 100644
--- a/gcc/config/nds32/nds32-predicates.c
+++ b/gcc/config/nds32/nds32-predicates.c
@@ -518,4 +518,81 @@ nds32_const_double_range_ok_p (rtx op, machine_mode mode,
return val >= lower && val < upper;
}
+
+HOST_WIDE_INT
+const_vector_to_hwint (rtx op)
+{
+ HOST_WIDE_INT hwint = 0;
+ HOST_WIDE_INT mask;
+ int i;
+ int shift_adv;
+ int shift = 0;
+ int nelem;
+
+ switch (GET_MODE (op))
+ {
+ case V2HImode:
+ mask = 0xffff;
+ shift_adv = 16;
+ nelem = 2;
+ break;
+ case V4QImode:
+ mask = 0xff;
+ shift_adv = 8;
+ nelem = 4;
+ break;
+ default:
+ gcc_unreachable ();
+ }
+
+ if (TARGET_BIG_ENDIAN)
+ {
+ for (i = 0; i < nelem; ++i)
+ {
+ HOST_WIDE_INT val = XINT (XVECEXP (op, 0, nelem - i - 1), 0);
+ hwint |= (val & mask) << shift;
+ shift = shift + shift_adv;
+ }
+ }
+ else
+ {
+ for (i = 0; i < nelem; ++i)
+ {
+ HOST_WIDE_INT val = XINT (XVECEXP (op, 0, i), 0);
+ hwint |= (val & mask) << shift;
+ shift = shift + shift_adv;
+ }
+ }
+
+ return hwint;
+}
+
+bool
+nds32_valid_CVp5_p (rtx op)
+{
+ HOST_WIDE_INT ival = const_vector_to_hwint (op);
+ return (ival < ((1 << 5) + 16)) && (ival >= (0 + 16));
+}
+
+bool
+nds32_valid_CVs5_p (rtx op)
+{
+ HOST_WIDE_INT ival = const_vector_to_hwint (op);
+ return (ival < (1 << 4)) && (ival >= -(1 << 4));
+}
+
+bool
+nds32_valid_CVs2_p (rtx op)
+{
+ HOST_WIDE_INT ival = const_vector_to_hwint (op);
+ return (ival < (1 << 19)) && (ival >= -(1 << 19));
+}
+
+bool
+nds32_valid_CVhi_p (rtx op)
+{
+ HOST_WIDE_INT ival = const_vector_to_hwint (op);
+ return (ival != 0) && ((ival & 0xfff) == 0);
+}
+
/* ------------------------------------------------------------------------ */