In 64-bit mode, implement V2SF add/sub/mul with SEE. Only SSE register source operand is allowed.
gcc/ PR target/89028 * config/i386/i386.md (comm): Handle mult. * config/i386/mmx.md (plusminusmult): New. (plusminusmult_insn): Likewse. (plusminusmult_mnemonic): Likewse. (plusminusmult_type): Likewse. (mmx_addv2sf3): Add "&& !TARGET_MMX_WITH_SSE". (*mmx_addv2sf3): Likewise. (mmx_subv2sf3): Likewise. (mmx_subrv2sf3): Likewise. (*mmx_subv2sf3): Likewise. (mmx_mulv2sf3): Likewise. (*mmx_mulv2sf3): Likewise. (<plusminusmult_insn>v2sf3): New. (*sse_<plusminusmult_insn>v2sf3): Likewise. gcc/testsuite/ PR target/89028 * gcc.target/i386/pr89028-2.c: New test. * gcc.target/i386/pr89028-3.c: Likewise. * gcc.target/i386/pr89028-4.c: Likewise. * gcc.target/i386/pr89028-5.c: Likewise. * gcc.target/i386/pr89028-6.c: Likewise. * gcc.target/i386/pr89028-7.c: Likewise. --- gcc/config/i386/i386.md | 3 +- gcc/config/i386/mmx.md | 56 ++++++++++++++++++++--- gcc/testsuite/gcc.target/i386/pr89028-2.c | 11 +++++ gcc/testsuite/gcc.target/i386/pr89028-3.c | 14 ++++++ gcc/testsuite/gcc.target/i386/pr89028-4.c | 14 ++++++ gcc/testsuite/gcc.target/i386/pr89028-5.c | 11 +++++ gcc/testsuite/gcc.target/i386/pr89028-6.c | 14 ++++++ gcc/testsuite/gcc.target/i386/pr89028-7.c | 14 ++++++ 8 files changed, 129 insertions(+), 8 deletions(-) create mode 100644 gcc/testsuite/gcc.target/i386/pr89028-2.c create mode 100644 gcc/testsuite/gcc.target/i386/pr89028-3.c create mode 100644 gcc/testsuite/gcc.target/i386/pr89028-4.c create mode 100644 gcc/testsuite/gcc.target/i386/pr89028-5.c create mode 100644 gcc/testsuite/gcc.target/i386/pr89028-6.c create mode 100644 gcc/testsuite/gcc.target/i386/pr89028-7.c diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index 72685107fc0..cda973c0fbf 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -873,7 +873,8 @@ ;; Mark commutative operators as such in constraints. (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%") - (minus "") (ss_minus "") (us_minus "")]) + (minus "") (ss_minus "") (us_minus "") + (mult "%")]) ;; Mapping of max and min (define_code_iterator maxmin [smax smin umax umin]) diff --git a/gcc/config/i386/mmx.md b/gcc/config/i386/mmx.md index e56d2e71168..88c1ecd9ae6 100644 --- a/gcc/config/i386/mmx.md +++ b/gcc/config/i386/mmx.md @@ -63,6 +63,20 @@ ;; Instruction suffix for truncations with saturation. (define_code_attr s_trunsuffix [(ss_truncate "s") (us_truncate "u")]) +(define_code_iterator plusminusmult [plus minus mult]) + +;; Base name for define_insn +(define_code_attr plusminusmult_insn + [(plus "add") (minus "sub") (mult "mul")]) + +;; Base name for insn mnemonic. +(define_code_attr plusminusmult_mnemonic + [(plus "add") (minus "sub") (mult "mul")]) + +;; Insn type name for insn mnemonic. +(define_code_attr plusminusmult_type + [(plus "add") (minus "add") (mult "mul")]) + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Move patterns @@ -279,14 +293,16 @@ (plus:V2SF (match_operand:V2SF 1 "nonimmediate_operand") (match_operand:V2SF 2 "nonimmediate_operand")))] - "TARGET_3DNOW" + "TARGET_3DNOW && !TARGET_MMX_WITH_SSE" "ix86_fixup_binary_operands_no_copy (PLUS, V2SFmode, operands);") (define_insn "*mmx_addv2sf3" [(set (match_operand:V2SF 0 "register_operand" "=y") (plus:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "%0") (match_operand:V2SF 2 "nonimmediate_operand" "ym")))] - "TARGET_3DNOW && ix86_binary_operator_ok (PLUS, V2SFmode, operands)" + "TARGET_3DNOW + && !TARGET_MMX_WITH_SSE + && ix86_binary_operator_ok (PLUS, V2SFmode, operands)" "pfadd\t{%2, %0|%0, %2}" [(set_attr "type" "mmxadd") (set_attr "prefix_extra" "1") @@ -296,19 +312,21 @@ [(set (match_operand:V2SF 0 "register_operand") (minus:V2SF (match_operand:V2SF 1 "register_operand") (match_operand:V2SF 2 "nonimmediate_operand")))] - "TARGET_3DNOW") + "TARGET_3DNOW && !TARGET_MMX_WITH_SSE") (define_expand "mmx_subrv2sf3" [(set (match_operand:V2SF 0 "register_operand") (minus:V2SF (match_operand:V2SF 2 "register_operand") (match_operand:V2SF 1 "nonimmediate_operand")))] - "TARGET_3DNOW") + "TARGET_3DNOW && !TARGET_MMX_WITH_SSE") (define_insn "*mmx_subv2sf3" [(set (match_operand:V2SF 0 "register_operand" "=y,y") (minus:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "0,ym") (match_operand:V2SF 2 "nonimmediate_operand" "ym,0")))] - "TARGET_3DNOW && !(MEM_P (operands[0]) && MEM_P (operands[1]))" + "TARGET_3DNOW + && !TARGET_MMX_WITH_SSE + && !(MEM_P (operands[0]) && MEM_P (operands[1]))" "@ pfsub\t{%2, %0|%0, %2} pfsubr\t{%1, %0|%0, %1}" @@ -320,19 +338,43 @@ [(set (match_operand:V2SF 0 "register_operand") (mult:V2SF (match_operand:V2SF 1 "nonimmediate_operand") (match_operand:V2SF 2 "nonimmediate_operand")))] - "TARGET_3DNOW" + "TARGET_3DNOW && !TARGET_MMX_WITH_SSE" "ix86_fixup_binary_operands_no_copy (MULT, V2SFmode, operands);") (define_insn "*mmx_mulv2sf3" [(set (match_operand:V2SF 0 "register_operand" "=y") (mult:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "%0") (match_operand:V2SF 2 "nonimmediate_operand" "ym")))] - "TARGET_3DNOW && ix86_binary_operator_ok (MULT, V2SFmode, operands)" + "TARGET_3DNOW + && !TARGET_MMX_WITH_SSE + && ix86_binary_operator_ok (MULT, V2SFmode, operands)" "pfmul\t{%2, %0|%0, %2}" [(set_attr "type" "mmxmul") (set_attr "prefix_extra" "1") (set_attr "mode" "V2SF")]) +(define_expand "<plusminusmult_insn>v2sf3" + [(set (match_operand:V2SF 0 "register_operand") + (plusminusmult:V2SF + (match_operand:V2SF 1 "nonimmediate_operand") + (match_operand:V2SF 2 "nonimmediate_operand")))] + "TARGET_MMX_WITH_SSE" + "ix86_fixup_binary_operands_no_copy (<CODE>, V2SFmode, operands);") + +(define_insn "*sse_<plusminusmult_insn>v2sf3" + [(set (match_operand:V2SF 0 "register_operand" "=x,Yv") + (plusminusmult:V2SF + (match_operand:V2SF 1 "nonimmediate_operand" "<comm>0,Yv") + (match_operand:V2SF 2 "nonimmediate_operand" "x,Yv")))] + "TARGET_MMX_WITH_SSE + && ix86_binary_operator_ok (<CODE>, V4SFmode, operands)" + "@ + <plusminusmult_mnemonic>ps\t{%2, %0|%0, %2} + v<plusminusmult_mnemonic>ps\t{%2, %1, %0|%0, %1, %2}" + [(set_attr "isa" "noavx,avx") + (set_attr "type" "sse<plusminusmult_type>") + (set_attr "mode" "V4SF")]) + (define_expand "mmx_<code>v2sf3" [(set (match_operand:V2SF 0 "register_operand") (smaxmin:V2SF diff --git a/gcc/testsuite/gcc.target/i386/pr89028-2.c b/gcc/testsuite/gcc.target/i386/pr89028-2.c new file mode 100644 index 00000000000..d096b0b6863 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr89028-2.c @@ -0,0 +1,11 @@ +/* { dg-do compile { target { ! ia32 } } } */ +/* { dg-options "-O2 -msse2 -mno-mmx" } */ +/* { dg-final { scan-assembler-times "addps" 1 } } */ + +typedef float __v2sf __attribute__ ((__vector_size__ (8))); + +__v2sf +foo1 (__v2sf x, __v2sf y) +{ + return x + y; +} diff --git a/gcc/testsuite/gcc.target/i386/pr89028-3.c b/gcc/testsuite/gcc.target/i386/pr89028-3.c new file mode 100644 index 00000000000..0fa187aaf72 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr89028-3.c @@ -0,0 +1,14 @@ +/* { dg-do compile { target { ! ia32 } } } */ +/* { dg-options "-O2 -msse2 -mno-mmx" } */ +/* { dg-final { scan-assembler-times "movlps" 2 } } */ +/* { dg-final { scan-assembler-times "addps" 1 } } */ + +typedef float __v2sf __attribute__ ((__vector_size__ (8))); + +extern __v2sf x, y, z; + +__v2sf +foo2 (void) +{ + return x + y; +} diff --git a/gcc/testsuite/gcc.target/i386/pr89028-4.c b/gcc/testsuite/gcc.target/i386/pr89028-4.c new file mode 100644 index 00000000000..b25f67632cb --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr89028-4.c @@ -0,0 +1,14 @@ +/* { dg-do compile { target { ! ia32 } } } */ +/* { dg-options "-O2 -msse2 -mno-mmx" } */ +/* { dg-final { scan-assembler-times "movlps" 1 } } */ +/* { dg-final { scan-assembler-times "addps" 1 } } */ + +typedef float __v2sf __attribute__ ((__vector_size__ (8))); + +extern __v2sf x, y, z; + +void +foo3 (__v2sf x, __v2sf y) +{ + z = x + y; +} diff --git a/gcc/testsuite/gcc.target/i386/pr89028-5.c b/gcc/testsuite/gcc.target/i386/pr89028-5.c new file mode 100644 index 00000000000..4ead7187605 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr89028-5.c @@ -0,0 +1,11 @@ +/* { dg-do compile { target { ! ia32 } } } */ +/* { dg-options "-O2 -msse2 -mno-mmx" } */ +/* { dg-final { scan-assembler-times "mulps" 1 } } */ + +typedef float __v2sf __attribute__ ((__vector_size__ (8))); + +__v2sf +foo1 (__v2sf x, __v2sf y) +{ + return x * y; +} diff --git a/gcc/testsuite/gcc.target/i386/pr89028-6.c b/gcc/testsuite/gcc.target/i386/pr89028-6.c new file mode 100644 index 00000000000..9277c848c6c --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr89028-6.c @@ -0,0 +1,14 @@ +/* { dg-do compile { target { ! ia32 } } } */ +/* { dg-options "-O2 -msse2 -mno-mmx" } */ +/* { dg-final { scan-assembler-times "movlps" 2 } } */ +/* { dg-final { scan-assembler-times "mulps" 1 } } */ + +typedef float __v2sf __attribute__ ((__vector_size__ (8))); + +extern __v2sf x, y, z; + +__v2sf +foo2 (void) +{ + return x * y; +} diff --git a/gcc/testsuite/gcc.target/i386/pr89028-7.c b/gcc/testsuite/gcc.target/i386/pr89028-7.c new file mode 100644 index 00000000000..c8af7b2a4e9 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr89028-7.c @@ -0,0 +1,14 @@ +/* { dg-do compile { target { ! ia32 } } } */ +/* { dg-options "-O2 -msse2 -mno-mmx" } */ +/* { dg-final { scan-assembler-times "movlps" 1 } } */ +/* { dg-final { scan-assembler-times "mulps" 1 } } */ + +typedef float __v2sf __attribute__ ((__vector_size__ (8))); + +extern __v2sf x, y, z; + +void +foo3 (__v2sf x, __v2sf y) +{ + z = x * y; +} -- 2.20.1