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, i386]: Fix PR target/38222: Problems with popcnt on Darwin targets


Hello!

This patch generates popcnt insn mnemonic without mode extensions on Darwin x86 targets due to apple as bug. Since gnu as supports popcnt mnemonic with and without extensions, just default to "no-extensions" mode on Darwin.

Patch was bootstrapped and regression tested on x86_64-pc-linux-gnu and manually checked on x86 Darwin crosscompiler.

2008-11-22 Uros Bizjak <ubizjak@gmail.com>

   PR target/38222
   * config/i386/i386.md (SWI248): New mode iterator.
   (SWI32): Remove mode iterator.
   (popcount<mode>2): Rename from popcounthi2, popcountsi2 and
   popcounthi2 insn patterns. Macroize pattern using SWI248 mode
   iterator.  Generate popcnt mnemonic without mode extensions
   for Darwin x86 targets.
   (*popcount<mode>2_cmp): Ditto.
   (*popcountsi2_cmp_zext): Generate popcnt mnemonic without mode
   extensions for Darwin x86 targets.

testsuite/ChangeLog:
2008-11-22 Uros Bizjak <ubizjak@gmail.com>


   PR target/38222
   * gcc.target/i386/funcspec-3.c: Scan for popcnt on Darwin targets.

Uros.
Index: testsuite/gcc.target/i386/funcspec-3.c
===================================================================
--- testsuite/gcc.target/i386/funcspec-3.c	(revision 142117)
+++ testsuite/gcc.target/i386/funcspec-3.c	(working copy)
@@ -59,8 +59,9 @@
   exit (0);
 }
 
-/* { dg-final { scan-assembler "popcntl" } } */
-/* { dg-final { scan-assembler "popcntq" } } */
+/* { dg-final { scan-assembler "popcntl" { target { ! *-*-darwin* } } } } */
+/* { dg-final { scan-assembler "popcntq" { target { ! *-*-darwin* } } } } */
+/* { dg-final { scan-assembler-times "popcnt" 2 { target *-*-darwin* } } } */
 /* { dg-final { scan-assembler "call\t(.*)sse4a_pop_i" } } */
 /* { dg-final { scan-assembler "call\t(.*)sse42_pop_l" } } */
 /* { dg-final { scan-assembler "call\t(.*)popcountdi2" } } */
Index: config/i386/i386.md
===================================================================
--- config/i386/i386.md	(revision 142117)
+++ config/i386/i386.md	(working copy)
@@ -652,8 +652,8 @@
 ;; All single word integer modes.
 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
 
-;; Single word integer modes up to SImode.
-(define_mode_iterator SWI32 [QI HI SI])
+;; Single word integer modes without QImode.
+(define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
 
 ;; Instruction suffix for integer modes.
 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
@@ -15493,28 +15493,42 @@
   [(set_attr "prefix_0f" "1")
    (set_attr "mode" "SI")])
 
