diff --git a/gcc/config/i386/constraints.md b/gcc/config/i386/constraints.md
index 6cb53b8..34adbc8 100644
--- a/gcc/config/i386/constraints.md
+++ b/gcc/config/i386/constraints.md
@@ -18,7 +18,7 @@
 ;; <http://www.gnu.org/licenses/>.
 
 ;;; Unused letters:
-;;;     B     H           T
+;;;           H           T
 ;;;           h jk          v
 
 ;; Integer register constraints.
@@ -85,6 +85,9 @@
 (define_register_constraint "x" "TARGET_SSE ? SSE_REGS : NO_REGS"
  "Any SSE register.")
 
+(define_register_constraint "B" "BND_REGS"
+ "@internal Any bound register.")
+
 ;; We use the Y prefix to denote any number of conditional register sets:
 ;;  z	First SSE register.
 ;;  i	SSE2 inter-unit moves to SSE register enabled
diff --git a/gcc/config/i386/i386-modes.def b/gcc/config/i386/i386-modes.def
index 393cd4a..23734ca 100644
--- a/gcc/config/i386/i386-modes.def
+++ b/gcc/config/i386/i386-modes.def
@@ -85,6 +85,9 @@ VECTOR_MODE (INT, DI, 1);     /*                   V1DI */
 VECTOR_MODE (INT, SI, 1);     /*                   V1SI */
 VECTOR_MODE (INT, QI, 2);     /*                   V2QI */
 
+BOUND_MODE (BND32, 8);
+BOUND_MODE (BND64, 16);
+
 INT_MODE (OI, 32);
 
 /* The symbol Pmode stands for one of the above machine modes (usually SImode).
diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h
index 0966789..e747e98 100644
--- a/gcc/config/i386/i386-protos.h
+++ b/gcc/config/i386/i386-protos.h
@@ -237,6 +237,8 @@ extern void ix86_expand_mul_widen_hilo (rtx, rtx, rtx, bool, bool);
 extern void ix86_expand_sse2_mulv4si3 (rtx, rtx, rtx);
 extern void ix86_expand_sse2_mulvxdi3 (rtx, rtx, rtx);
 
+extern bool ix86_bnd_prefixed_insn_p (rtx);
+
 /* In i386-c.c  */
 extern void ix86_target_macros (void);
 extern void ix86_register_pragmas (void);
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 0c546af..05eab8b 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -2188,6 +2188,8 @@ enum reg_class const regclass_map[FIRST_PSEUDO_REGISTER] =
   /* SSE REX registers */
   SSE_REGS, SSE_REGS, SSE_REGS, SSE_REGS, SSE_REGS, SSE_REGS,
   SSE_REGS, SSE_REGS,
+  /* MPX bound registers */
+  BND_REGS, BND_REGS, BND_REGS, BND_REGS,
 };
 
 /* The "default" register map used in 32bit mode.  */
@@ -2201,6 +2203,7 @@ int const dbx_register_map[FIRST_PSEUDO_REGISTER] =
   29, 30, 31, 32, 33, 34, 35, 36,       /* MMX */
   -1, -1, -1, -1, -1, -1, -1, -1,	/* extended integer registers */
   -1, -1, -1, -1, -1, -1, -1, -1,	/* extended SSE registers */
+  101, 102, 103, 104,			/* bound registers */
 };
 
 /* The "default" register map used in 64bit mode.  */
@@ -2214,6 +2217,7 @@ int const dbx64_register_map[FIRST_PSEUDO_REGISTER] =
   41, 42, 43, 44, 45, 46, 47, 48,       /* MMX */
   8,9,10,11,12,13,14,15,		/* extended integer registers */
   25, 26, 27, 28, 29, 30, 31, 32,	/* extended SSE registers */
+  126, 127, 128, 129,			/* bound registers */
 };
 
 /* Define the register numbers to be used in Dwarf debugging information.
@@ -2279,6 +2283,7 @@ int const svr4_dbx_register_map[FIRST_PSEUDO_REGISTER] =
   29, 30, 31, 32, 33, 34, 35, 36,	/* MMX registers */
   -1, -1, -1, -1, -1, -1, -1, -1,	/* extended integer registers */
   -1, -1, -1, -1, -1, -1, -1, -1,	/* extended SSE registers */
+  -1, -1, -1, -1,                       /* bound registers */
 };
 
 /* Define parameter passing and return registers.  */
@@ -8781,7 +8786,7 @@ ix86_code_end (void)
       xops[0] = gen_rtx_REG (Pmode, regno);
       xops[1] = gen_rtx_MEM (Pmode, stack_pointer_rtx);
       output_asm_insn ("mov%z0\t{%1, %0|%0, %1}", xops);
-      fputs ("\tret\n", asm_out_file);
+      output_asm_insn ("%!ret", NULL);
       final_end_function ();
       init_insn_lengths ();
       free_after_compilation (cfun);
@@ -8839,7 +8844,7 @@ output_set_got (rtx dest, rtx label ATTRIBUTE_UNUSED)
 
       xops[2] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (name));
       xops[2] = gen_rtx_MEM (QImode, xops[2]);
-      output_asm_insn ("call\t%X2", xops);
+      output_asm_insn ("%!call\t%X2", xops);
 
 #if TARGET_MACHO
       /* Output the Mach-O "canonical" pic base label name ("Lxx$pb") here.
@@ -14169,7 +14174,7 @@ print_reg (rtx x, int code, FILE *file)
     case 8:
     case 4:
     case 12:
-      if (! ANY_FP_REG_P (x))
+      if (! ANY_FP_REG_P (x) &&  ! ANY_BND_REG_P (x))
 	putc (code == 8 && TARGET_64BIT ? 'r' : 'e', file);
       /* FALLTHRU */
     case 16:
@@ -14283,6 +14288,7 @@ get_some_local_dynamic_name (void)
    ~ -- print "i" if TARGET_AVX2, "f" otherwise.
    @ -- print a segment register of thread base pointer load
    ^ -- print addr32 prefix if TARGET_64BIT and Pmode != word_mode
+   ! -- print MPX prefix for jxx/call/ret instructions if required.
  */
 
 void
@@ -14776,6 +14782,11 @@ ix86_print_operand (FILE *file, rtx x, int code)
 	    fputs ("addr32 ", file);
 	  return;
 
