aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorTejas Belagod <tejas.belagod@arm.com>2013-07-12 13:50:23 +0100
committerTejas Belagod <belagod@gcc.gnu.org>2013-07-12 13:50:23 +0100
commite4f0f84d56bccc7ffcbf2ba7def8bcc7cb921b6b (patch)
treeff20b173f361cd44a121b3f749dea4ffff591d4f /gcc
parentdd4afcc2f0b8edde8373be1eed2215bdd39b6d4e (diff)
downloadgcc-e4f0f84d56bccc7ffcbf2ba7def8bcc7cb921b6b.zip
gcc-e4f0f84d56bccc7ffcbf2ba7def8bcc7cb921b6b.tar.gz
gcc-e4f0f84d56bccc7ffcbf2ba7def8bcc7cb921b6b.tar.bz2
2013-07-12 Tejas Belagod <tejas.belagod@arm.com>
gcc/ * config/aarch64/aarch64-protos.h (aarch64_simd_immediate_valid_for_move): Remove. * config/aarch64/aarch64.c (simd_immediate_info): New member. (aarch64_simd_valid_immediate): Recognize idioms for shifting ones cases. (aarch64_output_simd_mov_immediate): Print the correct shift specifier. testsuite/ * gcc.target/aarch64/vect-movi.c: New. From-SVN: r200922
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog9
-rw-r--r--gcc/config/aarch64/aarch64-protos.h3
-rw-r--r--gcc/config/aarch64/aarch64.c27
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gcc.target/aarch64/vect-movi.c74
5 files changed, 101 insertions, 16 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 1d8c05a..bf75708 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,12 @@
+2013-07-12 Tejas Belagod <tejas.belagod@arm.com>
+
+ * config/aarch64/aarch64-protos.h
+ (aarch64_simd_immediate_valid_for_move): Remove.
+ * config/aarch64/aarch64.c (simd_immediate_info): New member.
+ (aarch64_simd_valid_immediate): Recognize idioms for shifting ones
+ cases.
+ (aarch64_output_simd_mov_immediate): Print the correct shift specifier.
+
2013-07-11 Steve Ellcey <sellcey@mips.com>
* config/mips/mips.c (mips_conditional_register_usage): Do not
diff --git a/gcc/config/aarch64/aarch64-protos.h b/gcc/config/aarch64/aarch64-protos.h
index a024bd2..e749cc1 100644
--- a/gcc/config/aarch64/aarch64-protos.h
+++ b/gcc/config/aarch64/aarch64-protos.h
@@ -204,9 +204,6 @@ int aarch64_asm_preferred_eh_data_format (int, int);
int aarch64_hard_regno_mode_ok (unsigned, enum machine_mode);
int aarch64_hard_regno_nregs (unsigned, enum machine_mode);
int aarch64_simd_attr_length_move (rtx);
-int aarch64_simd_immediate_valid_for_move (rtx, enum machine_mode, rtx *,
- int *, unsigned char *, int *,
- int *);
int aarch64_uxt_size (int, HOST_WIDE_INT);
rtx aarch64_final_eh_return_addr (void);
rtx aarch64_legitimize_reload_address (rtx *, enum machine_mode, int, int, int);
diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index 4ba46d2..025975c 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -95,6 +95,7 @@ struct simd_immediate_info
int shift;
int element_width;
bool mvn;
+ bool msl;
};
/* The current code model. */
@@ -6437,16 +6438,16 @@ aarch64_simd_valid_immediate (rtx op, enum machine_mode mode, bool inverse,
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);
@@ -6455,12 +6456,7 @@ aarch64_simd_valid_immediate (rtx op, enum machine_mode mode, bool inverse,
}
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)
@@ -6471,6 +6467,9 @@ aarch64_simd_valid_immediate (rtx op, enum machine_mode mode, bool inverse,
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++)
@@ -7403,10 +7402,11 @@ aarch64_output_simd_mov_immediate (rtx const_vector,
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
@@ -7442,14 +7442,15 @@ aarch64_output_simd_mov_immediate (rtx const_vector,
}
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));
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 57ab286f..061a842 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+2013-07-12 Tejas Belagod <tejas.belagod@arm.com>
+
+ * gcc.target/aarch64/vect-movi.c: New.
+
2013-07-11 Sriraman Tallam <tmsriram@google.com>
PR target/57362
diff --git a/gcc/testsuite/gcc.target/aarch64/vect-movi.c b/gcc/testsuite/gcc.target/aarch64/vect-movi.c
new file mode 100644
index 0000000..59a0bd5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/vect-movi.c
@@ -0,0 +1,74 @@
+/* { 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 } } */