mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-04-13 13:41:12 +08:00
[PATCH][AArch64] Add BIC-imm and ORR-imm SIMD pattern
This patch adds the support for BIC (vector, immediate) and ORR (vector, immediate) SIMD patterns to the AArch64 backend. Committed on behalf of Sudi Das. Reviewed-by: Richard Earnshaw <Richard.Earnshaw@arm.com> Reviewed-by: James Greenhalgh <james.greenhalgh@arm.com> gcc/ * config/aarch64/aarch64-protos.h (enum simd_immediate_check): New check type for aarch64_simd_valid_immediate. (aarch64_output_simd_mov_immediate): Update prototype. (aarch64_simd_valid_immediate): Update prototype. * config/aarch64/aarch64-simd.md (orr<mode>3): modified pattern to add support for ORR-immediate. (and<mode>3): modified pattern to add support for BIC-immediate. * config/aarch64/aarch64.c (aarch64_simd_valid_immediate): Function now checks for valid immediate for BIC and ORR based on new enum argument. (aarch64_output_simd_mov_immediate): Function now used to output BIC/ORR imm as well based on new enum argument. * config/aarch64/constraints.md (Do): New vector immediate constraint. (Db) : Likewise. * config/aarch64/predicates.md (aarch64_reg_or_orr_imm): New predicate. (aarch64_reg_or_bic_imm): Likewise. gcc/testsuite/ * gcc.target/aarch64/bic_imm_1.c: New test. * gcc.target/aarch64/orr_imm_1.c: Likewise. From-SVN: r253422
This commit is contained in:
parent
b419102c12
commit
ab6501d713
gcc
@ -1,3 +1,22 @@
|
||||
2017-10-04 Sudakshina Das <sudi.das@arm.com>
|
||||
|
||||
* config/aarch64/aarch64-protos.h (enum simd_immediate_check): New
|
||||
check type for aarch64_simd_valid_immediate.
|
||||
(aarch64_output_simd_mov_immediate): Update prototype.
|
||||
(aarch64_simd_valid_immediate): Update prototype.
|
||||
* config/aarch64/aarch64-simd.md (orr<mode>3): modified pattern to add
|
||||
support for ORR-immediate.
|
||||
(and<mode>3): modified pattern to add support for BIC-immediate.
|
||||
* config/aarch64/aarch64.c (aarch64_simd_valid_immediate): Function
|
||||
now checks for valid immediate for BIC and ORR based on new enum
|
||||
argument.
|
||||
(aarch64_output_simd_mov_immediate): Function now used to output
|
||||
BIC/ORR imm as well based on new enum argument.
|
||||
* config/aarch64/constraints.md (Do): New vector immediate constraint.
|
||||
(Db) : Likewise.
|
||||
* config/aarch64/predicates.md (aarch64_reg_or_orr_imm): New predicate.
|
||||
(aarch64_reg_or_bic_imm): Likewise.
|
||||
|
||||
2017-10-04 Andreas Krebbel <krebbel@linux.vnet.ibm.com>
|
||||
|
||||
* config/s390/vx-builtins.md ("vec_mergeh<mode>")
|
||||
|
@ -308,6 +308,16 @@ enum aarch64_parse_opt_result
|
||||
AARCH64_PARSE_INVALID_ARG /* Invalid arch, tune, cpu arg. */
|
||||
};
|
||||
|
||||
/* Enum to distinguish which type of check is to be done in
|
||||
aarch64_simd_valid_immediate. This is used as a bitmask where
|
||||
AARCH64_CHECK_MOV has both bits set. Thus AARCH64_CHECK_MOV will
|
||||
perform all checks. Adding new types would require changes accordingly. */
|
||||
enum simd_immediate_check {
|
||||
AARCH64_CHECK_ORR = 1 << 0,
|
||||
AARCH64_CHECK_BIC = 1 << 1,
|
||||
AARCH64_CHECK_MOV = AARCH64_CHECK_ORR | AARCH64_CHECK_BIC
|
||||
};
|
||||
|
||||
extern struct tune_params aarch64_tune_params;
|
||||
|
||||
HOST_WIDE_INT aarch64_initial_elimination_offset (unsigned, unsigned);
|
||||
@ -345,7 +355,8 @@ bool aarch64_mov_operand_p (rtx, machine_mode);
|
||||
rtx aarch64_reverse_mask (machine_mode);
|
||||
bool aarch64_offset_7bit_signed_scaled_p (machine_mode, HOST_WIDE_INT);
|
||||
char *aarch64_output_scalar_simd_mov_immediate (rtx, scalar_int_mode);
|
||||
char *aarch64_output_simd_mov_immediate (rtx, machine_mode, unsigned);
|
||||
char *aarch64_output_simd_mov_immediate (rtx, machine_mode, unsigned,
|
||||
enum simd_immediate_check w = AARCH64_CHECK_MOV);
|
||||
bool aarch64_pad_reg_upward (machine_mode, const_tree, bool);
|
||||
bool aarch64_regno_ok_for_base_p (int, bool);
|
||||
bool aarch64_regno_ok_for_index_p (int, bool);
|
||||
@ -356,7 +367,8 @@ bool aarch64_simd_imm_zero_p (rtx, machine_mode);
|
||||
bool aarch64_simd_scalar_immediate_valid_for_move (rtx, scalar_int_mode);
|
||||
bool aarch64_simd_shift_imm_p (rtx, machine_mode, bool);
|
||||
bool aarch64_simd_valid_immediate (rtx, machine_mode, bool,
|
||||
struct simd_immediate_info *);
|
||||
struct simd_immediate_info *,
|
||||
enum simd_immediate_check w = AARCH64_CHECK_MOV);
|
||||
bool aarch64_split_dimode_const_store (rtx, rtx);
|
||||
bool aarch64_symbolic_address_p (rtx);
|
||||
bool aarch64_uimm12_shift (HOST_WIDE_INT);
|
||||
|
@ -558,21 +558,45 @@
|
||||
[(set_attr "type" "neon_fp_abd_<stype><q>")]
|
||||
)
|
||||
|
||||
;; For AND (vector, register) and BIC (vector, immediate)
|
||||
(define_insn "and<mode>3"
|
||||
[(set (match_operand:VDQ_I 0 "register_operand" "=w")
|
||||
(and:VDQ_I (match_operand:VDQ_I 1 "register_operand" "w")
|
||||
(match_operand:VDQ_I 2 "register_operand" "w")))]
|
||||
[(set (match_operand:VDQ_I 0 "register_operand" "=w,w")
|
||||
(and:VDQ_I (match_operand:VDQ_I 1 "register_operand" "w,0")
|
||||
(match_operand:VDQ_I 2 "aarch64_reg_or_bic_imm" "w,Db")))]
|
||||
"TARGET_SIMD"
|
||||
"and\t%0.<Vbtype>, %1.<Vbtype>, %2.<Vbtype>"
|
||||
{
|
||||
switch (which_alternative)
|
||||
{
|
||||
case 0:
|
||||
return "and\t%0.<Vbtype>, %1.<Vbtype>, %2.<Vbtype>";
|
||||
case 1:
|
||||
return aarch64_output_simd_mov_immediate (operands[2],
|
||||
<MODE>mode, GET_MODE_BITSIZE (<MODE>mode), AARCH64_CHECK_BIC);
|
||||
default:
|
||||
gcc_unreachable ();
|
||||
}
|
||||
}
|
||||
[(set_attr "type" "neon_logic<q>")]
|
||||
)
|
||||
|
||||
;; For ORR (vector, register) and ORR (vector, immediate)
|
||||
(define_insn "ior<mode>3"
|
||||
[(set (match_operand:VDQ_I 0 "register_operand" "=w")
|
||||
(ior:VDQ_I (match_operand:VDQ_I 1 "register_operand" "w")
|
||||
(match_operand:VDQ_I 2 "register_operand" "w")))]
|
||||
[(set (match_operand:VDQ_I 0 "register_operand" "=w,w")
|
||||
(ior:VDQ_I (match_operand:VDQ_I 1 "register_operand" "w,0")
|
||||
(match_operand:VDQ_I 2 "aarch64_reg_or_orr_imm" "w,Do")))]
|
||||
"TARGET_SIMD"
|
||||
"orr\t%0.<Vbtype>, %1.<Vbtype>, %2.<Vbtype>"
|
||||
{
|
||||
switch (which_alternative)
|
||||
{
|
||||
case 0:
|
||||
return "orr\t%0.<Vbtype>, %1.<Vbtype>, %2.<Vbtype>";
|
||||
case 1:
|
||||
return aarch64_output_simd_mov_immediate (operands[2],
|
||||
<MODE>mode, GET_MODE_BITSIZE (<MODE>mode), AARCH64_CHECK_ORR);
|
||||
default:
|
||||
gcc_unreachable ();
|
||||
}
|
||||
}
|
||||
[(set_attr "type" "neon_logic<q>")]
|
||||
)
|
||||
|
||||
|
@ -11483,7 +11483,8 @@ aarch64_vect_float_const_representable_p (rtx x)
|
||||
/* Return true for valid and false for invalid. */
|
||||
bool
|
||||
aarch64_simd_valid_immediate (rtx op, machine_mode mode, bool inverse,
|
||||
struct simd_immediate_info *info)
|
||||
struct simd_immediate_info *info,
|
||||
enum simd_immediate_check which)
|
||||
{
|
||||
#define CHECK(STRIDE, ELSIZE, CLASS, TEST, SHIFT, NEG) \
|
||||
matches = 1; \
|
||||
@ -11551,54 +11552,65 @@ aarch64_simd_valid_immediate (rtx op, machine_mode mode, bool inverse,
|
||||
|
||||
do
|
||||
{
|
||||
CHECK (4, 32, 0, bytes[i] == bytes[0] && bytes[i + 1] == 0
|
||||
&& bytes[i + 2] == 0 && bytes[i + 3] == 0, 0, 0);
|
||||
if (which & AARCH64_CHECK_ORR)
|
||||
{
|
||||
CHECK (4, 32, 0, bytes[i] == bytes[0] && bytes[i + 1] == 0
|
||||
&& bytes[i + 2] == 0 && bytes[i + 3] == 0, 0, 0);
|
||||
|
||||
CHECK (4, 32, 1, bytes[i] == 0 && bytes[i + 1] == bytes[1]
|
||||
&& bytes[i + 2] == 0 && bytes[i + 3] == 0, 8, 0);
|
||||
CHECK (4, 32, 1, bytes[i] == 0 && bytes[i + 1] == bytes[1]
|
||||
&& bytes[i + 2] == 0 && bytes[i + 3] == 0, 8, 0);
|
||||
|
||||
CHECK (4, 32, 2, bytes[i] == 0 && bytes[i + 1] == 0
|
||||
&& bytes[i + 2] == bytes[2] && bytes[i + 3] == 0, 16, 0);
|
||||
CHECK (4, 32, 2, bytes[i] == 0 && bytes[i + 1] == 0
|
||||
&& bytes[i + 2] == bytes[2] && bytes[i + 3] == 0, 16, 0);
|
||||
|
||||
CHECK (4, 32, 3, bytes[i] == 0 && bytes[i + 1] == 0
|
||||
&& bytes[i + 2] == 0 && bytes[i + 3] == bytes[3], 24, 0);
|
||||
CHECK (4, 32, 3, bytes[i] == 0 && bytes[i + 1] == 0
|
||||
&& bytes[i + 2] == 0 && bytes[i + 3] == bytes[3], 24, 0);
|
||||
|
||||
CHECK (2, 16, 4, bytes[i] == bytes[0] && bytes[i + 1] == 0, 0, 0);
|
||||
CHECK (2, 16, 4, bytes[i] == bytes[0] && bytes[i + 1] == 0, 0, 0);
|
||||
|
||||
CHECK (2, 16, 5, bytes[i] == 0 && bytes[i + 1] == bytes[1], 8, 0);
|
||||
CHECK (2, 16, 5, bytes[i] == 0 && bytes[i + 1] == bytes[1], 8, 0);
|
||||
}
|
||||
|
||||
CHECK (4, 32, 6, bytes[i] == bytes[0] && bytes[i + 1] == 0xff
|
||||
&& bytes[i + 2] == 0xff && bytes[i + 3] == 0xff, 0, 1);
|
||||
if (which & AARCH64_CHECK_BIC)
|
||||
{
|
||||
CHECK (4, 32, 6, bytes[i] == bytes[0] && bytes[i + 1] == 0xff
|
||||
&& bytes[i + 2] == 0xff && bytes[i + 3] == 0xff, 0, 1);
|
||||
|
||||
CHECK (4, 32, 7, bytes[i] == 0xff && bytes[i + 1] == bytes[1]
|
||||
&& bytes[i + 2] == 0xff && bytes[i + 3] == 0xff, 8, 1);
|
||||
CHECK (4, 32, 7, bytes[i] == 0xff && bytes[i + 1] == bytes[1]
|
||||
&& bytes[i + 2] == 0xff && bytes[i + 3] == 0xff, 8, 1);
|
||||
|
||||
CHECK (4, 32, 8, bytes[i] == 0xff && bytes[i + 1] == 0xff
|
||||
&& bytes[i + 2] == bytes[2] && bytes[i + 3] == 0xff, 16, 1);
|
||||
CHECK (4, 32, 8, bytes[i] == 0xff && bytes[i + 1] == 0xff
|
||||
&& bytes[i + 2] == bytes[2] && bytes[i + 3] == 0xff, 16, 1);
|
||||
|
||||
CHECK (4, 32, 9, bytes[i] == 0xff && bytes[i + 1] == 0xff
|
||||
&& bytes[i + 2] == 0xff && bytes[i + 3] == bytes[3], 24, 1);
|
||||
CHECK (4, 32, 9, bytes[i] == 0xff && bytes[i + 1] == 0xff
|
||||
&& bytes[i + 2] == 0xff && bytes[i + 3] == bytes[3], 24, 1);
|
||||
|
||||
CHECK (2, 16, 10, bytes[i] == bytes[0] && bytes[i + 1] == 0xff, 0, 1);
|
||||
CHECK (2, 16, 10, bytes[i] == bytes[0] && bytes[i + 1] == 0xff, 0, 1);
|
||||
|
||||
CHECK (2, 16, 11, bytes[i] == 0xff && bytes[i + 1] == bytes[1], 8, 1);
|
||||
CHECK (2, 16, 11, bytes[i] == 0xff && bytes[i + 1] == bytes[1], 8, 1);
|
||||
}
|
||||
|
||||
CHECK (4, 32, 12, bytes[i] == 0xff && bytes[i + 1] == bytes[1]
|
||||
&& bytes[i + 2] == 0 && bytes[i + 3] == 0, 8, 0);
|
||||
/* Shifting ones / 8-bit / 64-bit variants only checked
|
||||
for 'ALL' (MOVI/MVNI). */
|
||||
if (which == AARCH64_CHECK_MOV)
|
||||
{
|
||||
CHECK (4, 32, 12, bytes[i] == 0xff && bytes[i + 1] == bytes[1]
|
||||
&& bytes[i + 2] == 0 && bytes[i + 3] == 0, 8, 0);
|
||||
|
||||
CHECK (4, 32, 13, bytes[i] == 0 && bytes[i + 1] == bytes[1]
|
||||
&& bytes[i + 2] == 0xff && bytes[i + 3] == 0xff, 8, 1);
|
||||
CHECK (4, 32, 13, bytes[i] == 0 && bytes[i + 1] == bytes[1]
|
||||
&& bytes[i + 2] == 0xff && bytes[i + 3] == 0xff, 8, 1);
|
||||
|
||||
CHECK (4, 32, 14, bytes[i] == 0xff && bytes[i + 1] == 0xff
|
||||
&& bytes[i + 2] == bytes[2] && bytes[i + 3] == 0, 16, 0);
|
||||
CHECK (4, 32, 14, bytes[i] == 0xff && bytes[i + 1] == 0xff
|
||||
&& bytes[i + 2] == bytes[2] && bytes[i + 3] == 0, 16, 0);
|
||||
|
||||
CHECK (4, 32, 15, bytes[i] == 0 && bytes[i + 1] == 0
|
||||
&& bytes[i + 2] == bytes[2] && bytes[i + 3] == 0xff, 16, 1);
|
||||
CHECK (4, 32, 15, bytes[i] == 0 && bytes[i + 1] == 0
|
||||
&& bytes[i + 2] == bytes[2] && bytes[i + 3] == 0xff, 16, 1);
|
||||
|
||||
CHECK (1, 8, 16, bytes[i] == bytes[0], 0, 0);
|
||||
CHECK (1, 8, 16, bytes[i] == bytes[0], 0, 0);
|
||||
|
||||
CHECK (1, 64, 17, (bytes[i] == 0 || bytes[i] == 0xff)
|
||||
&& bytes[i] == bytes[(i + 8) % idx], 0, 0);
|
||||
CHECK (1, 64, 17, (bytes[i] == 0 || bytes[i] == 0xff)
|
||||
&& bytes[i] == bytes[(i + 8) % idx], 0, 0);
|
||||
}
|
||||
}
|
||||
while (0);
|
||||
|
||||
@ -13000,10 +13012,14 @@ aarch64_float_const_representable_p (rtx x)
|
||||
return (exponent >= 0 && exponent <= 7);
|
||||
}
|
||||
|
||||
/* Returns the string with the instruction for AdvSIMD MOVI, MVNI, ORR or BIC
|
||||
immediate with a CONST_VECTOR of MODE and WIDTH. WHICH selects whether to
|
||||
output MOVI/MVNI, ORR or BIC immediate. */
|
||||
char*
|
||||
aarch64_output_simd_mov_immediate (rtx const_vector,
|
||||
machine_mode mode,
|
||||
unsigned width)
|
||||
unsigned width,
|
||||
enum simd_immediate_check which)
|
||||
{
|
||||
bool is_valid;
|
||||
static char templ[40];
|
||||
@ -13015,9 +13031,11 @@ aarch64_output_simd_mov_immediate (rtx const_vector,
|
||||
struct simd_immediate_info info = { NULL_RTX, 0, 0, false, false };
|
||||
|
||||
/* This will return true to show const_vector is legal for use as either
|
||||
a AdvSIMD MOVI instruction (or, implicitly, MVNI) immediate. It will
|
||||
also update INFO to show how the immediate should be generated. */
|
||||
is_valid = aarch64_simd_valid_immediate (const_vector, mode, false, &info);
|
||||
a AdvSIMD MOVI instruction (or, implicitly, MVNI), ORR or BIC immediate.
|
||||
It will also update INFO to show how the immediate should be generated.
|
||||
WHICH selects whether to check for MOVI/MVNI, ORR or BIC. */
|
||||
is_valid = aarch64_simd_valid_immediate (const_vector, mode, false,
|
||||
&info, which);
|
||||
gcc_assert (is_valid);
|
||||
|
||||
element_char = sizetochar (info.element_width);
|
||||
@ -13048,20 +13066,37 @@ aarch64_output_simd_mov_immediate (rtx const_vector,
|
||||
}
|
||||
}
|
||||
|
||||
mnemonic = info.mvn ? "mvni" : "movi";
|
||||
shift_op = info.msl ? "msl" : "lsl";
|
||||
|
||||
gcc_assert (CONST_INT_P (info.value));
|
||||
if (lane_count == 1)
|
||||
snprintf (templ, sizeof (templ), "%s\t%%d0, " HOST_WIDE_INT_PRINT_HEX,
|
||||
mnemonic, UINTVAL (info.value));
|
||||
else if (info.shift)
|
||||
snprintf (templ, sizeof (templ), "%s\t%%0.%d%c, " HOST_WIDE_INT_PRINT_HEX
|
||||
", %s %d", mnemonic, lane_count, element_char,
|
||||
UINTVAL (info.value), shift_op, info.shift);
|
||||
|
||||
if (which == AARCH64_CHECK_MOV)
|
||||
{
|
||||
mnemonic = info.mvn ? "mvni" : "movi";
|
||||
shift_op = info.msl ? "msl" : "lsl";
|
||||
if (lane_count == 1)
|
||||
snprintf (templ, sizeof (templ), "%s\t%%d0, " HOST_WIDE_INT_PRINT_HEX,
|
||||
mnemonic, UINTVAL (info.value));
|
||||
else if (info.shift)
|
||||
snprintf (templ, sizeof (templ), "%s\t%%0.%d%c, "
|
||||
HOST_WIDE_INT_PRINT_HEX ", %s %d", mnemonic, lane_count,
|
||||
element_char, UINTVAL (info.value), shift_op, info.shift);
|
||||
else
|
||||
snprintf (templ, sizeof (templ), "%s\t%%0.%d%c, "
|
||||
HOST_WIDE_INT_PRINT_HEX, mnemonic, lane_count,
|
||||
element_char, UINTVAL (info.value));
|
||||
}
|
||||
else
|
||||
snprintf (templ, sizeof (templ), "%s\t%%0.%d%c, " HOST_WIDE_INT_PRINT_HEX,
|
||||
mnemonic, lane_count, element_char, UINTVAL (info.value));
|
||||
{
|
||||
/* For AARCH64_CHECK_BIC and AARCH64_CHECK_ORR. */
|
||||
mnemonic = info.mvn ? "bic" : "orr";
|
||||
if (info.shift)
|
||||
snprintf (templ, sizeof (templ), "%s\t%%0.%d%c, #"
|
||||
HOST_WIDE_INT_PRINT_DEC ", %s #%d", mnemonic, lane_count,
|
||||
element_char, UINTVAL (info.value), "lsl", info.shift);
|
||||
else
|
||||
snprintf (templ, sizeof (templ), "%s\t%%0.%d%c, #"
|
||||
HOST_WIDE_INT_PRINT_DEC, mnemonic, lane_count,
|
||||
element_char, UINTVAL (info.value));
|
||||
}
|
||||
return templ;
|
||||
}
|
||||
|
||||
|
@ -190,6 +190,20 @@
|
||||
(and (match_code "const_double")
|
||||
(match_test "aarch64_can_const_movi_rtx_p (op, GET_MODE (op))")))
|
||||
|
||||
(define_constraint "Do"
|
||||
"@internal
|
||||
A constraint that matches vector of immediates for orr."
|
||||
(and (match_code "const_vector")
|
||||
(match_test "aarch64_simd_valid_immediate (op, mode, false,
|
||||
NULL, AARCH64_CHECK_ORR)")))
|
||||
|
||||
(define_constraint "Db"
|
||||
"@internal
|
||||
A constraint that matches vector of immediates for bic."
|
||||
(and (match_code "const_vector")
|
||||
(match_test "aarch64_simd_valid_immediate (op, mode, false,
|
||||
NULL, AARCH64_CHECK_BIC)")))
|
||||
|
||||
(define_constraint "Dn"
|
||||
"@internal
|
||||
A constraint that matches vector of immediates."
|
||||
|
@ -69,6 +69,16 @@
|
||||
(ior (match_test "op == constm1_rtx")
|
||||
(match_test "op == const1_rtx"))))))
|
||||
|
||||
(define_predicate "aarch64_reg_or_orr_imm"
|
||||
(ior (match_operand 0 "register_operand")
|
||||
(match_test "aarch64_simd_valid_immediate (op, mode, false,
|
||||
NULL, AARCH64_CHECK_ORR)")))
|
||||
|
||||
(define_predicate "aarch64_reg_or_bic_imm"
|
||||
(ior (match_operand 0 "register_operand")
|
||||
(match_test "aarch64_simd_valid_immediate (op, mode, false,
|
||||
NULL, AARCH64_CHECK_BIC)")))
|
||||
|
||||
(define_predicate "aarch64_fp_compare_operand"
|
||||
(ior (match_operand 0 "register_operand")
|
||||
(and (match_code "const_double")
|
||||
|
@ -1,3 +1,8 @@
|
||||
2017-10-04 Sudakshina Das <sudi.das@arm.com>
|
||||
|
||||
* gcc.target/aarch64/bic_imm_1.c: New.
|
||||
* gcc.target/aarch64/orr_imm_1.c: Likewise.
|
||||
|
||||
2017-10-04 Nathan Sidwell <nathan@acm.org>
|
||||
|
||||
* g++.dg/abi/mangle41.C: Adjust diagnostics.
|
||||
|
Loading…
x
Reference in New Issue
Block a user