+	case '!':
+	  if (ix86_bnd_prefixed_insn_p (NULL_RTX))
+	    fputs ("bnd ", file);
+	  return;
+
 	default:
 	    output_operand_lossage ("invalid operand code '%c'", code);
 	}
@@ -14917,7 +14928,7 @@ static bool
 ix86_print_operand_punct_valid_p (unsigned char code)
 {
   return (code == '@' || code == '*' || code == '+' || code == '&'
-	  || code == ';' || code == '~' || code == '^');
+	  || code == ';' || code == '~' || code == '^' || code == '!');
 }
 
 /* Print a memory operand whose address is ADDR.  */
@@ -14947,6 +14958,25 @@ ix86_print_operand_address (FILE *file, rtx addr)
       ok = ix86_decompose_address (XVECEXP (addr, 0, 0), &parts);
       code = 'q';
     }
+  else if (GET_CODE (addr) == UNSPEC && XINT (addr, 1) == UNSPEC_BNDMK_ADDR)
+    {
+      ok = ix86_decompose_address (XVECEXP (addr, 0, 1), &parts);
+      gcc_assert (parts.base == NULL_RTX || parts.index == NULL_RTX);
+      if (parts.base != NULL_RTX)
+	{
+	  parts.index = parts.base;
+	  parts.scale = 1;
+	}
+      parts.base = XVECEXP (addr, 0, 0);
+      addr = XVECEXP (addr, 0, 0);
+    }
+  else if (GET_CODE (addr) == UNSPEC && XINT (addr, 1) == UNSPEC_BNDLDX_ADDR)
+    {
+      ok = ix86_decompose_address (XVECEXP (addr, 0, 0), &parts);
+      gcc_assert (parts.index == NULL_RTX);
+      parts.index = XVECEXP (addr, 0, 1);
+      addr = XVECEXP (addr, 0, 0);
+    }
   else
     ok = ix86_decompose_address (addr, &parts);
 
@@ -23910,13 +23940,13 @@ ix86_output_call_insn (rtx insn, rtx call_op)
   if (SIBLING_CALL_P (insn))
     {
       if (direct_p)
-	xasm = "jmp\t%P0";
+	xasm = "%!jmp\t%P0";
       /* SEH epilogue detection requires the indirect branch case
 	 to include REX.W.  */
       else if (TARGET_SEH)
-	xasm = "rex.W jmp %A0";
+	xasm = "%!rex.W jmp %A0";
       else
-	xasm = "jmp\t%A0";
+	xasm = "%!jmp\t%A0";
 
       output_asm_insn (xasm, &call_op);
       return "";
@@ -23953,9 +23983,9 @@ ix86_output_call_insn (rtx insn, rtx call_op)
     }
 
   if (direct_p)
-    xasm = "call\t%P0";
+    xasm = "%!call\t%P0";
   else
-    xasm = "call\t%A0";
+    xasm = "%!call\t%A0";
 
   output_asm_insn (xasm, &call_op);
 
@@ -33919,6 +33949,7 @@ ix86_class_likely_spilled_p (reg_class_t rclass)
       case SSE_FIRST_REG:
       case FP_TOP_REG:
       case FP_SECOND_REG:
+      case BND_REGS:
 	return true;
 
       default:
@@ -34265,6 +34296,8 @@ ix86_hard_regno_mode_ok (int regno, enum machine_mode mode)
     return false;
   if (STACK_REGNO_P (regno))
     return VALID_FP_MODE_P (mode);
+  if (BND_REGNO_P (regno))
+    return VALID_BND_REG_MODE(mode);
   if (SSE_REGNO_P (regno))
     {
       /* We implement the move patterns for all vector modes into and
@@ -35054,6 +35087,10 @@ x86_order_regs_for_local_alloc (void)
    for (i = FIRST_REX_SSE_REG; i <= LAST_REX_SSE_REG; i++)
      reg_alloc_order [pos++] = i;
 
+   /* MPX bound registers.  */
+   for (i = FIRST_BND_REG; i <= LAST_BND_REG; i++)
+     reg_alloc_order [pos++] = i;
+
    /* x87 registers.  */
    if (TARGET_SSE_MATH)
      for (i = FIRST_STACK_REG; i <= LAST_STACK_REG; i++)
@@ -41486,6 +41523,18 @@ ix86_expand_sse2_mulvxdi3 (rtx op0, rtx op1, rtx op2)
 		       gen_rtx_MULT (mode, op1, op2));
 }
 
+/* Return 1 if control tansfer instruction INSN
+   should be encoded with bnd prefix.
+   If insn is NULL then return 1 when control
+   transfer instructions should be prefixed with
+   bnd by default for current function.  */
+
+bool
+ix86_bnd_prefixed_insn_p (rtx insn ATTRIBUTE_UNUSED)
+{
+  return false;
+}
+
 /* Expand an insert into a vector register through pinsr insn.
    Return true if successful.  */
 
diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h
index 7d940f9..bf670bf 100644
--- a/gcc/config/i386/i386.h
+++ b/gcc/config/i386/i386.h
@@ -958,7 +958,7 @@ enum target_cpu_default
    eliminated during reloading in favor of either the stack or frame
    pointer.  */
 
-#define FIRST_PSEUDO_REGISTER 53
+#define FIRST_PSEUDO_REGISTER 57
 
 /* Number of hardware registers that go into the DWARF-2 unwind info.
    If not defined, equals FIRST_PSEUDO_REGISTER.  */
@@ -984,7 +984,10 @@ enum target_cpu_default
 /*  r8,  r9, r10, r11, r12, r13, r14, r15*/			\
      0,   0,   0,   0,   0,   0,   0,   0,			\
 /*xmm8,xmm9,xmm10,xmm11,xmm12,xmm13,xmm14,xmm15*/		\
-     0,   0,    0,    0,    0,    0,    0,    0 }
+     0,   0,    0,    0,    0,    0,    0,    0,		\
+/*  b0,b1,b2,b3*/						\
+     0, 0, 0, 0 }
+
 
 /* 1 for registers not available across function calls.
    These must include the FIXED_REGISTERS and also any
@@ -1012,7 +1015,9 @@ enum target_cpu_default
 /*  r8,  r9, r10, r11, r12, r13, r14, r15*/			\
      1,   1,   1,   1,   2,   2,   2,   2,			\
 /*xmm8,xmm9,xmm10,xmm11,xmm12,xmm13,xmm14,xmm15*/		\
