gcc/ChangeLog: * config/i386/i386.md (*sub<mode>_1_nf): New define_insn. (*anddi_1_nf): Ditto. (*and<mode>_1_nf): Ditto. (*<code>qi_1_nf): Ditto. (*<code><mode>_1_nf): Ditto. (*neg<mode>_1_nf): Ditto. * config/i386/sse.md : New define_split.
gcc/testsuite/ChangeLog: * gcc.target/i386/apx-nf.c: Add test. --- gcc/config/i386/i386.md | 129 +++++++++++++++++++++++++ gcc/config/i386/sse.md | 11 +++ gcc/testsuite/gcc.target/i386/apx-nf.c | 9 ++ 3 files changed, 149 insertions(+) diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index 4a9e35c4990..66dc5e1035f 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -7888,6 +7888,24 @@ "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[3]);" [(set_attr "isa" "*,*,apx_ndd,apx_ndd")]) +(define_insn "*sub<mode>_1_nf" + [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,rjM,<r>,r,r,r") + (minus:SWI + (match_operand:SWI 1 "nonimmediate_operand" "0,0,0,rm,rjM,r") + (match_operand:SWI 2 "<general_operand>" "<r>,<i>,<m>,r,<i>,<m>")))] + "TARGET_APX_NF && + ix86_binary_operator_ok (MINUS, <MODE>mode, operands, TARGET_APX_NDD)" + "@ + %{nf%} sub{<imodesuffix>}\t{%2, %0|%0, %2} + %{nf%} sub{<imodesuffix>}\t{%2, %0|%0, %2} + %{nf%} sub{<imodesuffix>}\t{%2, %0|%0, %2} + %{nf%} sub{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2} + %{nf%} sub{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2} + %{nf%} sub{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}" + [(set_attr "isa" "*,*,*,apx_ndd,apx_ndd,apx_ndd") + (set_attr "type" "alu") + (set_attr "mode" "<MODE>")]) + (define_insn "*sub<mode>_1" [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>,r,r,r") (minus:SWI @@ -11790,6 +11808,27 @@ } [(set_attr "isa" "*,*,apx_ndd,apx_ndd,apx_ndd,apx_ndd_64,apx_ndd")]) +(define_insn "*anddi_1_nf" + [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm,rjM,r,r,r,r,?k") + (and:DI + (match_operand:DI 1 "nonimmediate_operand" "%0,r,0,0,0,rm,rjM,r,k") + (match_operand:DI 2 "x86_64_szext_general_operand" +"Z,Z,r,e,m,r,e,m,k")))] + "TARGET_APX_NF + && ix86_binary_operator_ok (AND, DImode, operands, TARGET_APX_NDD)" + "@ + %{nf%} and{l}\t{%k2, %k0|%k0, %k2} + %{nf%} and{l}\t{%k2, %k1, %k0|%k0, %k1, %k2} + %{nf%} and{q}\t{%2, %0|%0, %2} + %{nf%} and{q}\t{%2, %0|%0, %2} + %{nf%} and{q}\t{%2, %0|%0, %2} + %{nf%} and{q}\t{%2, %1, %0|%0, %1, %2} + %{nf%} and{q}\t{%2, %1, %0|%0, %1, %2} + %{nf%} and{q}\t{%2, %1, %0|%0, %1, %2} + #" + [(set_attr "isa" "*,apx_ndd,*,*,*,apx_ndd,apx_ndd,apx_ndd,avx512bw") + (set_attr "type" "alu,alu,alu,alu,alu,alu,alu,alu,msklog") + (set_attr "mode" "SI,SI,DI,DI,DI,DI,DI,DI,DI")]) + (define_insn "*anddi_1" [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm,r,r,r,r,r,?k") (and:DI @@ -11889,6 +11928,33 @@ (set_attr "isa" "*,apx_ndd,apx_ndd,apx_ndd") (set_attr "mode" "SI")]) +(define_insn "*and<mode>_1_nf" + [(set (match_operand:SWI24 0 "nonimmediate_operand" "=rm,rjM,r,r,r,r,?k") + (and:SWI24 (match_operand:SWI24 1 "nonimmediate_operand" "%0,0,0,rm,rjM,r,k") + (match_operand:SWI24 2 "<general_operand>" +"r,<i>,<m>,r,<i>,<m>,k")))] + "TARGET_APX_NF && + ix86_binary_operator_ok (AND, <MODE>mode, operands, TARGET_APX_NDD)" + "@ + %{nf%} and{<imodesuffix>}\t{%2, %0|%0, %2} + %{nf%} and{<imodesuffix>}\t{%2, %0|%0, %2} + %{nf%} and{<imodesuffix>}\t{%2, %0|%0, %2} + %{nf%} and{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2} + %{nf%} and{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2} + %{nf%} and{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2} + #" + [(set (attr "isa") + (cond [(eq_attr "alternative" "3,4,5") + (const_string "apx_ndd") + (eq_attr "alternative" "6") + (if_then_else (eq_attr "mode" "SI") + (const_string "avx512bw") + (const_string "avx512f")) + ] + (const_string "*"))) + (set_attr "type" "alu,alu,alu,alu,alu,alu,msklog") + (set_attr "type" "alu") + (set_attr "mode" "<MODE>")]) + (define_insn "*and<mode>_1" [(set (match_operand:SWI24 0 "nonimmediate_operand" "=rm,r,r,r,r,Ya,?k") (and:SWI24 (match_operand:SWI24 1 "nonimmediate_operand" "%0,0,rm,rjM,r,qm,k") @@ -11923,6 +11989,37 @@ (const_string "*"))) (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<MODE>,SI,<MODE>")]) +;; NF for and,or,xor + +(define_insn "*<code>qi_1_nf" + [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r,r,?k") + (any_logic:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,rm,r,k") + (match_operand:QI 2 "general_operand" "qn,m,rn,rn,m,k")))] + "TARGET_APX_NF && + ix86_binary_operator_ok (<CODE>, QImode, operands, TARGET_APX_NDD)" + "@ + %{nf%} <logic>{b}\t{%2, %0|%0, %2} + %{nf%} <logic>{b}\t{%2, %0|%0, %2} + %{nf%} <logic>{l}\t{%k2, %k0|%k0, %k2} + %{nf%} <logic>{b}\t{%2, %1, %0|%0, %1, %2} + %{nf%} <logic>{b}\t{%2, %1, %0|%0, %1, %2} + #" + [(set_attr "isa" "*,*,*,apx_ndd,apx_ndd,avx512f") + (set_attr "type" "alu,alu,alu,alu,alu,msklog") + (set (attr "mode") + (cond [(eq_attr "alternative" "2") + (const_string "SI") + (and (eq_attr "alternative" "5") + (match_test "!TARGET_AVX512DQ")) + (const_string "HI") + ] + (const_string "QI"))) + ;; Potential partial reg stall on alternative 2. + (set (attr "preferred_for_speed") + (cond [(eq_attr "alternative" "2") + (symbol_ref "!TARGET_PARTIAL_REG_STALL")] + (symbol_ref "true")))]) + (define_insn "*andqi_1" [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r,r,?k") (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,rm,r,k") @@ -12797,6 +12894,26 @@ } [(set_attr "isa" "*,*,apx_ndd,apx_ndd,apx_ndd,apx_ndd_64,apx_ndd")]) +;; or xor +(define_insn "*<code><mode>_1_nf" + [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm,rjM,r,r,r,r,?k") + (any_or:SWI248 + (match_operand:SWI248 1 "nonimmediate_operand" "0,0,0,rm,rjM,r,k") + (match_operand:SWI248 2 "<general_operand>" +"r,<i>,<m>,r,<i>,<m>,k")))] + "TARGET_APX_NF && + ix86_binary_operator_ok (<CODE>, <MODE>mode, operands, TARGET_APX_NDD)" + "@ + %{nf%} <logic>{<imodesuffix>}\t{%2, %0|%0, %2} + %{nf%} <logic>{<imodesuffix>}\t{%2, %0|%0, %2} + %{nf%} <logic>{<imodesuffix>}\t{%2, %0|%0, %2} + %{nf%} <logic>{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2} + %{nf%} <logic>{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2} + %{nf%} <logic>{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2} + #" + [(set_attr "isa" "*,*,*,apx_ndd,apx_ndd,apx_ndd,<kmov_isa>") + (set_attr "type" "alu,alu, alu, alu, alu, alu, msklog") + (set_attr "mode" "<MODE>")]) + (define_insn "*<code><mode>_1" [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm,r,r,r,r,?k") (any_or:SWI248 @@ -13529,6 +13646,18 @@ (const_int 0))) (clobber (reg:CC FLAGS_REG))])]) +(define_insn "*neg<mode>_1_nf" + [(set (match_operand:SWI 0 "nonimmediate_operand" "=rm,r") + (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0,rm")))] + "TARGET_APX_NF && + ix86_unary_operator_ok (NEG, <MODE>mode, operands, TARGET_APX_NDD)" + "@ + %{nf%} neg{<imodesuffix>}\t%0 + %{nf%} neg{<imodesuffix>}\t{%1, %0|%0, %1}" + [(set_attr "type" "negnot") + (set_attr "isa" "*,apx_ndd") + (set_attr "mode" "<MODE>")]) + (define_insn "*neg<mode>_1" [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,r") (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0,rm"))) diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md index f57f36ae380..72d4556f47d 100644 --- a/gcc/config/i386/sse.md +++ b/gcc/config/i386/sse.md @@ -2005,6 +2005,17 @@ ] (const_string "<MODE>")))]) +(define_split + [(set (match_operand:SWI1248_AVX512BW 0 "mask_reg_operand") + (any_logic:SWI1248_AVX512BW + (match_operand:SWI1248_AVX512BW 1 "mask_reg_operand") + (match_operand:SWI1248_AVX512BW 2 "mask_reg_operand")))] + "TARGET_AVX512F && reload_completed" + [(parallel + [(set (match_dup 0) + (any_logic:SWI1248_AVX512BW (match_dup 1) (match_dup 2))) + (unspec [(const_int 0)] UNSPEC_MASKOP)])]) + (define_split [(set (match_operand:SWI1248_AVX512BW 0 "mask_reg_operand") (any_logic:SWI1248_AVX512BW diff --git a/gcc/testsuite/gcc.target/i386/apx-nf.c b/gcc/testsuite/gcc.target/i386/apx-nf.c index 3adc7a27902..608dbf8f5f7 100644 --- a/gcc/testsuite/gcc.target/i386/apx-nf.c +++ b/gcc/testsuite/gcc.target/i386/apx-nf.c @@ -1,6 +1,15 @@ /* { dg-do compile { target { ! ia32 } } } */ /* { dg-options "-mapx-features=egpr,push2pop2,ndd,ppx,nf -march=x86-64 -O2" } */ /* { dg-final { scan-assembler-times "\{nf\} add" 4 } } */ +/* { dg-final { scan-assembler-times "\{nf\} and" 1 } } */ +/* { dg-final { scan-assembler-times "\{nf\} or" 1 } } */ #include "apx-ndd.c" +struct B { unsigned bit0 : 1; unsigned bit1 : 1; }; + +void +foo (struct B *b) +{ + b->bit0 = b->bit0 | b->bit1; +} -- 2.31.1