This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

PATCH: Add x86 integer intrinsics


Hi,

Icc has some 32bit integer intrinsics in <ia32intrin.h>.  This patch
extends them to 64bit.

Implementation: 
1. <x86intrin.h> won't have any intrinsic prototypes. 
2. <x86instrin.h> will include <ia32intrin.h>. 
3. Including <ia32intrin.h> directly will lead an error. 
4. Provide backward compatibilities for existing icc intrinsics. 
5. The name of intrinsic should be  __<XXX>[b|w|d|q>, where <XXX> is the
instruction mnemonic. [b|w|d|q] is required only if the instruction can
have different data sizes. 

Any comments?

Thanks.


H.J.
----
2009-06-10  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_ROLSI, IX86_BUILTIN_ROLDI, IX86_BUILTIN_RORQI,
	IX86_BUILTIN_RORHI, IX86_BUILTIN_RORSI and IX86_BUILTIN_RORDI.
	(ix86_special_builtin_type): Add UINT64_FTYPE_VOID,
	UINT64_FTYPE_PINT, INT_FTYPE_INT, UINT64_FTYPE_INT,
	INT64_FTYPE_INT64, UINT64_FTYPE_UINT64_INT,
	UINT_FTYPE_UINT_INT, 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_rolsi,
	__builtin_ia32_roldi.  __builtin_ia32_rorqi, __builtin_ia32_rorhi,
	__builtin_ia32_rorsi and __builtin_ia32_rordi.
	(ix86_init_mmx_sse_builtins): Handle UINT64_FTYPE_VOID,
	UINT64_FTYPE_PINT, INT_FTYPE_INT, UINT64_FTYPE_INT,
	INT64_FTYPE_INT64, UINT64_FTYPE_UINT64_INT,
	UINT_FTYPE_UINT_INT, UINT16_FTYPE_UINT16_INT,
	UINT8_FTYPE_UINT8_INT.
	(ix86_expand_args_builtin): Likewise.
	(ix86_expand_special_args_builtin): Likewise.
	(x86_64_load_64bit_split): New.

	* config/i386/i386.md (UNSPECV_RDTSCP): New.
	(UNSPECV_RDTSC): Likewise.
	(UNSPECV_RDPMC): Likewise.
	(bsr): New.
	(bsr_rex64): Likewise.
	(rdpmc): Likewise.
	(*rdpmc): Likewise.
	(*rdpmc_rex64): Likewise.
	(rdtsc): Likewise.
	(*rdtsc): Likewise.
	(*rdtsc_rex64): Likewise.
	(rdtscp): Likewise.
	(*rdtscp): Likewise.
	(*rdtscp_rex64): Likewise.

	* config/i386/i386-protos.h (x86_64_load_64bit_split): New.

	* config/i386/ia32intrin.h: New.

	* config/i386/x86intrin.h: Include <ia32intrin.h>.

diff -x LAST_UPDATED -x REVISION -x gcc_update \
	 	-x ChangeLog.* -x .svn -upr \
	 	../gcc/gcc/gcc gcc/gcc
diff -x LAST_UPDATED -x REVISION -x gcc_update -x 'ChangeLog.*' -x .svn -upr ../gcc/gcc/gcc/config/i386/i386.c gcc/gcc/config/i386/i386.c
--- ../gcc/gcc/gcc/config/i386/i386.c	2009-06-10 06:01:50.000000000 -0700
+++ gcc/gcc/config/i386/i386.c	2009-06-10 04:20:10.000000000 -0700
@@ -20746,6 +20746,20 @@ 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_ROLSI,
+  IX86_BUILTIN_ROLDI,
+  IX86_BUILTIN_RORQI,
+  IX86_BUILTIN_RORHI,
+  IX86_BUILTIN_RORSI,
+  IX86_BUILTIN_RORDI,
+
   /* SSE3.  */
   IX86_BUILTIN_ADDSUBPS,
   IX86_BUILTIN_HADDPS,
@@ -21448,6 +21462,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,
@@ -21493,6 +21509,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,
@@ -21600,9 +21619,13 @@ enum ix86_builtin_type
   V1DI_FTYPE_V2SI_V2SI,
   V1DI_FTYPE_V1DI_SI_COUNT,
   UINT64_FTYPE_UINT64_UINT64,
+  UINT64_FTYPE_UINT64_INT,
   UINT_FTYPE_UINT_UINT,
   UINT_FTYPE_UINT_USHORT,
   UINT_FTYPE_UINT_UCHAR,
+  UINT_FTYPE_UINT_INT,
+  UINT16_FTYPE_UINT16_INT,
+  UINT8_FTYPE_UINT8_INT,
   V8HI_FTYPE_V8HI_INT,
   V4SI_FTYPE_V4SI_INT,
   V4HI_FTYPE_V4HI_INT,
@@ -21641,6 +21664,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 },
 
