]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Support Intel CMPccXADD
authorHaochen Jiang <haochen.jiang@intel.com>
Fri, 4 Nov 2022 01:20:54 +0000 (09:20 +0800)
committerHaochen Jiang <haochen.jiang@intel.com>
Fri, 4 Nov 2022 01:35:52 +0000 (09:35 +0800)
gcc/ChangeLog:

* common/config/i386/cpuinfo.h (get_available_features):
Detect cmpccxadd.
* common/config/i386/i386-common.cc
(OPTION_MASK_ISA2_CMPCCXADD_SET,
OPTION_MASK_ISA2_CMPCCXADD_UNSET): New.
(ix86_handle_option): Handle -mcmpccxadd.
* common/config/i386/i386-cpuinfo.h (enum processor_features):
Add FEATURE_CMPCCXADD.
* common/config/i386/i386-isas.h: Add ISA_NAME_TABLE_ENTRY for
cmpccxadd.
* config.gcc: Add cmpccxaddintrin.h.
* config/i386/cpuid.h (bit_CMPCCXADD): New.
* config/i386/i386-builtin-types.def:
Add DEF_FUNCTION_TYPE(INT, PINT, INT, INT, INT)
and DEF_FUNCTION_TYPE(LONGLONG, PLONGLONG, LONGLONG, LONGLONG, INT).
* config/i386/i386-builtin.def (BDESC): Add new builtins.
* config/i386/i386-c.cc (ix86_target_macros_internal): Define
__CMPCCXADD__.
* config/i386/i386-expand.cc (ix86_expand_special_args_builtin):
Add new parameter to indicate constant position.
Handle INT_FTYPE_PINT_INT_INT_INT
and LONGLONG_FTYPE_PLONGLONG_LONGLONG_LONGLONG_INT.
* config/i386/i386-isa.def (CMPCCXADD): Add DEF_PTA(CMPCCXADD).
* config/i386/i386-options.cc (isa2_opts): Add -mcmpccxadd.
(ix86_valid_target_attribute_inner_p): Handle cmpccxadd.
* config/i386/i386.opt: Add option -mcmpccxadd.
* config/i386/sync.md (cmpccxadd_<mode>): New define insn.
* config/i386/x86gprintrin.h: Include cmpccxaddintrin.h.
* doc/extend.texi: Document cmpccxadd.
* doc/invoke.texi: Document -mcmpccxadd.
* doc/sourcebuild.texi: Document target cmpccxadd.
* config/i386/cmpccxaddintrin.h: New file.

gcc/testsuite/ChangeLog:

* g++.dg/other/i386-2.C: Add -mcmpccxadd.
* g++.dg/other/i386-3.C: Ditto.
* gcc.target/i386/avx-1.c: Ditto.
* gcc.target/i386/funcspec-56.inc: Add new target attribute.
* gcc.target/i386/sse-13.c: Add -mcmpccxadd.
* gcc.target/i386/sse-23.c: Ditto.
* gcc.target/i386/x86gprintrin-1.c: Ditto.
* gcc.target/i386/x86gprintrin-2.c: Ditto.
* gcc.target/i386/x86gprintrin-3.c: Ditto.
* gcc.target/i386/x86gprintrin-4.c: Ditto.
* gcc.target/i386/x86gprintrin-5.c: Ditto.
* lib/target-supports.exp (check_effective_target_cmpccxadd):
New.
* gcc.target/i386/cmpccxadd-1.c: New test.
* gcc.target/i386/cmpccxadd-2.c: Ditto.

33 files changed:
gcc/common/config/i386/cpuinfo.h
gcc/common/config/i386/i386-common.cc
gcc/common/config/i386/i386-cpuinfo.h
gcc/common/config/i386/i386-isas.h
gcc/config.gcc
gcc/config/i386/cmpccxaddintrin.h [new file with mode: 0644]
gcc/config/i386/cpuid.h
gcc/config/i386/i386-builtin-types.def
gcc/config/i386/i386-builtin.def
gcc/config/i386/i386-c.cc
gcc/config/i386/i386-expand.cc
gcc/config/i386/i386-isa.def
gcc/config/i386/i386-options.cc
gcc/config/i386/i386.opt
gcc/config/i386/sync.md
gcc/config/i386/x86gprintrin.h
gcc/doc/extend.texi
gcc/doc/invoke.texi
gcc/doc/sourcebuild.texi
gcc/testsuite/g++.dg/other/i386-2.C
gcc/testsuite/g++.dg/other/i386-3.C
gcc/testsuite/gcc.target/i386/avx-1.c
gcc/testsuite/gcc.target/i386/cmpccxadd-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/cmpccxadd-2.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/funcspec-56.inc
gcc/testsuite/gcc.target/i386/sse-13.c
gcc/testsuite/gcc.target/i386/sse-23.c
gcc/testsuite/gcc.target/i386/x86gprintrin-1.c
gcc/testsuite/gcc.target/i386/x86gprintrin-2.c
gcc/testsuite/gcc.target/i386/x86gprintrin-3.c
gcc/testsuite/gcc.target/i386/x86gprintrin-4.c
gcc/testsuite/gcc.target/i386/x86gprintrin-5.c
gcc/testsuite/lib/target-supports.exp

index 62c3d1b6b0013bc7152441f935e3048a64586c1f..f21be393ccbd37df4688a93db09f13f908ef93a5 100644 (file)
@@ -831,6 +831,8 @@ get_available_features (struct __processor_model *cpu_model,
       __cpuid_count (7, 1, eax, ebx, ecx, edx);
       if (eax & bit_HRESET)
        set_feature (FEATURE_HRESET);
+      if (eax & bit_CMPCCXADD)
+       set_feature(FEATURE_CMPCCXADD);
       if (avx_usable)
        {
          if (eax & bit_AVXVNNI)
index cd6ad2c477b6b8e837940d01938978976015d71f..770e93423b9da34fcfca14abb85018e0abbe97d5 100644 (file)
@@ -110,6 +110,7 @@ along with GCC; see the file COPYING3.  If not see
 #define OPTION_MASK_ISA2_AMX_BF16_SET OPTION_MASK_ISA2_AMX_BF16
 #define OPTION_MASK_ISA2_AVXVNNIINT8_SET OPTION_MASK_ISA2_AVXVNNIINT8
 #define OPTION_MASK_ISA2_AVXNECONVERT_SET OPTION_MASK_ISA2_AVXNECONVERT
+#define OPTION_MASK_ISA2_CMPCCXADD_SET OPTION_MASK_ISA2_CMPCCXADD
 
 /* SSE4 includes both SSE4.1 and SSE4.2. -msse4 should be the same
    as -msse4.2.  */
@@ -283,6 +284,7 @@ along with GCC; see the file COPYING3.  If not see
 #define OPTION_MASK_ISA2_WIDEKL_UNSET OPTION_MASK_ISA2_WIDEKL
 #define OPTION_MASK_ISA2_AVXVNNIINT8_UNSET OPTION_MASK_ISA2_AVXVNNIINT8
 #define OPTION_MASK_ISA2_AVXNECONVERT_UNSET OPTION_MASK_ISA2_AVXNECONVERT
+#define OPTION_MASK_ISA2_CMPCCXADD_UNSET OPTION_MASK_ISA2_CMPCCXADD
 
 /* SSE4 includes both SSE4.1 and SSE4.2.  -mno-sse4 should the same
    as -mno-sse4.1. */
@@ -1181,6 +1183,19 @@ ix86_handle_option (struct gcc_options *opts,
        }
       return true;
 
+    case OPT_mcmpccxadd:
+      if (value)
+       {
+         opts->x_ix86_isa_flags2 |= OPTION_MASK_ISA2_CMPCCXADD_SET;
+         opts->x_ix86_isa_flags2_explicit |= OPTION_MASK_ISA2_CMPCCXADD_SET;
+       }
+      else
+       {
+         opts->x_ix86_isa_flags2 &= ~OPTION_MASK_ISA2_CMPCCXADD_UNSET;
+         opts->x_ix86_isa_flags2_explicit |= OPTION_MASK_ISA2_CMPCCXADD_UNSET;
+       }
+      return true;
+
     case OPT_mfma:
       if (value)
        {
index 4fbbfa5b701c7a4b4028504c41a18af73b0817a1..e46aa00ca7edef28435901bf55cb7d5260a728b3 100644 (file)
@@ -246,6 +246,7 @@ enum processor_features
   FEATURE_AVXIFMA,
   FEATURE_AVXVNNIINT8,
   FEATURE_AVXNECONVERT,
+  FEATURE_CMPCCXADD,
   CPU_FEATURE_MAX
 };
 
index bceaee589ee3c3a1ee36c7ec22929f3b7c0815a6..3035e4a8186fc62dbd4a44d91e3d82fbe0b4e72e 100644 (file)
@@ -180,4 +180,5 @@ ISA_NAMES_TABLE_START
                        P_NONE, "-mavxvnniint8")
   ISA_NAMES_TABLE_ENTRY("avxneconvert", FEATURE_AVXNECONVERT,
                        P_NONE, "-mavxneconvert")
+  ISA_NAMES_TABLE_ENTRY("cmpccxadd", FEATURE_CMPCCXADD, P_NONE, "-mcmpccxadd")
 ISA_NAMES_TABLE_END
index c2f8aab04db0a7b66589459e8a727a1ceb30a6ea..e142af309474bf3410c82d77df8797cfc8fe912f 100644 (file)
@@ -422,7 +422,8 @@ i[34567]86-*-* | x86_64-*-*)
                       amxbf16intrin.h x86gprintrin.h uintrintrin.h
                       hresetintrin.h keylockerintrin.h avxvnniintrin.h
                       mwaitintrin.h avx512fp16intrin.h avx512fp16vlintrin.h
