PATCH: Support -mmovbe

H.J. Lu hjl.tools@gmail.com
Thu May 21 18:10:00 GMT 2009


On Thu, May 21, 2009 at 10:38 AM, Uros Bizjak <ubizjak@gmail.com> wrote:
> H.J. Lu wrote:
>
>>>>> +(define_insn "*movbedi2"
>>>>> + �[(set (match_operand:DI 0 "nonimmediate_operand" "=r,m")
>>>>> + � � � (bswap:DI (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
>>>>> + �"TARGET_MOVBE && TARGET_64BIT"
>>>>> + �"movbe\t{%1, %0|%0, %1}"
>>>>> + �[(set_attr "type" "imov")
>>>>> + � (set_attr "modrm" "1")
>>>>> + � (set_attr "prefix_0f" "1")
>>>>> + � (set_attr "prefix_extra" "1")
>>>>> + � (set_attr "mode" "DI")])
>>>>>
>>>>
>>>> Also the pattern above; it should be integrated with existing bswapdi2.
>>>>
>>>
>>> movbe doesn't support "movbe reg, reg".
>>>
>
> Sure, but attached patch automatically emits bswap in this case.
>
>> It is much cleaner to have a separate pattern since expander is
>>
>
> The constraints on expanders are actually not that important. The
> constraints on the insns pattern operands are what matters, and combine does
> a great job to merge memory operands whenever it can.
>>
>> (define_expand "bswapsi2"
>>  [(set (match_operand:SI 0 "register_operand" "")
>>        (bswap:SI (match_operand:SI 1 "register_operand" "")))]
>>
>> The new movbe pattern will be used optimizer.
>>
>
> Please see attached i386.md part of the patch. The patch assumes that
> TARGET_MOVBE also supports bswap insn, so following part is not needed
> anymore:
>
> +  /* Enable bswap if movbe is enabled.  */
> +  if (TARGET_MOVBE)
> +    TARGET_BSWAP = 1;
> +
>
>
> BTW: the patch uses shadowing to select between two patterns.
>

Here is the updated patch.  There is no need to check TARGET_BSWAP
for TARGET_64BIT.  OK for trunk?

Thanks.

-- 
H.J.
---
gcc/

2009-05-21  H.J. Lu  <hongjiu.lu@intel.com>
	    Uros Bizjak  <ubizjak@gmail.com>

	* config/i386/cpuid.h (bit_MOVBE): New.

	* config/i386/driver-i386.c (host_detect_local_cpu): Check movbe.

	* config/i386/i386.c (OPTION_MASK_ISA_MOVBE_SET): New.
	(OPTION_MASK_ISA_MOVBE_UNSET): Likewise.
	(ix86_handle_option): Handle OPT_mmovbe.
	(ix86_target_string): Add -mmovbe.
	(pta_flags): Add PTA_MOVBE.
	(processor_alias_table): Add PTA_MOVBE to "atom".
	(override_options): Handle PTA_MOVBE.

	* config/i386/i386.h (TARGET_MOVBE): New.

	* config/i386/i386.md (bswapsi2): Check TARGET_MOVBE.
	(*bswapsi_movbe): New.
        (*bswapdi_movbe): Likewise.
	(bswapdi2): Renamed to ...
	(*bswapdi_1): This.
	(bswapdi2): New expander.

	* config/i386/i386.opt (mmovbe): New.

	* doc/invoke.texi: Document -mmovbe.

gcc/testsuite/

2009-05-21  H.J. Lu  <hongjiu.lu@intel.com>

 	* gcc.target/i386/movbe-1.c: New.
	* gcc.target/i386/movbe-2.c: Likewise.
-------------- next part --------------
gcc/

2009-05-21  H.J. Lu  <hongjiu.lu@intel.com>
	    Uros Bizjak  <ubizjak@gmail.com>

	* config/i386/cpuid.h (bit_MOVBE): New.

	* config/i386/driver-i386.c (host_detect_local_cpu): Check movbe.

	* config/i386/i386.c (OPTION_MASK_ISA_MOVBE_SET): New.
	(OPTION_MASK_ISA_MOVBE_UNSET): Likewise.
	(ix86_handle_option): Handle OPT_mmovbe.
	(ix86_target_string): Add -mmovbe.
	(pta_flags): Add PTA_MOVBE.
	(processor_alias_table): Add PTA_MOVBE to "atom".
	(override_options): Handle PTA_MOVBE.

	* config/i386/i386.h (TARGET_MOVBE): New.

	* config/i386/i386.md (bswapsi2): Check TARGET_MOVBE.
	(*bswapsi_movbe): New.
	(*bswapdi_movbe): Likewise.
	(bswapdi2): Renamed to ...
	(*bswapdi_1): This.
	(bswapdi2): New expander.

	* config/i386/i386.opt (mmovbe): New.

	* doc/invoke.texi: Document -mmovbe.

gcc/testsuite/

2009-05-21  H.J. Lu  <hongjiu.lu@intel.com>
 
 	* gcc.target/i386/movbe-1.c: New.
	* gcc.target/i386/movbe-2.c: Likewise.

--- gcc/config/i386/cpuid.h.movbe	2009-04-09 09:36:18.000000000 -0700
+++ gcc/config/i386/cpuid.h	2009-05-20 11:41:55.000000000 -0700
@@ -29,6 +29,7 @@
 #define bit_CMPXCHG16B	(1 << 13)
 #define bit_SSE4_1	(1 << 19)
 #define bit_SSE4_2	(1 << 20)
+#define bit_MOVBE	(1 << 22)
 #define bit_POPCNT	(1 << 23)
 #define bit_AES		(1 << 25)
 #define bit_XSAVE	(1 << 26)
--- gcc/config/i386/driver-i386.c.movbe	2009-05-20 11:36:52.000000000 -0700
+++ gcc/config/i386/driver-i386.c	2009-05-20 11:54:53.000000000 -0700
@@ -378,6 +378,7 @@ const char *host_detect_local_cpu (int a
   /* Extended features */
   unsigned int has_lahf_lm = 0, has_sse4a = 0;
   unsigned int has_longmode = 0, has_3dnowp = 0, has_3dnow = 0;
+  unsigned int has_movbe = 0;
 
   bool arch;
 
@@ -415,6 +416,7 @@ const char *host_detect_local_cpu (int a
   has_sse3 = ecx & bit_SSE3;
   has_ssse3 = ecx & bit_SSSE3;
   has_cmpxchg16b = ecx & bit_CMPXCHG16B;
+  has_movbe = ecx & bit_MOVBE;
 
   has_cmpxchg8b = edx & bit_CMPXCHG8B;
   has_cmov = edx & bit_CMOV;
@@ -601,6 +603,8 @@ const char *host_detect_local_cpu (int a
 	options = concat (options, "-mcx16 ", NULL);
       if (has_lahf_lm)
 	options = concat (options, "-msahf ", NULL);
+      if (has_movbe)
+	options = concat (options, "-mmovbe", NULL);
     }
 
 done:
--- gcc/config/i386/i386.c.movbe	2009-05-20 06:58:59.000000000 -0700
+++ gcc/config/i386/i386.c	2009-05-21 10:59:36.000000000 -0700
@@ -1965,9 +1965,11 @@ static int ix86_isa_flags_explicit;
 
 #define OPTION_MASK_ISA_ABM_SET \
   (OPTION_MASK_ISA_ABM | OPTION_MASK_ISA_POPCNT)
+
 #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
+#define OPTION_MASK_ISA_MOVBE_SET OPTION_MASK_ISA_MOVBE
 
 /* Define a set of ISAs which aren't available when a given ISA is
    disabled.  MMX and SSE ISAs are handled separately.  */
@@ -2009,6 +2011,7 @@ static int ix86_isa_flags_explicit;
 #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
+#define OPTION_MASK_ISA_MOVBE_UNSET OPTION_MASK_ISA_MOVBE
 
 /* Vectorization library interface and handlers.  */
 tree (*ix86_veclib_handler)(enum built_in_function, tree, tree) = NULL;
@@ -2299,6 +2302,19 @@ ix86_handle_option (size_t code, const c
 	}
       return true;
 
+    case OPT_mmovbe:
+      if (value)
+	{
+	  ix86_isa_flags |= OPTION_MASK_ISA_MOVBE_SET;
+	  ix86_isa_flags_explicit |= OPTION_MASK_ISA_MOVBE_SET;
+	}
+      else
+	{
+	  ix86_isa_flags &= ~OPTION_MASK_ISA_MOVBE_UNSET;
+	  ix86_isa_flags_explicit |= OPTION_MASK_ISA_MOVBE_UNSET;
+	}
+      return true;
+
     case OPT_maes:
       if (value)
 	{
@@ -2361,6 +2377,7 @@ ix86_target_string (int isa, int flags, 
     { "-mmmx",		OPTION_MASK_ISA_MMX },
     { "-mabm",		OPTION_MASK_ISA_ABM },
     { "-mpopcnt",	OPTION_MASK_ISA_POPCNT },
+    { "-mmovbe",	OPTION_MASK_ISA_MOVBE },
     { "-maes",		OPTION_MASK_ISA_AES },
     { "-mpclmul",	OPTION_MASK_ISA_PCLMUL },
   };
@@ -2577,7 +2594,8 @@ override_options (bool main_args_p)
       PTA_AES = 1 << 17,
       PTA_PCLMUL = 1 << 18,
       PTA_AVX = 1 << 19,
-      PTA_FMA = 1 << 20 
+      PTA_FMA = 1 << 20,
+      PTA_MOVBE = 1 << 21
     };
 
   static struct pta
@@ -2621,7 +2639,7 @@ override_options (bool main_args_p)
 	| PTA_SSSE3 | PTA_CX16},
       {"atom", PROCESSOR_ATOM, CPU_ATOM,
 	PTA_64BIT | PTA_MMX | PTA_SSE | PTA_SSE2 | PTA_SSE3
-	| PTA_SSSE3 | PTA_CX16},
+	| PTA_SSSE3 | PTA_CX16 | PTA_MOVBE},
       {"geode", PROCESSOR_GEODE, CPU_GEODE,
 	PTA_MMX | PTA_3DNOW | PTA_3DNOW_A |PTA_PREFETCH_SSE},
       {"k6", PROCESSOR_K6, CPU_K6, PTA_MMX},
@@ -2935,6 +2953,9 @@ override_options (bool main_args_p)
 	if (!(TARGET_64BIT && (processor_alias_table[i].flags & PTA_NO_SAHF))
 	    && !(ix86_isa_flags_explicit & OPTION_MASK_ISA_SAHF))
 	  ix86_isa_flags |= OPTION_MASK_ISA_SAHF;
+	if (processor_alias_table[i].flags & PTA_MOVBE
+	    && !(ix86_isa_flags_explicit & OPTION_MASK_ISA_MOVBE))
+	  ix86_isa_flags |= OPTION_MASK_ISA_MOVBE;
 	if (processor_alias_table[i].flags & PTA_AES
 	    && !(ix86_isa_flags_explicit & OPTION_MASK_ISA_AES))
 	  ix86_isa_flags |= OPTION_MASK_ISA_AES;
--- gcc/config/i386/i386.h.movbe	2009-05-19 09:48:04.000000000 -0700
+++ gcc/config/i386/i386.h	2009-05-20 11:49:20.000000000 -0700
@@ -59,6 +59,7 @@ see the files COPYING3 and COPYING.RUNTI
 #define TARGET_ABM	OPTION_ISA_ABM
 #define TARGET_POPCNT	OPTION_ISA_POPCNT
 #define TARGET_SAHF	OPTION_ISA_SAHF
+#define TARGET_MOVBE	OPTION_ISA_MOVBE
 #define TARGET_AES	OPTION_ISA_AES
 #define TARGET_PCLMUL	OPTION_ISA_PCLMUL
 #define TARGET_CMPXCHG16B OPTION_ISA_CX16
--- gcc/config/i386/i386.md.movbe	2009-05-19 09:48:04.000000000 -0700
+++ gcc/config/i386/i386.md	2009-05-21 11:04:51.000000000 -0700
@@ -15853,7 +15853,7 @@
 	(bswap:SI (match_operand:SI 1 "register_operand" "")))]
   ""
 {
-  if (!TARGET_BSWAP)
+  if (!(TARGET_BSWAP || TARGET_MOVBE))
     {
       rtx x = operands[0];
 
@@ -15865,6 +15865,21 @@
     }
 })
 
+(define_insn "*bswapsi_movbe"
+  [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,m")
+	(bswap:SI (match_operand:SI 1 "nonimmediate_operand" "0,m,r")))]
+  "TARGET_MOVBE && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
+  "@
+    bswap\t%0
+    movbe\t{%1, %0|%0, %1}
+    movbe\t{%1, %0|%0, %1}"
+  [(set_attr "type" "*,imov,imov")
+   (set_attr "modrm" "*,1,1")
+   (set_attr "prefix_0f" "1")
+   (set_attr "prefix_extra" "*,1,1")
+   (set_attr "length" "2,*,*")
+   (set_attr "mode" "SI")])
+
 (define_insn "*bswapsi_1"
   [(set (match_operand:SI 0 "register_operand" "=r")
 	(bswap:SI (match_operand:SI 1 "register_operand" "0")))]
@@ -15893,7 +15908,29 @@
   [(set_attr "length" "4")
    (set_attr "mode" "HI")])
 
-(define_insn "bswapdi2"
+(define_expand "bswapdi2"
+  [(set (match_operand:DI 0 "register_operand" "")
+	(bswap:DI (match_operand:DI 1 "register_operand" "")))]
+  "TARGET_64BIT"
+  "")
+
+(define_insn "*bswapdi_movbe"
+  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m")
+	(bswap:DI (match_operand:DI 1 "nonimmediate_operand" "0,m,r")))]
+  "TARGET_64BIT && TARGET_MOVBE
+   && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
+  "@
+    bswap\t%0
+    movbe\t{%1, %0|%0, %1}
+    movbe\t{%1, %0|%0, %1}"
+  [(set_attr "type" "*,imov,imov")
+   (set_attr "modrm" "*,1,1")
+   (set_attr "prefix_0f" "1")
+   (set_attr "prefix_extra" "*,1,1")
+   (set_attr "length" "3,*,*")
+   (set_attr "mode" "DI")])
+
+(define_insn "*bswapdi_1"
   [(set (match_operand:DI 0 "register_operand" "=r")
 	(bswap:DI (match_operand:DI 1 "register_operand" "0")))]
   "TARGET_64BIT"
--- gcc/config/i386/i386.opt.movbe	2009-03-28 08:39:48.000000000 -0700
+++ gcc/config/i386/i386.opt	2009-05-20 11:44:23.000000000 -0700
@@ -339,6 +339,10 @@ msahf
 Target Report Mask(ISA_SAHF) Var(ix86_isa_flags) VarExists Save
 Support code generation of sahf instruction in 64bit x86-64 code.
 
+mmovbe
+Target Report Mask(ISA_MOVBE) Var(ix86_isa_flags) VarExists Save
+Support code generation of movbe instruction.
+
 maes
 Target Report Mask(ISA_AES) Var(ix86_isa_flags) VarExists Save
 Support AES built-in functions and code generation
--- gcc/doc/invoke.texi.movbe	2009-05-19 13:15:47.000000000 -0700
+++ gcc/doc/invoke.texi	2009-05-20 12:51:41.000000000 -0700
@@ -577,7 +577,7 @@ Objective-C and Objective-C++ Dialects}.
 -mno-wide-multiply  -mrtd  -malign-double @gol
 -mpreferred-stack-boundary=@var{num}
 -mincoming-stack-boundary=@var{num}
