Commit 342be7f7 by James Greenhalgh Committed by James Greenhalgh

gcc/

	* 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): New.
	* config/aarch64/aarch64-simd-builtins.def: New file.
	* config/aarch64/aarch64.c (aarch64_init_builtins):
	Move to aarch64-builtins.c.
	(aarch64_expand_builtin): Likewise.
	* config/aarch64/aarch64.h
	(aarch64_builtins): Move to aarch64-builtins.c.


Co-Authored-By: Tejas Belagod <tejas.belagod@arm.com>

From-SVN: r193658
parent dffdd6e5
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): New.
* config/aarch64/aarch64-simd-builtins.def: New file.
* config/aarch64/aarch64.c (aarch64_init_builtins):
Move to aarch64-builtins.c.
(aarch64_expand_builtin): Likewise.
* config/aarch64/aarch64.h
(aarch64_builtins): Move to aarch64-builtins.c.
2012-11-20 Martin Jambor <mjambor@suse.cz> 2012-11-20 Martin Jambor <mjambor@suse.cz>
PR tree-optimization/55260 PR tree-optimization/55260
...@@ -31,27 +31,28 @@ ...@@ -31,27 +31,28 @@
#include "diagnostic-core.h" #include "diagnostic-core.h"
#include "optabs.h" #include "optabs.h"
enum aarch64_simd_builtin_type_bits enum aarch64_simd_builtin_type_mode
{ {
T_V8QI = 0x0001, T_V8QI,
T_V4HI = 0x0002, T_V4HI,
T_V2SI = 0x0004, T_V2SI,
T_V2SF = 0x0008, T_V2SF,
T_DI = 0x0010, T_DI,
T_DF = 0x0020, T_DF,
T_V16QI = 0x0040, T_V16QI,
T_V8HI = 0x0080, T_V8HI,
T_V4SI = 0x0100, T_V4SI,
T_V4SF = 0x0200, T_V4SF,
T_V2DI = 0x0400, T_V2DI,
T_V2DF = 0x0800, T_V2DF,
T_TI = 0x1000, T_TI,
T_EI = 0x2000, T_EI,
T_OI = 0x4000, T_OI,
T_XI = 0x8000, T_XI,
T_SI = 0x10000, T_SI,
T_HI = 0x20000, T_HI,
T_QI = 0x40000 T_QI,
T_MAX
}; };
#define v8qi_UP T_V8QI #define v8qi_UP T_V8QI
...@@ -76,8 +77,6 @@ enum aarch64_simd_builtin_type_bits ...@@ -76,8 +77,6 @@ enum aarch64_simd_builtin_type_bits
#define UP(X) X##_UP #define UP(X) X##_UP
#define T_MAX 19
typedef enum typedef enum
{ {
AARCH64_SIMD_BINOP, AARCH64_SIMD_BINOP,
...@@ -124,253 +123,174 @@ typedef struct ...@@ -124,253 +123,174 @@ typedef struct
{ {
const char *name; const char *name;
const aarch64_simd_itype itype; const aarch64_simd_itype itype;
const int bits; enum aarch64_simd_builtin_type_mode mode;
const enum insn_code codes[T_MAX]; const enum insn_code code;
const unsigned int num_vars; unsigned int fcode;
unsigned int base_fcode;
} aarch64_simd_builtin_datum; } aarch64_simd_builtin_datum;
#define CF(N, X) CODE_FOR_aarch64_##N##X #define CF(N, X) CODE_FOR_aarch64_##N##X
#define VAR1(T, N, A) \ #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) \ #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) \ #define VAR3(T, N, A, B, C) \
#N, AARCH64_SIMD_##T, UP (A) | UP (B) | UP (C), \ VAR2 (T, N, A, B) \
{ CF (N, A), CF (N, B), CF (N, C) }, 3, 0 VAR1 (T, N, C)
#define VAR4(T, N, A, B, C, D) \ #define VAR4(T, N, A, B, C, D) \
#N, AARCH64_SIMD_##T, UP (A) | UP (B) | UP (C) | UP (D), \ VAR3 (T, N, A, B, C) \
{ CF (N, A), CF (N, B), CF (N, C), CF (N, D) }, 4, 0 VAR1 (T, N, D)
#define VAR5(T, N, A, B, C, D, E) \ #define VAR5(T, N, A, B, C, D, E) \
#N, AARCH64_SIMD_##T, UP (A) | UP (B) | UP (C) | UP (D) | UP (E), \ VAR4 (T, N, A, B, C, D) \
{ CF (N, A), CF (N, B), CF (N, C), CF (N, D), CF (N, E) }, 5, 0 VAR1 (T, N, E)
#define VAR6(T, N, A, B, C, D, E, F) \ #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), \ VAR5 (T, N, A, B, C, D, E) \
{ CF (N, A), CF (N, B), CF (N, C), CF (N, D), CF (N, E), CF (N, F) }, 6, 0 VAR1 (T, N, F)
#define VAR7(T, N, A, B, C, D, E, F, G) \ #define VAR7(T, N, A, B, C, D, E, F, G) \
#N, AARCH64_SIMD_##T, UP (A) | UP (B) | UP (C) | UP (D) \ VAR6 (T, N, A, B, C, D, E, F) \
| UP (E) | UP (F) | UP (G), \ VAR1 (T, N, G)
{ CF (N, A), CF (N, B), CF (N, C), CF (N, D), CF (N, E), CF (N, F), \
CF (N, G) }, 7, 0
#define VAR8(T, N, A, B, C, D, E, F, G, H) \ #define VAR8(T, N, A, B, C, D, E, F, G, H) \
#N, AARCH64_SIMD_##T, UP (A) | UP (B) | UP (C) | UP (D) \ VAR7 (T, N, A, B, C, D, E, F, G) \
| UP (E) | UP (F) | UP (G) \ VAR1 (T, N, H)
| 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
#define VAR9(T, N, A, B, C, D, E, F, G, H, I) \ #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) \ VAR8 (T, N, A, B, C, D, E, F, G, H) \
| UP (E) | UP (F) | UP (G) \ VAR1 (T, N, I)
| 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
#define VAR10(T, N, A, B, C, D, E, F, G, H, I, J) \ #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) \ VAR9 (T, N, A, B, C, D, E, F, G, H, I) \
| UP (E) | UP (F) | UP (G) \ VAR1 (T, N, J)
| 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
#define VAR11(T, N, A, B, C, D, E, F, G, H, I, J, K) \ #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) \ VAR10 (T, N, A, B, C, D, E, F, G, H, I, J) \
| UP (E) | UP (F) | UP (G) \ VAR1 (T, N, K)
| 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
#define VAR12(T, N, A, B, C, D, E, F, G, H, I, J, K, L) \ #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) \ VAR11 (T, N, A, B, C, D, E, F, G, H, I, J, K) \
| UP (E) | UP (F) | UP (G) \ VAR1 (T, N, L)
| 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), \ /* BUILTIN_<ITERATOR> macros should expand to cover the same range of
CF (N, G), CF (N, H), CF (N, I), CF (N, J), CF (N, K), CF (N, L) }, 12, 0 modes as is given for each define_mode_iterator in
config/aarch64/iterators.md. */
/* The mode entries in the following table correspond to the "key" type of the #define BUILTIN_DX(T, N) \
instruction variant, i.e. equivalent to that which would be specified after VAR2 (T, N, di, df)
the assembler mnemonic, which usually refers to the last vector operand. #define BUILTIN_SDQ_I(T, N) \
(Signed/unsigned/polynomial types are not differentiated between though, and VAR4 (T, N, qi, hi, si, di)
are all mapped onto the same mode for a given element size.) The modes #define BUILTIN_SD_HSI(T, N) \
listed per instruction should be the same as those defined for that VAR2 (T, N, hi, si)
instruction's pattern in aarch64_simd.md. #define BUILTIN_V2F(T, N) \
WARNING: Variants should be listed in the same increasing order as VAR2 (T, N, v2sf, v2df)
aarch64_simd_builtin_type_bits. */ #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[] = { static aarch64_simd_builtin_datum aarch64_simd_builtin_data[] = {
{VAR6 (CREATE, create, v8qi, v4hi, v2si, v2sf, di, df)}, #include "aarch64-simd-builtins.def"
{VAR6 (GETLANE, get_lane_signed, };
v8qi, v4hi, v2si, v16qi, v8hi, v4si)},
{VAR7 (GETLANE, get_lane_unsigned, #undef VAR1
v8qi, v4hi, v2si, v16qi, v8hi, v4si, v2di)}, #define VAR1(T, N, A) \
{VAR4 (GETLANE, get_lane, v2sf, di, v4sf, v2df)}, AARCH64_SIMD_BUILTIN_##N##A,
{VAR6 (GETLANE, get_dregoi, v8qi, v4hi, v2si, v2sf, di, df)},
{VAR6 (GETLANE, get_qregoi, v16qi, v8hi, v4si, v4sf, v2di, v2df)}, enum aarch64_builtins
{VAR6 (GETLANE, get_dregci, v8qi, v4hi, v2si, v2sf, di, df)}, {
{VAR6 (GETLANE, get_qregci, v16qi, v8hi, v4si, v4sf, v2di, v2df)}, AARCH64_BUILTIN_MIN,
{VAR6 (GETLANE, get_dregxi, v8qi, v4hi, v2si, v2sf, di, df)}, AARCH64_SIMD_BUILTIN_BASE,
{VAR6 (GETLANE, get_qregxi, v16qi, v8hi, v4si, v4sf, v2di, v2df)}, #include "aarch64-simd-builtins.def"
{VAR6 (SETLANE, set_qregoi, v16qi, v8hi, v4si, v4sf, v2di, v2df)}, AARCH64_SIMD_BUILTIN_MAX = AARCH64_SIMD_BUILTIN_BASE
{VAR6 (SETLANE, set_qregci, v16qi, v8hi, v4si, v4sf, v2di, v2df)}, + ARRAY_SIZE (aarch64_simd_builtin_data),
{VAR6 (SETLANE, set_qregxi, v16qi, v8hi, v4si, v4sf, v2di, v2df)}, AARCH64_BUILTIN_MAX
{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)},
}; };
#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 CF
#undef VAR1 #undef VAR1
#undef VAR2 #undef VAR2
...@@ -388,9 +308,9 @@ static aarch64_simd_builtin_datum aarch64_simd_builtin_data[] = { ...@@ -388,9 +308,9 @@ static aarch64_simd_builtin_datum aarch64_simd_builtin_data[] = {
#define NUM_QREG_TYPES 6 #define NUM_QREG_TYPES 6
void 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. */ /* Scalar type nodes. */
tree aarch64_simd_intQI_type_node; tree aarch64_simd_intQI_type_node;
...@@ -680,417 +600,367 @@ init_aarch64_simd_builtins (void) ...@@ -680,417 +600,367 @@ 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]; 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;
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[] = { case AARCH64_SIMD_LOAD1:
"v8qi", "v4hi", "v2si", "v2sf", "di", "df", case AARCH64_SIMD_LOAD1LANE:
"v16qi", "v8hi", "v4si", "v4sf", "v2di", "v2df", case AARCH64_SIMD_LOADSTRUCT:
"ti", "ei", "oi", "xi", "si", "hi", "qi" case AARCH64_SIMD_LOADSTRUCTLANE:
}; is_load = 1;
char namebuf[60]; /* Fall through. */
tree ftype = NULL; case AARCH64_SIMD_STORE1:
enum insn_code icode; case AARCH64_SIMD_STORE1LANE:
int is_load = 0; case AARCH64_SIMD_STORESTRUCT:
int is_store = 0; case AARCH64_SIMD_STORESTRUCTLANE:
if (!is_load)
/* Skip if particular mode not supported. */ is_store = 1;
if ((d->bits & (1 << j)) == 0) /* Fall through. */
continue; case AARCH64_SIMD_UNOP:
case AARCH64_SIMD_BINOP:
icode = d->codes[codeidx++]; case AARCH64_SIMD_TERNOP:
case AARCH64_SIMD_QUADOP:
switch (d->itype) case AARCH64_SIMD_COMBINE:
{ case AARCH64_SIMD_CONVERT:
case AARCH64_SIMD_LOAD1: case AARCH64_SIMD_CREATE:
case AARCH64_SIMD_LOAD1LANE: case AARCH64_SIMD_DUP:
case AARCH64_SIMD_LOADSTRUCTLANE: case AARCH64_SIMD_DUPLANE:
case AARCH64_SIMD_LOADSTRUCT: case AARCH64_SIMD_FIXCONV:
is_load = 1; case AARCH64_SIMD_GETLANE:
/* Fall through. */ case AARCH64_SIMD_LANEMAC:
case AARCH64_SIMD_STORE1: case AARCH64_SIMD_LANEMUL:
case AARCH64_SIMD_STORE1LANE: case AARCH64_SIMD_LANEMULH:
case AARCH64_SIMD_STORESTRUCTLANE: case AARCH64_SIMD_LANEMULL:
case AARCH64_SIMD_STORESTRUCT: case AARCH64_SIMD_LOGICBINOP:
if (!is_load) case AARCH64_SIMD_SCALARMAC:
is_store = 1; case AARCH64_SIMD_SCALARMUL:
/* Fall through. */ case AARCH64_SIMD_SCALARMULH:
case AARCH64_SIMD_UNOP: case AARCH64_SIMD_SCALARMULL:
case AARCH64_SIMD_BINOP: case AARCH64_SIMD_SELECT:
case AARCH64_SIMD_LOGICBINOP: case AARCH64_SIMD_SETLANE:
case AARCH64_SIMD_SHIFTINSERT: case AARCH64_SIMD_SHIFTACC:
case AARCH64_SIMD_TERNOP: case AARCH64_SIMD_SHIFTIMM:
case AARCH64_SIMD_QUADOP: case AARCH64_SIMD_SHIFTINSERT:
case AARCH64_SIMD_GETLANE: case AARCH64_SIMD_SPLIT:
case AARCH64_SIMD_SETLANE: case AARCH64_SIMD_VTBL:
case AARCH64_SIMD_CREATE: case AARCH64_SIMD_VTBX:
case AARCH64_SIMD_DUP: {
case AARCH64_SIMD_DUPLANE: int k;
case AARCH64_SIMD_SHIFTIMM: tree return_type = void_type_node, args = void_list_node;
case AARCH64_SIMD_SHIFTACC: tree eltype;
case AARCH64_SIMD_COMBINE: /* Build a function type directly from the insn_data for this
case AARCH64_SIMD_SPLIT: builtin. The build_function_type () function takes care of
case AARCH64_SIMD_CONVERT: removing duplicates for us. */
case AARCH64_SIMD_FIXCONV:
case AARCH64_SIMD_LANEMUL: for (k = insn_data[d->code].n_operands -1; k >= 0; k--)
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:
{ {
int k; /* Skip an internal operand for vget_{low, high}. */
tree return_type = void_type_node, args = void_list_node; if (k == 2 && d->itype == AARCH64_SIMD_SPLIT)
continue;
/* Build a function type directly from the insn_data for this if (is_load && k == 1)
builtin. The build_function_type() function takes care of
removing duplicates for us. */
for (k = insn_data[icode].n_operands - 1; k >= 0; k--)
{ {
tree eltype; /* 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);
/* Skip an internal operand for vget_{low, high}. */ switch (d->mode)
if (k == 2 && d->itype == AARCH64_SIMD_SPLIT)
continue;
if (is_load && k == 1)
{ {
/* AdvSIMD load patterns always have the memory operand case T_V8QI:
(a DImode pointer) in the operand 1 position. We case T_V16QI:
want a const pointer to the element type in that eltype = const_intQI_pointer_node;
position. */ break;
gcc_assert (insn_data[icode].operand[k].mode ==
DImode); case T_V4HI:
case T_V8HI:
switch (1 << j) eltype = const_intHI_pointer_node;
{ break;
case T_V8QI:
case T_V16QI: case T_V2SI:
eltype = const_intQI_pointer_node; case T_V4SI:
break; eltype = const_intSI_pointer_node;
break;
case T_V4HI:
case T_V8HI: case T_V2SF:
eltype = const_intHI_pointer_node; case T_V4SF:
break; eltype = const_float_pointer_node;
break;
case T_V2SI:
case T_V4SI: case T_DI:
eltype = const_intSI_pointer_node; case T_V2DI:
break; eltype = const_intDI_pointer_node;
break;
case T_V2SF:
case T_V4SF: case T_DF:
eltype = const_float_pointer_node; case T_V2DF:
break; eltype = const_double_pointer_node;
break;
case T_DI:
case T_V2DI: default:
eltype = const_intDI_pointer_node; gcc_unreachable ();
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 case T_V8QI:
the memory location to store to (a DImode pointer). case T_V16QI:
Use a pointer to the element type of the store in eltype = intQI_pointer_node;
that position. */ break;
gcc_assert (insn_data[icode].operand[k].mode ==
DImode); case T_V4HI:
case T_V8HI:
switch (1 << j) eltype = intHI_pointer_node;
{ break;
case T_V8QI:
case T_V16QI: case T_V2SI:
eltype = intQI_pointer_node; case T_V4SI:
break; eltype = intSI_pointer_node;
break;
case T_V4HI:
case T_V8HI: case T_V2SF:
eltype = intHI_pointer_node; case T_V4SF:
break; eltype = float_pointer_node;
break;
case T_V2SI:
case T_V4SI: case T_DI:
eltype = intSI_pointer_node; case T_V2DI:
break; eltype = intDI_pointer_node;
break;
case T_V2SF:
case T_V4SF: case T_DF:
eltype = float_pointer_node; case T_V2DF:
break; eltype = double_pointer_node;
break;
case T_DI:
case T_V2DI: default:
eltype = intDI_pointer_node; gcc_unreachable ();
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;
case VOIDmode: break;
eltype = void_type_node; /* Scalars. */
break; case QImode:
/* Scalars. */ eltype = aarch64_simd_intQI_type_node;
case QImode: break;
eltype = aarch64_simd_intQI_type_node; case HImode:
break; eltype = aarch64_simd_intHI_type_node;
case HImode: break;
eltype = aarch64_simd_intHI_type_node; case SImode:
break; eltype = aarch64_simd_intSI_type_node;
case SImode: break;
eltype = aarch64_simd_intSI_type_node; case SFmode:
break; eltype = aarch64_simd_float_type_node;
case SFmode: break;
eltype = aarch64_simd_float_type_node; case DFmode:
break; eltype = aarch64_simd_double_type_node;
case DFmode: break;
eltype = aarch64_simd_double_type_node; case DImode:
break; eltype = aarch64_simd_intDI_type_node;
case DImode: break;
eltype = aarch64_simd_intDI_type_node; case TImode:
break; eltype = intTI_type_node;
case TImode: break;
eltype = intTI_type_node; case EImode:
break; eltype = intEI_type_node;
case EImode: break;
eltype = intEI_type_node; case OImode:
break; eltype = intOI_type_node;
case OImode: break;
eltype = intOI_type_node; case CImode:
break; eltype = intCI_type_node;
case CImode: break;
eltype = intCI_type_node; case XImode:
break; eltype = intXI_type_node;
case XImode: break;
eltype = intXI_type_node; /* 64-bit vectors. */
break; case V8QImode:
/* 64-bit vectors. */ eltype = V8QI_type_node;
case V8QImode: break;
eltype = V8QI_type_node; case V4HImode:
break; eltype = V4HI_type_node;
case V4HImode: break;
eltype = V4HI_type_node; case V2SImode:
break; eltype = V2SI_type_node;
case V2SImode: break;
eltype = V2SI_type_node; case V2SFmode:
break; eltype = V2SF_type_node;
case V2SFmode: break;
eltype = V2SF_type_node; /* 128-bit vectors. */
break; case V16QImode:
/* 128-bit vectors. */ eltype = V16QI_type_node;
case V16QImode: break;
eltype = V16QI_type_node; case V8HImode:
break; eltype = V8HI_type_node;
case V8HImode: break;
eltype = V8HI_type_node; case V4SImode:
break; eltype = V4SI_type_node;
case V4SImode: break;
eltype = V4SI_type_node; case V4SFmode:
break; eltype = V4SF_type_node;
case V4SFmode: break;
eltype = V4SF_type_node; case V2DImode:
break; eltype = V2DI_type_node;
case V2DImode: break;
eltype = V2DI_type_node; case V2DFmode:
break; eltype = V2DF_type_node;
case V2DFmode: break;
eltype = V2DF_type_node; default:
break; gcc_unreachable ();
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;
case V8QImode: break;
ftype = void_ftype_pv8qi_v8qi_v8qi; case V4HImode:
break; ftype = void_ftype_pv4hi_v4hi_v4hi;
case V4HImode: break;
ftype = void_ftype_pv4hi_v4hi_v4hi; case V2SImode:
break; ftype = void_ftype_pv2si_v2si_v2si;
case V2SImode: break;
ftype = void_ftype_pv2si_v2si_v2si; case V2SFmode:
break; ftype = void_ftype_pv2sf_v2sf_v2sf;
case V2SFmode: break;
ftype = void_ftype_pv2sf_v2sf_v2sf; case DImode:
break; ftype = void_ftype_pdi_di_di;
case DImode: break;
ftype = void_ftype_pdi_di_di; case V16QImode:
break; ftype = void_ftype_pv16qi_v16qi_v16qi;
case V16QImode: break;
ftype = void_ftype_pv16qi_v16qi_v16qi; case V8HImode:
break; ftype = void_ftype_pv8hi_v8hi_v8hi;
case V8HImode: break;
ftype = void_ftype_pv8hi_v8hi_v8hi; case V4SImode:
break; ftype = void_ftype_pv4si_v4si_v4si;
case V4SImode: break;
ftype = void_ftype_pv4si_v4si_v4si; case V4SFmode:
break; ftype = void_ftype_pv4sf_v4sf_v4sf;
case V4SFmode: break;
ftype = void_ftype_pv4sf_v4sf_v4sf; case V2DImode:
break; ftype = void_ftype_pv2di_v2di_v2di;
case V2DImode: break;
ftype = void_ftype_pv2di_v2di_v2di; case V2DFmode:
break; ftype = void_ftype_pv2df_v2df_v2df;
case V2DFmode: break;
ftype = void_ftype_pv2df_v2df_v2df; default:
break; gcc_unreachable ();
default:
gcc_unreachable ();
}
} }
break; }
break;
case AARCH64_SIMD_REINTERP:
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 case V8QImode:
types. */ ftype = reinterp_ftype_dreg[0][rhs_d];
int rhs_d = j % NUM_DREG_TYPES; break;
int rhs_q = (j - NUM_DREG_TYPES) % NUM_QREG_TYPES; case V4HImode:
switch (insn_data[icode].operand[0].mode) ftype = reinterp_ftype_dreg[1][rhs_d];
{ break;
case V8QImode: case V2SImode:
ftype = reinterp_ftype_dreg[0][rhs_d]; ftype = reinterp_ftype_dreg[2][rhs_d];
break; break;
case V4HImode: case V2SFmode:
ftype = reinterp_ftype_dreg[1][rhs_d]; ftype = reinterp_ftype_dreg[3][rhs_d];
break; break;
case V2SImode: case DImode:
ftype = reinterp_ftype_dreg[2][rhs_d]; ftype = reinterp_ftype_dreg[4][rhs_d];
break; break;
case V2SFmode: case DFmode:
ftype = reinterp_ftype_dreg[3][rhs_d]; ftype = reinterp_ftype_dreg[5][rhs_d];
break; break;
case DImode: case V16QImode:
ftype = reinterp_ftype_dreg[4][rhs_d]; ftype = reinterp_ftype_qreg[0][rhs_q];
break; break;
case DFmode: case V8HImode:
ftype = reinterp_ftype_dreg[5][rhs_d]; ftype = reinterp_ftype_qreg[1][rhs_q];
break; break;
case V16QImode: case V4SImode:
ftype = reinterp_ftype_qreg[0][rhs_q]; ftype = reinterp_ftype_qreg[2][rhs_q];
break; break;
case V8HImode: case V4SFmode:
ftype = reinterp_ftype_qreg[1][rhs_q]; ftype = reinterp_ftype_qreg[3][rhs_q];
break; break;
case V4SImode: case V2DImode:
ftype = reinterp_ftype_qreg[2][rhs_q]; ftype = reinterp_ftype_qreg[4][rhs_q];
break; break;
case V4SFmode: case V2DFmode:
ftype = reinterp_ftype_qreg[3][rhs_q]; ftype = reinterp_ftype_qreg[5][rhs_q];
break; break;
case V2DImode: default:
ftype = reinterp_ftype_qreg[4][rhs_q]; gcc_unreachable ();
break;
case V2DFmode:
ftype = reinterp_ftype_qreg[5][rhs_q];
break;
default:
gcc_unreachable ();
}
} }
break; }
break;
default: default:
gcc_unreachable (); gcc_unreachable ();
} }
gcc_assert (ftype != NULL);
gcc_assert (ftype != NULL);
snprintf (namebuf, sizeof (namebuf), "__builtin_aarch64_%s%s", snprintf (namebuf, sizeof (namebuf), "__builtin_aarch64_%s%s",
d->name, modenames[j]); d->name, modenames[d->mode]);
add_builtin_function (namebuf, ftype, fcode++, BUILT_IN_MD, NULL, add_builtin_function (namebuf, ftype, fcode, BUILT_IN_MD, NULL,
NULL_TREE); NULL_TREE);
}
} }
} }
static int void
aarch64_simd_builtin_compare (const void *a, const void *b) 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;
}
static enum insn_code
locate_simd_builtin_icode (int fcode, aarch64_simd_itype * itype)
{ {
aarch64_simd_builtin_datum key if (TARGET_SIMD)
= { NULL, (aarch64_simd_itype) 0, 0, {CODE_FOR_nothing}, 0, 0}; aarch64_init_simd_builtins ();
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];
} }
typedef enum typedef enum
...@@ -1225,8 +1095,10 @@ aarch64_simd_expand_args (rtx target, int icode, int have_retval, ...@@ -1225,8 +1095,10 @@ aarch64_simd_expand_args (rtx target, int icode, int have_retval,
rtx rtx
aarch64_simd_expand_builtin (int fcode, tree exp, rtx target) aarch64_simd_expand_builtin (int fcode, tree exp, rtx target)
{ {
aarch64_simd_itype itype; aarch64_simd_builtin_datum *d =
enum insn_code icode = locate_simd_builtin_icode (fcode, &itype); &aarch64_simd_builtin_data[fcode - (AARCH64_SIMD_BUILTIN_BASE + 1)];
aarch64_simd_itype itype = d->itype;
enum insn_code icode = d->code;
switch (itype) switch (itype)
{ {
...@@ -1318,3 +1190,21 @@ aarch64_simd_expand_builtin (int fcode, tree exp, rtx target) ...@@ -1318,3 +1190,21 @@ aarch64_simd_expand_builtin (int fcode, tree exp, rtx target)
gcc_unreachable (); 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_SIMD_BUILTIN_BASE)
return aarch64_simd_expand_builtin (fcode, exp, target);
return NULL_RTX;
}
...@@ -228,4 +228,11 @@ void aarch64_split_atomic_op (enum rtx_code, rtx, rtx, rtx, rtx, rtx, rtx); ...@@ -228,4 +228,11 @@ void aarch64_split_atomic_op (enum rtx_code, rtx, rtx, rtx, rtx, rtx, rtx);
#endif /* RTX_CODE */ #endif /* RTX_CODE */
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);
#endif /* GCC_AARCH64_PROTOS_H */ #endif /* GCC_AARCH64_PROTOS_H */
/* 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)
...@@ -5008,13 +5008,6 @@ aarch64_legitimate_constant_p (enum machine_mode mode, rtx x) ...@@ -5008,13 +5008,6 @@ aarch64_legitimate_constant_p (enum machine_mode mode, rtx x)
return aarch64_constant_address_p (x); return aarch64_constant_address_p (x);
} }
static void
aarch64_init_builtins (void)
{
if (TARGET_SIMD)
init_aarch64_simd_builtins ();
}
rtx rtx
aarch64_load_tp (rtx target) aarch64_load_tp (rtx target)
{ {
...@@ -5028,24 +5021,6 @@ aarch64_load_tp (rtx target) ...@@ -5028,24 +5021,6 @@ aarch64_load_tp (rtx target)
return 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_SIMD_BUILTIN_BASE)
return aarch64_simd_expand_builtin (fcode, exp, target);
return NULL_RTX;
}
/* On AAPCS systems, this is the "struct __va_list". */ /* On AAPCS systems, this is the "struct __va_list". */
static GTY(()) tree va_list_type; static GTY(()) tree va_list_type;
......
...@@ -789,14 +789,6 @@ do { \ ...@@ -789,14 +789,6 @@ do { \
extern void __aarch64_sync_cache_range (void *, void *); \ extern void __aarch64_sync_cache_range (void *, void *); \
__aarch64_sync_cache_range (beg, end) __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_SIMD_BUILTIN_BASE
};
/* VFP registers may only be accessed in the mode they /* VFP registers may only be accessed in the mode they
were set. */ were set. */
#define CANNOT_CHANGE_MODE_CLASS(FROM, TO, CLASS) \ #define CANNOT_CHANGE_MODE_CLASS(FROM, TO, CLASS) \
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment