constraints.md (B): New.
* 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. (<mode>_mk): New. (*<mode>_mk): New. (mov<mode>): New. (*mov<mode>_internal_mpx): New. (<mode>_<bndcheck>): New. (*<mode>_<bndcheck>): New. (<mode>_ldx): New. (*<mode>_ldx): New. (<mode>_stx): New. (*<mode>_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. From-SVN: r204046
This commit is contained in:
parent
65f55baca4
commit
66d6cbaa56
@ -1,3 +1,98 @@
|
||||
2013-10-24 Ilya Enkovich <ilya.enkovich@intel.com>
|
||||
|
||||
* 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.
|
||||
(<mode>_mk): New.
|
||||
(*<mode>_mk): New.
|
||||
(mov<mode>): New.
|
||||
(*mov<mode>_internal_mpx): New.
|
||||
(<mode>_<bndcheck>): New.
|
||||
(*<mode>_<bndcheck>): New.
|
||||
(<mode>_ldx): New.
|
||||
(*<mode>_ldx): New.
|
||||
(<mode>_stx): New.
|
||||
(*<mode>_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 <ilya.enkovich@intel.com>
|
||||
|
||||
* mode-classes.def (MODE_POINTER_BOUNDS): New.
|
||||
|
@ -18,7 +18,7 @@
|
||||
;; <http://www.gnu.org/licenses/>.
|
||||
|
||||
;;; 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"))
|
||||
|
@ -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__");
|
||||
}
|
||||
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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. */
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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<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))
|
||||
@ -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 "<mode>_mk"
|
||||
[(set (match_operand:BND 0 "register_operand")
|
||||
(unspec:BND
|
||||
[(mem:<bnd_ptr>
|
||||
(match_par_dup 3
|
||||
[(match_operand:<bnd_ptr> 1 "register_operand")
|
||||
(match_operand:<bnd_ptr> 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 "*<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" "Tb")]
|
||||
UNSPEC_BNDMK_ADDR)])]
|
||||
UNSPEC_BNDMK))]
|
||||
"TARGET_MPX"
|
||||
"bndmk\t{%3, %0|%0, %3}"
|
||||
[(set_attr "type" "mpxmk")])
|
||||
|
||||
(define_expand "mov<mode>"
|
||||
[(set (match_operand:BND 0 "general_operand")
|
||||
(match_operand:BND 1 "general_operand"))]
|
||||
"TARGET_MPX"
|
||||
{
|
||||
ix86_expand_move (<MODE>mode, operands);DONE;
|
||||
})
|
||||
|
||||
(define_insn "*mov<mode>_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 "<mode>_<bndcheck>"
|
||||
[(parallel [(unspec [(match_operand:BND 0 "register_operand")
|
||||
(match_operand:<bnd_ptr> 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 "*<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))])]
|
||||
"TARGET_MPX"
|
||||
"bnd<bndcheck>\t{%a1, %0|%0, %a1}"
|
||||
[(set_attr "type" "mpxchk")])
|
||||
|
||||
(define_expand "<mode>_ldx"
|
||||
[(parallel [(set:BND (match_operand:BND 0 "register_operand")
|
||||
(unspec:BND
|
||||
[(mem:<bnd_ptr>
|
||||
(match_par_dup 3
|
||||
[(match_operand:<bnd_ptr> 1 "address_mpx_no_index_operand")
|
||||
(match_operand:<bnd_ptr> 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 "*<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" "Ti")
|
||||
(match_operand:<bnd_ptr> 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 "<mode>_stx"
|
||||
[(parallel [(unspec [(mem:<bnd_ptr>
|
||||
(match_par_dup 3
|
||||
[(match_operand:<bnd_ptr> 0 "address_mpx_no_index_operand")
|
||||
(match_operand:<bnd_ptr> 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 "*<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" "Ti")
|
||||
(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))])]
|
||||
"TARGET_MPX"
|
||||
"bndstx\t{%2, %3|%3, %2}"
|
||||
[(set_attr "type" "mpxst")])
|
||||
|
||||
(include "mmx.md")
|
||||
(include "sse.md")
|
||||
(include "sync.md")
|
||||
|
@ -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
|
||||
|
@ -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")
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user