aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYvan Roux <yvan.roux@linaro.org>2012-12-10 15:58:14 +0100
committerYvan Roux <yvan.roux@linaro.org>2012-12-10 15:58:14 +0100
commit1cec431e430405762f883c3bc2905d05b3f5ded8 (patch)
tree86cd60a3f41ad7f3b02ab1df73219d55f2f56b19
parenta3e13840617a8fafd2e72e5d13b95ab3133f6314 (diff)
parent9d22ede3d1152cf9f1820efc8c80e7b7b107ce38 (diff)
Michael Hope 2012-12-05 Merge from FSF arm/aarch64-4.7-branch r193937..r194154.
-rw-r--r--ChangeLog.linaro97
-rw-r--r--gcc/ChangeLog.aarch6480
-rw-r--r--gcc/config/aarch64/aarch64-builtins.c1179
-rw-r--r--gcc/config/aarch64/aarch64-protos.h9
-rw-r--r--gcc/config/aarch64/aarch64-simd-builtins.def208
-rw-r--r--gcc/config/aarch64/aarch64-simd.md144
-rw-r--r--gcc/config/aarch64/aarch64.c130
-rw-r--r--gcc/config/aarch64/aarch64.h9
-rw-r--r--gcc/config/aarch64/iterators.md1
-rw-r--r--gcc/testsuite/ChangeLog.aarch646
-rw-r--r--gcc/testsuite/gcc.target/aarch64/121127.c4
-rw-r--r--libgcc/ChangeLog.aarch646
-rw-r--r--libgcc/config/aarch64/sfp-exceptions.c76
-rw-r--r--libgcc/config/aarch64/sfp-machine.h68
-rw-r--r--libgcc/config/aarch64/t-softfp2
15 files changed, 1265 insertions, 754 deletions
diff --git a/ChangeLog.linaro b/ChangeLog.linaro
index 765a3c91c05..99615957378 100644
--- a/ChangeLog.linaro
+++ b/ChangeLog.linaro
@@ -1,3 +1,100 @@
+2012-12-05 Michael Hope <michael.hope@linaro.org>
+
+ Merge from FSF arm/aarch64-4.7-branch r193937..r194154.
+
+ Backport arm-aarch64-4.7 r193937:
+ gcc/ChangeLog.aarch64
+
+ Backport from mainline.
+ 2012-11-20 James Greenhalgh <james.greenhalgh@arm.com>
+ Tejas Belagod <tejas.belagod@arm.com>
+
+ * config/aarch64/aarch64-builtins.c
+ (aarch64_simd_builtin_type_bits): Rename to...
+ (aarch64_simd_builtin_type_mode): ...this, make sequential.
+ (aarch64_simd_builtin_datum): Refactor members.
+ (VAR1, VAR2, ..., VAR12): Update accordingly.
+ (aarch64_simd_builtin_data): Include from aarch64-simd-builtins.def.
+ (aarch64_builtins): Update accordingly.
+ (init_aarch64_simd_builtins): Refactor, rename to...
+ (aarch64_init_simd_builtins): ...this.
+ (aarch64_simd_builtin_compare): Remove.
+ (locate_simd_builtin_icode): Likewise.
+ * config/aarch64/aarch64-protos.h (aarch64_init_builtins): New.
+ (aarch64_expand_builtin): Likewise.
+ (aarch64_load_tp): Likewise.
+ * config/aarch64/aarch64-simd-builtins.def: New file.
+ * config/aarch64/aarch64.c (aarch64_init_builtins):
+ Move to aarch64-builtins.c.
+ (aarch64_expand_builtin): Likewise.
+ (aarch64_load_tp): Remove static designation.
+ * config/aarch64/aarch64.h
+ (aarch64_builtins): Move to aarch64-builtins.c.
+
+ Backport arm-aarch64-4.7 r193939:
+ gcc/
+
+ Backport from mainline.
+ 2012-11-26 James Greenhalgh <james.greenhalgh@arm.com>
+
+ * config/aarch64/aarch64-builtins.c (aarch64_builtin_decls): New.
+ (aarch64_init_simd_builtins): Store declaration after builtin
+ initialisation.
+ (aarch64_init_builtins): Likewise.
+ (aarch64_builtin_decl): New.
+ * config/aarch64/aarch64-protos.h (aarch64_builtin_decl): New.
+ * config/aarch64/aarch64.c (TARGET_BUILTIN_DECL): Define.
+
+ Backport arm-aarch64-4.7 r194079:
+ [AARCH64-4.7] Refactor constant generation.
+
+ 2012-12-03 Sofiane Naci <sofiane.naci@arm.com>
+
+ * config/aarch64/aarch64.c (aarch64_build_constant): Update prototype.
+ Call emit_move_insn instead of printing movi/movn/movz instructions.
+ Call gen_insv_immdi instead of printing movk instruction.
+ (aarch64_add_constant): Update prototype.
+ Generate RTL instead of printing add/sub instructions.
+ (aarch64_output_mi_thunk): Update calls to aarch64_build_constant
+ and aarch64_add_constant.
+
+ Backport arm-aarch64-4.7 r194089:
+ [AARCH64-4.7] Backport - Add vcond, vcondu support.
+
+ Backport of revision 192985.
+
+ gcc/
+ * config/aarch64/aarch64-simd.md
+ (aarch64_simd_bsl<mode>_internal): New pattern.
+ (aarch64_simd_bsl<mode>): Likewise.
+ (aarch64_vcond_internal<mode>): Likewise.
+ (vcondu<mode><mode>): Likewise.
+ (vcond<mode><mode>): Likewise.
+ * config/aarch64/iterators.md (UNSPEC_BSL): Add to define_constants.
+
+ Backport arm-aarch64-4.7 r194131:
+
+ 2012-12-04 Tejas Belagod <tejas.belagod@arm.com>
+
+ * config/aarch64/aarch64.c (aarch64_simd_vector_alignment,
+ aarch64_simd_vector_alignment_reachable): New.
+ (TARGET_VECTOR_ALIGNMENT, TARGET_VECTORIZE_VECTOR_ALIGNMENT_REACHABLE):
+ Define.
+
+ Backport arm-aarch64-4.7 r194148:
+ AArch64: Fix ICE due to missing TYPE_STUB_DECL on builtin va_list.
+
+ 2012-12-04 Marcus Shawcroft <marcus.shawcroft@arm.com>
+
+ * config/aarch64/aarch64.c (aarch64_build_builtin_va_list): Set
+ TYPE_STUB_DECL.
+
+ Backport arm-aarch64-4.7 r194153:
+ AArch64-4.7: Backport refactor of sfp-machine.h
+
+ Backport arm-aarch64-4.7 r194154:
+ AArch64-4.7: Backport implement FP_TRAPPING_EXCEPTIONS.
+
2012-12-05 Yvan Roux <yvan.roux@linaro.org>
Merge from FSF GCC 4.7.2 (svn branches/gcc-4_7-branch 194184).
diff --git a/gcc/ChangeLog.aarch64 b/gcc/ChangeLog.aarch64
index b7d675bac50..7ff42f5fc61 100644
--- a/gcc/ChangeLog.aarch64
+++ b/gcc/ChangeLog.aarch64
@@ -1,3 +1,83 @@
+2012-12-04 Marcus Shawcroft <marcus.shawcroft@arm.com>
+
+ Backport from mainline
+ 2012-12-04 Marcus Shawcroft <marcus.shawcroft@arm.com>
+
+ * config/aarch64/aarch64.c (aarch64_build_builtin_va_list): Set
+ TYPE_STUB_DECL.
+
+2012-12-04 Tejas Belagod <tejas.belagod@arm.com>
+
+ * config/aarch64/aarch64.c (aarch64_simd_vector_alignment,
+ aarch64_simd_vector_alignment_reachable): New.
+ (TARGET_VECTOR_ALIGNMENT, TARGET_VECTORIZE_VECTOR_ALIGNMENT_REACHABLE):
+ Define.
+
+2012-12-03 James Greenhalgh <james.greenhalgh@arm.com>
+
+ Backport from mainline.
+ 2012-10-30 James Greenhalgh <james.greenhalgh@arm.com>
+ Tejas Belagod <tejas.belagod@arm.com>
+
+ * config/aarch64/aarch64-simd.md
+ (aarch64_simd_bsl<mode>_internal): New pattern.
+ (aarch64_simd_bsl<mode>): Likewise.
+ (aarch64_vcond_internal<mode>): Likewise.
+ (vcondu<mode><mode>): Likewise.
+ (vcond<mode><mode>): Likewise.
+ * config/aarch64/iterators.md (UNSPEC_BSL): Add to define_constants.
+
+2012-12-03 Sofiane Naci <sofiane.naci@arm.com>
+
+ * config/aarch64/aarch64.c (aarch64_build_constant): Update prototype.
+ Call emit_move_insn instead of printing movi/movn/movz instructions.
+ Call gen_insv_immdi instead of printing movk instruction.
+ (aarch64_add_constant): Update prototype.
+ Generate RTL instead of printing add/sub instructions.
+ (aarch64_output_mi_thunk): Update calls to aarch64_build_constant
+ and aarch64_add_constant.
+
+2012-11-29 James Greenhalgh <james.greenhalgh@arm.com>
+
+ Backport from mainline.
+ 2012-11-26 James Greenhalgh <james.greenhalgh@arm.com>
+
+ * config/aarch64/aarch64-builtins.c (aarch64_builtin_decls): New.
+ (aarch64_init_simd_builtins): Store declaration after builtin
+ initialisation.
+ (aarch64_init_builtins): Likewise.
+ (aarch64_builtin_decl): New.
+ * config/aarch64/aarch64-protos.h (aarch64_builtin_decl): New.
+ * config/aarch64/aarch64.c (TARGET_BUILTIN_DECL): Define.
+
+2012-11-29 James Greenhalgh <james.greenhalgh@arm.com>
+
+ Backport from mainline.
+ 2012-11-20 James Greenhalgh <james.greenhalgh@arm.com>
+ Tejas Belagod <tejas.belagod@arm.com>
+
+ * config/aarch64/aarch64-builtins.c
+ (aarch64_simd_builtin_type_bits): Rename to...
+ (aarch64_simd_builtin_type_mode): ...this, make sequential.
+ (aarch64_simd_builtin_datum): Refactor members.
+ (VAR1, VAR2, ..., VAR12): Update accordingly.
+ (aarch64_simd_builtin_data): Include from aarch64-simd-builtins.def.
+ (aarch64_builtins): Update accordingly.
+ (init_aarch64_simd_builtins): Refactor, rename to...
+ (aarch64_init_simd_builtins): ...this.
+ (aarch64_simd_builtin_compare): Remove.
+ (locate_simd_builtin_icode): Likewise.
+ * config/aarch64/aarch64-protos.h (aarch64_init_builtins): New.
+ (aarch64_expand_builtin): Likewise.
+ (aarch64_load_tp): Likewise.
+ * config/aarch64/aarch64-simd-builtins.def: New file.
+ * config/aarch64/aarch64.c (aarch64_init_builtins):
+ Move to aarch64-builtins.c.
+ (aarch64_expand_builtin): Likewise.
+ (aarch64_load_tp): Remove static designation.
+ * config/aarch64/aarch64.h
+ (aarch64_builtins): Move to aarch64-builtins.c.
+
2012-11-22 Marcus Shawcroft <marcus.shawcroft@arm.com>
* doc/md.texi (AArch64 family): Remove Utf.
diff --git a/gcc/config/aarch64/aarch64-builtins.c b/gcc/config/aarch64/aarch64-builtins.c
index 429a0dfdbfc..2db7edb235a 100644
--- a/gcc/config/aarch64/aarch64-builtins.c
+++ b/gcc/config/aarch64/aarch64-builtins.c
@@ -31,27 +31,28 @@
#include "diagnostic-core.h"
#include "optabs.h"
-enum aarch64_simd_builtin_type_bits
+enum aarch64_simd_builtin_type_mode
{
- T_V8QI = 0x0001,
- T_V4HI = 0x0002,
- T_V2SI = 0x0004,
- T_V2SF = 0x0008,
- T_DI = 0x0010,
- T_DF = 0x0020,
- T_V16QI = 0x0040,
- T_V8HI = 0x0080,
- T_V4SI = 0x0100,
- T_V4SF = 0x0200,
- T_V2DI = 0x0400,
- T_V2DF = 0x0800,
- T_TI = 0x1000,
- T_EI = 0x2000,
- T_OI = 0x4000,
- T_XI = 0x8000,
- T_SI = 0x10000,
- T_HI = 0x20000,
- T_QI = 0x40000
+ T_V8QI,
+ T_V4HI,
+ T_V2SI,
+ T_V2SF,
+ T_DI,
+ T_DF,
+ T_V16QI,
+ T_V8HI,
+ T_V4SI,
+ T_V4SF,
+ T_V2DI,
+ T_V2DF,
+ T_TI,
+ T_EI,
+ T_OI,
+ T_XI,
+ T_SI,
+ T_HI,
+ T_QI,
+ T_MAX
};
#define v8qi_UP T_V8QI
@@ -76,8 +77,6 @@ enum aarch64_simd_builtin_type_bits
#define UP(X) X##_UP
-#define T_MAX 19
-
typedef enum
{
AARCH64_SIMD_BINOP,
@@ -124,253 +123,175 @@ typedef struct
{
const char *name;
const aarch64_simd_itype itype;
- const int bits;
- const enum insn_code codes[T_MAX];
- const unsigned int num_vars;
- unsigned int base_fcode;
+ enum aarch64_simd_builtin_type_mode mode;
+ const enum insn_code code;
+ unsigned int fcode;
} aarch64_simd_builtin_datum;
#define CF(N, X) CODE_FOR_aarch64_##N##X
#define VAR1(T, N, A) \
- #N, AARCH64_SIMD_##T, UP (A), { CF (N, A) }, 1, 0
+ {#N, AARCH64_SIMD_##T, UP (A), CF (N, A), 0},
#define VAR2(T, N, A, B) \
- #N, AARCH64_SIMD_##T, UP (A) | UP (B), { CF (N, A), CF (N, B) }, 2, 0
+ VAR1 (T, N, A) \
+ VAR1 (T, N, B)
#define VAR3(T, N, A, B, C) \
- #N, AARCH64_SIMD_##T, UP (A) | UP (B) | UP (C), \
- { CF (N, A), CF (N, B), CF (N, C) }, 3, 0
+ VAR2 (T, N, A, B) \
+ VAR1 (T, N, C)
#define VAR4(T, N, A, B, C, D) \
- #N, AARCH64_SIMD_##T, UP (A) | UP (B) | UP (C) | UP (D), \
- { CF (N, A), CF (N, B), CF (N, C), CF (N, D) }, 4, 0
+ VAR3 (T, N, A, B, C) \
+ VAR1 (T, N, D)
#define VAR5(T, N, A, B, C, D, E) \
- #N, AARCH64_SIMD_##T, UP (A) | UP (B) | UP (C) | UP (D) | UP (E), \
- { CF (N, A), CF (N, B), CF (N, C), CF (N, D), CF (N, E) }, 5, 0
+ VAR4 (T, N, A, B, C, D) \
+ VAR1 (T, N, E)
#define VAR6(T, N, A, B, C, D, E, F) \
- #N, AARCH64_SIMD_##T, UP (A) | UP (B) | UP (C) | UP (D) | UP (E) | UP (F), \
- { CF (N, A), CF (N, B), CF (N, C), CF (N, D), CF (N, E), CF (N, F) }, 6, 0
+ VAR5 (T, N, A, B, C, D, E) \
+ VAR1 (T, N, F)
#define VAR7(T, N, A, B, C, D, E, F, G) \
- #N, AARCH64_SIMD_##T, UP (A) | UP (B) | UP (C) | UP (D) \
- | UP (E) | UP (F) | UP (G), \
- { CF (N, A), CF (N, B), CF (N, C), CF (N, D), CF (N, E), CF (N, F), \
- CF (N, G) }, 7, 0
+ VAR6 (T, N, A, B, C, D, E, F) \
+ VAR1 (T, N, G)
#define VAR8(T, N, A, B, C, D, E, F, G, H) \
- #N, AARCH64_SIMD_##T, UP (A) | UP (B) | UP (C) | UP (D) \
- | UP (E) | UP (F) | UP (G) \
- | UP (H), \
- { CF (N, A), CF (N, B), CF (N, C), CF (N, D), CF (N, E), CF (N, F), \
- CF (N, G), CF (N, H) }, 8, 0
+ VAR7 (T, N, A, B, C, D, E, F, G) \
+ VAR1 (T, N, H)
#define VAR9(T, N, A, B, C, D, E, F, G, H, I) \
- #N, AARCH64_SIMD_##T, UP (A) | UP (B) | UP (C) | UP (D) \
- | UP (E) | UP (F) | UP (G) \
- | UP (H) | UP (I), \
- { CF (N, A), CF (N, B), CF (N, C), CF (N, D), CF (N, E), CF (N, F), \
- CF (N, G), CF (N, H), CF (N, I) }, 9, 0
+ VAR8 (T, N, A, B, C, D, E, F, G, H) \
+ VAR1 (T, N, I)
#define VAR10(T, N, A, B, C, D, E, F, G, H, I, J) \
- #N, AARCH64_SIMD_##T, UP (A) | UP (B) | UP (C) | UP (D) \
- | UP (E) | UP (F) | UP (G) \
- | UP (H) | UP (I) | UP (J), \
- { CF (N, A), CF (N, B), CF (N, C), CF (N, D), CF (N, E), CF (N, F), \
- CF (N, G), CF (N, H), CF (N, I), CF (N, J) }, 10, 0
-
+ VAR9 (T, N, A, B, C, D, E, F, G, H, I) \
+ VAR1 (T, N, J)
#define VAR11(T, N, A, B, C, D, E, F, G, H, I, J, K) \
- #N, AARCH64_SIMD_##T, UP (A) | UP (B) | UP (C) | UP (D) \
- | UP (E) | UP (F) | UP (G) \
- | UP (H) | UP (I) | UP (J) | UP (K), \
- { CF (N, A), CF (N, B), CF (N, C), CF (N, D), CF (N, E), CF (N, F), \
- CF (N, G), CF (N, H), CF (N, I), CF (N, J), CF (N, K) }, 11, 0
-
+ VAR10 (T, N, A, B, C, D, E, F, G, H, I, J) \
+ VAR1 (T, N, K)
#define VAR12(T, N, A, B, C, D, E, F, G, H, I, J, K, L) \
- #N, AARCH64_SIMD_##T, UP (A) | UP (B) | UP (C) | UP (D) \
- | UP (E) | UP (F) | UP (G) \
- | UP (H) | UP (I) | UP (J) | UP (K) | UP (L), \
- { CF (N, A), CF (N, B), CF (N, C), CF (N, D), CF (N, E), CF (N, F), \
- CF (N, G), CF (N, H), CF (N, I), CF (N, J), CF (N, K), CF (N, L) }, 12, 0
-
-
-/* The mode entries in the following table correspond to the "key" type of the
- instruction variant, i.e. equivalent to that which would be specified after
- the assembler mnemonic, which usually refers to the last vector operand.
- (Signed/unsigned/polynomial types are not differentiated between though, and
- are all mapped onto the same mode for a given element size.) The modes
- listed per instruction should be the same as those defined for that
- instruction's pattern in aarch64_simd.md.
- WARNING: Variants should be listed in the same increasing order as
- aarch64_simd_builtin_type_bits. */
+ VAR11 (T, N, A, B, C, D, E, F, G, H, I, J, K) \
+ VAR1 (T, N, L)
+
+/* BUILTIN_<ITERATOR> macros should expand to cover the same range of
+ modes as is given for each define_mode_iterator in
+ config/aarch64/iterators.md. */
+
+#define BUILTIN_DX(T, N) \
+ VAR2 (T, N, di, df)
+#define BUILTIN_SDQ_I(T, N) \
+ VAR4 (T, N, qi, hi, si, di)
+#define BUILTIN_SD_HSI(T, N) \
+ VAR2 (T, N, hi, si)
+#define BUILTIN_V2F(T, N) \
+ VAR2 (T, N, v2sf, v2df)
+#define BUILTIN_VALL(T, N) \
+ VAR10 (T, N, v8qi, v16qi, v4hi, v8hi, v2si, v4si, v2di, v2sf, v4sf, v2df)
+#define BUILTIN_VB(T, N) \
+ VAR2 (T, N, v8qi, v16qi)
+#define BUILTIN_VD(T, N) \
+ VAR4 (T, N, v8qi, v4hi, v2si, v2sf)
+#define BUILTIN_VDC(T, N) \
+ VAR6 (T, N, v8qi, v4hi, v2si, v2sf, di, df)
+#define BUILTIN_VDIC(T, N) \
+ VAR3 (T, N, v8qi, v4hi, v2si)
+#define BUILTIN_VDN(T, N) \
+ VAR3 (T, N, v4hi, v2si, di)
+#define BUILTIN_VDQ(T, N) \
+ VAR7 (T, N, v8qi, v16qi, v4hi, v8hi, v2si, v4si, v2di)
+#define BUILTIN_VDQF(T, N) \
+ VAR3 (T, N, v2sf, v4sf, v2df)
+#define BUILTIN_VDQHS(T, N) \
+ VAR4 (T, N, v4hi, v8hi, v2si, v4si)
+#define BUILTIN_VDQIF(T, N) \
+ VAR9 (T, N, v8qi, v16qi, v4hi, v8hi, v2si, v4si, v2sf, v4sf, v2df)
+#define BUILTIN_VDQM(T, N) \
+ VAR6 (T, N, v8qi, v16qi, v4hi, v8hi, v2si, v4si)
+#define BUILTIN_VDQV(T, N) \
+ VAR5 (T, N, v8qi, v16qi, v4hi, v8hi, v4si)
+#define BUILTIN_VDQ_BHSI(T, N) \
+ VAR6 (T, N, v8qi, v16qi, v4hi, v8hi, v2si, v4si)
+#define BUILTIN_VDQ_I(T, N) \
+ VAR7 (T, N, v8qi, v16qi, v4hi, v8hi, v2si, v4si, v2di)
+#define BUILTIN_VDW(T, N) \
+ VAR3 (T, N, v8qi, v4hi, v2si)
+#define BUILTIN_VD_BHSI(T, N) \
+ VAR3 (T, N, v8qi, v4hi, v2si)
+#define BUILTIN_VD_HSI(T, N) \
+ VAR2 (T, N, v4hi, v2si)
+#define BUILTIN_VD_RE(T, N) \
+ VAR6 (T, N, v8qi, v4hi, v2si, v2sf, di, df)
+#define BUILTIN_VQ(T, N) \
+ VAR6 (T, N, v16qi, v8hi, v4si, v2di, v4sf, v2df)
+#define BUILTIN_VQN(T, N) \
+ VAR3 (T, N, v8hi, v4si, v2di)
+#define BUILTIN_VQW(T, N) \
+ VAR3 (T, N, v16qi, v8hi, v4si)
+#define BUILTIN_VQ_HSI(T, N) \
+ VAR2 (T, N, v8hi, v4si)
+#define BUILTIN_VQ_S(T, N) \
+ VAR6 (T, N, v8qi, v16qi, v4hi, v8hi, v2si, v4si)
+#define BUILTIN_VSDQ_HSI(T, N) \
+ VAR6 (T, N, v4hi, v8hi, v2si, v4si, hi, si)
+#define BUILTIN_VSDQ_I(T, N) \
+ VAR11 (T, N, v8qi, v16qi, v4hi, v8hi, v2si, v4si, v2di, qi, hi, si, di)
+#define BUILTIN_VSDQ_I_BHSI(T, N) \
+ VAR10 (T, N, v8qi, v16qi, v4hi, v8hi, v2si, v4si, v2di, qi, hi, si)
+#define BUILTIN_VSDQ_I_DI(T, N) \
+ VAR8 (T, N, v8qi, v16qi, v4hi, v8hi, v2si, v4si, v2di, di)
+#define BUILTIN_VSD_HSI(T, N) \
+ VAR4 (T, N, v4hi, v2si, hi, si)
+#define BUILTIN_VSQN_HSDI(T, N) \
+ VAR6 (T, N, v8hi, v4si, v2di, hi, si, di)
+#define BUILTIN_VSTRUCT(T, N) \
+ VAR3 (T, N, oi, ci, xi)
static aarch64_simd_builtin_datum aarch64_simd_builtin_data[] = {
- {VAR6 (CREATE, create, v8qi, v4hi, v2si, v2sf, di, df)},
- {VAR6 (GETLANE, get_lane_signed,
- v8qi, v4hi, v2si, v16qi, v8hi, v4si)},
- {VAR7 (GETLANE, get_lane_unsigned,
- v8qi, v4hi, v2si, v16qi, v8hi, v4si, v2di)},
- {VAR4 (GETLANE, get_lane, v2sf, di, v4sf, v2df)},
- {VAR6 (GETLANE, get_dregoi, v8qi, v4hi, v2si, v2sf, di, df)},
- {VAR6 (GETLANE, get_qregoi, v16qi, v8hi, v4si, v4sf, v2di, v2df)},
- {VAR6 (GETLANE, get_dregci, v8qi, v4hi, v2si, v2sf, di, df)},
- {VAR6 (GETLANE, get_qregci, v16qi, v8hi, v4si, v4sf, v2di, v2df)},
- {VAR6 (GETLANE, get_dregxi, v8qi, v4hi, v2si, v2sf, di, df)},
- {VAR6 (GETLANE, get_qregxi, v16qi, v8hi, v4si, v4sf, v2di, v2df)},
- {VAR6 (SETLANE, set_qregoi, v16qi, v8hi, v4si, v4sf, v2di, v2df)},
- {VAR6 (SETLANE, set_qregci, v16qi, v8hi, v4si, v4sf, v2di, v2df)},
- {VAR6 (SETLANE, set_qregxi, v16qi, v8hi, v4si, v4sf, v2di, v2df)},
-
- {VAR5 (REINTERP, reinterpretv8qi, v8qi, v4hi, v2si, v2sf, di)},
- {VAR5 (REINTERP, reinterpretv4hi, v8qi, v4hi, v2si, v2sf, di)},
- {VAR5 (REINTERP, reinterpretv2si, v8qi, v4hi, v2si, v2sf, di)},
- {VAR5 (REINTERP, reinterpretv2sf, v8qi, v4hi, v2si, v2sf, di)},
- {VAR5 (REINTERP, reinterpretdi, v8qi, v4hi, v2si, v2sf, di)},
- {VAR6 (REINTERP, reinterpretv16qi, v16qi, v8hi, v4si, v4sf, v2di, v2df)},
- {VAR6 (REINTERP, reinterpretv8hi, v16qi, v8hi, v4si, v4sf, v2di, v2df)},
- {VAR6 (REINTERP, reinterpretv4si, v16qi, v8hi, v4si, v4sf, v2di, v2df)},
- {VAR6 (REINTERP, reinterpretv4sf, v16qi, v8hi, v4si, v4sf, v2di, v2df)},
- {VAR6 (REINTERP, reinterpretv2di, v16qi, v8hi, v4si, v4sf, v2di, v2df)},
- {VAR6 (COMBINE, combine, v8qi, v4hi, v2si, v2sf, di, df)},
-
- {VAR3 (BINOP, saddl, v8qi, v4hi, v2si)},
- {VAR3 (BINOP, uaddl, v8qi, v4hi, v2si)},
- {VAR3 (BINOP, saddl2, v16qi, v8hi, v4si)},
- {VAR3 (BINOP, uaddl2, v16qi, v8hi, v4si)},
- {VAR3 (BINOP, saddw, v8qi, v4hi, v2si)},
- {VAR3 (BINOP, uaddw, v8qi, v4hi, v2si)},
- {VAR3 (BINOP, saddw2, v16qi, v8hi, v4si)},
- {VAR3 (BINOP, uaddw2, v16qi, v8hi, v4si)},
- {VAR6 (BINOP, shadd, v8qi, v4hi, v2si, v16qi, v8hi, v4si)},
- {VAR6 (BINOP, uhadd, v8qi, v4hi, v2si, v16qi, v8hi, v4si)},
- {VAR6 (BINOP, srhadd, v8qi, v4hi, v2si, v16qi, v8hi, v4si)},
- {VAR6 (BINOP, urhadd, v8qi, v4hi, v2si, v16qi, v8hi, v4si)},
- {VAR3 (BINOP, addhn, v8hi, v4si, v2di)},
- {VAR3 (BINOP, raddhn, v8hi, v4si, v2di)},
- {VAR3 (TERNOP, addhn2, v8hi, v4si, v2di)},
- {VAR3 (TERNOP, raddhn2, v8hi, v4si, v2di)},
- {VAR3 (BINOP, ssubl, v8qi, v4hi, v2si)},
- {VAR3 (BINOP, usubl, v8qi, v4hi, v2si)},
- {VAR3 (BINOP, ssubl2, v16qi, v8hi, v4si) },
- {VAR3 (BINOP, usubl2, v16qi, v8hi, v4si) },
- {VAR3 (BINOP, ssubw, v8qi, v4hi, v2si) },
- {VAR3 (BINOP, usubw, v8qi, v4hi, v2si) },
- {VAR3 (BINOP, ssubw2, v16qi, v8hi, v4si) },
- {VAR3 (BINOP, usubw2, v16qi, v8hi, v4si) },
- {VAR11 (BINOP, sqadd, v8qi, v4hi, v2si, di, v16qi, v8hi, v4si, v2di,
- si, hi, qi)},
- {VAR11 (BINOP, uqadd, v8qi, v4hi, v2si, di, v16qi, v8hi, v4si, v2di,
- si, hi, qi)},
- {VAR11 (BINOP, sqsub, v8qi, v4hi, v2si, di, v16qi, v8hi, v4si, v2di,
- si, hi, qi)},
- {VAR11 (BINOP, uqsub, v8qi, v4hi, v2si, di, v16qi, v8hi, v4si, v2di,
- si, hi, qi)},
- {VAR11 (BINOP, suqadd, v8qi, v4hi, v2si, di, v16qi, v8hi, v4si, v2di,
- si, hi, qi)},
- {VAR11 (BINOP, usqadd, v8qi, v4hi, v2si, di, v16qi, v8hi, v4si, v2di,
- si, hi, qi)},
- {VAR6 (UNOP, sqmovun, di, v8hi, v4si, v2di, si, hi)},
- {VAR6 (UNOP, sqmovn, di, v8hi, v4si, v2di, si, hi)},
- {VAR6 (UNOP, uqmovn, di, v8hi, v4si, v2di, si, hi)},
- {VAR10 (UNOP, sqabs, v8qi, v4hi, v2si, v16qi, v8hi, v4si, v2di, si, hi, qi)},
- {VAR10 (UNOP, sqneg, v8qi, v4hi, v2si, v16qi, v8hi, v4si, v2di, si, hi, qi)},
- {VAR2 (BINOP, pmul, v8qi, v16qi)},
- {VAR4 (TERNOP, sqdmlal, v4hi, v2si, si, hi)},
- {VAR4 (QUADOP, sqdmlal_lane, v4hi, v2si, si, hi) },
- {VAR2 (QUADOP, sqdmlal_laneq, v4hi, v2si) },
- {VAR2 (TERNOP, sqdmlal_n, v4hi, v2si) },
- {VAR2 (TERNOP, sqdmlal2, v8hi, v4si)},
- {VAR2 (QUADOP, sqdmlal2_lane, v8hi, v4si) },
- {VAR2 (QUADOP, sqdmlal2_laneq, v8hi, v4si) },
- {VAR2 (TERNOP, sqdmlal2_n, v8hi, v4si) },
- {VAR4 (TERNOP, sqdmlsl, v4hi, v2si, si, hi)},
- {VAR4 (QUADOP, sqdmlsl_lane, v4hi, v2si, si, hi) },
- {VAR2 (QUADOP, sqdmlsl_laneq, v4hi, v2si) },
- {VAR2 (TERNOP, sqdmlsl_n, v4hi, v2si) },
- {VAR2 (TERNOP, sqdmlsl2, v8hi, v4si)},
- {VAR2 (QUADOP, sqdmlsl2_lane, v8hi, v4si) },
- {VAR2 (QUADOP, sqdmlsl2_laneq, v8hi, v4si) },
- {VAR2 (TERNOP, sqdmlsl2_n, v8hi, v4si) },
- {VAR4 (BINOP, sqdmull, v4hi, v2si, si, hi)},
- {VAR4 (TERNOP, sqdmull_lane, v4hi, v2si, si, hi) },
- {VAR2 (TERNOP, sqdmull_laneq, v4hi, v2si) },
- {VAR2 (BINOP, sqdmull_n, v4hi, v2si) },
- {VAR2 (BINOP, sqdmull2, v8hi, v4si) },
- {VAR2 (TERNOP, sqdmull2_lane, v8hi, v4si) },
- {VAR2 (TERNOP, sqdmull2_laneq, v8hi, v4si) },
- {VAR2 (BINOP, sqdmull2_n, v8hi, v4si) },
- {VAR6 (BINOP, sqdmulh, v4hi, v2si, v8hi, v4si, si, hi)},
- {VAR6 (BINOP, sqrdmulh, v4hi, v2si, v8hi, v4si, si, hi)},
- {VAR8 (BINOP, sshl, v8qi, v4hi, v2si, di, v16qi, v8hi, v4si, v2di) },
- {VAR3 (SHIFTIMM, sshll_n, v8qi, v4hi, v2si) },
- {VAR3 (SHIFTIMM, ushll_n, v8qi, v4hi, v2si) },
- {VAR3 (SHIFTIMM, sshll2_n, v16qi, v8hi, v4si) },
- {VAR3 (SHIFTIMM, ushll2_n, v16qi, v8hi, v4si) },
- {VAR8 (BINOP, ushl, v8qi, v4hi, v2si, di, v16qi, v8hi, v4si, v2di) },
- {VAR8 (BINOP, sshl_n, v8qi, v4hi, v2si, di, v16qi, v8hi, v4si, v2di) },
- {VAR8 (BINOP, ushl_n, v8qi, v4hi, v2si, di, v16qi, v8hi, v4si, v2di) },
- {VAR11 (BINOP, sqshl, v8qi, v4hi, v2si, di, v16qi, v8hi, v4si, v2di,
- si, hi, qi) },
- {VAR11 (BINOP, uqshl, v8qi, v4hi, v2si, di, v16qi, v8hi, v4si, v2di,
- si, hi, qi) },
- {VAR8 (BINOP, srshl, v8qi, v4hi, v2si, di, v16qi, v8hi, v4si, v2di) },
- {VAR8 (BINOP, urshl, v8qi, v4hi, v2si, di, v16qi, v8hi, v4si, v2di) },
- {VAR11 (BINOP, sqrshl, v8qi, v4hi, v2si, di, v16qi, v8hi, v4si, v2di,
- si, hi, qi) },
- {VAR11 (BINOP, uqrshl, v8qi, v4hi, v2si, di, v16qi, v8hi, v4si, v2di,
- si, hi, qi) },
- {VAR8 (SHIFTIMM, sshr_n, v8qi, v4hi, v2si, di, v16qi, v8hi, v4si, v2di) },
- {VAR8 (SHIFTIMM, ushr_n, v8qi, v4hi, v2si, di, v16qi, v8hi, v4si, v2di) },
- {VAR8 (SHIFTIMM, srshr_n, v8qi, v4hi, v2si, di, v16qi, v8hi, v4si, v2di) },
- {VAR8 (SHIFTIMM, urshr_n, v8qi, v4hi, v2si, di, v16qi, v8hi, v4si, v2di) },
- {VAR8 (SHIFTACC, ssra_n, v8qi, v4hi, v2si, di, v16qi, v8hi, v4si, v2di) },
- {VAR8 (SHIFTACC, usra_n, v8qi, v4hi, v2si, di, v16qi, v8hi, v4si, v2di) },
- {VAR8 (SHIFTACC, srsra_n, v8qi, v4hi, v2si, di, v16qi, v8hi, v4si, v2di) },
- {VAR8 (SHIFTACC, ursra_n, v8qi, v4hi, v2si, di, v16qi, v8hi, v4si, v2di) },
- {VAR8 (SHIFTINSERT, ssri_n, v8qi, v4hi, v2si, di, v16qi, v8hi, v4si, v2di) },
- {VAR8 (SHIFTINSERT, usri_n, v8qi, v4hi, v2si, di, v16qi, v8hi, v4si, v2di) },
- {VAR8 (SHIFTINSERT, ssli_n, v8qi, v4hi, v2si, di, v16qi, v8hi, v4si, v2di) },
- {VAR8 (SHIFTINSERT, usli_n, v8qi, v4hi, v2si, di, v16qi, v8hi, v4si, v2di) },
- {VAR11 (SHIFTIMM, sqshlu_n, v8qi, v4hi, v2si, di, v16qi, v8hi, v4si, v2di,
- si, hi, qi) },
- {VAR11 (SHIFTIMM, sqshl_n, v8qi, v4hi, v2si, di, v16qi, v8hi, v4si, v2di,
- si, hi, qi) },
- {VAR11 (SHIFTIMM, uqshl_n, v8qi, v4hi, v2si, di, v16qi, v8hi, v4si, v2di,
- si, hi, qi) },
- { VAR6 (SHIFTIMM, sqshrun_n, di, v8hi, v4si, v2di, si, hi) },
- { VAR6 (SHIFTIMM, sqrshrun_n, di, v8hi, v4si, v2di, si, hi) },
- { VAR6 (SHIFTIMM, sqshrn_n, di, v8hi, v4si, v2di, si, hi) },
- { VAR6 (SHIFTIMM, uqshrn_n, di, v8hi, v4si, v2di, si, hi) },
- { VAR6 (SHIFTIMM, sqrshrn_n, di, v8hi, v4si, v2di, si, hi) },
- { VAR6 (SHIFTIMM, uqrshrn_n, di, v8hi, v4si, v2di, si, hi) },
- { VAR8 (BINOP, cmeq, v8qi, v4hi, v2si, di, v16qi, v8hi, v4si, v2di) },
- { VAR8 (BINOP, cmge, v8qi, v4hi, v2si, di, v16qi, v8hi, v4si, v2di) },
- { VAR8 (BINOP, cmgt, v8qi, v4hi, v2si, di, v16qi, v8hi, v4si, v2di) },
- { VAR8 (BINOP, cmle, v8qi, v4hi, v2si, di, v16qi, v8hi, v4si, v2di) },
- { VAR8 (BINOP, cmlt, v8qi, v4hi, v2si, di, v16qi, v8hi, v4si, v2di) },
- { VAR8 (BINOP, cmhs, v8qi, v4hi, v2si, di, v16qi, v8hi, v4si, v2di) },
- { VAR8 (BINOP, cmhi, v8qi, v4hi, v2si, di, v16qi, v8hi, v4si, v2di) },
- { VAR8 (BINOP, cmtst, v8qi, v4hi, v2si, di, v16qi, v8hi, v4si, v2di) },
- { VAR6 (TERNOP, sqdmulh_lane, v4hi, v2si, v8hi, v4si, si, hi) },
- { VAR6 (TERNOP, sqrdmulh_lane, v4hi, v2si, v8hi, v4si, si, hi) },
- { VAR3 (BINOP, addp, v8qi, v4hi, v2si) },
- { VAR1 (UNOP, addp, di) },
- { VAR11 (BINOP, dup_lane, v8qi, v4hi, v2si, di, v16qi, v8hi, v4si, v2di,
- si, hi, qi) },
- { VAR3 (BINOP, fmax, v2sf, v4sf, v2df) },
- { VAR3 (BINOP, fmin, v2sf, v4sf, v2df) },
- { VAR6 (BINOP, smax, v8qi, v4hi, v2si, v16qi, v8hi, v4si) },
- { VAR6 (BINOP, smin, v8qi, v4hi, v2si, v16qi, v8hi, v4si) },
- { VAR6 (BINOP, umax, v8qi, v4hi, v2si, v16qi, v8hi, v4si) },
- { VAR6 (BINOP, umin, v8qi, v4hi, v2si, v16qi, v8hi, v4si) },
- { VAR3 (UNOP, sqrt, v2sf, v4sf, v2df) },
- {VAR12 (LOADSTRUCT, ld2,
- v8qi, v4hi, v2si, v2sf, di, df, v16qi, v8hi, v4si, v4sf, v2di, v2df)},
- {VAR12 (LOADSTRUCT, ld3,
- v8qi, v4hi, v2si, v2sf, di, df, v16qi, v8hi, v4si, v4sf, v2di, v2df)},
- {VAR12 (LOADSTRUCT, ld4,
- v8qi, v4hi, v2si, v2sf, di, df, v16qi, v8hi, v4si, v4sf, v2di, v2df)},
- {VAR12 (STORESTRUCT, st2,
- v8qi, v4hi, v2si, v2sf, di, df, v16qi, v8hi, v4si, v4sf, v2di, v2df)},
- {VAR12 (STORESTRUCT, st3,
- v8qi, v4hi, v2si, v2sf, di, df, v16qi, v8hi, v4si, v4sf, v2di, v2df)},
- {VAR12 (STORESTRUCT, st4,
- v8qi, v4hi, v2si, v2sf, di, df, v16qi, v8hi, v4si, v4sf, v2di, v2df)},
+#include "aarch64-simd-builtins.def"
+};
+
+#undef VAR1
+#define VAR1(T, N, A) \
+ AARCH64_SIMD_BUILTIN_##N##A,
+
+enum aarch64_builtins
+{
+ AARCH64_BUILTIN_MIN,
+ AARCH64_BUILTIN_THREAD_POINTER,
+ AARCH64_SIMD_BUILTIN_BASE,
+#include "aarch64-simd-builtins.def"
+ AARCH64_SIMD_BUILTIN_MAX = AARCH64_SIMD_BUILTIN_BASE
+ + ARRAY_SIZE (aarch64_simd_builtin_data),
+ AARCH64_BUILTIN_MAX
};
+#undef BUILTIN_DX
+#undef BUILTIN_SDQ_I
+#undef BUILTIN_SD_HSI
+#undef BUILTIN_V2F
+#undef BUILTIN_VALL
+#undef BUILTIN_VB
+#undef BUILTIN_VD
+#undef BUILTIN_VDC
+#undef BUILTIN_VDIC
+#undef BUILTIN_VDN
+#undef BUILTIN_VDQ
+#undef BUILTIN_VDQF
+#undef BUILTIN_VDQHS
+#undef BUILTIN_VDQIF
+#undef BUILTIN_VDQM
+#undef BUILTIN_VDQV
+#undef BUILTIN_VDQ_BHSI
+#undef BUILTIN_VDQ_I
+#undef BUILTIN_VDW
+#undef BUILTIN_VD_BHSI
+#undef BUILTIN_VD_HSI
+#undef BUILTIN_VD_RE
+#undef BUILTIN_VQ
+#undef BUILTIN_VQN
+#undef BUILTIN_VQW
+#undef BUILTIN_VQ_HSI
+#undef BUILTIN_VQ_S
+#undef BUILTIN_VSDQ_HSI
+#undef BUILTIN_VSDQ_I
+#undef BUILTIN_VSDQ_I_BHSI
+#undef BUILTIN_VSDQ_I_DI
+#undef BUILTIN_VSD_HSI
+#undef BUILTIN_VSQN_HSDI
+#undef BUILTIN_VSTRUCT
#undef CF
#undef VAR1
#undef VAR2
@@ -384,13 +305,15 @@ static aarch64_simd_builtin_datum aarch64_simd_builtin_data[] = {
#undef VAR10
#undef VAR11
+static GTY(()) tree aarch64_builtin_decls[AARCH64_BUILTIN_MAX];
+
#define NUM_DREG_TYPES 6
#define NUM_QREG_TYPES 6
void
-init_aarch64_simd_builtins (void)
+aarch64_init_simd_builtins (void)
{
- unsigned int i, fcode = AARCH64_SIMD_BUILTIN_BASE;
+ unsigned int i, fcode = AARCH64_SIMD_BUILTIN_BASE + 1;
/* Scalar type nodes. */
tree aarch64_simd_intQI_type_node;
@@ -680,417 +603,388 @@ init_aarch64_simd_builtins (void)
}
}
- for (i = 0; i < ARRAY_SIZE (aarch64_simd_builtin_data); i++)
+ for (i = 0; i < ARRAY_SIZE (aarch64_simd_builtin_data); i++, fcode++)
{
aarch64_simd_builtin_datum *d = &aarch64_simd_builtin_data[i];
- unsigned int j, codeidx = 0;
+ const char *const modenames[] =
+ {
+ "v8qi", "v4hi", "v2si", "v2sf", "di", "df",
+ "v16qi", "v8hi", "v4si", "v4sf", "v2di", "v2df",
+ "ti", "ei", "oi", "xi", "si", "hi", "qi"
+ };
+ char namebuf[60];
+ tree ftype = NULL;
+ tree fndecl = NULL;
+ int is_load = 0;
+ int is_store = 0;
+
+ gcc_assert (ARRAY_SIZE (modenames) == T_MAX);
- d->base_fcode = fcode;
+ d->fcode = fcode;
- for (j = 0; j < T_MAX; j++)
+ switch (d->itype)
{
- const char *const modenames[] = {
- "v8qi", "v4hi", "v2si", "v2sf", "di", "df",
- "v16qi", "v8hi", "v4si", "v4sf", "v2di", "v2df",
- "ti", "ei", "oi", "xi", "si", "hi", "qi"
- };
- char namebuf[60];
- tree ftype = NULL;
- enum insn_code icode;
- int is_load = 0;
- int is_store = 0;
-
- /* Skip if particular mode not supported. */
- if ((d->bits & (1 << j)) == 0)
- continue;
-
- icode = d->codes[codeidx++];
-
- switch (d->itype)
- {
- case AARCH64_SIMD_LOAD1:
- case AARCH64_SIMD_LOAD1LANE:
- case AARCH64_SIMD_LOADSTRUCTLANE:
- case AARCH64_SIMD_LOADSTRUCT:
- is_load = 1;
- /* Fall through. */
- case AARCH64_SIMD_STORE1:
- case AARCH64_SIMD_STORE1LANE:
- case AARCH64_SIMD_STORESTRUCTLANE:
- case AARCH64_SIMD_STORESTRUCT:
- if (!is_load)
- is_store = 1;
- /* Fall through. */
- case AARCH64_SIMD_UNOP:
- case AARCH64_SIMD_BINOP:
- case AARCH64_SIMD_LOGICBINOP:
- case AARCH64_SIMD_SHIFTINSERT:
- case AARCH64_SIMD_TERNOP:
- case AARCH64_SIMD_QUADOP:
- case AARCH64_SIMD_GETLANE:
- case AARCH64_SIMD_SETLANE:
- case AARCH64_SIMD_CREATE:
- case AARCH64_SIMD_DUP:
- case AARCH64_SIMD_DUPLANE:
- case AARCH64_SIMD_SHIFTIMM:
- case AARCH64_SIMD_SHIFTACC:
- case AARCH64_SIMD_COMBINE:
- case AARCH64_SIMD_SPLIT:
- case AARCH64_SIMD_CONVERT:
- case AARCH64_SIMD_FIXCONV:
- case AARCH64_SIMD_LANEMUL:
- case AARCH64_SIMD_LANEMULL:
- case AARCH64_SIMD_LANEMULH:
- case AARCH64_SIMD_LANEMAC:
- case AARCH64_SIMD_SCALARMUL:
- case AARCH64_SIMD_SCALARMULL:
- case AARCH64_SIMD_SCALARMULH:
- case AARCH64_SIMD_SCALARMAC:
- case AARCH64_SIMD_SELECT:
- case AARCH64_SIMD_VTBL:
- case AARCH64_SIMD_VTBX:
+ case AARCH64_SIMD_LOAD1:
+ case AARCH64_SIMD_LOAD1LANE:
+ case AARCH64_SIMD_LOADSTRUCT:
+ case AARCH64_SIMD_LOADSTRUCTLANE:
+ is_load = 1;
+ /* Fall through. */
+ case AARCH64_SIMD_STORE1:
+ case AARCH64_SIMD_STORE1LANE:
+ case AARCH64_SIMD_STORESTRUCT:
+ case AARCH64_SIMD_STORESTRUCTLANE:
+ if (!is_load)
+ is_store = 1;
+ /* Fall through. */
+ case AARCH64_SIMD_UNOP:
+ case AARCH64_SIMD_BINOP:
+ case AARCH64_SIMD_TERNOP:
+ case AARCH64_SIMD_QUADOP:
+ case AARCH64_SIMD_COMBINE:
+ case AARCH64_SIMD_CONVERT:
+ case AARCH64_SIMD_CREATE:
+ case AARCH64_SIMD_DUP:
+ case AARCH64_SIMD_DUPLANE:
+ case AARCH64_SIMD_FIXCONV:
+ case AARCH64_SIMD_GETLANE:
+ case AARCH64_SIMD_LANEMAC:
+ case AARCH64_SIMD_LANEMUL:
+ case AARCH64_SIMD_LANEMULH:
+ case AARCH64_SIMD_LANEMULL:
+ case AARCH64_SIMD_LOGICBINOP:
+ case AARCH64_SIMD_SCALARMAC:
+ case AARCH64_SIMD_SCALARMUL:
+ case AARCH64_SIMD_SCALARMULH:
+ case AARCH64_SIMD_SCALARMULL:
+ case AARCH64_SIMD_SELECT:
+ case AARCH64_SIMD_SETLANE:
+ case AARCH64_SIMD_SHIFTACC:
+ case AARCH64_SIMD_SHIFTIMM:
+ case AARCH64_SIMD_SHIFTINSERT:
+ case AARCH64_SIMD_SPLIT:
+ case AARCH64_SIMD_VTBL:
+ case AARCH64_SIMD_VTBX:
+ {
+ int k;
+ tree return_type = void_type_node, args = void_list_node;
+ tree eltype;
+ /* Build a function type directly from the insn_data for this
+ builtin. The build_function_type () function takes care of
+ removing duplicates for us. */
+
+ for (k = insn_data[d->code].n_operands -1; k >= 0; k--)
{
- int k;
- tree return_type = void_type_node, args = void_list_node;
+ /* Skip an internal operand for vget_{low, high}. */
+ if (k == 2 && d->itype == AARCH64_SIMD_SPLIT)
+ continue;
- /* Build a function type directly from the insn_data for this
- builtin. The build_function_type() function takes care of
- removing duplicates for us. */
- for (k = insn_data[icode].n_operands - 1; k >= 0; k--)
+ if (is_load && k == 1)
{
- tree eltype;
-
- /* Skip an internal operand for vget_{low, high}. */
- if (k == 2 && d->itype == AARCH64_SIMD_SPLIT)
- continue;
+ /* AdvSIMD load patterns always have the memory operand
+ (a DImode pointer) in the operand 1 position. We
+ want a const pointer to the element type in that
+ position. */
+ gcc_assert (insn_data[d->code].operand[k].mode == DImode);
- if (is_load && k == 1)
+ switch (d->mode)
{
- /* AdvSIMD load patterns always have the memory operand
- (a DImode pointer) in the operand 1 position. We
- want a const pointer to the element type in that
- position. */
- gcc_assert (insn_data[icode].operand[k].mode ==
- DImode);
-
- switch (1 << j)
- {
- case T_V8QI:
- case T_V16QI:
- eltype = const_intQI_pointer_node;
- break;
-
- case T_V4HI:
- case T_V8HI:
- eltype = const_intHI_pointer_node;
- break;
-
- case T_V2SI:
- case T_V4SI:
- eltype = const_intSI_pointer_node;
- break;
-
- case T_V2SF:
- case T_V4SF:
- eltype = const_float_pointer_node;
- break;
-
- case T_DI:
- case T_V2DI:
- eltype = const_intDI_pointer_node;
- break;
-
- case T_DF:
- case T_V2DF:
- eltype = const_double_pointer_node;
- break;
-
- default:
- gcc_unreachable ();
- }
+ case T_V8QI:
+ case T_V16QI:
+ eltype = const_intQI_pointer_node;
+ break;
+
+ case T_V4HI:
+ case T_V8HI:
+ eltype = const_intHI_pointer_node;
+ break;
+
+ case T_V2SI:
+ case T_V4SI:
+ eltype = const_intSI_pointer_node;
+ break;
+
+ case T_V2SF:
+ case T_V4SF:
+ eltype = const_float_pointer_node;
+ break;
+
+ case T_DI:
+ case T_V2DI:
+ eltype = const_intDI_pointer_node;
+ break;
+
+ case T_DF:
+ case T_V2DF:
+ eltype = const_double_pointer_node;
+ break;
+
+ default:
+ gcc_unreachable ();
}
- else if (is_store && k == 0)
+ }
+ else if (is_store && k == 0)
+ {
+ /* Similarly, AdvSIMD store patterns use operand 0 as
+ the memory location to store to (a DImode pointer).
+ Use a pointer to the element type of the store in
+ that position. */
+ gcc_assert (insn_data[d->code].operand[k].mode == DImode);
+
+ switch (d->mode)
{
- /* Similarly, AdvSIMD store patterns use operand 0 as
- the memory location to store to (a DImode pointer).
- Use a pointer to the element type of the store in
- that position. */
- gcc_assert (insn_data[icode].operand[k].mode ==
- DImode);
-
- switch (1 << j)
- {
- case T_V8QI:
- case T_V16QI:
- eltype = intQI_pointer_node;
- break;
-
- case T_V4HI:
- case T_V8HI:
- eltype = intHI_pointer_node;
- break;
-
- case T_V2SI:
- case T_V4SI:
- eltype = intSI_pointer_node;
- break;
-
- case T_V2SF:
- case T_V4SF:
- eltype = float_pointer_node;
- break;
-
- case T_DI:
- case T_V2DI:
- eltype = intDI_pointer_node;
- break;
-
- case T_DF:
- case T_V2DF:
- eltype = double_pointer_node;
- break;
-
- default:
- gcc_unreachable ();
- }
+ case T_V8QI:
+ case T_V16QI:
+ eltype = intQI_pointer_node;
+ break;
+
+ case T_V4HI:
+ case T_V8HI:
+ eltype = intHI_pointer_node;
+ break;
+
+ case T_V2SI:
+ case T_V4SI:
+ eltype = intSI_pointer_node;
+ break;
+
+ case T_V2SF:
+ case T_V4SF:
+ eltype = float_pointer_node;
+ break;
+
+ case T_DI:
+ case T_V2DI:
+ eltype = intDI_pointer_node;
+ break;
+
+ case T_DF:
+ case T_V2DF:
+ eltype = double_pointer_node;
+ break;
+
+ default:
+ gcc_unreachable ();
}
- else
+ }
+ else
+ {
+ switch (insn_data[d->code].operand[k].mode)
{
- switch (insn_data[icode].operand[k].mode)
- {
- case VOIDmode:
- eltype = void_type_node;
- break;
- /* Scalars. */
- case QImode:
- eltype = aarch64_simd_intQI_type_node;
- break;
- case HImode:
- eltype = aarch64_simd_intHI_type_node;
- break;
- case SImode:
- eltype = aarch64_simd_intSI_type_node;
- break;
- case SFmode:
- eltype = aarch64_simd_float_type_node;
- break;
- case DFmode:
- eltype = aarch64_simd_double_type_node;
- break;
- case DImode:
- eltype = aarch64_simd_intDI_type_node;
- break;
- case TImode:
- eltype = intTI_type_node;
- break;
- case EImode:
- eltype = intEI_type_node;
- break;
- case OImode:
- eltype = intOI_type_node;
- break;
- case CImode:
- eltype = intCI_type_node;
- break;
- case XImode:
- eltype = intXI_type_node;
- break;
- /* 64-bit vectors. */
- case V8QImode:
- eltype = V8QI_type_node;
- break;
- case V4HImode:
- eltype = V4HI_type_node;
- break;
- case V2SImode:
- eltype = V2SI_type_node;
- break;
- case V2SFmode:
- eltype = V2SF_type_node;
- break;
- /* 128-bit vectors. */
- case V16QImode:
- eltype = V16QI_type_node;
- break;
- case V8HImode:
- eltype = V8HI_type_node;
- break;
- case V4SImode:
- eltype = V4SI_type_node;
- break;
- case V4SFmode:
- eltype = V4SF_type_node;
- break;
- case V2DImode:
- eltype = V2DI_type_node;
- break;
- case V2DFmode:
- eltype = V2DF_type_node;
- break;
- default:
- gcc_unreachable ();
- }
+ case VOIDmode:
+ eltype = void_type_node;
+ break;
+ /* Scalars. */
+ case QImode:
+ eltype = aarch64_simd_intQI_type_node;
+ break;
+ case HImode:
+ eltype = aarch64_simd_intHI_type_node;
+ break;
+ case SImode:
+ eltype = aarch64_simd_intSI_type_node;
+ break;
+ case SFmode:
+ eltype = aarch64_simd_float_type_node;
+ break;
+ case DFmode:
+ eltype = aarch64_simd_double_type_node;
+ break;
+ case DImode:
+ eltype = aarch64_simd_intDI_type_node;
+ break;
+ case TImode:
+ eltype = intTI_type_node;
+ break;
+ case EImode:
+ eltype = intEI_type_node;
+ break;
+ case OImode:
+ eltype = intOI_type_node;
+ break;
+ case CImode:
+ eltype = intCI_type_node;
+ break;
+ case XImode:
+ eltype = intXI_type_node;
+ break;
+ /* 64-bit vectors. */
+ case V8QImode:
+ eltype = V8QI_type_node;
+ break;
+ case V4HImode:
+ eltype = V4HI_type_node;
+ break;
+ case V2SImode:
+ eltype = V2SI_type_node;
+ break;
+ case V2SFmode:
+ eltype = V2SF_type_node;
+ break;
+ /* 128-bit vectors. */
+ case V16QImode:
+ eltype = V16QI_type_node;
+ break;
+ case V8HImode:
+ eltype = V8HI_type_node;
+ break;
+ case V4SImode:
+ eltype = V4SI_type_node;
+ break;
+ case V4SFmode:
+ eltype = V4SF_type_node;
+ break;
+ case V2DImode:
+ eltype = V2DI_type_node;
+ break;
+ case V2DFmode:
+ eltype = V2DF_type_node;
+ break;
+ default:
+ gcc_unreachable ();
}
-
- if (k == 0 && !is_store)
- return_type = eltype;
- else
- args = tree_cons (NULL_TREE, eltype, args);
}
- ftype = build_function_type (return_type, args);
+ if (k == 0 && !is_store)
+ return_type = eltype;
+ else
+ args = tree_cons (NULL_TREE, eltype, args);
}
- break;
+ ftype = build_function_type (return_type, args);
+ }
+ break;
- case AARCH64_SIMD_RESULTPAIR:
+ case AARCH64_SIMD_RESULTPAIR:
+ {
+ switch (insn_data[d->code].operand[1].mode)
{
- switch (insn_data[icode].operand[1].mode)
- {
- case V8QImode:
- ftype = void_ftype_pv8qi_v8qi_v8qi;
- break;
- case V4HImode:
- ftype = void_ftype_pv4hi_v4hi_v4hi;
- break;
- case V2SImode:
- ftype = void_ftype_pv2si_v2si_v2si;
- break;
- case V2SFmode:
- ftype = void_ftype_pv2sf_v2sf_v2sf;
- break;
- case DImode:
- ftype = void_ftype_pdi_di_di;
- break;
- case V16QImode:
- ftype = void_ftype_pv16qi_v16qi_v16qi;
- break;
- case V8HImode:
- ftype = void_ftype_pv8hi_v8hi_v8hi;
- break;
- case V4SImode:
- ftype = void_ftype_pv4si_v4si_v4si;
- break;
- case V4SFmode:
- ftype = void_ftype_pv4sf_v4sf_v4sf;
- break;
- case V2DImode:
- ftype = void_ftype_pv2di_v2di_v2di;
- break;
- case V2DFmode:
- ftype = void_ftype_pv2df_v2df_v2df;
- break;
- default:
- gcc_unreachable ();
- }
+ case V8QImode:
+ ftype = void_ftype_pv8qi_v8qi_v8qi;
+ break;
+ case V4HImode:
+ ftype = void_ftype_pv4hi_v4hi_v4hi;
+ break;
+ case V2SImode:
+ ftype = void_ftype_pv2si_v2si_v2si;
+ break;
+ case V2SFmode:
+ ftype = void_ftype_pv2sf_v2sf_v2sf;
+ break;
+ case DImode:
+ ftype = void_ftype_pdi_di_di;
+ break;
+ case V16QImode:
+ ftype = void_ftype_pv16qi_v16qi_v16qi;
+ break;
+ case V8HImode:
+ ftype = void_ftype_pv8hi_v8hi_v8hi;
+ break;
+ case V4SImode:
+ ftype = void_ftype_pv4si_v4si_v4si;
+ break;
+ case V4SFmode:
+ ftype = void_ftype_pv4sf_v4sf_v4sf;
+ break;
+ case V2DImode:
+ ftype = void_ftype_pv2di_v2di_v2di;
+ break;
+ case V2DFmode:
+ ftype = void_ftype_pv2df_v2df_v2df;
+ break;
+ default:
+ gcc_unreachable ();
}
- break;
-
- case AARCH64_SIMD_REINTERP:
+ }
+ break;
+
+ case AARCH64_SIMD_REINTERP:
+ {
+ /* We iterate over 6 doubleword types, then 6 quadword
+ types. */
+ int rhs_d = d->mode % NUM_DREG_TYPES;
+ int rhs_q = (d->mode - NUM_DREG_TYPES) % NUM_QREG_TYPES;
+ switch (insn_data[d->code].operand[0].mode)
{
- /* We iterate over 6 doubleword types, then 6 quadword
- types. */
- int rhs_d = j % NUM_DREG_TYPES;
- int rhs_q = (j - NUM_DREG_TYPES) % NUM_QREG_TYPES;
- switch (insn_data[icode].operand[0].mode)
- {
- case V8QImode:
- ftype = reinterp_ftype_dreg[0][rhs_d];
- break;
- case V4HImode:
- ftype = reinterp_ftype_dreg[1][rhs_d];
- break;
- case V2SImode:
- ftype = reinterp_ftype_dreg[2][rhs_d];
- break;
- case V2SFmode:
- ftype = reinterp_ftype_dreg[3][rhs_d];
- break;
- case DImode:
- ftype = reinterp_ftype_dreg[4][rhs_d];
- break;
- case DFmode:
- ftype = reinterp_ftype_dreg[5][rhs_d];
- break;
- case V16QImode:
- ftype = reinterp_ftype_qreg[0][rhs_q];
- break;
- case V8HImode:
- ftype = reinterp_ftype_qreg[1][rhs_q];
- break;
- case V4SImode:
- ftype = reinterp_ftype_qreg[2][rhs_q];
- break;
- case V4SFmode:
- ftype = reinterp_ftype_qreg[3][rhs_q];
- break;
- case V2DImode:
- ftype = reinterp_ftype_qreg[4][rhs_q];
- break;
- case V2DFmode:
- ftype = reinterp_ftype_qreg[5][rhs_q];
- break;
- default:
- gcc_unreachable ();
- }
+ case V8QImode:
+ ftype = reinterp_ftype_dreg[0][rhs_d];
+ break;
+ case V4HImode:
+ ftype = reinterp_ftype_dreg[1][rhs_d];
+ break;
+ case V2SImode:
+ ftype = reinterp_ftype_dreg[2][rhs_d];
+ break;
+ case V2SFmode:
+ ftype = reinterp_ftype_dreg[3][rhs_d];
+ break;
+ case DImode:
+ ftype = reinterp_ftype_dreg[4][rhs_d];
+ break;
+ case DFmode:
+ ftype = reinterp_ftype_dreg[5][rhs_d];
+ break;
+ case V16QImode:
+ ftype = reinterp_ftype_qreg[0][rhs_q];
+ break;
+ case V8HImode:
+ ftype = reinterp_ftype_qreg[1][rhs_q];
+ break;
+ case V4SImode:
+ ftype = reinterp_ftype_qreg[2][rhs_q];
+ break;
+ case V4SFmode:
+ ftype = reinterp_ftype_qreg[3][rhs_q];
+ break;
+ case V2DImode:
+ ftype = reinterp_ftype_qreg[4][rhs_q];
+ break;
+ case V2DFmode:
+ ftype = reinterp_ftype_qreg[5][rhs_q];
+ break;
+ default:
+ gcc_unreachable ();
}
- break;
+ }
+ break;
- default:
- gcc_unreachable ();
- }
-
- gcc_assert (ftype != NULL);
+ default:
+ gcc_unreachable ();
+ }
+ gcc_assert (ftype != NULL);
- snprintf (namebuf, sizeof (namebuf), "__builtin_aarch64_%s%s",
- d->name, modenames[j]);
+ snprintf (namebuf, sizeof (namebuf), "__builtin_aarch64_%s%s",
+ d->name, modenames[d->mode]);
- add_builtin_function (namebuf, ftype, fcode++, BUILT_IN_MD, NULL,
- NULL_TREE);
- }
+ fndecl = add_builtin_function (namebuf, ftype, fcode, BUILT_IN_MD,
+ NULL, NULL_TREE);
+ aarch64_builtin_decls[fcode] = fndecl;
}
}
-static int
-aarch64_simd_builtin_compare (const void *a, const void *b)
+void
+aarch64_init_builtins (void)
{
- const aarch64_simd_builtin_datum *const key =
- (const aarch64_simd_builtin_datum *) a;
- const aarch64_simd_builtin_datum *const memb =
- (const aarch64_simd_builtin_datum *) b;
- unsigned int soughtcode = key->base_fcode;
-
- if (soughtcode >= memb->base_fcode
- && soughtcode < memb->base_fcode + memb->num_vars)
- return 0;
- else if (soughtcode < memb->base_fcode)
- return -1;
- else
- return 1;
+ tree ftype, decl = NULL;
+
+ ftype = build_function_type (ptr_type_node, void_list_node);
+ decl = add_builtin_function ("__builtin_thread_pointer", ftype,
+ AARCH64_BUILTIN_THREAD_POINTER, BUILT_IN_MD,
+ NULL, NULL_TREE);
+ TREE_NOTHROW (decl) = 1;
+ TREE_READONLY (decl) = 1;
+ aarch64_builtin_decls[AARCH64_BUILTIN_THREAD_POINTER] = decl;
+
+ if (TARGET_SIMD)
+ aarch64_init_simd_builtins ();
}
-
-static enum insn_code
-locate_simd_builtin_icode (int fcode, aarch64_simd_itype * itype)
+tree
+aarch64_builtin_decl (unsigned code, bool initialize_p ATTRIBUTE_UNUSED)
{
- aarch64_simd_builtin_datum key
- = { NULL, (aarch64_simd_itype) 0, 0, {CODE_FOR_nothing}, 0, 0};
- aarch64_simd_builtin_datum *found;
- int idx;
-
- key.base_fcode = fcode;
- found = (aarch64_simd_builtin_datum *)
- bsearch (&key, &aarch64_simd_builtin_data[0],
- ARRAY_SIZE (aarch64_simd_builtin_data),
- sizeof (aarch64_simd_builtin_data[0]),
- aarch64_simd_builtin_compare);
- gcc_assert (found);
- idx = fcode - (int) found->base_fcode;
- gcc_assert (idx >= 0 && idx < T_MAX && idx < (int) found->num_vars);
-
- if (itype)
- *itype = found->itype;
-
- return found->codes[idx];
+ if (code >= AARCH64_BUILTIN_MAX)
+ return error_mark_node;
+
+ return aarch64_builtin_decls[code];
}
typedef enum
@@ -1225,8 +1119,10 @@ aarch64_simd_expand_args (rtx target, int icode, int have_retval,
rtx
aarch64_simd_expand_builtin (int fcode, tree exp, rtx target)
{
- aarch64_simd_itype itype;
- enum insn_code icode = locate_simd_builtin_icode (fcode, &itype);
+ aarch64_simd_builtin_datum *d =
+ &aarch64_simd_builtin_data[fcode - (AARCH64_SIMD_BUILTIN_BASE + 1)];
+ aarch64_simd_itype itype = d->itype;
+ enum insn_code icode = d->code;
switch (itype)
{
@@ -1318,3 +1214,24 @@ aarch64_simd_expand_builtin (int fcode, tree exp, rtx target)
gcc_unreachable ();
}
}
+
+/* Expand an expression EXP that calls a built-in function,
+ with result going to TARGET if that's convenient. */
+rtx
+aarch64_expand_builtin (tree exp,
+ rtx target,
+ rtx subtarget ATTRIBUTE_UNUSED,
+ enum machine_mode mode ATTRIBUTE_UNUSED,
+ int ignore ATTRIBUTE_UNUSED)
+{
+ tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
+ int fcode = DECL_FUNCTION_CODE (fndecl);
+
+ if (fcode == AARCH64_BUILTIN_THREAD_POINTER)
+ return aarch64_load_tp (target);
+
+ if (fcode >= AARCH64_SIMD_BUILTIN_BASE)
+ return aarch64_simd_expand_builtin (fcode, exp, target);
+
+ return NULL_RTX;
+}
diff --git a/gcc/config/aarch64/aarch64-protos.h b/gcc/config/aarch64/aarch64-protos.h
index 11e35103657..31d978b4c86 100644
--- a/gcc/config/aarch64/aarch64-protos.h
+++ b/gcc/config/aarch64/aarch64-protos.h
@@ -227,4 +227,13 @@ void aarch64_split_atomic_op (enum rtx_code, rtx, rtx, rtx, rtx, rtx, rtx);
#endif /* RTX_CODE */
+rtx aarch64_load_tp (rtx target);
+void aarch64_init_builtins (void);
+rtx aarch64_expand_builtin (tree exp,
+ rtx target,
+ rtx subtarget ATTRIBUTE_UNUSED,
+ enum machine_mode mode ATTRIBUTE_UNUSED,
+ int ignore ATTRIBUTE_UNUSED);
+tree aarch64_builtin_decl (unsigned, bool ATTRIBUTE_UNUSED);
+
#endif /* GCC_AARCH64_PROTOS_H */
diff --git a/gcc/config/aarch64/aarch64-simd-builtins.def b/gcc/config/aarch64/aarch64-simd-builtins.def
new file mode 100644
index 00000000000..2e3c4e1ca5f
--- /dev/null
+++ b/gcc/config/aarch64/aarch64-simd-builtins.def
@@ -0,0 +1,208 @@
+
+/* In the list below, the BUILTIN_<ITERATOR> macros should
+ correspond to the iterator used to construct the instruction's
+ patterns in aarch64-simd.md. A helpful idiom to follow when
+ adding new builtins is to add a line for each pattern in the md
+ file. Thus, ADDP, which has one pattern defined for the VD_BHSI
+ iterator, and one for DImode, has two entries below. */
+
+ BUILTIN_VD_RE (CREATE, create)
+ BUILTIN_VQ_S (GETLANE, get_lane_signed)
+ BUILTIN_VDQ (GETLANE, get_lane_unsigned)
+ BUILTIN_VDQF (GETLANE, get_lane)
+ VAR1 (GETLANE, get_lane, di)
+ BUILTIN_VDC (COMBINE, combine)
+ BUILTIN_VB (BINOP, pmul)
+ BUILTIN_VDQF (UNOP, sqrt)
+ BUILTIN_VD_BHSI (BINOP, addp)
+ VAR1 (UNOP, addp, di)
+
+ BUILTIN_VD_RE (REINTERP, reinterpretdi)
+ BUILTIN_VDC (REINTERP, reinterpretv8qi)
+ BUILTIN_VDC (REINTERP, reinterpretv4hi)
+ BUILTIN_VDC (REINTERP, reinterpretv2si)
+ BUILTIN_VDC (REINTERP, reinterpretv2sf)
+ BUILTIN_VQ (REINTERP, reinterpretv16qi)
+ BUILTIN_VQ (REINTERP, reinterpretv8hi)
+ BUILTIN_VQ (REINTERP, reinterpretv4si)
+ BUILTIN_VQ (REINTERP, reinterpretv4sf)
+ BUILTIN_VQ (REINTERP, reinterpretv2di)
+ BUILTIN_VQ (REINTERP, reinterpretv2df)
+
+ BUILTIN_VDQ_I (BINOP, dup_lane)
+ BUILTIN_SDQ_I (BINOP, dup_lane)
+ /* Implemented by aarch64_<sur>q<r>shl<mode>. */
+ BUILTIN_VSDQ_I (BINOP, sqshl)
+ BUILTIN_VSDQ_I (BINOP, uqshl)
+ BUILTIN_VSDQ_I (BINOP, sqrshl)
+ BUILTIN_VSDQ_I (BINOP, uqrshl)
+ /* Implemented by aarch64_<su_optab><optab><mode>. */
+ BUILTIN_VSDQ_I (BINOP, sqadd)
+ BUILTIN_VSDQ_I (BINOP, uqadd)
+ BUILTIN_VSDQ_I (BINOP, sqsub)
+ BUILTIN_VSDQ_I (BINOP, uqsub)
+ /* Implemented by aarch64_<sur>qadd<mode>. */
+ BUILTIN_VSDQ_I (BINOP, suqadd)
+ BUILTIN_VSDQ_I (BINOP, usqadd)
+
+ /* Implemented by aarch64_get_dreg<VSTRUCT:mode><VDC:mode>. */
+ BUILTIN_VDC (GETLANE, get_dregoi)
+ BUILTIN_VDC (GETLANE, get_dregci)
+ BUILTIN_VDC (GETLANE, get_dregxi)
+ /* Implemented by aarch64_get_qreg<VSTRUCT:mode><VQ:mode>. */
+ BUILTIN_VQ (GETLANE, get_qregoi)
+ BUILTIN_VQ (GETLANE, get_qregci)
+ BUILTIN_VQ (GETLANE, get_qregxi)
+ /* Implemented by aarch64_set_qreg<VSTRUCT:mode><VQ:mode>. */
+ BUILTIN_VQ (SETLANE, set_qregoi)
+ BUILTIN_VQ (SETLANE, set_qregci)
+ BUILTIN_VQ (SETLANE, set_qregxi)
+ /* Implemented by aarch64_ld<VSTRUCT:nregs><VDC:mode>. */
+ BUILTIN_VDC (LOADSTRUCT, ld2)
+ BUILTIN_VDC (LOADSTRUCT, ld3)
+ BUILTIN_VDC (LOADSTRUCT, ld4)
+ /* Implemented by aarch64_ld<VSTRUCT:nregs><VQ:mode>. */
+ BUILTIN_VQ (LOADSTRUCT, ld2)
+ BUILTIN_VQ (LOADSTRUCT, ld3)
+ BUILTIN_VQ (LOADSTRUCT, ld4)
+ /* Implemented by aarch64_st<VSTRUCT:nregs><VDC:mode>. */
+ BUILTIN_VDC (STORESTRUCT, st2)
+ BUILTIN_VDC (STORESTRUCT, st3)
+ BUILTIN_VDC (STORESTRUCT, st4)
+ /* Implemented by aarch64_st<VSTRUCT:nregs><VQ:mode>. */
+ BUILTIN_VQ (STORESTRUCT, st2)
+ BUILTIN_VQ (STORESTRUCT, st3)
+ BUILTIN_VQ (STORESTRUCT, st4)
+
+ BUILTIN_VQW (BINOP, saddl2)
+ BUILTIN_VQW (BINOP, uaddl2)
+ BUILTIN_VQW (BINOP, ssubl2)
+ BUILTIN_VQW (BINOP, usubl2)
+ BUILTIN_VQW (BINOP, saddw2)
+ BUILTIN_VQW (BINOP, uaddw2)
+ BUILTIN_VQW (BINOP, ssubw2)
+ BUILTIN_VQW (BINOP, usubw2)
+ /* Implemented by aarch64_<ANY_EXTEND:su><ADDSUB:optab>l<mode>. */
+ BUILTIN_VDW (BINOP, saddl)
+ BUILTIN_VDW (BINOP, uaddl)
+ BUILTIN_VDW (BINOP, ssubl)
+ BUILTIN_VDW (BINOP, usubl)
+ /* Implemented by aarch64_<ANY_EXTEND:su><ADDSUB:optab>w<mode>. */
+ BUILTIN_VDW (BINOP, saddw)
+ BUILTIN_VDW (BINOP, uaddw)
+ BUILTIN_VDW (BINOP, ssubw)
+ BUILTIN_VDW (BINOP, usubw)
+ /* Implemented by aarch64_<sur>h<addsub><mode>. */
+ BUILTIN_VQ_S (BINOP, shadd)
+ BUILTIN_VQ_S (BINOP, uhadd)
+ BUILTIN_VQ_S (BINOP, srhadd)
+ BUILTIN_VQ_S (BINOP, urhadd)
+ /* Implemented by aarch64_<sur><addsub>hn<mode>. */
+ BUILTIN_VQN (BINOP, addhn)
+ BUILTIN_VQN (BINOP, raddhn)
+ /* Implemented by aarch64_<sur><addsub>hn2<mode>. */
+ BUILTIN_VQN (TERNOP, addhn2)
+ BUILTIN_VQN (TERNOP, raddhn2)
+
+ BUILTIN_VSQN_HSDI (UNOP, sqmovun)
+ /* Implemented by aarch64_<sur>qmovn<mode>. */
+ BUILTIN_VSQN_HSDI (UNOP, sqmovn)
+ BUILTIN_VSQN_HSDI (UNOP, uqmovn)
+ /* Implemented by aarch64_s<optab><mode>. */
+ BUILTIN_VSDQ_I_BHSI (UNOP, sqabs)
+ BUILTIN_VSDQ_I_BHSI (UNOP, sqneg)
+
+ BUILTIN_VSD_HSI (QUADOP, sqdmlal_lane)
+ BUILTIN_VSD_HSI (QUADOP, sqdmlsl_lane)
+ BUILTIN_VSD_HSI (QUADOP, sqdmlal_laneq)
+ BUILTIN_VSD_HSI (QUADOP, sqdmlsl_laneq)
+ BUILTIN_VQ_HSI (TERNOP, sqdmlal2)
+ BUILTIN_VQ_HSI (TERNOP, sqdmlsl2)
+ BUILTIN_VQ_HSI (QUADOP, sqdmlal2_lane)
+ BUILTIN_VQ_HSI (QUADOP, sqdmlsl2_lane)
+ BUILTIN_VQ_HSI (QUADOP, sqdmlal2_laneq)
+ BUILTIN_VQ_HSI (QUADOP, sqdmlsl2_laneq)
+ BUILTIN_VQ_HSI (TERNOP, sqdmlal2_n)
+ BUILTIN_VQ_HSI (TERNOP, sqdmlsl2_n)
+ /* Implemented by aarch64_sqdml<SBINQOPS:as>l<mode>. */
+ BUILTIN_VSD_HSI (TERNOP, sqdmlal)
+ BUILTIN_VSD_HSI (TERNOP, sqdmlsl)
+ /* Implemented by aarch64_sqdml<SBINQOPS:as>l_n<mode>. */
+ BUILTIN_VD_HSI (TERNOP, sqdmlal_n)
+ BUILTIN_VD_HSI (TERNOP, sqdmlsl_n)
+
+ BUILTIN_VSD_HSI (BINOP, sqdmull)
+ BUILTIN_VSD_HSI (TERNOP, sqdmull_lane)
+ BUILTIN_VD_HSI (TERNOP, sqdmull_laneq)
+ BUILTIN_VD_HSI (BINOP, sqdmull_n)
+ BUILTIN_VQ_HSI (BINOP, sqdmull2)
+ BUILTIN_VQ_HSI (TERNOP, sqdmull2_lane)
+ BUILTIN_VQ_HSI (TERNOP, sqdmull2_laneq)
+ BUILTIN_VQ_HSI (BINOP, sqdmull2_n)
+ /* Implemented by aarch64_sq<r>dmulh<mode>. */
+ BUILTIN_VSDQ_HSI (BINOP, sqdmulh)
+ BUILTIN_VSDQ_HSI (BINOP, sqrdmulh)
+ /* Implemented by aarch64_sq<r>dmulh_lane<mode>. */
+ BUILTIN_VSDQ_HSI (TERNOP, sqdmulh_lane)
+ BUILTIN_VSDQ_HSI (TERNOP, sqrdmulh_lane)
+
+ BUILTIN_VSDQ_I_DI (BINOP, sshl_n)
+ BUILTIN_VSDQ_I_DI (BINOP, ushl_n)
+ /* Implemented by aarch64_<sur>shl<mode>. */
+ BUILTIN_VSDQ_I_DI (BINOP, sshl)
+ BUILTIN_VSDQ_I_DI (BINOP, ushl)
+ BUILTIN_VSDQ_I_DI (BINOP, srshl)
+ BUILTIN_VSDQ_I_DI (BINOP, urshl)
+
+ BUILTIN_VSDQ_I_DI (SHIFTIMM, sshr_n)
+ BUILTIN_VSDQ_I_DI (SHIFTIMM, ushr_n)
+ /* Implemented by aarch64_<sur>shr_n<mode>. */
+ BUILTIN_VSDQ_I_DI (SHIFTIMM, srshr_n)
+ BUILTIN_VSDQ_I_DI (SHIFTIMM, urshr_n)
+ /* Implemented by aarch64_<sur>sra_n<mode>. */
+ BUILTIN_VSDQ_I_DI (SHIFTACC, ssra_n)
+ BUILTIN_VSDQ_I_DI (SHIFTACC, usra_n)
+ BUILTIN_VSDQ_I_DI (SHIFTACC, srsra_n)
+ BUILTIN_VSDQ_I_DI (SHIFTACC, ursra_n)
+ /* Implemented by aarch64_<sur>shll_n<mode>. */
+ BUILTIN_VDW (SHIFTIMM, sshll_n)
+ BUILTIN_VDW (SHIFTIMM, ushll_n)
+ /* Implemented by aarch64_<sur>shll2_n<mode>. */
+ BUILTIN_VQW (SHIFTIMM, sshll2_n)
+ BUILTIN_VQW (SHIFTIMM, ushll2_n)
+ /* Implemented by aarch64_<sur>q<r>shr<u>n_n<mode>. */
+ BUILTIN_VSQN_HSDI (SHIFTIMM, sqshrun_n)
+ BUILTIN_VSQN_HSDI (SHIFTIMM, sqrshrun_n)
+ BUILTIN_VSQN_HSDI (SHIFTIMM, sqshrn_n)
+ BUILTIN_VSQN_HSDI (SHIFTIMM, uqshrn_n)
+ BUILTIN_VSQN_HSDI (SHIFTIMM, sqrshrn_n)
+ BUILTIN_VSQN_HSDI (SHIFTIMM, uqrshrn_n)
+ /* Implemented by aarch64_<sur>s<lr>i_n<mode>. */
+ BUILTIN_VSDQ_I_DI (SHIFTINSERT, ssri_n)
+ BUILTIN_VSDQ_I_DI (SHIFTINSERT, usri_n)
+ BUILTIN_VSDQ_I_DI (SHIFTINSERT, ssli_n)
+ BUILTIN_VSDQ_I_DI (SHIFTINSERT, usli_n)
+ /* Implemented by aarch64_<sur>qshl<u>_n<mode>. */
+ BUILTIN_VSDQ_I (SHIFTIMM, sqshlu_n)
+ BUILTIN_VSDQ_I (SHIFTIMM, sqshl_n)
+ BUILTIN_VSDQ_I (SHIFTIMM, uqshl_n)
+
+ /* Implemented by aarch64_cm<cmp><mode>. */
+ BUILTIN_VSDQ_I_DI (BINOP, cmeq)
+ BUILTIN_VSDQ_I_DI (BINOP, cmge)
+ BUILTIN_VSDQ_I_DI (BINOP, cmgt)
+ BUILTIN_VSDQ_I_DI (BINOP, cmle)
+ BUILTIN_VSDQ_I_DI (BINOP, cmlt)
+ /* Implemented by aarch64_cm<cmp><mode>. */
+ BUILTIN_VSDQ_I_DI (BINOP, cmhs)
+ BUILTIN_VSDQ_I_DI (BINOP, cmhi)
+ BUILTIN_VSDQ_I_DI (BINOP, cmtst)
+
+ /* Implemented by aarch64_<fmaxmin><mode>. */
+ BUILTIN_VDQF (BINOP, fmax)
+ BUILTIN_VDQF (BINOP, fmin)
+ /* Implemented by aarch64_<maxmin><mode>. */
+ BUILTIN_VDQ_BHSI (BINOP, smax)
+ BUILTIN_VDQ_BHSI (BINOP, smin)
+ BUILTIN_VDQ_BHSI (BINOP, umax)
+ BUILTIN_VDQ_BHSI (BINOP, umin)
diff --git a/gcc/config/aarch64/aarch64-simd.md b/gcc/config/aarch64/aarch64-simd.md
index a7ddfb1c1d3..b3d01c19199 100644
--- a/gcc/config/aarch64/aarch64-simd.md
+++ b/gcc/config/aarch64/aarch64-simd.md
@@ -1467,6 +1467,150 @@
(set_attr "simd_mode" "V2SI")]
)
+;; vbsl_* intrinsics may compile to any of vbsl/vbif/vbit depending on register
+;; allocation. For an intrinsic of form:
+;; vD = bsl_* (vS, vN, vM)
+;; We can use any of:
+;; bsl vS, vN, vM (if D = S)
+;; bit vD, vN, vS (if D = M, so 1-bits in vS choose bits from vN, else vM)
+;; bif vD, vM, vS (if D = N, so 0-bits in vS choose bits from vM, else vN)
+
+(define_insn "aarch64_simd_bsl<mode>_internal"
+ [(set (match_operand:VDQ 0 "register_operand" "=w,w,w")
+ (unspec:VDQ [(match_operand:VDQ 1 "register_operand" " 0,w,w")
+ (match_operand:VDQ 2 "register_operand" " w,w,0")
+ (match_operand:VDQ 3 "register_operand" " w,0,w")]
+ UNSPEC_BSL))]
+ "TARGET_SIMD"
+ "@
+ bsl\\t%0.<Vbtype>, %2.<Vbtype>, %3.<Vbtype>
+ bit\\t%0.<Vbtype>, %2.<Vbtype>, %1.<Vbtype>
+ bif\\t%0.<Vbtype>, %3.<Vbtype>, %1.<Vbtype>"
+)
+
+(define_expand "aarch64_simd_bsl<mode>"
+ [(set (match_operand:VDQ 0 "register_operand")
+ (unspec:VDQ [(match_operand:<V_cmp_result> 1 "register_operand")
+ (match_operand:VDQ 2 "register_operand")
+ (match_operand:VDQ 3 "register_operand")]
+ UNSPEC_BSL))]
+ "TARGET_SIMD"
+{
+ /* We can't alias operands together if they have different modes. */
+ operands[1] = gen_lowpart (<MODE>mode, operands[1]);
+})
+
+(define_expand "aarch64_vcond_internal<mode>"
+ [(set (match_operand:VDQ 0 "register_operand")
+ (if_then_else:VDQ
+ (match_operator 3 "comparison_operator"
+ [(match_operand:VDQ 4 "register_operand")
+ (match_operand:VDQ 5 "nonmemory_operand")])
+ (match_operand:VDQ 1 "register_operand")
+ (match_operand:VDQ 2 "register_operand")))]
+ "TARGET_SIMD"
+{
+ int inverse = 0, has_zero_imm_form = 0;
+ rtx mask = gen_reg_rtx (<MODE>mode);
+
+ switch (GET_CODE (operands[3]))
+ {
+ case LE:
+ case LT:
+ case NE:
+ inverse = 1;
+ /* Fall through. */
+ case GE:
+ case GT:
+ case EQ:
+ has_zero_imm_form = 1;
+ break;
+ case LEU:
+ case LTU:
+ inverse = 1;
+ break;
+ default:
+ break;
+ }
+
+ if (!REG_P (operands[5])
+ && (operands[5] != CONST0_RTX (<MODE>mode) || !has_zero_imm_form))
+ operands[5] = force_reg (<MODE>mode, operands[5]);
+
+ switch (GET_CODE (operands[3]))
+ {
+ case LT:
+ case GE:
+ emit_insn (gen_aarch64_cmge<mode> (mask, operands[4], operands[5]));
+ break;
+
+ case LE:
+ case GT:
+ emit_insn (gen_aarch64_cmgt<mode> (mask, operands[4], operands[5]));
+ break;
+
+ case LTU:
+ case GEU:
+ emit_insn (gen_aarch64_cmhs<mode> (mask, operands[4], operands[5]));
+ break;
+
+ case LEU:
+ case GTU:
+ emit_insn (gen_aarch64_cmhi<mode> (mask, operands[4], operands[5]));
+ break;
+
+ case NE:
+ case EQ:
+ emit_insn (gen_aarch64_cmeq<mode> (mask, operands[4], operands[5]));
+ break;
+
+ default:
+ gcc_unreachable ();
+ }
+
+ if (inverse)
+ emit_insn (gen_aarch64_simd_bsl<mode> (operands[0], mask, operands[2],
+ operands[1]));
+ else
+ emit_insn (gen_aarch64_simd_bsl<mode> (operands[0], mask, operands[1],
+ operands[2]));
+
+ DONE;
+})
+
+(define_expand "vcond<mode><mode>"
+ [(set (match_operand:VDQ 0 "register_operand")
+ (if_then_else:VDQ
+ (match_operator 3 "comparison_operator"
+ [(match_operand:VDQ 4 "register_operand")
+ (match_operand:VDQ 5 "nonmemory_operand")])
+ (match_operand:VDQ 1 "register_operand")
+ (match_operand:VDQ 2 "register_operand")))]
+ "TARGET_SIMD"
+{
+ emit_insn (gen_aarch64_vcond_internal<mode> (operands[0], operands[1],
+ operands[2], operands[3],
+ operands[4], operands[5]));
+ DONE;
+})
+
+
+(define_expand "vcondu<mode><mode>"
+ [(set (match_operand:VDQ 0 "register_operand")
+ (if_then_else:VDQ
+ (match_operator 3 "comparison_operator"
+ [(match_operand:VDQ 4 "register_operand")
+ (match_operand:VDQ 5 "nonmemory_operand")])
+ (match_operand:VDQ 1 "register_operand")
+ (match_operand:VDQ 2 "register_operand")))]
+ "TARGET_SIMD"
+{
+ emit_insn (gen_aarch64_vcond_internal<mode> (operands[0], operands[1],
+ operands[2], operands[3],
+ operands[4], operands[5]));
+ DONE;
+})
+
;; Patterns for AArch64 SIMD Intrinsics.
(define_expand "aarch64_create<mode>"
diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index 212bf116802..35f4b9267c8 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -102,7 +102,6 @@ static bool aarch64_vfp_is_call_or_return_candidate (enum machine_mode,
bool *);
static void aarch64_elf_asm_constructor (rtx, int) ATTRIBUTE_UNUSED;
static void aarch64_elf_asm_destructor (rtx, int) ATTRIBUTE_UNUSED;
-static rtx aarch64_load_tp (rtx);
static void aarch64_override_options_after_change (void);
static int aarch64_simd_valid_immediate (rtx, enum machine_mode, int, rtx *,
int *, unsigned char *, int *, int *);
@@ -2167,12 +2166,10 @@ aarch64_final_eh_return_addr (void)
/* Output code to build up a constant in a register. */
static void
-aarch64_build_constant (FILE *file,
- int regnum,
- HOST_WIDE_INT val)
+aarch64_build_constant (int regnum, HOST_WIDE_INT val)
{
if (aarch64_bitmask_imm (val, DImode))
- asm_fprintf (file, "\tmovi\t%r, %wd\n", regnum, val);
+ emit_move_insn (gen_rtx_REG (Pmode, regnum), GEN_INT (val));
else
{
int i;
@@ -2203,12 +2200,14 @@ aarch64_build_constant (FILE *file,
the same. */
if (ncount < zcount)
{
- asm_fprintf (file, "\tmovn\t%r, %wd\n", regnum, (~val) & 0xffff);
+ emit_move_insn (gen_rtx_REG (Pmode, regnum),
+ GEN_INT ((~val) & 0xffff));
tval = 0xffff;
}
else
{
- asm_fprintf (file, "\tmovz\t%r, %wd\n", regnum, val & 0xffff);
+ emit_move_insn (gen_rtx_REG (Pmode, regnum),
+ GEN_INT (val & 0xffff));
tval = 0;
}
@@ -2217,39 +2216,47 @@ aarch64_build_constant (FILE *file,
for (i = 16; i < 64; i += 16)
{
if ((val & 0xffff) != tval)
- asm_fprintf (file, "\tmovk\t%r, %wd, lsl %d\n",
- regnum, val & 0xffff, i);
+ emit_insn (gen_insv_immdi (gen_rtx_REG (Pmode, regnum),
+ GEN_INT (i), GEN_INT (val & 0xffff)));
val >>= 16;
}
}
}
static void
-aarch64_add_constant (FILE *file, int regnum, int scratchreg,
- HOST_WIDE_INT delta)
+aarch64_add_constant (int regnum, int scratchreg, HOST_WIDE_INT delta)
{
HOST_WIDE_INT mdelta = delta;
+ rtx this_rtx = gen_rtx_REG (Pmode, regnum);
+ rtx scratch_rtx = gen_rtx_REG (Pmode, scratchreg);
if (mdelta < 0)
mdelta = -mdelta;
if (mdelta >= 4096 * 4096)
{
- aarch64_build_constant (file, scratchreg, delta);
- asm_fprintf (file, "\tadd\t%r, %r, %r\n", regnum, regnum,
- scratchreg);
+ aarch64_build_constant (scratchreg, delta);
+ emit_insn (gen_add3_insn (this_rtx, this_rtx, scratch_rtx));
}
else if (mdelta > 0)
{
- const char *const mi_op = delta < 0 ? "sub" : "add";
-
if (mdelta >= 4096)
- asm_fprintf (file, "\t%s\t%r, %r, %wd, lsl 12\n", mi_op, regnum, regnum,
- mdelta / 4096);
-
+ {
+ emit_insn (gen_rtx_SET (Pmode, scratch_rtx, GEN_INT (mdelta / 4096)));
+ rtx shift = gen_rtx_ASHIFT (Pmode, scratch_rtx, GEN_INT (12));
+ if (delta < 0)
+ emit_insn (gen_rtx_SET (Pmode, this_rtx,
+ gen_rtx_MINUS (Pmode, this_rtx, shift)));
+ else
+ emit_insn (gen_rtx_SET (Pmode, this_rtx,
+ gen_rtx_PLUS (Pmode, this_rtx, shift)));
+ }
if (mdelta % 4096 != 0)
- asm_fprintf (file, "\t%s\t%r, %r, %wd\n", mi_op, regnum, regnum,
- mdelta % 4096);
+ {
+ scratch_rtx = GEN_INT ((delta < 0 ? -1 : 1) * (mdelta % 4096));
+ emit_insn (gen_rtx_SET (Pmode, this_rtx,
+ gen_rtx_PLUS (Pmode, this_rtx, scratch_rtx)));
+ }
}
}
@@ -2272,7 +2279,7 @@ aarch64_output_mi_thunk (FILE *file, tree thunk ATTRIBUTE_UNUSED,
emit_note (NOTE_INSN_PROLOGUE_END);
if (vcall_offset == 0)
- aarch64_add_constant (file, this_regno, IP1_REGNUM, delta);
+ aarch64_add_constant (this_regno, IP1_REGNUM, delta);
else
{
gcc_assert ((vcall_offset & 0x7) == 0);
@@ -2288,7 +2295,7 @@ aarch64_output_mi_thunk (FILE *file, tree thunk ATTRIBUTE_UNUSED,
addr = gen_rtx_PRE_MODIFY (Pmode, this_rtx,
plus_constant (this_rtx, delta));
else
- aarch64_add_constant (file, this_regno, IP1_REGNUM, delta);
+ aarch64_add_constant (this_regno, IP1_REGNUM, delta);
}
aarch64_emit_move (temp0, gen_rtx_MEM (Pmode, addr));
@@ -2297,7 +2304,7 @@ aarch64_output_mi_thunk (FILE *file, tree thunk ATTRIBUTE_UNUSED,
addr = plus_constant (temp0, vcall_offset);
else
{
- aarch64_build_constant (file, IP1_REGNUM, vcall_offset);
+ aarch64_build_constant (IP1_REGNUM, vcall_offset);
addr = gen_rtx_PLUS (Pmode, temp0, temp1);
}
@@ -5003,23 +5010,7 @@ aarch64_legitimate_constant_p (enum machine_mode mode, rtx x)
return aarch64_constant_address_p (x);
}
-static void
-aarch64_init_builtins (void)
-{
- tree ftype, decl = NULL;
-
- ftype = build_function_type (ptr_type_node, void_list_node);
- decl = add_builtin_function ("__builtin_thread_pointer", ftype,
- AARCH64_BUILTIN_THREAD_POINTER, BUILT_IN_MD,
- NULL, NULL_TREE);
- TREE_NOTHROW (decl) = 1;
- TREE_READONLY (decl) = 1;
-
- if (TARGET_SIMD)
- init_aarch64_simd_builtins ();
-}
-
-static rtx
+rtx
aarch64_load_tp (rtx target)
{
if (!target
@@ -5032,27 +5023,6 @@ aarch64_load_tp (rtx target)
return target;
}
-/* Expand an expression EXP that calls a built-in function,
- with result going to TARGET if that's convenient. */
-static rtx
-aarch64_expand_builtin (tree exp,
- rtx target,
- rtx subtarget ATTRIBUTE_UNUSED,
- enum machine_mode mode ATTRIBUTE_UNUSED,
- int ignore ATTRIBUTE_UNUSED)
-{
- tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
- int fcode = DECL_FUNCTION_CODE (fndecl);
-
- if (fcode == AARCH64_BUILTIN_THREAD_POINTER)
- return aarch64_load_tp (target);
-
- if (fcode >= AARCH64_SIMD_BUILTIN_BASE)
- return aarch64_simd_expand_builtin (fcode, exp, target);
-
- return NULL_RTX;
-}
-
/* On AAPCS systems, this is the "struct __va_list". */
static GTY(()) tree va_list_type;
@@ -5085,6 +5055,7 @@ aarch64_build_builtin_va_list (void)
va_list_type);
DECL_ARTIFICIAL (va_list_name) = 1;
TYPE_NAME (va_list_type) = va_list_name;
+ TYPE_STUB_DECL (va_list_type) = va_list_name;
/* Create the fields. */
f_stack = build_decl (BUILTINS_LOCATION,
@@ -6340,6 +6311,31 @@ aarch64_simd_attr_length_move (rtx insn)
return 4;
}
+/* Implement target hook TARGET_VECTOR_ALIGNMENT. The AAPCS64 sets the maximum
+ alignment of a vector to 128 bits. */
+static HOST_WIDE_INT
+aarch64_simd_vector_alignment (const_tree type)
+{
+ HOST_WIDE_INT align = tree_low_cst (TYPE_SIZE (type), 0);
+ return MIN (align, 128);
+}
+
+/* Implement target hook TARGET_VECTORIZE_VECTOR_ALIGNMENT_REACHABLE. */
+static bool
+aarch64_simd_vector_alignment_reachable (const_tree type, bool is_packed)
+{
+ if (is_packed)
+ return false;
+
+ /* We guarantee alignment for vectors up to 128-bits. */
+ if (tree_int_cst_compare (TYPE_SIZE (type),
+ bitsize_int (BIGGEST_ALIGNMENT)) > 0)
+ return false;
+
+ /* Vectors whose size is <= BIGGEST_ALIGNMENT are naturally aligned. */
+ return true;
+}
+
static unsigned HOST_WIDE_INT
aarch64_shift_truncation_mask (enum machine_mode mode)
{
@@ -6768,6 +6764,9 @@ aarch64_c_mode_for_suffix (char suffix)
#undef TARGET_CLASS_MAX_NREGS
#define TARGET_CLASS_MAX_NREGS aarch64_class_max_nregs
+#undef TARGET_BUILTIN_DECL
+#define TARGET_BUILTIN_DECL aarch64_builtin_decl
+
#undef TARGET_EXPAND_BUILTIN
#define TARGET_EXPAND_BUILTIN aarch64_expand_builtin
@@ -6874,6 +6873,13 @@ aarch64_c_mode_for_suffix (char suffix)
#undef TARGET_VECTORIZE_PREFERRED_SIMD_MODE
#define TARGET_VECTORIZE_PREFERRED_SIMD_MODE aarch64_preferred_simd_mode
+#undef TARGET_VECTOR_ALIGNMENT
+#define TARGET_VECTOR_ALIGNMENT aarch64_simd_vector_alignment
+
+#undef TARGET_VECTORIZE_VECTOR_ALIGNMENT_REACHABLE
+#define TARGET_VECTORIZE_VECTOR_ALIGNMENT_REACHABLE \
+ aarch64_simd_vector_alignment_reachable
+
struct gcc_target targetm = TARGET_INITIALIZER;
#include "gt-aarch64.h"
diff --git a/gcc/config/aarch64/aarch64.h b/gcc/config/aarch64/aarch64.h
index d354bc2b6d1..8019f4c2a59 100644
--- a/gcc/config/aarch64/aarch64.h
+++ b/gcc/config/aarch64/aarch64.h
@@ -794,15 +794,6 @@ do { \
extern void __aarch64_sync_cache_range (void *, void *); \
__aarch64_sync_cache_range (beg, end)
-/* This should be integrated with the equivalent in the 32 bit
- world. */
-enum aarch64_builtins
-{
- AARCH64_BUILTIN_MIN,
- AARCH64_BUILTIN_THREAD_POINTER,
- AARCH64_SIMD_BUILTIN_BASE
-};
-
/* VFP registers may only be accessed in the mode they
were set. */
#define CANNOT_CHANGE_MODE_CLASS(FROM, TO, CLASS) \
diff --git a/gcc/config/aarch64/iterators.md b/gcc/config/aarch64/iterators.md
index e41d64d3e73..7a1cdc89535 100644
--- a/gcc/config/aarch64/iterators.md
+++ b/gcc/config/aarch64/iterators.md
@@ -227,6 +227,7 @@
UNSPEC_CMTST ; Used in aarch64-simd.md.
UNSPEC_FMAX ; Used in aarch64-simd.md.
UNSPEC_FMIN ; Used in aarch64-simd.md.
+ UNSPEC_BSL ; Used in aarch64-simd.md.
])
;; -------------------------------------------------------------------
diff --git a/gcc/testsuite/ChangeLog.aarch64 b/gcc/testsuite/ChangeLog.aarch64
index 2f1ad235d40..f765277c664 100644
--- a/gcc/testsuite/ChangeLog.aarch64
+++ b/gcc/testsuite/ChangeLog.aarch64
@@ -1,3 +1,9 @@
+2012-12-04 Marcus Shawcroft <marcus.shawcroft@arm.com>
+
+ Backport form mainline
+ 2012-12-04 Marcus Shawcroft <marcus.shawcroft@arm.com>
+ * gcc.target/aarch64/121127.c: New test.
+
2012-11-22 Ian Bolton <ian.bolton@arm.com>
Backport from mainline
diff --git a/gcc/testsuite/gcc.target/aarch64/121127.c b/gcc/testsuite/gcc.target/aarch64/121127.c
new file mode 100644
index 00000000000..a7dca09fec8
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/121127.c
@@ -0,0 +1,4 @@
+/* { dg-do compile } */
+/* { dg-options "-g -femit-struct-debug-baseonly" } */
+
+typedef __builtin_va_list __gnuc_va_list;
diff --git a/libgcc/ChangeLog.aarch64 b/libgcc/ChangeLog.aarch64
index 3f48587a728..53d718bf811 100644
--- a/libgcc/ChangeLog.aarch64
+++ b/libgcc/ChangeLog.aarch64
@@ -1,3 +1,9 @@
+2012-12-04 Marcus Shawcroft <marcus.shawcroft@arm.com>
+
+ * config/aarch64/sfp-machine.h (FP_EX_ALL): Define.
+ (FP_EX_SHIFT): Define.
+ (FP_TRAPPING_EXCEPTIONS): Define.
+
2012-11-15 Marcus Shawcroft <marcus.shawcroft@arm.com>
* soft-fp: Updated from glibc upstream.
diff --git a/libgcc/config/aarch64/sfp-exceptions.c b/libgcc/config/aarch64/sfp-exceptions.c
new file mode 100644
index 00000000000..878cf8f95cd
--- /dev/null
+++ b/libgcc/config/aarch64/sfp-exceptions.c
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2012 Free Software Foundation, Inc.
+ *
+ * This file is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 3, or (at your option) any
+ * later version.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * Under Section 7 of GPL version 3, you are granted additional
+ * permissions described in the GCC Runtime Library Exception, version
+ * 3.1, as published by the Free Software Foundation.
+ *
+ * You should have received a copy of the GNU General Public License and
+ * a copy of the GCC Runtime Library Exception along with this program;
+ * see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+ * <http://www.gnu.org/licenses/>.
+ */
+
+#include "sfp-machine.h"
+
+void
+__sfp_handle_exceptions (int _fex)
+{
+ const float fp_max = __FLT_MAX__;
+ const float fp_min = __FLT_MIN__;
+ const float fp_1e32 = 1.0e32f;
+ const float fp_zero = 0.0;
+ const float fp_one = 1.0;
+ unsigned fpsr;
+
+ if (_fex & FP_EX_INVALID)
+ {
+ __asm__ __volatile__ ("fdiv\ts0, %s0, %s0"
+ :
+ : "w" (fp_zero)
+ : "s0");
+ __asm__ __volatile__ ("mrs\t%0, fpsr" : "=r" (fpsr));
+ }
+ if (_fex & FP_EX_DIVZERO)
+ {
+ __asm__ __volatile__ ("fdiv\ts0, %s0, %s1"
+ :
+ : "w" (fp_one), "w" (fp_zero)
+ : "s0");
+ __asm__ __volatile__ ("mrs\t%0, fpsr" : "=r" (fpsr));
+ }
+ if (_fex & FP_EX_OVERFLOW)
+ {
+ __asm__ __volatile__ ("fadd\ts0, %s0, %s1"
+ :
+ : "w" (fp_max), "w" (fp_1e32)
+ : "s0");
+ __asm__ __volatile__ ("mrs\t%0, fpsr" : "=r" (fpsr));
+ }
+ if (_fex & FP_EX_UNDERFLOW)
+ {
+ __asm__ __volatile__ ("fmul\ts0, %s0, %s0"
+ :
+ : "w" (fp_min)
+ : "s0");
+ __asm__ __volatile__ ("mrs\t%0, fpsr" : "=r" (fpsr));
+ }
+ if (_fex & FP_EX_INEXACT)
+ {
+ __asm__ __volatile__ ("fsub\ts0, %s0, %s1"
+ :
+ : "w" (fp_max), "w" (fp_one)
+ : "s0");
+ __asm__ __volatile__ ("mrs\t%0, fpsr" : "=r" (fpsr));
+ }
+}
diff --git a/libgcc/config/aarch64/sfp-machine.h b/libgcc/config/aarch64/sfp-machine.h
index 3a09ae7605f..52b6fb2c446 100644
--- a/libgcc/config/aarch64/sfp-machine.h
+++ b/libgcc/config/aarch64/sfp-machine.h
@@ -69,62 +69,26 @@ typedef int __gcc_CMPtype __attribute__ ((mode (__libgcc_cmp_return__)));
#define FP_EX_OVERFLOW 0x04
#define FP_EX_UNDERFLOW 0x08
#define FP_EX_INEXACT 0x10
+#define FP_EX_SHIFT 8
+#define FP_EX_ALL \
+ (FP_EX_INVALID | FP_EX_DIVZERO | FP_EX_OVERFLOW | FP_EX_UNDERFLOW \
+ | FP_EX_INEXACT)
-#define FP_HANDLE_EXCEPTIONS \
- do { \
- const float fp_max = __FLT_MAX__; \
- const float fp_min = __FLT_MIN__; \
- const float fp_1e32 = 1.0e32f; \
- const float fp_zero = 0.0; \
- const float fp_one = 1.0; \
- unsigned fpsr; \
- if (_fex & FP_EX_INVALID) \
- { \
- __asm__ __volatile__ ("fdiv\ts0, %s0, %s0" \
- : \
- : "w" (fp_zero) \
- : "s0"); \
- __asm__ __volatile__ ("mrs\t%0, fpsr" : "=r" (fpsr)); \
- } \
- if (_fex & FP_EX_DIVZERO) \
- { \
- __asm__ __volatile__ ("fdiv\ts0, %s0, %s1" \
- : \
- : "w" (fp_one), "w" (fp_zero) \
- : "s0"); \
- __asm__ __volatile__ ("mrs\t%0, fpsr" : "=r" (fpsr)); \
- } \
- if (_fex & FP_EX_OVERFLOW) \
- { \
- __asm__ __volatile__ ("fadd\ts0, %s0, %s1" \
- : \
- : "w" (fp_max), "w" (fp_1e32) \
- : "s0"); \
- __asm__ __volatile__ ("mrs\t%0, fpsr" : "=r" (fpsr)); \
- } \
- if (_fex & FP_EX_UNDERFLOW) \
- { \
- __asm__ __volatile__ ("fmul\ts0, %s0, %s0" \
- : \
- : "w" (fp_min) \
- : "s0"); \
- __asm__ __volatile__ ("mrs\t%0, fpsr" : "=r" (fpsr)); \
- } \
- if (_fex & FP_EX_INEXACT) \
- { \
- __asm__ __volatile__ ("fsub\ts0, %s0, %s1" \
- : \
- : "w" (fp_max), "w" (fp_one) \
- : "s0"); \
- __asm__ __volatile__ ("mrs\t%0, fpsr" : "=r" (fpsr)); \
- } \
- } while (0)
+void __sfp_handle_exceptions (int);
+#define FP_HANDLE_EXCEPTIONS \
+ do { \
+ if (__builtin_expect (_fex, 0)) \
+ __sfp_handle_exceptions (_fex); \
+ } while (0);
-#define FP_RND_NEAREST 0
-#define FP_RND_ZERO 0xc00000
+#define FP_TRAPPING_EXCEPTIONS ((_fpcr >> FP_EX_SHIFT) & FP_EX_ALL)
+
+#define FP_RND_NEAREST 0x000000
#define FP_RND_PINF 0x400000
#define FP_RND_MINF 0x800000
+#define FP_RND_ZERO 0xc00000
+#define FP_RND_MASK 0xc00000
#define _FP_DECL_EX \
unsigned long int _fpcr __attribute__ ((unused)) = FP_RND_NEAREST
@@ -135,7 +99,7 @@ typedef int __gcc_CMPtype __attribute__ ((mode (__libgcc_cmp_return__)));
: "=r" (_fpcr)); \
} while (0)
-#define FP_ROUNDMODE (_fpcr & 0xc00000)
+#define FP_ROUNDMODE (_fpcr & FP_RND_MASK)
#define __LITTLE_ENDIAN 1234
#define __BIG_ENDIAN 4321
diff --git a/libgcc/config/aarch64/t-softfp b/libgcc/config/aarch64/t-softfp
index 6500b5243e4..586dca22469 100644
--- a/libgcc/config/aarch64/t-softfp
+++ b/libgcc/config/aarch64/t-softfp
@@ -5,3 +5,5 @@ softfp_truncations := tfsf tfdf
softfp_exclude_libgcc2 := n
TARGET_LIBGCC2_CFLAGS += -Wno-missing-prototypes
+
+LIB2ADD += $(srcdir)/config/aarch64/sfp-exceptions.c