--mcld -mcx16 -msahf -mrecip @gol
+-mcld -mcx16 -msahf -mmovbe -mrecip @gol
 -mmmx  -msse  -msse2 -msse3 -mssse3 -msse4.1 -msse4.2 -msse4 -mavx @gol
 -maes -mpclmul @gol
 -msse4a -m3dnow -mpopcnt -mabm -msse5 @gol
@@ -11458,6 +11458,11 @@ SAHF are load and store instructions, re
 In 64-bit mode, SAHF instruction is used to optimize @code{fmod}, @code{drem}
 or @code{remainder} built-in functions: see @ref{Other Builtins} for details.
 
+@item -mmovbe
+@opindex mmovbe
+This option will enable GCC to use movbe instruction to implement
+@code{__builtin_bswap32} and @code{__builtin_bswap64}.
+
 @item -mrecip
 @opindex mrecip
 This option will enable GCC to use RCPSS and RSQRTSS instructions (and their
--- gcc/testsuite/gcc.target/i386/movbe-1.c.movbe	2009-05-20 13:03:00.000000000 -0700
+++ gcc/testsuite/gcc.target/i386/movbe-1.c	2009-05-20 12:59:35.000000000 -0700
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mmovbe" } */
+
+extern int x;
+
+void
+foo (int i)
+{
+  x = __builtin_bswap32 (i);
+}
+
+int
+bar ()
+{
+  return __builtin_bswap32 (x);
+}
+
+/* { dg-final { scan-assembler-times "movbe\[ \t\]" 2 } } */
--- gcc/testsuite/gcc.target/i386/movbe-2.c.movbe	2009-05-20 13:03:02.000000000 -0700
+++ gcc/testsuite/gcc.target/i386/movbe-2.c	2009-05-20 13:02:41.000000000 -0700
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mmovbe" } */
+
+extern long long x;
+
+void
+foo (long long i)
+{
+  x = __builtin_bswap64 (i);
+}
+
+long long
+bar ()
+{
+  return __builtin_bswap64 (x);
+}
+
+/* { dg-final { scan-assembler-times "movbe\[ \t\]" 4 { target ilp32 } } } */
+/* { dg-final { scan-assembler-times "movbe\[ \t\]" 2 { target lp64 } } } */


More information about the Gcc-patches mailing list