config.gcc (extra_headers): Add ia32intrin.h for x86.
authorH.J. Lu <hongjiu.lu@intel.com>
Tue, 16 Jun 2009 21:17:31 +0000 (21:17 +0000)
committerH.J. Lu <hjl@gcc.gnu.org>
Tue, 16 Jun 2009 21:17:31 +0000 (14:17 -0700)
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

gcc/ChangeLog
gcc/config.gcc
gcc/config/i386/i386.c
gcc/config/i386/i386.md
gcc/config/i386/ia32intrin.h [new file with mode: 0644]
gcc/config/i386/x86intrin.h

index 98d6b57ff1698f50205d4d3e2ccb0b14201332b5..67f67eac56314b714e257f497ae7b2ad4aa9ee92 100644 (file)
@@ -1,3 +1,48 @@
+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>.
+
 2009-06-16  Ian Lance Taylor  <iant@google.com>
 
        * ira-build.c (copy_info_to_removed_store_destinations):
index ceb911abf636d17bcd5ac4c1b7398811bf9044c3..7b599173371c9006435efc46ba61dbfb850fcbc4 100644 (file)
@@ -288,7 +288,7 @@ i[34567]86-*-*)
                       pmmintrin.h tmmintrin.h ammintrin.h smmintrin.h
                       nmmintrin.h bmmintrin.h mmintrin-common.h
                       wmmintrin.h immintrin.h x86intrin.h avxintrin.h 
-                      cross-stdarg.h"
+                      ia32intrin.h cross-stdarg.h"
        ;;
 x86_64-*-*)
        cpu_type=i386
@@ -298,7 +298,7 @@ x86_64-*-*)
                       pmmintrin.h tmmintrin.h ammintrin.h smmintrin.h
                       nmmintrin.h bmmintrin.h mmintrin-common.h
                       wmmintrin.h immintrin.h x86intrin.h avxintrin.h 
-                      cross-stdarg.h"
+                      ia32intrin.h cross-stdarg.h"
        need_64bit_hwint=yes
        ;;
 ia64-*-*)
index 2c637631cae89830fdcbbd3d64b54543377bc1f6..0e4e46c38889d2709ffad27043b08d728124982a 100644 (file)
@@ -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;
index c21aa9c679e1eff010debb5b69b88a02e1406ad9..59d9e829ed017b9098ff67fea07e09e93f73afef 100644 (file)
    (UNSPECV_CLD                        15)
    (UNSPECV_VZEROALL           16)
    (UNSPECV_VZEROUPPER         17)
+   (UNSPECV_RDTSC              18)
+   (UNSPECV_RDTSCP             19)
+   (UNSPECV_RDPMC              20)
   ])
 
 ;; Constants to represent pcomtrue/pcomfalse variants
    (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"))))
    (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"))))
    (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 (file)
index 0000000..e701b19
--- /dev/null
@@ -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))
index d848811d34c10e2e263489a06fbbe52df4e9b33b..705300c23eb13a9ad9a94a4fffca6b88ce8f6a20 100644 (file)
@@ -24,6 +24,8 @@
 #ifndef _X86INTRIN_H_INCLUDED
 #define _X86INTRIN_H_INCLUDED
 
+#include <ia32intrin.h>
+
 #ifdef __MMX__
 #include <mmintrin.h>
 #endif