diff --git a/gcc/config.gcc b/gcc/config.gcc
index 99f0b47..a829d4c 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -360,7 +360,7 @@ i[34567]86-*-*)
 		       immintrin.h x86intrin.h avxintrin.h xopintrin.h
 		       ia32intrin.h cross-stdarg.h lwpintrin.h popcntintrin.h
 		       lzcntintrin.h bmiintrin.h bmi2intrin.h tbmintrin.h
-		       avx2intrin.h fmaintrin.h f16cintrin.h"
+		       avx2intrin.h fmaintrin.h f16cintrin.h hleintrin.h"
 	;;
 x86_64-*-*)
 	cpu_type=i386
@@ -373,7 +373,7 @@ x86_64-*-*)
 		       immintrin.h x86intrin.h avxintrin.h xopintrin.h
 		       ia32intrin.h cross-stdarg.h lwpintrin.h popcntintrin.h
 		       lzcntintrin.h bmiintrin.h tbmintrin.h bmi2intrin.h
-		       avx2intrin.h fmaintrin.h f16cintrin.h"
+		       avx2intrin.h fmaintrin.h f16cintrin.h hleintrin.h"
 	need_64bit_hwint=yes
 	;;
 ia64-*-*)
diff --git a/gcc/config/i386/hleintrin.h b/gcc/config/i386/hleintrin.h
new file mode 100644
index 0000000..0a44bf0
--- /dev/null
+++ b/gcc/config/i386/hleintrin.h
@@ -0,0 +1,288 @@
+/* Copyright (C) 2011 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 _IMMINTRIN_H_INCLUDED
+# error "Never use <hleintrin.h> directly; include <immintrin.h> instead."
+#endif
+
+#ifndef _HLEINTRIN_H_INCLUDED
+#define _HLEINTRIN_H_INCLUDED
+
+#define __LOCK_NONE		0
+#define __LOCK_NORMAL		1
+#define __LOCK_XACQUIRE		2
+#define __LOCK_XRELEASE		3
+
+#ifdef __OPTIMIZE__
+extern __inline int
+__attribute__((__gnu_inline__, __always_inline__, __artificial__))
+_lock_btc_i16 (const int __L, short *__P, short __V)
+{
+  return (int) __builtin_ia32_hle_btc_i16 (__L, __P, __V);
+}
+
+extern __inline int
+__attribute__((__gnu_inline__, __always_inline__, __artificial__))
+_lock_btc_i32 (const int __L, int *__P, int __V)
+{
+  return (int) __builtin_ia32_hle_btc_i32 (__L, __P, __V);
+}
+
+extern __inline int
+__attribute__((__gnu_inline__, __always_inline__, __artificial__))
+_lock_btr_i16 (const int __L, short *__P, short __V)
+{
+  return (int) __builtin_ia32_hle_btr_i16 (__L, __P, __V);
+}
+
+extern __inline int
+__attribute__((__gnu_inline__, __always_inline__, __artificial__))
+_lock_btr_i32 (const int __L, int *__P, int __V)
+{
+  return (int) __builtin_ia32_hle_btr_i32 (__L, __P, __V);
+}
+
+extern __inline int
+__attribute__((__gnu_inline__, __always_inline__, __artificial__))
+_lock_bts_i16 (const int __L, short *__P, short __V)
+{
+  return (int) __builtin_ia32_hle_bts_i16 (__L, __P, __V);
+}
+
+extern __inline int
+__attribute__((__gnu_inline__, __always_inline__, __artificial__))
+_lock_bts_i32 (const int __L, int *__P, int __V)
+{
+  return (int) __builtin_ia32_hle_bts_i32 (__L, __P, __V);
+}
+
+extern __inline char
+__attribute__((__gnu_inline__, __always_inline__, __artificial__))
+_lock_val_cmpxchg_i8 (const int __L, char *__P, char __O, char __N)
+{
+  return (char) __builtin_ia32_hle_val_cmpxchg_i8 (__L, __P, __O, __N);
+}
+
+extern __inline short
+__attribute__((__gnu_inline__, __always_inline__, __artificial__))
+_lock_val_cmpxchg_i16 (const int __L, short *__P, short __O, short __N)
+{
+  return (short) __builtin_ia32_hle_val_cmpxchg_i16 (__L, __P, __O, __N);
+}
+
+extern __inline int
+__attribute__((__gnu_inline__, __always_inline__, __artificial__))
+_lock_val_cmpxchg_i32 (const int __L, int *__P, int __O, int __N)
+{
+  return (int) __builtin_ia32_hle_val_cmpxchg_i32 (__L, __P, __O, __N);
+}
+
+extern __inline int
+__attribute__((__gnu_inline__, __always_inline__, __artificial__))
+_lock_bool_cmpxchg_i8 (const int __L, char *__P, char __O, char __N)
+{
+  return (int) __builtin_ia32_hle_bool_cmpxchg_i8 (__L, __P, __O, __N);
+}
+
+extern __inline int
+__attribute__((__gnu_inline__, __always_inline__, __artificial__))
+_lock_bool_cmpxchg_i16 (const int __L, short *__P, short __O, short __N)
+{
+  return (int) __builtin_ia32_hle_bool_cmpxchg_i16 (__L, __P, __O, __N);
+}
+
+extern __inline int
+__attribute__((__gnu_inline__, __always_inline__, __artificial__))
+_lock_bool_cmpxchg_i32 (const int __L, int *__P, int __O, int __N)
+{
+  return (int) __builtin_ia32_hle_bool_cmpxchg_i32 (__L, __P, __O, __N);
+}
+
+extern __inline char
+__attribute__((__gnu_inline__, __always_inline__, __artificial__))
+_lock_xadd_i8 (const int __L, char *__P, char __V)
+{
+  return (char) __builtin_ia32_hle_xadd_i8 (__L, __P, __V);
+}
+
+extern __inline short
+__attribute__((__gnu_inline__, __always_inline__, __artificial__))
+_lock_xadd_i16 (const int __L, short *__P, short __V)
+{
+  return (short) __builtin_ia32_hle_xadd_i16 (__L, __P, __V);
+}
+
+extern __inline int
+__attribute__((__gnu_inline__, __always_inline__, __artificial__))
+_lock_xadd_i32 (const int __L, int *__P, int __V)
+{
+  return (int) __builtin_ia32_hle_xadd_i32 (__L, __P, __V);
+}
+
+extern __inline char
+__attribute__((__gnu_inline__, __always_inline__, __artificial__))
+_lock_xchg_i8 (const int __L, char *__P, char __V)
+{
+  return (char) __builtin_ia32_hle_xchg_i8 (__L, __P, __V);
+}
+
+extern __inline short
+__attribute__((__gnu_inline__, __always_inline__, __artificial__))
+_lock_xchg_i16 (const int __L, short *__P, short __V)
+{
+  return (short) __builtin_ia32_hle_xchg_i16 (__L, __P, __V);
+}
+
+extern __inline int
+__attribute__((__gnu_inline__, __always_inline__, __artificial__))
+_lock_xchg_i32 (const int __L, int *__P, int __V)
+{
+  return (int) __builtin_ia32_hle_xchg_i32 (__L, __P, __V);
+}
+
+extern __inline void
+__attribute__((__gnu_inline__, __always_inline__, __artificial__))
+_lock_store_i8 (const int __L, char *__P, char __V)
+{
+  __builtin_ia32_hle_store_i8 (__L, __P, __V);
+}
+
+extern __inline void
+__attribute__((__gnu_inline__, __always_inline__, __artificial__))
+_lock_store_i16 (const int __L, short *__P, short __V)
+{
+  __builtin_ia32_hle_store_i16 (__L, __P, __V);
+}
+
+extern __inline void
+__attribute__((__gnu_inline__, __always_inline__, __artificial__))
+_lock_store_i32 (const int __L, int *__P, int __V)
+{
+  __builtin_ia32_hle_store_i32 (__L, __P, __V);
+}
+
+#ifdef __x86_64__
+extern __inline int
+__attribute__((__gnu_inline__, __always_inline__, __artificial__))
+_lock_bts_i64 (const int __L, long long *__P, long long __V)
+{
+  return (int) __builtin_ia32_hle_bts_i64 (__L, __P, __V);
+}
+
+extern __inline long long
+__attribute__((__gnu_inline__, __always_inline__, __artificial__))
+_lock_val_cmpxchg_i64 (const int __L, long long *__P, long long __O,
+		       long long __N)
+{
+  return (long long) __builtin_ia32_hle_val_cmpxchg_i64 (__L, __P,
+							 __O, __N);
+}
+
+extern __inline int
+__attribute__((__gnu_inline__, __always_inline__, __artificial__))
+_lock_bool_cmpxchg_i64 (const int __L, long long *__P, long long __O,
+		       long long __N)
+{
+  return (int) __builtin_ia32_hle_bool_cmpxchg_i64 (__L, __P, __O, __N);
+}
+
+extern __inline long long
+__attribute__((__gnu_inline__, __always_inline__, __artificial__))
+_lock_xadd_i64 (const int __L, long long *__P, long long __V)
+{
+  return (long long) __builtin_ia32_hle_xadd_i64 (__L, __P, __V);
+}
+
+extern __inline long long
+__attribute__((__gnu_inline__, __always_inline__, __artificial__))
+_lock_xchg_i64 (const int __L, long long *__P, long long __V)
+{
+  return (long long) __builtin_ia32_hle_xchg_i64 (__L, __P, __V);
+}
+
+extern __inline void
+__attribute__((__gnu_inline__, __always_inline__, __artificial__))
+_lock_store_i64 (const int __L, long long *__P, long long __V)
+{
+  __builtin_ia32_hle_store_i64 (__L, __P, __V);
+}
+#endif
+#else
+#define _lock_bts_i16(LOCK, PTR, VAL) \
+  ((int) __builtin_ia32_hle_bts_i16 ((LOCK), (PTR), (VAL)))
+#define _lock_bts_i32(LOCK, PTR, VAL) \
+  ((int) __builtin_ia32_hle_bts_i32 ((LOCK), (PTR), (VAL)))
+
+#define _lock_val_cmpxchg_i8(LOCK, PTR, OLD, NEW) \
+  ((char) __builtin_ia32_hle_val_cmpxchg_i8 ((LOCK), (PTR), (OLD), (NEW)))
+#define _lock_val_cmpxchg_i16(LOCK, PTR, OLD, NEW) \
+  ((short) __builtin_ia32_hle_val_cmpxchg_i16 ((LOCK), (PTR), (OLD), (NEW)))
+#define _lock_val_cmpxchg_i32(LOCK, PTR, OLD, NEW) \
+  ((int) __builtin_ia32_hle_val_cmpxchg_i32 ((LOCK), (PTR), (OLD), (NEW)))
+
+#define _lock_bool_cmpxchg_i8(LOCK, PTR, OLD, NEW) \
+  ((int) __builtin_ia32_hle_bool_cmpxchg_i8 ((LOCK), (PTR), (OLD), (NEW)))
+#define _lock_bool_cmpxchg_i16(LOCK, PTR, OLD, NEW) \
+  ((int) __builtin_ia32_hle_bool_cmpxchg_i16 ((LOCK), (PTR), (OLD), (NEW)))
+#define _lock_bool_cmpxchg_i32(LOCK, PTR, OLD, NEW) \
+  ((int) __builtin_ia32_hle_bool_cmpxchg_i32 ((LOCK), (PTR), (OLD), (NEW)))
+
+#define _lock_xadd_i8(LOCK, PTR, VAL) \
+  ((char) __builtin_ia32_hle_xadd_i8 ((LOCK), (PTR), (VAL)))
+#define _lock_xadd_i16(LOCK, PTR, VAL) \
+  ((short) __builtin_ia32_hle_xadd_i16 ((LOCK), (PTR), (VAL)))
+#define _lock_xadd_i32(LOCK, PTR, VAL) \
+  ((int) __builtin_ia32_hle_xadd_i32 ((LOCK), (PTR), (VAL)))
+
+#define _lock_xchg_i8(LOCK, PTR, VAL) \
+  ((char) __builtin_ia32_hle_xchg_i8 ((LOCK), (PTR), (VAL)))
+#define _lock_xchg_i8(LOCK, PTR, VAL) \
+  ((char) __builtin_ia32_hle_xchg_i8 ((LOCK), (PTR), (VAL)))
+#define _lock_xchg_i16(LOCK, PTR, VAL) \
+  ((short) __builtin_ia32_hle_xchg_i16 ((LOCK), (PTR), (VAL)))
+#define _lock_xchg_i32(LOCK, PTR, VAL) \
+  ((int) __builtin_ia32_hle_xchg_i32 ((LOCK), (PTR), (VAL)))
+
+#ifdef __x86_64__
+#define _lock_btc_i64(LOCK, PTR, VAL) \
+  ((int) __builtin_ia32_hle_btc_i64 ((LOCK), (PTR), (VAL)))
+#define _lock_btr_i64(LOCK, PTR, VAL) \
+  ((int) __builtin_ia32_hle_btr_i64 ((LOCK), (PTR), (VAL)))
+#define _lock_bts_i64(LOCK, PTR, VAL) \
+  ((int) __builtin_ia32_hle_bts_i64 ((LOCK), (PTR), (VAL)))
+
+#define _lock_val_cmpxchg_i64(LOCK, PTR, OLD, NEW) \
+  ((long long) __builtin_ia32_hle_val_cmpxchg_i64 ((LOCK), (PTR), (OLD), (NEW)))
+#define _lock_bool_cmpxchg_i64(LOCK, PTR, OLD, NEW) \
+  ((int) __builtin_ia32_hle_bool_cmpxchg_i64 ((LOCK), (PTR), (OLD), (NEW)))
+#define _lock_xadd_i64(LOCK, PTR, VAL) \
+  ((long long) __builtin_ia32_hle_xadd_i64 ((LOCK), (PTR), (VAL)))
+#define _lock_xchg_i64(LOCK, PTR, VAL) \
+  ((long long) __builtin_ia32_hle_xchg_i64 ((LOCK), (PTR), (VAL)))
+
+#define _lock_store_i64(LOCK, PTR, VAL) \
+  __builtin_ia32_hle_store_i64 ((LOCK), (PTR), (VAL))
+#endif
+#endif
+
+#endif
diff --git a/gcc/config/i386/i386-builtin-types.def b/gcc/config/i386/i386-builtin-types.def
index d00b053..8e70557 100644
--- a/gcc/config/i386/i386-builtin-types.def
+++ b/gcc/config/i386/i386-builtin-types.def
@@ -56,6 +56,7 @@ DEF_PRIMITIVE_TYPE (UHI, unsigned_intHI_type_node)
 DEF_PRIMITIVE_TYPE (USI, unsigned_intSI_type_node)
 DEF_PRIMITIVE_TYPE (UDI, long_long_unsigned_type_node)
 # ??? Some of the types below should use the mode types above.
+DEF_PRIMITIVE_TYPE (SHORT, short_integer_type_node)
 DEF_PRIMITIVE_TYPE (USHORT, short_unsigned_type_node)
 DEF_PRIMITIVE_TYPE (INT, integer_type_node)
 DEF_PRIMITIVE_TYPE (UINT, unsigned_type_node)
@@ -109,6 +110,7 @@ DEF_POINTER_TYPE (PCVOID, VOID, CONST)
 DEF_POINTER_TYPE (PVOID, VOID)
 DEF_POINTER_TYPE (PDOUBLE, DOUBLE)
 DEF_POINTER_TYPE (PFLOAT, FLOAT)
+DEF_POINTER_TYPE (PSHORT, SHORT)
 DEF_POINTER_TYPE (PUSHORT, USHORT)
 DEF_POINTER_TYPE (PINT, INT)
 DEF_POINTER_TYPE (PLONGLONG, LONGLONG)
@@ -432,9 +434,26 @@ DEF_FUNCTION_TYPE (V8UHI, V8UHI, V8UHI, V8UHI)
 DEF_FUNCTION_TYPE (V16UQI, V16UQI, V16UQI, V16UQI)
 DEF_FUNCTION_TYPE (V4DF, V4DF, V4DF, V4DI)
 DEF_FUNCTION_TYPE (V8SF, V8SF, V8SF, V8SI)
+DEF_FUNCTION_TYPE (CHAR, INT, PCHAR, CHAR)
+DEF_FUNCTION_TYPE (SHORT, INT, PSHORT, SHORT)
+DEF_FUNCTION_TYPE (INT, INT, PINT, INT)
+DEF_FUNCTION_TYPE (LONGLONG, INT, PLONGLONG, LONGLONG)
+DEF_FUNCTION_TYPE (INT, INT, PSHORT, SHORT)
+DEF_FUNCTION_TYPE (INT, INT, PLONGLONG, LONGLONG)
+DEF_FUNCTION_TYPE (VOID, INT, PCHAR, CHAR)
+DEF_FUNCTION_TYPE (VOID, INT, PSHORT, SHORT)
+DEF_FUNCTION_TYPE (VOID, INT, PINT, INT)
+DEF_FUNCTION_TYPE (VOID, INT, PLONGLONG, LONGLONG)
 
 DEF_FUNCTION_TYPE (V2DI, V2DI, V2DI, UINT, UINT)
 DEF_FUNCTION_TYPE (V4HI, HI, HI, HI, HI)
+DEF_FUNCTION_TYPE (CHAR, INT, PCHAR, CHAR, CHAR)
+DEF_FUNCTION_TYPE (INT, INT, PCHAR, CHAR, CHAR)
+DEF_FUNCTION_TYPE (SHORT, INT, PSHORT, SHORT, SHORT)
+DEF_FUNCTION_TYPE (INT, INT, PSHORT, SHORT, SHORT)
+DEF_FUNCTION_TYPE (INT, INT, PINT, INT, INT)
+DEF_FUNCTION_TYPE (LONGLONG, INT, PLONGLONG, LONGLONG, LONGLONG)
+DEF_FUNCTION_TYPE (INT, INT, PLONGLONG, LONGLONG, LONGLONG)
 
 DEF_FUNCTION_TYPE (INT, V16QI, INT, V16QI, INT, INT)
 DEF_FUNCTION_TYPE (V16QI, V16QI, INT, V16QI, INT, INT)
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 973bbeb..05589a1 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -25634,6 +25634,37 @@ enum ix86_builtins
   IX86_BUILTIN_CVTPS2PH,
   IX86_BUILTIN_CVTPS2PH256,
 
+  /* Instructions with HLE prefix.  */
+  IX86_BUILTIN_HLE_BTC16,
+  IX86_BUILTIN_HLE_BTC32,
+  IX86_BUILTIN_HLE_BTC64,
+  IX86_BUILTIN_HLE_BTR16,
+  IX86_BUILTIN_HLE_BTR32,
+  IX86_BUILTIN_HLE_BTR64,
+  IX86_BUILTIN_HLE_BTS16,
+  IX86_BUILTIN_HLE_BTS32,
+  IX86_BUILTIN_HLE_BTS64,
+  IX86_BUILTIN_HLE_VAL_CMPXCHG8,
+  IX86_BUILTIN_HLE_VAL_CMPXCHG16,
+  IX86_BUILTIN_HLE_VAL_CMPXCHG32,
+  IX86_BUILTIN_HLE_VAL_CMPXCHG64,
+  IX86_BUILTIN_HLE_BOOL_CMPXCHG8,
+  IX86_BUILTIN_HLE_BOOL_CMPXCHG16,
+  IX86_BUILTIN_HLE_BOOL_CMPXCHG32,
+  IX86_BUILTIN_HLE_BOOL_CMPXCHG64,
+  IX86_BUILTIN_HLE_XADD8,
+  IX86_BUILTIN_HLE_XADD16,
+  IX86_BUILTIN_HLE_XADD32,
+  IX86_BUILTIN_HLE_XADD64,
+  IX86_BUILTIN_HLE_XCHG8,
+  IX86_BUILTIN_HLE_XCHG16,
+  IX86_BUILTIN_HLE_XCHG32,
+  IX86_BUILTIN_HLE_XCHG64,
+  IX86_BUILTIN_HLE_STORE8,
+  IX86_BUILTIN_HLE_STORE16,
+  IX86_BUILTIN_HLE_STORE32,
+  IX86_BUILTIN_HLE_STORE64,
+
   /* CFString built-in for darwin */
   IX86_BUILTIN_CFSTRING,
 
