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 744f155fca6..89ebca70e6d 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -861,7 +861,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 ba81b48e515..7350da03069 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
@@ -277,14 +291,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")
@@ -294,19 +310,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}"
@@ -318,19 +336,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" "=Yx,Yy")
+        (plusminusmult:V2SF
+         (match_operand:V2SF 1 "nonimmediate_operand" "<comm>0,Yy")
+         (match_operand:V2SF 2 "nonimmediate_operand" "Yx,Yy")))]
+  "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

Reply via email to