-     6,   6,    6,    6,    6,    6,    6,    6 }
+     6,   6,    6,    6,    6,    6,    6,    6,		\
+/*b0,b1,b2,b3*/							\
+   1, 1, 1, 1 }
 
 /* Order in which to allocate registers.  Each register must be
    listed once, even those in FIXED_REGISTERS.  List frame pointer
@@ -1027,7 +1032,7 @@ enum target_cpu_default
 {  0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,\
    18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32,	\
    33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,  \
-   48, 49, 50, 51, 52 }
+   48, 49, 50, 51, 52, 53, 54, 55, 56 }
 
 /* ADJUST_REG_ALLOC_ORDER is a macro which permits reg_alloc_order
    to be rearranged based on a particular function.  When using sse math,
@@ -1049,6 +1054,7 @@ enum target_cpu_default
 
 #define HARD_REGNO_NREGS(REGNO, MODE)					\
   (STACK_REGNO_P (REGNO) || SSE_REGNO_P (REGNO) || MMX_REGNO_P (REGNO)	\
+   || BND_REGNO_P (REGNO)						\
    ? (COMPLEX_MODE_P (MODE) ? 2 : 1)					\
    : ((MODE) == XFmode							\
       ? (TARGET_64BIT ? 2 : 3)						\
@@ -1090,6 +1096,9 @@ enum target_cpu_default
    || (MODE) == V2SImode || (MODE) == SImode				\
    || (MODE) == V4HImode || (MODE) == V8QImode)
 
+#define VALID_BND_REG_MODE(MODE) \
+  (TARGET_64BIT? (MODE) == BND64mode : (MODE) == BND32mode)
+
 #define VALID_DFP_MODE_P(MODE) \
   ((MODE) == SDmode || (MODE) == DDmode || (MODE) == TDmode)
 
@@ -1184,6 +1193,9 @@ enum target_cpu_default
 #define FIRST_REX_SSE_REG  (LAST_REX_INT_REG + 1)
 #define LAST_REX_SSE_REG   (FIRST_REX_SSE_REG + 7)
 
+#define FIRST_BND_REG  (LAST_REX_SSE_REG + 1)
+#define LAST_BND_REG   (FIRST_BND_REG + 3)
+
 /* Override this in other tm.h files to cope with various OS lossage
    requiring a frame pointer.  */
 #ifndef SUBTARGET_FRAME_POINTER_REQUIRED
@@ -1270,6 +1282,7 @@ enum reg_class
   FLOAT_INT_REGS,
   INT_SSE_REGS,
   FLOAT_INT_SSE_REGS,
+  BND_REGS,
   ALL_REGS, LIM_REG_CLASSES
 };
 
@@ -1318,6 +1331,7 @@ enum reg_class
    "FLOAT_INT_REGS",			\
    "INT_SSE_REGS",			\
    "FLOAT_INT_SSE_REGS",		\
+   "BND_REGS",				\
    "ALL_REGS" }
 
 /* Define which registers fit in which classes.  This is an initializer
@@ -1327,29 +1341,30 @@ enum reg_class
    TARGET_CONDITIONAL_REGISTER_USAGE.  */
 
 #define REG_CLASS_CONTENTS						\
