]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
i386-common.c (OPTION_MASK_ISA_ADX_SET): New.
authorMichael Zolotukhin <michael.v.zolotukhin@intel.com>
Wed, 8 Aug 2012 13:25:58 +0000 (13:25 +0000)
committerKirill Yukhin <kyukhin@gcc.gnu.org>
Wed, 8 Aug 2012 13:25:58 +0000 (13:25 +0000)
ChangeLog:
2012-08-08 Michael Zolotukhin <michael.v.zolotukhin@intel.com>

        * common/config/i386/i386-common.c (OPTION_MASK_ISA_ADX_SET): New.
        (OPTION_MASK_ISA_ADX_UNSET): Likewise.
        (ix86_handle_option): Handle madx option.
        * config.gcc (i[34567]86-*-*): Add adxintrin.h.
        (x86_64-*-*): Likewise.
        * config/i386/adxintrin.h: New header.
        * config/i386/driver-i386.c (host_detect_local_cpu): Detect ADCX/ADOX
        support.
        * config/i386/i386-builtin-types.def
        (UCHAR_FTYPE_UCHAR_UINT_UINT_PUNSIGNED): New function type.
        (UCHAR_FTYPE_UCHAR_ULONGLONG_ULONGLONG_PULONGLONG): Likewise.
        * config/i386/i386-c.c: Define __ADX__ if needed.
        * config/i386/i386.c (ix86_target_string): Define -madx option.
        (PTA_ADX): New.
        (ix86_option_override_internal): Handle new option.
        (ix86_valid_target_attribute_inner_p): Add OPT_madx.
        (ix86_builtins): Add IX86_BUILTIN_ADDCARRYX32,
        IX86_BUILTIN_ADDCARRYX64.
        (ix86_init_mmx_sse_builtins): Define corresponding built-ins.
        (ix86_expand_builtin): Handle these built-ins.
        (ix86_expand_args_builtin): Handle new function types.
        * config/i386/i386.h (TARGET_ADX): New.
        * config/i386/i386.md (adcx<mode>3): New define_insn.
        * config/i386/i386.opt (madx): New.
        * config/i386/x86intrin.h: Include adxintrin.h.

testsuite/ChangeLog:
        * gcc.target/i386/adx-addcarryx32-1.c: New.
        * gcc.target/i386/adx-addcarryx32-2.c: New.
        * gcc.target/i386/adx-addcarryx64-1.c: New.
        * gcc.target/i386/adx-addcarryx64-2.c: New.
        * gcc.target/i386/adx-check.h: New.
        * gcc.target/i386/i386.exp (check_effective_target_adx): New.
        * gcc.target/i386/sse-12.c: Add -madx.
        * gcc.target/i386/sse-13.c: Ditto.
        * gcc.target/i386/sse-14.c: Ditto.
        * gcc.target/i386/sse-22.c: Ditto.
        * gcc.target/i386/sse-23.c: Ditto.
        * g++.dg/other/i386-2.C: Ditto.
        * g++.dg/other/i386-3.C: Ditto.

From-SVN: r190227

