/* Return true for valid and false for invalid. */
bool
aarch64_simd_valid_immediate (rtx op, machine_mode mode, bool inverse,
- struct simd_immediate_info *info)
+ struct simd_immediate_info *info,
+ enum simd_immediate_check which)
{
#define CHECK(STRIDE, ELSIZE, CLASS, TEST, SHIFT, NEG) \
matches = 1; \
do
{
- CHECK (4, 32, 0, bytes[i] == bytes[0] && bytes[i + 1] == 0
- && bytes[i + 2] == 0 && bytes[i + 3] == 0, 0, 0);
+ if (which & AARCH64_CHECK_ORR)
+ {
+ CHECK (4, 32, 0, bytes[i] == bytes[0] && bytes[i + 1] == 0
+ && bytes[i + 2] == 0 && bytes[i + 3] == 0, 0, 0);
- CHECK (4, 32, 1, bytes[i] == 0 && bytes[i + 1] == bytes[1]
- && bytes[i + 2] == 0 && bytes[i + 3] == 0, 8, 0);
+ CHECK (4, 32, 1, bytes[i] == 0 && bytes[i + 1] == bytes[1]
+ && bytes[i + 2] == 0 && bytes[i + 3] == 0, 8, 0);
- CHECK (4, 32, 2, bytes[i] == 0 && bytes[i + 1] == 0
- && bytes[i + 2] == bytes[2] && bytes[i + 3] == 0, 16, 0);
+ CHECK (4, 32, 2, bytes[i] == 0 && bytes[i + 1] == 0
+ && bytes[i + 2] == bytes[2] && bytes[i + 3] == 0, 16, 0);
- CHECK (4, 32, 3, bytes[i] == 0 && bytes[i + 1] == 0
- && bytes[i + 2] == 0 && bytes[i + 3] == bytes[3], 24, 0);
+ CHECK (4, 32, 3, bytes[i] == 0 && bytes[i + 1] == 0
+ && bytes[i + 2] == 0 && bytes[i + 3] == bytes[3], 24, 0);
- CHECK (2, 16, 4, bytes[i] == bytes[0] && bytes[i + 1] == 0, 0, 0);
+ CHECK (2, 16, 4, bytes[i] == bytes[0] && bytes[i + 1] == 0, 0, 0);
- CHECK (2, 16, 5, bytes[i] == 0 && bytes[i + 1] == bytes[1], 8, 0);
+ CHECK (2, 16, 5, bytes[i] == 0 && bytes[i + 1] == bytes[1], 8, 0);
+ }
- CHECK (4, 32, 6, bytes[i] == bytes[0] && bytes[i + 1] == 0xff
- && bytes[i + 2] == 0xff && bytes[i + 3] == 0xff, 0, 1);
+ if (which & AARCH64_CHECK_BIC)
+ {
+ CHECK (4, 32, 6, bytes[i] == bytes[0] && bytes[i + 1] == 0xff
+ && bytes[i + 2] == 0xff && bytes[i + 3] == 0xff, 0, 1);
- CHECK (4, 32, 7, bytes[i] == 0xff && bytes[i + 1] == bytes[1]
- && bytes[i + 2] == 0xff && bytes[i + 3] == 0xff, 8, 1);
+ CHECK (4, 32, 7, bytes[i] == 0xff && bytes[i + 1] == bytes[1]
+ && bytes[i + 2] == 0xff && bytes[i + 3] == 0xff, 8, 1);
- CHECK (4, 32, 8, bytes[i] == 0xff && bytes[i + 1] == 0xff
- && bytes[i + 2] == bytes[2] && bytes[i + 3] == 0xff, 16, 1);
+ CHECK (4, 32, 8, bytes[i] == 0xff && bytes[i + 1] == 0xff
+ && bytes[i + 2] == bytes[2] && bytes[i + 3] == 0xff, 16, 1);
- CHECK (4, 32, 9, bytes[i] == 0xff && bytes[i + 1] == 0xff
- && bytes[i + 2] == 0xff && bytes[i + 3] == bytes[3], 24, 1);
+ CHECK (4, 32, 9, bytes[i] == 0xff && bytes[i + 1] == 0xff
+ && bytes[i + 2] == 0xff && bytes[i + 3] == bytes[3], 24, 1);
- CHECK (2, 16, 10, bytes[i] == bytes[0] && bytes[i + 1] == 0xff, 0, 1);
+ CHECK (2, 16, 10, bytes[i] == bytes[0] && bytes[i + 1] == 0xff, 0, 1);
- CHECK (2, 16, 11, bytes[i] == 0xff && bytes[i + 1] == bytes[1], 8, 1);
+ CHECK (2, 16, 11, bytes[i] == 0xff && bytes[i + 1] == bytes[1], 8, 1);
+ }
- CHECK (4, 32, 12, bytes[i] == 0xff && bytes[i + 1] == bytes[1]
- && bytes[i + 2] == 0 && bytes[i + 3] == 0, 8, 0);
+ /* Shifting ones / 8-bit / 64-bit variants only checked
+ for 'ALL' (MOVI/MVNI). */
+ if (which == AARCH64_CHECK_MOV)
+ {
+ CHECK (4, 32, 12, bytes[i] == 0xff && bytes[i + 1] == bytes[1]
+ && bytes[i + 2] == 0 && bytes[i + 3] == 0, 8, 0);
- CHECK (4, 32, 13, bytes[i] == 0 && bytes[i + 1] == bytes[1]
- && bytes[i + 2] == 0xff && bytes[i + 3] == 0xff, 8, 1);
+ CHECK (4, 32, 13, bytes[i] == 0 && bytes[i + 1] == bytes[1]
+ && bytes[i + 2] == 0xff && bytes[i + 3] == 0xff, 8, 1);
- CHECK (4, 32, 14, bytes[i] == 0xff && bytes[i + 1] == 0xff
- && bytes[i + 2] == bytes[2] && bytes[i + 3] == 0, 16, 0);
+ CHECK (4, 32, 14, bytes[i] == 0xff && bytes[i + 1] == 0xff
+ && bytes[i + 2] == bytes[2] && bytes[i + 3] == 0, 16, 0);
- CHECK (4, 32, 15, bytes[i] == 0 && bytes[i + 1] == 0
- && bytes[i + 2] == bytes[2] && bytes[i + 3] == 0xff, 16, 1);
+ CHECK (4, 32, 15, bytes[i] == 0 && bytes[i + 1] == 0
+ && bytes[i + 2] == bytes[2] && bytes[i + 3] == 0xff, 16, 1);
- CHECK (1, 8, 16, bytes[i] == bytes[0], 0, 0);
+ CHECK (1, 8, 16, bytes[i] == bytes[0], 0, 0);
- CHECK (1, 64, 17, (bytes[i] == 0 || bytes[i] == 0xff)
- && bytes[i] == bytes[(i + 8) % idx], 0, 0);
+ CHECK (1, 64, 17, (bytes[i] == 0 || bytes[i] == 0xff)
+ && bytes[i] == bytes[(i + 8) % idx], 0, 0);
+ }
}
while (0);
return (exponent >= 0 && exponent <= 7);
}
+/* Returns the string with the instruction for AdvSIMD MOVI, MVNI, ORR or BIC
+ immediate with a CONST_VECTOR of MODE and WIDTH. WHICH selects whether to
+ output MOVI/MVNI, ORR or BIC immediate. */
char*
aarch64_output_simd_mov_immediate (rtx const_vector,
machine_mode mode,
- unsigned width)
+ unsigned width,
+ enum simd_immediate_check which)
{
bool is_valid;
static char templ[40];
struct simd_immediate_info info = { NULL_RTX, 0, 0, false, false };
/* This will return true to show const_vector is legal for use as either
- a AdvSIMD MOVI instruction (or, implicitly, MVNI) immediate. It will
- also update INFO to show how the immediate should be generated. */
- is_valid = aarch64_simd_valid_immediate (const_vector, mode, false, &info);
+ a AdvSIMD MOVI instruction (or, implicitly, MVNI), ORR or BIC immediate.
+ It will also update INFO to show how the immediate should be generated.
+ WHICH selects whether to check for MOVI/MVNI, ORR or BIC. */
+ is_valid = aarch64_simd_valid_immediate (const_vector, mode, false,
+ &info, which);
gcc_assert (is_valid);
element_char = sizetochar (info.element_width);
}
}
- mnemonic = info.mvn ? "mvni" : "movi";
- shift_op = info.msl ? "msl" : "lsl";
-
gcc_assert (CONST_INT_P (info.value));
- if (lane_count == 1)
- snprintf (templ, sizeof (templ), "%s\t%%d0, " HOST_WIDE_INT_PRINT_HEX,
- mnemonic, UINTVAL (info.value));
- else if (info.shift)
- snprintf (templ, sizeof (templ), "%s\t%%0.%d%c, " HOST_WIDE_INT_PRINT_HEX
- ", %s %d", mnemonic, lane_count, element_char,
- UINTVAL (info.value), shift_op, info.shift);
+
+ if (which == AARCH64_CHECK_MOV)
+ {
+ mnemonic = info.mvn ? "mvni" : "movi";
+ shift_op = info.msl ? "msl" : "lsl";
+ if (lane_count == 1)
+ snprintf (templ, sizeof (templ), "%s\t%%d0, " HOST_WIDE_INT_PRINT_HEX,
+ mnemonic, UINTVAL (info.value));
+ else if (info.shift)
+ snprintf (templ, sizeof (templ), "%s\t%%0.%d%c, "
+ HOST_WIDE_INT_PRINT_HEX ", %s %d", mnemonic, lane_count,
+ element_char, UINTVAL (info.value), shift_op, info.shift);
+ else
+ snprintf (templ, sizeof (templ), "%s\t%%0.%d%c, "
+ HOST_WIDE_INT_PRINT_HEX, mnemonic, lane_count,
+ element_char, UINTVAL (info.value));
+ }
else
- snprintf (templ, sizeof (templ), "%s\t%%0.%d%c, " HOST_WIDE_INT_PRINT_HEX,
- mnemonic, lane_count, element_char, UINTVAL (info.value));
+ {
+ /* For AARCH64_CHECK_BIC and AARCH64_CHECK_ORR. */
+ mnemonic = info.mvn ? "bic" : "orr";
+ if (info.shift)
+ snprintf (templ, sizeof (templ), "%s\t%%0.%d%c, #"
+ HOST_WIDE_INT_PRINT_DEC ", %s #%d", mnemonic, lane_count,
+ element_char, UINTVAL (info.value), "lsl", info.shift);
+ else
+ snprintf (templ, sizeof (templ), "%s\t%%0.%d%c, #"
+ HOST_WIDE_INT_PRINT_DEC, mnemonic, lane_count,
+ element_char, UINTVAL (info.value));
+ }
return templ;
}