diff options
author | H.J. Lu <hongjiu.lu@intel.com> | 2009-06-16 21:17:31 +0000 |
---|---|---|
committer | H.J. Lu <hjl@gcc.gnu.org> | 2009-06-16 14:17:31 -0700 |
commit | 7c45393e40d63f23b2691285d5ed450ce4fb5389 (patch) | |
tree | 45ac6794a48bd3484b3e2a6c77c35d5300994e10 /gcc/config | |
parent | cd3b0fafaaebab56b17ec9f4fceff4c0f8e26aec (diff) | |
download | gcc-7c45393e40d63f23b2691285d5ed450ce4fb5389.tar.gz |
config.gcc (extra_headers): Add ia32intrin.h for x86.
2009-06-16 H.J. Lu <hongjiu.lu@intel.com>
* config.gcc (extra_headers): Add ia32intrin.h for x86.
* config/i386/i386.c (ix86_builtins): Add IX86_BUILTIN_BSRSI,
IX86_BUILTIN_BSRDI. IX86_BUILTIN_RDPMC, IX86_BUILTIN_RDTSC.
IX86_BUILTIN_RDTSCP. IX86_BUILTIN_ROLQI, IX86_BUILTIN_ROLHI,
IX86_BUILTIN_RORQI and IX86_BUILTIN_RORHI.
(ix86_special_builtin_type): Add UINT64_FTYPE_VOID,
UINT64_FTYPE_PINT, INT_FTYPE_INT, UINT64_FTYPE_INT,
INT64_FTYPE_INT64, UINT16_FTYPE_UINT16_INT and
UINT8_FTYPE_UINT8_INT
(bdesc_special_args): Add __builtin_ia32_rdtsc and
__builtin_ia32_rdtscp.
(bdesc_args): Add __builtin_ia32_bsrsi, __builtin_ia32_bsrdi,
__builtin_ia32_rolqi, __builtin_ia32_rolhi, __builtin_ia32_rorqi
and __builtin_ia32_rorhi,
(ix86_init_mmx_sse_builtins): Handle UINT64_FTYPE_VOID,
UINT64_FTYPE_PINT, INT_FTYPE_INT, UINT64_FTYPE_INT,
INT64_FTYPE_INT64, UINT16_FTYPE_UINT16_INT and
UINT8_FTYPE_UINT8_INT.
(ix86_expand_args_builtin): Likewise.
(ix86_expand_special_args_builtin): Likewise.
* config/i386/i386.md (UNSPECV_RDTSCP): New.
(UNSPECV_RDTSC): Likewise.
(UNSPECV_RDPMC): Likewise.
(*bsr): Removed to ...
(bsr): This
(*bsr_rex64): Removed to ...
(bsr_rex64): This.
(rdpmc): New.
(*rdpmc): Likewise.
(*rdpmc_rex64): Likewise.
(rdtsc): Likewise.
(*rdtsc): Likewise.
(*rdtsc_rex64): Likewise.
(rdtscp): Likewise.
(*rdtscp): Likewise.
(*rdtscp_rex64): Likewise.
* config/i386/ia32intrin.h: New.
* config/i386/x86intrin.h: Include <ia32intrin.h>.
From-SVN: r148554
Diffstat (limited to 'gcc/config')
-rw-r--r-- | gcc/config/i386/i386.c | 91 | ||||
-rw-r--r-- | gcc/config/i386/i386.md | 170 | ||||
-rw-r--r-- | gcc/config/i386/ia32intrin.h | 230 | ||||
-rw-r--r-- | gcc/config/i386/x86intrin.h | 2 |
4 files changed, 491 insertions, 2 deletions
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 2c637631cae..0e4e46c3888 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -20769,6 +20769,16 @@ enum ix86_builtins IX86_BUILTIN_MFENCE, IX86_BUILTIN_LFENCE, + IX86_BUILTIN_BSRSI, + IX86_BUILTIN_BSRDI, + IX86_BUILTIN_RDPMC, + IX86_BUILTIN_RDTSC, + IX86_BUILTIN_RDTSCP, + IX86_BUILTIN_ROLQI, + IX86_BUILTIN_ROLHI, + IX86_BUILTIN_RORQI, + IX86_BUILTIN_RORHI, + /* SSE3. */ IX86_BUILTIN_ADDSUBPS, IX86_BUILTIN_HADDPS, @@ -21471,6 +21481,8 @@ enum ix86_special_builtin_type { SPECIAL_FTYPE_UNKNOWN, VOID_FTYPE_VOID, + UINT64_FTYPE_VOID, + UINT64_FTYPE_PINT, V32QI_FTYPE_PCCHAR, V16QI_FTYPE_PCCHAR, V8SF_FTYPE_PCV4SF, @@ -21516,6 +21528,9 @@ enum ix86_builtin_type INT_FTYPE_V4SF_V4SF_PTEST, INT_FTYPE_V2DI_V2DI_PTEST, INT_FTYPE_V2DF_V2DF_PTEST, + INT_FTYPE_INT, + UINT64_FTYPE_INT, + INT64_FTYPE_INT64, INT64_FTYPE_V4SF, INT64_FTYPE_V2DF, INT_FTYPE_V16QI, @@ -21626,6 +21641,8 @@ enum ix86_builtin_type UINT_FTYPE_UINT_UINT, UINT_FTYPE_UINT_USHORT, UINT_FTYPE_UINT_UCHAR, + UINT16_FTYPE_UINT16_INT, + UINT8_FTYPE_UINT8_INT, V8HI_FTYPE_V8HI_INT, V4SI_FTYPE_V4SI_INT, V4HI_FTYPE_V4HI_INT, @@ -21664,6 +21681,9 @@ enum ix86_builtin_type /* Special builtins with variable number of arguments. */ static const struct builtin_description bdesc_special_args[] = { + { ~OPTION_MASK_ISA_64BIT, CODE_FOR_rdtsc, "__builtin_ia32_rdtsc", IX86_BUILTIN_RDTSC, UNKNOWN, (int) UINT64_FTYPE_VOID }, + { ~OPTION_MASK_ISA_64BIT, CODE_FOR_rdtscp, "__builtin_ia32_rdtscp", IX86_BUILTIN_RDTSCP, UNKNOWN, (int) UINT64_FTYPE_PINT }, + /* MMX */ { OPTION_MASK_ISA_MMX, CODE_FOR_mmx_emms, "__builtin_ia32_emms", IX86_BUILTIN_EMMS, UNKNOWN, (int) VOID_FTYPE_VOID }, @@ -21744,6 +21764,14 @@ static const struct builtin_description bdesc_special_args[] = /* Builtins with variable number of arguments. */ static const struct builtin_description bdesc_args[] = { + { ~OPTION_MASK_ISA_64BIT, CODE_FOR_bsr, "__builtin_ia32_bsrsi", IX86_BUILTIN_BSRSI, UNKNOWN, (int) INT_FTYPE_INT }, + { OPTION_MASK_ISA_64BIT, CODE_FOR_bsr_rex64, "__builtin_ia32_bsrdi", IX86_BUILTIN_BSRDI, UNKNOWN, (int) INT64_FTYPE_INT64 }, + { ~OPTION_MASK_ISA_64BIT, CODE_FOR_rdpmc, "__builtin_ia32_rdpmc", IX86_BUILTIN_RDPMC, UNKNOWN, (int) UINT64_FTYPE_INT }, + { ~OPTION_MASK_ISA_64BIT, CODE_FOR_rotlqi3, "__builtin_ia32_rolqi", IX86_BUILTIN_ROLQI, UNKNOWN, (int) UINT8_FTYPE_UINT8_INT }, + { ~OPTION_MASK_ISA_64BIT, CODE_FOR_rotlhi3, "__builtin_ia32_rolhi", IX86_BUILTIN_ROLHI, UNKNOWN, (int) UINT16_FTYPE_UINT16_INT }, + { ~OPTION_MASK_ISA_64BIT, CODE_FOR_rotrqi3, "__builtin_ia32_rorqi", IX86_BUILTIN_RORQI, UNKNOWN, (int) UINT8_FTYPE_UINT8_INT }, + { ~OPTION_MASK_ISA_64BIT, CODE_FOR_rotrhi3, "__builtin_ia32_rorhi", IX86_BUILTIN_RORHI, UNKNOWN, (int) UINT16_FTYPE_UINT16_INT }, + /* MMX */ { OPTION_MASK_ISA_MMX, CODE_FOR_mmx_addv8qi3, "__builtin_ia32_paddb", IX86_BUILTIN_PADDB, UNKNOWN, (int) V8QI_FTYPE_V8QI_V8QI }, { OPTION_MASK_ISA_MMX, CODE_FOR_mmx_addv4hi3, "__builtin_ia32_paddw", IX86_BUILTIN_PADDW, UNKNOWN, (int) V4HI_FTYPE_V4HI_V4HI }, @@ -23388,6 +23416,34 @@ ix86_init_mmx_sse_builtins (void) = build_function_type_list (V2DF_type_node, V2DF_type_node, V2DI_type_node, NULL_TREE); + /* Integer intrinsics. */ + tree uint64_ftype_void + = build_function_type (long_long_unsigned_type_node, + void_list_node); + tree int_ftype_int + = build_function_type_list (integer_type_node, + integer_type_node, NULL_TREE); + tree int64_ftype_int64 + = build_function_type_list (long_long_integer_type_node, + long_long_integer_type_node, + NULL_TREE); + tree uint64_ftype_int + = build_function_type_list (long_long_unsigned_type_node, + integer_type_node, NULL_TREE); + tree uint64_ftype_pint + = build_function_type_list (long_long_unsigned_type_node, + pint_type_node, NULL_TREE); + tree ushort_ftype_ushort_int + = build_function_type_list (short_unsigned_type_node, + short_unsigned_type_node, + integer_type_node, + NULL_TREE); + tree uchar_ftype_uchar_int + = build_function_type_list (unsigned_char_type_node, + unsigned_char_type_node, + integer_type_node, + NULL_TREE); + tree ftype; /* Add all special builtins with variable number of operands. */ @@ -23405,6 +23461,12 @@ ix86_init_mmx_sse_builtins (void) case VOID_FTYPE_VOID: type = void_ftype_void; break; + case UINT64_FTYPE_VOID: + type = uint64_ftype_void; + break; + case UINT64_FTYPE_PINT: + type = uint64_ftype_pint; + break; case V32QI_FTYPE_PCCHAR: type = v32qi_ftype_pcchar; break; @@ -23535,6 +23597,15 @@ ix86_init_mmx_sse_builtins (void) case INT_FTYPE_V2DF_V2DF_PTEST: type = int_ftype_v2df_v2df; break; + case INT_FTYPE_INT: + type = int_ftype_int; + break; + case UINT64_FTYPE_INT: + type = uint64_ftype_int; + break; + case INT64_FTYPE_INT64: + type = int64_ftype_int64; + break; case INT64_FTYPE_V4SF: type = int64_ftype_v4sf; break; @@ -23845,6 +23916,12 @@ ix86_init_mmx_sse_builtins (void) case UINT_FTYPE_UINT_UCHAR: type = unsigned_ftype_unsigned_uchar; break; + case UINT16_FTYPE_UINT16_INT: + type = ushort_ftype_ushort_int; + break; + case UINT8_FTYPE_UINT8_INT: + type = uchar_ftype_uchar_int; + break; case V8HI_FTYPE_V8HI_INT: type = v8hi_ftype_v8hi_int; break; @@ -24924,6 +25001,9 @@ ix86_expand_args_builtin (const struct builtin_description *d, return ix86_expand_sse_ptest (d, exp, target); case FLOAT128_FTYPE_FLOAT128: case FLOAT_FTYPE_FLOAT: + case INT_FTYPE_INT: + case UINT64_FTYPE_INT: + case INT64_FTYPE_INT64: case INT64_FTYPE_V4SF: case INT64_FTYPE_V2DF: case INT_FTYPE_V16QI: @@ -25049,6 +25129,8 @@ ix86_expand_args_builtin (const struct builtin_description *d, case UINT_FTYPE_UINT_UINT: case UINT_FTYPE_UINT_USHORT: case UINT_FTYPE_UINT_UCHAR: + case UINT16_FTYPE_UINT16_INT: + case UINT8_FTYPE_UINT8_INT: nargs = 2; break; case V2DI2TI_FTYPE_V2DI_INT: @@ -25293,6 +25375,12 @@ ix86_expand_special_args_builtin (const struct builtin_description *d, case VOID_FTYPE_VOID: emit_insn (GEN_FCN (icode) (target)); return 0; + case UINT64_FTYPE_VOID: + nargs = 0; + klass = load; + memory = 0; + break; + case UINT64_FTYPE_PINT: case V2DI_FTYPE_PV2DI: case V32QI_FTYPE_PCCHAR: case V16QI_FTYPE_PCCHAR: @@ -25415,6 +25503,9 @@ ix86_expand_special_args_builtin (const struct builtin_description *d, switch (nargs) { + case 0: + pat = GEN_FCN (icode) (target); + break; case 1: pat = GEN_FCN (icode) (target, args[0].op); break; diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index c21aa9c679e..59d9e829ed0 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -244,6 +244,9 @@ (UNSPECV_CLD 15) (UNSPECV_VZEROALL 16) (UNSPECV_VZEROUPPER 17) + (UNSPECV_RDTSC 18) + (UNSPECV_RDTSCP 19) + (UNSPECV_RDPMC 20) ]) ;; Constants to represent pcomtrue/pcomfalse variants @@ -16153,7 +16156,7 @@ (set_attr "type" "bitmanip") (set_attr "mode" "SI")]) -(define_insn "*bsr" +(define_insn "bsr" [(set (match_operand:SI 0 "register_operand" "=r") (minus:SI (const_int 31) (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))) @@ -16338,7 +16341,7 @@ (set_attr "type" "bitmanip") (set_attr "mode" "DI")]) -(define_insn "*bsr_rex64" +(define_insn "bsr_rex64" [(set (match_operand:DI 0 "register_operand" "=r") (minus:DI (const_int 63) (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))) @@ -22670,6 +22673,169 @@ (set_attr "prefix_extra" "1") (set_attr "mode" "DI")]) +(define_expand "rdpmc" + [(match_operand:DI 0 "register_operand" "") + (match_operand:SI 1 "register_operand" "")] + "" +{ + rtx reg = gen_reg_rtx (DImode); + rtx si; + + /* Force operand 1 into ECX. */ + rtx ecx = gen_rtx_REG (SImode, CX_REG); + emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1])); + si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx), + UNSPECV_RDPMC); + + if (TARGET_64BIT) + { + rtvec vec = rtvec_alloc (2); + rtx load = gen_rtx_PARALLEL (VOIDmode, vec); + rtx upper = gen_reg_rtx (DImode); + rtx di = gen_rtx_UNSPEC_VOLATILE (DImode, + gen_rtvec (1, const0_rtx), + UNSPECV_RDPMC); + RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si); + RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di); + emit_insn (load); + upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32), + NULL, 1, OPTAB_DIRECT); + reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1, + OPTAB_DIRECT); + } + else + emit_insn (gen_rtx_SET (VOIDmode, reg, si)); + emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg)); + DONE; +}) + +(define_insn "*rdpmc" + [(set (match_operand:DI 0 "register_operand" "=A") + (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")] + UNSPECV_RDPMC))] + "!TARGET_64BIT" + "rdpmc" + [(set_attr "type" "other") + (set_attr "length" "2")]) + +(define_insn "*rdpmc_rex64" + [(set (match_operand:DI 0 "register_operand" "=a") + (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")] + UNSPECV_RDPMC)) + (set (match_operand:DI 1 "register_operand" "=d") + (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))] + "TARGET_64BIT" + "rdpmc" + [(set_attr "type" "other") + (set_attr "length" "2")]) + +(define_expand "rdtsc" + [(set (match_operand:DI 0 "register_operand" "") + (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))] + "" +{ + if (TARGET_64BIT) + { + rtvec vec = rtvec_alloc (2); + rtx load = gen_rtx_PARALLEL (VOIDmode, vec); + rtx upper = gen_reg_rtx (DImode); + rtx lower = gen_reg_rtx (DImode); + rtx src = gen_rtx_UNSPEC_VOLATILE (DImode, + gen_rtvec (1, const0_rtx), + UNSPECV_RDTSC); + RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src); + RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src); + emit_insn (load); + upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32), + NULL, 1, OPTAB_DIRECT); + lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1, + OPTAB_DIRECT); + emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower)); + DONE; + } +}) + +(define_insn "*rdtsc" + [(set (match_operand:DI 0 "register_operand" "=A") + (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))] + "!TARGET_64BIT" + "rdtsc" + [(set_attr "type" "other") + (set_attr "length" "2")]) + +(define_insn "*rdtsc_rex64" + [(set (match_operand:DI 0 "register_operand" "=a") + (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC)) + (set (match_operand:DI 1 "register_operand" "=d") + (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))] + "TARGET_64BIT" + "rdtsc" + [(set_attr "type" "other") + (set_attr "length" "2")]) + +(define_expand "rdtscp" + [(match_operand:DI 0 "register_operand" "") + (match_operand:SI 1 "memory_operand" "")] + "" +{ + rtx di = gen_rtx_UNSPEC_VOLATILE (DImode, + gen_rtvec (1, const0_rtx), + UNSPECV_RDTSCP); + rtx si = gen_rtx_UNSPEC_VOLATILE (SImode, + gen_rtvec (1, const0_rtx), + UNSPECV_RDTSCP); + rtx reg = gen_reg_rtx (DImode); + rtx tmp = gen_reg_rtx (SImode); + + if (TARGET_64BIT) + { + rtvec vec = rtvec_alloc (3); + rtx load = gen_rtx_PARALLEL (VOIDmode, vec); + rtx upper = gen_reg_rtx (DImode); + RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di); + RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di); + RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si); + emit_insn (load); + upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32), + NULL, 1, OPTAB_DIRECT); + reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1, + OPTAB_DIRECT); + } + else + { + rtvec vec = rtvec_alloc (2); + rtx load = gen_rtx_PARALLEL (VOIDmode, vec); + RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di); + RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si); + emit_insn (load); + } + emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg)); + emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp)); + DONE; +}) + +(define_insn "*rdtscp" + [(set (match_operand:DI 0 "register_operand" "=A") + (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP)) + (set (match_operand:SI 1 "register_operand" "=c") + (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))] + "!TARGET_64BIT" + "rdtscp" + [(set_attr "type" "other") + (set_attr "length" "3")]) + +(define_insn "*rdtscp_rex64" + [(set (match_operand:DI 0 "register_operand" "=a") + (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP)) + (set (match_operand:DI 1 "register_operand" "=d") + (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP)) + (set (match_operand:SI 2 "register_operand" "=c") + (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))] + "TARGET_64BIT" + "rdtscp" + [(set_attr "type" "other") + (set_attr "length" "3")]) + (include "mmx.md") (include "sse.md") (include "sync.md") diff --git a/gcc/config/i386/ia32intrin.h b/gcc/config/i386/ia32intrin.h new file mode 100644 index 00000000000..e701b19e2a8 --- /dev/null +++ b/gcc/config/i386/ia32intrin.h @@ -0,0 +1,230 @@ +/* Copyright (C) 2009 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 + <http://www.gnu.org/licenses/>. */ + +#ifndef _X86INTRIN_H_INCLUDED +# error "Never use <ia32intrin.h> directly; include <x86intrin.h> instead." +#endif + +/* 32bit bsf */ +extern __inline int +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +__bsfd (int __X) +{ + return __builtin_ctz (__X); +} + +/* 32bit bsr */ +extern __inline int +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +__bsrd (int __X) +{ + return __builtin_ia32_bsrsi (__X); +} + +/* 32bit bswap */ +extern __inline int +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +__bswapd (int __X) +{ + return __builtin_bswap32 (__X); +} + +/* 32bit accumulate CRC32 (polynomial 0x11EDC6F41) value. */ +extern __inline unsigned int +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +__crc32b (unsigned int __C, unsigned char __V) +{ + return __builtin_ia32_crc32qi (__C, __V); +} + +extern __inline unsigned int +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +__crc32w (unsigned int __C, unsigned short __V) +{ + return __builtin_ia32_crc32hi (__C, __V); +} + +extern __inline unsigned int +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +__crc32d (unsigned int __C, unsigned int __V) +{ + return __builtin_ia32_crc32si (__C, __V); +} + +/* 32bit popcnt */ +extern __inline int +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +__popcntd (unsigned int __X) +{ + return __builtin_popcount (__X); +} + +/* rdpmc */ +extern __inline unsigned long long +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +__rdpmc (int __S) +{ + return __builtin_ia32_rdpmc (__S); +} + +/* rdtsc */ +extern __inline unsigned long long +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +__rdtsc (void) +{ + return __builtin_ia32_rdtsc (); +} + +/* rdtscp */ +extern __inline unsigned long long +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +__rdtscp (unsigned int *__A) +{ + return __builtin_ia32_rdtscp (__A); +} + +/* 8bit rol */ +extern __inline unsigned char +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +__rolb (unsigned char __X, int __C) +{ + return __builtin_ia32_rolqi (__X, __C); +} + +/* 16bit rol */ +extern __inline unsigned short +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +__rolw (unsigned short __X, int __C) +{ + return __builtin_ia32_rolhi (__X, __C); +} + +/* 32bit rol */ +extern __inline unsigned int +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +__rold (unsigned int __X, int __C) +{ + return (__X << __C) | (__X >> (32 - __C)); +} + +/* 8bit ror */ +extern __inline unsigned char +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +__rorb (unsigned char __X, int __C) +{ + return __builtin_ia32_rorqi (__X, __C); +} + +/* 16bit ror */ +extern __inline unsigned short +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +__rorw (unsigned short __X, int __C) +{ + return __builtin_ia32_rorhi (__X, __C); +} + +/* 32bit ror */ +extern __inline unsigned int +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +__rord (unsigned int __X, int __C) +{ + return (__X >> __C) | (__X << (32 - __C)); +} + +#ifdef __x86_64__ +/* 64bit bsf */ +extern __inline int +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +__bsfq (long long __X) +{ + return __builtin_ctzll (__X); +} + +/* 64bit bsr */ +extern __inline int +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +__bsrq (long long __X) +{ + return __builtin_ia32_bsrdi (__X); +} + +/* 64bit bswap */ +extern __inline long long +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +__bswapq (long long __X) +{ + return __builtin_bswap64 (__X); +} + +/* 64bit accumulate CRC32 (polynomial 0x11EDC6F41) value. */ +extern __inline unsigned long long +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +__crc32q (unsigned long long __C, unsigned long long __V) +{ + return __builtin_ia32_crc32di (__C, __V); +} + +/* 64bit popcnt */ +extern __inline long long +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +__popcntq (unsigned long long __X) +{ + return __builtin_popcountll (__X); +} + +/* 64bit rol */ +extern __inline unsigned long long +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +__rolq (unsigned long long __X, int __C) +{ + return (__X << __C) | (__X >> (64 - __C)); +} + +/* 64bit ror */ +extern __inline unsigned long long +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +__rorq (unsigned long long __X, int __C) +{ + return (__X >> __C) | (__X << (64 - __C)); +} + +#define _bswap64(a) __bswapq(a) +#define _popcnt64(a) __popcntq(a) +#define _lrotl(a,b) __rolq((a), (b)) +#define _lrotr(a,b) __rorq((a), (b)) +#else +#define _lrotl(a,b) __rold((a), (b)) +#define _lrotr(a,b) __rord((a), (b)) +#endif + +#define _bit_scan_forward(a) __bsfd(a) +#define _bit_scan_reverse(a) __bsrd(a) +#define _bswap(a) __bswapd(a) +#define _popcnt32(a) __popcntd(a) +#define _rdpmc(a) __rdpmc(a) +#define _rdtsc() __rdtsc() +#define _rdtscp(a) __rdtscp(a) +#define _rotwl(a,b) __rolw((a), (b)) +#define _rotwr(a,b) __rorw((a), (b)) +#define _rotl(a,b) __rold((a), (b)) +#define _rotr(a,b) __rord((a), (b)) diff --git a/gcc/config/i386/x86intrin.h b/gcc/config/i386/x86intrin.h index d848811d34c..705300c23eb 100644 --- a/gcc/config/i386/x86intrin.h +++ b/gcc/config/i386/x86intrin.h @@ -24,6 +24,8 @@ #ifndef _X86INTRIN_H_INCLUDED #define _X86INTRIN_H_INCLUDED +#include <ia32intrin.h> + #ifdef __MMX__ #include <mmintrin.h> #endif |