aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndre Vieira <andre.simoesdiasvieira@arm.com>2017-01-06 17:26:11 +0000
committerAndre Vieira <avieira@gcc.gnu.org>2017-01-06 17:26:11 +0000
commit131e1faa2228126845c1e76fcf3fd850f1b05ffa (patch)
treec3dc9b03bdde8f3135615fb234e99b4c03bcd5b6
parentea4ad78e2c35e19b9a3387ecb4f021419e37ea9d (diff)
downloadgcc-131e1faa2228126845c1e76fcf3fd850f1b05ffa.zip
gcc-131e1faa2228126845c1e76fcf3fd850f1b05ffa.tar.gz
gcc-131e1faa2228126845c1e76fcf3fd850f1b05ffa.tar.bz2
[ARM] Refactor NEON builtin framework to work for other builtins
gcc/ChangeLog: 2017-01-06 Andre Vieira <andre.simoesdiasvieira@arm.com> * config/arm/arm-builtins.c (neon_builtin_datum): Rename to .. (arm_builtin_datum): ... this. (arm_init_neon_builtin): Rename to ... (arm_init_builtin): ... this. Add a new parameters PREFIX and USE_SIG_IN_NAME. (arm_init_neon_builtins): Replace 'arm_init_neon_builtin' with 'arm_init_builtin'. Replace type 'neon_builtin_datum' with 'arm_builtin_datum'. (arm_init_vfp_builtins): Likewise. (builtin_arg): Rename enum's replacing 'NEON_ARG' with 'ARG_BUILTIN' and add a 'ARG_BUILTIN_NEON_MEMORY. (arm_expand_neon_args): Rename to ... (arm_expand_builtin_args): ... this. Rename builtin_arg enum values and differentiate between ARG_BUILTIN_MEMORY and ARG_BUILTIN_NEON_MEMORY. (arm_expand_neon_builtin_1): Rename to ... (arm_expand_builtin_1): ... this. Rename builtin_arg enum values, arm_expand_builtin_args and add bool parameter NEON. (arm_expand_neon_builtin): Use arm_expand_builtin_1. (arm_expand_vfp_builtin): Likewise. (NEON_MAX_BUILTIN_ARGS): Remove, it was unused. From-SVN: r244170
-rw-r--r--gcc/ChangeLog24
-rw-r--r--gcc/config/arm/arm-builtins.c129
2 files changed, 96 insertions, 57 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 10d9412..ede69fb 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,27 @@
+2017-01-06 Andre Vieira <andre.simoesdiasvieira@arm.com>
+
+ * config/arm/arm-builtins.c (neon_builtin_datum): Rename to ..
+ (arm_builtin_datum): ... this.
+ (arm_init_neon_builtin): Rename to ...
+ (arm_init_builtin): ... this. Add a new parameters PREFIX
+ and USE_SIG_IN_NAME.
+ (arm_init_neon_builtins): Replace 'arm_init_neon_builtin' with
+ 'arm_init_builtin'. Replace type 'neon_builtin_datum' with
+ 'arm_builtin_datum'.
+ (arm_init_vfp_builtins): Likewise.
+ (builtin_arg): Rename enum's replacing 'NEON_ARG' with
+ 'ARG_BUILTIN' and add a 'ARG_BUILTIN_NEON_MEMORY.
+ (arm_expand_neon_args): Rename to ...
+ (arm_expand_builtin_args): ... this. Rename builtin_arg
+ enum values and differentiate between ARG_BUILTIN_MEMORY
+ and ARG_BUILTIN_NEON_MEMORY.
+ (arm_expand_neon_builtin_1): Rename to ...
+ (arm_expand_builtin_1): ... this. Rename builtin_arg enum
+ values, arm_expand_builtin_args and add bool parameter NEON.
+ (arm_expand_neon_builtin): Use arm_expand_builtin_1.
+ (arm_expand_vfp_builtin): Likewise.
+ (NEON_MAX_BUILTIN_ARGS): Remove, it was unused.
+
2017-01-01 Jan Hubicka <hubicka@ucw.cz>
PR middle-end/77484
diff --git a/gcc/config/arm/arm-builtins.c b/gcc/config/arm/arm-builtins.c
index 55f3387..9101ad2 100644
--- a/gcc/config/arm/arm-builtins.c
+++ b/gcc/config/arm/arm-builtins.c
@@ -203,7 +203,7 @@ typedef struct {
const enum insn_code code;
unsigned int fcode;
enum arm_type_qualifiers *qualifiers;
-} neon_builtin_datum;
+} arm_builtin_datum;
#define CF(N,X) CODE_FOR_neon_##N##X
@@ -243,7 +243,7 @@ typedef struct {
VAR11 (T, N, A, B, C, D, E, F, G, H, I, J, K) \
VAR1 (T, N, L)
-/* The NEON builtin data can be found in arm_neon_builtins.def and
+/* The builtin data can be found in arm_neon_builtins.def,
arm_vfp_builtins.def. The entries in arm_neon_builtins.def require
TARGET_NEON to be true. The feature tests are checked when the
builtins are expanded.
@@ -253,14 +253,14 @@ typedef struct {
would be specified after the assembler mnemonic, which usually
refers to the last vector operand. The modes listed per
instruction should be the same as those defined for that
- instruction's pattern in neon.md. */
+ instruction's pattern, for instance in neon.md. */
-static neon_builtin_datum vfp_builtin_data[] =
+static arm_builtin_datum vfp_builtin_data[] =
{
#include "arm_vfp_builtins.def"
};
-static neon_builtin_datum neon_builtin_data[] =
+static arm_builtin_datum neon_builtin_data[] =
{
#include "arm_neon_builtins.def"
};
@@ -919,11 +919,15 @@ arm_init_simd_builtin_scalar_types (void)
"__builtin_neon_uti");
}
-/* Set up a NEON builtin. */
+/* Set up a builtin. It will use information stored in the argument struct D to
+ derive the builtin's type signature and name. It will append the name in D
+ to the PREFIX passed and use these to create a builtin declaration that is
+ then stored in 'arm_builtin_decls' under index FCODE. This FCODE is also
+ written back to D for future use. */
static void
-arm_init_neon_builtin (unsigned int fcode,
- neon_builtin_datum *d)
+arm_init_builtin (unsigned int fcode, arm_builtin_datum *d,
+ const char * prefix)
{
bool print_type_signature_p = false;
char type_signature[SIMD_MAX_BUILTIN_ARGS] = { 0 };
@@ -1011,12 +1015,13 @@ arm_init_neon_builtin (unsigned int fcode,
gcc_assert (ftype != NULL);
- if (print_type_signature_p)
- snprintf (namebuf, sizeof (namebuf), "__builtin_neon_%s_%s",
- d->name, type_signature);
+ if (print_type_signature_p
+ && IN_RANGE (fcode, ARM_BUILTIN_VFP_BASE, ARM_BUILTIN_MAX - 1))
+ snprintf (namebuf, sizeof (namebuf), "%s_%s_%s",
+ prefix, d->name, type_signature);
else
- snprintf (namebuf, sizeof (namebuf), "__builtin_neon_%s",
- d->name);
+ snprintf (namebuf, sizeof (namebuf), "%s_%s",
+ prefix, d->name);
fndecl = add_builtin_function (namebuf, ftype, fcode, BUILT_IN_MD,
NULL, NULL_TREE);
@@ -1052,8 +1057,8 @@ arm_init_neon_builtins (void)
for (i = 0; i < ARRAY_SIZE (neon_builtin_data); i++, fcode++)
{
- neon_builtin_datum *d = &neon_builtin_data[i];
- arm_init_neon_builtin (fcode, d);
+ arm_builtin_datum *d = &neon_builtin_data[i];
+ arm_init_builtin (fcode, d, "__builtin_neon");
}
}
@@ -1066,8 +1071,8 @@ arm_init_vfp_builtins (void)
for (i = 0; i < ARRAY_SIZE (vfp_builtin_data); i++, fcode++)
{
- neon_builtin_datum *d = &vfp_builtin_data[i];
- arm_init_neon_builtin (fcode, d);
+ arm_builtin_datum *d = &vfp_builtin_data[i];
+ arm_init_builtin (fcode, d, "__builtin_neon");
}
}
@@ -2031,15 +2036,15 @@ arm_expand_unop_builtin (enum insn_code icode,
}
typedef enum {
- NEON_ARG_COPY_TO_REG,
- NEON_ARG_CONSTANT,
- NEON_ARG_LANE_INDEX,
- NEON_ARG_STRUCT_LOAD_STORE_LANE_INDEX,
- NEON_ARG_MEMORY,
- NEON_ARG_STOP
+ ARG_BUILTIN_COPY_TO_REG,
+ ARG_BUILTIN_CONSTANT,
+ ARG_BUILTIN_LANE_INDEX,
+ ARG_BUILTIN_STRUCT_LOAD_STORE_LANE_INDEX,
+ ARG_BUILTIN_NEON_MEMORY,
+ ARG_BUILTIN_MEMORY,
+ ARG_BUILTIN_STOP
} builtin_arg;
-#define NEON_MAX_BUILTIN_ARGS 5
/* EXP is a pointer argument to a Neon load or store intrinsic. Derive
and return an expression for the accessed memory.
@@ -2089,9 +2094,9 @@ neon_dereference_pointer (tree exp, tree type, machine_mode mem_mode,
build_int_cst (build_pointer_type (array_type), 0));
}
-/* Expand a Neon builtin. */
+/* Expand a builtin. */
static rtx
-arm_expand_neon_args (rtx target, machine_mode map_mode, int fcode,
+arm_expand_builtin_args (rtx target, machine_mode map_mode, int fcode,
int icode, int have_retval, tree exp,
builtin_arg *args)
{
@@ -2115,14 +2120,14 @@ arm_expand_neon_args (rtx target, machine_mode map_mode, int fcode,
{
builtin_arg thisarg = args[argc];
- if (thisarg == NEON_ARG_STOP)
+ if (thisarg == ARG_BUILTIN_STOP)
break;
else
{
int opno = argc + have_retval;
arg[argc] = CALL_EXPR_ARG (exp, argc);
mode[argc] = insn_data[icode].operand[opno].mode;
- if (thisarg == NEON_ARG_MEMORY)
+ if (thisarg == ARG_BUILTIN_NEON_MEMORY)
{
machine_mode other_mode
= insn_data[icode].operand[1 - opno].mode;
@@ -2132,15 +2137,17 @@ arm_expand_neon_args (rtx target, machine_mode map_mode, int fcode,
map_mode);
}
- /* Use EXPAND_MEMORY for NEON_ARG_MEMORY to ensure a MEM_P
- be returned. */
+ /* Use EXPAND_MEMORY for ARG_BUILTIN_MEMORY and
+ ARG_BUILTIN_NEON_MEMORY to ensure a MEM_P be returned. */
op[argc] = expand_expr (arg[argc], NULL_RTX, VOIDmode,
- (thisarg == NEON_ARG_MEMORY
+ ((thisarg == ARG_BUILTIN_MEMORY
+ || thisarg == ARG_BUILTIN_NEON_MEMORY)
? EXPAND_MEMORY : EXPAND_NORMAL));
switch (thisarg)
{
- case NEON_ARG_COPY_TO_REG:
+ case ARG_BUILTIN_MEMORY:
+ case ARG_BUILTIN_COPY_TO_REG:
if (POINTER_TYPE_P (TREE_TYPE (arg[argc])))
op[argc] = convert_memory_address (Pmode, op[argc]);
/*gcc_assert (GET_MODE (op[argc]) == mode[argc]); */
@@ -2149,7 +2156,7 @@ arm_expand_neon_args (rtx target, machine_mode map_mode, int fcode,
op[argc] = copy_to_mode_reg (mode[argc], op[argc]);
break;
- case NEON_ARG_STRUCT_LOAD_STORE_LANE_INDEX:
+ case ARG_BUILTIN_STRUCT_LOAD_STORE_LANE_INDEX:
gcc_assert (argc > 1);
if (CONST_INT_P (op[argc]))
{
@@ -2161,7 +2168,7 @@ arm_expand_neon_args (rtx target, machine_mode map_mode, int fcode,
}
goto constant_arg;
- case NEON_ARG_LANE_INDEX:
+ case ARG_BUILTIN_LANE_INDEX:
/* Previous argument must be a vector, which this indexes. */
gcc_assert (argc > 0);
if (CONST_INT_P (op[argc]))
@@ -2172,7 +2179,7 @@ arm_expand_neon_args (rtx target, machine_mode map_mode, int fcode,
/* If the lane index isn't a constant then the next
case will error. */
/* Fall through. */
- case NEON_ARG_CONSTANT:
+ case ARG_BUILTIN_CONSTANT:
constant_arg:
if (!(*insn_data[icode].operand[opno].predicate)
(op[argc], mode[argc]))
@@ -2183,7 +2190,7 @@ constant_arg:
}
break;
- case NEON_ARG_MEMORY:
+ case ARG_BUILTIN_NEON_MEMORY:
/* Check if expand failed. */
if (op[argc] == const0_rtx)
return 0;
@@ -2200,7 +2207,7 @@ constant_arg:
copy_to_mode_reg (Pmode, XEXP (op[argc], 0))));
break;
- case NEON_ARG_STOP:
+ case ARG_BUILTIN_STOP:
gcc_unreachable ();
}
@@ -2269,21 +2276,24 @@ constant_arg:
return target;
}
-/* Expand a neon builtin. This is also used for vfp builtins, which behave in
- the same way. These builtins are "special" because they don't have symbolic
- constants defined per-instruction or per instruction-variant. Instead, the
- required info is looked up in the NEON_BUILTIN_DATA record that is passed
- into the function. */
+/* Expand a builtin. These builtins are "special" because they don't have
+ symbolic constants defined per-instruction or per instruction-variant.
+ Instead, the required info is looked up in the ARM_BUILTIN_DATA record that
+ is passed into the function. */
static rtx
-arm_expand_neon_builtin_1 (int fcode, tree exp, rtx target,
- neon_builtin_datum *d)
+arm_expand_builtin_1 (int fcode, tree exp, rtx target,
+ arm_builtin_datum *d)
{
enum insn_code icode = d->code;
builtin_arg args[SIMD_MAX_BUILTIN_ARGS + 1];
int num_args = insn_data[d->code].n_operands;
int is_void = 0;
int k;
+ bool neon = false;
+
+ if (IN_RANGE (fcode, ARM_BUILTIN_VFP_BASE, ARM_BUILTIN_MAX - 1))
+ neon = true;
is_void = !!(d->qualifiers[0] & qualifier_void);
@@ -2303,11 +2313,11 @@ arm_expand_neon_builtin_1 (int fcode, tree exp, rtx target,
int expr_args_k = k - 1;
if (d->qualifiers[qualifiers_k] & qualifier_lane_index)
- args[k] = NEON_ARG_LANE_INDEX;
+ args[k] = ARG_BUILTIN_LANE_INDEX;
else if (d->qualifiers[qualifiers_k] & qualifier_struct_load_store_lane_index)
- args[k] = NEON_ARG_STRUCT_LOAD_STORE_LANE_INDEX;
+ args[k] = ARG_BUILTIN_STRUCT_LOAD_STORE_LANE_INDEX;
else if (d->qualifiers[qualifiers_k] & qualifier_immediate)
- args[k] = NEON_ARG_CONSTANT;
+ args[k] = ARG_BUILTIN_CONSTANT;
else if (d->qualifiers[qualifiers_k] & qualifier_maybe_immediate)
{
rtx arg
@@ -2318,18 +2328,23 @@ arm_expand_neon_builtin_1 (int fcode, tree exp, rtx target,
(CONST_INT_P (arg)
&& (*insn_data[icode].operand[operands_k].predicate)
(arg, insn_data[icode].operand[operands_k].mode));
- args[k] = op_const_int_p ? NEON_ARG_CONSTANT : NEON_ARG_COPY_TO_REG;
+ args[k] = op_const_int_p ? ARG_BUILTIN_CONSTANT : ARG_BUILTIN_COPY_TO_REG;
}
else if (d->qualifiers[qualifiers_k] & qualifier_pointer)
- args[k] = NEON_ARG_MEMORY;
+ {
+ if (neon)
+ args[k] = ARG_BUILTIN_NEON_MEMORY;
+ else
+ args[k] = ARG_BUILTIN_MEMORY;
+ }
else
- args[k] = NEON_ARG_COPY_TO_REG;
+ args[k] = ARG_BUILTIN_COPY_TO_REG;
}
- args[k] = NEON_ARG_STOP;
+ args[k] = ARG_BUILTIN_STOP;
- /* The interface to arm_expand_neon_args expects a 0 if
+ /* The interface to arm_expand_builtin_args expects a 0 if
the function is void, and a 1 if it is not. */
- return arm_expand_neon_args
+ return arm_expand_builtin_args
(target, d->mode, fcode, icode, !is_void, exp,
&args[1]);
}
@@ -2367,10 +2382,10 @@ arm_expand_neon_builtin (int fcode, tree exp, rtx target)
return const0_rtx;
}
- neon_builtin_datum *d
+ arm_builtin_datum *d
= &neon_builtin_data[fcode - ARM_BUILTIN_NEON_PATTERN_START];
- return arm_expand_neon_builtin_1 (fcode, exp, target, d);
+ return arm_expand_builtin_1 (fcode, exp, target, d);
}
/* Expand a VFP builtin. These builtins are treated like
@@ -2388,10 +2403,10 @@ arm_expand_vfp_builtin (int fcode, tree exp, rtx target)
return const0_rtx;
}
- neon_builtin_datum *d
+ arm_builtin_datum *d
= &vfp_builtin_data[fcode - ARM_BUILTIN_VFP_PATTERN_START];
- return arm_expand_neon_builtin_1 (fcode, exp, target, d);
+ return arm_expand_builtin_1 (fcode, exp, target, d);
}
/* Expand an expression EXP that calls a built-in function,