From 94d13ad18df325e53e10c4ed44dde8b60c4f6708 Mon Sep 17 00:00:00 2001 From: Quentin Neill Date: Wed, 10 Nov 2010 22:02:34 +0000 Subject: [PATCH] Add support for TBM. 2010-11-10 Quentin Neill gcc/ * config.gcc (i[34567]86-*-*): Include tbmintrin.h. (x86_64-*-*): Likewise. * config/i386/cpuid.h: Define TBM bit. * config/i386/driver-i386.c (host_detect_local_cpu): Define and set has_tbm. * config/i386/i386-c.c (ix86_target_macros_internal): Check isa_flag for TBM. * config/i386/i386.c (OPTION_MASK_ISA_TBM_SET): New. (OPTION_MASK_ISA_TBM_UNSET): New. (ix86_handle_option): Handle -mtbm. (isa_opts): Add -mtbm. (enum pta_flags): Add PTA_TBM. (ix86_option_override_internal): Add TBM support. (ix86_valid_target_attribute_inner_p): Handle -mtbm. (IX86_BUILTIN_BEXTRI32): New for TBM intrinsic. (IX86_BUILTIN_BEXTRI64): Likewise. (bdesc_args): Add TBM intrinsics. (ix86_expand_builtin): Add TBM specific case. * config/i386/i386.h (TARGET_TBM): New for TBM. * config/i386/i386.md (UNSPEC_BEXTRI): New for TBM. (tbm_bextri_): Likewise. (*tbm_blcfill_): Likewise. (*tbm_blci_): Likewise. (*tbm_blcic_): Likewise. (*tbm_blcmsk_): Likewise. (*tbm_blcs_): Likewise. (*tbm_blsfill_): Likewise. (*tbm_blsic_): Likewise. (*tbm_t1mskc_): Likewise. (*tbm_tzmsk_): Likewise. * config/i386/i386.opt: Add -mtbm. * config/i386/tbmintrin.h (__bextri_u32): New. (__blcfill_u32): Likewise. (__blci_u32): Likewise. (__blcic_u32): Likewise. (__blcmsk_u32): Likewise. (__blcs_u32): Likewise. (__blsfill_u32): Likewise. (__blsic_u32): Likewise. (__t1mskc_u32): Likewise. (__tzmsk_u32): Likewise. (__bextri_u64): Likewise. (__blcfill_u64): Likewise. (__blci_u64): Likewise. (__blcic_u64): Likewise. (__blcmsk_u64): Likewise. (__blcs_u64): Likewise. (__blsfill_u64): Likewise. (__blsic_u64): Likewise. (__t1mskc_u64): Likewise. (__tzmsk_u64): Likewise. * config/i386/x86intrin.h: Add TBM check and tbmintrin.h. * doc/invoke.texi: Document -mtbm. * doc/extend.texi: Document TBM built-in functions. gcc/testsuite/ * g++.dg/other/i386-2.C: Add -mtbm. * g++.dg/other/i386-3.C: Likewise. * gcc.target/i386/funcspec-5.c: Add tbm and no-tbm targets. * gcc.target/i386/funcspec-6.c: Likewise. * gcc.target/i386/sse-12.c: Add -mtbm. * gcc.target/i386/sse-13.c: Add -mtbm and test immediate operand intrinsics. * gcc.target/i386/sse-14.c: Likewise. * gcc.target/i386/sse-22.c: Likewise. * gcc.target/i386/sse-23.c: Likewise. * gcc.target/i386/tbm-1.c: New file. * gcc.target/i386/tbm-2.c: Likewise. From-SVN: r166562 --- gcc/ChangeLog | 57 ++++++ gcc/config.gcc | 4 +- gcc/config/i386/cpuid.h | 1 + gcc/config/i386/driver-i386.c | 5 +- gcc/config/i386/i386-c.c | 2 + gcc/config/i386/i386.c | 59 ++++++- gcc/config/i386/i386.h | 1 + gcc/config/i386/i386.md | 138 +++++++++++++++ gcc/config/i386/i386.opt | 4 + gcc/config/i386/tbmintrin.h | 191 +++++++++++++++++++++ gcc/config/i386/x86intrin.h | 4 + gcc/doc/extend.texi | 8 + gcc/doc/invoke.texi | 4 +- gcc/testsuite/ChangeLog | 15 ++ gcc/testsuite/g++.dg/other/i386-2.C | 6 +- gcc/testsuite/g++.dg/other/i386-3.C | 6 +- gcc/testsuite/gcc.target/i386/bmi-5.c | 2 +- gcc/testsuite/gcc.target/i386/bmi-6.c | 2 +- gcc/testsuite/gcc.target/i386/funcspec-5.c | 2 + gcc/testsuite/gcc.target/i386/funcspec-6.c | 2 + gcc/testsuite/gcc.target/i386/sse-12.c | 4 +- gcc/testsuite/gcc.target/i386/sse-13.c | 11 +- gcc/testsuite/gcc.target/i386/sse-14.c | 8 +- gcc/testsuite/gcc.target/i386/sse-22.c | 20 ++- gcc/testsuite/gcc.target/i386/sse-23.c | 12 +- gcc/testsuite/gcc.target/i386/tbm-1.c | 74 ++++++++ gcc/testsuite/gcc.target/i386/tbm-2.c | 75 ++++++++ 27 files changed, 688 insertions(+), 29 deletions(-) create mode 100644 gcc/config/i386/tbmintrin.h create mode 100644 gcc/testsuite/gcc.target/i386/tbm-1.c create mode 100644 gcc/testsuite/gcc.target/i386/tbm-2.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index bbd9c9d95be..16920f3715d 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,60 @@ +2010-11-10 Quentin Neill + + * config.gcc (i[34567]86-*-*): Include tbmintrin.h. + (x86_64-*-*): Likewise. + * config/i386/cpuid.h: Define TBM bit. + * config/i386/driver-i386.c (host_detect_local_cpu): Define + and set has_tbm. + * config/i386/i386-c.c (ix86_target_macros_internal): Check + isa_flag for TBM. + * config/i386/i386.c (OPTION_MASK_ISA_TBM_SET): New. + (OPTION_MASK_ISA_TBM_UNSET): New. + (ix86_handle_option): Handle -mtbm. + (isa_opts): Add -mtbm. + (enum pta_flags): Add PTA_TBM. + (ix86_option_override_internal): Add TBM support. + (ix86_valid_target_attribute_inner_p): Handle -mtbm. + (IX86_BUILTIN_BEXTRI32): New for TBM intrinsic. + (IX86_BUILTIN_BEXTRI64): Likewise. + (bdesc_args): Add TBM intrinsics. + (ix86_expand_builtin): Add TBM specific case. + * config/i386/i386.h (TARGET_TBM): New for TBM. + * config/i386/i386.md (UNSPEC_BEXTRI): New for TBM. + (tbm_bextri_): Likewise. + (*tbm_blcfill_): Likewise. + (*tbm_blci_): Likewise. + (*tbm_blcic_): Likewise. + (*tbm_blcmsk_): Likewise. + (*tbm_blcs_): Likewise. + (*tbm_blsfill_): Likewise. + (*tbm_blsic_): Likewise. + (*tbm_t1mskc_): Likewise. + (*tbm_tzmsk_): Likewise. + * config/i386/i386.opt: Add -mtbm. + * config/i386/tbmintrin.h (__bextri_u32): New. + (__blcfill_u32): Likewise. + (__blci_u32): Likewise. + (__blcic_u32): Likewise. + (__blcmsk_u32): Likewise. + (__blcs_u32): Likewise. + (__blsfill_u32): Likewise. + (__blsic_u32): Likewise. + (__t1mskc_u32): Likewise. + (__tzmsk_u32): Likewise. + (__bextri_u64): Likewise. + (__blcfill_u64): Likewise. + (__blci_u64): Likewise. + (__blcic_u64): Likewise. + (__blcmsk_u64): Likewise. + (__blcs_u64): Likewise. + (__blsfill_u64): Likewise. + (__blsic_u64): Likewise. + (__t1mskc_u64): Likewise. + (__tzmsk_u64): Likewise. + * config/i386/x86intrin.h: Add TBM check and tbmintrin.h. + * doc/invoke.texi: Document -mtbm. + * doc/extend.texi: Document TBM built-in functions. + 2010-11-10 Quentin Neill * config.gcc (i[34567]86-*-*): Include bmiintrin.h. diff --git a/gcc/config.gcc b/gcc/config.gcc index 73016ce6ffb..67877db3999 100644 --- a/gcc/config.gcc +++ b/gcc/config.gcc @@ -316,7 +316,7 @@ i[34567]86-*-*) nmmintrin.h bmmintrin.h fma4intrin.h wmmintrin.h immintrin.h x86intrin.h avxintrin.h xopintrin.h ia32intrin.h cross-stdarg.h lwpintrin.h popcntintrin.h - abmintrin.h bmiintrin.h" + abmintrin.h bmiintrin.h tbmintrin.h" ;; x86_64-*-*) cpu_type=i386 @@ -327,7 +327,7 @@ x86_64-*-*) nmmintrin.h bmmintrin.h fma4intrin.h wmmintrin.h immintrin.h x86intrin.h avxintrin.h xopintrin.h ia32intrin.h cross-stdarg.h lwpintrin.h popcntintrin.h - abmintrin.h bmiintrin.h" + abmintrin.h bmiintrin.h tbmintrin.h" need_64bit_hwint=yes ;; ia64-*-*) diff --git a/gcc/config/i386/cpuid.h b/gcc/config/i386/cpuid.h index 0f1af7f8d0d..e9d0fab6f39 100644 --- a/gcc/config/i386/cpuid.h +++ b/gcc/config/i386/cpuid.h @@ -54,6 +54,7 @@ #define bit_XOP (1 << 11) #define bit_LWP (1 << 15) #define bit_FMA4 (1 << 16) +#define bit_TBM (1 << 21) /* %edx */ #define bit_LM (1 << 29) diff --git a/gcc/config/i386/driver-i386.c b/gcc/config/i386/driver-i386.c index 6319a14b78a..288d5072662 100644 --- a/gcc/config/i386/driver-i386.c +++ b/gcc/config/i386/driver-i386.c @@ -397,7 +397,7 @@ const char *host_detect_local_cpu (int argc, const char **argv) unsigned int has_popcnt = 0, has_aes = 0, has_avx = 0; unsigned int has_pclmul = 0, has_abm = 0, has_lwp = 0; unsigned int has_fma4 = 0, has_xop = 0; - unsigned int has_bmi = 0; + unsigned int has_bmi = 0, has_tbm = 0; bool arch; @@ -464,6 +464,7 @@ const char *host_detect_local_cpu (int argc, const char **argv) has_lwp = ecx & bit_LWP; has_fma4 = ecx & bit_FMA4; has_xop = ecx & bit_XOP; + has_tbm = ecx & bit_TBM; has_longmode = edx & bit_LM; has_3dnowp = edx & bit_3DNOWP; @@ -693,6 +694,8 @@ const char *host_detect_local_cpu (int argc, const char **argv) options = concat (options, " -mxop", NULL); if (has_bmi) options = concat (options, " -mbmi", NULL); + if (has_tbm) + options = concat (options, " -mtbm", NULL); if (has_avx) options = concat (options, " -mavx", NULL); diff --git a/gcc/config/i386/i386-c.c b/gcc/config/i386/i386-c.c index 51c0c135ad2..ca3517726cd 100644 --- a/gcc/config/i386/i386-c.c +++ b/gcc/config/i386/i386-c.c @@ -255,6 +255,8 @@ ix86_target_macros_internal (int isa_flag, def_or_undef (parse_in, "__ABM__"); if (isa_flag & OPTION_MASK_ISA_BMI) def_or_undef (parse_in, "__BMI__"); + if (isa_flag & OPTION_MASK_ISA_TBM) + def_or_undef (parse_in, "__TBM__"); if (isa_flag & OPTION_MASK_ISA_POPCNT) def_or_undef (parse_in, "__POPCNT__"); if (isa_flag & OPTION_MASK_ISA_FSGSBASE) diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 3c7dc8c827e..d52a0a45de7 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -2326,7 +2326,7 @@ static int ix86_isa_flags_explicit; (OPTION_MASK_ISA_ABM | OPTION_MASK_ISA_POPCNT) #define OPTION_MASK_ISA_BMI_SET OPTION_MASK_ISA_BMI - +#define OPTION_MASK_ISA_TBM_SET OPTION_MASK_ISA_TBM #define OPTION_MASK_ISA_POPCNT_SET OPTION_MASK_ISA_POPCNT #define OPTION_MASK_ISA_CX16_SET OPTION_MASK_ISA_CX16 #define OPTION_MASK_ISA_SAHF_SET OPTION_MASK_ISA_SAHF @@ -2382,6 +2382,7 @@ static int ix86_isa_flags_explicit; #define OPTION_MASK_ISA_PCLMUL_UNSET OPTION_MASK_ISA_PCLMUL #define OPTION_MASK_ISA_ABM_UNSET OPTION_MASK_ISA_ABM #define OPTION_MASK_ISA_BMI_UNSET OPTION_MASK_ISA_BMI +#define OPTION_MASK_ISA_TBM_UNSET OPTION_MASK_ISA_TBM #define OPTION_MASK_ISA_POPCNT_UNSET OPTION_MASK_ISA_POPCNT #define OPTION_MASK_ISA_CX16_UNSET OPTION_MASK_ISA_CX16 #define OPTION_MASK_ISA_SAHF_UNSET OPTION_MASK_ISA_SAHF @@ -2697,6 +2698,19 @@ ix86_handle_option (size_t code, const char *arg ATTRIBUTE_UNUSED, int value) } return true; + case OPT_mtbm: + if (value) + { + ix86_isa_flags |= OPTION_MASK_ISA_TBM_SET; + ix86_isa_flags_explicit |= OPTION_MASK_ISA_TBM_SET; + } + else + { + ix86_isa_flags &= ~OPTION_MASK_ISA_TBM_UNSET; + ix86_isa_flags_explicit |= OPTION_MASK_ISA_TBM_UNSET; + } + return true; + case OPT_mpopcnt: if (value) { @@ -2866,6 +2880,7 @@ ix86_target_string (int isa, int flags, const char *arch, const char *tune, { "-mmmx", OPTION_MASK_ISA_MMX }, { "-mabm", OPTION_MASK_ISA_ABM }, { "-mbmi", OPTION_MASK_ISA_BMI }, + { "-mtbm", OPTION_MASK_ISA_TBM }, { "-mpopcnt", OPTION_MASK_ISA_POPCNT }, { "-mmovbe", OPTION_MASK_ISA_MOVBE }, { "-mcrc32", OPTION_MASK_ISA_CRC32 }, @@ -3122,7 +3137,8 @@ ix86_option_override_internal (bool main_args_p) PTA_FSGSBASE = 1 << 24, PTA_RDRND = 1 << 25, PTA_F16C = 1 << 26, - PTA_BMI = 1 << 27 + PTA_BMI = 1 << 27, + PTA_TBM = 1 << 28 /* if this reaches 32, need to widen struct pta flags below */ }; @@ -3461,6 +3477,9 @@ ix86_option_override_internal (bool main_args_p) if (processor_alias_table[i].flags & PTA_BMI && !(ix86_isa_flags_explicit & OPTION_MASK_ISA_BMI)) ix86_isa_flags |= OPTION_MASK_ISA_BMI; + if (processor_alias_table[i].flags & PTA_TBM + && !(ix86_isa_flags_explicit & OPTION_MASK_ISA_TBM)) + ix86_isa_flags |= OPTION_MASK_ISA_TBM; if (processor_alias_table[i].flags & PTA_CX16 && !(ix86_isa_flags_explicit & OPTION_MASK_ISA_CX16)) ix86_isa_flags |= OPTION_MASK_ISA_CX16; @@ -4299,6 +4318,7 @@ ix86_valid_target_attribute_inner_p (tree args, char *p_strings[]) IX86_ATTR_ISA ("3dnow", OPT_m3dnow), IX86_ATTR_ISA ("abm", OPT_mabm), IX86_ATTR_ISA ("bmi", OPT_mbmi), + IX86_ATTR_ISA ("tbm", OPT_mtbm), IX86_ATTR_ISA ("aes", OPT_maes), IX86_ATTR_ISA ("avx", OPT_mavx), IX86_ATTR_ISA ("mmx", OPT_mmmx), @@ -24044,6 +24064,11 @@ enum ix86_builtins IX86_BUILTIN_BEXTR64, IX86_BUILTIN_CTZS, + /* TBM instructions. */ + IX86_BUILTIN_BEXTRI32, + IX86_BUILTIN_BEXTRI64, + + /* FSGSBASE instructions. */ IX86_BUILTIN_RDFSBASE32, IX86_BUILTIN_RDFSBASE64, @@ -24988,6 +25013,10 @@ static const struct builtin_description bdesc_args[] = { OPTION_MASK_ISA_BMI, CODE_FOR_bmi_bextr_di, "__builtin_ia32_bextr_u64", IX86_BUILTIN_BEXTR64, UNKNOWN, (int) UINT64_FTYPE_UINT64_UINT64 }, { OPTION_MASK_ISA_BMI, CODE_FOR_ctzhi2, "__builtin_ctzs", IX86_BUILTIN_CTZS, UNKNOWN, (int) UINT16_FTYPE_UINT16 }, + /* TBM */ + { OPTION_MASK_ISA_TBM, CODE_FOR_tbm_bextri_si, "__builtin_ia32_bextri_u32", IX86_BUILTIN_BEXTRI32, UNKNOWN, (int) UINT_FTYPE_UINT_UINT }, + { OPTION_MASK_ISA_TBM, CODE_FOR_tbm_bextri_di, "__builtin_ia32_bextri_u64", IX86_BUILTIN_BEXTRI64, UNKNOWN, (int) UINT64_FTYPE_UINT64_UINT64 }, + /* F16C */ { OPTION_MASK_ISA_F16C, CODE_FOR_vcvtph2ps, "__builtin_ia32_vcvtph2ps", IX86_BUILTIN_CVTPH2PS, UNKNOWN, (int) V4SF_FTYPE_V8HI }, { OPTION_MASK_ISA_F16C, CODE_FOR_vcvtph2ps256, "__builtin_ia32_vcvtph2ps256", IX86_BUILTIN_CVTPH2PS256, UNKNOWN, (int) V8SF_FTYPE_V8HI }, @@ -27098,6 +27127,32 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED, emit_insn (gen_lwp_slwpcb (target)); return target; + case IX86_BUILTIN_BEXTRI32: + case IX86_BUILTIN_BEXTRI64: + arg0 = CALL_EXPR_ARG (exp, 0); + arg1 = CALL_EXPR_ARG (exp, 1); + op0 = expand_normal (arg0); + op1 = expand_normal (arg1); + icode = (fcode == IX86_BUILTIN_BEXTRI32 + ? CODE_FOR_tbm_bextri_si + : CODE_FOR_tbm_bextri_di); + if (!CONST_INT_P (op1)) + { + error ("last argument must be an immediate"); + return const0_rtx; + } + else + { + unsigned char length = (INTVAL (op1) >> 8) & 0xFF; + unsigned char lsb_index = INTVAL (op1) & 0xFF; + op1 = GEN_INT (length); + op2 = GEN_INT (lsb_index); + pat = GEN_FCN (icode) (target, op0, op1, op2); + if (pat) + emit_insn (pat); + return target; + } + default: break; } diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h index d854797be82..8ef0d7b4d6b 100644 --- a/gcc/config/i386/i386.h +++ b/gcc/config/i386/i386.h @@ -60,6 +60,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #define TARGET_ROUND OPTION_ISA_ROUND #define TARGET_ABM OPTION_ISA_ABM #define TARGET_BMI OPTION_ISA_BMI +#define TARGET_TBM OPTION_ISA_TBM #define TARGET_POPCNT OPTION_ISA_POPCNT #define TARGET_SAHF OPTION_ISA_SAHF #define TARGET_MOVBE OPTION_ISA_MOVBE diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index a4881f5e6fb..10c4bb2e359 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -12098,6 +12098,144 @@ [(set_attr "type" "bitmanip") (set_attr "mode" "")]) +;; TBM instructions. +(define_insn "tbm_bextri_" + [(set (match_operand:SWI48 0 "register_operand" "=r") + (zero_extract:SWI48 + (match_operand:SWI48 1 "nonimmediate_operand" "rm") + (match_operand:SWI48 2 "const_0_to_255_operand" "n") + (match_operand:SWI48 3 "const_0_to_255_operand" "n"))) + (clobber (reg:CC FLAGS_REG))] + "TARGET_TBM" +{ + operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3])); + return "bextr\t{%2, %1, %0|%0, %1, %2}"; +} + [(set_attr "type" "bitmanip") + (set_attr "mode" "")]) + +(define_insn "*tbm_blcfill_" + [(set (match_operand:SWI48 0 "register_operand" "=r") + (and:SWI48 + (plus:SWI48 + (match_operand:SWI48 1 "nonimmediate_operand" "rm") + (const_int 1)) + (match_dup 1))) + (clobber (reg:CC FLAGS_REG))] + "TARGET_TBM" + "blcfill\t{%1, %0|%0, %1}" + [(set_attr "type" "bitmanip") + (set_attr "mode" "")]) + +(define_insn "*tbm_blci_" + [(set (match_operand:SWI48 0 "register_operand" "=r") + (ior:SWI48 + (not:SWI48 + (plus:SWI48 + (match_operand:SWI48 1 "nonimmediate_operand" "rm") + (const_int 1))) + (match_dup 1))) + (clobber (reg:CC FLAGS_REG))] + "TARGET_TBM" + "blci\t{%1, %0|%0, %1}" + [(set_attr "type" "bitmanip") + (set_attr "mode" "")]) + +(define_insn "*tbm_blcic_" + [(set (match_operand:SWI48 0 "register_operand" "=r") + (and:SWI48 + (plus:SWI48 + (match_operand:SWI48 1 "nonimmediate_operand" "rm") + (const_int 1)) + (not:SWI48 + (match_dup 1)))) + (clobber (reg:CC FLAGS_REG))] + "TARGET_TBM" + "blcic\t{%1, %0|%0, %1}" + [(set_attr "type" "bitmanip") + (set_attr "mode" "")]) + +(define_insn "*tbm_blcmsk_" + [(set (match_operand:SWI48 0 "register_operand" "=r") + (xor:SWI48 + (plus:SWI48 + (match_operand:SWI48 1 "nonimmediate_operand" "rm") + (const_int 1)) + (match_dup 1))) + (clobber (reg:CC FLAGS_REG))] + "TARGET_TBM" + "blcmsk\t{%1, %0|%0, %1}" + [(set_attr "type" "bitmanip") + (set_attr "mode" "")]) + +(define_insn "*tbm_blcs_" + [(set (match_operand:SWI48 0 "register_operand" "=r") + (ior:SWI48 + (plus:SWI48 + (match_operand:SWI48 1 "nonimmediate_operand" "rm") + (const_int 1)) + (match_dup 1))) + (clobber (reg:CC FLAGS_REG))] + "TARGET_TBM" + "blcs\t{%1, %0|%0, %1}" + [(set_attr "type" "bitmanip") + (set_attr "mode" "")]) + +(define_insn "*tbm_blsfill_" + [(set (match_operand:SWI48 0 "register_operand" "=r") + (ior:SWI48 + (plus:SWI48 + (match_operand:SWI48 1 "nonimmediate_operand" "rm") + (const_int -1)) + (match_dup 1))) + (clobber (reg:CC FLAGS_REG))] + "TARGET_TBM" + "blsfill\t{%1, %0|%0, %1}" + [(set_attr "type" "bitmanip") + (set_attr "mode" "")]) + +(define_insn "*tbm_blsic_" + [(set (match_operand:SWI48 0 "register_operand" "=r") + (ior:SWI48 + (plus:SWI48 + (match_operand:SWI48 1 "nonimmediate_operand" "rm") + (const_int -1)) + (not:SWI48 + (match_dup 1)))) + (clobber (reg:CC FLAGS_REG))] + "TARGET_TBM" + "blsic\t{%1, %0|%0, %1}" + [(set_attr "type" "bitmanip") + (set_attr "mode" "")]) + +(define_insn "*tbm_t1mskc_" + [(set (match_operand:SWI48 0 "register_operand" "=r") + (ior:SWI48 + (plus:SWI48 + (match_operand:SWI48 1 "nonimmediate_operand" "rm") + (const_int 1)) + (not:SWI48 + (match_dup 1)))) + (clobber (reg:CC FLAGS_REG))] + "TARGET_TBM" + "t1mskc\t{%1, %0|%0, %1}" + [(set_attr "type" "bitmanip") + (set_attr "mode" "")]) + +(define_insn "*tbm_tzmsk_" + [(set (match_operand:SWI48 0 "register_operand" "=r") + (and:SWI48 + (plus:SWI48 + (match_operand:SWI48 1 "nonimmediate_operand" "rm") + (const_int -1)) + (not:SWI48 + (match_dup 1)))) + (clobber (reg:CC FLAGS_REG))] + "TARGET_TBM" + "tzmsk\t{%1, %0|%0, %1}" + [(set_attr "type" "bitmanip") + (set_attr "mode" "")]) + (define_insn "bsr_rex64" [(set (match_operand:DI 0 "register_operand" "=r") (minus:DI (const_int 63) diff --git a/gcc/config/i386/i386.opt b/gcc/config/i386/i386.opt index f4c3c582a15..aa1d615f7ef 100644 --- a/gcc/config/i386/i386.opt +++ b/gcc/config/i386/i386.opt @@ -362,6 +362,10 @@ mbmi Target Report Mask(ISA_BMI) Var(ix86_isa_flags) Save Support BMI built-in functions and code generation +mtbm +Target Report Mask(ISA_TBM) Var(ix86_isa_flags) Save +Support TBM built-in functions and code generation + mcx16 Target Report Mask(ISA_CX16) Var(ix86_isa_flags) Save Support code generation of cmpxchg16b instruction. diff --git a/gcc/config/i386/tbmintrin.h b/gcc/config/i386/tbmintrin.h new file mode 100644 index 00000000000..8d2431d41cd --- /dev/null +++ b/gcc/config/i386/tbmintrin.h @@ -0,0 +1,191 @@ +/* Copyright (C) 2010 Free Software Foundation, Inc. + + This file is part of GCC. + + GCC is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + GCC is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + Under Section 7 of GPL version 3, you are granted additional + permissions described in the GCC Runtime Library Exception, version + 3.1, as published by the Free Software Foundation. + + You should have received a copy of the GNU General Public License and + a copy of the GCC Runtime Library Exception along with this program; + see the files COPYING3 and COPYING.RUNTIME respectively. If not, see + . */ + +#ifndef _X86INTRIN_H_INCLUDED +# error "Never use directly; include instead." +#endif + +#ifndef __TBM__ +# error "TBM instruction set not enabled" +#endif /* __TBM__ */ + +#ifndef _TBMINTRIN_H_INCLUDED +#define _TBMINTRIN_H_INCLUDED + +#ifdef __OPTIMIZE__ +extern __inline unsigned int __attribute__((__gnu_inline__, __always_inline__, __artificial__)) +__bextri_u32 (unsigned int __X, const unsigned int __I) +{ + return __builtin_ia32_bextri_u32 (__X, __I); +} +#else +#define __bextri_u32(X, I) \ + ((unsigned int)__builtin_ia32_bextri_u32 ((unsigned int)(X), \ + (unsigned int)(I))) +#endif /*__OPTIMIZE__ */ + +extern __inline unsigned int __attribute__((__gnu_inline__, __always_inline__, __artificial__)) +__blcfill_u32 (unsigned int __X) +{ + unsigned int tmp = (__X) & ((__X) + 1); + return tmp; +} + +extern __inline unsigned int __attribute__((__gnu_inline__, __always_inline__, __artificial__)) +__blci_u32 (unsigned int __X) +{ + unsigned int tmp = (__X) | (~((__X) + 1)); + return tmp; +} + +extern __inline unsigned int __attribute__((__gnu_inline__, __always_inline__, __artificial__)) +__blcic_u32 (unsigned int __X) +{ + unsigned int tmp = (~(__X)) & ((__X) + 1); + return tmp; +} + +extern __inline unsigned int __attribute__((__gnu_inline__, __always_inline__, __artificial__)) +__blcmsk_u32 (unsigned int __X) +{ + unsigned int tmp = (__X) ^ ((__X) + 1); + return tmp; +} + +extern __inline unsigned int __attribute__((__gnu_inline__, __always_inline__, __artificial__)) +__blcs_u32 (unsigned int __X) +{ + unsigned int tmp = (__X) | ((__X) + 1); + return tmp; +} + +extern __inline unsigned int __attribute__((__gnu_inline__, __always_inline__, __artificial__)) +__blsfill_u32 (unsigned int __X) +{ + unsigned int tmp = (__X) | ((__X) - 1); + return tmp; +} + +extern __inline unsigned int __attribute__((__gnu_inline__, __always_inline__, __artificial__)) +__blsic_u32 (unsigned int __X) +{ + unsigned int tmp = (~(__X)) | ((__X) - 1); + return tmp; +} + +extern __inline unsigned int __attribute__((__gnu_inline__, __always_inline__, __artificial__)) +__t1mskc_u32 (unsigned int __X) +{ + unsigned int tmp = (~(__X)) | ((__X) + 1); + return tmp; +} + +extern __inline unsigned int __attribute__((__gnu_inline__, __always_inline__, __artificial__)) +__tzmsk_u32 (unsigned int __X) +{ + unsigned int tmp = (~(__X)) & ((__X) - 1); + return tmp; +} + + + +#ifdef __x86_64__ +#ifdef __OPTIMIZE__ +extern __inline unsigned long long __attribute__((__gnu_inline__, __always_inline__, __artificial__)) +__bextri_u64 (unsigned long long __X, const unsigned int __I) +{ + return __builtin_ia32_bextri_u64 (__X, __I); +} +#else +#define __bextri_u64(X, I) \ + ((unsigned long long)__builtin_ia32_bextri_u64 ((unsigned long long)(X), \ + (unsigned long long)(I))) +#endif /*__OPTIMIZE__ */ + +extern __inline unsigned long long __attribute__((__gnu_inline__, __always_inline__, __artificial__)) +__blcfill_u64 (unsigned long long __X) +{ + unsigned long long tmp = (__X) & ((__X) + 1); + return tmp; +} + +extern __inline unsigned long long __attribute__((__gnu_inline__, __always_inline__, __artificial__)) +__blci_u64 (unsigned long long __X) +{ + unsigned long long tmp = (__X) | (~((__X) + 1)); + return tmp; +} + +extern __inline unsigned long long __attribute__((__gnu_inline__, __always_inline__, __artificial__)) +__blcic_u64 (unsigned long long __X) +{ + unsigned long long tmp = (~(__X)) & ((__X) + 1); + return tmp; +} + +extern __inline unsigned long long __attribute__((__gnu_inline__, __always_inline__, __artificial__)) +__blcmsk_u64 (unsigned long long __X) +{ + unsigned long long tmp = (__X) ^ ((__X) + 1); + return tmp; +} + +extern __inline unsigned long long __attribute__((__gnu_inline__, __always_inline__, __artificial__)) +__blcs_u64 (unsigned long long __X) +{ + unsigned long long tmp = (__X) | ((__X) + 1); + return tmp; +} + +extern __inline unsigned long long __attribute__((__gnu_inline__, __always_inline__, __artificial__)) +__blsfill_u64 (unsigned long long __X) +{ + unsigned long long tmp = (__X) | ((__X) - 1); + return tmp; +} + +extern __inline unsigned long long __attribute__((__gnu_inline__, __always_inline__, __artificial__)) +__blsic_u64 (unsigned long long __X) +{ + unsigned long long tmp = (~(__X)) | ((__X) - 1); + return tmp; +} + +extern __inline unsigned long long __attribute__((__gnu_inline__, __always_inline__, __artificial__)) +__t1mskc_u64 (unsigned long long __X) +{ + unsigned long long tmp = (~(__X)) | ((__X) + 1); + return tmp; +} + +extern __inline unsigned long long __attribute__((__gnu_inline__, __always_inline__, __artificial__)) +__tzmsk_u64 (unsigned long long __X) +{ + unsigned long long tmp = (~(__X)) & ((__X) - 1); + return tmp; +} + + +#endif /* __x86_64__ */ +#endif /* _TBMINTRIN_H_INCLUDED */ + diff --git a/gcc/config/i386/x86intrin.h b/gcc/config/i386/x86intrin.h index 9a7366b769c..72c41753dbe 100644 --- a/gcc/config/i386/x86intrin.h +++ b/gcc/config/i386/x86intrin.h @@ -85,6 +85,10 @@ #include #endif +#ifdef __TBM__ +#include +#endif + #ifdef __POPCNT__ #include #endif diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index 15abbb8243b..ccd0d914372 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -9402,6 +9402,14 @@ unsigned int __builtin_ia32_lzcnt_u32(unsigned int); unsigned long long __builtin_ia32_lzcnt_u64 (unsigned long long); @end smallexample +The following built-in functions are available when @option{-mtbm} is used. +Both of them generate the immediate form of the bextr machine instruction. +@smallexample +unsigned int __builtin_ia32_bextri_u32 (unsigned int, const unsigned int); +unsigned long long __builtin_ia32_bextri_u64 (unsigned long long, const unsigned long long); +@end smallexample + + The following built-in functions are available when @option{-m3dnow} is used. All of them generate the machine instruction that is part of the name. diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 99a7a890d7b..f19748391f6 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -598,7 +598,7 @@ Objective-C and Objective-C++ Dialects}. -mcld -mcx16 -msahf -mmovbe -mcrc32 -mrecip -mvzeroupper @gol -mmmx -msse -msse2 -msse3 -mssse3 -msse4.1 -msse4.2 -msse4 -mavx @gol -maes -mpclmul -mfsgsbase -mrdrnd -mf16c -mfused-madd @gol --msse4a -m3dnow -mpopcnt -mabm -mbmi -mfma4 -mxop -mlwp @gol +-msse4a -m3dnow -mpopcnt -mabm -mbmi -mtbm -mfma4 -mxop -mlwp @gol -mthreads -mno-align-stringops -minline-all-stringops @gol -minline-stringops-dynamically -mstringop-strategy=@var{alg} @gol -mpush-args -maccumulate-outgoing-args -m128bit-long-double @gol @@ -12452,6 +12452,8 @@ preferred alignment to @option{-mpreferred-stack-boundary=2}. @itemx -mno-abm @itemx -mbmi @itemx -mno-bmi +@itemx -mtbm +@itemx -mno-tbm @opindex mmmx @opindex mno-mmx @opindex msse diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index bc71f3cae8c..52507c0747e 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,18 @@ +2010-11-10 Quentin Neill + + * g++.dg/other/i386-2.C: Add -mtbm. + * g++.dg/other/i386-3.C: Likewise. + * gcc.target/i386/funcspec-5.c: Add tbm and no-tbm targets. + * gcc.target/i386/funcspec-6.c: Likewise. + * gcc.target/i386/sse-12.c: Add -mtbm. + * gcc.target/i386/sse-13.c: Add -mtbm and test immediate + operand intrinsics. + * gcc.target/i386/sse-14.c: Likewise. + * gcc.target/i386/sse-22.c: Likewise. + * gcc.target/i386/sse-23.c: Likewise. + * gcc.target/i386/tbm-1.c: New file. + * gcc.target/i386/tbm-2.c: Likewise. + 2010-11-10 Quentin Neill * g++.dg/other/i386-2.C: Add -mbmi. diff --git a/gcc/testsuite/g++.dg/other/i386-2.C b/gcc/testsuite/g++.dg/other/i386-2.C index f0a382a8857..6f7ca84ca80 100644 --- a/gcc/testsuite/g++.dg/other/i386-2.C +++ b/gcc/testsuite/g++.dg/other/i386-2.C @@ -1,9 +1,9 @@ /* { dg-do compile { target i?86-*-* x86_64-*-* } } */ -/* { dg-options "-O -pedantic-errors -march=k8 -m3dnow -mavx -mxop -maes -mpclmul -mpopcnt -mabm -mbmi -mlwp -mfsgsbase -mrdrnd -mf16c" } */ +/* { dg-options "-O -pedantic-errors -march=k8 -m3dnow -mavx -mxop -maes -mpclmul -mpopcnt -mabm -mbmi -mtbm -mlwp -mfsgsbase -mrdrnd -mf16c" } */ /* Test that {,x,e,p,t,s,w,a,b,i}mmintrin.h, xopintrin.h, abmintrin.h, - bmiintrin.h, lwpintrin.h, popcntintrin.h and mm3dnow.h are usable with - -O -pedantic-errors. */ + bmiintrin.h, tbmintrin.h, lwpintrin.h, popcntintrin.h and mm3dnow.h + are usable with -O -pedantic-errors. */ #include diff --git a/gcc/testsuite/g++.dg/other/i386-3.C b/gcc/testsuite/g++.dg/other/i386-3.C index 4b27372320d..a8b2039fe96 100644 --- a/gcc/testsuite/g++.dg/other/i386-3.C +++ b/gcc/testsuite/g++.dg/other/i386-3.C @@ -1,8 +1,8 @@ /* { dg-do compile { target i?86-*-* x86_64-*-* } } */ -/* { dg-options "-O -fkeep-inline-functions -march=k8 -m3dnow -mavx -mxop -maes -mpclmul -mpopcnt -mabm -mbmi -mlwp -mfsgsbase -mrdrnd -mf16c" } */ +/* { dg-options "-O -fkeep-inline-functions -march=k8 -m3dnow -mavx -mxop -maes -mpclmul -mpopcnt -mabm -mbmi -mtbm -mlwp -mfsgsbase -mrdrnd -mf16c" } */ /* Test that {,x,e,p,t,s,w,a,b,i}mmintrin.h, xopintrin.h, abmintrin.h, - bmiintrin.h, lwpintrin.h, popcntintrin.h and mm3dnow.h are usable with - -O -fkeep-inline-functions. */ + bmiintrin.h, tbmintrin.h, lwpintrin.h, popcntintrin.h and mm3dnow.h + are usable with -O -fkeep-inline-functions. */ #include diff --git a/gcc/testsuite/gcc.target/i386/bmi-5.c b/gcc/testsuite/gcc.target/i386/bmi-5.c index b29c4533062..906bf217cc1 100644 --- a/gcc/testsuite/gcc.target/i386/bmi-5.c +++ b/gcc/testsuite/gcc.target/i386/bmi-5.c @@ -1,6 +1,6 @@ /* { dg-do link } */ /* { dg-require-effective-target lp64 } */ -/* { dg-options "-O0 -mbmi" } */ +/* { dg-options "-O2 -mbmi" } */ #include diff --git a/gcc/testsuite/gcc.target/i386/bmi-6.c b/gcc/testsuite/gcc.target/i386/bmi-6.c index 5d4bcf490d3..a4489e0b5a6 100644 --- a/gcc/testsuite/gcc.target/i386/bmi-6.c +++ b/gcc/testsuite/gcc.target/i386/bmi-6.c @@ -1,5 +1,5 @@ /* { dg-do link } */ -/* { dg-options "-O0 -mbmi" } */ +/* { dg-options "-O2 -mbmi" } */ #include diff --git a/gcc/testsuite/gcc.target/i386/funcspec-5.c b/gcc/testsuite/gcc.target/i386/funcspec-5.c index 5e07d8530fd..1e18dcf871f 100644 --- a/gcc/testsuite/gcc.target/i386/funcspec-5.c +++ b/gcc/testsuite/gcc.target/i386/funcspec-5.c @@ -19,6 +19,7 @@ extern void test_sse4_2 (void) __attribute__((__target__("sse4.2"))); extern void test_sse4a (void) __attribute__((__target__("sse4a"))); extern void test_fma4 (void) __attribute__((__target__("fma4"))); extern void test_ssse3 (void) __attribute__((__target__("ssse3"))); +extern void test_tbm (void) __attribute__((__target__("tbm"))); extern void test_no_abm (void) __attribute__((__target__("no-abm"))); extern void test_no_aes (void) __attribute__((__target__("no-aes"))); @@ -36,6 +37,7 @@ extern void test_no_sse4_2 (void) __attribute__((__target__("no-sse4.2"))); extern void test_no_sse4a (void) __attribute__((__target__("no-sse4a"))); extern void test_no_fma4 (void) __attribute__((__target__("no-fma4"))); extern void test_no_ssse3 (void) __attribute__((__target__("no-ssse3"))); +extern void test_no_tbm (void) __attribute__((__target__("no-tbm"))); extern void test_arch_i386 (void) __attribute__((__target__("arch=i386"))); extern void test_arch_i486 (void) __attribute__((__target__("arch=i486"))); diff --git a/gcc/testsuite/gcc.target/i386/funcspec-6.c b/gcc/testsuite/gcc.target/i386/funcspec-6.c index 81c831cd45b..92a3cb52d7b 100644 --- a/gcc/testsuite/gcc.target/i386/funcspec-6.c +++ b/gcc/testsuite/gcc.target/i386/funcspec-6.c @@ -19,6 +19,7 @@ extern void test_sse4_2 (void) __attribute__((__target__("sse4.2"))); extern void test_sse4a (void) __attribute__((__target__("sse4a"))); extern void test_fma4 (void) __attribute__((__target__("fma4"))); extern void test_ssse3 (void) __attribute__((__target__("ssse3"))); +extern void test_tbm (void) __attribute__((__target__("tbm"))); extern void test_no_abm (void) __attribute__((__target__("no-abm"))); extern void test_no_aes (void) __attribute__((__target__("no-aes"))); @@ -36,6 +37,7 @@ extern void test_no_sse4_2 (void) __attribute__((__target__("no-sse4.2"))); extern void test_no_sse4a (void) __attribute__((__target__("no-sse4a"))); extern void test_no_fma4 (void) __attribute__((__target__("no-fma4"))); extern void test_no_ssse3 (void) __attribute__((__target__("no-ssse3"))); +extern void test_no_tbm (void) __attribute__((__target__("no-tbm"))); extern void test_arch_nocona (void) __attribute__((__target__("arch=nocona"))); extern void test_arch_core2 (void) __attribute__((__target__("arch=core2"))); diff --git a/gcc/testsuite/gcc.target/i386/sse-12.c b/gcc/testsuite/gcc.target/i386/sse-12.c index d59777bd0c1..fb53c3c5071 100644 --- a/gcc/testsuite/gcc.target/i386/sse-12.c +++ b/gcc/testsuite/gcc.target/i386/sse-12.c @@ -1,9 +1,9 @@ /* Test that {,x,e,p,t,s,w,a,b,i}mmintrin.h, xopintrin.h, mm3dnow.h, - fma4intrin.h, abmintrin.h, bmiintrin.h, lwpintrin.h, + fma4intrin.h, abmintrin.h, bmiintrin.h, tbmintrin.h, lwpintrin.h, popcntintrin.h and mm_malloc.h are usable with -O -std=c89 -pedantic-errors. */ /* { dg-do compile } */ -/* { dg-options "-O -std=c89 -pedantic-errors -march=k8 -m3dnow -mavx -mfma4 -mxop -maes -mpclmul -mpopcnt -mabm -mbmi -mlwp -mfsgsbase -mrdrnd -mf16c" } */ +/* { dg-options "-O -std=c89 -pedantic-errors -march=k8 -m3dnow -mavx -mfma4 -mxop -maes -mpclmul -mpopcnt -mabm -mbmi -mtbm -mlwp -mfsgsbase -mrdrnd -mf16c" } */ #include diff --git a/gcc/testsuite/gcc.target/i386/sse-13.c b/gcc/testsuite/gcc.target/i386/sse-13.c index 01809d0cffa..6d84e3a1bb8 100644 --- a/gcc/testsuite/gcc.target/i386/sse-13.c +++ b/gcc/testsuite/gcc.target/i386/sse-13.c @@ -5,9 +5,9 @@ /* Test that the intrinsics compile with optimization. All of them are defined as inline functions in {,x,e,p,t,s,w,a,b,i}mmintrin.h, - xopintrin.h, abmintrin.h, lwpintrin.h, popcntintrin.h and mm3dnow.h - that reference the proper builtin functions. Defining away - "extern" and "__inline" results in all of them being compiled as + xopintrin.h, abmintrin.h, tbmintrin.h, lwpintrin.h, popcntintrin.h + and mm3dnow.h that reference the proper builtin functions. Defining + away "extern" and "__inline" results in all of them being compiled as proper functions. */ #define extern @@ -141,4 +141,9 @@ #define __builtin_ia32_lwpins32(D2, D1, F) __builtin_ia32_lwpins32 (D2, D1, 1) #define __builtin_ia32_lwpins64(D2, D1, F) __builtin_ia32_lwpins64 (D2, D1, 1) +/* tbmintrin.h */ +#define __builtin_ia32_bextri_u32(X, Y) __builtin_ia32_bextri_u32 (X, 1) +#define __builtin_ia32_bextri_u64(X, Y) __builtin_ia32_bextri_u64 (X, 1) + + #include diff --git a/gcc/testsuite/gcc.target/i386/sse-14.c b/gcc/testsuite/gcc.target/i386/sse-14.c index d256e68c4be..41bde1ba2f9 100644 --- a/gcc/testsuite/gcc.target/i386/sse-14.c +++ b/gcc/testsuite/gcc.target/i386/sse-14.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O0 -Werror-implicit-function-declaration -march=k8 -m3dnow -mavx -mxop -msse4a -maes -mpclmul -mpopcnt -mabm -mlwp -mfsgsbase -mrdrnd -mf16c" } */ +/* { dg-options "-O0 -Werror-implicit-function-declaration -march=k8 -m3dnow -mavx -mxop -msse4a -maes -mpclmul -mpopcnt -mabm -mtbm -mlwp -mfsgsbase -mrdrnd -mf16c" } */ #include @@ -177,3 +177,9 @@ test_2 ( __lwpins32, unsigned char, unsigned int, unsigned int, 1) test_2 ( __lwpval64, void, unsigned long long, unsigned int, 1) test_2 ( __lwpins64, unsigned char, unsigned long long, unsigned int, 1) #endif + +/* tbmintrin.h */ +test_1 ( __bextri_u32, unsigned int, unsigned int, 1) +#ifdef __x86_64__ +test_1 ( __bextri_u64, unsigned long long, unsigned long long, 1) +#endif diff --git a/gcc/testsuite/gcc.target/i386/sse-22.c b/gcc/testsuite/gcc.target/i386/sse-22.c index bb0472d471c..e28164d080d 100644 --- a/gcc/testsuite/gcc.target/i386/sse-22.c +++ b/gcc/testsuite/gcc.target/i386/sse-22.c @@ -6,10 +6,10 @@ /* Test that the intrinsics compile without optimization. All of them are defined as inline functions in {,x,e,p,t,s,w,a}mmintrin.h, - xopintrin.h, lwpintrin.h, popcntintrin.h and mm3dnow.h that - reference the proper builtin functions. Defining away "extern" and - "__inline" results in all of them being compiled as proper - functions. */ + xopintrin.h, tbmintrin.h, lwpintrin.h, popcntintrin.h and + mm3dnow.h that reference the proper builtin functions. Defining + away "extern" and "__inline" results in all of them being compiled as + proper functions. */ #define extern #define __inline @@ -39,7 +39,7 @@ #ifndef DIFFERENT_PRAGMAS -#pragma GCC target ("mmx,3dnow,sse,sse2,sse3,ssse3,sse4.1,sse4.2,sse4a,aes,pclmul,xop,popcnt,abm,lwp,fsgsbase,rdrnd,f16c") +#pragma GCC target ("mmx,3dnow,sse,sse2,sse3,ssse3,sse4.1,sse4.2,sse4a,aes,pclmul,xop,popcnt,abm,lwp,fsgsbase,rdrnd,f16c,tbm") #endif /* Following intrinsics require immediate arguments. They @@ -188,3 +188,13 @@ test_2 ( __lwpins64, unsigned char, unsigned long long, unsigned int, 1) test_1 (_cvtss_sh, unsigned short, float, 1) test_1 (_mm_cvtps_ph, __m128i, __m128, 1) test_1 (_mm256_cvtps_ph, __m128i, __m256, 1) + +/* tbmintrin.h (TBM). */ +#ifdef DIFFERENT_PRAGMAS +#pragma GCC target ("tbm") +#endif +#include +test_1 ( __bextri_u32, unsigned int, unsigned int, 1) +#ifdef __x86_64__ +test_1 ( __bextri_u64, unsigned long long, unsigned long long, 1) +#endif diff --git a/gcc/testsuite/gcc.target/i386/sse-23.c b/gcc/testsuite/gcc.target/i386/sse-23.c index 0e15bb25418..3d932e16bbf 100644 --- a/gcc/testsuite/gcc.target/i386/sse-23.c +++ b/gcc/testsuite/gcc.target/i386/sse-23.c @@ -5,9 +5,9 @@ /* Test that the intrinsics compile with optimization. All of them are defined as inline functions in {,x,e,p,t,s,w,a}mmintrin.h, - xopintrin.h, lwpintrin.h, popcntintrin.h and mm3dnow.h that - reference the proper builtin functions. Defining away "extern" and - "__inline" results in all of them being compiled as proper + xopintrin.h, lwpintrin.h, tbmintrin.h, popcntintrin.h and mm3dnow.h + that reference the proper builtin functions. Defining away "extern" + and "__inline" results in all of them being compiled as proper functions. */ #define extern @@ -141,7 +141,11 @@ #define __builtin_ia32_lwpins32(D2, D1, F) __builtin_ia32_lwpins32 (D2, D1, 1) #define __builtin_ia32_lwpins64(D2, D1, F) __builtin_ia32_lwpins64 (D2, D1, 1) -#pragma GCC target ("3dnow,sse4,sse4a,aes,pclmul,xop,abm,popcnt,lwp,fsgsbase,rdrnd,f16c") +/* tbmintrin.h */ +#define __builtin_ia32_bextri_u32(X, Y) __builtin_ia32_bextr_u32 (X, 1) +#define __builtin_ia32_bextri_u64(X, Y) __builtin_ia32_bextr_u64 (X, 1) + +#pragma GCC target ("3dnow,sse4,sse4a,aes,pclmul,xop,abm,popcnt,lwp,tbm,fsgsbase,rdrnd,f16c") #include #include #include diff --git a/gcc/testsuite/gcc.target/i386/tbm-1.c b/gcc/testsuite/gcc.target/i386/tbm-1.c new file mode 100644 index 00000000000..2c16d74db49 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/tbm-1.c @@ -0,0 +1,74 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mtbm" } */ +/* { dg-final { scan-assembler "bextr\[^\\n]*(%|)eax" } } */ +/* { dg-final { scan-assembler "blcfill\[^\\n]*(%|)eax" } } */ +/* { dg-final { scan-assembler "blci\[^\\n]*(%|)eax" } } */ +/* { dg-final { scan-assembler "blcic\[^\\n]*(%|)eax" } } */ +/* { dg-final { scan-assembler "blcmsk\[^\\n]*(%|)eax" } } */ +/* { dg-final { scan-assembler "blcs\[^\\n]*(%|)eax" } } */ +/* { dg-final { scan-assembler "blsfill\[^\\n]*(%|)eax" } } */ +/* { dg-final { scan-assembler "blsic\[^\\n]*(%|)eax" } } */ +/* { dg-final { scan-assembler "t1mskc\[^\\n]*(%|)eax" } } */ +/* { dg-final { scan-assembler "tzmsk\[^\\n]*(%|)eax" } } */ + +#include + +unsigned int +func_bextri32 (unsigned int X) +{ + return __bextri_u32 (X, 0x101); +} + +unsigned int +func_blcfill32 (unsigned int X) +{ + return __blcfill_u32 (X); +} + +unsigned int +func_blci32 (unsigned int X) +{ + return __blci_u32 (X); +} + +unsigned int +func_blcic32 (unsigned int X) +{ + return __blcic_u32 (X); +} + +unsigned int +func_blcmsk32 (unsigned int X) +{ + return __blcmsk_u32 (X); +} + +unsigned int +func_blcs32 (unsigned int X) +{ + return __blcs_u32 (X); +} + +unsigned int +func_blsfill32 (unsigned int X) +{ + return __blsfill_u32 (X); +} + +unsigned int +func_blsic32 (unsigned int X) +{ + return __blsic_u32 (X); +} + +unsigned int +func_t1mskc32 (unsigned int X) +{ + return __t1mskc_u32 (X); +} + +unsigned int +func_tzmsk32 (unsigned int X) +{ + return __tzmsk_u32 (X); +} diff --git a/gcc/testsuite/gcc.target/i386/tbm-2.c b/gcc/testsuite/gcc.target/i386/tbm-2.c new file mode 100644 index 00000000000..447e0ab66c6 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/tbm-2.c @@ -0,0 +1,75 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target lp64 } */ +/* { dg-options "-O2 -mtbm" } */ +/* { dg-final { scan-assembler "bextr\[^\\n]*(%|)rax" } } */ +/* { dg-final { scan-assembler "blcfill\[^\\n]*(%|)rax" } } */ +/* { dg-final { scan-assembler "blci\[^\\n]*(%|)rax" } } */ +/* { dg-final { scan-assembler "blcic\[^\\n]*(%|)rax" } } */ +/* { dg-final { scan-assembler "blcmsk\[^\\n]*(%|)rax" } } */ +/* { dg-final { scan-assembler "blcs\[^\\n]*(%|)rax" } } */ +/* { dg-final { scan-assembler "blsfill\[^\\n]*(%|)rax" } } */ +/* { dg-final { scan-assembler "blsic\[^\\n]*(%|)rax" } } */ +/* { dg-final { scan-assembler "t1mskc\[^\\n]*(%|)rax" } } */ +/* { dg-final { scan-assembler "tzmsk\[^\\n]*(%|)rax" } } */ + +#include + +unsigned long long +func_bextri64 (unsigned long long X) +{ + return __bextri_u64 (X, 0x101); +} + +unsigned long long +func_blcfill64 (unsigned long long X) +{ + return __blcfill_u64 (X); +} + +unsigned long long +func_blci64 (unsigned long long X) +{ + return __blci_u64 (X); +} + +unsigned long long +func_blcic64 (unsigned long long X) +{ + return __blcic_u64 (X); +} + +unsigned long long +func_blcmsk64 (unsigned long long X) +{ + return __blcmsk_u64 (X); +} + +unsigned long long +func_blcs64 (unsigned long long X) +{ + return __blcs_u64 (X); +} + +unsigned long long +func_blsfill64 (unsigned long long X) +{ + return __blsfill_u64 (X); +} + +unsigned long long +func_blsic64 (unsigned long long X) +{ + return __blsic_u64 (X); +} + +unsigned long long +func_t1mskc64 (unsigned long long X) +{ + return __t1mskc_u64 (X); +} + +unsigned long long +func_tzmsk64 (unsigned long long X) +{ + return __tzmsk_u64 (X); +}