26 files changed:
gcc/ChangeLog
gcc/common/config/i386/i386-common.c
gcc/config.gcc
gcc/config/i386/adxintrin.h [new file with mode: 0644]
gcc/config/i386/driver-i386.c
gcc/config/i386/i386-builtin-types.def
gcc/config/i386/i386-c.c
gcc/config/i386/i386.c
gcc/config/i386/i386.h
gcc/config/i386/i386.md
gcc/config/i386/i386.opt
gcc/config/i386/x86intrin.h
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/other/i386-2.C
gcc/testsuite/g++.dg/other/i386-3.C
gcc/testsuite/gcc.target/i386/adx-addcarryx32-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/adx-addcarryx32-2.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/adx-addcarryx64-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/adx-addcarryx64-2.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/adx-check.h [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/i386.exp
gcc/testsuite/gcc.target/i386/sse-12.c
gcc/testsuite/gcc.target/i386/sse-13.c
gcc/testsuite/gcc.target/i386/sse-14.c
gcc/testsuite/gcc.target/i386/sse-22.c
gcc/testsuite/gcc.target/i386/sse-23.c

index 41e8f052654676c62ab20a3b7e303509c31ab1b9..5aa6902dbbecb0ef009adacb510e2f31ca9ddb86 100644 (file)
@@ -1,3 +1,31 @@
+2012-08-08 Michael Zolotukhin <michael.v.zolotukhin@intel.com>
+
+       * common/config/i386/i386-common.c (OPTION_MASK_ISA_ADX_SET): New.
+       (OPTION_MASK_ISA_ADX_UNSET): Likewise.
+       (ix86_handle_option): Handle madx option.
+       * config.gcc (i[34567]86-*-*): Add adxintrin.h.
+       (x86_64-*-*): Likewise.
+       * config/i386/adxintrin.h: New header.
+       * config/i386/driver-i386.c (host_detect_local_cpu): Detect ADCX/ADOX
+       support.
+       * config/i386/i386-builtin-types.def
+       (UCHAR_FTYPE_UCHAR_UINT_UINT_PUNSIGNED): New function type.
+       (UCHAR_FTYPE_UCHAR_ULONGLONG_ULONGLONG_PULONGLONG): Likewise.
+       * config/i386/i386-c.c: Define __ADX__ if needed.
+       * config/i386/i386.c (ix86_target_string): Define -madx option.
+       (PTA_ADX): New.
+       (ix86_option_override_internal): Handle new option.
+       (ix86_valid_target_attribute_inner_p): Add OPT_madx.
+       (ix86_builtins): Add IX86_BUILTIN_ADDCARRYX32,
+       IX86_BUILTIN_ADDCARRYX64.
+       (ix86_init_mmx_sse_builtins): Define corresponding built-ins.
+       (ix86_expand_builtin): Handle these built-ins.
+       (ix86_expand_args_builtin): Handle new function types.
+       * config/i386/i386.h (TARGET_ADX): New.
+       * config/i386/i386.md (adcx<mode>3): New define_insn.
+       * config/i386/i386.opt (madx): New.
+       * config/i386/x86intrin.h: Include adxintrin.h.
+
 2012-08-08  Nick Clifton  <nickc@redhat.com>
 
        * config/rl78/rl78.c: Include tree-pass.h.
index 70dcae07a33edbcbd3005a866dcf10c409bfb89e..e05cd562f44a55d443a0f5a532cd2a82933c8678 100644 (file)
@@ -57,6 +57,7 @@ along with GCC; see the file COPYING3.  If not see
 #define OPTION_MASK_ISA_RTM_SET OPTION_MASK_ISA_RTM
 #define OPTION_MASK_ISA_PRFCHW_SET OPTION_MASK_ISA_PRFCHW
 #define OPTION_MASK_ISA_RDSEED_SET OPTION_MASK_ISA_RDSEED
+#define OPTION_MASK_ISA_ADX_SET OPTION_MASK_ISA_ADX
 
 /* SSE4 includes both SSE4.1 and SSE4.2. -msse4 should be the same
    as -msse4.2.  */
@@ -127,6 +128,7 @@ along with GCC; see the file COPYING3.  If not see
 #define OPTION_MASK_ISA_RTM_UNSET OPTION_MASK_ISA_RTM
 #define OPTION_MASK_ISA_PRFCHW_UNSET OPTION_MASK_ISA_PRFCHW
 #define OPTION_MASK_ISA_RDSEED_UNSET OPTION_MASK_ISA_RDSEED
+#define OPTION_MASK_ISA_ADX_UNSET OPTION_MASK_ISA_ADX
 
 /* SSE4 includes both SSE4.1 and SSE4.2.  -mno-sse4 should the same
    as -mno-sse4.1. */
@@ -598,6 +600,19 @@ ix86_handle_option (struct gcc_options *opts,
        }
       return true;
 
+    case OPT_madx:
+      if (value)
+       {
+         opts->x_ix86_isa_flags |= OPTION_MASK_ISA_ADX_SET;
+         opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_ADX_SET;
+       }
+      else
+       {
+         opts->x_ix86_isa_flags &= ~OPTION_MASK_ISA_ADX_UNSET;
+         opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_ADX_UNSET;
+       }
+      return true;
+
   /* Comes from final.c -- no real reason to change it.  */
 #define MAX_CODE_ALIGN 16
 
index dad4c3aa8ed58dc7ea9690747907b702e0468d7c..f40ac0ea739bcfb19d48b07353df71f6c8047225 100644 (file)
@@ -361,7 +361,7 @@ i[34567]86-*-*)
                       ia32intrin.h cross-stdarg.h lwpintrin.h popcntintrin.h
                       lzcntintrin.h bmiintrin.h bmi2intrin.h tbmintrin.h
                       avx2intrin.h fmaintrin.h f16cintrin.h rtmintrin.h
-                      xtestintrin.h rdseedintrin.h prfchwintrin.h"
+                      xtestintrin.h rdseedintrin.h prfchwintrin.h adxintrin.h"
        ;;
 x86_64-*-*)
        cpu_type=i386
