int shift;
int element_width;
bool mvn;
+ bool msl;
};
/* The current code model. */
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, 0, 0);
+ && 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, 0, 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, 0, 0);
+ && 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, 0, 1);
+ && bytes[i + 2] == bytes[2] && bytes[i + 3] == 0xff, 16, 1);
CHECK (1, 8, 16, bytes[i] == bytes[0], 0, 0);
}
while (0);
- /* TODO: Currently the assembler cannot handle types 12 to 15.
- And there is no way to specify cmode through the compiler.
- Disable them till there is support in the assembler. */
- if (immtype == -1
- || (immtype >= 12 && immtype <= 15)
- || immtype == 18)
+ if (immtype == -1)
return false;
if (info)
unsigned HOST_WIDE_INT imm = 0;
+ if (immtype >= 12 && immtype <= 15)
+ info->msl = true;
+
/* Un-invert bytes of recognized vector, if necessary. */
if (invmask != 0)
for (i = 0; i < idx; i++)
bool is_valid;
static char templ[40];
const char *mnemonic;
+ const char *shift_op;
unsigned int lane_count = 0;
char element_char;
- struct simd_immediate_info info;
+ 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
}
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
- ", lsl %d", mnemonic, lane_count, element_char,
- UINTVAL (info.value), info.shift);
+ ", %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));
--- /dev/null
+/* { dg-do run } */
+/* { dg-options "-O3 --save-temps -fno-inline" } */
+
+extern void abort (void);
+
+#define N 16
+
+static void
+movi_msl8 (int *__restrict a)
+{
+ int i;
+
+ /* { dg-final { scan-assembler "movi\\tv\[0-9\]+\.4s, 0xab, msl 8" } } */
+ for (i = 0; i < N; i++)
+ a[i] = 0xabff;
+}
+
+static void
+movi_msl16 (int *__restrict a)
+{
+ int i;
+
+ /* { dg-final { scan-assembler "movi\\tv\[0-9\]+\.4s, 0xab, msl 16" } } */
+ for (i = 0; i < N; i++)
+ a[i] = 0xabffff;
+}
+
+static void
+mvni_msl8 (int *__restrict a)
+{
+ int i;
+
+ /* { dg-final { scan-assembler "mvni\\tv\[0-9\]+\.4s, 0xab, msl 8" } } */
+ for (i = 0; i < N; i++)
+ a[i] = 0xffff5400;
+}
+
+static void
+mvni_msl16 (int *__restrict a)
+{
+ int i;
+
+ /* { dg-final { scan-assembler "mvni\\tv\[0-9\]+\.4s, 0xab, msl 16" } } */
+ for (i = 0; i < N; i++)
+ a[i] = 0xff540000;
+}
+
+int
+main (void)
+{
+ int a[N] = { 0 };
+ int i;
+
+#define CHECK_ARRAY(a, val) \
+ for (i = 0; i < N; i++) \
+ if (a[i] != val) \
+ abort ();
+
+ movi_msl8 (a);
+ CHECK_ARRAY (a, 0xabff);
+
+ movi_msl16 (a);
+ CHECK_ARRAY (a, 0xabffff);
+
+ mvni_msl8 (a);
+ CHECK_ARRAY (a, 0xffff5400);
+
+ mvni_msl16 (a);
+ CHECK_ARRAY (a, 0xff540000);
+
+ return 0;
+}
+
+/* { dg-final { cleanup-saved-temps } } */