@@ -25824,6 +25855,99 @@ static const struct builtin_description bdesc_pcmpistr[] =
   { OPTION_MASK_ISA_SSE4_2, CODE_FOR_sse4_2_pcmpistr, "__builtin_ia32_pcmpistriz128", IX86_BUILTIN_PCMPISTRZ128, UNKNOWN, (int) CCZmode },
 };
 
+static const struct builtin_description bdesc_hle[] =
+{
+  /* HLE */
+  { ~OPTION_MASK_ISA_64BIT, CODE_FOR_hle_btchi,
+    "__builtin_ia32_hle_btc_i16", IX86_BUILTIN_HLE_BTC16,
+    UNKNOWN, (int) INT_FTYPE_INT_PSHORT_SHORT },
+  { ~OPTION_MASK_ISA_64BIT, CODE_FOR_hle_btcsi,
+    "__builtin_ia32_hle_btc_i32", IX86_BUILTIN_HLE_BTC32,
+    UNKNOWN, (int) INT_FTYPE_INT_PINT_INT },
+  { OPTION_MASK_ISA_64BIT, CODE_FOR_hle_btcdi,
+    "__builtin_ia32_hle_btc_i64", IX86_BUILTIN_HLE_BTC64,
+    UNKNOWN, (int) INT_FTYPE_INT_PLONGLONG_LONGLONG },
+  { ~OPTION_MASK_ISA_64BIT, CODE_FOR_hle_btrhi,
+    "__builtin_ia32_hle_btr_i16", IX86_BUILTIN_HLE_BTR16,
+    UNKNOWN, (int) INT_FTYPE_INT_PSHORT_SHORT },
+  { ~OPTION_MASK_ISA_64BIT, CODE_FOR_hle_btrsi,
+    "__builtin_ia32_hle_btr_i32",
+    IX86_BUILTIN_HLE_BTR32, UNKNOWN,
+    (int) INT_FTYPE_INT_PINT_INT },
+  { OPTION_MASK_ISA_64BIT, CODE_FOR_hle_btrdi,
+    "__builtin_ia32_hle_btr_i64", IX86_BUILTIN_HLE_BTR64,
+    UNKNOWN, (int) INT_FTYPE_INT_PLONGLONG_LONGLONG },
+  { ~OPTION_MASK_ISA_64BIT, CODE_FOR_hle_btshi,
+    "__builtin_ia32_hle_bts_i16", IX86_BUILTIN_HLE_BTS16,
+    UNKNOWN, (int) INT_FTYPE_INT_PSHORT_SHORT },
+  { ~OPTION_MASK_ISA_64BIT, CODE_FOR_hle_btssi,
+    "__builtin_ia32_hle_bts_i32", IX86_BUILTIN_HLE_BTS32,
+    UNKNOWN, (int) INT_FTYPE_INT_PINT_INT },
+  { OPTION_MASK_ISA_64BIT, CODE_FOR_hle_btsdi,
+    "__builtin_ia32_hle_bts_i64", IX86_BUILTIN_HLE_BTS64,
+    UNKNOWN, (int) INT_FTYPE_INT_PLONGLONG_LONGLONG },
+  { ~OPTION_MASK_ISA_64BIT, CODE_FOR_hle_cmpxchgqi,
+    "__builtin_ia32_hle_val_cmpxchg_i8", IX86_BUILTIN_HLE_VAL_CMPXCHG8,
+    UNKNOWN, (int) CHAR_FTYPE_INT_PCHAR_CHAR_CHAR },
+  { ~OPTION_MASK_ISA_64BIT, CODE_FOR_hle_cmpxchghi,
+    "__builtin_ia32_hle_val_cmpxchg_i16", IX86_BUILTIN_HLE_VAL_CMPXCHG16,
+    UNKNOWN, (int) SHORT_FTYPE_INT_PSHORT_SHORT_SHORT },
+  { ~OPTION_MASK_ISA_64BIT, CODE_FOR_hle_cmpxchgsi,
+    "__builtin_ia32_hle_val_cmpxchg_i32", IX86_BUILTIN_HLE_VAL_CMPXCHG32,
+    UNKNOWN, (int) INT_FTYPE_INT_PINT_INT_INT },
+  { OPTION_MASK_ISA_64BIT, CODE_FOR_hle_cmpxchgdi,
+    "__builtin_ia32_hle_val_cmpxchg_i64", IX86_BUILTIN_HLE_VAL_CMPXCHG64,
+    UNKNOWN, (int) LONGLONG_FTYPE_INT_PLONGLONG_LONGLONG_LONGLONG },
+  { ~OPTION_MASK_ISA_64BIT, CODE_FOR_hle_bool_cmpxchgqi,
+    "__builtin_ia32_hle_bool_cmpxchg_i8", IX86_BUILTIN_HLE_BOOL_CMPXCHG8,
+    UNKNOWN, (int) INT_FTYPE_INT_PCHAR_CHAR_CHAR },
+  { ~OPTION_MASK_ISA_64BIT, CODE_FOR_hle_bool_cmpxchghi,
+    "__builtin_ia32_hle_bool_cmpxchg_i16", IX86_BUILTIN_HLE_BOOL_CMPXCHG16,
+    UNKNOWN, (int) INT_FTYPE_INT_PSHORT_SHORT_SHORT },
+  { ~OPTION_MASK_ISA_64BIT, CODE_FOR_hle_bool_cmpxchgsi,
+    "__builtin_ia32_hle_bool_cmpxchg_i32", IX86_BUILTIN_HLE_BOOL_CMPXCHG32,
+    UNKNOWN, (int) INT_FTYPE_INT_PINT_INT_INT },
+  { OPTION_MASK_ISA_64BIT, CODE_FOR_hle_bool_cmpxchgdi,
+    "__builtin_ia32_hle_bool_cmpxchg_i64", IX86_BUILTIN_HLE_BOOL_CMPXCHG64,
+    UNKNOWN, (int) INT_FTYPE_INT_PLONGLONG_LONGLONG_LONGLONG },
+  { ~OPTION_MASK_ISA_64BIT, CODE_FOR_hle_xaddqi,
+    "__builtin_ia32_hle_xadd_i8", IX86_BUILTIN_HLE_XADD8,
+    UNKNOWN, (int) CHAR_FTYPE_INT_PCHAR_CHAR },
+  { ~OPTION_MASK_ISA_64BIT, CODE_FOR_hle_xaddhi,
+    "__builtin_ia32_hle_xadd_i16", IX86_BUILTIN_HLE_XADD16,
+    UNKNOWN, (int) SHORT_FTYPE_INT_PSHORT_SHORT },
+  { ~OPTION_MASK_ISA_64BIT, CODE_FOR_hle_xaddsi,
+    "__builtin_ia32_hle_xadd_i32", IX86_BUILTIN_HLE_XADD32,
+    UNKNOWN, (int) INT_FTYPE_INT_PINT_INT },
+  { OPTION_MASK_ISA_64BIT, CODE_FOR_hle_xadddi,
+    "__builtin_ia32_hle_xadd_i64", IX86_BUILTIN_HLE_XADD64,
+    UNKNOWN, (int) LONGLONG_FTYPE_INT_PLONGLONG_LONGLONG },
+  { ~OPTION_MASK_ISA_64BIT, CODE_FOR_hle_xchgqi,
+    "__builtin_ia32_hle_xchg_i8", IX86_BUILTIN_HLE_XCHG8,
+    UNKNOWN, (int) CHAR_FTYPE_INT_PCHAR_CHAR },
+  { ~OPTION_MASK_ISA_64BIT, CODE_FOR_hle_xchghi,
+    "__builtin_ia32_hle_xchg_i16", IX86_BUILTIN_HLE_XCHG16,
+    UNKNOWN, (int) SHORT_FTYPE_INT_PSHORT_SHORT },
+  { ~OPTION_MASK_ISA_64BIT, CODE_FOR_hle_xchgsi,
+    "__builtin_ia32_hle_xchg_i32", IX86_BUILTIN_HLE_XCHG32,
+    UNKNOWN, (int) INT_FTYPE_INT_PINT_INT },
+  { OPTION_MASK_ISA_64BIT, CODE_FOR_hle_xchgdi, 
+    "__builtin_ia32_hle_xchg_i64", IX86_BUILTIN_HLE_XCHG64,
+    UNKNOWN, (int) LONGLONG_FTYPE_INT_PLONGLONG_LONGLONG },
+  { ~OPTION_MASK_ISA_64BIT, CODE_FOR_hle_storeqi,
+    "__builtin_ia32_hle_store_i8", IX86_BUILTIN_HLE_STORE8,
+    UNKNOWN, (int) VOID_FTYPE_INT_PCHAR_CHAR },
+  { ~OPTION_MASK_ISA_64BIT, CODE_FOR_hle_storehi,
+    "__builtin_ia32_hle_store_i16", IX86_BUILTIN_HLE_STORE16,
+    UNKNOWN, (int) VOID_FTYPE_INT_PSHORT_SHORT },
+  { ~OPTION_MASK_ISA_64BIT, CODE_FOR_hle_storesi,
+    "__builtin_ia32_hle_store_i32", IX86_BUILTIN_HLE_STORE32,
+    UNKNOWN, (int) VOID_FTYPE_INT_PINT_INT },
+  { OPTION_MASK_ISA_64BIT, CODE_FOR_hle_storedi, 
+    "__builtin_ia32_hle_store_i64", IX86_BUILTIN_HLE_STORE64,
+    UNKNOWN, (int) VOID_FTYPE_INT_PLONGLONG_LONGLONG },
+};
+
 /* Special builtins with variable number of arguments.  */
 static const struct builtin_description bdesc_special_args[] =
 {
@@ -27246,6 +27370,13 @@ ix86_init_mmx_sse_builtins (void)
       def_builtin_const (d->mask, d->name, ftype, d->code);
     }
 