-                      avxifmaintrin.h avxvnniint8intrin.h avxneconvertintrin.h"
+                      avxifmaintrin.h avxvnniint8intrin.h avxneconvertintrin.h
+                      cmpccxaddintrin.h"
        ;;
 ia64-*-*)
        extra_headers=ia64intrin.h
diff --git a/gcc/config/i386/cmpccxaddintrin.h b/gcc/config/i386/cmpccxaddintrin.h
new file mode 100644 (file)
index 0000000..1afa03b
--- /dev/null
@@ -0,0 +1,89 @@
+/* Copyright (C) 2012-2021 Free Software Foundation, Inc.
+
+   This file is part of GCC.
+
+   GCC is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3, or (at your option)
+   any later version.
+
+   GCC is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   Under Section 7 of GPL version 3, you are granted additional
+   permissions described in the GCC Runtime Library Exception, version
+   3.1, as published by the Free Software Foundation.
+
+   You should have received a copy of the GNU General Public License and
+   a copy of the GCC Runtime Library Exception along with this program;
+   see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef _X86GPRINTRIN_H_INCLUDED
+#error "Never use <cmpccxaddintrin.h> directly; include <x86gprintrin.h> instead."
+#endif
+
+#ifndef _CMPCCXADDINTRIN_H_INCLUDED
+#define _CMPCCXADDINTRIN_H_INCLUDED
+
+#ifdef __x86_64__
+
+#ifndef __CMPCCXADD__
+#pragma GCC push_options
+#pragma GCC target("cmpccxadd")
+#define __DISABLE_CMPCCXADD__
+#endif /* __CMPCCXADD__ */
+
+typedef enum {
+    _CMPCCX_O,   /* Overflow.  */
+    _CMPCCX_NO,  /* No overflow.  */
+    _CMPCCX_B,   /* Below.  */
+    _CMPCCX_NB,  /* Not below.  */
+    _CMPCCX_Z,   /* Zero.  */
+    _CMPCCX_NZ,  /* Not zero.  */
+    _CMPCCX_BE,  /* Below or equal.  */
+    _CMPCCX_NBE, /* Neither below nor equal.  */
+    _CMPCCX_S,   /* Sign.  */
+    _CMPCCX_NS,  /* No sign.  */
+    _CMPCCX_P,   /* Parity.  */
+    _CMPCCX_NP,  /* No parity.  */
+    _CMPCCX_L,   /* Less.  */
+    _CMPCCX_NL,  /* Not less.  */
+    _CMPCCX_LE,  /* Less or equal.  */
+    _CMPCCX_NLE, /* Neither less nor equal.  */
+} _CMPCCX_ENUM;
+
+#ifdef __OPTIMIZE__
+extern __inline int
+__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
+__cmpccxadd_epi32 (int *__A, int __B, int __C, const _CMPCCX_ENUM __D)
+{
+  return __builtin_ia32_cmpccxadd (__A, __B, __C, __D);
+}
+
+extern __inline long long
+__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
+__cmpccxadd_epi64 (long long *__A, long long __B, long long __C,
+                  const _CMPCCX_ENUM __D)
+{
+  return __builtin_ia32_cmpccxadd64 (__A, __B, __C, __D);
+}
+#else
+#define __cmpccxadd_epi32(A,B,C,D) \
+  __builtin_ia32_cmpccxadd ((int *) (A), (int) (B), (int) (C), \
+                           (_CMPCCX_ENUM) (D))
+#define __cmpccxadd_epi64(A,B,C,D) \
+  __builtin_ia32_cmpccxadd64 ((long long *) (A), (long long) (B), \
+                             (long long) (C), (_CMPCCX_ENUM) (D))
+#endif
+
+#ifdef __DISABLE_CMPCCXADD__
+#undef __DISABLE_CMPCCXADD__
+#pragma GCC pop_options
+#endif /* __DISABLE_CMPCCXADD__ */
+
+#endif
+
+#endif /* _CMPCCXADDINTRIN_H_INCLUDED */
index 18bbc0cb7bed7e9862deaa0672c9f8391a01109a..19c0d033921e334c4d54c100b632d1d8cd9e5170 100644 (file)
@@ -27,6 +27,7 @@
 /* %eax */
 #define bit_AVXVNNI    (1 << 4)
 #define bit_AVX512BF16 (1 << 5)
+#define bit_CMPCCXADD  (1 << 7)
 #define bit_HRESET     (1 << 22)
 #define bit_AVXIFMA    (1 << 23)
 
index abbb50b1192ea6710756f7c1e9beec1f6c1a36d6..2af66145d4b59d663b880ddcdb42aded3f7937b4 100644 (file)
@@ -1407,3 +1407,7 @@ DEF_FUNCTION_TYPE (V4SF, PCV8HF)
 DEF_FUNCTION_TYPE (V8SF, PCV16HF)
 DEF_FUNCTION_TYPE (V4SF, PCV8BF)
 DEF_FUNCTION_TYPE (V8SF, PCV16BF)