-{     { 0x00,     0x0 },						\
-      { 0x01,     0x0 }, { 0x02, 0x0 },	/* AREG, DREG */		\
-      { 0x04,     0x0 }, { 0x08, 0x0 },	/* CREG, BREG */		\
-      { 0x10,     0x0 }, { 0x20, 0x0 },	/* SIREG, DIREG */		\
-      { 0x03,     0x0 },		/* AD_REGS */			\
-      { 0x0f,     0x0 },		/* Q_REGS */			\
-  { 0x1100f0,  0x1fe0 },		/* NON_Q_REGS */		\
-      { 0x7f,  0x1fe0 },		/* INDEX_REGS */		\
-  { 0x1100ff,     0x0 },		/* LEGACY_REGS */		\
-      { 0x00,     0x0 },		/* CLOBBERED_REGS */		\
-  { 0x1100ff,  0x1fe0 },		/* GENERAL_REGS */		\
-     { 0x100,     0x0 }, { 0x0200, 0x0 },/* FP_TOP_REG, FP_SECOND_REG */\
-    { 0xff00,     0x0 },		/* FLOAT_REGS */		\
-  { 0x200000,     0x0 },		/* SSE_FIRST_REG */		\
-{ 0x1fe00000,0x1fe000 },		/* SSE_REGS */			\
-{ 0xe0000000,    0x1f },		/* MMX_REGS */			\
-{ 0x1fe00100,0x1fe000 },		/* FP_TOP_SSE_REG */		\
-{ 0x1fe00200,0x1fe000 },		/* FP_SECOND_SSE_REG */		\
-{ 0x1fe0ff00,0x1fe000 },		/* FLOAT_SSE_REGS */		\
-  { 0x11ffff,  0x1fe0 },		/* FLOAT_INT_REGS */		\
-{ 0x1ff100ff,0x1fffe0 },		/* INT_SSE_REGS */		\
-{ 0x1ff1ffff,0x1fffe0 },		/* FLOAT_INT_SSE_REGS */	\
-{ 0xffffffff,0x1fffff }							\
+{     { 0x00,     0x0  },						\
+      { 0x01,     0x0  }, { 0x02, 0x0 },	/* AREG, DREG */		\
+      { 0x04,     0x0  }, { 0x08, 0x0 },	/* CREG, BREG */		\
+      { 0x10,     0x0  }, { 0x20, 0x0 },	/* SIREG, DIREG */		\
+      { 0x03,     0x0  },		/* AD_REGS */			  	\
+      { 0x0f,     0x0  },		/* Q_REGS */			  	\
+  { 0x1100f0,  0x1fe0  },		/* NON_Q_REGS */		  	\
+      { 0x7f,  0x1fe0  },		/* INDEX_REGS */		  	\
+  { 0x1100ff,     0x0  },		/* LEGACY_REGS */		  	\
+      { 0x00,     0x0  },		/* CLOBBERED_REGS */		  	\
+  { 0x1100ff,  0x1fe0  },		/* GENERAL_REGS */		  	\
+     { 0x100,     0x0  }, { 0x0200, 0x0 },/* FP_TOP_REG, FP_SECOND_REG */ 	\
+    { 0xff00,     0x0  },		/* FLOAT_REGS */		  	\
+  { 0x200000,     0x0  },		/* SSE_FIRST_REG */		  	\
+{ 0x1fe00000,0x1fe000  },		/* SSE_REGS */				\
+{ 0xe0000000,    0x1f  },		/* MMX_REGS */				\
+{ 0x1fe00100,0x1fe000  },		/* FP_TOP_SSE_REG */			\
+{ 0x1fe00200,0x1fe000  },		/* FP_SECOND_SSE_REG */			\
+{ 0x1fe0ff00,0x1fe000  },		/* FLOAT_SSE_REGS */			\
+  { 0x11ffff,  0x1fe0  },		/* FLOAT_INT_REGS */			\
+{ 0x1ff100ff,0x1fffe0  },		/* INT_SSE_REGS */			\
+{ 0x1ff1ffff,0x1fffe0  },		/* FLOAT_INT_SSE_REGS */		\
+{        0x0,0x1e00000 },		/* BND_REGS */                  	\
+{ 0xffffffff,0x1ffffff }							\
 }
 
 /* The same information, inverted:
@@ -1416,6 +1431,9 @@ enum reg_class
 #define CC_REG_P(X) (REG_P (X) && CC_REGNO_P (REGNO (X)))
 #define CC_REGNO_P(X) ((X) == FLAGS_REG || (X) == FPSR_REG)
 
+#define BND_REGNO_P(N) IN_RANGE ((N), FIRST_BND_REG, LAST_BND_REG)
+#define ANY_BND_REG_P(X) (REG_P (X) && BND_REGNO_P (REGNO (X)))
+
 /* The class value for index registers, and the one for base regs.  */
 
 #define INDEX_REG_CLASS INDEX_REGS
@@ -1847,6 +1865,9 @@ do {							\
    between pointers and any other objects of this machine mode.  */
 #define Pmode (ix86_pmode == PMODE_DI ? DImode : SImode)
 
+/* Specify the machine mode that bounds have.  */
+#define BNDmode (TARGET_64BIT ? BND64mode : BND32mode)
+
 /* A C expression whose value is zero if pointers that need to be extended
    from being `POINTER_SIZE' bits wide to `Pmode' are sign-extended and
    greater then zero if they are zero-extended and less then zero if the
@@ -1952,7 +1973,8 @@ do {							\
  "xmm0","xmm1","xmm2","xmm3","xmm4","xmm5","xmm6","xmm7",		\
  "mm0", "mm1", "mm2", "mm3", "mm4", "mm5", "mm6", "mm7",		\
  "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",			\
- "xmm8", "xmm9", "xmm10", "xmm11", "xmm12", "xmm13", "xmm14", "xmm15"}
+ "xmm8", "xmm9", "xmm10", "xmm11", "xmm12", "xmm13", "xmm14", "xmm15",	\
+ "bnd0", "bnd1", "bnd2", "bnd3" }
 
 #define REGISTER_NAMES HI_REGISTER_NAMES
 
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index c67ed31..30e40a8 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -63,6 +63,7 @@
 ;; ~ -- print "i" if TARGET_AVX2, "f" otherwise.
 ;; @ -- print a segment register of thread base pointer load
 ;; ^ -- print addr32 prefix if TARGET_64BIT and Pmode != word_mode
+;; ! -- print MPX prefix for jxx/call/ret instructions if required.
 
 (define_c_enum "unspec" [
   ;; Relocation specifiers
@@ -178,6 +179,16 @@
   ;; For BMI2 support
   UNSPEC_PDEP
   UNSPEC_PEXT
+
+  UNSPEC_BNDMK
+  UNSPEC_BNDMK_ADDR
+  UNSPEC_BNDSTX
+  UNSPEC_BNDLDX
+  UNSPEC_BNDLDX_ADDR
+  UNSPEC_BNDCL
+  UNSPEC_BNDCU
+  UNSPEC_BNDCN
+  UNSPEC_MPX_FENCE
 ])
 
 (define_c_enum "unspecv" [
@@ -312,6 +323,8 @@
    (XMM13_REG			50)
    (XMM14_REG			51)
    (XMM15_REG			52)
+   (BND0_REG			53)
+   (BND1_REG			54)
   ])
 
 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
@@ -345,7 +358,8 @@
    ssecvt,ssecvt1,sseicvt,sseins,
    sseshuf,sseshuf1,ssemuladd,sse4arg,
    lwp,
-   mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
+   mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft,
+   mpxmov,mpxmk,mpxchk,mpxld,mpxst"
   (const_string "other"))
 
 ;; Main data type used by the insn
@@ -373,7 +387,7 @@
 ;; The (bounding maximum) length of an instruction immediate.
 (define_attr "length_immediate" ""
   (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
-			  bitmanip,imulx")
+			  bitmanip,imulx,mpxmk,mpxmov,mpxchk,mpxld,mpxst")
 	   (const_int 0)
 	 (eq_attr "unit" "i387,sse,mmx")
 	   (const_int 0)
@@ -428,13 +442,17 @@
 	   (const_int 0)
 	 (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
 	   (const_int 1)
+	 (and (eq_attr "type" "ibr,call,callv")
+	      (match_test "ix86_bnd_prefixed_insn_p (insn)"))
+	   (const_int 1)
 	]
 	(const_int 0)))
 
 ;; Set when 0f opcode prefix is used.
 (define_attr "prefix_0f" ""
   (if_then_else
-    (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
+    (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip,
+			  mpxmk,mpxmov,mpxchk,mpxld,mpxst")
 	 (eq_attr "unit" "sse,mmx"))
     (const_int 1)
     (const_int 0)))
@@ -568,12 +586,16 @@
 (define_attr "memory" "none,load,store,both,unknown"
   (cond [(eq_attr "type" "other,multi,str,lwp")
 	   (const_string "unknown")
-	 (eq_attr "type" "lea,fcmov,fpspc")
+	 (eq_attr "type" "lea,fcmov,fpspc,mpxmk,mpxchk")
 	   (const_string "none")
 	 (eq_attr "type" "fistp,leave")
 	   (const_string "both")
 	 (eq_attr "type" "frndint")
 	   (const_string "load")
+	 (eq_attr "type" "mpxld")
+	   (const_string "load")
+	 (eq_attr "type" "mpxst")
+	   (const_string "store")
 	 (eq_attr "type" "push")
 	   (if_then_else (match_operand 1 "memory_operand")
 	     (const_string "both")
@@ -619,7 +641,7 @@
 		   fmov,fcmp,fsgn,
 		   sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,
 		   sselog1,sseshuf1,sseadd1,sseiadd1,sseishft1,
-		   mmx,mmxmov,mmxcmp,mmxcvt")
+		   mmx,mmxmov,mmxcmp,mmxcvt,mpxmov")
 	      (match_operand 2 "memory_operand"))
 	   (const_string "load")
 	 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
@@ -839,6 +861,20 @@
 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
 			    (DI "TARGET_64BIT")])
 
+;; Bound modes.
+(define_mode_iterator BND [(BND32 "!TARGET_64BIT") (BND64 "TARGET_64BIT")])
+
+;; Pointer mode corresponding to bound mode.
+(define_mode_attr bnd_ptr [(BND32 "SI") (BND64 "DI")])
+
+;; MPX check types
+(define_int_iterator BNDCHECK [UNSPEC_BNDCL UNSPEC_BNDCU UNSPEC_BNDCN])
+
+;; Check name
+(define_int_attr bndcheck [(UNSPEC_BNDCL "cl")
+			   (UNSPEC_BNDCU "cu")
+			   (UNSPEC_BNDCN "cn")])
+
 ;; Instruction suffix for integer modes.
 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
 
@@ -5120,7 +5156,7 @@
 
 (define_insn_and_split "*lea<mode>"
   [(set (match_operand:SWI48 0 "register_operand" "=r")
-	(match_operand:SWI48 1 "lea_address_operand" "p"))]
+	(match_operand:SWI48 1 "address_no_seg_operand" "p"))]
   ""
 {
   if (SImode_address_operand (operands[1], VOIDmode))
@@ -10363,7 +10399,7 @@
 		      (label_ref (match_operand 0))
 		      (pc)))]
   ""
-  "%+j%C1\t%l0"
+  "%!%+j%C1\t%l0"
   [(set_attr "type" "ibr")
    (set_attr "modrm" "0")
    (set (attr "length")
@@ -10371,8 +10407,8 @@
 				  (const_int -126))
 			      (lt (minus (match_dup 0) (pc))
 				  (const_int 128)))
-	     (const_int 2)
-	     (const_int 6)))])
+	     (plus (const_int 2) (attr "prefix_rep"))
+	     (plus (const_int 6) (attr "prefix_rep"))))])
 
 (define_insn "*jcc_2"
   [(set (pc)
@@ -10381,7 +10417,7 @@
 		      (pc)
 		      (label_ref (match_operand 0))))]
   ""
-  "%+j%c1\t%l0"
+  "%!%+j%c1\t%l0"
   [(set_attr "type" "ibr")
    (set_attr "modrm" "0")
    (set (attr "length")
@@ -10389,8 +10425,8 @@
 				  (const_int -126))
 			      (lt (minus (match_dup 0) (pc))
 				  (const_int 128)))
-	     (const_int 2)
-	     (const_int 6)))])
+	     (plus (const_int 2) (attr "prefix_rep"))
+	     (plus (const_int 6) (attr "prefix_rep"))))])
 
 ;; In general it is not safe to assume too much about CCmode registers,
 ;; so simplify-rtx stops when it sees a second one.  Under certain
@@ -10847,15 +10883,15 @@
   [(set (pc)
 	(label_ref (match_operand 0)))]
   ""
-  "jmp\t%l0"
+  "%!jmp\t%l0"
   [(set_attr "type" "ibr")
    (set (attr "length")
 	   (if_then_else (and (ge (minus (match_dup 0) (pc))
 				  (const_int -126))
 			      (lt (minus (match_dup 0) (pc))
 				  (const_int 128)))
-	     (const_int 2)
-	     (const_int 5)))
+	     (plus (const_int 2) (attr "prefix_rep"))
+	     (plus (const_int 5) (attr "prefix_rep"))))
    (set_attr "modrm" "0")])
 
 (define_expand "indirect_jump"
@@ -10869,7 +10905,7 @@
 (define_insn "*indirect_jump"
   [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rw"))]
   ""
-  "jmp\t%A0"
+  "%!jmp\t%A0"
   [(set_attr "type" "ibr")
    (set_attr "length_immediate" "0")])
 
@@ -10918,7 +10954,7 @@
   [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rw"))
    (use (label_ref (match_operand 1)))]
   ""
-  "jmp\t%A0"
+  "%!jmp\t%A0"
   [(set_attr "type" "ibr")
    (set_attr "length_immediate" "0")])
 
@@ -11305,8 +11341,14 @@
 (define_insn "simple_return_internal"
   [(simple_return)]
   "reload_completed"
-  "ret"
-  [(set_attr "length" "1")
+  "%!ret"
+  [(set (attr "length")
+          (plus (const_int 1)
+                (attr "prefix_rep")))
+   (set (attr "prefix_rep")
+	(if_then_else (match_test "ix86_bnd_prefixed_insn_p (insn)")
+	  (const_int 1)
+	  (const_int 0)))
    (set_attr "atom_unit" "jeu")
    (set_attr "length_immediate" "0")
    (set_attr "modrm" "0")])
@@ -11318,7 +11360,12 @@
   [(simple_return)
    (unspec [(const_int 0)] UNSPEC_REP)]
   "reload_completed"
-  "rep%; ret"
+{
+  if (ix86_bnd_prefixed_insn_p (insn))
+    return "%!ret";
+
+  return "rep%; ret";
+}
   [(set_attr "length" "2")
    (set_attr "atom_unit" "jeu")
    (set_attr "length_immediate" "0")
@@ -11329,8 +11376,14 @@
   [(simple_return)
    (use (match_operand:SI 0 "const_int_operand"))]
   "reload_completed"
-  "ret\t%0"
-  [(set_attr "length" "3")
+  "%!ret\t%0"
+  [(set (attr "length")
+          (plus (const_int 3)
+                (attr "prefix_rep")))
+   (set (attr "prefix_rep")
+	(if_then_else (match_test "ix86_bnd_prefixed_insn_p (insn)")
+	  (const_int 1)
+	  (const_int 0)))
    (set_attr "atom_unit" "jeu")
    (set_attr "length_immediate" "2")
    (set_attr "modrm" "0")])
@@ -11339,7 +11392,7 @@
   [(simple_return)
    (use (match_operand:SI 0 "register_operand" "r"))]
   "reload_completed"
-  "jmp\t%A0"
+  "%!jmp\t%A0"
   [(set_attr "type" "ibr")
    (set_attr "length_immediate" "0")])
 
@@ -17758,6 +17811,141 @@
   [(set_attr "type" "other")
    (set_attr "length" "3")])
 
+;; MPX instructions
+
+(define_expand "<mode>_mk"
+  [(set (match_operand:BND 0 "register_operand" "=B")
+    (unspec:BND
+      [(mem:<bnd_ptr>
+       (match_par_dup 3
+        [(match_operand:<bnd_ptr> 1 "register_operand" "r")
+	 (match_operand:<bnd_ptr> 2 "address_mpx_no_base_operand" "p")]))]
+      UNSPEC_BNDMK))]
+""
+{
+  operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[1],
+						  operands[2]),
+                                UNSPEC_BNDMK_ADDR);
+})
+
+(define_insn "*<mode>_mk"
+  [(set (match_operand:BND 0 "register_operand" "=B")
+    (unspec:BND
+      [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
+        [(unspec:<bnd_ptr>
+	   [(match_operand:<bnd_ptr> 1 "register_operand" "r")
+            (match_operand:<bnd_ptr> 2 "address_mpx_no_base_operand" "p")]
+	   UNSPEC_BNDMK_ADDR)])]
+      UNSPEC_BNDMK))]
+  ""
+{
+  return "bndmk\t{%3, %0|%0, %3}";
+}
+  [(set_attr "type" "mpxmk")])
+
+(define_expand "mov<mode>"
+  [(set (match_operand:BND 0 "general_operand" "=B,m,B")
+        (match_operand:BND 1 "general_operand" "m,B,B"))]
+  ""
+{
+  ix86_expand_move (<MODE>mode, operands);DONE;
+})
+
+(define_insn "*mov<mode>_internal_mpx"
+  [(set (match_operand:BND 0 "nonimmediate_operand" "=B,m,B")
+        (match_operand:BND 1 "general_operand" "m,B,B"))]
+  ""
+{
+  return "bndmov\t{%1, %0|%0, %1}";
+}
+  [(set_attr "type" "mpxmov")])
+
+(define_expand "<mode>_<bndcheck>"
+  [(parallel [(unspec [(match_operand:BND 0 "register_operand" "B")
+                       (match_operand:<bnd_ptr> 1 "address_no_seg_operand" "p")] BNDCHECK)
+              (set (match_dup 2)
+                   (unspec:BLK [(match_dup 2)] UNSPEC_MPX_FENCE))])]
+  ""
+{
+  operands[2] = gen_rtx_MEM (BLKmode, operands[1]);
+  MEM_VOLATILE_P (operands[2]) = 1;
+})
+
+(define_insn "*<mode>_<bndcheck>"
+  [(parallel [(unspec [(match_operand:BND 0 "register_operand" "B")
+                       (match_operand:<bnd_ptr> 1 "address_no_seg_operand" "p")] BNDCHECK)
+              (set (match_operand:BLK 2 "bnd_mem_operator")
+                   (unspec:BLK [(match_dup 2)] UNSPEC_MPX_FENCE))])]
+  ""
+{
+  return "bnd<bndcheck>\t{%a1, %0|%0, %a1}";
+}
+  [(set_attr "type" "mpxchk")])
+
+(define_expand "<mode>_ldx"
+  [(parallel [(set:BND (match_operand:BND 0 "register_operand" "=B")
+                       (unspec:BND
+		         [(mem:<bnd_ptr>
+			   (match_par_dup 3
+			     [(match_operand:<bnd_ptr> 1 "address_mpx_no_index_operand" "p")
+	                      (match_operand:<bnd_ptr> 2 "register_operand" "l")]))]
+			 UNSPEC_BNDLDX))
+              (use (mem:BLK (match_dup 1)))])]
+  ""
+{
+  operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[1],
+                                                  operands[2]),
+				UNSPEC_BNDLDX_ADDR);
+})
+
+(define_insn "*<mode>_ldx"
+  [(parallel [(set:BND (match_operand:BND 0 "register_operand" "=B")
+                       (unspec:BND
+		         [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
+			   [(unspec:<bnd_ptr>
+			     [(match_operand:<bnd_ptr> 1 "address_mpx_no_index_operand" "p")
+	                      (match_operand:<bnd_ptr> 2 "register_operand" "l")]
+			    UNSPEC_BNDLDX_ADDR)])]
+			 UNSPEC_BNDLDX))
+              (use (mem:BLK (match_dup 1)))])]
+  ""
+{
+  return "bndldx\t{%3, %0|%0, %3}";
+}
+  [(set_attr "type" "mpxld")])
+
+(define_expand "<mode>_stx"
+  [(parallel [(unspec [(mem:<bnd_ptr>
+			 (match_par_dup 3
+			   [(match_operand:<bnd_ptr> 0 "address_mpx_no_index_operand" "p")
+	                    (match_operand:<bnd_ptr> 1 "register_operand" "l")]))
+	               (match_operand:BND 2 "register_operand" "B")] UNSPEC_BNDSTX)
+              (set (match_dup 4)
+                   (unspec:BLK [(match_dup 4)] UNSPEC_MPX_FENCE))])]
+  ""
+{
+  operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[0],
+                                                  operands[1]),
+				UNSPEC_BNDLDX_ADDR);
+  operands[4] = gen_rtx_MEM (BLKmode, operands[0]);
+  MEM_VOLATILE_P (operands[4]) = 1;
+})
+
+(define_insn "*<mode>_stx"
+  [(parallel [(unspec [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
+			 [(unspec:<bnd_ptr>
+			  [(match_operand:<bnd_ptr> 0 "address_mpx_no_index_operand" "p")
+	                   (match_operand:<bnd_ptr> 1 "register_operand" "l")]
+			 UNSPEC_BNDLDX_ADDR)])
+	               (match_operand:BND 2 "register_operand" "B")] UNSPEC_BNDSTX)
+              (set (match_operand:BLK 4 "bnd_mem_operator")
+                   (unspec:BLK [(match_dup 4)] UNSPEC_MPX_FENCE))])]
+  ""
+{
+  return "bndstx\t{%2, %3|%3, %2}";
+}
+  [(set_attr "type" "mpxst")])
+
 (include "mmx.md")
 (include "sse.md")
 (include "sync.md")
diff --git a/gcc/config/i386/predicates.md b/gcc/config/i386/predicates.md
index b64ef69..4f115c8 100644
--- a/gcc/config/i386/predicates.md
+++ b/gcc/config/i386/predicates.md
@@ -850,7 +850,7 @@
 ;; Return true if op if a valid address for LEA, and does not contain
 ;; a segment override.  Defined as a special predicate to allow
 ;; mode-less const_int operands pass to address_operand.
-(define_special_predicate "lea_address_operand"
+(define_special_predicate "address_no_seg_operand"
   (match_operand 0 "address_operand")
 {
   struct ix86_address parts;
@@ -907,9 +907,74 @@
   return true;
 })
 
+;; Return true if op is valid MPX address operand without base
+(define_predicate "address_mpx_no_base_operand"
+  (match_operand 0 "address_operand")
+{
+  struct ix86_address parts;
+  int ok;
+
+  ok = ix86_decompose_address (op, &parts);
+  gcc_assert (ok);
+
+  if (parts.index && parts.base)
+    return false;
+
+  if (parts.seg != SEG_DEFAULT)
+    return false;
+
+  /* Do not support (%rip).  */
+  if (parts.disp && flag_pic && TARGET_64BIT
+      && SYMBOLIC_CONST (parts.disp))
+    {
+      if (GET_CODE (parts.disp) != CONST
+	  || GET_CODE (XEXP (parts.disp, 0)) != PLUS
+	  || GET_CODE (XEXP (XEXP (parts.disp, 0), 0)) != UNSPEC
+	  || !CONST_INT_P (XEXP (XEXP (parts.disp, 0), 1))
+	  || (XINT (XEXP (XEXP (parts.disp, 0), 0), 1) != UNSPEC_DTPOFF
+	      && XINT (XEXP (XEXP (parts.disp, 0), 0), 1) != UNSPEC_NTPOFF))
+	return false;
+    }
+
+  return true;
+})
+
+;; Return true if op is valid MPX address operand without index
+(define_predicate "address_mpx_no_index_operand"
+  (match_operand 0 "address_operand")
+{
+  struct ix86_address parts;
+  int ok;
+
+  ok = ix86_decompose_address (op, &parts);
+  gcc_assert (ok);
+
+  if (parts.index)
+    return false;
+
+  if (parts.seg != SEG_DEFAULT)
+    return false;
+
+  /* Do not support (%rip).  */
+  if (parts.disp && flag_pic && TARGET_64BIT
+      && SYMBOLIC_CONST (parts.disp)
+      && (GET_CODE (parts.disp) != CONST
+	  || GET_CODE (XEXP (parts.disp, 0)) != PLUS
+	  || GET_CODE (XEXP (XEXP (parts.disp, 0), 0)) != UNSPEC
+	  || !CONST_INT_P (XEXP (XEXP (parts.disp, 0), 1))
+	  || (XINT (XEXP (XEXP (parts.disp, 0), 0), 1) != UNSPEC_DTPOFF
+	      && XINT (XEXP (XEXP (parts.disp, 0), 0), 1) != UNSPEC_NTPOFF)))
+    return false;
+
+  return true;
+})
+
 (define_predicate "vsib_mem_operator"
   (match_code "mem"))
 
