This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH, i386]: Fix PR target/38222: Problems with popcnt on Darwin targets
- From: Uros Bizjak <ubizjak at gmail dot com>
- To: GCC Patches <gcc-patches at gcc dot gnu dot org>
- Date: Sat, 22 Nov 2008 15:16:52 +0100
- Subject: [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" "")))]