diff options
Diffstat (limited to 'gcc/config/nds32/nds32-predicates.c')
-rw-r--r-- | gcc/config/nds32/nds32-predicates.c | 77 |
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); +} + /* ------------------------------------------------------------------------ */ |