+(define_predicate "bnd_mem_operator"
+  (match_code "mem"))
+
 ;; Return true if the rtx is known to be at least 32 bits aligned.
 (define_predicate "aligned_operand"
   (match_operand 0 "general_operand")
diff --git a/gcc/genmodes.c b/gcc/genmodes.c
index dc38483..2cd9331 100644
--- a/gcc/genmodes.c
+++ b/gcc/genmodes.c
@@ -333,6 +333,7 @@ complete_mode (struct mode_data *m)
       break;
 
     case MODE_INT:
+    case MODE_BOUND:
     case MODE_FLOAT:
     case MODE_DECIMAL_FLOAT:
     case MODE_FRACT:
@@ -533,6 +534,18 @@ make_special_mode (enum mode_class cl, const char *name,
   new_mode (cl, name, file, line);
 }
 
+#define BOUND_MODE(N, Y) make_bound_mode (#N, Y, __FILE__, __LINE__)
+
+static void
+make_bound_mode (const char *name,
+               unsigned int bytesize,
+               const char *file, unsigned int line)
+{
+  struct mode_data *m = new_mode (MODE_BOUND, name, file, line);
+  m->bytesize = bytesize;
+}
+
+
 #define INT_MODE(N, Y) FRACTIONAL_INT_MODE (N, -1U, Y)
 #define FRACTIONAL_INT_MODE(N, B, Y) \
   make_int_mode (#N, B, Y, __FILE__, __LINE__)
diff --git a/gcc/machmode.h b/gcc/machmode.h
index 981ee92..d4a20b2 100644
--- a/gcc/machmode.h
+++ b/gcc/machmode.h
@@ -174,6 +174,9 @@ extern const unsigned char mode_class[NUM_MACHINE_MODES];
    || CLASS == MODE_ACCUM                      \
    || CLASS == MODE_UACCUM)
 
+#define BOUND_MODE_P(MODE)      \
+  (GET_MODE_CLASS (MODE) == MODE_BOUND)
+
 /* Get the size in bytes and bits of an object of mode MODE.  */
 
 extern CONST_MODE_SIZE unsigned char mode_size[NUM_MACHINE_MODES];
diff --git a/gcc/mode-classes.def b/gcc/mode-classes.def
index 7207ef7..c5ea215 100644
--- a/gcc/mode-classes.def
+++ b/gcc/mode-classes.def
@@ -21,6 +21,7 @@ along with GCC; see the file COPYING3.  If not see
   DEF_MODE_CLASS (MODE_RANDOM),		/* other */			   \
   DEF_MODE_CLASS (MODE_CC),		/* condition code in a register */ \
   DEF_MODE_CLASS (MODE_INT),		/* integer */			   \
+  DEF_MODE_CLASS (MODE_BOUND),            /* bounds */                     \
   DEF_MODE_CLASS (MODE_PARTIAL_INT),	/* integer with padding bits */    \
   DEF_MODE_CLASS (MODE_FRACT),		/* signed fractional number */	   \
   DEF_MODE_CLASS (MODE_UFRACT),		/* unsigned fractional number */   \
diff --git a/gcc/stor-layout.c b/gcc/stor-layout.c
index 6f6b310..e269347 100644
--- a/gcc/stor-layout.c
+++ b/gcc/stor-layout.c
@@ -323,6 +323,20 @@ mode_for_size (unsigned int size, enum mode_class mclass, int limit)
   return BLKmode;
 }
 