@@ -375,7 +375,7 @@ x86_64-*-*)
                       ia32intrin.h cross-stdarg.h lwpintrin.h popcntintrin.h
                       lzcntintrin.h bmiintrin.h tbmintrin.h bmi2intrin.h
                       avx2intrin.h fmaintrin.h f16cintrin.h rtmintrin.h
-                      xtestintrin.h rdseedintrin.h prfchwintrin.h"
+                      xtestintrin.h rdseedintrin.h prfchwintrin.h adxintrin.h"
        need_64bit_hwint=yes
        ;;
 ia64-*-*)
diff --git a/gcc/config/i386/adxintrin.h b/gcc/config/i386/adxintrin.h
new file mode 100644 (file)
index 0000000..2e2a18b
--- /dev/null
@@ -0,0 +1,53 @@
+/* Copyright (C) 2012 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/>.  */
+
+#if !defined _X86INTRIN_H_INCLUDED && !defined _IMMINTRIN_H_INCLUDED
+# error "Never use <adxintrin.h> directly; include <x86intrin.h> instead."
+#endif
+
+#ifndef __ADX__
+# error "Flag-preserving add-carry instructions not enabled"
+#endif /* __ADX__ */
+
+#ifndef _ADXINTRIN_H_INCLUDED
+#define _ADXINTRIN_H_INCLUDED
+
+extern __inline unsigned char
+__attribute__((__gnu_inline__, __always_inline__, __artificial__))
+_addcarryx_u32 (unsigned char __CF, unsigned int __X,
+               unsigned int __Y, unsigned int *__P)
+{
+    return __builtin_ia32_addcarryx_u32 (__CF, __X, __Y, __P);
+}
+
+#ifdef __x86_64__
+extern __inline unsigned char
+__attribute__((__gnu_inline__, __always_inline__, __artificial__))
+_addcarryx_u64 (unsigned char __CF, unsigned long __X,
+               unsigned long __Y, unsigned long long *__P)
+{
+    return __builtin_ia32_addcarryx_u64 (__CF, __X, __Y, __P);
+}
+#endif
+
+#endif /* _ADXINTRIN_H_INCLUDED */
index 46161087e906dbd3b99e054191b9fb8b29e5f9d9..0b56f3f47b1351ebdf6eba6d621a15a275ceece2 100644 (file)
@@ -399,7 +399,7 @@ const char *host_detect_local_cpu (int argc, const char **argv)
   unsigned int has_bmi = 0, has_bmi2 = 0, has_tbm = 0, has_lzcnt = 0;
   unsigned int has_hle = 0, has_rtm = 0;
   unsigned int has_rdrnd = 0, has_f16c = 0, has_fsgsbase = 0;
-  unsigned int has_rdseed = 0, has_prfchw = 0;
+  unsigned int has_rdseed = 0, has_prfchw = 0, has_adx = 0;
 
   bool arch;
 
@@ -468,6 +468,7 @@ const char *host_detect_local_cpu (int argc, const char **argv)
       has_fsgsbase = ebx & bit_FSGSBASE;
       has_rdseed = ebx & bit_RDSEED;
       has_prfchw = ecx & bit_PRFCHW;
+      has_adx = ebx & bit_ADX;
     }
 
   /* Check cpuid level of extended features.  */
@@ -750,11 +751,12 @@ const char *host_detect_local_cpu (int argc, const char **argv)
       const char *fsgsbase = has_fsgsbase ? " -mfsgsbase" : " -mno-fsgsbase";
       const char *rdseed = has_rdseed ? " -mrdseed" : " -mno-rdseed";
       const char *prfchw = has_prfchw ? " -mprfchw" : " -mno-prfchw";
+      const char *adx = has_adx ? " -madx" : " -mno-adx";
 
       options = concat (options, cx16, sahf, movbe, ase, pclmul,
                        popcnt, abm, lwp, fma, fma4, xop, bmi, bmi2,
                        tbm, avx, avx2, sse4_2, sse4_1, lzcnt, rtm,
-                       hle, rdrnd, f16c, fsgsbase, rdseed, prfchw, NULL);
+                       hle, rdrnd, f16c, fsgsbase, rdseed, prfchw, adx, NULL);
     }
 
 done:
index 398bf0af07dc7f4716effdb7066fb8d096886b01..8a199c0a7f8d0eff1fba2c9b5c26fb41c87e5bb9 100644 (file)
@@ -446,6 +446,9 @@ DEF_FUNCTION_TYPE (V16QI, V16QI, INT, V16QI, INT, INT)
 
 DEF_FUNCTION_TYPE (V8QI, QI, QI, QI, QI, QI, QI, QI, QI)
 