@@ -21721,6 +21747,18 @@ static const struct builtin_description 
 /* 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_rotlsi3, "__builtin_ia32_rolsi", IX86_BUILTIN_ROLSI, UNKNOWN, (int) UINT_FTYPE_UINT_INT },
+  { OPTION_MASK_ISA_64BIT, CODE_FOR_rotldi3, "__builtin_ia32_roldi", IX86_BUILTIN_ROLDI, UNKNOWN, (int) UINT64_FTYPE_UINT64_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 },
+  { ~OPTION_MASK_ISA_64BIT, CODE_FOR_rotrsi3, "__builtin_ia32_rorsi", IX86_BUILTIN_RORSI, UNKNOWN, (int) UINT_FTYPE_UINT_INT },
+  { OPTION_MASK_ISA_64BIT, CODE_FOR_rotrdi3, "__builtin_ia32_rordi", IX86_BUILTIN_RORDI, UNKNOWN, (int) UINT64_FTYPE_UINT64_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 },
@@ -23365,6 +23403,44 @@ 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 uint64_ftype_uint64_int
+    = build_function_type_list (long_long_unsigned_type_node,
+				long_long_unsigned_type_node,
+				integer_type_node,
+				NULL_TREE);
+  tree unsigned_ftype_unsigned_int
+    = build_function_type_list (unsigned_type_node,
+				unsigned_type_node,
+				integer_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.  */
@@ -23382,6 +23458,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;
@@ -23512,6 +23594,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;
@@ -23813,6 +23904,9 @@ ix86_init_mmx_sse_builtins (void)
 	case UINT64_FTYPE_UINT64_UINT64:
 	  type = uint64_ftype_uint64_uint64;
 	  break;
+	case UINT64_FTYPE_UINT64_INT:
+	  type = uint64_ftype_uint64_int;
+	  break;
 	case UINT_FTYPE_UINT_UINT:
 	  type = unsigned_ftype_unsigned_unsigned;
 	  break;
@@ -23822,6 +23916,15 @@ ix86_init_mmx_sse_builtins (void)
 	case UINT_FTYPE_UINT_UCHAR:
 	  type = unsigned_ftype_unsigned_uchar;
 	  break;
+	case UINT_FTYPE_UINT_INT:
+	  type = unsigned_ftype_unsigned_int;
+	  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;
@@ -24901,6 +25004,9 @@ ix86_expand_args_builtin (const struct b
       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:
@@ -25023,9 +25129,13 @@ ix86_expand_args_builtin (const struct b
       last_arg_count = true;
       break;
     case UINT64_FTYPE_UINT64_UINT64:
+    case UINT64_FTYPE_UINT64_INT:
     case UINT_FTYPE_UINT_UINT:
     case UINT_FTYPE_UINT_USHORT:
     case UINT_FTYPE_UINT_UCHAR:
+    case UINT_FTYPE_UINT_INT:
+    case UINT16_FTYPE_UINT16_INT:
+    case UINT8_FTYPE_UINT8_INT:
       nargs = 2;
       break;
     case V2DI2TI_FTYPE_V2DI_INT:
@@ -25270,6 +25380,12 @@ ix86_expand_special_args_builtin (const 
     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:
@@ -25392,6 +25508,9 @@ ix86_expand_special_args_builtin (const 
 
   switch (nargs)
     {
+    case 0:
+      pat = GEN_FCN (icode) (target);
+      break;
     case 1:
       pat = GEN_FCN (icode) (target, args[0].op);
       break;
@@ -30451,6 +30570,29 @@ ix86_enum_va_list (int idx, const char *
   return 1;
 }
 
+/* This function loads 64bit integer into REG from UNSPECV insn using
+   lower 32bits of 2 64bit registers.   */
+
+void
+x86_64_load_64bit_split (rtx reg, int unspecv)
+{
+  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);
+  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, reg, lower));
+}
+
 /* Initialize the GCC target structure.  */
 #undef TARGET_RETURN_IN_MEMORY
 #define TARGET_RETURN_IN_MEMORY ix86_return_in_memory
diff -x LAST_UPDATED -x REVISION -x gcc_update -x 'ChangeLog.*' -x .svn -upr ../gcc/gcc/gcc/config/i386/i386.md gcc/gcc/config/i386/i386.md
--- ../gcc/gcc/gcc/config/i386/i386.md	2009-06-10 06:01:50.000000000 -0700
+++ gcc/gcc/config/i386/i386.md	2009-06-10 04:20:10.000000000 -0700
@@ -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,6 +16156,15 @@
    (set_attr "type" "bitmanip")
    (set_attr "mode" "SI")])
 