+enum machine_mode
+mode_for_bound (unsigned int size, enum mode_class mclass)
+{
+  enum machine_mode mode;
+
+  /* Get the first mode which has this size, in the specified class.  */
+  for (mode = GET_CLASS_NARROWEST_MODE (mclass); mode != VOIDmode;
+       mode = GET_MODE_WIDER_MODE (mode))
+    if (GET_MODE_SIZE (mode) == (size/8))
+      return mode;
+
+  return BLKmode;
+}
+
 /* Similar, except passed a tree node.  */
 
 enum machine_mode
@@ -383,6 +397,7 @@ int_mode_for_mode (enum machine_mode mode)
     case MODE_VECTOR_ACCUM:
     case MODE_VECTOR_UFRACT:
     case MODE_VECTOR_UACCUM:
+    case MODE_BOUND:
       mode = mode_for_size (GET_MODE_BITSIZE (mode), MODE_INT, 0);
       break;
 
@@ -2135,6 +2150,13 @@ layout_type (tree type)
       SET_TYPE_MODE (type, VOIDmode);
       break;
 
+    case BOUND_TYPE:
+      SET_TYPE_MODE (type,
+                     mode_for_bound (TYPE_PRECISION (type), MODE_BOUND));
+      TYPE_SIZE (type) = bitsize_int (GET_MODE_BITSIZE (TYPE_MODE (type)));
+      TYPE_SIZE_UNIT (type) = size_int (GET_MODE_SIZE (TYPE_MODE (type)));
+      break;
+
     case OFFSET_TYPE:
       TYPE_SIZE (type) = bitsize_int (POINTER_SIZE);
       TYPE_SIZE_UNIT (type) = size_int (POINTER_SIZE / BITS_PER_UNIT);
