[PATCH 1/3] [ARM] PR63870 NEON error messages
Alan Lawrence
alan.lawrence@arm.com
Mon Jul 6 10:18:00 GMT 2015
I note some parts of this duplicate my
https://gcc.gnu.org/ml/gcc-patches/2015-01/msg01422.html , which has been pinged
a couple of times. Both Charles' patch, and my two, contain parts the other does
not...
Cheers, Alan
Charles Baylis wrote:
> gcc/ChangeLog:
>
> <DATE> Charles Baylis <charles.baylis@linaro.org>
>
> * config/arm/arm-builtins.c (enum arm_type_qualifiers): New enumerators
> qualifier_lane_index, qualifier_struct_load_store_lane_index.
> (arm_expand_neon_args): New parameter. Remove ellipsis. Handle NEON
> argument qualifiers.
> (arm_expand_neon_builtin): Handle NEON argument qualifiers.
> * config/arm/arm-protos.h: (arm_neon_lane_bounds) New prototype.
> * config/arm/arm.c (arm_neon_lane_bounds): New function.
> * config/arm/arm.h (ENDIAN_LANE_N): New macro.
>
> Change-Id: Iaa14d8736879fa53776319977eda2089f0a26647
> ---
> gcc/config/arm/arm-builtins.c | 65 ++++++++++++++++++++++++++++++++-----------
> gcc/config/arm/arm-protos.h | 4 +++
> gcc/config/arm/arm.c | 20 +++++++++++++
> gcc/config/arm/arm.h | 3 ++
> 4 files changed, 75 insertions(+), 17 deletions(-)
>
> diff --git a/gcc/config/arm/arm-builtins.c b/gcc/config/arm/arm-builtins.c
> index f960e0a..8f1253e 100644
> --- a/gcc/config/arm/arm-builtins.c
> +++ b/gcc/config/arm/arm-builtins.c
> @@ -77,7 +77,11 @@ enum arm_type_qualifiers
> /* qualifier_const_pointer | qualifier_map_mode */
> qualifier_const_pointer_map_mode = 0x86,
> /* Polynomial types. */
> - qualifier_poly = 0x100
> + qualifier_poly = 0x100,
> + /* Lane indices - must be in range, and flipped for bigendian. */
> + qualifier_lane_index = 0x200,
> + /* Lane indices for single lane structure loads and stores. */
> + qualifier_struct_load_store_lane_index = 0x400
> };
>
> /* The qualifier_internal allows generation of a unary builtin from
> @@ -1927,6 +1931,8 @@ 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
> } builtin_arg;
> @@ -1984,9 +1990,9 @@ neon_dereference_pointer (tree exp, tree type, machine_mode mem_mode,
> /* Expand a Neon builtin. */
> static rtx
> arm_expand_neon_args (rtx target, machine_mode map_mode, int fcode,
> - int icode, int have_retval, tree exp, ...)
> + int icode, int have_retval, tree exp,
> + builtin_arg *args)
> {
> - va_list ap;
> rtx pat;
> tree arg[SIMD_MAX_BUILTIN_ARGS];
> rtx op[SIMD_MAX_BUILTIN_ARGS];
> @@ -2001,13 +2007,11 @@ arm_expand_neon_args (rtx target, machine_mode map_mode, int fcode,
> || !(*insn_data[icode].operand[0].predicate) (target, tmode)))
> target = gen_reg_rtx (tmode);
>
> - va_start (ap, exp);
> -
> formals = TYPE_ARG_TYPES (TREE_TYPE (arm_builtin_decls[fcode]));
>
> for (;;)
> {
> - builtin_arg thisarg = (builtin_arg) va_arg (ap, int);
> + builtin_arg thisarg = args[argc];
>
> if (thisarg == NEON_ARG_STOP)
> break;
> @@ -2043,17 +2047,46 @@ 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:
> + gcc_assert (argc > 1);
> + if (CONST_INT_P (op[argc]))
> + {
> + arm_neon_lane_bounds (op[argc], 0,
> + GET_MODE_NUNITS (map_mode), exp);
> + /* Keep to GCC-vector-extension lane indices in the RTL. */
> + op[argc] =
> + GEN_INT (ENDIAN_LANE_N (map_mode, INTVAL (op[argc])));
> + }
> + goto constant_arg;
> +
> + case NEON_ARG_LANE_INDEX:
> + /* Must be a previous operand into which this is an index. */
> + gcc_assert (argc > 0);
> + if (CONST_INT_P (op[argc]))
> + {
> + machine_mode vmode = insn_data[icode].operand[argc - 1].mode;
> + arm_neon_lane_bounds (op[argc],
> + 0, GET_MODE_NUNITS (vmode), exp);
> + /* Keep to GCC-vector-extension lane indices in the RTL. */
> + op[argc] = GEN_INT (ENDIAN_LANE_N (vmode, INTVAL (op[argc])));
> + }
> + /* Fall through - if the lane index isn't a constant then
> + the next case will error. */
> case NEON_ARG_CONSTANT:
> +constant_arg:
> if (!(*insn_data[icode].operand[opno].predicate)
> (op[argc], mode[argc]))
> - error_at (EXPR_LOCATION (exp), "incompatible type for argument %d, "
> - "expected %<const int%>", argc + 1);
> + {
> + error ("%Kargument %d must be a constant immediate",
> + exp, argc + 1);
> + return const0_rtx;
> + }
> break;
> +
> case NEON_ARG_MEMORY:
> /* Check if expand failed. */
> if (op[argc] == const0_rtx)
> {
> - va_end (ap);
> return 0;
> }
> gcc_assert (MEM_P (op[argc]));
> @@ -2076,8 +2109,6 @@ arm_expand_neon_args (rtx target, machine_mode map_mode, int fcode,
> }
> }
>
> - va_end (ap);
> -
> if (have_retval)
> switch (argc)
> {
> @@ -2170,7 +2201,11 @@ arm_expand_neon_builtin (int fcode, tree exp, rtx target)
> int operands_k = k - is_void;
> int expr_args_k = k - 1;
>
> - if (d->qualifiers[qualifiers_k] & qualifier_immediate)
> + if (d->qualifiers[qualifiers_k] & qualifier_lane_index)
> + args[k] = NEON_ARG_LANE_INDEX;
> + else if (d->qualifiers[qualifiers_k] & qualifier_struct_load_store_lane_index)
> + args[k] = NEON_ARG_STRUCT_LOAD_STORE_LANE_INDEX;
> + else if (d->qualifiers[qualifiers_k] & qualifier_immediate)
> args[k] = NEON_ARG_CONSTANT;
> else if (d->qualifiers[qualifiers_k] & qualifier_maybe_immediate)
> {
> @@ -2195,11 +2230,7 @@ arm_expand_neon_builtin (int fcode, tree exp, rtx target)
> the function is void, and a 1 if it is not. */
> return arm_expand_neon_args
> (target, d->mode, fcode, icode, !is_void, exp,
> - args[1],
> - args[2],
> - args[3],
> - args[4],
> - NEON_ARG_STOP);
> + &args[1]);
> }
>
> /* Expand an expression EXP that calls a built-in function,
> diff --git a/gcc/config/arm/arm-protos.h b/gcc/config/arm/arm-protos.h
> index 62f91ef..0b4bef5 100644
> --- a/gcc/config/arm/arm-protos.h
> +++ b/gcc/config/arm/arm-protos.h
> @@ -343,6 +343,10 @@ extern void arm_cpu_builtins (struct cpp_reader *, int);
>
> extern bool arm_is_constant_pool_ref (rtx);
>
> +void arm_neon_lane_bounds (rtx operand, HOST_WIDE_INT low, HOST_WIDE_INT high,
> + const_tree exp);
> +
> +
> /* Flags used to identify the presence of processor capabilities. */
>
> /* Bit values used to identify processor capabilities. */
> diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
> index d794fc0..2cbfd64 100644
> --- a/gcc/config/arm/arm.c
> +++ b/gcc/config/arm/arm.c
> @@ -29652,4 +29652,24 @@ arm_sched_fusion_priority (rtx_insn *insn, int max_pri,
> *pri = tmp;
> return;
> }
> +
> +/* Bounds-check lanes. Ensure OPERAND lies between LOW (inclusive) and
> + HIGH (exclusive). */
> +void
> +arm_neon_lane_bounds (rtx operand, HOST_WIDE_INT low, HOST_WIDE_INT high,
> + const_tree exp)
> +{
> + HOST_WIDE_INT lane;
> + gcc_assert (CONST_INT_P (operand));
> + lane = INTVAL (operand);
> +
> + if (lane < low || lane >= high)
> + {
> + if (exp)
> + error ("%Klane %ld out of range %ld - %ld", exp, lane, low, high - 1);
> + else
> + error ("lane %ld out of range %ld - %ld", lane, low, high - 1);
> + }
> +}
> +
> #include "gt-arm.h"
> diff --git a/gcc/config/arm/arm.h b/gcc/config/arm/arm.h
> index 373dc85..1a55ac8 100644
> --- a/gcc/config/arm/arm.h
> +++ b/gcc/config/arm/arm.h
> @@ -298,6 +298,9 @@ extern void (*arm_lang_output_object_attributes_hook)(void);
> #define TARGET_BPABI false
> #endif
>
> +#define ENDIAN_LANE_N(mode, n) \
> + (BYTES_BIG_ENDIAN ? GET_MODE_NUNITS (mode) - 1 - n : n)
> +
> /* Support for a compile-time default CPU, et cetera. The rules are:
> --with-arch is ignored if -march or -mcpu are specified.
> --with-cpu is ignored if -march or -mcpu are specified, and is overridden
> --
> 1.9.1
>
>
More information about the Gcc-patches
mailing list