From 0b177abbcdd46841d1f1bee6977dde4fac7ddeaf Mon Sep 17 00:00:00 2001 From: kyukhin Date: Fri, 25 Oct 2013 05:37:57 +0000 Subject: [PATCH] * config/i386/constraints.md (B): New. (Ti): New. (Tb): New. * config/i386/i386-c.c (ix86_target_macros_internal): Add __MPX__. * config/i386/i386-modes.def (BND32): New. (BND64): New. * config/i386/i386-protos.h (ix86_bnd_prefixed_insn_p): New. * config/i386/i386.c (isa_opts): Add mmpx. (regclass_map): Add bound registers. (dbx_register_map): Likewise. (dbx64_register_map): Likewise. (svr4_dbx_register_map): Likewise. (PTA_MPX): New. (ix86_option_override_internal): Support MPX ISA. (ix86_conditional_register_usage): Support bound registers. (print_reg): Likewise. (ix86_code_end): Add MPX bnd prefix. (output_set_got): Likewise. (ix86_output_call_insn): Likewise. (ix86_print_operand): Add '!' (MPX bnd) print prefix support. (ix86_print_operand_punct_valid_p): Likewise. (ix86_print_operand_address): Support UNSPEC_BNDMK_ADDR and UNSPEC_BNDMK_ADDR. (ix86_class_likely_spilled_p): Add bound regs support. (ix86_hard_regno_mode_ok): Likewise. (x86_order_regs_for_local_alloc): Likewise. (ix86_bnd_prefixed_insn_p): New. * config/i386/i386.h (FIRST_PSEUDO_REGISTER): Fix to new value. (FIXED_REGISTERS): Add bound registers. (CALL_USED_REGISTERS): Likewise. (REG_ALLOC_ORDER): Likewise. (HARD_REGNO_NREGS): Likewise. (TARGET_MPX): New. (VALID_BND_REG_MODE): New. (FIRST_BND_REG): New. (LAST_BND_REG): New. (reg_class): Add BND_REGS. (REG_CLASS_NAMES): Likewise. (REG_CLASS_CONTENTS): Likewise. (BND_REGNO_P): New. (ANY_BND_REG_P): New. (BNDmode): New. (HI_REGISTER_NAMES): Add bound registers. * config/i386/i386.md (UNSPEC_BNDMK): New. (UNSPEC_BNDMK_ADDR): New. (UNSPEC_BNDSTX): New. (UNSPEC_BNDLDX): New. (UNSPEC_BNDLDX_ADDR): New. (UNSPEC_BNDCL): New. (UNSPEC_BNDCU): New. (UNSPEC_BNDCN): New. (UNSPEC_MPX_FENCE): New. (BND0_REG): New. (BND1_REG): New. (type): Add mpxmov, mpxmk, mpxchk, mpxld, mpxst. (length_immediate): Likewise. (prefix_0f): Likewise. (memory): Likewise. (prefix_rep): Check for bnd prefix. (length_nobnd): New. (length): Use length_nobnd if specified. (BND): New. (bnd_ptr): New. (BNDCHECK): New. (bndcheck): New. (*jcc_1): Add bnd prefix and rename length attr to length_nobnd. (*jcc_2): Likewise. (jump): Likewise. (simple_return_internal): Likewise. (simple_return_pop_internal): Likewise. (*indirect_jump): Add MPX bnd prefix. (*tablejump_1): Likewise. (simple_return_internal_long): Likewise. (simple_return_indirect_internal): Likewise. (_mk): New. (*_mk): New. (mov): New. (*mov_internal_mpx): New. (_): New. (*_): New. (_ldx): New. (*_ldx): New. (_stx): New. (*_stx): New. * config/i386/predicates.md (lea_address_operand): Rename to... (address_no_seg_operand): ... this. (address_mpx_no_base_operand): New. (address_mpx_no_index_operand): New. (bnd_mem_operator): New. * config/i386/i386.opt (mmpx): New. * doc/invoke.texi: Add documentation for the flags -mmpx, -mno-mpx. * doc/rtl.texi Add documentation for BND32mode and BND64mode. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@204046 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 95 ++++++++++++++++++ gcc/config/i386/constraints.md | 17 +++- gcc/config/i386/i386-c.c | 2 + gcc/config/i386/i386-modes.def | 3 + gcc/config/i386/i386-protos.h | 2 + gcc/config/i386/i386.c | 74 ++++++++++++-- gcc/config/i386/i386.h | 94 +++++++++++------- gcc/config/i386/i386.md | 217 +++++++++++++++++++++++++++++++++++++---- gcc/config/i386/i386.opt | 4 + gcc/config/i386/predicates.md | 67 ++++++++++++- gcc/doc/invoke.texi | 6 +- gcc/doc/rtl.texi | 6 ++ 12 files changed, 517 insertions(+), 70 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index e919420a8af..6702604ef55 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,100 @@ 2013-10-24 Ilya Enkovich + * config/i386/constraints.md (B): New. + (Ti): New. + (Tb): New. + * config/i386/i386-c.c (ix86_target_macros_internal): Add __MPX__. + * config/i386/i386-modes.def (BND32): New. + (BND64): New. + * config/i386/i386-protos.h (ix86_bnd_prefixed_insn_p): New. + * config/i386/i386.c (isa_opts): Add mmpx. + (regclass_map): Add bound registers. + (dbx_register_map): Likewise. + (dbx64_register_map): Likewise. + (svr4_dbx_register_map): Likewise. + (PTA_MPX): New. + (ix86_option_override_internal): Support MPX ISA. + (ix86_conditional_register_usage): Support bound registers. + (print_reg): Likewise. + (ix86_code_end): Add MPX bnd prefix. + (output_set_got): Likewise. + (ix86_output_call_insn): Likewise. + (ix86_print_operand): Add '!' (MPX bnd) print prefix support. + (ix86_print_operand_punct_valid_p): Likewise. + (ix86_print_operand_address): Support UNSPEC_BNDMK_ADDR and + UNSPEC_BNDMK_ADDR. + (ix86_class_likely_spilled_p): Add bound regs support. + (ix86_hard_regno_mode_ok): Likewise. + (x86_order_regs_for_local_alloc): Likewise. + (ix86_bnd_prefixed_insn_p): New. + * config/i386/i386.h (FIRST_PSEUDO_REGISTER): Fix to new value. + (FIXED_REGISTERS): Add bound registers. + (CALL_USED_REGISTERS): Likewise. + (REG_ALLOC_ORDER): Likewise. + (HARD_REGNO_NREGS): Likewise. + (TARGET_MPX): New. + (VALID_BND_REG_MODE): New. + (FIRST_BND_REG): New. + (LAST_BND_REG): New. + (reg_class): Add BND_REGS. + (REG_CLASS_NAMES): Likewise. + (REG_CLASS_CONTENTS): Likewise. + (BND_REGNO_P): New. + (ANY_BND_REG_P): New. + (BNDmode): New. + (HI_REGISTER_NAMES): Add bound registers. + * config/i386/i386.md (UNSPEC_BNDMK): New. + (UNSPEC_BNDMK_ADDR): New. + (UNSPEC_BNDSTX): New. + (UNSPEC_BNDLDX): New. + (UNSPEC_BNDLDX_ADDR): New. + (UNSPEC_BNDCL): New. + (UNSPEC_BNDCU): New. + (UNSPEC_BNDCN): New. + (UNSPEC_MPX_FENCE): New. + (BND0_REG): New. + (BND1_REG): New. + (type): Add mpxmov, mpxmk, mpxchk, mpxld, mpxst. + (length_immediate): Likewise. + (prefix_0f): Likewise. + (memory): Likewise. + (prefix_rep): Check for bnd prefix. + (length_nobnd): New. + (length): Use length_nobnd if specified. + (BND): New. + (bnd_ptr): New. + (BNDCHECK): New. + (bndcheck): New. + (*jcc_1): Add bnd prefix and rename length attr to length_nobnd. + (*jcc_2): Likewise. + (jump): Likewise. + (simple_return_internal): Likewise. + (simple_return_pop_internal): Likewise. + (*indirect_jump): Add MPX bnd prefix. + (*tablejump_1): Likewise. + (simple_return_internal_long): Likewise. + (simple_return_indirect_internal): Likewise. + (_mk): New. + (*_mk): New. + (mov): New. + (*mov_internal_mpx): New. + (_): New. + (*_): New. + (_ldx): New. + (*_ldx): New. + (_stx): New. + (*_stx): New. + * config/i386/predicates.md (lea_address_operand): Rename to... + (address_no_seg_operand): ... this. + (address_mpx_no_base_operand): New. + (address_mpx_no_index_operand): New. + (bnd_mem_operator): New. + * config/i386/i386.opt (mmpx): New. + * doc/invoke.texi: Add documentation for the flags -mmpx, -mno-mpx. + * doc/rtl.texi Add documentation for BND32mode and BND64mode. + +2013-10-24 Ilya Enkovich + * mode-classes.def (MODE_POINTER_BOUNDS): New. * tree.def (POINTER_BOUNDS_TYPE): New. * genmodes.c (complete_mode): Support MODE_POINTER_BOUNDS. diff --git a/gcc/config/i386/constraints.md b/gcc/config/i386/constraints.md index 92e0c053fac..ddfd402ba11 100644 --- a/gcc/config/i386/constraints.md +++ b/gcc/config/i386/constraints.md @@ -18,7 +18,7 @@ ;; . ;;; Unused letters: -;;; B H T +;;; H ;;; h j ;; Integer register constraints. @@ -91,6 +91,9 @@ (define_register_constraint "x" "TARGET_SSE ? SSE_REGS : NO_REGS" "Any SSE register.") +(define_register_constraint "B" "TARGET_MPX ? BND_REGS : NO_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 @@ -232,3 +235,15 @@ to fit that range (for immediate operands in zero-extending x86-64 instructions)." (match_operand 0 "x86_64_zext_immediate_operand")) + +;; T prefix is used for different address constraints +;; i - address with no index and no rip +;; b - address with no base and no rip + +(define_address_constraint "Ti" + "MPX address operand without index" + (match_operand 0 "address_mpx_no_index_operand")) + +(define_address_constraint "Tb" + "MPX address operand without base" + (match_operand 0 "address_mpx_no_base_operand")) diff --git a/gcc/config/i386/i386-c.c b/gcc/config/i386/i386-c.c index 8a41fb0ddf7..a6eaf8ad34a 100644 --- a/gcc/config/i386/i386-c.c +++ b/gcc/config/i386/i386-c.c @@ -358,6 +358,8 @@ ix86_target_macros_internal (HOST_WIDE_INT isa_flag, def_or_undef (parse_in, "__SSE_MATH__"); if ((fpmath & FPMATH_SSE) && (isa_flag & OPTION_MASK_ISA_SSE2)) def_or_undef (parse_in, "__SSE2_MATH__"); + if (isa_flag & OPTION_MASK_ISA_MPX) + def_or_undef (parse_in, "__MPX__"); } diff --git a/gcc/config/i386/i386-modes.def b/gcc/config/i386/i386-modes.def index e0b8fc826ab..a73730e08e2 100644 --- a/gcc/config/i386/i386-modes.def +++ b/gcc/config/i386/i386-modes.def @@ -87,6 +87,9 @@ VECTOR_MODE (INT, DI, 1); /* V1DI */ VECTOR_MODE (INT, SI, 1); /* V1SI */ VECTOR_MODE (INT, QI, 2); /* V2QI */ +POINTER_BOUNDS_MODE (BND32, 8); +POINTER_BOUNDS_MODE (BND64, 16); + INT_MODE (OI, 32); INT_MODE (XI, 64); diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h index df388765497..b1d014a1a27 100644 --- a/gcc/config/i386/i386-protos.h +++ b/gcc/config/i386/i386-protos.h @@ -241,6 +241,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 25c63c7749a..4a185bfe535 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -1943,6 +1943,8 @@ enum reg_class const regclass_map[FIRST_PSEUDO_REGISTER] = /* Mask registers. */ MASK_REGS, MASK_EVEX_REGS, MASK_EVEX_REGS, MASK_EVEX_REGS, MASK_EVEX_REGS, MASK_EVEX_REGS, MASK_EVEX_REGS, MASK_EVEX_REGS, + /* MPX bound registers */ + BND_REGS, BND_REGS, BND_REGS, BND_REGS, }; /* The "default" register map used in 32bit mode. */ @@ -1959,6 +1961,7 @@ int const dbx_register_map[FIRST_PSEUDO_REGISTER] = -1, -1, -1, -1, -1, -1, -1, -1, /* AVX-512 registers 16-23*/ -1, -1, -1, -1, -1, -1, -1, -1, /* AVX-512 registers 24-31*/ 93, 94, 95, 96, 97, 98, 99, 100, /* Mask registers */ + 101, 102, 103, 104, /* bound registers */ }; /* The "default" register map used in 64bit mode. */ @@ -1975,6 +1978,7 @@ int const dbx64_register_map[FIRST_PSEUDO_REGISTER] = 67, 68, 69, 70, 71, 72, 73, 74, /* AVX-512 registers 16-23 */ 75, 76, 77, 78, 79, 80, 81, 82, /* AVX-512 registers 24-31 */ 118, 119, 120, 121, 122, 123, 124, 125, /* Mask registers */ + 126, 127, 128, 129, /* bound registers */ }; /* Define the register numbers to be used in Dwarf debugging information. @@ -2043,6 +2047,7 @@ int const svr4_dbx_register_map[FIRST_PSEUDO_REGISTER] = -1, -1, -1, -1, -1, -1, -1, -1, /* AVX-512 registers 16-23*/ -1, -1, -1, -1, -1, -1, -1, -1, /* AVX-512 registers 24-31*/ 93, 94, 95, 96, 97, 98, 99, 100, /* Mask registers */ + -1, -1, -1, -1, /* bound registers */ }; /* Define parameter passing and return registers. */ @@ -2469,6 +2474,7 @@ ix86_target_string (HOST_WIDE_INT isa, int flags, const char *arch, { "-mrtm", OPTION_MASK_ISA_RTM }, { "-mxsave", OPTION_MASK_ISA_XSAVE }, { "-mxsaveopt", OPTION_MASK_ISA_XSAVEOPT }, + { "-mmpx", OPTION_MASK_ISA_MPX }, }; /* Flag options. */ @@ -2963,6 +2969,7 @@ ix86_option_override_internal (bool main_args_p, #define PTA_AVX512ER (HOST_WIDE_INT_1 << 41) #define PTA_AVX512PF (HOST_WIDE_INT_1 << 42) #define PTA_AVX512CD (HOST_WIDE_INT_1 << 43) +#define PTA_MPX (HOST_WIDE_INT_1 << 44) /* if this reaches 64, need to widen struct pta flags below */ @@ -4148,6 +4155,11 @@ ix86_conditional_register_usage (void) for (i = FIRST_MASK_REG; i <= LAST_MASK_REG; i++) fixed_regs[i] = call_used_regs[i] = 1, reg_names[i] = ""; } + + /* If MPX is disabled, squash the registers. */ + if (! TARGET_MPX) + for (i = FIRST_BND_REG; i <= LAST_BND_REG; i++) + fixed_regs[i] = call_used_regs[i] = 1, reg_names[i] = ""; } @@ -8870,7 +8882,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); @@ -8928,7 +8940,7 @@ output_set_got (rtx dest, rtx label) 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. @@ -14281,7 +14293,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: @@ -14404,6 +14416,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 @@ -14898,6 +14911,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); } @@ -15040,7 +15058,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. */ @@ -15070,6 +15088,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); @@ -24284,13 +24321,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 ""; @@ -24327,9 +24364,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); @@ -34320,6 +34357,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: @@ -34668,6 +34706,8 @@ ix86_hard_regno_mode_ok (int regno, enum machine_mode mode) return VALID_FP_MODE_P (mode); if (MASK_REGNO_P (regno)) return VALID_MASK_REG_MODE (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 @@ -35481,6 +35521,10 @@ x86_order_regs_for_local_alloc (void) for (i = FIRST_MASK_REG; i <= LAST_MASK_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++) @@ -41914,6 +41958,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 52670422606..92299a2f77f 100644 --- a/gcc/config/i386/i386.h +++ b/gcc/config/i386/i386.h @@ -945,7 +945,7 @@ enum target_cpu_default eliminated during reloading in favor of either the stack or frame pointer. */ -#define FIRST_PSEUDO_REGISTER 77 +#define FIRST_PSEUDO_REGISTER 81 /* Number of hardware registers that go into the DWARF-2 unwind info. If not defined, equals FIRST_PSEUDO_REGISTER. */ @@ -977,7 +977,9 @@ enum target_cpu_default /*xmm24,xmm25,xmm26,xmm27,xmm28,xmm29,xmm30,xmm31*/ \ 0, 0, 0, 0, 0, 0, 0, 0, \ /* k0, k1, k2, k3, k4, k5, k6, k7*/ \ - 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 @@ -1011,7 +1013,9 @@ enum target_cpu_default /*xmm24,xmm25,xmm26,xmm27,xmm28,xmm29,xmm30,xmm31*/ \ 6, 6, 6, 6, 6, 6, 6, 6, \ /* k0, k1, k2, k3, k4, k5, k6, k7*/ \ - 1, 1, 1, 1, 1, 1, 1, 1 } + 1, 1, 1, 1, 1, 1, 1, 1, \ +/* 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 +1031,8 @@ enum target_cpu_default 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, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, \ - 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76 } + 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, \ + 78, 79, 80 } /* 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) \ @@ -1098,6 +1104,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) @@ -1204,6 +1213,9 @@ enum target_cpu_default #define FIRST_MASK_REG (LAST_EXT_REX_SSE_REG + 1) /*69*/ #define LAST_MASK_REG (FIRST_MASK_REG + 7) /*76*/ +#define FIRST_BND_REG (LAST_MASK_REG + 1) /*77*/ +#define LAST_BND_REG (FIRST_BND_REG + 3) /*80*/ + /* Override this in other tm.h files to cope with various OS lossage requiring a frame pointer. */ #ifndef SUBTARGET_FRAME_POINTER_REQUIRED @@ -1284,6 +1296,7 @@ enum reg_class SSE_FIRST_REG, SSE_REGS, EVEX_SSE_REGS, + BND_REGS, ALL_SSE_REGS, MMX_REGS, FP_TOP_SSE_REGS, @@ -1341,6 +1354,7 @@ enum reg_class "SSE_FIRST_REG", \ "SSE_REGS", \ "EVEX_SSE_REGS", \ + "BND_REGS", \ "ALL_SSE_REGS", \ "MMX_REGS", \ "FP_TOP_SSE_REGS", \ @@ -1360,37 +1374,38 @@ enum reg_class TARGET_CONDITIONAL_REGISTER_USAGE. */ #define REG_CLASS_CONTENTS \ -{ { 0x00, 0x0, 0x0 }, \ - { 0x01, 0x0, 0x0 }, /* AREG */ \ - { 0x02, 0x0, 0x0 }, /* DREG */ \ - { 0x04, 0x0, 0x0 }, /* CREG */ \ - { 0x08, 0x0, 0x0 }, /* BREG */ \ - { 0x10, 0x0, 0x0 }, /* SIREG */ \ - { 0x20, 0x0, 0x0 }, /* DIREG */ \ - { 0x03, 0x0, 0x0 }, /* AD_REGS */ \ - { 0x0f, 0x0, 0x0 }, /* Q_REGS */ \ - { 0x1100f0, 0x1fe0, 0x0 }, /* NON_Q_REGS */ \ - { 0x7f, 0x1fe0, 0x0 }, /* INDEX_REGS */ \ - { 0x1100ff, 0x0, 0x0 }, /* LEGACY_REGS */ \ - { 0x07, 0x0, 0x0 }, /* CLOBBERED_REGS */ \ - { 0x1100ff, 0x1fe0, 0x0 }, /* GENERAL_REGS */ \ - { 0x100, 0x0, 0x0 }, /* FP_TOP_REG */ \ - { 0x0200, 0x0, 0x0 }, /* FP_SECOND_REG */ \ - { 0xff00, 0x0, 0x0 }, /* FLOAT_REGS */ \ - { 0x200000, 0x0, 0x0 }, /* SSE_FIRST_REG */ \ -{ 0x1fe00000, 0x1fe000, 0x0 }, /* SSE_REGS */ \ - { 0x0,0xffe00000, 0x1f }, /* EVEX_SSE_REGS */ \ -{ 0x1fe00000,0xffffe000, 0x1f }, /* ALL_SSE_REGS */ \ -{ 0xe0000000, 0x1f, 0x0 }, /* MMX_REGS */ \ -{ 0x1fe00100,0xffffe000, 0x1f }, /* FP_TOP_SSE_REG */ \ -{ 0x1fe00200,0xffffe000, 0x1f }, /* FP_SECOND_SSE_REG */ \ -{ 0x1fe0ff00,0xffffe000, 0x1f }, /* FLOAT_SSE_REGS */ \ -{ 0x11ffff, 0x1fe0, 0x0 }, /* FLOAT_INT_REGS */ \ -{ 0x1ff100ff,0xffffffe0, 0x1f }, /* INT_SSE_REGS */ \ -{ 0x1ff1ffff,0xffffffe0, 0x1f }, /* FLOAT_INT_SSE_REGS */ \ - { 0x0, 0x0,0x1fc0 }, /* MASK_EVEX_REGS */ \ - { 0x0, 0x0,0x1fe0 }, /* MASK_REGS */ \ -{ 0xffffffff,0xffffffff,0x1fff } \ +{ { 0x00, 0x0, 0x0 }, \ + { 0x01, 0x0, 0x0 }, /* AREG */ \ + { 0x02, 0x0, 0x0 }, /* DREG */ \ + { 0x04, 0x0, 0x0 }, /* CREG */ \ + { 0x08, 0x0, 0x0 }, /* BREG */ \ + { 0x10, 0x0, 0x0 }, /* SIREG */ \ + { 0x20, 0x0, 0x0 }, /* DIREG */ \ + { 0x03, 0x0, 0x0 }, /* AD_REGS */ \ + { 0x0f, 0x0, 0x0 }, /* Q_REGS */ \ + { 0x1100f0, 0x1fe0, 0x0 }, /* NON_Q_REGS */ \ + { 0x7f, 0x1fe0, 0x0 }, /* INDEX_REGS */ \ + { 0x1100ff, 0x0, 0x0 }, /* LEGACY_REGS */ \ + { 0x07, 0x0, 0x0 }, /* CLOBBERED_REGS */ \ + { 0x1100ff, 0x1fe0, 0x0 }, /* GENERAL_REGS */ \ + { 0x100, 0x0, 0x0 }, /* FP_TOP_REG */ \ + { 0x0200, 0x0, 0x0 }, /* FP_SECOND_REG */ \ + { 0xff00, 0x0, 0x0 }, /* FLOAT_REGS */ \ + { 0x200000, 0x0, 0x0 }, /* SSE_FIRST_REG */ \ +{ 0x1fe00000, 0x1fe000, 0x0 }, /* SSE_REGS */ \ + { 0x0,0xffe00000, 0x1f }, /* EVEX_SSE_REGS */ \ + { 0x0, 0x0,0x1e000 }, /* BND_REGS */ \ +{ 0x1fe00000,0xffffe000, 0x1f }, /* ALL_SSE_REGS */ \ +{ 0xe0000000, 0x1f, 0x0 }, /* MMX_REGS */ \ +{ 0x1fe00100,0xffffe000, 0x1f }, /* FP_TOP_SSE_REG */ \ +{ 0x1fe00200,0xffffe000, 0x1f }, /* FP_SECOND_SSE_REG */ \ +{ 0x1fe0ff00,0xffffe000, 0x1f }, /* FLOAT_SSE_REGS */ \ +{ 0x11ffff, 0x1fe0, 0x0 }, /* FLOAT_INT_REGS */ \ +{ 0x1ff100ff,0xffffffe0, 0x1f }, /* INT_SSE_REGS */ \ +{ 0x1ff1ffff,0xffffffe0, 0x1f }, /* FLOAT_INT_SSE_REGS */ \ + { 0x0, 0x0, 0x1fc0 }, /* MASK_EVEX_REGS */ \ + { 0x0, 0x0, 0x1fe0 }, /* MASK_REGS */ \ +{ 0xffffffff,0xffffffff, 0x1fff } \ } /* The same information, inverted: @@ -1466,6 +1481,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 @@ -1910,6 +1928,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 (ix86_pmode == PMODE_DI ? 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 @@ -2020,7 +2041,8 @@ do { \ "xmm20", "xmm21", "xmm22", "xmm23", \ "xmm24", "xmm25", "xmm26", "xmm27", \ "xmm28", "xmm29", "xmm30", "xmm31", \ - "k0", "k1", "k2", "k3", "k4", "k5", "k6", "k7" } + "k0", "k1", "k2", "k3", "k4", "k5", "k6", "k7", \ + "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 d06de40b927..bb2581bcfad 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" [ @@ -336,6 +347,8 @@ (MASK5_REG 74) (MASK6_REG 75) (MASK7_REG 76) + (BND0_REG 77) + (BND1_REG 78) ]) ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls @@ -369,7 +382,8 @@ ssecvt,ssecvt1,sseicvt,sseins, sseshuf,sseshuf1,ssemuladd,sse4arg, lwp,mskmov,msklog, - 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 @@ -398,7 +412,8 @@ ;; 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,msklog,mskmov") + bitmanip,imulx,msklog,mskmov,mpxmk,mpxmov,mpxchk, + mpxld,mpxst") (const_int 0) (eq_attr "unit" "i387,sse,mmx") (const_int 0) @@ -453,13 +468,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,msklog,mskmov") + (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip,msklog,mskmov, + mpxmk,mpxmov,mpxchk,mpxld,mpxst") (eq_attr "unit" "sse,mmx")) (const_int 1) (const_int 0))) @@ -562,12 +581,19 @@ ] (const_int 1))) +;; When this attribute is set, calculate total insn length from +;; length_nobnd attribute, prefixed with eventual bnd prefix byte +(define_attr "length_nobnd" "" (const_int 0)) + ;; The (bounding maximum) length of an instruction in bytes. ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences. ;; Later we may want to split them and compute proper length as for ;; other insns. (define_attr "length" "" - (cond [(eq_attr "type" "other,multi,fistp,frndint") + (cond [(eq_attr "length_nobnd" "!0") + (plus (symbol_ref ("ix86_bnd_prefixed_insn_p (insn)")) + (attr "length_nobnd")) + (eq_attr "type" "other,multi,fistp,frndint") (const_int 16) (eq_attr "type" "fcmp") (const_int 4) @@ -608,12 +634,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") @@ -659,7 +689,7 @@ fmov,fcmp,fsgn, sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt, sselog1,sseshuf1,sseadd1,sseiadd1,sseishft1, - mmx,mmxmov,mmxcmp,mmxcvt,mskmov,msklog") + mmx,mmxmov,mmxcmp,mmxcvt,mskmov,msklog,mpxmov") (match_operand 2 "memory_operand")) (const_string "load") (and (eq_attr "type" "icmov,ssemuladd,sse4arg") @@ -893,6 +923,21 @@ (define_mode_iterator DWIH [(SI "!TARGET_64BIT") (DI "TARGET_64BIT")]) +;; Bound modes. +(define_mode_iterator BND [(BND32 "!TARGET_LP64") + (BND64 "TARGET_LP64")]) + +;; 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")]) @@ -5347,7 +5392,7 @@ (define_insn_and_split "*lea" [(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)) @@ -10734,10 +10779,10 @@ (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") + (set (attr "length_nobnd") (if_then_else (and (ge (minus (match_dup 0) (pc)) (const_int -126)) (lt (minus (match_dup 0) (pc)) @@ -10752,10 +10797,10 @@ (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") + (set (attr "length_nobnd") (if_then_else (and (ge (minus (match_dup 0) (pc)) (const_int -126)) (lt (minus (match_dup 0) (pc)) @@ -11218,9 +11263,9 @@ [(set (pc) (label_ref (match_operand 0)))] "" - "jmp\t%l0" + "%!jmp\t%l0" [(set_attr "type" "ibr") - (set (attr "length") + (set (attr "length_nobnd") (if_then_else (and (ge (minus (match_dup 0) (pc)) (const_int -126)) (lt (minus (match_dup 0) (pc)) @@ -11240,7 +11285,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")]) @@ -11289,7 +11334,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")]) @@ -11676,8 +11721,8 @@ (define_insn "simple_return_internal" [(simple_return)] "reload_completed" - "ret" - [(set_attr "length" "1") + "%!ret" + [(set_attr "length_nobnd" "1") (set_attr "atom_unit" "jeu") (set_attr "length_immediate" "0") (set_attr "modrm" "0")]) @@ -11689,7 +11734,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") @@ -11700,8 +11750,8 @@ [(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_nobnd" "3") (set_attr "atom_unit" "jeu") (set_attr "length_immediate" "2") (set_attr "modrm" "0")]) @@ -11710,7 +11760,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")]) @@ -18173,6 +18223,131 @@ [(set_attr "type" "other") (set_attr "length" "3")]) +;; MPX instructions + +(define_expand "_mk" + [(set (match_operand:BND 0 "register_operand") + (unspec:BND + [(mem: + (match_par_dup 3 + [(match_operand: 1 "register_operand") + (match_operand: 2 "address_mpx_no_base_operand")]))] + UNSPEC_BNDMK))] + "TARGET_MPX" +{ + operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[1], + operands[2]), + UNSPEC_BNDMK_ADDR); +}) + +(define_insn "*_mk" + [(set (match_operand:BND 0 "register_operand" "=B") + (unspec:BND + [(match_operator: 3 "bnd_mem_operator" + [(unspec: + [(match_operand: 1 "register_operand" "r") + (match_operand: 2 "address_mpx_no_base_operand" "Tb")] + UNSPEC_BNDMK_ADDR)])] + UNSPEC_BNDMK))] + "TARGET_MPX" + "bndmk\t{%3, %0|%0, %3}" + [(set_attr "type" "mpxmk")]) + +(define_expand "mov" + [(set (match_operand:BND 0 "general_operand") + (match_operand:BND 1 "general_operand"))] + "TARGET_MPX" +{ + ix86_expand_move (mode, operands);DONE; +}) + +(define_insn "*mov_internal_mpx" + [(set (match_operand:BND 0 "nonimmediate_operand" "=B,m") + (match_operand:BND 1 "general_operand" "Bm,B"))] + "TARGET_MPX" + "bndmov\t{%1, %0|%0, %1}" + [(set_attr "type" "mpxmov")]) + +(define_expand "_" + [(parallel [(unspec [(match_operand:BND 0 "register_operand") + (match_operand: 1 "address_no_seg_operand")] BNDCHECK) + (set (match_dup 2) + (unspec:BLK [(match_dup 2)] UNSPEC_MPX_FENCE))])] + "TARGET_MPX" +{ + operands[2] = gen_rtx_MEM (BLKmode, operands[1]); + MEM_VOLATILE_P (operands[2]) = 1; +}) + +(define_insn "*_" + [(parallel [(unspec [(match_operand:BND 0 "register_operand" "B") + (match_operand: 1 "address_no_seg_operand" "p")] BNDCHECK) + (set (match_operand:BLK 2 "bnd_mem_operator") + (unspec:BLK [(match_dup 2)] UNSPEC_MPX_FENCE))])] + "TARGET_MPX" + "bnd\t{%a1, %0|%0, %a1}" + [(set_attr "type" "mpxchk")]) + +(define_expand "_ldx" + [(parallel [(set:BND (match_operand:BND 0 "register_operand") + (unspec:BND + [(mem: + (match_par_dup 3 + [(match_operand: 1 "address_mpx_no_index_operand") + (match_operand: 2 "register_operand")]))] + UNSPEC_BNDLDX)) + (use (mem:BLK (match_dup 1)))])] + "TARGET_MPX" +{ + operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[1], + operands[2]), + UNSPEC_BNDLDX_ADDR); +}) + +(define_insn "*_ldx" + [(parallel [(set:BND (match_operand:BND 0 "register_operand" "=B") + (unspec:BND + [(match_operator: 3 "bnd_mem_operator" + [(unspec: + [(match_operand: 1 "address_mpx_no_index_operand" "Ti") + (match_operand: 2 "register_operand" "l")] + UNSPEC_BNDLDX_ADDR)])] + UNSPEC_BNDLDX)) + (use (mem:BLK (match_dup 1)))])] + "TARGET_MPX" + "bndldx\t{%3, %0|%0, %3}" + [(set_attr "type" "mpxld")]) + +(define_expand "_stx" + [(parallel [(unspec [(mem: + (match_par_dup 3 + [(match_operand: 0 "address_mpx_no_index_operand") + (match_operand: 1 "register_operand")])) + (match_operand:BND 2 "register_operand")] UNSPEC_BNDSTX) + (set (match_dup 4) + (unspec:BLK [(match_dup 4)] UNSPEC_MPX_FENCE))])] + "TARGET_MPX" +{ + 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 "*_stx" + [(parallel [(unspec [(match_operator: 3 "bnd_mem_operator" + [(unspec: + [(match_operand: 0 "address_mpx_no_index_operand" "Ti") + (match_operand: 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))])] + "TARGET_MPX" + "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/i386.opt b/gcc/config/i386/i386.opt index 1e624ab0222..1a1b8abefdc 100644 --- a/gcc/config/i386/i386.opt +++ b/gcc/config/i386/i386.opt @@ -669,6 +669,10 @@ mrtm Target Report Mask(ISA_RTM) Var(ix86_isa_flags) Save Support RTM built-in functions and code generation +mmpx +Target Report Mask(ISA_MPX) Var(ix86_isa_flags) Save +Support MPX code generation + mstack-protector-guard= Target RejectNegative Joined Enum(stack_protector_guard) Var(ix86_stack_protector_guard) Init(SSP_TLS) Use given stack-protector guard diff --git a/gcc/config/i386/predicates.md b/gcc/config/i386/predicates.md index 06b291445a9..d1a4f6639d2 100644 --- a/gcc/config/i386/predicates.md +++ b/gcc/config/i386/predicates.md @@ -875,7 +875,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; @@ -932,9 +932,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/doc/invoke.texi b/gcc/doc/invoke.texi index e1303bf4f7d..9b5b0775c4c 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -668,7 +668,7 @@ Objective-C and Objective-C++ Dialects}. -mavx2 -mavx512f -mavx512pf -mavx512er -mavx512cd @gol -maes -mpclmul -mfsgsbase -mrdrnd -mf16c -mfma @gol -msse4a -m3dnow -mpopcnt -mabm -mbmi -mtbm -mfma4 -mxop -mlzcnt @gol --mbmi2 -mfxsr -mxsave -mxsaveopt -mrtm -mlwp -mthreads @gol +-mbmi2 -mfxsr -mxsave -mxsaveopt -mrtm -mlwp -mmpx -mthreads @gol -mno-align-stringops -minline-all-stringops @gol -minline-stringops-dynamically -mstringop-strategy=@var{alg} @gol -mmemcpy-strategy=@var{strategy} -mmemset-strategy=@var{strategy} @@ -14992,6 +14992,8 @@ preferred alignment to @option{-mpreferred-stack-boundary=2}. @itemx -mrtm @itemx -mtbm @itemx -mno-tbm +@itemx -mmpx +@itemx -mno-mpx @opindex mmmx @opindex mno-mmx @opindex msse @@ -15001,7 +15003,7 @@ preferred alignment to @option{-mpreferred-stack-boundary=2}. These switches enable or disable the use of instructions in the MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, AVX, AVX2, AVX512F, AVX512PF, AVX512ER, AVX512CD, AES, PCLMUL, FSGSBASE, RDRND, F16C, FMA, SSE4A, FMA4, XOP, LWP, ABM, BMI, BMI2, -FXSR, XSAVE, XSAVEOPT, LZCNT, RTM or 3DNow!@: +FXSR, XSAVE, XSAVEOPT, LZCNT, RTM, MPX or 3DNow!@: extended instruction sets. These extensions are also available as built-in functions: see @ref{X86 Built-in Functions}, for details of the functions enabled and diff --git a/gcc/doc/rtl.texi b/gcc/doc/rtl.texi index 77a9c703216..df2bb6806dc 100644 --- a/gcc/doc/rtl.texi +++ b/gcc/doc/rtl.texi @@ -1295,6 +1295,12 @@ These modes stand for a complex number represented as a pair of integer values. The integer values are in @code{QImode}, @code{HImode}, @code{SImode}, @code{DImode}, @code{TImode}, and @code{OImode}, respectively. + +@findex BND32mode +@findex BND64mode +@item BND32mode BND64mode +These modes stand for bounds for pointer of 32 and 64 bit size respectively. +Mode size is double pointer mode size. @end table The machine description defines @code{Pmode} as a C macro which expands -- 2.11.4.GIT