+(define_expand "bsr"
+  [(parallel
+    [(set (match_operand:SI 0 "register_operand" "")
+	  (minus:SI (const_int 31)
+		    (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
+     (clobber (reg:CC FLAGS_REG))])]
+  ""
+  "")
+
 (define_insn "*bsr"
   [(set (match_operand:SI 0 "register_operand" "=r")
 	(minus:SI (const_int 31)
@@ -16338,6 +16350,15 @@
    (set_attr "type" "bitmanip")
    (set_attr "mode" "DI")])
 
+(define_expand "bsr_rex64"
+  [(parallel
+    [(set (match_operand:DI 0 "register_operand" "")
+	  (minus:DI (const_int 63)
+	  (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
+     (clobber (reg:CC FLAGS_REG))])]
+  "TARGET_64BIT"
+  "")
+
 (define_insn "*bsr_rex64"
   [(set (match_operand:DI 0 "register_operand" "=r")
 	(minus:DI (const_int 63)
@@ -22670,6 +22691,164 @@
    (set_attr "prefix_extra" "1")
    (set_attr "mode" "DI")])
 
+(define_expand "rdpmc"
+  [(parallel [(set (match_operand:DI 0 "register_operand" "")
+		   (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))
+  	      (unspec_volatile [(match_operand:SI 1 "nonimmediate_operand" "")] UNSPECV_RDPMC)])]
+  ""
+{
+  rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
+				    gen_rtvec (1, const0_rtx),
+				    UNSPECV_RDPMC);
+  rtx reg = gen_reg_rtx (DImode);
+  rtx si;
+
+  operands[1] = force_reg (SImode, operands[1]);
+  si = gen_rtx_UNSPEC_VOLATILE (VOIDmode,
+				gen_rtvec (1, operands[1]),
+				UNSPECV_RDPMC);
+
+  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) = 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) = si;
+      emit_insn (load);
+    }
+  emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
+  DONE;
+})
+
+(define_insn "*rdpmc"
+  [(parallel [(set (match_operand:DI 0 "register_operand" "=A")
+		   (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))
+  	      (unspec_volatile [(match_operand:SI 1 "register_operand" "c")] UNSPECV_RDPMC)])]
+  "!TARGET_64BIT"
+  "rdpmc"
+  [(set_attr "type" "other")
+   (set_attr "length" "2")])
+
+(define_insn "*rdpmc_rex64"
+  [(parallel [(set (match_operand:DI 0 "register_operand" "=a")
+		   (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))
+	      (set (match_operand:DI 1 "register_operand" "=d")
+		   (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))
+  	      (unspec_volatile [(match_operand:SI 2 "register_operand" "c")] 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)
+    {
+      x86_64_load_64bit_split (operands[0], UNSPECV_RDTSC);
+      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"
+  [(parallel [(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"
+  [(parallel [(set (match_operand:DI 0 "register_operand" "")
+		   (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
+	      (set (match_operand:SI 1 "memory_operand" "")
+		   (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))])]
+  ""
+{
+  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"
+  [(parallel [(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"
+  [(parallel [(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 -x LAST_UPDATED -x REVISION -x gcc_update -x 'ChangeLog.*' -x .svn -upr ../gcc/gcc/gcc/config/i386/i386-protos.h gcc/gcc/config/i386/i386-protos.h
--- ../gcc/gcc/gcc/config/i386/i386-protos.h	2009-05-15 09:40:00.000000000 -0700
+++ gcc/gcc/config/i386/i386-protos.h	2009-06-03 14:42:48.000000000 -0700
@@ -264,6 +264,8 @@ extern void x86_output_aligned_bss (FILE
 extern void x86_elf_aligned_common (FILE *, const char *,
 				    unsigned HOST_WIDE_INT, int);
 
+extern void x86_64_load_64bit_split (rtx, int);
+
 #ifdef RTX_CODE
 extern void ix86_fp_comparison_codes (enum rtx_code code, enum rtx_code *,
 				      enum rtx_code *, enum rtx_code *);
Only in gcc/gcc/config/i386: ia32intrin.h
diff -x LAST_UPDATED -x REVISION -x gcc_update -x 'ChangeLog.*' -x .svn -upr ../gcc/gcc/gcc/config/i386/x86intrin.h gcc/gcc/config/i386/x86intrin.h
--- ../gcc/gcc/gcc/config/i386/x86intrin.h	2009-05-05 10:18:54.000000000 -0700
+++ gcc/gcc/config/i386/x86intrin.h	2009-05-12 07:21:43.000000000 -0700
@@ -24,6 +24,8 @@
 #ifndef _X86INTRIN_H_INCLUDED
 #define _X86INTRIN_H_INCLUDED
 
+#include <ia32intrin.h>
+
 #ifdef __MMX__
 #include <mmintrin.h>
 #endif
diff -x LAST_UPDATED -x REVISION -x gcc_update -x 'ChangeLog.*' -x .svn -upr ../gcc/gcc/gcc/config.gcc gcc/gcc/config.gcc
--- ../gcc/gcc/gcc/config.gcc	2009-06-10 06:02:03.000000000 -0700
+++ gcc/gcc/config.gcc	2009-06-10 03:02:14.000000000 -0700
@@ -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-*-*)
--- /dev/null	2009-05-26 14:15:31.001012594 -0700
+++ gcc/gcc/config/i386/ia32intrin.h	2009-05-12 15:56:06.000000000 -0700
@@ -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 __builtin_ia32_rolsi (__X, __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 __builtin_ia32_rorsi (__X, __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 __builtin_ia32_roldi (__X, __C);
+}
+
+/* 64bit ror */
+extern __inline unsigned long long
+__attribute__((__gnu_inline__, __always_inline__, __artificial__))
+__rorq (unsigned long long __X, int __C)
+{
+  return __builtin_ia32_rordi (__X, __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 Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]