-(define_insn "popcountsi2"
-  [(set (match_operand:SI 0 "register_operand" "=r")
-	(popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
+(define_insn "popcount<mode>2"
+  [(set (match_operand:SWI248 0 "register_operand" "=r")
+	(popcount:SWI248
+	  (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
    (clobber (reg:CC FLAGS_REG))]
   "TARGET_POPCNT"
-  "popcnt{l}\t{%1, %0|%0, %1}"
+{
+#if TARGET_MACHO
+  return "popcnt\t{%1, %0|%0, %1}";
+#else
+  return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
+#endif
+}
   [(set_attr "prefix_rep" "1")
    (set_attr "type" "bitmanip")
-   (set_attr "mode" "SI")])
+   (set_attr "mode" "<MODE>")])
 
-(define_insn "*popcountsi2_cmp"
+(define_insn "*popcount<mode>2_cmp"
   [(set (reg FLAGS_REG)
 	(compare
-	  (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
+	  (popcount:SWI248
+	    (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
 	  (const_int 0)))
-   (set (match_operand:SI 0 "register_operand" "=r")
-	(popcount:SI (match_dup 1)))]
+   (set (match_operand:SWI248 0 "register_operand" "=r")
+	(popcount:SWI248 (match_dup 1)))]
   "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
-  "popcnt{l}\t{%1, %0|%0, %1}"
+{
+#if TARGET_MACHO
+  return "popcnt\t{%1, %0|%0, %1}";
+#else
+  return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
+#endif
+}
   [(set_attr "prefix_rep" "1")
    (set_attr "type" "bitmanip")
-   (set_attr "mode" "SI")])
+   (set_attr "mode" "<MODE>")])
 
 (define_insn "*popcountsi2_cmp_zext"
   [(set (reg FLAGS_REG)
@@ -15524,7 +15538,13 @@
    (set (match_operand:DI 0 "register_operand" "=r")
         (zero_extend:DI(popcount:SI (match_dup 1))))]
   "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
-  "popcnt{l}\t{%1, %0|%0, %1}"
+{
+#if TARGET_MACHO
+  return "popcnt\t{%1, %0|%0, %1}";
+#else
+  return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
+#endif
+}
   [(set_attr "prefix_rep" "1")
    (set_attr "type" "bitmanip")
    (set_attr "mode" "SI")])
@@ -15620,29 +15640,6 @@
   [(set_attr "prefix_0f" "1")
    (set_attr "mode" "DI")])
 
-(define_insn "popcountdi2"
-  [(set (match_operand:DI 0 "register_operand" "=r")
-	(popcount:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
-   (clobber (reg:CC FLAGS_REG))]
-  "TARGET_64BIT && TARGET_POPCNT"
-  "popcnt{q}\t{%1, %0|%0, %1}"
-  [(set_attr "prefix_rep" "1")
-   (set_attr "type" "bitmanip")
-   (set_attr "mode" "DI")])
-
-(define_insn "*popcountdi2_cmp"
-  [(set (reg FLAGS_REG)
-	(compare
-	  (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))
-	  (const_int 0)))
-   (set (match_operand:DI 0 "register_operand" "=r")
-	(popcount:DI (match_dup 1)))]
-  "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
-  "popcnt{q}\t{%1, %0|%0, %1}"
-  [(set_attr "prefix_rep" "1")
-   (set_attr "type" "bitmanip")
-   (set_attr "mode" "DI")])
-
 (define_expand "clzhi2"
   [(parallel
      [(set (match_operand:HI 0 "register_operand" "")
@@ -15681,29 +15678,6 @@
   [(set_attr "prefix_0f" "1")
    (set_attr "mode" "HI")])
 
-(define_insn "popcounthi2"
-  [(set (match_operand:HI 0 "register_operand" "=r")
-	(popcount:HI (match_operand:HI 1 "nonimmediate_operand" "rm")))
-   (clobber (reg:CC FLAGS_REG))]
-  "TARGET_POPCNT"
-  "popcnt{w}\t{%1, %0|%0, %1}"
-  [(set_attr "prefix_rep" "1")
-   (set_attr "type" "bitmanip")
-   (set_attr "mode" "HI")])
-
-(define_insn "*popcounthi2_cmp"
-  [(set (reg FLAGS_REG)
-        (compare
-          (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))
-          (const_int 0)))
-   (set (match_operand:HI 0 "register_operand" "=r")
-        (popcount:HI (match_dup 1)))]
-  "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
-  "popcnt{w}\t{%1, %0|%0, %1}"
-  [(set_attr "prefix_rep" "1")
-   (set_attr "type" "bitmanip")
-   (set_attr "mode" "HI")])
-
 (define_expand "paritydi2"
   [(set (match_operand:DI 0 "register_operand" "")
 	(parity:DI (match_operand:DI 1 "register_operand" "")))]

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]