On 02/10/17 10:05, Sudi Das wrote: > > Hi Richard > > Thanks, I have made the change to the patch. > > > 2017-10-02 Sudakshina Das <sudi....@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-02 Sudakshina Das <sudi....@arm.com> > > * gcc.target/aarch64/bic_imm_1.c: New test. > * gcc.target/aarch64/orr_imm_1.c: Likewise. >
OK. R. > > From: Richard Earnshaw (lists) <richard.earns...@arm.com> > Sent: Thursday, September 28, 2017 9:55 AM > To: Sudi Das; James Greenhalgh > Cc: gcc-patches@gcc.gnu.org; nd; Marcus Shawcroft > Subject: Re: [PATCH][AArch64] Add BIC-imm and ORR-imm SIMD pattern > > On 27/09/17 18:57, Sudi Das wrote: >> >> >> Hi James >> >> I have made the requested changes to the patch. >> >> >> 2017-09-27 Sudakshina Das <sudi....@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. >> >> 2017-09-27 Sudakshina Das <sudi....@arm.com> >> >> * gcc.target/aarch64/bic_imm_1.c: New test. >> * gcc.target/aarch64/orr_imm_1.c: Likewise. >> >> >> Thanks >> Sudi >> >> >> From: James Greenhalgh <james.greenha...@arm.com> >> Sent: Tuesday, September 26, 2017 8:04:38 PM >> To: Sudi Das >> Cc: Richard Earnshaw; gcc-patches@gcc.gnu.org; nd; Marcus Shawcroft >> Subject: Re: [PATCH][AArch64] Add BIC-imm and ORR-imm SIMD pattern >> >> On Mon, Sep 25, 2017 at 11:13:57AM +0100, Sudi Das wrote: >>> >>> Hi James >>> >>> I put aarch64_output_simd_general_immediate looking at the similarities of >>> the immediates for mov/mvni and orr/bic. The CHECK macro in >>> aarch64_simd_valid_immediate both checks >>> and converts the immediates in a manner that are needed for the >>> instructions. >>> >>> Having said that, I agree that maybe I could have refactored >>> aarch64_output_simd_mov_immediate to do the work rather than creating a new >>> functions to do similar things. I have done so in this patch. >> >> Thanks, this looks much neater. >> >>> I have also changed the names of the enum simd_immediate_check to be better >>> indicative of what they are doing. >> >> Thanks, I'd tweak them to look more like the bitmasks you use them as, but >> that is a small change for my personal preference. >> >>> Lastly I have added more cases in the tests (according to all the possible >>> CHECKs) and made them dg-do assemble (although I had to add --save-temps so >>> that the scan-assembler would work). Do you think I should not put that >>> option and rather create separate tests? >> >> This is good - thanks. >> >> I think clean up the enum definitions and this patch will be good. >> >>> @@ -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, /* Perform immediate checks for ORR. */ >>> + AARCH64_CHECK_BIC = 2, /* Perform immediate checks for BIC. */ >>> + AARCH64_CHECK_MOV = 3 /* Perform all checks (used for MOVI/MNVI). >>> */ >> >> These are used in bit-mask style, so how about: >> >> AARCH64_CHECK_ORR = 1 << 0, >> AARCH64_CHECK_BIC = 1 << 1, >> AARCH64_CHECK_MOV = AARCH64_CHECK_ORR | AARCH64_CHECK_BIC >> >> Which is more self-documenting. >> >>> @@ -13001,7 +13013,8 @@ aarch64_float_const_representable_p (rtx x) >>> char* >>> aarch64_output_simd_mov_immediate (rtx const_vector, >>> machine_mode mode, >>> - unsigned width) >>> + unsigned width, >>> + enum simd_immediate_check which) >> >> This function is sorely missing a comment explaining the parameters - it >> would be very helpful if you could add one as part of this patch. >> >> Thanks, >> James >> >> >> > +;; 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 "nonmemory_operand" "w,Db")))] > > You should define a new predicate operation for operand 2 that accepts > just registers or the valid constants. Otherwise you'll may get > spilling during register allocation. > > Similarly for the other pattern. > > R. > > > > patch-7260-6.diff > > > diff --git a/gcc/config/aarch64/aarch64-protos.h > b/gcc/config/aarch64/aarch64-protos.h > index e67c2ed..5d7c5df 100644 > --- a/gcc/config/aarch64/aarch64-protos.h > +++ b/gcc/config/aarch64/aarch64-protos.h > @@ -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); > diff --git a/gcc/config/aarch64/aarch64-simd.md > b/gcc/config/aarch64/aarch64-simd.md > index 70e9339..12da8be 100644 > --- a/gcc/config/aarch64/aarch64-simd.md > +++ b/gcc/config/aarch64/aarch64-simd.md > @@ -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>")] > ) > > diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c > index 5e26cb7..6a6b3d5 100644 > --- a/gcc/config/aarch64/aarch64.c > +++ b/gcc/config/aarch64/aarch64.c > @@ -11471,7 +11471,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; \ > @@ -11539,54 +11540,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); > > @@ -12998,10 +13010,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]; > @@ -13013,9 +13029,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); > @@ -13046,20 +13064,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; > } > > diff --git a/gcc/config/aarch64/constraints.md > b/gcc/config/aarch64/constraints.md > index 3649fb4..77c510c 100644 > --- a/gcc/config/aarch64/constraints.md > +++ b/gcc/config/aarch64/constraints.md > @@ -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." > diff --git a/gcc/config/aarch64/predicates.md > b/gcc/config/aarch64/predicates.md > index 11243c4..887a13e 100644 > --- a/gcc/config/aarch64/predicates.md > +++ b/gcc/config/aarch64/predicates.md > @@ -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") > diff --git a/gcc/testsuite/gcc.target/aarch64/bic_imm_1.c > b/gcc/testsuite/gcc.target/aarch64/bic_imm_1.c > new file mode 100644 > index 0000000..b14f009 > --- /dev/null > +++ b/gcc/testsuite/gcc.target/aarch64/bic_imm_1.c > @@ -0,0 +1,56 @@ > +/* { dg-do assemble } */ > +/* { dg-options "-O2 --save-temps -ftree-vectorize" } */ > + > +/* Each function uses the correspoding 'CLASS' in > + Marco CHECK (aarch64_simd_valid_immediate). */ > + > +void > +bic_6 (int *a) > +{ > + for (int i = 0; i < 1024; i++) > + a[i] &= ~(0xab); > +} > + > +void > +bic_7 (int *a) > +{ > + for (int i = 0; i < 1024; i++) > + a[i] &= ~(0xcd00); > +} > + > +void > +bic_8 (int *a) > +{ > + for (int i = 0; i < 1024; i++) > + a[i] &= ~(0xef0000); > +} > + > +void > +bic_9 (int *a) > +{ > + for (int i = 0; i < 1024; i++) > + a[i] &= ~(0x12000000); > +} > + > +void > +bic_10 (short *a) > +{ > + for (int i = 0; i < 1024; i++) > + a[i] &= ~(0x34); > +} > + > + > +void > +bic_11 (short *a) > +{ > + for (int i = 0; i < 1024; i++) > + a[i] &= ~(0x5600); > +} > + > + > +/* { dg-final { scan-assembler "bic\\tv\[0-9\]+.4s, #171" } } */ > +/* { dg-final { scan-assembler "bic\\tv\[0-9\]+.4s, #205, lsl #8" } } */ > +/* { dg-final { scan-assembler "bic\\tv\[0-9\]+.4s, #239, lsl #16" } } */ > +/* { dg-final { scan-assembler "bic\\tv\[0-9\]+.4s, #18, lsl #24" } } */ > +/* { dg-final { scan-assembler "bic\\tv\[0-9\]+.8h, #52" } } */ > +/* { dg-final { scan-assembler "bic\\tv\[0-9\]+.8h, #86, lsl #8" } } */ > diff --git a/gcc/testsuite/gcc.target/aarch64/orr_imm_1.c > b/gcc/testsuite/gcc.target/aarch64/orr_imm_1.c > new file mode 100644 > index 0000000..ff6f683 > --- /dev/null > +++ b/gcc/testsuite/gcc.target/aarch64/orr_imm_1.c > @@ -0,0 +1,54 @@ > +/* { dg-do assemble } */ > +/* { dg-options "-O2 --save-temps -ftree-vectorize" } */ > + > +/* Each function uses the correspoding 'CLASS' in > + Marco CHECK (aarch64_simd_valid_immediate). */ > + > +void > +orr_0 (int *a) > +{ > + for (int i = 0; i < 1024; i++) > + a[i] |= 0xab; > +} > + > +void > +orr_1 (int *a) > +{ > + for (int i = 0; i < 1024; i++) > + a[i] |= 0x0000cd00; > +} > + > +void > +orr_2 (int *a) > +{ > + for (int i = 0; i < 1024; i++) > + a[i] |= 0x00ef0000; > +} > + > +void > +orr_3 (int *a) > +{ > + for (int i = 0; i < 1024; i++) > + a[i] |= 0x12000000; > +} > + > +void > +orr_4 (short *a) > +{ > + for (int i = 0; i < 1024; i++) > + a[i] |= 0x00340034; > +} > + > +void > +orr_5 (int *a) > +{ > + for (int i = 0; i < 1024; i++) > + a[i] |= 0x56005600; > +} > + > +/* { dg-final { scan-assembler "orr\\tv\[0-9\]+.4s, #171" } } */ > +/* { dg-final { scan-assembler "orr\\tv\[0-9\]+.4s, #205, lsl #8" } } */ > +/* { dg-final { scan-assembler "orr\\tv\[0-9\]+.4s, #239, lsl #16" } } */ > +/* { dg-final { scan-assembler "orr\\tv\[0-9\]+.4s, #18, lsl #24" } } */ > +/* { dg-final { scan-assembler "orr\\tv\[0-9\]+.8h, #52" } } */ > +/* { dg-final { scan-assembler "orr\\tv\[0-9\]+.8h, #86, lsl #8" } } */ >