aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/i386/i386.c
diff options
context:
space:
mode:
authorMichael Zolotukhin <michael.v.zolotukhin@intel.com>2012-08-08 13:25:58 +0000
committerKirill Yukhin <kyukhin@gcc.gnu.org>2012-08-08 13:25:58 +0000
commitd05e383bc7a06abdc444ff6f42a91fdce0ff3551 (patch)
tree08fa7a69df52351b77d733e3e1b596f2a978f98f /gcc/config/i386/i386.c
parent916f8bbf52a678ae51404a571cdcaad19117aff3 (diff)
downloadgcc-d05e383bc7a06abdc444ff6f42a91fdce0ff3551.zip
gcc-d05e383bc7a06abdc444ff6f42a91fdce0ff3551.tar.gz
gcc-d05e383bc7a06abdc444ff6f42a91fdce0ff3551.tar.bz2
i386-common.c (OPTION_MASK_ISA_ADX_SET): New.
ChangeLog: 2012-08-08 Michael Zolotukhin <michael.v.zolotukhin@intel.com> * common/config/i386/i386-common.c (OPTION_MASK_ISA_ADX_SET): New. (OPTION_MASK_ISA_ADX_UNSET): Likewise. (ix86_handle_option): Handle madx option. * config.gcc (i[34567]86-*-*): Add adxintrin.h. (x86_64-*-*): Likewise. * config/i386/adxintrin.h: New header. * config/i386/driver-i386.c (host_detect_local_cpu): Detect ADCX/ADOX support. * config/i386/i386-builtin-types.def (UCHAR_FTYPE_UCHAR_UINT_UINT_PUNSIGNED): New function type. (UCHAR_FTYPE_UCHAR_ULONGLONG_ULONGLONG_PULONGLONG): Likewise. * config/i386/i386-c.c: Define __ADX__ if needed. * config/i386/i386.c (ix86_target_string): Define -madx option. (PTA_ADX): New. (ix86_option_override_internal): Handle new option. (ix86_valid_target_attribute_inner_p): Add OPT_madx. (ix86_builtins): Add IX86_BUILTIN_ADDCARRYX32, IX86_BUILTIN_ADDCARRYX64. (ix86_init_mmx_sse_builtins): Define corresponding built-ins. (ix86_expand_builtin): Handle these built-ins. (ix86_expand_args_builtin): Handle new function types. * config/i386/i386.h (TARGET_ADX): New. * config/i386/i386.md (adcx<mode>3): New define_insn. * config/i386/i386.opt (madx): New. * config/i386/x86intrin.h: Include adxintrin.h. testsuite/ChangeLog: * gcc.target/i386/adx-addcarryx32-1.c: New. * gcc.target/i386/adx-addcarryx32-2.c: New. * gcc.target/i386/adx-addcarryx64-1.c: New. * gcc.target/i386/adx-addcarryx64-2.c: New. * gcc.target/i386/adx-check.h: New. * gcc.target/i386/i386.exp (check_effective_target_adx): New. * gcc.target/i386/sse-12.c: Add -madx. * gcc.target/i386/sse-13.c: Ditto. * gcc.target/i386/sse-14.c: Ditto. * gcc.target/i386/sse-22.c: Ditto. * gcc.target/i386/sse-23.c: Ditto. * g++.dg/other/i386-2.C: Ditto. * g++.dg/other/i386-3.C: Ditto. From-SVN: r190227
Diffstat (limited to 'gcc/config/i386/i386.c')
-rw-r--r--gcc/config/i386/i386.c77
1 files changed, 77 insertions, 0 deletions
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 1146d05..17d4446 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -2769,6 +2769,7 @@ ix86_target_string (HOST_WIDE_INT isa, int flags, const char *arch,
{ "-mhle", OPTION_MASK_ISA_HLE },
{ "-mrdseed", OPTION_MASK_ISA_RDSEED },
{ "-mprfchw", OPTION_MASK_ISA_PRFCHW },
+ { "-madx", OPTION_MASK_ISA_ADX },
{ "-mtbm", OPTION_MASK_ISA_TBM },
{ "-mpopcnt", OPTION_MASK_ISA_POPCNT },
{ "-mmovbe", OPTION_MASK_ISA_MOVBE },
@@ -3047,6 +3048,7 @@ ix86_option_override_internal (bool main_args_p)
#define PTA_HLE (HOST_WIDE_INT_1 << 33)
#define PTA_PRFCHW (HOST_WIDE_INT_1 << 34)
#define PTA_RDSEED (HOST_WIDE_INT_1 << 35)
+#define PTA_ADX (HOST_WIDE_INT_1 << 36)
/* if this reaches 64, need to widen struct pta flags below */
static struct pta
@@ -3538,6 +3540,9 @@ ix86_option_override_internal (bool main_args_p)
if (processor_alias_table[i].flags & PTA_RDSEED
&& !(ix86_isa_flags_explicit & OPTION_MASK_ISA_RDSEED))
ix86_isa_flags |= OPTION_MASK_ISA_RDSEED;
+ if (processor_alias_table[i].flags & PTA_ADX
+ && !(ix86_isa_flags_explicit & OPTION_MASK_ISA_ADX))
+ ix86_isa_flags |= OPTION_MASK_ISA_ADX;
if (processor_alias_table[i].flags & (PTA_PREFETCH_SSE | PTA_SSE))
x86_prefetch_sse = true;
@@ -4361,6 +4366,7 @@ ix86_valid_target_attribute_inner_p (tree args, char *p_strings[],
IX86_ATTR_ISA ("hle", OPT_mhle),
IX86_ATTR_ISA ("prfchw", OPT_mprfchw),
IX86_ATTR_ISA ("rdseed", OPT_mrdseed),
+ IX86_ATTR_ISA ("adx", OPT_madx),
/* enum options */
IX86_ATTR_ENUM ("fpmath=", OPT_mfpmath_),
@@ -26107,6 +26113,10 @@ enum ix86_builtins
IX86_BUILTIN_PEXT32,
IX86_BUILTIN_PEXT64,
+ /* ADX instructions. */
+ IX86_BUILTIN_ADDCARRYX32,
+ IX86_BUILTIN_ADDCARRYX64,
+
/* FSGSBASE instructions. */
IX86_BUILTIN_RDFSBASE32,
IX86_BUILTIN_RDFSBASE64,
@@ -27957,6 +27967,14 @@ ix86_init_mmx_sse_builtins (void)
"__builtin_ia32_rdseed_di_step",
INT_FTYPE_PULONGLONG, IX86_BUILTIN_RDSEED64_STEP);
+ /* ADCX */
+ def_builtin (OPTION_MASK_ISA_ADX, "__builtin_ia32_addcarryx_u32",
+ UCHAR_FTYPE_UCHAR_UINT_UINT_PUNSIGNED, IX86_BUILTIN_ADDCARRYX32);
+ def_builtin (OPTION_MASK_ISA_ADX && OPTION_MASK_ISA_64BIT,
+ "__builtin_ia32_addcarryx_u64",
+ UCHAR_FTYPE_UCHAR_ULONGLONG_ULONGLONG_PULONGLONG,
+ IX86_BUILTIN_ADDCARRYX64);
+
/* Add FMA4 multi-arg argument instructions */
for (i = 0, d = bdesc_multi_arg; i < ARRAY_SIZE (bdesc_multi_arg); i++, d++)
{
@@ -29472,6 +29490,10 @@ ix86_expand_args_builtin (const struct builtin_description *d,
nargs = 4;
nargs_constant = 2;
break;
+ case UCHAR_FTYPE_UCHAR_UINT_UINT_PUNSIGNED:
+ case UCHAR_FTYPE_UCHAR_ULONGLONG_ULONGLONG_PULONGLONG:
+ nargs = 4;
+ break;
default:
gcc_unreachable ();
}
@@ -30318,7 +30340,62 @@ rdseed_step:
target = gen_reg_rtx (SImode);
emit_insn (gen_zero_extendqisi2 (target, op2));
+ return target;
+
+ case IX86_BUILTIN_ADDCARRYX32:
+ icode = CODE_FOR_adcxsi3;
+ mode0 = SImode;
+ goto addcarryx;
+
+ case IX86_BUILTIN_ADDCARRYX64:
+ icode = CODE_FOR_adcxdi3;
+ mode0 = DImode;
+
+addcarryx:
+ arg0 = CALL_EXPR_ARG (exp, 0); /* unsigned char c_in. */
+ arg1 = CALL_EXPR_ARG (exp, 1); /* unsigned int src1. */
+ arg2 = CALL_EXPR_ARG (exp, 2); /* unsigned int src2. */
+ arg3 = CALL_EXPR_ARG (exp, 3); /* unsigned int *sum_out. */
+
+ op0 = gen_reg_rtx (QImode);
+
+ /* Generate CF from input operand. */
+ op1 = expand_normal (arg0);
+ if (GET_MODE (op1) != QImode)
+ op1 = convert_to_mode (QImode, op1, 1);
+ op1 = copy_to_mode_reg (QImode, op1);
+ emit_insn (gen_addqi3_cc (op0, op1, constm1_rtx));
+
+ /* Gen ADCX instruction to compute X+Y+CF. */
+ op2 = expand_normal (arg1);
+ op3 = expand_normal (arg2);
+
+ if (!REG_P (op2))
+ op2 = copy_to_mode_reg (mode0, op2);
+ if (!REG_P (op3))
+ op3 = copy_to_mode_reg (mode0, op3);
+
+ op0 = gen_reg_rtx (mode0);
+
+ op4 = gen_rtx_REG (CCCmode, FLAGS_REG);
+ pat = gen_rtx_LTU (VOIDmode, op4, const0_rtx);
+ emit_insn (GEN_FCN (icode) (op0, op2, op3, op4, pat));
+
+ /* Store the result. */
+ op4 = expand_normal (arg3);
+ if (!address_operand (op4, VOIDmode))
+ {
+ op4 = convert_memory_address (Pmode, op4);
+ op4 = copy_addr_to_reg (op4);
+ }
+ emit_move_insn (gen_rtx_MEM (mode0, op4), op0);
+
+ /* Return current CF value. */
+ if (target == 0)
+ target = gen_reg_rtx (QImode);
+ PUT_MODE (pat, QImode);
+ emit_insn (gen_rtx_SET (VOIDmode, target, pat));
return target;
case IX86_BUILTIN_GATHERSIV2DF: