From 0ad91047cd146c0f2e5a7589b2f11bb08fe1685b Mon Sep 17 00:00:00 2001
From: David Edelsohn <edelsohn@gnu.org>
Date: Mon, 19 Jul 1999 19:11:29 +0000
Subject: [PATCH] rs6000.md (arithmetic, [...]): Disable patterns performing
 SImode comparisons with SImode values if...

	* rs6000.md (arithmetic, logical, and shift Rc combiner patterns):
	Disable patterns performing SImode comparisons with SImode values
	if TARGET_POWERPC64 and instruction does not sign-extend or does
	not mask to narrower than SImode, i.e. where bit 31 and bit 63 may
	differ for signed quantities.
	(indirect_jump): Add expander to choose RTL based on TARGET_64BIT.
	(tablejump): Patterns contingent on TARGET_64BIT not TARGET_POWERPC64.
	(decrement_and_branch_on_count): Add 64-bit variant.

From-SVN: r28172
---
 gcc/ChangeLog               |  11 +
 gcc/config/rs6000/rs6000.md | 475 +++++++++++++++++++++++++++---------
 2 files changed, 370 insertions(+), 116 deletions(-)

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index e1e892a18706..dd689e275eb8 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,14 @@
+Mon Jul 19 15:09:29 1999  David Edelsohn  <edelsohn@gnu.org>
+
+	* rs6000.md (arithmetic, logical, and shift Rc combiner patterns):
+	Disable patterns performing SImode comparisons with SImode values
+	if TARGET_POWERPC64 and instruction does not sign-extend or does
+	not mask to narrower than SImode, i.e. where bit 31 and bit 63 may
+	differ for signed quantities.
+	(indirect_jump): Add expander to choose RTL based on TARGET_64BIT.
+	(tablejump): Patterns contingent on TARGET_64BIT not TARGET_POWERPC64.
+	(decrement_and_branch_on_count): Add 64-bit variant.
+
 Mon Jul 19 09:36:27 1999  Bernd Schmidt  <bernds@cygnus.co.uk>
 
 	* final.c (output_asm_insn): When searching for the matching string
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index 085db80462d8..d9e82a815a33 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -931,7 +931,7 @@
 			     (match_operand:SI 2 "reg_or_short_operand" "r,I,r,I"))
 		    (const_int 0)))
    (clobber (match_scratch:SI 3 "=r,r,r,r"))]
-  ""
+  "! TARGET_POWERPC64"
   "@
    {cax.|add.} %3,%1,%2
    {ai.|addic.} %3,%1,%2
@@ -946,7 +946,7 @@
 			     (match_operand:SI 2 "reg_or_short_operand" ""))
 		    (const_int 0)))
    (clobber (match_scratch:SI 3 ""))]
-  "reload_completed"
+  "! TARGET_POWERPC64 && reload_completed"
   [(set (match_dup 3)
 	(plus:SI (match_dup 1)
 		 (match_dup 2)))
@@ -963,7 +963,7 @@
    (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r")
 	(plus:SI (match_dup 1)
 		 (match_dup 2)))]
-  ""
+  "! TARGET_POWERPC64"
   "@
    {cax.|add.} %0,%1,%2
    {ai.|addic.} %0,%1,%2
@@ -979,7 +979,7 @@
 		    (const_int 0)))
    (set (match_operand:SI 0 "gpc_reg_operand" "")
 	(plus:SI (match_dup 1) (match_dup 2)))]
-  "reload_completed"
+  "! TARGET_POWERPC64 && reload_completed"
   [(set (match_dup 0)
 	(plus:SI (match_dup 1)
 		 (match_dup 2)))
@@ -1022,7 +1022,7 @@
 	(compare:CC (not:SI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
 		    (const_int 0)))
    (clobber (match_scratch:SI 2 "=r,r"))]
-  ""
+  "! TARGET_POWERPC64"
   "@
    nor. %2,%1,%1
    #"
@@ -1034,7 +1034,7 @@
 	(compare:CC (not:SI (match_operand:SI 1 "gpc_reg_operand" ""))
 		    (const_int 0)))
    (clobber (match_scratch:SI 2 ""))]
-  "reload_completed"
+  "! TARGET_POWERPC64 && reload_completed"
   [(set (match_dup 2)
 	(not:SI (match_dup 1)))
    (set (match_dup 0)
@@ -1048,7 +1048,7 @@
 		    (const_int 0)))
    (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
 	(not:SI (match_dup 1)))]
-  ""
+  "! TARGET_POWERPC64"
   "@
    nor. %0,%1,%1
    #"
@@ -1061,7 +1061,7 @@
 		    (const_int 0)))
    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
 	(not:SI (match_dup 1)))]
-  "reload_completed"
+  "! TARGET_POWERPC64 && reload_completed"
   [(set (match_dup 0)
 	(not:SI (match_dup 1)))
    (set (match_dup 2)
@@ -1104,7 +1104,7 @@
 			      (match_operand:SI 2 "gpc_reg_operand" "r,r"))
 		    (const_int 0)))
    (clobber (match_scratch:SI 3 "=r,r"))]
-  "TARGET_POWERPC"
+  "TARGET_POWERPC && ! TARGET_POWERPC64"
   "@
    subf. %3,%2,%1
    #"
@@ -1117,7 +1117,7 @@
 			      (match_operand:SI 2 "gpc_reg_operand" ""))
 		    (const_int 0)))
    (clobber (match_scratch:SI 3 ""))]
-  "reload_completed"
+  "! TARGET_POWERPC64 && reload_completed"
   [(set (match_dup 3)
 	(minus:SI (match_dup 1)
 		  (match_dup 2)))
@@ -1148,7 +1148,7 @@
    (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
 	(minus:SI (match_dup 1)
 		  (match_dup 2)))]
-  "TARGET_POWERPC"
+  "TARGET_POWERPC && ! TARGET_POWERPC64"
   "@
    subf. %0,%2,%1
    #"
@@ -1163,7 +1163,7 @@
    (set (match_operand:SI 0 "gpc_reg_operand" "")
 	(minus:SI (match_dup 1)
 		  (match_dup 2)))]
-  "reload_completed"
+  "! TARGET_POWERPC64 && reload_completed"
   [(set (match_dup 0)
 	(minus:SI (match_dup 1)
 		  (match_dup 2)))
@@ -1324,7 +1324,7 @@
   ""
   "
 {
-  if (!TARGET_POWER)
+  if (! TARGET_POWER)
     {
       emit_insn (gen_abssi2_nopower (operands[0], operands[1]));
       DONE;
@@ -1341,7 +1341,7 @@
   [(set (match_operand:SI 0 "gpc_reg_operand" "=&r,r")
 	(abs:SI (match_operand:SI 1 "gpc_reg_operand" "r,0")))
    (clobber (match_scratch:SI 2 "=&r,&r"))]
-  "!TARGET_POWER"
+  "! TARGET_POWER"
   "*
 {
   return (TARGET_POWERPC)
@@ -1354,7 +1354,7 @@
   [(set (match_operand:SI 0 "gpc_reg_operand" "=&r,r")
 	(abs:SI (match_operand:SI 1 "gpc_reg_operand" "r,0")))
    (clobber (match_scratch:SI 2 "=&r,&r"))]
-  "!TARGET_POWER && reload_completed"
+  "! TARGET_POWER && reload_completed"
   [(set (match_dup 2) (ashiftrt:SI (match_dup 1) (const_int 31)))
    (set (match_dup 0) (xor:SI (match_dup 2) (match_dup 1)))
    (set (match_dup 0) (minus:SI (match_dup 0) (match_dup 2)))]
@@ -1370,7 +1370,7 @@
   [(set (match_operand:SI 0 "gpc_reg_operand" "=&r,r")
 	(neg:SI (abs:SI (match_operand:SI 1 "gpc_reg_operand" "r,0"))))
    (clobber (match_scratch:SI 2 "=&r,&r"))]
-  "!TARGET_POWER"
+  "! TARGET_POWER"
   "*
 {
   return (TARGET_POWERPC)
@@ -1383,7 +1383,7 @@
   [(set (match_operand:SI 0 "gpc_reg_operand" "=&r,r")
 	(neg:SI (abs:SI (match_operand:SI 1 "gpc_reg_operand" "r,0"))))
    (clobber (match_scratch:SI 2 "=&r,&r"))]
-  "!TARGET_POWER && reload_completed"
+  "! TARGET_POWER && reload_completed"
   [(set (match_dup 2) (ashiftrt:SI (match_dup 1) (const_int 31)))
    (set (match_dup 0) (xor:SI (match_dup 2) (match_dup 1)))
    (set (match_dup 0) (minus:SI (match_dup 2) (match_dup 0)))]
@@ -1400,7 +1400,7 @@
 	(compare:CC (neg:SI (match_operand:SI 1 "gpc_reg_operand" "r"))
 		    (const_int 0)))
    (clobber (match_scratch:SI 2 "=r"))]
-  ""
+  "! TARGET_POWERPC64"
   "neg. %2,%1"
   [(set_attr "type" "compare")])
 
@@ -1410,7 +1410,7 @@
 		    (const_int 0)))
    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
 	(neg:SI (match_dup 1)))]
-  ""
+  "! TARGET_POWERPC64"
   "neg. %0,%1"
   [(set_attr "type" "compare")])
 
@@ -1874,7 +1874,7 @@
 		    (const_int 0)))
    (clobber (match_scratch:SI 3 "=r,r,r,r,r,r,r,r"))
    (clobber (match_scratch:CC 4 "=X,X,X,X,X,x,x,X"))]
-  ""
+  "! TARGET_POWERPC64"
   "@
    and. %3,%1,%2
    {andil.|andi.} %3,%1,%b2
@@ -1894,7 +1894,7 @@
 		    (const_int 0)))
    (clobber (match_scratch:SI 3 ""))
    (clobber (match_scratch:CC 4 ""))]
-  "reload_completed"
+  "! TARGET_POWERPC64 && reload_completed"
   [(parallel [(set (match_dup 3)
 		   (and:SI (match_dup 1)
 			   (match_dup 2)))
@@ -1913,7 +1913,7 @@
 	(and:SI (match_dup 1)
 		(match_dup 2)))
    (clobber (match_scratch:CC 4 "=X,X,X,X,X,x,x,X"))]
-  ""
+  "! TARGET_POWERPC64"
   "@
    and. %0,%1,%2
    {andil.|andi.} %0,%1,%b2
@@ -1935,7 +1935,7 @@
 	(and:SI (match_dup 1)
 		(match_dup 2)))
    (clobber (match_scratch:CC 4 ""))]
-  "reload_completed"
+  "! TARGET_POWERPC64 && reload_completed"
   [(parallel [(set (match_dup 0)
 		   (and:SI (match_dup 1)
 			   (match_dup 2)))
@@ -1983,7 +1983,7 @@
 			    (match_operand:SI 2 "gpc_reg_operand" "r,r"))
 		    (const_int 0)))
    (clobber (match_scratch:SI 3 "=r,r"))]
-  ""
+  "! TARGET_POWERPC64"
   "@
    or. %3,%1,%2
    #"
@@ -1996,7 +1996,7 @@
 			    (match_operand:SI 2 "gpc_reg_operand" ""))
 		    (const_int 0)))
    (clobber (match_scratch:SI 3 ""))]
-  "reload_completed"
+  "! TARGET_POWERPC64 && reload_completed"
   [(set (match_dup 3)
 	(ior:SI (match_dup 1)
 		(match_dup 2)))
@@ -2013,7 +2013,7 @@
    (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
 	(ior:SI (match_dup 1)
 		(match_dup 2)))]
-  ""
+  "! TARGET_POWERPC64"
   "@
    or. %0,%1,%2
    #"
@@ -2027,7 +2027,7 @@
 		    (const_int 0)))
    (set (match_operand:SI 0 "gpc_reg_operand" "")
 	(ior:SI (match_dup 1) (match_dup 2)))]
-  "reload_completed"
+  "! TARGET_POWERPC64 && reload_completed"
   [(set (match_dup 0)
 	(ior:SI (match_dup 1)
 		(match_dup 2)))
@@ -2090,7 +2090,7 @@
 			    (match_operand:SI 2 "gpc_reg_operand" "r,r"))
 		    (const_int 0)))
    (clobber (match_scratch:SI 3 "=r,r"))]
-  ""
+  "! TARGET_POWERPC64"
   "@
    xor. %3,%1,%2
    #"
@@ -2103,7 +2103,7 @@
 			    (match_operand:SI 2 "gpc_reg_operand" ""))
 		    (const_int 0)))
    (clobber (match_scratch:SI 3 ""))]
-  "reload_completed"
+  "! TARGET_POWERPC64 && reload_completed"
   [(set (match_dup 3)
 	(xor:SI (match_dup 1)
 		(match_dup 2)))
@@ -2120,7 +2120,7 @@
    (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
 	(xor:SI (match_dup 1)
 		(match_dup 2)))]
-  ""
+  "! TARGET_POWERPC64"
   "@
    xor. %0,%1,%2
    #"
@@ -2134,7 +2134,7 @@
 		    (const_int 0)))
    (set (match_operand:SI 0 "gpc_reg_operand" "")
 	(xor:SI (match_dup 1) (match_dup 2)))]
-  "reload_completed"
+  "! TARGET_POWERPC64 && reload_completed"
   [(set (match_dup 0)
 	(xor:SI (match_dup 1)
 		(match_dup 2)))
@@ -2172,7 +2172,7 @@
 				    (match_operand:SI 2 "gpc_reg_operand" "r,r")))
 		    (const_int 0)))
    (clobber (match_scratch:SI 3 "=r,r"))]
-   ""
+   "! TARGET_POWERPC64"
    "@
     eqv. %3,%1,%2
     #"
@@ -2185,7 +2185,7 @@
 				    (match_operand:SI 2 "gpc_reg_operand" "")))
 		    (const_int 0)))
    (clobber (match_scratch:SI 3 ""))]
-  "reload_completed"
+  "! TARGET_POWERPC64 && reload_completed"
   [(set (match_dup 3)
 	(not:SI (xor:SI (match_dup 1)
 			(match_dup 2))))
@@ -2201,7 +2201,7 @@
 		    (const_int 0)))
    (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
 	(not:SI (xor:SI (match_dup 1) (match_dup 2))))]
-   ""
+   "! TARGET_POWERPC64"
    "@
     eqv. %0,%1,%2
     #"
@@ -2216,7 +2216,7 @@
    (set (match_operand:SI 0 "gpc_reg_operand" "")
 	(not:SI (xor:SI (match_dup 1)
 			(match_dup 2))))]
-  "reload_completed"
+  "! TARGET_POWERPC64 && reload_completed"
   [(set (match_dup 0)
 	(not:SI (xor:SI (match_dup 1)
 			(match_dup 2))))
@@ -2238,7 +2238,7 @@
 			    (match_operand:SI 2 "gpc_reg_operand" "r,r"))
 		    (const_int 0)))
    (clobber (match_scratch:SI 3 "=r,r"))]
-  ""
+  "! TARGET_POWERPC64"
   "@
    andc. %3,%2,%1
    #"
@@ -2251,7 +2251,7 @@
 			    (match_operand:SI 2 "gpc_reg_operand" ""))
 		    (const_int 0)))
    (clobber (match_scratch:SI 3 ""))]
-  "reload_completed"
+  "! TARGET_POWERPC64 && reload_completed"
   [(set (match_dup 3)
 	(and:SI (not:SI (match_dup 1))
 		(match_dup 2)))
@@ -2268,7 +2268,7 @@
    (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
 	(and:SI (not:SI (match_dup 1))
 		(match_dup 2)))]
-  ""
+  "! TARGET_POWERPC64"
   "@
    andc. %0,%2,%1
    #"
@@ -2283,7 +2283,7 @@
    (set (match_operand:SI 0 "gpc_reg_operand" "")
 	(and:SI (not:SI (match_dup 1))
 		(match_dup 2)))]
-  "reload_completed"
+  "! TARGET_POWERPC64 && reload_completed"
   [(set (match_dup 0)
 	(and:SI (not:SI (match_dup 1))
 		(match_dup 2)))
@@ -2305,7 +2305,7 @@
 			    (match_operand:SI 2 "gpc_reg_operand" "r,r"))
 		    (const_int 0)))
    (clobber (match_scratch:SI 3 "=r,r"))]
-  ""
+  "! TARGET_POWERPC64"
   "@
    orc. %3,%2,%1
    #"
@@ -2318,7 +2318,7 @@
 			    (match_operand:SI 2 "gpc_reg_operand" ""))
 		    (const_int 0)))
    (clobber (match_scratch:SI 3 ""))]
-  "reload_completed"
+  "! TARGET_POWERPC64 && reload_completed"
   [(set (match_dup 3)
 	(ior:SI (not:SI (match_dup 1))
 		(match_dup 2)))
@@ -2334,7 +2334,7 @@
 		    (const_int 0)))
    (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
 	(ior:SI (not:SI (match_dup 1)) (match_dup 2)))]
-  ""
+  "! TARGET_POWERPC64"
   "@
    orc. %0,%2,%1
    #"
@@ -2348,7 +2348,7 @@
    (set (match_operand:SI 0 "gpc_reg_operand" "")
 	(ior:SI (not:SI (match_dup 1))
 		(match_dup 2)))]
-  "reload_completed"
+  "! TARGET_POWERPC64 && reload_completed"
   [(set (match_dup 0)
 	(ior:SI (not:SI (match_dup 1))
 		(match_dup 2)))
@@ -2370,7 +2370,7 @@
 			    (not:SI (match_operand:SI 2 "gpc_reg_operand" "r,r")))
 		    (const_int 0)))
    (clobber (match_scratch:SI 3 "=r,r"))]
-  ""
+  "! TARGET_POWERPC64"
   "@
    nand. %3,%1,%2
    #"
@@ -2383,7 +2383,7 @@
 			    (not:SI (match_operand:SI 2 "gpc_reg_operand" "")))
 		    (const_int 0)))
    (clobber (match_scratch:SI 3 ""))]
-  "reload_completed"
+  "! TARGET_POWERPC64 && reload_completed"
   [(set (match_dup 3)
 	(ior:SI (not:SI (match_dup 1))
 		(not:SI (match_dup 2))))
@@ -2400,7 +2400,7 @@
    (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
 	(ior:SI (not:SI (match_dup 1))
 		(not:SI (match_dup 2))))]
-  ""
+  "! TARGET_POWERPC64"
   "@
    nand. %0,%1,%2
    #"
@@ -2415,7 +2415,7 @@
    (set (match_operand:SI 0 "gpc_reg_operand" "")
 	(ior:SI (not:SI (match_dup 1))
 		(not:SI (match_dup 2))))]
-  "reload_completed"
+  "! TARGET_POWERPC64 && reload_completed"
   [(set (match_dup 0)
 	(ior:SI (not:SI (match_dup 1))
 		(not:SI (match_dup 2))))
@@ -2437,7 +2437,7 @@
 			    (not:SI (match_operand:SI 2 "gpc_reg_operand" "r,r")))
 		    (const_int 0)))
    (clobber (match_scratch:SI 3 "=r,r"))]
-  ""
+  "! TARGET_POWERPC64"
   "@
    nor. %3,%1,%2
    #"
@@ -2450,7 +2450,7 @@
 			    (not:SI (match_operand:SI 2 "gpc_reg_operand" "")))
 		    (const_int 0)))
    (clobber (match_scratch:SI 3 ""))]
-  "reload_completed"
+  "! TARGET_POWERPC64 && reload_completed"
   [(set (match_dup 3)
 	(and:SI (not:SI (match_dup 1))
 		(not:SI (match_dup 2))))
@@ -2467,7 +2467,7 @@
    (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
 	(and:SI (not:SI (match_dup 1))
 		(not:SI (match_dup 2))))]
-  ""
+  "! TARGET_POWERPC64"
   "@
    nor. %0,%1,%2
    #"
@@ -2482,7 +2482,7 @@
    (set (match_operand:SI 0 "gpc_reg_operand" "")
 	(and:SI (not:SI (match_dup 1))
 		(not:SI (match_dup 2))))]
-  "reload_completed"
+  "! TARGET_POWERPC64 && reload_completed"
   [(set (match_dup 0)
 	(and:SI (not:SI (match_dup 1))
 		(not:SI (match_dup 2))))
@@ -2594,10 +2594,10 @@
 ;; Rotate and shift insns, in all their variants.  These support shifts,
 ;; field inserts and extracts, and various combinations thereof.
 (define_expand "insv"
-  [(set (zero_extract (match_operand 0 "gpc_reg_operand" "+r")
-		       (match_operand:SI 1 "const_int_operand" "i")
-		       (match_operand:SI 2 "const_int_operand" "i"))
-	(match_operand 3 "gpc_reg_operand" "r"))]
+  [(set (zero_extract (match_operand 0 "gpc_reg_operand" "")
+		       (match_operand:SI 1 "const_int_operand" "")
+		       (match_operand:SI 2 "const_int_operand" ""))
+	(match_operand 3 "gpc_reg_operand" ""))]
   ""
   "
 {
@@ -2722,10 +2722,10 @@
 }")
 
 (define_expand "extzv"
-  [(set (match_operand 0 "gpc_reg_operand" "=r")
-	(zero_extract (match_operand 1 "gpc_reg_operand" "r")
-		       (match_operand:SI 2 "const_int_operand" "i")
-		       (match_operand:SI 3 "const_int_operand" "i")))]
+  [(set (match_operand 0 "gpc_reg_operand" "")
+	(zero_extract (match_operand 1 "gpc_reg_operand" "")
+		       (match_operand:SI 2 "const_int_operand" "")
+		       (match_operand:SI 3 "const_int_operand" "")))]
   ""
   "
 {
@@ -2768,7 +2768,7 @@
 			 (match_operand:SI 3 "const_int_operand" "i"))
 		    (const_int 0)))
    (clobber (match_scratch:SI 4 "=r"))]
-  ""
+  "! TARGET_POWERPC64"
   "*
 {
   int start = INTVAL (operands[3]) & 31;
@@ -2806,7 +2806,7 @@
 		    (const_int 0)))
    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
 	(zero_extract:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
-  ""
+  "! TARGET_POWERPC64"
   "*
 {
   int start = INTVAL (operands[3]) & 31;
@@ -2901,7 +2901,7 @@
 			       (match_operand:SI 2 "reg_or_cint_operand" "ri"))
 		    (const_int 0)))
    (clobber (match_scratch:SI 3 "=r"))]
-  ""
+  "! TARGET_POWERPC64"
   "{rl%I2nm.|rlw%I2nm.} %3,%1,%h2,0xffffffff"
   [(set_attr "type" "delayed_compare")])
 
@@ -2912,7 +2912,7 @@
 		    (const_int 0)))
    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
 	(rotate:SI (match_dup 1) (match_dup 2)))]
-  ""
+  "! TARGET_POWERPC64"
   "{rl%I2nm.|rlw%I2nm.} %0,%1,%h2,0xffffffff"
   [(set_attr "type" "delayed_compare")])
 
@@ -2932,7 +2932,7 @@
 		     (match_operand:SI 3 "mask_operand" "T"))
 		    (const_int 0)))
    (clobber (match_scratch:SI 4 "=r"))]
-  ""
+  "! TARGET_POWERPC64"
   "{rl%I2nm.|rlw%I2nm.} %4,%1,%h2,%m3,%M3"
   [(set_attr "type" "delayed_compare")])
 
@@ -2945,7 +2945,7 @@
 		    (const_int 0)))
    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
 	(and:SI (rotate:SI (match_dup 1) (match_dup 2)) (match_dup 3)))]
-  ""
+  "! TARGET_POWERPC64"
   "{rl%I2nm.|rlw%I2nm.} %0,%1,%h2,%m3,%M3"
   [(set_attr "type" "delayed_compare")])
 
@@ -3072,7 +3072,7 @@
 			       (match_operand:SI 2 "reg_or_cint_operand" "ri"))
 		    (const_int 0)))
    (clobber (match_scratch:SI 3 "=r"))]
-  "! TARGET_POWER"
+  "! TARGET_POWER && ! TARGET_POWERPC64"
   "{sl|slw}%I2. %3,%1,%h2"
   [(set_attr "type" "delayed_compare")])
 
@@ -3097,7 +3097,7 @@
 		    (const_int 0)))
    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
 	(ashift:SI (match_dup 1) (match_dup 2)))]
-  "! TARGET_POWER"
+  "! TARGET_POWER && ! TARGET_POWERPC64"
   "{sl|slw}%I2. %0,%1,%h2"
   [(set_attr "type" "delayed_compare")])
 
@@ -3117,7 +3117,7 @@
 		 (match_operand:SI 3 "mask_operand" "T"))
 	 (const_int 0)))
    (clobber (match_scratch:SI 4 "=r"))]
-  "includes_lshift_p (operands[2], operands[3])"
+  "! TARGET_POWERPC64 && includes_lshift_p (operands[2], operands[3])"
   "{rlinm.|rlwinm.} %4,%1,%h2,%m3,%M3"
   [(set_attr "type" "delayed_compare")])
 
@@ -3130,7 +3130,7 @@
 	 (const_int 0)))
    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
 	(and:SI (ashift:SI (match_dup 1) (match_dup 2)) (match_dup 3)))]
-  "includes_lshift_p (operands[2], operands[3])"
+  "! TARGET_POWERPC64 && includes_lshift_p (operands[2], operands[3])"
   "{rlinm.|rlwinm.} %0,%1,%h2,%m3,%M3"
   [(set_attr "type" "delayed_compare")])
 
@@ -3190,7 +3190,7 @@
 				 (match_operand:SI 2 "reg_or_cint_operand" "O,ri"))
 		    (const_int 0)))
    (clobber (match_scratch:SI 3 "=X,r"))]
-  "! TARGET_POWER"
+  "! TARGET_POWER && ! TARGET_POWERPC64"
   "@
    mr. %1,%1
    {sr|srw}%I2. %3,%1,%h2"
@@ -3218,7 +3218,7 @@
 		    (const_int 0)))
    (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
 	(lshiftrt:SI (match_dup 1) (match_dup 2)))]
-  "! TARGET_POWER"
+  "! TARGET_POWER && ! TARGET_POWERPC64"
   "@
    mr. %0,%1
    {sr|srw}%I2. %0,%1,%h2"
@@ -3240,7 +3240,7 @@
 		 (match_operand:SI 3 "mask_operand" "T"))
 	 (const_int 0)))
    (clobber (match_scratch:SI 4 "=r"))]
-  "includes_rshift_p (operands[2], operands[3])"
+  "! TARGET_POWERPC64 && includes_rshift_p (operands[2], operands[3])"
   "{rlinm.|rlwinm.} %4,%1,%s2,%m3,%M3"
   [(set_attr "type" "delayed_compare")])
 
@@ -3253,7 +3253,7 @@
 	 (const_int 0)))
    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
 	(and:SI (lshiftrt:SI (match_dup 1) (match_dup 2)) (match_dup 3)))]
-  "includes_rshift_p (operands[2], operands[3])"
+  "! TARGET_POWERPC64 && includes_rshift_p (operands[2], operands[3])"
   "{rlinm.|rlwinm.} %0,%1,%s2,%m3,%M3"
   [(set_attr "type" "delayed_compare")])
 
@@ -3745,10 +3745,10 @@
   "")
 
 (define_expand "movsfcc"
-   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
+   [(set (match_operand:SF 0 "gpc_reg_operand" "")
 	 (if_then_else:SF (match_operand 1 "comparison_operator" "")
-			  (match_operand:SF 2 "gpc_reg_operand" "f")
-			  (match_operand:SF 3 "gpc_reg_operand" "f")))]
+			  (match_operand:SF 2 "gpc_reg_operand" "")
+			  (match_operand:SF 3 "gpc_reg_operand" "")))]
   "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT"
   "
 {
@@ -3992,10 +3992,10 @@
   "")
 
 (define_expand "movdfcc"
-   [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
+   [(set (match_operand:DF 0 "gpc_reg_operand" "")
 	 (if_then_else:DF (match_operand 1 "comparison_operator" "")
-			  (match_operand:DF 2 "gpc_reg_operand" "f")
-			  (match_operand:DF 3 "gpc_reg_operand" "f")))]
+			  (match_operand:DF 2 "gpc_reg_operand" "")
+			  (match_operand:DF 3 "gpc_reg_operand" "")))]
   "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT"
   "
 {
@@ -5775,14 +5775,14 @@
 (define_insn "elf_high"
   [(set (match_operand:SI 0 "gpc_reg_operand" "=b")
 	(high:SI (match_operand 1 "" "")))]
-  "TARGET_ELF && !TARGET_64BIT"
+  "TARGET_ELF && ! TARGET_64BIT"
   "{liu|lis} %0,%1@ha")
 
 (define_insn "elf_low"
   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
 	(lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
 		   (match_operand 2 "" "")))]
-   "TARGET_ELF && !TARGET_64BIT"
+   "TARGET_ELF && ! TARGET_64BIT"
    "{cal|la} %0,%2@l(%1)")
 
 ;; Set up a register with a value from the GOT table
@@ -6015,7 +6015,7 @@
 	(compare:CC (match_operand:SI 1 "gpc_reg_operand" "r")
 		    (const_int 0)))
    (set (match_operand:SI 0 "gpc_reg_operand" "=r") (match_dup 1))]
-  ""
+  "! TARGET_POWERPC64"
   "mr. %0,%1"
   [(set_attr "type" "compare")])
 
@@ -6896,7 +6896,7 @@
   [(set (match_operand:TI 0 "reg_or_mem_operand" "=m,????r,????r")
 	(match_operand:TI 1 "reg_or_mem_operand" "r,r,m"))
    (clobber (match_scratch:SI 2 "=X,X,X"))]
-  "TARGET_STRING && !TARGET_POWER && ! TARGET_POWERPC64
+  "TARGET_STRING && ! TARGET_POWER && ! TARGET_POWERPC64
    && (gpc_reg_operand (operands[0], TImode) || gpc_reg_operand (operands[1], TImode))"
   "*
 {
@@ -7126,7 +7126,7 @@
 		   [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
 			 (match_operand:SI 2 "gpc_reg_operand" "r"))
 		    (clobber (match_scratch:SI 3 "X"))])]
-  "TARGET_STRING && !TARGET_POWER"
+  "TARGET_STRING && ! TARGET_POWER"
   "{stsi|stswi} %2,%1,%O0"
   [(set_attr "type" "store")])
 
@@ -7207,7 +7207,7 @@
    (clobber (reg:SI 11))
    (clobber (reg:SI 12))
    (clobber (match_scratch:SI 5 "X"))]
-  "TARGET_STRING && !TARGET_POWER
+  "TARGET_STRING && ! TARGET_POWER
    && ((INTVAL (operands[2]) > 24 && INTVAL (operands[2]) < 32) || INTVAL (operands[2]) == 0)
    && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 12)
    && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 12)
@@ -7266,7 +7266,7 @@
    (clobber (reg:SI 11))
    (clobber (reg:SI 12))
    (clobber (match_scratch:SI 5 "X"))]
-  "TARGET_STRING && !TARGET_POWER
+  "TARGET_STRING && ! TARGET_POWER
    && INTVAL (operands[2]) > 16 && INTVAL (operands[2]) <= 32
    && (REGNO (operands[0]) < 7 || REGNO (operands[0]) > 12)
    && (REGNO (operands[1]) < 7 || REGNO (operands[1]) > 12)
@@ -7319,7 +7319,7 @@
    (clobber (reg:SI 11))
    (clobber (reg:SI 12))
    (clobber (match_scratch:SI 5 "X"))]
-  "TARGET_STRING && !TARGET_POWER
+  "TARGET_STRING && ! TARGET_POWER
    && INTVAL (operands[2]) > 8 && INTVAL (operands[2]) <= 16
    && (REGNO (operands[0]) < 9 || REGNO (operands[0]) > 12)
    && (REGNO (operands[1]) < 9 || REGNO (operands[1]) > 12)
@@ -7336,7 +7336,7 @@
 	      (use (match_operand 3 "" ""))
 	      (clobber (match_scratch:DI 4 ""))
 	      (clobber (match_scratch:SI 5 ""))])]
-  "TARGET_STRING && !TARGET_64BIT"
+  "TARGET_STRING && ! TARGET_64BIT"
   "")
 
 (define_insn ""
@@ -7346,7 +7346,7 @@
    (use (match_operand:SI 3 "immediate_operand" "i"))
    (clobber (match_scratch:DI 4 "=&r"))
    (clobber (match_scratch:SI 5 "=q"))]
-  "TARGET_STRING && TARGET_POWER && !TARGET_64BIT
+  "TARGET_STRING && TARGET_POWER && ! TARGET_64BIT
    && INTVAL (operands[2]) > 4 && INTVAL (operands[2]) <= 8"
   "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2"
   [(set_attr "type" "load")
@@ -7359,7 +7359,7 @@
    (use (match_operand:SI 3 "immediate_operand" "i"))
    (clobber (match_scratch:DI 4 "=&r"))
    (clobber (match_scratch:SI 5 "X"))]
-  "TARGET_STRING && !TARGET_POWER && !TARGET_64BIT
+  "TARGET_STRING && ! TARGET_POWER && ! TARGET_64BIT
    && INTVAL (operands[2]) > 4 && INTVAL (operands[2]) <= 8"
   "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2"
   [(set_attr "type" "load")
@@ -7396,7 +7396,7 @@
    (use (match_operand:SI 3 "immediate_operand" "i"))
    (clobber (match_scratch:SI 4 "=&r"))
    (clobber (match_scratch:SI 5 "X"))]
-  "TARGET_STRING && !TARGET_POWER
+  "TARGET_STRING && ! TARGET_POWER
    && INTVAL (operands[2]) > 0 && INTVAL (operands[2]) <= 4"
   "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2"
   [(set_attr "type" "load")
@@ -8881,7 +8881,7 @@
 		    (const_int 0)))
    (set (match_operand:SI 3 "gpc_reg_operand" "=r")
 	(match_op_dup 1 [(match_dup 2) (const_int 0)]))]
-  ""
+  "! TARGET_POWERPC64"
   "%D1mfcr %3\;{rlinm.|rlwinm.} %3,%3,%J1,1"
   [(set_attr "type" "delayed_compare")
    (set_attr "length" "12")])
@@ -10124,17 +10124,29 @@
   "{br|blr}"
   [(set_attr "type" "jmpreg")])
 
-(define_insn "indirect_jump"
-  [(set (pc) (match_operand:SI 0 "register_operand" "c,l"))]
+(define_expand "indirect_jump"
+  [(set (pc) (match_operand 0 "register_operand" ""))]
   ""
+  "
+{
+  if (TARGET_32BIT)
+    emit_jump_insn (gen_indirect_jumpsi (operands[0]));
+  else
+    emit_jump_insn (gen_indirect_jumpdi (operands[0]));
+  DONE;
+}")
+
+(define_insn "indirect_jumpsi"
+  [(set (pc) (match_operand:SI 0 "register_operand" "c,l"))]
+  "TARGET_32BIT"
   "@
    bctr
    {br|blr}"
   [(set_attr "type" "jmpreg")])
 
-(define_insn ""
+(define_insn "indirect_jumpdi"
   [(set (pc) (match_operand:DI 0 "register_operand" "c,l"))]
-  "TARGET_POWERPC64"
+  "TARGET_64BIT"
   "@
    bctr
    {br|blr}"
@@ -10160,7 +10172,7 @@
 		 (match_dup 2)))
    (parallel [(set (pc) (match_dup 3))
 	      (use (label_ref (match_operand 1 "" "")))])]
-  ""
+  "TARGET_32BIT"
   "
 { operands[0] = force_reg (SImode, operands[0]);
   operands[2] = force_reg (SImode, gen_rtx_LABEL_REF (VOIDmode, operands[1]));
@@ -10173,7 +10185,7 @@
 		 (match_dup 2)))
    (parallel [(set (pc) (match_dup 3))
 	      (use (label_ref (match_operand 1 "" "")))])]