+  /* Instructions with HLE prefix.  */
+  for (i = 0, d = bdesc_hle; i < ARRAY_SIZE (bdesc_hle); i++, d++)
+    {
+      ftype = (enum ix86_builtin_func_type) d->flag;
+      def_builtin (d->mask, d->name, ftype, d->code);
+    }
+
   /* SSE */
   def_builtin (OPTION_MASK_ISA_SSE, "__builtin_ia32_ldmxcsr",
 	       VOID_FTYPE_UNSIGNED, IX86_BUILTIN_LDMXCSR);
@@ -29003,6 +29134,128 @@ ix86_expand_special_args_builtin (const struct builtin_description *d,
   return klass == store ? 0 : target;
 }
 
+/* Subroutine of ix86_expand_builtin to take care of insns with HLE
+   prefix.  */
+
+static rtx
+ix86_expand_hle (const struct builtin_description *d, tree exp,
+		 rtx target)
+{
+  tree arg;
+  rtx pat, op;
+  unsigned int i, nargs;
+  rtx args[4];
+  enum insn_code icode = d->icode;
+  const struct insn_data_d *insn_p = &insn_data[icode];
+  enum machine_mode tmode = insn_p->operand[0].mode;
+  bool store = false;
+
+  switch ((enum ix86_builtin_func_type) d->flag)
+    {
+    case VOID_FTYPE_INT_PCHAR_CHAR:
+    case VOID_FTYPE_INT_PSHORT_SHORT:
+    case VOID_FTYPE_INT_PINT_INT:
+    case VOID_FTYPE_INT_PLONGLONG_LONGLONG:
+      store = true;
+    case CHAR_FTYPE_INT_PCHAR_CHAR:
+    case SHORT_FTYPE_INT_PSHORT_SHORT:
+    case INT_FTYPE_INT_PINT_INT:
+    case LONGLONG_FTYPE_INT_PLONGLONG_LONGLONG:
+    case INT_FTYPE_INT_PSHORT_SHORT:
+    case INT_FTYPE_INT_PLONGLONG_LONGLONG:
+      nargs = 3;
+      break;
+    case CHAR_FTYPE_INT_PCHAR_CHAR_CHAR:
+    case SHORT_FTYPE_INT_PSHORT_SHORT_SHORT:
+    case INT_FTYPE_INT_PINT_INT_INT:
+    case LONGLONG_FTYPE_INT_PLONGLONG_LONGLONG_LONGLONG:
+    case INT_FTYPE_INT_PCHAR_CHAR_CHAR:
+    case INT_FTYPE_INT_PSHORT_SHORT_SHORT:
+    case INT_FTYPE_INT_PLONGLONG_LONGLONG_LONGLONG:
+      nargs = 4;
+      break;
+    default:
+      gcc_unreachable ();
+    }
+
+  gcc_assert (nargs <= ARRAY_SIZE (args));
+
+   /* Check Lock type.  */
+  arg = CALL_EXPR_ARG (exp, 0);
+  op = expand_normal (arg);
+
+  if (store)
+    {
+      if (!CONST_INT_P (op) || (INTVAL (op) != 0 && INTVAL (op) != 3))
+	error ("the first argument must be 0 or 3");
+
+      gcc_assert (target == 0);
+    }
+  else
+    {
+      if (!CONST_INT_P (op) || INTVAL (op) < 0 || INTVAL (op) > 3)
+	error ("the first argument must be 0, 1, 2 or 3");
+
+      if (optimize
+	  || target == 0
+	  || GET_MODE (target) != tmode
+	  || !insn_p->operand[0].predicate (target, tmode))
+	target = gen_reg_rtx (tmode);
+    }
+
+  args[0] = op;
+
+  for (i = 1; i < nargs; i++)
+    {
+      enum machine_mode mode = insn_p->operand[i].mode;
+
+      arg = CALL_EXPR_ARG (exp, i);
+      op = expand_normal (arg);
+
+      switch (i)
+	{
+	case 1:
+	  /* Memory operand.  */
+	  if (GET_MODE (op) != Pmode)
+	    op = convert_to_mode (Pmode, op, 1);
+	  op = gen_rtx_MEM (mode, force_reg (Pmode, op));
+	  gcc_assert (GET_MODE (op) == mode
+		      || GET_MODE (op) == VOIDmode);
+	  break;
+	default:
+	  if (!insn_p->operand[i].predicate (op, mode))
+	    {
+	      if ((GET_MODE (op) != mode && GET_MODE (op) != VOIDmode))
+		op = simplify_gen_subreg (mode, op, GET_MODE (op), 0);
+	      op = copy_to_mode_reg (mode, op);
+	    }
+	  break;
+	}
+
+      args[i] = op;
+    }
+
+  switch (nargs)
+    {
+    case 3:
+      if (store)
+	pat = GEN_FCN (icode) (args[1], args[2], args[0]);
+      else
+	pat = GEN_FCN (icode) (target, args[1], args[2], args[0]);
+      break;
+    case 4:
+      pat = GEN_FCN (icode) (target, args[1], args[2], args[3], args[0]);
+      break;
+    default:
+      gcc_unreachable ();
+    }
+
+  if (! pat)
+    return 0;
+  emit_insn (pat);
+  return store ? 0 : target;
+}
+
 /* Return the integer constant in ARG.  Constrain it to be in the range
    of the subparts of VEC_TYPE; issue an error if not.  */
 