diff --git a/gcc/tree-pretty-print.c b/gcc/tree-pretty-print.c
index 7745f73..83458e6 100644
--- a/gcc/tree-pretty-print.c
+++ b/gcc/tree-pretty-print.c
@@ -668,6 +668,7 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
       break;
 
     case VOID_TYPE:
+    case BOUND_TYPE:
     case INTEGER_TYPE:
     case REAL_TYPE:
     case FIXED_POINT_TYPE:
diff --git a/gcc/tree.c b/gcc/tree.c
index ab11735..0c53795 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -1189,6 +1189,7 @@ build_int_cst_wide (tree type, unsigned HOST_WIDE_INT low, HOST_WIDE_INT hi)
 
     case INTEGER_TYPE:
     case OFFSET_TYPE:
+    case BOUND_TYPE:
       if (TYPE_UNSIGNED (type))
 	{
 	  /* Cache 0..N */
@@ -3224,6 +3225,7 @@ type_contains_placeholder_1 (const_tree type)
   switch (TREE_CODE (type))
     {
     case VOID_TYPE:
+    case BOUND_TYPE:
     case COMPLEX_TYPE:
     case ENUMERAL_TYPE:
     case BOOLEAN_TYPE:
diff --git a/gcc/tree.def b/gcc/tree.def
index da30074..9395813 100644
--- a/gcc/tree.def
+++ b/gcc/tree.def
@@ -232,6 +232,8 @@ DEFTREECODE (QUAL_UNION_TYPE, "qual_union_type", tcc_type, 0)
 /* The void type in C */
 DEFTREECODE (VOID_TYPE, "void_type", tcc_type, 0)
 
+DEFTREECODE (BOUND_TYPE, "bound_type", tcc_type, 0)
+
 /* Type of functions.  Special fields:
    TREE_TYPE		    type of value returned.
    TYPE_ARG_TYPES      list of types of arguments expected.
diff --git a/gcc/tree.h b/gcc/tree.h
index 0058a4b..65f87fb 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -1076,6 +1076,10 @@ extern void omp_clause_range_check_failed (const_tree, const char *, int,
 /* Nonzero if this type is a complete type.  */
 #define COMPLETE_TYPE_P(NODE) (TYPE_SIZE (NODE) != NULL_TREE)
 
+/* Nonzero if this type is a bound type.  */
+#define BOUND_TYPE_P(NODE) \
+  (TREE_CODE (NODE) == BOUND_TYPE)
+
 /* Nonzero if this type is the (possibly qualified) void type.  */
 #define VOID_TYPE_P(NODE) (TREE_CODE (NODE) == VOID_TYPE)
 
diff --git a/gcc/varasm.c b/gcc/varasm.c
index 8efd98e..c6e9063 100644
--- a/gcc/varasm.c
+++ b/gcc/varasm.c
@@ -4660,6 +4660,7 @@ output_constant (tree exp, unsigned HOST_WIDE_INT size, unsigned int align)
     case REFERENCE_TYPE:
     case OFFSET_TYPE:
     case FIXED_POINT_TYPE:
+    case BOUND_TYPE:
       if (! assemble_integer (expand_expr (exp, NULL_RTX, VOIDmode,
 					   EXPAND_INITIALIZER),
 			      MIN (size, thissize), align, 0))