-  ""
+  "TARGET_64BIT"
   "
 { operands[0] = force_reg (DImode, operands[0]);
   operands[2] = force_reg (DImode, gen_rtx_LABEL_REF (VOIDmode, operands[1]));
@@ -10184,7 +10196,7 @@
   [(set (pc)
 	(match_operand:SI 0 "register_operand" "c,l"))
    (use (label_ref (match_operand 1 "" "")))]
-  ""
+  "TARGET_32BIT"
   "@
    bctr
    {br|blr}"
@@ -10194,7 +10206,7 @@
   [(set (pc)
 	(match_operand:DI 0 "register_operand" "c,l"))
    (use (label_ref (match_operand 1 "" "")))]
-  "TARGET_POWERPC64"
+  "TARGET_64BIT"
   "@
    bctr
    {br|blr}"
@@ -10209,6 +10221,19 @@
 ;; so loop.c knows what to generate.
 
 (define_expand "decrement_and_branch_on_count"
+  [(use (match_operand 0 "register_operand" ""))
+   (use (label_ref (match_operand 1 "" "")))]
+  ""
+  "
+{
+  if (TARGET_POWERPC64)
+    emit_jump_insn (gen_ctrdi (operands[0], operands[1]));
+  else
+    emit_jump_insn (gen_ctrsi (operands[0], operands[1]));
+  DONE;
+}")
+
+(define_expand "ctrsi"
   [(parallel [(set (pc) (if_then_else (ne (match_operand:SI 0 "register_operand" "")
 					  (const_int 1))
 				      (label_ref (match_operand 1 "" ""))
@@ -10218,16 +10243,29 @@
 			    (const_int -1)))
 	      (clobber (match_scratch:CC 2 ""))
 	      (clobber (match_scratch:SI 3 ""))])]
-  ""
+  "! TARGET_POWERPC64"
+  "")
+
+(define_expand "ctrdi"
+  [(parallel [(set (pc) (if_then_else (ne (match_operand:DI 0 "register_operand" "")
+					  (const_int 1))
+				      (label_ref (match_operand 1 "" ""))
+				      (pc)))
+	      (set (match_dup 0)
+		   (plus:DI (match_dup 0)
+			    (const_int -1)))
+	      (clobber (match_scratch:CC 2 ""))
+	      (clobber (match_scratch:DI 3 ""))])]
+  "TARGET_POWERPC64"
   "")
 
 ;; We need to be able to do this for any operand, including MEM, or we
 ;; will cause reload to blow up since we don't allow output reloads on
 ;; JUMP_INSNs.
-;; In order that the length attribute is calculated correctly, the
+;; For the length attribute to be calculated correctly, the
 ;; label MUST be operand 0.
 
-(define_insn ""
+(define_insn "*ctrsi_internal1"
   [(set (pc)
 	(if_then_else (ne (match_operand:SI 1 "register_operand" "c,*r,*r")
 			  (const_int 1))
@@ -10238,7 +10276,7 @@
 		 (const_int -1)))
    (clobber (match_scratch:CC 3 "=X,&x,&x"))
    (clobber (match_scratch:SI 4 "=X,X,r"))]
-  ""
+  "! TARGET_POWERPC64"
   "*
 {
   if (which_alternative != 0)
@@ -10251,7 +10289,7 @@
   [(set_attr "type" "branch")
    (set_attr "length" "*,12,16")])
 
-(define_insn ""
+(define_insn "*ctrsi_internal2"
   [(set (pc)
 	(if_then_else (ne (match_operand:SI 1 "register_operand" "c,*r,*r")
 			  (const_int 1))
@@ -10262,7 +10300,55 @@
 		 (const_int -1)))
    (clobber (match_scratch:CC 3 "=X,&x,&x"))
    (clobber (match_scratch:SI 4 "=X,X,r"))]
-  ""
+  "! TARGET_POWERPC64"
+  "*
+{
+  if (which_alternative != 0)
+    return \"#\";
+  else if (get_attr_length (insn) == 8)
+    return \"bdz %l0\";
+  else
+    return \"{bdn|bdnz} %$+8\;b %l0\";
+}"
+  [(set_attr "type" "branch")
+   (set_attr "length" "*,12,16")])
+
+(define_insn "*ctrdi_internal1"
+  [(set (pc)
+	(if_then_else (ne (match_operand:DI 1 "register_operand" "c,*r,*r")
+			  (const_int 1))
+		      (label_ref (match_operand 0 "" ""))
+		      (pc)))
+   (set (match_operand:DI 2 "register_operand" "=1,*r,m*q*c*l")
+	(plus:DI (match_dup 1)
+		 (const_int -1)))
+   (clobber (match_scratch:CC 3 "=X,&x,&x"))
+   (clobber (match_scratch:DI 4 "=X,X,r"))]
+  "TARGET_POWERPC64"
+  "*
+{
+  if (which_alternative != 0)
+    return \"#\";
+  else if (get_attr_length (insn) == 8)
+    return \"{bdn|bdnz} %l0\";
+  else
+    return \"bdz %$+8\;b %l0\";
+}"
+  [(set_attr "type" "branch")
+   (set_attr "length" "*,12,16")])
+
+(define_insn "*ctrdi_internal2"
+  [(set (pc)
+	(if_then_else (ne (match_operand:DI 1 "register_operand" "c,*r,*r")
+			  (const_int 1))
+		      (pc)
+		      (label_ref (match_operand 0 "" ""))))
+   (set (match_operand:DI 2 "register_operand" "=1,*r,m*q*c*l")
+	(plus:DI (match_dup 1)
+		 (const_int -1)))
+   (clobber (match_scratch:CC 3 "=X,&x,&x"))
+   (clobber (match_scratch:DI 4 "=X,X,r"))]
+  "TARGET_POWERPC64"
   "*
 {
   if (which_alternative != 0)
@@ -10276,7 +10362,8 @@
    (set_attr "length" "*,12,16")])
 
 ;; Similar, but we can use GE since we have a REG_NONNEG.
-(define_insn ""
+
+(define_insn "*ctrsi_internal3"
   [(set (pc)
 	(if_then_else (ge (match_operand:SI 1 "register_operand" "c,*r,*r")
 			  (const_int 0))
@@ -10287,7 +10374,7 @@
 		 (const_int -1)))
    (clobber (match_scratch:CC 3 "=X,&x,&X"))
    (clobber (match_scratch:SI 4 "=X,X,r"))]
-  "find_reg_note (insn, REG_NONNEG, 0)"
+  "! TARGET_POWERPC64 && find_reg_note (insn, REG_NONNEG, 0)"
   "*
 {
   if (which_alternative != 0)
@@ -10300,7 +10387,7 @@
   [(set_attr "type" "branch")
    (set_attr "length" "*,12,16")])
 
-(define_insn ""
+(define_insn "*ctrsi_internal4"
   [(set (pc)
 	(if_then_else (ge (match_operand:SI 1 "register_operand" "c,*r,*r")
 			  (const_int 0))
@@ -10311,7 +10398,7 @@
 		 (const_int -1)))
    (clobber (match_scratch:CC 3 "=X,&x,&X"))
    (clobber (match_scratch:SI 4 "=X,X,r"))]
-  "find_reg_note (insn, REG_NONNEG, 0)"
+  "! TARGET_POWERPC64 && find_reg_note (insn, REG_NONNEG, 0)"
   "*
 {
   if (which_alternative != 0)
@@ -10324,7 +10411,57 @@
   [(set_attr "type" "branch")
    (set_attr "length" "*,12,16")])
 
-(define_insn ""
+(define_insn "*ctrdi_internal3"
+  [(set (pc)
+	(if_then_else (ge (match_operand:DI 1 "register_operand" "c,*r,*r")
+			  (const_int 0))
+		      (label_ref (match_operand 0 "" ""))
+		      (pc)))
+   (set (match_operand:DI 2 "register_operand" "=1,*r,m*q*c*l")
+	(plus:DI (match_dup 1)
+		 (const_int -1)))
+   (clobber (match_scratch:CC 3 "=X,&x,&X"))
+   (clobber (match_scratch:DI 4 "=X,X,r"))]
+  "TARGET_POWERPC64 && find_reg_note (insn, REG_NONNEG, 0)"
+  "*
+{
+  if (which_alternative != 0)
+    return \"#\";
+  else if (get_attr_length (insn) == 8)
+    return \"{bdn|bdnz} %l0\";
+  else
+    return \"bdz %$+8\;b %l0\";
+}"
+  [(set_attr "type" "branch")
+   (set_attr "length" "*,12,16")])
+
+(define_insn "*ctrdi_internal4"
+  [(set (pc)
+	(if_then_else (ge (match_operand:DI 1 "register_operand" "c,*r,*r")
+			  (const_int 0))
+		      (pc)
+		      (label_ref (match_operand 0 "" ""))))
+   (set (match_operand:DI 2 "register_operand" "=1,*r,m*q*c*l")
+	(plus:DI (match_dup 1)
+		 (const_int -1)))
+   (clobber (match_scratch:CC 3 "=X,&x,&X"))
+   (clobber (match_scratch:DI 4 "=X,X,r"))]
+  "TARGET_POWERPC64 && find_reg_note (insn, REG_NONNEG, 0)"
+  "*
+{
+  if (which_alternative != 0)
+    return \"#\";
+  else if (get_attr_length (insn) == 8)
+    return \"bdz %l0\";
+  else
+    return \"{bdn|bdnz} %$+8\;b %l0\";
+}"
+  [(set_attr "type" "branch")
+   (set_attr "length" "*,12,16")])
+
+;; Similar but use EQ
+
+(define_insn "*ctrsi_internal5"
   [(set (pc)
 	(if_then_else (eq (match_operand:SI 1 "register_operand" "c,*r,*r")
 			  (const_int 1))
@@ -10335,7 +10472,7 @@
 		 (const_int -1)))
    (clobber (match_scratch:CC 3 "=X,&x,&x"))
    (clobber (match_scratch:SI 4 "=X,X,r"))]
-  ""
+  "! TARGET_POWERPC64"
   "*
 {
   if (which_alternative != 0)
@@ -10348,7 +10485,7 @@
   [(set_attr "type" "branch")
    (set_attr "length" "*,12,16")])
 
-(define_insn ""
+(define_insn "*ctrsi_internal6"
   [(set (pc)
 	(if_then_else (eq (match_operand:SI 1 "register_operand" "c,*r,*r")
 			  (const_int 1))
@@ -10359,7 +10496,55 @@
 		 (const_int -1)))
    (clobber (match_scratch:CC 3 "=X,&x,&x"))
    (clobber (match_scratch:SI 4 "=X,X,r"))]
-  ""
+  "! TARGET_POWERPC64"
+  "*
+{
+  if (which_alternative != 0)
+    return \"#\";
+  else if (get_attr_length (insn) == 8)
+    return \"{bdn|bdnz} %l0\";
+  else
+    return \"bdz %$+8\;b %l0\";
+}"
+  [(set_attr "type" "branch")
+   (set_attr "length" "*,12,16")])
+
+(define_insn "*ctrdi_internal5"
+  [(set (pc)
+	(if_then_else (eq (match_operand:DI 1 "register_operand" "c,*r,*r")
+			  (const_int 1))
+		      (label_ref (match_operand 0 "" ""))
+		      (pc)))
+   (set (match_operand:DI 2 "register_operand" "=1,*r,m*q*c*l")
+	(plus:DI (match_dup 1)
+		 (const_int -1)))
+   (clobber (match_scratch:CC 3 "=X,&x,&x"))
+   (clobber (match_scratch:DI 4 "=X,X,r"))]
+  "TARGET_POWERPC64"
+  "*
+{
+  if (which_alternative != 0)
+    return \"#\";
+  else if (get_attr_length (insn) == 8)
+    return \"bdz %l0\";
+  else
+    return \"{bdn|bdnz} %$+8\;b %l0\";
+}"
+  [(set_attr "type" "branch")
+   (set_attr "length" "*,12,16")])
+
+(define_insn "*ctrdi_internal6"
+  [(set (pc)
+	(if_then_else (eq (match_operand:DI 1 "register_operand" "c,*r,*r")
+			  (const_int 1))
+		      (pc)
+		      (label_ref (match_operand 0 "" ""))))
+   (set (match_operand:DI 2 "register_operand" "=1,*r,m*q*c*l")
+	(plus:DI (match_dup 1)
+		 (const_int -1)))
+   (clobber (match_scratch:CC 3 "=X,&x,&x"))
+   (clobber (match_scratch:DI 4 "=X,X,r"))]
+  "TARGET_POWERPC64"
   "*
 {
   if (which_alternative != 0)
@@ -10372,6 +10557,8 @@
   [(set_attr "type" "branch")
    (set_attr "length" "*,12,16")])
 
+;; Now the splitters if we could not allocate the CTR register
+
 (define_split
   [(set (pc)
 	(if_then_else (match_operator 2 "comparison_operator"
@@ -10384,7 +10571,7 @@
 		 (const_int -1)))
    (clobber (match_scratch:CC 3 ""))
    (clobber (match_scratch:SI 4 ""))]
-  "reload_completed"
+  "! TARGET_POWERPC64 && reload_completed"
   [(parallel [(set (match_dup 3)
 		   (compare:CC (plus:SI (match_dup 1)
 					(const_int -1))
@@ -10410,7 +10597,8 @@
 	(plus:SI (match_dup 1) (const_int -1)))
    (clobber (match_scratch:CC 3 ""))
    (clobber (match_scratch:SI 4 ""))]
-  "reload_completed && ! gpc_reg_operand (operands[0], SImode)"
+  "! TARGET_POWERPC64 && reload_completed
+   && ! gpc_reg_operand (operands[0], SImode)"
   [(parallel [(set (match_dup 3)
 		   (compare:CC (plus:SI (match_dup 1)
 					(const_int -1))
@@ -10426,6 +10614,61 @@
   "
 { operands[7] = gen_rtx (GET_CODE (operands[2]), VOIDmode, operands[3],
 			 const0_rtx); }")
+(define_split
+  [(set (pc)
+	(if_then_else (match_operator 2 "comparison_operator"
+				      [(match_operand:DI 1 "gpc_reg_operand" "")
+				       (const_int 1)])
+		      (match_operand 5 "" "")
+		      (match_operand 6 "" "")))
+   (set (match_operand:DI 0 "gpc_reg_operand" "")
+	(plus:DI (match_dup 1)
+		 (const_int -1)))
+   (clobber (match_scratch:CC 3 ""))
+   (clobber (match_scratch:DI 4 ""))]
+  "TARGET_POWERPC64 && reload_completed"
+  [(parallel [(set (match_dup 3)
+		   (compare:CC (plus:DI (match_dup 1)
+					(const_int -1))
+			       (const_int 0)))
+	      (set (match_dup 0)
+		   (plus:DI (match_dup 1)
+			    (const_int -1)))])
+   (set (pc) (if_then_else (match_dup 7)
+			   (match_dup 5)
+			   (match_dup 6)))]
+  "
+{ operands[7] = gen_rtx (GET_CODE (operands[2]), VOIDmode, operands[3],
+			 const0_rtx); }")
+
+(define_split
+  [(set (pc)
+	(if_then_else (match_operator 2 "comparison_operator"
+				      [(match_operand:DI 1 "gpc_reg_operand" "")
+				       (const_int 1)])
+		      (match_operand 5 "" "")
+		      (match_operand 6 "" "")))
+   (set (match_operand:DI 0 "general_operand" "")
+	(plus:DI (match_dup 1) (const_int -1)))
+   (clobber (match_scratch:CC 3 ""))
+   (clobber (match_scratch:DI 4 ""))]
+  "TARGET_POWERPC64 && reload_completed
+   && ! gpc_reg_operand (operands[0], DImode)"
+  [(parallel [(set (match_dup 3)
+		   (compare:CC (plus:DI (match_dup 1)
+					(const_int -1))
+			       (const_int 0)))
+	      (set (match_dup 4)
+		   (plus:DI (match_dup 1)
+			    (const_int -1)))])
+   (set (match_dup 0)
+	(match_dup 4))
+   (set (pc) (if_then_else (match_dup 7)
+			   (match_dup 5)
+			   (match_dup 6)))]
+  "
+{ operands[7] = gen_rtx (GET_CODE (operands[2]), VOIDmode, operands[3],
+			 const0_rtx); }")
 
 (define_insn "trap"
   [(trap_if (const_int 1) (const_int 0))]
-- 
GitLab