@@ -29657,6 +29910,10 @@ rdrand_step:
     if (d->code == fcode)
       return ix86_expand_sse_pcmpistr (d, exp, target);
 
+  for (i = 0, d = bdesc_hle; i < ARRAY_SIZE (bdesc_hle); i++, d++)
+    if (d->code == fcode)
+      return ix86_expand_hle (d, exp, target);
+
   for (i = 0, d = bdesc_multi_arg; i < ARRAY_SIZE (bdesc_multi_arg); i++, d++)
     if (d->code == fcode)
       return ix86_expand_multi_arg_builtin (d->icode, exp, target,
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index bfbf5bf..e4fd6ce 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -201,6 +201,11 @@
   UNSPECV_RDGSBASE
   UNSPECV_WRFSBASE
   UNSPECV_WRGSBASE
+
+  UNSPECV_HLE_CMPXCHG
+  UNSPECV_HLE_XCHG
+  UNSPECV_BT_CARRY
+  UNSPECV_STORE
 ])
 
 ;; Constants to represent rounding modes in the ROUND instruction
@@ -18115,6 +18120,338 @@
   [(set_attr "length" "2")
    (set_attr "memory" "unknown")])
 
+;; Patterns with HLE prefixes.
+(define_insn "hle_cmpxchg<mode>"
+  [(set (match_operand:SWI 0 "register_operand" "=a")
+	(match_operand:SWI 1 "memory_operand" "+m"))
+   (set (match_dup 1)
+	(unspec_volatile:SWI
+	  [(match_dup 1)
+	   (match_operand:SWI 2 "register_operand" "a")
+	   (match_operand:SWI 3 "register_operand" "<r>")
+	   (match_operand:SWI 4 "const_int_operand" "n")]
+	  UNSPECV_HLE_CMPXCHG))
+   (set (reg:CCZ FLAGS_REG)
+        (compare:CCZ
+          (unspec_volatile:SWI
+            [(match_dup 1) (match_dup 2) (match_dup 3)] UNSPECV_HLE_CMPXCHG)
+          (match_dup 2)))]
+  "TARGET_CMPXCHG"
+{
+    switch (INTVAL (operands[4]))
+      {
+      case 0:
+	return "cmpxchg{<imodesuffix>}\t{%3, %1|%1, %3}";
+      case 1:
+	return "lock{%;} cmpxchg{<imodesuffix>}\t{%3, %1|%1, %3}";
+      case 2:
+	return ASM_BYTE "0xf2; lock{%;} cmpxchg{<imodesuffix>}\t{%3, %1|%1, %3}";
+      case 3:
+	return ASM_BYTE "0xf3; lock{%;} cmpxchg{<imodesuffix>}\t{%3, %1|%1, %3}";
+      default:
+	gcc_unreachable ();
+      }
+})
+
+(define_expand "hle_bool_cmpxchg<mode>"
+  [(set (match_operand:SI 0 "register_operand" "")
+	(unspec_volatile:SWI
+	  [(match_operand:SWI 1 "memory_operand" "")
+	   (match_operand:SWI 2 "register_operand" "")
+	   (match_operand:SWI 3 "register_operand" "")
+	   (match_operand:SWI 4 "const_int_operand" "")]
+	  UNSPECV_HLE_CMPXCHG))]
+  "TARGET_CMPXCHG"
+{
+  rtx insn, op0, op1, tmp;
+  tmp = gen_reg_rtx (<MODE>mode);
+  op0 = gen_reg_rtx (SImode);
+  emit_move_insn (op0, const0_rtx);
+  op1 = gen_reg_rtx (SImode);
+  emit_move_insn (op1, const1_rtx);
+  emit_insn (gen_hle_cmpxchg<mode> (tmp, operands[1],
+				    operands[2], operands[3],
+				    operands[4]));
+  insn = gen_rtx_EQ (VOIDmode, gen_rtx_REG (CCZmode, FLAGS_REG),
+		     const0_rtx);
+  emit_insn (gen_rtx_SET (VOIDmode, operands[0],
+			  gen_rtx_IF_THEN_ELSE (SImode, insn,
+						op1, op0)));
+  DONE;
+})
+
+(define_insn "hle_xadd<mode>"
+  [(set (match_operand:SWI 0 "register_operand" "=<r>")
+	(unspec_volatile:SWI
+	  [(match_operand:SWI 1 "memory_operand" "+m")
+	   (match_operand:SWI 3 "const_int_operand" "n")] UNSPECV_HLE_XCHG))
+   (set (match_dup 1)
+	(plus:SWI (match_dup 1)
+		  (match_operand:SWI 2 "nonmemory_operand" "0")))
+   (clobber (reg:CC FLAGS_REG))]
+  "TARGET_XADD"
+{
+    switch (INTVAL (operands[3]))
+      {
+      case 0:
+	return "xadd{<imodesuffix>}\t{%0, %1|%1, %0}"; 
+      case 1:
+	return "lock{%;} xadd{<imodesuffix>}\t{%0, %1|%1, %0}"; 
+      case 2:
+	return ASM_BYTE "0xf2; lock{%;} xadd{<imodesuffix>}\t{%0, %1|%1, %0}"; 
+      case 3:
+	return ASM_BYTE "0xf3; lock{%;} xadd{<imodesuffix>}\t{%0, %1|%1, %0}"; 
+      default:
+	gcc_unreachable ();
+      }
+})
+
+(define_insn "hle_xchg<mode>"
+  [(set (match_operand:SWI 0 "register_operand" "=<r>")
+	(unspec_volatile:SWI
+	  [(match_operand:SWI 1 "memory_operand" "+m")
+	   (match_operand:SWI 3 "const_int_operand" "n")] 
+	  UNSPECV_HLE_XCHG))
+   (set (match_dup 1)
+	(match_operand:SWI 2 "register_operand" "0"))]
+  ""
+{
+    switch (INTVAL (operands[3]))
+      {
+      case 0:
+      case 1:
+	return "xchg{<imodesuffix>}\t{%1, %0|%0, %1}";
+      case 2:
+	return ASM_BYTE "0xf2; xchg{<imodesuffix>}\t{%1, %0|%0, %1}";
+      case 3:
+	return ASM_BYTE "0xf3; xchg{<imodesuffix>}\t{%1, %0|%0, %1}";
+      default:
+	gcc_unreachable ();
+      }
+})
+
+(define_expand "hle_bts<mode>"
+  [(parallel
+    [(set (match_operand:SI 0 "register_operand" "")
+	  (unspec_volatile:SI
+	    [(match_operand:SWI248 1 "memory_operand" "")
+	     (match_operand:SWI248 2 "x86_64_nonmemory_operand" "")
+	     (match_operand:SWI248 3 "const_int_operand" "")] 
+	    UNSPECV_BT_CARRY))
+     (set (zero_extract:SWI248
+	    (match_dup 0)
+	    (const_int 1)
+	    (match_dup 1))
+	  (const_int 1))])]
+  ""
+{
+  rtx insn, op0, op1;
+  op0 = gen_reg_rtx (SImode);
+  emit_move_insn (op0, const0_rtx);
+  op1 = gen_reg_rtx (SImode);
+  emit_move_insn (op1, const1_rtx);
+  emit_insn (gen_hle_bts<mode>_1 (operands[1], operands[2], operands[3]));
+  insn = gen_rtx_EQ (VOIDmode, gen_rtx_REG (CCCmode, FLAGS_REG),
+		     const0_rtx);
+  emit_insn (gen_rtx_SET (VOIDmode, operands[0],
+			  gen_rtx_IF_THEN_ELSE (SImode, insn,
+						op1, op0)));
+  DONE;
+})
+
+(define_insn "hle_bts<mode>_1"
+  [(set (zero_extract:SWI248
+	   (match_operand:SWI248 0 "memory_operand" "+m")
+	   (const_int 1)
+	   (match_operand:SWI248 1 "x86_64_nonmemory_operand" "rN"))
+	(const_int 1))
+   (set (reg:CCC FLAGS_REG)
+	(unspec_volatile:CCC
+	  [(match_dup 0)
+	   (match_dup 1)
+	   (match_operand:SWI248 2 "const_int_operand" "n")] 
+	  UNSPECV_BT_CARRY))]
+  ""
+{
+  switch (INTVAL (operands[2]))
+    {
+    case 0:
+      return "bts{<imodesuffix>}\t{%1, %0|%0, %1}";
+    case 1:
+      return "lock{%;} bts{<imodesuffix>}\t{%1, %0|%0, %1}";
+    case 2:
+      return ASM_BYTE "0xf2; lock{%;} bts{<imodesuffix>}\t{%1, %0|%0, %1}";
+    case 3:
+      return ASM_BYTE "0xf3; lock{%;} bts{<imodesuffix>}\t{%1, %0|%0, %1}";
+    default:
+      gcc_unreachable ();
+    }
+}
+  [(set_attr "type" "alu1")
+   (set_attr "prefix_0f" "1")
+   (set_attr "mode" "<MODE>")
+   (set (attr "length_immediate")
+     (if_then_else (match_operand 1 "register_operand" "")
+       (const_string "0")
+       (const_string "1")))])
+
+(define_expand "hle_btr<mode>"
+  [(parallel
+    [(set (match_operand:SI 0 "register_operand" "")
+	  (unspec_volatile:SI
+	    [(match_operand:SWI248 1 "memory_operand" "")
+	     (match_operand:SWI248 2 "x86_64_nonmemory_operand" "")
+	     (match_operand:SWI248 3 "const_int_operand" "")] 
+	    UNSPECV_BT_CARRY))
+     (set (zero_extract:SWI248
+	    (match_dup 0)
+	    (const_int 1)
+	    (match_dup 1))
+	  (const_int 0))])]
+  ""
+{
+  rtx insn, op0, op1;
+  op0 = gen_reg_rtx (SImode);
+  emit_move_insn (op0, const0_rtx);
+  op1 = gen_reg_rtx (SImode);
+  emit_move_insn (op1, const1_rtx);
+  emit_insn (gen_hle_btr<mode>_1 (operands[1], operands[2], operands[3]));
+  insn = gen_rtx_EQ (VOIDmode, gen_rtx_REG (CCCmode, FLAGS_REG),
+		     const0_rtx);
+  emit_insn (gen_rtx_SET (VOIDmode, operands[0],
+			  gen_rtx_IF_THEN_ELSE (SImode, insn,
+						op1, op0)));
+  DONE;
+})
+
+(define_insn "hle_btr<mode>_1"
+  [(set (zero_extract:SWI248
+	   (match_operand:SWI248 0 "memory_operand" "+m")
+	   (const_int 1)
+	   (match_operand:SWI248 1 "x86_64_nonmemory_operand" "rN"))
+	(const_int 0))
+   (set (reg:CCC FLAGS_REG)
+	(unspec_volatile:CCC
+	  [(match_dup 0)
+	   (match_dup 1)
+	   (match_operand:SWI248 2 "const_int_operand" "n")] 
+	  UNSPECV_BT_CARRY))]
+  ""
+{
+  switch (INTVAL (operands[2]))
+    {
+    case 0:
+      return "btr{<imodesuffix>}\t{%1, %0|%0, %1}";
+    case 1:
+      return "lock{%;} btr{<imodesuffix>}\t{%1, %0|%0, %1}";
+    case 2:
+      return ASM_BYTE "0xf2; lock{%;} btr{<imodesuffix>}\t{%1, %0|%0, %1}";
+    case 3:
+      return ASM_BYTE "0xf3; lock{%;} btr{<imodesuffix>}\t{%1, %0|%0, %1}";
+    default:
+      gcc_unreachable ();
+    }
+}
+  [(set_attr "type" "alu1")
+   (set_attr "prefix_0f" "1")
+   (set_attr "mode" "<MODE>")
+   (set (attr "length_immediate")
+     (if_then_else (match_operand 1 "register_operand" "")
+       (const_string "0")
+       (const_string "1")))])
+
+(define_expand "hle_btc<mode>"
+  [(parallel
+    [(set (match_operand:SI 0 "register_operand" "")
+	  (unspec_volatile:SI
+	    [(match_operand:SWI248 1 "memory_operand" "")
+	     (match_operand:SWI248 2 "x86_64_nonmemory_operand" "")
+	     (match_operand:SWI248 3 "const_int_operand" "")] 
+	    UNSPECV_BT_CARRY))
+     (set (zero_extract:SWI248
+	    (match_dup 0)
+	    (const_int 1)
+	    (match_dup 1))
+	  (not:SWI248
+	    (zero_extract:SWI248
+	      (match_dup 0)
+	      (const_int 1)
+	      (match_dup 1))))])]
+  ""
+{
+  rtx insn, op0, op1;
+  op0 = gen_reg_rtx (SImode);
+  emit_move_insn (op0, const0_rtx);
+  op1 = gen_reg_rtx (SImode);
+  emit_move_insn (op1, const1_rtx);
+  emit_insn (gen_hle_btc<mode>_1 (operands[1], operands[2], operands[3]));
+  insn = gen_rtx_EQ (VOIDmode, gen_rtx_REG (CCCmode, FLAGS_REG),
+		     const0_rtx);
+  emit_insn (gen_rtx_SET (VOIDmode, operands[0],
+			  gen_rtx_IF_THEN_ELSE (SImode, insn,
+						op1, op0)));
+  DONE;
+})
+
+(define_insn "hle_btc<mode>_1"
+  [(set (zero_extract:SWI248
+	   (match_operand:SWI248 0 "memory_operand" "+m")
+	   (const_int 1)
+	   (match_operand:SWI248 1 "x86_64_nonmemory_operand" "rN"))
+	(not:SWI248
+	  (zero_extract:SWI248
+	    (match_dup 0)
+	    (const_int 1)
+	    (match_dup 1))))
+   (set (reg:CCC FLAGS_REG)
+	(unspec_volatile:CCC
+	  [(match_dup 0)
+	   (match_dup 1)
+	   (match_operand:SWI248 2 "const_int_operand" "n")] 
+	  UNSPECV_BT_CARRY))]
+  ""
+{
+  switch (INTVAL (operands[2]))
+    {
+    case 0:
+      return "btc{<imodesuffix>}\t{%1, %0|%0, %1}";
+    case 1:
+      return "lock{%;} btc{<imodesuffix>}\t{%1, %0|%0, %1}";
+    case 2:
+      return ASM_BYTE "0xf2; lock{%;} btc{<imodesuffix>}\t{%1, %0|%0, %1}";
+    case 3:
+      return ASM_BYTE "0xf3; lock{%;} btc{<imodesuffix>}\t{%1, %0|%0, %1}";
+    default:
+      gcc_unreachable ();
+    }
+}
+  [(set_attr "type" "alu1")
+   (set_attr "prefix_0f" "1")
+   (set_attr "mode" "<MODE>")
+   (set (attr "length_immediate")
+     (if_then_else (match_operand 1 "register_operand" "")
+       (const_string "0")
+       (const_string "1")))])
+
+(define_insn "hle_store<mode>"
+  [(set (match_operand:SWI 0 "memory_operand" "=m")
+	(unspec_volatile:SWI
+	  [(match_operand:SWI 1 "nonmemory_operand" "rn")
+	   (match_operand:SWI 2 "const_int_operand" "n")] 
+	  UNSPECV_STORE))]
+  ""
+{
+  switch (INTVAL (operands[2]))
+    {
+    case 0:
+      return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
+    case 3:
+      return ASM_BYTE "0xf3; mov{<imodesuffix>}\t{%1, %0|%0, %1}";
+    default:
+      gcc_unreachable ();
+    }
+})
+
 (include "mmx.md")
 (include "sse.md")
 (include "sync.md")
diff --git a/gcc/config/i386/immintrin.h b/gcc/config/i386/immintrin.h
index 986a573d..c76ddd3 100644
--- a/gcc/config/i386/immintrin.h
+++ b/gcc/config/i386/immintrin.h
@@ -80,6 +80,8 @@
 #include <f16cintrin.h>
 #endif
 
+#include <hleintrin.h>
+
 #ifdef __RDRND__
 extern __inline int
 __attribute__((__gnu_inline__, __always_inline__, __artificial__))