+
+# CMPccXADD builtins
+DEF_FUNCTION_TYPE (INT, PINT, INT, INT, INT)
+DEF_FUNCTION_TYPE (LONGLONG, PLONGLONG, LONGLONG, LONGLONG, INT)
index 9345b8c5d6944f2ef64d78cf1b3e64f946ec07a8..c272c392d0320e8c751c77cd7d621ad083716e52 100644 (file)
@@ -288,6 +288,10 @@ BDESC (0, OPTION_MASK_ISA2_AVXNECONVERT, CODE_FOR_vcvtneobf162ps_v16bf, "__built
 BDESC (0, OPTION_MASK_ISA2_AVXNECONVERT, CODE_FOR_vcvtneoph2ps_v8hf, "__builtin_ia32_vcvtneoph2ps128", IX86_BUILTIN_VCVTNEOPH2PS128, UNKNOWN, (int) V4SF_FTYPE_PCV8HF)
 BDESC (0, OPTION_MASK_ISA2_AVXNECONVERT, CODE_FOR_vcvtneoph2ps_v16hf, "__builtin_ia32_vcvtneoph2ps256", IX86_BUILTIN_VCVTNEOPH2PS256, UNKNOWN, (int) V8SF_FTYPE_PCV16HF)
 
+/* CMPCCXADD */
+BDESC (OPTION_MASK_ISA_64BIT, OPTION_MASK_ISA2_CMPCCXADD, CODE_FOR_cmpccxadd_si, "__builtin_ia32_cmpccxadd", IX86_BUILTIN_CMPCCXADD, UNKNOWN, (int) INT_FTYPE_PINT_INT_INT_INT)
+BDESC (OPTION_MASK_ISA_64BIT, OPTION_MASK_ISA2_CMPCCXADD, CODE_FOR_cmpccxadd_di, "__builtin_ia32_cmpccxadd64", IX86_BUILTIN_CMPCCXADD64, UNKNOWN, (int) LONGLONG_FTYPE_PLONGLONG_LONGLONG_LONGLONG_INT)
+
 /* AVX512BW */
 BDESC (OPTION_MASK_ISA_AVX512BW, 0, CODE_FOR_avx512bw_loadv32hi_mask, "__builtin_ia32_loaddquhi512_mask", IX86_BUILTIN_LOADDQUHI512_MASK, UNKNOWN, (int) V32HI_FTYPE_PCSHORT_V32HI_USI)
 BDESC (OPTION_MASK_ISA_AVX512BW, 0, CODE_FOR_avx512bw_loadv64qi_mask, "__builtin_ia32_loaddquqi512_mask", IX86_BUILTIN_LOADDQUQI512_MASK, UNKNOWN, (int) V64QI_FTYPE_PCCHAR_V64QI_UDI)
index fa195e739a6434ffbf6969b45ab1eda0777f483b..818cfd774916e762d52d721207b6cc41dab7cc4d 100644 (file)
@@ -646,6 +646,8 @@ ix86_target_macros_internal (HOST_WIDE_INT isa_flag,
     def_or_undef (parse_in, "__AVXVNNIINT8__");
   if (isa_flag2 & OPTION_MASK_ISA2_AVXNECONVERT)
     def_or_undef (parse_in, "__AVXNECONVERT__");
+  if (isa_flag2 & OPTION_MASK_ISA2_CMPCCXADD)
+    def_or_undef (parse_in, "__CMPCCXADD__");
   if (TARGET_IAMCU)
     {
       def_or_undef (parse_in, "__iamcu");
index 7d17bfeadeacc4576d5e903e1b31874203ad6349..a37fde307d1d7f8a8e4952d6e95305b3d493e3ed 100644 (file)
@@ -11860,8 +11860,9 @@ ix86_expand_special_args_builtin (const struct builtin_description *d,
   tree arg;
   rtx pat, op;
   unsigned int i, nargs, arg_adjust, memory;
+  unsigned int constant = 100;
   bool aligned_mem = false;
-  rtx xops[3];
+  rtx xops[4];
   enum insn_code icode = d->icode;
   const struct insn_data_d *insn_p = &insn_data[icode];
   machine_mode tmode = insn_p->operand[0].mode;
@@ -12152,6 +12153,13 @@ ix86_expand_special_args_builtin (const struct builtin_description *d,
       klass = load;
       memory = 0;
       break;
+    case INT_FTYPE_PINT_INT_INT_INT:
+    case LONGLONG_FTYPE_PLONGLONG_LONGLONG_LONGLONG_INT:
+      nargs = 4;
+      klass = load;
+      memory = 0;
+      constant = 3;
+      break;
     default:
       gcc_unreachable ();
     }
@@ -12217,6 +12225,15 @@ ix86_expand_special_args_builtin (const struct builtin_description *d,
          if (MEM_ALIGN (op) < align)
            set_mem_align (op, align);
        }
+      else if (i == constant)
+       {
+         /* This must be the constant.  */
+         if (!insn_p->operand[nargs].predicate(op, SImode))
+           {
+             error ("the fourth argument must be one of enum %qs", "_CMPCCX_ENUM");
+             return const0_rtx;
+           }
+       }
       else
        {
          /* This must be register.  */
@@ -12258,6 +12275,9 @@ ix86_expand_special_args_builtin (const struct builtin_description *d,
     case 3:
       pat = GEN_FCN (icode) (target, xops[0], xops[1], xops[2]);
       break;
+    case 4:
+      pat = GEN_FCN (icode) (target, xops[0], xops[1], xops[2], xops[3]);
+      break;
     default:
       gcc_unreachable ();
     }
index 4ea3f96f69fb4434c9732c2e077f79c8345c6154..7ffc73ba23e5073b280358c8d0fdd6c544c8fcc0 100644 (file)
@@ -112,3 +112,4 @@ DEF_PTA(AVX512FP16)
 DEF_PTA(AVXIFMA)
 DEF_PTA(AVXVNNIINT8)
 DEF_PTA(AVXNECONVERT)
+DEF_PTA(CMPCCXADD)
index ef9c888980c0c88a5df870865717d4d1eefd146c..38e3fd6b8c70d88c9fba6adf7212ff6ecaf4ef15 100644 (file)
@@ -230,7 +230,8 @@ static struct ix86_target_opts isa2_opts[] =
   { "-mavx512fp16",    OPTION_MASK_ISA2_AVX512FP16 },
   { "-mavxifma",       OPTION_MASK_ISA2_AVXIFMA },
   { "-mavxvnniint8",   OPTION_MASK_ISA2_AVXVNNIINT8 },
-  { "-mavxneconvert",   OPTION_MASK_ISA2_AVXNECONVERT }
+  { "-mavxneconvert",   OPTION_MASK_ISA2_AVXNECONVERT },
+  { "-mcmpccxadd",      OPTION_MASK_ISA2_CMPCCXADD }
 };
 static struct ix86_target_opts isa_opts[] =
 {
@@ -1080,6 +1081,7 @@ ix86_valid_target_attribute_inner_p (tree fndecl, tree args, char *p_strings[],
     IX86_ATTR_ISA ("avxifma", OPT_mavxifma),
     IX86_ATTR_ISA ("avxvnniint8", OPT_mavxvnniint8),
     IX86_ATTR_ISA ("avxneconvert", OPT_mavxneconvert),
+    IX86_ATTR_ISA ("cmpccxadd",   OPT_mcmpccxadd),
 
     /* enum options */
     IX86_ATTR_ENUM ("fpmath=", OPT_mfpmath_),
index 6e07b89ac4c86fd2214860eb49c6faad0d7cccdb..c4a3bdcf9606cc7116cfe06c992c2e234d376374 100644 (file)
@@ -1229,3 +1229,8 @@ mavxneconvert
 Target Mask(ISA2_AVXNECONVERT) Var(ix86_isa_flags2) Save
 Support MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, AVX, AVX2, and
 AVXNECONVERT build-in functions and code generation.
+
+mcmpccxadd
+Target Mask(ISA2_CMPCCXADD) Var(ix86_isa_flags2) Save
+Support MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, AVX, AVX2, and
+CMPCCXADD build-in functions and code generation.
index 92634d538cb89d394657147c55153a88035f1ae7..ff168b0c5c27207f2e5df7787ecdd035de1c0145 100644 (file)
@@ -37,6 +37,9 @@
   UNSPECV_CMPXCHG
   UNSPECV_XCHG
   UNSPECV_LOCK
+  ;; For CMPccXADD support
+  UNSPECV_CMPCCXADD
 ])
 
 (define_expand "sse2_lfence"
        (any_logic:SWI (match_dup 0) (match_dup 1)))]
   ""
   "lock{%;} %K2<logic>{<imodesuffix>}\t{%1, %0|%0, %1}")
+
+;; CMPCCXADD
+
+(define_insn "cmpccxadd_<mode>"
+  [(set (match_operand:SWI48x 0 "register_operand" "=r")
+       (unspec_volatile:SWI48x
+         [(match_operand:SWI48x 1 "memory_operand" "+m")
+          (match_operand:SWI48x 2 "register_operand" "0")
+          (match_operand:SWI48x 3 "register_operand" "r")
+          (match_operand:SI 4 "const_0_to_15_operand" "n")]
+         UNSPECV_CMPCCXADD))
+   (set (match_dup 1)
+       (unspec_volatile:SWI48x [(const_int 0)] UNSPECV_CMPCCXADD))
+   (clobber (reg:CC FLAGS_REG))]
+  "TARGET_CMPCCXADD && TARGET_64BIT"
+{
+  char buf[128];
+  const char *ops = "cmp%sxadd\t{%%3, %%0, %%1|%%1, %%0, %%3}";
+  char const *cc[16] = {"o" ,"no", "b", "nb", "z", "nz", "be", "nbe",
+                       "s", "ns", "p", "np", "l", "nl", "le", "nle"};
+
+  snprintf (buf, sizeof (buf), ops, cc[INTVAL (operands[4])]);
+  output_asm_insn (buf, operands);
+  return "";
+})
index e0be01d5e7889f47b77af8ef322ce8f0ce766beb..a84fbe9137d5b2476ac5b805633d626c7054dc2e 100644 (file)
@@ -52,6 +52,8 @@
 
 #include <clzerointrin.h>
 
+#include <cmpccxaddintrin.h>
+
 #include <enqcmdintrin.h>
 
 #include <fxsrintrin.h>
index 53478b7c4d7131f0b43114fb62cb31f5469f7e49..89d1d143d9f2a0bfbcfd966b8dfcfe58b88de4fa 100644 (file)
@@ -7075,6 +7075,11 @@ Enable/disable the generation of the AVXVNNIINT8 instructions.
 @cindex @code{target("avxneconvert")} function attribute, x86
 Enable/disable the generation of the AVXNECONVERT instructions.
 
+@item cmpccxadd
+@itemx no-cmpccxadd
+@cindex @code{target("cmpccxadd")} function attribute, x86
+Enable/disable the generation of the CMPccXADD instructions.
+
 @item cld
 @itemx no-cld
 @cindex @code{target("cld")} function attribute, x86
index 2b29db831aee04c4e118c485ebf56ddf4427e13d..834f010dfee5ef23edfcb72adcae5fdda2edd6b1 100644 (file)
@@ -1437,7 +1437,7 @@ See RS/6000 and PowerPC Options.
 -mavx5124fmaps  -mavx512vnni  -mavx5124vnniw  -mprfchw  -mrdpid @gol
 -mrdseed  -msgx -mavx512vp2intersect -mserialize -mtsxldtrk@gol
 -mamx-tile  -mamx-int8  -mamx-bf16 -muintr -mhreset -mavxvnni@gol
--mavx512fp16 -mavxifma -mavxvnniint8 -mavxneconvert @gol
+-mavx512fp16 -mavxifma -mavxvnniint8 -mavxneconvert -mcmpccxadd @gol
 -mcldemote  -mms-bitfields  -mno-align-stringops  -minline-all-stringops @gol
 -minline-stringops-dynamically  -mstringop-strategy=@var{alg} @gol
 -mkl -mwidekl @gol
@@ -32970,6 +32970,9 @@ preferred alignment to @option{-mpreferred-stack-boundary=2}.
 @need 200
 @itemx -mavxneconvert
 @opindex mavxneconvert
+@need 200
+@itemx -mcmpccxadd
+@opindex mcmpccxadd
 These switches enable the use of instructions in the MMX, SSE,
 SSE2, SSE3, SSSE3, SSE4, SSE4A, SSE4.1, SSE4.2, AVX, AVX2, AVX512F, AVX512PF,
 AVX512ER, AVX512CD, AVX512VL, AVX512BW, AVX512DQ, AVX512IFMA, AVX512VBMI, SHA,
@@ -32980,8 +32983,9 @@ XSAVEOPT, XSAVEC, XSAVES, RTM, HLE, TBM, MWAITX, CLZERO, PKU, AVX512VBMI2,
 GFNI, VAES, WAITPKG, VPCLMULQDQ, AVX512BITALG, MOVDIRI, MOVDIR64B, AVX512BF16,
 ENQCMD, AVX512VPOPCNTDQ, AVX5124FMAPS, AVX512VNNI, AVX5124VNNIW, SERIALIZE,
 UINTR, HRESET, AMXTILE, AMXINT8, AMXBF16, KL, WIDEKL, AVXVNNI, AVX512FP16,
-AVXIFMA, AVXVNNIINT8, AVXNECONVERT or CLDEMOTE extended instruction sets. Each
-has a corresponding @option{-mno-} option to disable use of these instructions.
+AVXIFMA, AVXVNNIINT8, AVXNECONVERT, CMPCCXADD or CLDEMOTE extended instruction
+sets. Each has a corresponding @option{-mno-} option to disable use of these
+instructions.
 
 These extensions are also available as built-in functions: see
 @ref{x86 Built-in Functions}, for details of the functions enabled and
index a12175b649848c7dd7802ae960f1360cd9261b88..714595d33bf320d1ff7e99ae3e9457f6bbed6589 100644 (file)
@@ -2511,6 +2511,9 @@ Target supports the execution of @code{amx-bf16} instructions.
 @item cell_hw
 Test system can execute AltiVec and Cell PPU instructions.
 
+@item cmpccxadd
+Target supports the execution of @code{cmpccxadd} instructions.
+
 @item coldfire_fpu
 Target uses a ColdFire FPU.
 
index dd3e71f25edbec9a8a21e1d0bc81ff0eb57639a1..f7dbbbbf619570f2480bd9a21b1d8706a59dee72 100644 (file)
@@ -1,5 +1,5 @@
 /* { dg-do compile { target i?86-*-* x86_64-*-* } } */
-/* { dg-options "-O -pedantic-errors -march=k8 -msse4a -m3dnow -mavx -mavx2 -mfma4 -mxop -maes -mpclmul -mpopcnt -mabm -mlzcnt -mbmi -mbmi2 -mtbm -mlwp -mfsgsbase -mrdrnd -mf16c -mfma -mrtm -mrdseed -mprfchw -madx -mfxsr -mxsaveopt -mavx512f -mavx512er -mavx512cd -mavx512pf -msha -mprefetchwt1 -mxsavec -mxsaves -mclflushopt  -mavx512dq -mavx512bw -mavx512vl -mavx512ifma -mavx512vbmi -mavx512vbmi2 -mavx5124fmaps -mavx5124vnniw -mavx512vpopcntdq -mclwb -mmwaitx -mclzero -mpku -msgx -mrdpid -mgfni -mavx512bitalg -mpconfig -mwbnoinvd -mavx512bf16 -menqcmd -mavx512vp2intersect -mserialize -mtsxldtrk -mamx-tile -mamx-int8 -mamx-bf16 -mkl -mwidekl -mavxvnni -mavx512fp16 -mavxifma -mavxvnniint8 -mavxneconvert" } */
+/* { dg-options "-O -pedantic-errors -march=k8 -msse4a -m3dnow -mavx -mavx2 -mfma4 -mxop -maes -mpclmul -mpopcnt -mabm -mlzcnt -mbmi -mbmi2 -mtbm -mlwp -mfsgsbase -mrdrnd -mf16c -mfma -mrtm -mrdseed -mprfchw -madx -mfxsr -mxsaveopt -mavx512f -mavx512er -mavx512cd -mavx512pf -msha -mprefetchwt1 -mxsavec -mxsaves -mclflushopt  -mavx512dq -mavx512bw -mavx512vl -mavx512ifma -mavx512vbmi -mavx512vbmi2 -mavx5124fmaps -mavx5124vnniw -mavx512vpopcntdq -mclwb -mmwaitx -mclzero -mpku -msgx -mrdpid -mgfni -mavx512bitalg -mpconfig -mwbnoinvd -mavx512bf16 -menqcmd -mavx512vp2intersect -mserialize -mtsxldtrk -mamx-tile -mamx-int8 -mamx-bf16 -mkl -mwidekl -mavxvnni -mavx512fp16 -mavxifma -mavxvnniint8 -mavxneconvert -mcmpccxadd" } */
 
 /* Test that {,x,e,p,t,s,w,a,b,i}mmintrin.h, mm3dnow.h, fma4intrin.h,
    xopintrin.h, abmintrin.h, bmiintrin.h, tbmintrin.h, lwpintrin.h,
index cd7045cc4e4350cab397c2d8850c4f80ef6d178c..2ac5d9f2df54d14afb5d7cba0b43c59a52f6469d 100644 (file)
@@ -1,5 +1,5 @@
 /* { dg-do compile { target i?86-*-* x86_64-*-* } } */
-/* { dg-options "-O -fkeep-inline-functions -march=k8 -msse4a -m3dnow -mavx -mavx2 -mfma4 -mxop -maes -mpclmul -mpopcnt -mabm -mlzcnt -mbmi -mbmi2 -mtbm -mlwp -mfsgsbase -mrdrnd -mf16c -mfma -mrtm -mrdseed -mprfchw -madx -mfxsr -mxsaveopt -mavx512f -mavx512er -mavx512cd -mavx512pf -msha -mprefetchwt1 -mxsavec -mxsaves -mclflushopt -mavx512dq -mavx512bw -mavx512vl -mavx512ifma -mavx512vbmi -mavx512vbmi2 -mavx5124fmaps -mavx5124vnniw -mavx512vpopcntdq -mclwb -mmwaitx -mclzero -mpku -msgx -mrdpid -mgfni -mavx512bitalg -mpconfig -mwbnoinvd -mavx512bf16 -menqcmd -mavx512vp2intersect -mserialize -mtsxldtrk -mamx-tile -mamx-int8 -mamx-bf16 -mkl -mwidekl -mavxvnni -mavx512fp16 -mavxifma -mavxvnniint8 -mavxneconvert" } */
+/* { dg-options "-O -fkeep-inline-functions -march=k8 -msse4a -m3dnow -mavx -mavx2 -mfma4 -mxop -maes -mpclmul -mpopcnt -mabm -mlzcnt -mbmi -mbmi2 -mtbm -mlwp -mfsgsbase -mrdrnd -mf16c -mfma -mrtm -mrdseed -mprfchw -madx -mfxsr -mxsaveopt -mavx512f -mavx512er -mavx512cd -mavx512pf -msha -mprefetchwt1 -mxsavec -mxsaves -mclflushopt -mavx512dq -mavx512bw -mavx512vl -mavx512ifma -mavx512vbmi -mavx512vbmi2 -mavx5124fmaps -mavx5124vnniw -mavx512vpopcntdq -mclwb -mmwaitx -mclzero -mpku -msgx -mrdpid -mgfni -mavx512bitalg -mpconfig -mwbnoinvd -mavx512bf16 -menqcmd -mavx512vp2intersect -mserialize -mtsxldtrk -mamx-tile -mamx-int8 -mamx-bf16 -mkl -mwidekl -mavxvnni -mavx512fp16 -mavxifma -mavxvnniint8 -mavxneconvert -mcmpccxadd" } */
 
 /* Test that {,x,e,p,t,s,w,a,b,i}mmintrin.h, mm3dnow.h, fma4intrin.h,
    xopintrin.h, abmintrin.h, bmiintrin.h, tbmintrin.h, lwpintrin.h,
index 154e7b3b107d2eca987eab74e63de3e725a006a9..051a1b59b5b0151bbf2a56fda34151b63b6832ad 100644 (file)
 #define __builtin_ia32_bextri_u32(X, Y) __builtin_ia32_bextri_u32 (X, 1)
 #define __builtin_ia32_bextri_u64(X, Y) __builtin_ia32_bextri_u64 (X, 1)
 
+/* cmpccxadd.h */
+#define __builtin_ia32_cmpccxadd(A, B, C, D) __builtin_ia32_cmpccxadd(A, B, C, 1)
+#define __builtin_ia32_cmpccxadd64(A, B, C, D) __builtin_ia32_cmpccxadd64(A, B, C, 1)
+
 #include <wmmintrin.h>
 #include <immintrin.h>
 #include <mm3dnow.h>
diff --git a/gcc/testsuite/gcc.target/i386/cmpccxadd-1.c b/gcc/testsuite/gcc.target/i386/cmpccxadd-1.c
new file mode 100644 (file)
index 0000000..c825717
--- /dev/null
@@ -0,0 +1,61 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-O2 -mcmpccxadd" } */
+/* { dg-final { scan-assembler-times "cmpoxadd\[ \\t\]" 2 } } */
+/* { dg-final { scan-assembler-times "cmpnoxadd\[ \\t\]" 2 } } */
+/* { dg-final { scan-assembler-times "cmpbxadd\[ \\t\]" 2 } } */
+/* { dg-final { scan-assembler-times "cmpnbxadd\[ \\t\]" 2 } } */
+/* { dg-final { scan-assembler-times "cmpzxadd\[ \\t\]" 2 } } */
+/* { dg-final { scan-assembler-times "cmpnzxadd\[ \\t\]" 2 } } */
+/* { dg-final { scan-assembler-times "cmpbexadd\[ \\t\]" 2 } } */
+/* { dg-final { scan-assembler-times "cmpnbexadd\[ \\t\]" 2 } } */
+/* { dg-final { scan-assembler-times "cmpsxadd\[ \\t\]" 2 } } */
+/* { dg-final { scan-assembler-times "cmpnsxadd\[ \\t\]" 2 } } */
+/* { dg-final { scan-assembler-times "cmppxadd\[ \\t\]" 2 } } */
+/* { dg-final { scan-assembler-times "cmpnpxadd\[ \\t\]" 2 } } */
+/* { dg-final { scan-assembler-times "cmplxadd\[ \\t\]" 2 } } */
+/* { dg-final { scan-assembler-times "cmpnlxadd\[ \\t\]" 2 } } */
+/* { dg-final { scan-assembler-times "cmplexadd\[ \\t\]" 2 } } */
+/* { dg-final { scan-assembler-times "cmpnlexadd\[ \\t\]" 2 } } */
+#include <x86gprintrin.h>
+
+int *a;
+int b, c;
+long long *d;
+long long e, f;
+
+void extern
+cmpccxadd_test(void)
+{
+  b = __cmpccxadd_epi32 (a, b, c, _CMPCCX_O);
+  e = __cmpccxadd_epi64 (d, e, f, _CMPCCX_O);
+  b = __cmpccxadd_epi32 (a, b, c, _CMPCCX_NO);
+  e = __cmpccxadd_epi64 (d, e, f, _CMPCCX_NO);
+  b = __cmpccxadd_epi32 (a, b, c, _CMPCCX_B);
+  e = __cmpccxadd_epi64 (d, e, f, _CMPCCX_B);
+  b = __cmpccxadd_epi32 (a, b, c, _CMPCCX_NB);
+  e = __cmpccxadd_epi64 (d, e, f, _CMPCCX_NB);
+  b = __cmpccxadd_epi32 (a, b, c, _CMPCCX_Z);
+  e = __cmpccxadd_epi64 (d, e, f, _CMPCCX_Z);
+  b = __cmpccxadd_epi32 (a, b, c, _CMPCCX_NZ);
+  e = __cmpccxadd_epi64 (d, e, f, _CMPCCX_NZ);
+  b = __cmpccxadd_epi32 (a, b, c, _CMPCCX_BE);
+  e = __cmpccxadd_epi64 (d, e, f, _CMPCCX_BE);
+  b = __cmpccxadd_epi32 (a, b, c, _CMPCCX_NBE);
+  e = __cmpccxadd_epi64 (d, e, f, _CMPCCX_NBE);
+  b = __cmpccxadd_epi32 (a, b, c, _CMPCCX_S);
+  e = __cmpccxadd_epi64 (d, e, f, _CMPCCX_S);
+  b = __cmpccxadd_epi32 (a, b, c, _CMPCCX_NS);
+  e = __cmpccxadd_epi64 (d, e, f, _CMPCCX_NS);
+  b = __cmpccxadd_epi32 (a, b, c, _CMPCCX_P);
+  e = __cmpccxadd_epi64 (d, e, f, _CMPCCX_P);
+  b = __cmpccxadd_epi32 (a, b, c, _CMPCCX_NP);
+  e = __cmpccxadd_epi64 (d, e, f, _CMPCCX_NP);
+  b = __cmpccxadd_epi32 (a, b, c, _CMPCCX_L);
+  e = __cmpccxadd_epi64 (d, e, f, _CMPCCX_L);
+  b = __cmpccxadd_epi32 (a, b, c, _CMPCCX_NL);
+  e = __cmpccxadd_epi64 (d, e, f, _CMPCCX_NL);
+  b = __cmpccxadd_epi32 (a, b, c, _CMPCCX_LE);
+  e = __cmpccxadd_epi64 (d, e, f, _CMPCCX_LE);
+  b = __cmpccxadd_epi32 (a, b, c, _CMPCCX_NLE);
+  e = __cmpccxadd_epi64 (d, e, f, _CMPCCX_NLE);
+}
diff --git a/gcc/testsuite/gcc.target/i386/cmpccxadd-2.c b/gcc/testsuite/gcc.target/i386/cmpccxadd-2.c
new file mode 100644 (file)
index 0000000..e713344
--- /dev/null
@@ -0,0 +1,138 @@
+/* { dg-do run { target { ! ia32 } } } */
+/* { dg-options "-O2 -mcmpccxadd" } */
+/* { dg-require-effective-target cmpccxadd } */
+
+#include <stdlib.h>
+#include <x86gprintrin.h>
+
+int
+main()
+{
+  if (!__builtin_cpu_supports("cmpccxadd"))
+    return 0;
+       
+  int srcdest1[16] = { -2147483648,1,1,1,1,2,1,2,1,2,4,2,1,1,1,2 };
+  int srcdest2[16] = { 1,1,2,1,1,1,1,1,2,1,1,1,2,1,1,1 };
+  int src3[16] = { 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 };
+  int _srcdest1[16], _srcdest2[16], res[16], cond[16];
+  long long srcdest1_64[16] = { -9223372036854775807LL-1,1,1,1,1,2,1,2,1,2,4,2,1,1,1,2 };
+  long long srcdest2_64[16] = { 1,1,2,1,1,1,1,1,2,1,1,1,2,1,1,1 };
+  long long src3_64[16] = { 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 };
+  long long _srcdest1_64[16], _srcdest2_64[16], res_64[16], cond_64[16];
+
+  int tmp2[16];
+  long long tmp2_64[16];
+
+  int cf[16] = { 0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0 };
+  int of[16] = { 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 };
+  int sf[16] = { 0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0 };
+  int zf[16] = { 0,0,0,0,1,0,1,0,0,0,0,0,0,0,1,0 };
+  int af[16] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 };
+  int pf[16] = { 0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0 };
+
+  for (int i = 0; i < 16; i++)
+  {
+    tmp2[i] = srcdest1[i] + src3[i];
+    tmp2_64[i] = srcdest1_64[i] + src3_64[i];
+  }
+
+  cond[0] = of[0] == 1 ? 1 : 0;
+  cond[1] = of[1] == 0 ? 1 : 0;
+  cond[2] = cf[2] == 1 ? 1 : 0;
+  cond[3] = cf[3] == 0 ? 1 : 0;
+  cond[4] = zf[4] == 1 ? 1 : 0;
+  cond[5] = zf[5] == 0 ? 1 : 0;
+  cond[6] = (cf[6] || zf[6]) == 1 ? 1 : 0;
+  cond[7] = (cf[7] || zf[7]) == 0 ? 1 : 0;
+  cond[8] = sf[8] == 1 ? 1 : 0;
+  cond[9] = sf[9] == 0 ? 1 : 0;
+  cond[10] = pf[10] == 1 ? 1 : 0;
+  cond[11] = pf[11] == 0 ? 1 : 0;
+  cond[12] = ((sf[12] && !of[12]) || (!sf[12] && of[12])) == 1 ? 1 : 0;
+  cond[13] = ((sf[13] && !of[13]) || (!sf[13] && of[13])) == 0 ? 1 : 0;
+  cond[14] = (((sf[14] && !of[14]) || (!sf[14] && of[14])) || zf[14]) == 1 ? 1 : 0;
+  cond[15] = (((sf[15] && !of[15]) || (!sf[15] && of[15])) || zf[15]) == 0 ? 1 : 0;
+
+  cond_64[0] = of[0] == 1 ? 1 : 0;
+  cond_64[1] = of[1] == 0 ? 1 : 0;
+  cond_64[2] = cf[2] == 1 ? 1 : 0;
+  cond_64[3] = cf[3] == 0 ? 1 : 0;
+  cond_64[4] = zf[4] == 1 ? 1 : 0;
+  cond_64[5] = zf[5] == 0 ? 1 : 0;
+  cond_64[6] = (cf[6] || zf[6]) == 1 ? 1 : 0;
+  cond_64[7] = (cf[7] || zf[7]) == 0 ? 1 : 0;
+  cond_64[8] = sf[8] == 1 ? 1 : 0;
+  cond_64[9] = sf[9] == 0 ? 1 : 0;
+  cond_64[10] = pf[10] == 1 ? 1 : 0;
+  cond_64[11] = pf[11] == 0 ? 1 : 0;
+  cond_64[12] = ((sf[12] && !of[12]) || (!sf[12] && of[12])) == 1 ? 1 : 0;
+  cond_64[13] = ((sf[13] && !of[13]) || (!sf[13] && of[13])) == 0 ? 1 : 0;
+  cond_64[14] = (((sf[14] && !of[14]) || (!sf[14] && of[14])) || zf[14]) == 1 ? 1 : 0;
+  cond_64[15] = (((sf[15] && !of[15]) || (!sf[15] && of[15])) || zf[15]) == 0 ? 1 : 0;
+
+  for (int i = 0; i < 16; i++)
+  {
+    if (cond[i] == 1)
+    {
+      _srcdest1[i] = tmp2[i];
+    }
+    else
+    {
+      _srcdest1[i] = srcdest1[i];
+    }
+    if (cond_64[i] == 1)
+    {
+      _srcdest1_64[i] = tmp2_64[i];
+    }
+    else
+    {
+      _srcdest1_64[i] = srcdest1_64[i];
+    }
+    _srcdest2[i] = srcdest1[i];
+    _srcdest2_64[i] = srcdest1_64[i];
+  }
+
+  res[0] = __cmpccxadd_epi32 (&srcdest1[0], srcdest2[0], src3[0], _CMPCCX_O);
+  res[1] = __cmpccxadd_epi32 (&srcdest1[1], srcdest2[1], src3[1], _CMPCCX_NO);
+  res[2] = __cmpccxadd_epi32 (&srcdest1[2], srcdest2[2], src3[2], _CMPCCX_B);
+  res[3] = __cmpccxadd_epi32 (&srcdest1[3], srcdest2[3], src3[3], _CMPCCX_NB);
+  res[4] = __cmpccxadd_epi32 (&srcdest1[4], srcdest2[4], src3[4], _CMPCCX_Z);
+  res[5] = __cmpccxadd_epi32 (&srcdest1[5], srcdest2[5], src3[5], _CMPCCX_NZ);
+  res[6] = __cmpccxadd_epi32 (&srcdest1[6], srcdest2[6], src3[6], _CMPCCX_BE);
+  res[7] = __cmpccxadd_epi32 (&srcdest1[7], srcdest2[7], src3[7], _CMPCCX_NBE);
+  res[8] = __cmpccxadd_epi32 (&srcdest1[8], srcdest2[8], src3[8], _CMPCCX_S);
+  res[9] = __cmpccxadd_epi32 (&srcdest1[9], srcdest2[9], src3[9], _CMPCCX_NS);
+  res[10] = __cmpccxadd_epi32 (&srcdest1[10], srcdest2[10], src3[10], _CMPCCX_P);
+  res[11] = __cmpccxadd_epi32 (&srcdest1[11], srcdest2[11], src3[11], _CMPCCX_NP);
+  res[12] = __cmpccxadd_epi32 (&srcdest1[12], srcdest2[12], src3[12], _CMPCCX_L);
+  res[13] = __cmpccxadd_epi32 (&srcdest1[13], srcdest2[13], src3[13], _CMPCCX_NL);
+  res[14] = __cmpccxadd_epi32 (&srcdest1[14], srcdest2[14], src3[14], _CMPCCX_LE);
+  res[15] = __cmpccxadd_epi32 (&srcdest1[15], srcdest2[15], src3[15], _CMPCCX_NLE);
+
+  res_64[0] = __cmpccxadd_epi64 (&srcdest1_64[0], srcdest2_64[0], src3_64[0], _CMPCCX_O);
+  res_64[1] = __cmpccxadd_epi64 (&srcdest1_64[1], srcdest2_64[1], src3_64[1], _CMPCCX_NO);
+  res_64[2] = __cmpccxadd_epi64 (&srcdest1_64[2], srcdest2_64[2], src3_64[2], _CMPCCX_B);
+  res_64[3] = __cmpccxadd_epi64 (&srcdest1_64[3], srcdest2_64[3], src3_64[3], _CMPCCX_NB);
+  res_64[4] = __cmpccxadd_epi64 (&srcdest1_64[4], srcdest2_64[4], src3_64[4], _CMPCCX_Z);
+  res_64[5] = __cmpccxadd_epi64 (&srcdest1_64[5], srcdest2_64[5], src3_64[5], _CMPCCX_NZ);
+  res_64[6] = __cmpccxadd_epi64 (&srcdest1_64[6], srcdest2_64[6], src3_64[6], _CMPCCX_BE);
+  res_64[7] = __cmpccxadd_epi64 (&srcdest1_64[7], srcdest2_64[7], src3_64[7], _CMPCCX_NBE);
+  res_64[8] = __cmpccxadd_epi64 (&srcdest1_64[8], srcdest2_64[8], src3_64[8], _CMPCCX_S);
+  res_64[9] = __cmpccxadd_epi64 (&srcdest1_64[9], srcdest2_64[9], src3_64[9], _CMPCCX_NS);
+  res_64[10] = __cmpccxadd_epi64 (&srcdest1_64[10], srcdest2_64[10], src3_64[10], _CMPCCX_P);
+  res_64[11] = __cmpccxadd_epi64 (&srcdest1_64[11], srcdest2_64[11], src3_64[11], _CMPCCX_NP);
+  res_64[12] = __cmpccxadd_epi64 (&srcdest1_64[12], srcdest2_64[12], src3_64[12], _CMPCCX_L);
+  res_64[13] = __cmpccxadd_epi64 (&srcdest1_64[13], srcdest2_64[13], src3_64[13], _CMPCCX_NL);
+  res_64[14] = __cmpccxadd_epi64 (&srcdest1_64[14], srcdest2_64[14], src3_64[14], _CMPCCX_LE);
+  res_64[15] = __cmpccxadd_epi64 (&srcdest1_64[15], srcdest2_64[15], src3_64[15], _CMPCCX_NLE);
+
+  for (int i = 0; i < 16; i++)
+  {
+    if ((srcdest1[i] != _srcdest1[i]) || (res[i] != _srcdest2[i]))
+      abort();
+    if ((srcdest1_64[i] != _srcdest1_64[i]) || (res_64[i] != _srcdest2_64[i]))
+      abort();
+  }
+
+  return 0;
+}
index 5655c5b191945e394114430fbf8a50bc7affddec..ab748fad994cac4a970149b51256c733cf33046d 100644 (file)
@@ -83,6 +83,7 @@ extern void test_avx512fp16 (void)            __attribute__((__target__("avx512fp16")));
 extern void test_avxifma (void)                        __attribute__((__target__("avxifma")));
 extern void test_avxvnniint8 (void)            __attribute__((__target__("avxvnniint8")));
 extern void test_avxneconvert (void)           __attribute__((__target__("avxneconvert")));
+extern void test_cmpccxadd (void)              __attribute__((__target__("cmpccxadd")));
 
 extern void test_no_sgx (void)                 __attribute__((__target__("no-sgx")));
 extern void test_no_avx5124fmaps(void)         __attribute__((__target__("no-avx5124fmaps")));
@@ -167,6 +168,7 @@ extern void test_no_avx512fp16 (void)               __attribute__((__target__("no-avx512fp16"
 extern void test_no_avxifma (void)             __attribute__((__target__("no-avxifma")));
 extern void test_no_avxvnniint8 (void)         __attribute__((__target__("no-avxvnniint8")));
 extern void test_no_avxneconvert (void)                __attribute__((__target__("no-avxneconvert")));
+extern void test_no_cmpccxadd (void)            __attribute__((__target__("no-cmpccxadd")));
 
 extern void test_arch_nocona (void)            __attribute__((__target__("arch=nocona")));
 extern void test_arch_core2 (void)             __attribute__((__target__("arch=core2")));
index b9cdfb690d1c2e148900157f03229cdadcccd70e..e947b4347f4b3af7acd824d06ae8d3692a8a5a29 100644 (file)
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-O2 -Werror-implicit-function-declaration -march=k8 -msse4a -m3dnow -mavx -mavx2 -mfma4 -mxop -maes -mpclmul -mpopcnt -mabm -mlzcnt -mbmi -mbmi2 -mtbm -mlwp -mfsgsbase -mrdrnd -mf16c -mfma -mrtm -mrdseed -mprfchw -madx -mfxsr -mxsaveopt -mavx512f -mavx512er -mavx512cd -mavx512pf -msha -mprefetchwt1 -mxsavec -mxsaves -mclflushopt -mavx512vl -mavx512dq -mavx512bw -mavx512vbmi -mavx512vbmi2 -mavx512ifma -mavx5124fmaps -mavx5124vnniw -mavx512vpopcntdq -mavx512vp2intersect -mclwb -mmwaitx -mclzero -mpku -msgx -mrdpid -mgfni -mavx512bitalg -mpconfig -mwbnoinvd -mavx512bf16 -menqcmd -mserialize -mtsxldtrk -mamx-tile -mamx-int8 -mamx-bf16 -mkl -mwidekl -mavxvnni -mavx512fp16 -mavxifma -mavxvnniint8 -mavxneconvert" } */
+/* { dg-options "-O2 -Werror-implicit-function-declaration -march=k8 -msse4a -m3dnow -mavx -mavx2 -mfma4 -mxop -maes -mpclmul -mpopcnt -mabm -mlzcnt -mbmi -mbmi2 -mtbm -mlwp -mfsgsbase -mrdrnd -mf16c -mfma -mrtm -mrdseed -mprfchw -madx -mfxsr -mxsaveopt -mavx512f -mavx512er -mavx512cd -mavx512pf -msha -mprefetchwt1 -mxsavec -mxsaves -mclflushopt -mavx512vl -mavx512dq -mavx512bw -mavx512vbmi -mavx512vbmi2 -mavx512ifma -mavx5124fmaps -mavx5124vnniw -mavx512vpopcntdq -mavx512vp2intersect -mclwb -mmwaitx -mclzero -mpku -msgx -mrdpid -mgfni -mavx512bitalg -mpconfig -mwbnoinvd -mavx512bf16 -menqcmd -mserialize -mtsxldtrk -mamx-tile -mamx-int8 -mamx-bf16 -mkl -mwidekl -mavxvnni -mavx512fp16 -mavxifma -mavxvnniint8 -mavxneconvert -mcmpccxadd" } */
 /* { dg-add-options bind_pic_locally } */
 
 #include <mm_malloc.h>
 #define __builtin_ia32_vpclmulqdq_v2di(A, B, C)  __builtin_ia32_vpclmulqdq_v2di(A, B, 1) 
 #define __builtin_ia32_vpclmulqdq_v8di(A, B, C)  __builtin_ia32_vpclmulqdq_v8di(A, B, 1) 
 
+/* cmpccxadd.h */
+#define __builtin_ia32_cmpccxadd(A, B, C, D) __builtin_ia32_cmpccxadd(A, B, C, 1)
+#define __builtin_ia32_cmpccxadd64(A, B, C, D) __builtin_ia32_cmpccxadd64(A, B, C, 1)
+
 #include <x86intrin.h>
index 898dde80c8ff6e1b5fd27e6a2b826be6011ca2b4..757ba9c9a7dc8525dfc06c77827bc7f09e208d43 100644 (file)
 #define __builtin_ia32_vpclmulqdq_v2di(A, B, C)  __builtin_ia32_vpclmulqdq_v2di(A, B, 1) 
 #define __builtin_ia32_vpclmulqdq_v8di(A, B, C)  __builtin_ia32_vpclmulqdq_v8di(A, B, 1) 
 
-#pragma GCC target ("sse4a,3dnow,avx,avx2,fma4,xop,aes,pclmul,popcnt,abm,lzcnt,bmi,bmi2,tbm,lwp,fsgsbase,rdrnd,f16c,fma,rtm,rdseed,prfchw,adx,fxsr,xsaveopt,avx512f,avx512er,avx512cd,avx512pf,sha,prefetchwt1,xsavec,xsaves,clflushopt,avx512bw,avx512dq,avx512vl,avx512vbmi,avx512ifma,avx5124fmaps,avx5124vnniw,avx512vpopcntdq,clwb,mwaitx,clzero,pku,sgx,rdpid,gfni,avx512vbmi2,vpclmulqdq,avx512bitalg,pconfig,wbnoinvd,avx512bf16,enqcmd,avx512vp2intersect,serialize,tsxldtrk,amx-tile,amx-int8,amx-bf16,kl,widekl,avxvnni,avx512fp16,avxifma,avxvnniint8,avxneconvert")
+/* cmpccxadd.h */
+#define __builtin_ia32_cmpccxadd(A, B, C, D) __builtin_ia32_cmpccxadd(A, B, C, 1)
+#define __builtin_ia32_cmpccxadd64(A, B, C, D) __builtin_ia32_cmpccxadd64(A, B, C, 1)
+
+#pragma GCC target ("sse4a,3dnow,avx,avx2,fma4,xop,aes,pclmul,popcnt,abm,lzcnt,bmi,bmi2,tbm,lwp,fsgsbase,rdrnd,f16c,fma,rtm,rdseed,prfchw,adx,fxsr,xsaveopt,avx512f,avx512er,avx512cd,avx512pf,sha,prefetchwt1,xsavec,xsaves,clflushopt,avx512bw,avx512dq,avx512vl,avx512vbmi,avx512ifma,avx5124fmaps,avx5124vnniw,avx512vpopcntdq,clwb,mwaitx,clzero,pku,sgx,rdpid,gfni,avx512vbmi2,vpclmulqdq,avx512bitalg,pconfig,wbnoinvd,avx512bf16,enqcmd,avx512vp2intersect,serialize,tsxldtrk,amx-tile,amx-int8,amx-bf16,kl,widekl,avxvnni,avx512fp16,avxifma,avxvnniint8,avxneconvert,cmpccxadd")
 
 #include <x86intrin.h>
index 293be094b787c238444ee7540df39fbe00dc3813..76de89d0cb701d718b8dd068dfd4834714c4245c 100644 (file)
@@ -1,7 +1,7 @@
 /* Test that <x86gprintrin.h> is usable with -O -std=c89 -pedantic-errors.  */
 /* { dg-do compile } */
 /* { dg-options "-O -std=c89 -pedantic-errors -march=x86-64 -madx -mbmi -mbmi2 -mcldemote -mclflushopt -mclwb -mclzero -menqcmd -mfsgsbase -mfxsr -mhreset -mlzcnt -mlwp -mmovdiri -mmwaitx -mpconfig -mpopcnt -mpku -mptwrite -mrdpid -mrdrnd -mrdseed -mrtm -mserialize -msgx -mshstk -mtbm -mtsxldtrk -mwaitpkg -mwbnoinvd -mxsave -mxsavec -mxsaveopt -mxsaves -mno-sse -mno-mmx" } */
-/* { dg-additional-options "-muintr" { target { ! ia32 } } }  */
+/* { dg-additional-options "-mcmpccxadd -muintr" { target { ! ia32 } } }  */
 
 #include <x86gprintrin.h>
 
index c63302757466d98e99325bec4dafef1fbfe57046..aefad77f864e206fd0edb064bb16899a1dca74a3 100644 (file)
@@ -1,7 +1,7 @@
 /* { dg-do compile } */
 /* { dg-options "-O2 -Werror-implicit-function-declaration -march=x86-64 -madx -mbmi -mbmi2 -mcldemote -mclflushopt -mclwb -mclzero -menqcmd -mfsgsbase -mfxsr -mhreset -mlzcnt -mlwp -mmovdiri -mmwaitx -mpconfig -mpopcnt -mpku -mptwrite -mrdpid -mrdrnd -mrdseed -mrtm -mserialize -msgx -mshstk -mtbm -mtsxldtrk -mwaitpkg -mwbnoinvd -mxsave -mxsavec -mxsaveopt -mxsaves -mno-sse -mno-mmx" } */
 /* { dg-add-options bind_pic_locally } */
-/* { dg-additional-options "-muintr" { target { ! ia32 } } }  */
+/* { dg-additional-options "-mcmpccxadd -muintr" { target { ! ia32 } } }  */
 
 /* Test that the intrinsics in <x86gprintrin.h> compile with optimization.
    All of them are defined as inline functions that reference the proper
@@ -28,4 +28,8 @@
 /* rtmintrin.h */
 #define __builtin_ia32_xabort(N) __builtin_ia32_xabort(1)
 
+/* cmpccxadd.h */
+#define __builtin_ia32_cmpccxadd(A, B, C, D) __builtin_ia32_cmpccxadd(A, B, C, 1)
+#define __builtin_ia32_cmpccxadd64(A, B, C, D) __builtin_ia32_cmpccxadd64(A, B, C, 1)
+
 #include <x86gprintrin.h>
index 3a7e1f4a10d1007caa17e6c500ac4216aa4b7c5d..261c9180aa07fe05475a6f4e9b0f5dc95e23cd5b 100644 (file)
@@ -1,7 +1,7 @@
 /* { dg-do compile } */
 /* { dg-options "-O0 -Werror-implicit-function-declaration -march=x86-64 -madx -mbmi -mbmi2 -mcldemote -mclflushopt -mclwb -mclzero -menqcmd -mfsgsbase -mfxsr -mhreset -mlzcnt -mlwp -mmovdiri -mmwaitx -mpconfig -mpopcnt -mpku -mptwrite -mrdpid -mrdrnd -mrdseed -mrtm -mserialize -msgx -mshstk -mtbm -mtsxldtrk -mwaitpkg -mwbnoinvd -mxsave -mxsavec -mxsaveopt -mxsaves -mno-sse -mno-mmx" } */
 /* { dg-add-options bind_pic_locally } */
-/* { dg-additional-options "-muintr" { target { ! ia32 } } }  */
+/* { dg-additional-options "-mcmpccxadd -muintr" { target { ! ia32 } } }  */
 
 /* Test that the intrinsics in <x86gprintrin.h> compile without optimization.
    All of them are defined as inline functions that reference the proper
index d8a6126e5dc6866c35ab6df4d87ab72de244436e..7f76b87093480731c6432ea780db27097404a95b 100644 (file)
@@ -15,7 +15,7 @@
 
 #ifndef DIFFERENT_PRAGMAS
 #ifdef __x86_64__
-#pragma GCC target ("adx,bmi,bmi2,fsgsbase,fxsr,hreset,lwp,lzcnt,popcnt,rdrnd,rdseed,tbm,rtm,serialize,tsxldtrk,uintr,xsaveopt")
+#pragma GCC target ("adx,bmi,bmi2,cmpccxadd,fsgsbase,fxsr,hreset,lwp,lzcnt,popcnt,rdrnd,rdseed,tbm,rtm,serialize,tsxldtrk,uintr,xsaveopt")
 #else
 #pragma GCC target ("adx,bmi,bmi2,fsgsbase,fxsr,hreset,lwp,lzcnt,popcnt,rdrnd,rdseed,tbm,rtm,serialize,tsxldtrk,xsaveopt")
 #endif
index 9ef66fdad54511a3f6073cf55cf630956adb2b4f..54d826c4f46c1dcd025e4dc4903ed51bcc4a96aa 100644 (file)
 /* rtmintrin.h */
 #define __builtin_ia32_xabort(M) __builtin_ia32_xabort(1)
 
+/* cmpccxadd.h */
+#define __builtin_ia32_cmpccxadd(A, B, C, D) __builtin_ia32_cmpccxadd(A, B, C, 1)
+#define __builtin_ia32_cmpccxadd64(A, B, C, D) __builtin_ia32_cmpccxadd64(A, B, C, 1)
+
 #ifdef __x86_64__
-#pragma GCC target ("adx,bmi,bmi2,clflushopt,clwb,clzero,enqcmd,fsgsbase,fxsr,hreset,lwp,lzcnt,mwaitx,pconfig,pku,popcnt,rdpid,rdrnd,rdseed,tbm,rtm,serialize,sgx,tsxldtrk,uintr,xsavec,xsaveopt,xsaves,wbnoinvd")
+#pragma GCC target ("adx,bmi,bmi2,clflushopt,clwb,clzero,cmpccxadd,enqcmd,fsgsbase,fxsr,hreset,lwp,lzcnt,mwaitx,pconfig,pku,popcnt,rdpid,rdrnd,rdseed,tbm,rtm,serialize,sgx,tsxldtrk,uintr,xsavec,xsaveopt,xsaves,wbnoinvd")
 #else
 #pragma GCC target ("adx,bmi,bmi2,clflushopt,clwb,clzero,enqcmd,fsgsbase,fxsr,hreset,lwp,lzcnt,mwaitx,pconfig,pku,popcnt,rdpid,rdrnd,rdseed,tbm,rtm,serialize,sgx,tsxldtrk,xsavec,xsaveopt,xsaves,wbnoinvd")
 #endif
index 750897d085480d791010c593b81e6910df246169..0e45a2baed59ab72bad0fb221534bd9884aa95b0 100644 (file)
@@ -9561,6 +9561,16 @@ proc check_effective_target_avxneconvert { } {
     } "-O0 -mavxneconvert" ]
 }
 
+# Return 1 if cmpccxadd instructions can be compiled.
+proc check_effective_target_cmpccxadd { } {
+    return [check_no_compiler_messages cmpccxadd object {
+       int _cmpccxadd_epi32 (int *__A, int __B, int __C, const int __D)
+        {
+          return (int)__builtin_ia32_cmpccxadd (__A, __B, __C, 1);
+       }
+    } "-mcmpccxadd" ]
+}
+
 # Return 1 if sse instructions can be compiled.
 proc check_effective_target_sse { } {
     return [check_no_compiler_messages sse object {