+DEF_FUNCTION_TYPE (UCHAR, UCHAR, UINT, UINT, PUNSIGNED)
+DEF_FUNCTION_TYPE (UCHAR, UCHAR, ULONGLONG, ULONGLONG, PULONGLONG)
+
 DEF_FUNCTION_TYPE (V2DF, V2DF, PCDOUBLE, V4SI, V2DF, INT)
 DEF_FUNCTION_TYPE (V4DF, V4DF, PCDOUBLE, V4SI, V4DF, INT)
 DEF_FUNCTION_TYPE (V4DF, V4DF, PCDOUBLE, V8SI, V4DF, INT)
index a4c947ace26cdc3f862754fdb41ca99b9edb48fb..d00e0ba54b93910419874f519aca9d4fa9afa983 100644 (file)
@@ -300,6 +300,8 @@ ix86_target_macros_internal (HOST_WIDE_INT isa_flag,
     def_or_undef (parse_in, "__RDSEED__");
   if (isa_flag & OPTION_MASK_ISA_PRFCHW)
     def_or_undef (parse_in, "__PRFCHW__");
+  if (isa_flag & OPTION_MASK_ISA_ADX)
+    def_or_undef (parse_in, "__ADX__");
   if ((fpmath & FPMATH_SSE) && (isa_flag & OPTION_MASK_ISA_SSE))
     def_or_undef (parse_in, "__SSE_MATH__");
   if ((fpmath & FPMATH_SSE) && (isa_flag & OPTION_MASK_ISA_SSE2))
index 1146d054ac8d4089238bc34edb491a94a210876f..17d4446b9a6c60b1e149d32a6cabcc1670f295a4 100644 (file)
@@ -2769,6 +2769,7 @@ ix86_target_string (HOST_WIDE_INT isa, int flags, const char *arch,
     { "-mhle",         OPTION_MASK_ISA_HLE },
     { "-mrdseed",      OPTION_MASK_ISA_RDSEED },
     { "-mprfchw",      OPTION_MASK_ISA_PRFCHW },
+    { "-madx",         OPTION_MASK_ISA_ADX },
     { "-mtbm",         OPTION_MASK_ISA_TBM },
     { "-mpopcnt",      OPTION_MASK_ISA_POPCNT },
     { "-mmovbe",       OPTION_MASK_ISA_MOVBE },
@@ -3047,6 +3048,7 @@ ix86_option_override_internal (bool main_args_p)
 #define PTA_HLE                        (HOST_WIDE_INT_1 << 33)
 #define PTA_PRFCHW             (HOST_WIDE_INT_1 << 34)
 #define PTA_RDSEED             (HOST_WIDE_INT_1 << 35)
+#define PTA_ADX                        (HOST_WIDE_INT_1 << 36)
 /* if this reaches 64, need to widen struct pta flags below */
 
   static struct pta
@@ -3538,6 +3540,9 @@ ix86_option_override_internal (bool main_args_p)
        if (processor_alias_table[i].flags & PTA_RDSEED
            && !(ix86_isa_flags_explicit & OPTION_MASK_ISA_RDSEED))
          ix86_isa_flags |= OPTION_MASK_ISA_RDSEED;
+       if (processor_alias_table[i].flags & PTA_ADX
+           && !(ix86_isa_flags_explicit & OPTION_MASK_ISA_ADX))
+         ix86_isa_flags |= OPTION_MASK_ISA_ADX;
        if (processor_alias_table[i].flags & (PTA_PREFETCH_SSE | PTA_SSE))
          x86_prefetch_sse = true;
 
@@ -4361,6 +4366,7 @@ ix86_valid_target_attribute_inner_p (tree args, char *p_strings[],
     IX86_ATTR_ISA ("hle",      OPT_mhle),
     IX86_ATTR_ISA ("prfchw",   OPT_mprfchw),
     IX86_ATTR_ISA ("rdseed",   OPT_mrdseed),
+    IX86_ATTR_ISA ("adx",      OPT_madx),
 
     /* enum options */
     IX86_ATTR_ENUM ("fpmath=", OPT_mfpmath_),
@@ -26107,6 +26113,10 @@ enum ix86_builtins
   IX86_BUILTIN_PEXT32,
   IX86_BUILTIN_PEXT64,
 
+  /* ADX instructions.  */
+  IX86_BUILTIN_ADDCARRYX32,
+  IX86_BUILTIN_ADDCARRYX64,
+
   /* FSGSBASE instructions.  */
   IX86_BUILTIN_RDFSBASE32,
   IX86_BUILTIN_RDFSBASE64,
@@ -27957,6 +27967,14 @@ ix86_init_mmx_sse_builtins (void)
               "__builtin_ia32_rdseed_di_step",
               INT_FTYPE_PULONGLONG, IX86_BUILTIN_RDSEED64_STEP);
 
+  /* ADCX */
+  def_builtin (OPTION_MASK_ISA_ADX, "__builtin_ia32_addcarryx_u32",
+              UCHAR_FTYPE_UCHAR_UINT_UINT_PUNSIGNED, IX86_BUILTIN_ADDCARRYX32);
+  def_builtin (OPTION_MASK_ISA_ADX && OPTION_MASK_ISA_64BIT,
+              "__builtin_ia32_addcarryx_u64",
+              UCHAR_FTYPE_UCHAR_ULONGLONG_ULONGLONG_PULONGLONG,
+              IX86_BUILTIN_ADDCARRYX64);
+
   /* Add FMA4 multi-arg argument instructions */
   for (i = 0, d = bdesc_multi_arg; i < ARRAY_SIZE (bdesc_multi_arg); i++, d++)
     {
@@ -29472,6 +29490,10 @@ ix86_expand_args_builtin (const struct builtin_description *d,
       nargs = 4;
       nargs_constant = 2;
       break;
+    case UCHAR_FTYPE_UCHAR_UINT_UINT_PUNSIGNED:
+    case UCHAR_FTYPE_UCHAR_ULONGLONG_ULONGLONG_PULONGLONG:
+      nargs = 4;
+      break;
     default:
       gcc_unreachable ();
     }
@@ -30318,7 +30340,62 @@ rdseed_step:
         target = gen_reg_rtx (SImode);
 
       emit_insn (gen_zero_extendqisi2 (target, op2));
+      return target;
+
+    case IX86_BUILTIN_ADDCARRYX32:
+      icode = CODE_FOR_adcxsi3;
+      mode0 = SImode;
+      goto addcarryx;
+
+    case IX86_BUILTIN_ADDCARRYX64:
+      icode = CODE_FOR_adcxdi3;
+      mode0 = DImode;
+
+addcarryx:
+      arg0 = CALL_EXPR_ARG (exp, 0); /* unsigned char c_in.  */
+      arg1 = CALL_EXPR_ARG (exp, 1); /* unsigned int src1.  */
+      arg2 = CALL_EXPR_ARG (exp, 2); /* unsigned int src2.  */
+      arg3 = CALL_EXPR_ARG (exp, 3); /* unsigned int *sum_out.  */
+
+      op0 = gen_reg_rtx (QImode);
+
+      /* Generate CF from input operand.  */
+      op1 = expand_normal (arg0);
+      if (GET_MODE (op1) != QImode)
+       op1 = convert_to_mode (QImode, op1, 1);
+      op1 = copy_to_mode_reg (QImode, op1);
+      emit_insn (gen_addqi3_cc (op0, op1, constm1_rtx));
+
+      /* Gen ADCX instruction to compute X+Y+CF.  */
+      op2 = expand_normal (arg1);
+      op3 = expand_normal (arg2);
+
+      if (!REG_P (op2))
+       op2 = copy_to_mode_reg (mode0, op2);
+      if (!REG_P (op3))
+       op3 = copy_to_mode_reg (mode0, op3);
+
+      op0 = gen_reg_rtx (mode0);
+
+      op4 = gen_rtx_REG (CCCmode, FLAGS_REG);
+      pat = gen_rtx_LTU (VOIDmode, op4, const0_rtx);
+      emit_insn (GEN_FCN (icode) (op0, op2, op3, op4, pat));
+
+      /* Store the result.  */
+      op4 = expand_normal (arg3);
+      if (!address_operand (op4, VOIDmode))
+       {
+         op4 = convert_memory_address (Pmode, op4);
+         op4 = copy_addr_to_reg (op4);
+       }
+      emit_move_insn (gen_rtx_MEM (mode0, op4), op0);
+
+      /* Return current CF value.  */
+      if (target == 0)
+        target = gen_reg_rtx (QImode);
 
+      PUT_MODE (pat, QImode);
+      emit_insn (gen_rtx_SET (VOIDmode, target, pat));
       return target;
 
     case IX86_BUILTIN_GATHERSIV2DF:
index 60f4018203e58aa88a44144fd961cbc543145e5c..c2b44607585c401c7019ac44cdf98ef3c5a99fa9 100644 (file)
@@ -78,6 +78,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
 #define TARGET_HLE     OPTION_ISA_HLE
 #define TARGET_RDSEED  OPTION_ISA_RDSEED
 #define TARGET_PRFCHW  OPTION_ISA_PRFCHW
+#define TARGET_ADX     OPTION_ISA_ADX
 
 #define TARGET_LP64    OPTION_ABI_64
 #define TARGET_X32     OPTION_ABI_X32
index ace3b6e250db3284ef03664ac566122c859eb38a..6774ae279d6662ed1b392ccd61f0370af22869ea 100644 (file)
    (set_attr "pent_pair" "pu")
    (set_attr "mode" "SI")])
 \f
+;; ADCX instruction
+
+(define_insn "adcx<mode>3"
+  [(set (reg:CCC FLAGS_REG)
+       (compare:CCC
+         (plus:SWI48
+           (match_operand:SWI48 1 "nonimmediate_operand" "%0")
+           (plus:SWI48
+             (match_operator 4 "ix86_carry_flag_operator"
+              [(match_operand 3 "flags_reg_operand") (const_int 0)])
+             (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
+         (const_int 0)))
+   (set (match_operand:SWI48 0 "register_operand" "=r")
+       (plus:SWI48 (match_dup 1)
+                   (plus:SWI48 (match_op_dup 4
+                                [(match_dup 3) (const_int 0)])
+                               (match_dup 2))))]
+  "TARGET_ADX && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
+  "adcx\t{%2, %0|%0, %2}"
+  [(set_attr "type" "alu")
+   (set_attr "use_carry" "1")
+   (set_attr "mode" "<MODE>")])
+\f
 ;; Overflow setting add and subtract instructions
 
 (define_insn "*add<mode>3_cconly_overflow"
index ccada37e543d767327d84bfda17bd5c41bc36a21..e4f78f3ce50f38953e289821f4dba6846857b491 100644 (file)
@@ -540,6 +540,10 @@ mprfchw
 Target Report Mask(ISA_PRFCHW) Var(ix86_isa_flags) Save
 Support PREFETCHW instruction
 
+madx
+Target Report Mask(ISA_ADX) Var(ix86_isa_flags) Save
+Support flag-preserving add-carry instructions
+
 mtbm
 Target Report Mask(ISA_TBM) Var(ix86_isa_flags) Save
 Support TBM built-in functions and code generation
index 9dee9ef64ec0acb346a713a14cd7679dc9b8c411..dc5c58eebf8af8c412cf54fa8e20b2e6ec90ad6c 100644 (file)
 #include <prfchwintrin.h>
 #endif
 
+#ifdef __ADX__
+#include <adxintrin.h>
+#endif
+
 #endif /* _X86INTRIN_H_INCLUDED */
index 171a16ecf4a81c491e0e4fc9f985a82f515484ea..dc3523ade1d7b7c50fcb02e37855faa1862fc693 100644 (file)
@@ -1,3 +1,19 @@
+2012-08-08 Michael Zolotukhin <michael.v.zolotukhin@intel.com>
+
+       * gcc.target/i386/adx-addcarryx32-1.c: New.
+       * gcc.target/i386/adx-addcarryx32-2.c: New.
+       * gcc.target/i386/adx-addcarryx64-1.c: New.
+       * gcc.target/i386/adx-addcarryx64-2.c: New.
+       * gcc.target/i386/adx-check.h: New.
+       * gcc.target/i386/i386.exp (check_effective_target_adx): New.
+       * gcc.target/i386/sse-12.c: Add -madx.
+       * gcc.target/i386/sse-13.c: Ditto.
+       * gcc.target/i386/sse-14.c: Ditto.
+       * gcc.target/i386/sse-22.c: Ditto.
+       * gcc.target/i386/sse-23.c: Ditto.
+       * g++.dg/other/i386-2.C: Ditto.
+       * g++.dg/other/i386-3.C: Ditto.
+
 2012-08-07  Bill Schmidt  <wschmidt@linux.vnet.ibm.com>
 
        * gcc.dg/tree-ssa/slsr-5.c: New.
index 47fda70bc90345951403266ad6882102a7dbfcd6..197497fcfe9a4c8febdcdac4276c2167104046d9 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" } */
+/* { 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" } */
 
 /* 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 ad477fa7ec35fc67a9100e49ac3671da780c3581..780731e03589a5d23d012e7f79ec0de859260d70 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" } */
+/* { 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" } */
 
 /* 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,
diff --git a/gcc/testsuite/gcc.target/i386/adx-addcarryx32-1.c b/gcc/testsuite/gcc.target/i386/adx-addcarryx32-1.c
new file mode 100644 (file)
index 0000000..daf5779
--- /dev/null
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+/* { dg-options "-madx -O2" } */
+/* { dg-final { scan-assembler "adcx" } } */
+
+#include <x86intrin.h>
+
+volatile unsigned char c;
+volatile unsigned int x, y;
+unsigned int *sum;
+
+void extern
+adx_test (void)
+{
+    c = _addcarryx_u32 (c, x, y, sum);
+}
diff --git a/gcc/testsuite/gcc.target/i386/adx-addcarryx32-2.c b/gcc/testsuite/gcc.target/i386/adx-addcarryx32-2.c
new file mode 100644 (file)
index 0000000..d38d7ee
--- /dev/null
@@ -0,0 +1,27 @@
+/* { dg-do run } */
+/* { dg-options "-madx -O2" } */
+/* { dg-require-effective-target adx } */
+
+#include <x86intrin.h>
+#include "adx-check.h"
+
+static void
+adx_test (void)
+{
+  volatile unsigned char c;
+  unsigned int x;
+  volatile unsigned int y, sum_ref;
+
+  c = 0;
+  x = y = 0xFFFFFFFF;
+  sum_ref = 0xFFFFFFFE;
+
+  /* X = 0xFFFFFFFF, Y = 0xFFFFFFFF, C = 0.  */
+  c = _addcarryx_u32 (c, x, y, &x);
+  /* X = 0xFFFFFFFE, Y = 0xFFFFFFFF, C = 1.  */
+  c = _addcarryx_u32 (c, x, y, &x);
+  /* X = 0xFFFFFFFE, Y = 0xFFFFFFFF, C = 1.  */
+
+  if (x != sum_ref)
+    abort ();
+}
diff --git a/gcc/testsuite/gcc.target/i386/adx-addcarryx64-1.c b/gcc/testsuite/gcc.target/i386/adx-addcarryx64-1.c
new file mode 100644 (file)
index 0000000..45beca8
--- /dev/null
@@ -0,0 +1,15 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-madx -O2" } */
+/* { dg-final { scan-assembler "adcx" } } */
+
+#include <x86intrin.h>
+
+volatile unsigned char c;
+volatile unsigned long long x, y;
+unsigned long long *sum;
+
+void extern
+adx_test (void)
+{
+    c = _addcarryx_u64 (c, x, y, sum);
+}
diff --git a/gcc/testsuite/gcc.target/i386/adx-addcarryx64-2.c b/gcc/testsuite/gcc.target/i386/adx-addcarryx64-2.c
new file mode 100644 (file)
index 0000000..6aa2539
--- /dev/null
@@ -0,0 +1,27 @@
+/* { dg-do run { target { ! ia32 } } } */
+/* { dg-options "-madx -O2" } */
+/* { dg-require-effective-target adx } */
+
+#include <x86intrin.h>
+#include "adx-check.h"
+
+static void
+adx_test (void)
+{
+  volatile unsigned char c;
+  unsigned long long x;
+  volatile unsigned long long y, sum_ref;
+
+  c = 0;
+  x = y = 0xFFFFFFFFFFFFFFFFLL;
+  sum_ref = 0xFFFFFFFFFFFFFFFELL;
+
+  /* X = 0xFFFFFFFFFFFFFFFF, Y = 0xFFFFFFFFFFFFFFFF, C = 0.  */
+  c = _addcarryx_u64 (c, x, y, &x);
+  /* X = 0xFFFFFFFFFFFFFFFE, Y = 0xFFFFFFFFFFFFFFFF, C = 1.  */
+  c = _addcarryx_u64 (c, x, y, &x);
+  /* X = 0xFFFFFFFFFFFFFFFE, Y = 0xFFFFFFFFFFFFFFFF, C = 1.  */
+
+  if (x != sum_ref)
+    abort ();
+}
diff --git a/gcc/testsuite/gcc.target/i386/adx-check.h b/gcc/testsuite/gcc.target/i386/adx-check.h
new file mode 100644 (file)
index 0000000..580cb49
--- /dev/null
@@ -0,0 +1,40 @@
+#include <stdlib.h>
+#include "cpuid.h"
+
+static void adx_test (void);
+
+static void __attribute__ ((noinline)) do_test (void)
+{
+  adx_test ();
+}
+
+  int
+main ()
+{
+  unsigned int eax, ebx, ecx, edx;
+
+  if (!__get_cpuid (1, &eax, &ebx, &ecx, &edx))
+    return 0;
+
+  /* Run ADX test only if host has ADX support.  */
+
+  if (__get_cpuid_max (0, NULL) < 7)
+    return 0;
+
+  __cpuid_count (7, 0, eax, ebx, ecx, edx);
+
+  if ((ebx & bit_ADX) == bit_ADX)
+    {
+      do_test ();
+#ifdef DEBUG
+      printf ("PASSED\n");
+#endif
+      return 0;
+    }
+#ifdef DEBUG
+  printf ("SKIPPED\n");
+#endif
+
+  return 0;
+}
+
index 785a973923617da5b4500926c4f6c96eec1b6815..37f43a60f05d730cf158a15831debf052f86d556 100644 (file)
@@ -243,6 +243,18 @@ proc check_effective_target_bmi2 { } {
     } "-mbmi2" ]
 }
 
+# Return 1 if ADX instructions can be compiled.
+proc check_effective_target_adx { } {
+    return [check_no_compiler_messages adx object {
+       unsigned char
+       _adxcarry_u32 (unsigned char __CF, unsigned int __X,
+                  unsigned int __Y, unsigned int *__P)
+       {
+           return __builtin_ia32_addcarryx_u32 (__CF, __X, __Y, __P);
+       }
+    } "-madx" ]
+}
+
 # Return 1 if rtm instructions can be compiled.
 proc check_effective_target_rtm { } {
     return [check_no_compiler_messages rtm object {
index cb3ab18d5eb7de43eb9a6b690bad43c30047f98f..0d78a0c84dc1e787c2a8c1feb278b28f2c727a26 100644 (file)
@@ -3,7 +3,7 @@
    popcntintrin.h and mm_malloc.h are usable
    with -O -std=c89 -pedantic-errors.  */
 /* { dg-do compile } */
-/* { dg-options "-O -std=c89 -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" } */
+/* { dg-options "-O -std=c89 -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" } */
 
 #include <x86intrin.h>
 
index fe2bf46042fcc2c21da17c2a767670299962c101..4c575baaf784012f9cbd787ed44ccb389e380fc8 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" } */
+/* { 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" } */
 
 #include <mm_malloc.h>
 
index 8877e312d753d212a19fbdc53a5c7958234a886d..c8c13cecb5313c4cf83af40b52c75b54244ca17b 100644 (file)
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-O0 -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" } */
+/* { dg-options "-O0 -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" } */
 
 #include <mm_malloc.h>
 
index ec5ccb894591ced9057963193be6903d9f55ced1..ec832552874555d372821f29598e4c6a2553f846 100644 (file)
@@ -50,7 +50,7 @@
 
 
 #ifndef DIFFERENT_PRAGMAS
-#pragma GCC target ("sse4a,3dnow,avx,avx2,fma4,xop,aes,pclmul,popcnt,abm,lzcnt,bmi,bmi2,tbm,lwp,fsgsbase,rdrnd,f16c,rtm,rdseed,prfchw")
+#pragma GCC target ("sse4a,3dnow,avx,avx2,fma4,xop,aes,pclmul,popcnt,abm,lzcnt,bmi,bmi2,tbm,lwp,fsgsbase,rdrnd,f16c,rtm,rdseed,prfchw,adx")
 #endif
 
 /* Following intrinsics require immediate arguments.  They
@@ -264,7 +264,7 @@ test_2 (_mm_clmulepi64_si128, __m128i, __m128i, __m128i, 1)
 
 /* x86intrin.h (FMA4/XOP/LWP/BMI/BMI2/TBM/LZCNT/FMA). */
 #ifdef DIFFERENT_PRAGMAS
-#pragma GCC target ("fma4,xop,lwp,bmi,bmi2,tbm,lzcnt,fma,rdseed,prfchw")
+#pragma GCC target ("fma4,xop,lwp,bmi,bmi2,tbm,lzcnt,fma,rdseed,prfchw,adx")
 #endif
 #include <x86intrin.h>
 /* xopintrin.h */
index 3b26d99b0198931a6fdcf08ddd795fdfda428fee..f046ef643b5e6d540d473a8fc4c65723f73cd9d8 100644 (file)
 /* rtmintrin.h */
 #define __builtin_ia32_xabort(M) __builtin_ia32_xabort(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")
+#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")
 #include <wmmintrin.h>
 #include <smmintrin.h>
 #include <mm3dnow.h>