public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH 1/4] rs6000: Merge mulsi3 and muldi3
@ 2014-09-01 19:53 Segher Boessenkool
  2014-09-01 19:56 ` [PATCH 3/4] rs6000: Merge zero_extend*si2 and zero_extend*di2 Segher Boessenkool
                   ` (3 more replies)
  0 siblings, 4 replies; 8+ messages in thread
From: Segher Boessenkool @ 2014-09-01 19:53 UTC (permalink / raw)
  To: gcc-patches; +Cc: dje.gcc, Segher Boessenkool

Nothing noteworthy in this patch, sorry.

Tested as usual (powerpc64-linux, -m64,-m32,-m32/-mpowerpc64), no
regressions.  Is this okay to apply?


Segher


2014-09-01  Segher Boessenkool  <segher@kernel.crashing.org>

gcc/
	* config/rs6000/rs6000.md (mulsi3, *mulsi3_internal1,
	*mulsi3_internal2, and two splitters): Delete.
	(muldi3, *muldi3_internal1, *muldi3_internal2, and two splitters):
	Delete.
	(mul<mode>3, mul<mode>3_dot, mul<mode>3_dot2): New.

---
 gcc/config/rs6000/rs6000.md | 167 +++++++++++---------------------------------
 1 file changed, 41 insertions(+), 126 deletions(-)

diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index 1ab8271..d903e4a 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -2701,79 +2701,70 @@ (define_split
   DONE;
 }")
 
-(define_insn "mulsi3"
-  [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
-	(mult:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r")
-		 (match_operand:SI 2 "reg_or_short_operand" "r,I")))]
+
+(define_insn "mul<mode>3"
+  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
+	(mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
+		  (match_operand:GPR 2 "reg_or_short_operand" "r,I")))]
   ""
   "@
-   mullw %0,%1,%2
+   mull<wd> %0,%1,%2
    mulli %0,%1,%2"
    [(set_attr "type" "mul")
     (set (attr "size")
-      (cond [(match_operand:SI 2 "s8bit_cint_operand" "")
+      (cond [(match_operand:GPR 2 "s8bit_cint_operand" "")
 		(const_string "8")
-             (match_operand:SI 2 "short_cint_operand" "")
+             (match_operand:GPR 2 "short_cint_operand" "")
 		(const_string "16")]
-	(const_string "32")))])
+	(const_string "<bits>")))])
 
-(define_insn "*mulsi3_internal1"
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
-	(compare:CC (mult:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r")
-			     (match_operand:SI 2 "gpc_reg_operand" "r,r"))
+(define_insn_and_split "*mul<mode>3_dot"
+  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
+	(compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
+			      (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
 		    (const_int 0)))
-   (clobber (match_scratch:SI 3 "=r,r"))]
-  "TARGET_32BIT"
+   (clobber (match_scratch:GPR 0 "=r,r"))]
+  "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
   "@
-   mullw. %3,%1,%2
+   mull<wd>. %0,%1,%2
    #"
+  "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
+  [(set (match_dup 0)
+	(mult:GPR (match_dup 1)
+		  (match_dup 2)))
+   (set (match_dup 3)
+	(compare:CC (match_dup 0)
+		    (const_int 0)))]
+  ""
   [(set_attr "type" "mul")
+   (set_attr "size" "<bits>")
    (set_attr "dot" "yes")
    (set_attr "length" "4,8")])
 
-(define_split
-  [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
-	(compare:CC (mult:SI (match_operand:SI 1 "gpc_reg_operand" "")
-			     (match_operand:SI 2 "gpc_reg_operand" ""))
-		    (const_int 0)))
-   (clobber (match_scratch:SI 3 ""))]
-  "TARGET_32BIT && reload_completed"
-  [(set (match_dup 3)
-	(mult:SI (match_dup 1) (match_dup 2)))
-   (set (match_dup 0)
-	(compare:CC (match_dup 3)
-		    (const_int 0)))]
-  "")
-
-(define_insn "*mulsi3_internal2"
+(define_insn_and_split "*mul<mode>3_dot2"
   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
-	(compare:CC (mult:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r")
-			     (match_operand:SI 2 "gpc_reg_operand" "r,r"))
+	(compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
+			      (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
 		    (const_int 0)))
-   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
-	(mult:SI (match_dup 1) (match_dup 2)))]
-  "TARGET_32BIT"
+   (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
+	(mult:GPR (match_dup 1)
+		  (match_dup 2)))]
+  "<MODE>mode == Pmode && rs6000_gen_cell_microcode"
   "@
-   mullw. %0,%1,%2
+   mull<wd>. %0,%1,%2
    #"
-  [(set_attr "type" "mul")
-   (set_attr "dot" "yes")
-   (set_attr "length" "4,8")])
-
-(define_split
-  [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "")
-	(compare:CC (mult:SI (match_operand:SI 1 "gpc_reg_operand" "")
-			     (match_operand:SI 2 "gpc_reg_operand" ""))
-		    (const_int 0)))
-   (set (match_operand:SI 0 "gpc_reg_operand" "")
-	(mult:SI (match_dup 1) (match_dup 2)))]
-  "TARGET_32BIT && reload_completed"
+  "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
   [(set (match_dup 0)
-	(mult:SI (match_dup 1) (match_dup 2)))
+	(mult:GPR (match_dup 1)
+		  (match_dup 2)))
    (set (match_dup 3)
 	(compare:CC (match_dup 0)
 		    (const_int 0)))]
-  "")
+  ""
+  [(set_attr "type" "mul")
+   (set_attr "size" "<bits>")
+   (set_attr "dot" "yes")
+   (set_attr "length" "4,8")])
 
 
 (define_insn "udiv<mode>3"
@@ -6767,82 +6758,6 @@ (define_insn "*ashrdisi3_noppc64be"
 \f
 ;; PowerPC64 DImode operations.
 
-(define_insn "muldi3"
-  [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
-        (mult:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r")
-                 (match_operand:DI 2 "reg_or_short_operand" "r,I")))]
-  "TARGET_POWERPC64"
-  "@
-   mulld %0,%1,%2
-   mulli %0,%1,%2"
-   [(set_attr "type" "mul")
-    (set (attr "size")
-      (cond [(match_operand:SI 2 "s8bit_cint_operand" "")
-		(const_string "8")
-	     (match_operand:SI 2 "short_cint_operand" "")
-		(const_string "16")]
-	(const_string "64")))])
-
-(define_insn "*muldi3_internal1"
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
-	(compare:CC (mult:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r")
-			     (match_operand:DI 2 "gpc_reg_operand" "r,r"))
-		    (const_int 0)))
-   (clobber (match_scratch:DI 3 "=r,r"))]
-  "TARGET_POWERPC64"
-  "@
-   mulld. %3,%1,%2
-   #"
-  [(set_attr "type" "mul")
-   (set_attr "size" "64")
-   (set_attr "dot" "yes")
-   (set_attr "length" "4,8")])
-
-(define_split
-  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
-	(compare:CC (mult:DI (match_operand:DI 1 "gpc_reg_operand" "")
-			     (match_operand:DI 2 "gpc_reg_operand" ""))
-		    (const_int 0)))
-   (clobber (match_scratch:DI 3 ""))]
-  "TARGET_POWERPC64 && reload_completed"
-  [(set (match_dup 3)
-	(mult:DI (match_dup 1) (match_dup 2)))
-   (set (match_dup 0)
-	(compare:CC (match_dup 3)
-		    (const_int 0)))]
-  "")
-
-(define_insn "*muldi3_internal2"
-  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
-	(compare:CC (mult:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r")
-			     (match_operand:DI 2 "gpc_reg_operand" "r,r"))
-		    (const_int 0)))
-   (set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
-	(mult:DI (match_dup 1) (match_dup 2)))]
-  "TARGET_POWERPC64"
-  "@
-   mulld. %0,%1,%2
-   #"
-  [(set_attr "type" "mul")
-   (set_attr "size" "64")
-   (set_attr "dot" "yes")
-   (set_attr "length" "4,8")])
-
-(define_split
-  [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "")
-	(compare:CC (mult:DI (match_operand:DI 1 "gpc_reg_operand" "")
-			     (match_operand:DI 2 "gpc_reg_operand" ""))
-		    (const_int 0)))
-   (set (match_operand:DI 0 "gpc_reg_operand" "")
-	(mult:DI (match_dup 1) (match_dup 2)))]
-  "TARGET_POWERPC64 && reload_completed"
-  [(set (match_dup 0)
-	(mult:DI (match_dup 1) (match_dup 2)))
-   (set (match_dup 3)
-	(compare:CC (match_dup 0)
-		    (const_int 0)))]
-  "")
-
 (define_insn "smuldi3_highpart"
   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
 	(truncate:DI
-- 
1.8.1.4

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH 3/4] rs6000: Merge zero_extend*si2 and zero_extend*di2
  2014-09-01 19:53 [PATCH 1/4] rs6000: Merge mulsi3 and muldi3 Segher Boessenkool
@ 2014-09-01 19:56 ` Segher Boessenkool
  2014-09-02  0:32   ` David Edelsohn
  2014-09-01 19:56 ` [PATCH 2/4] rs6000: Merge and improve highpart and widening muls Segher Boessenkool
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 8+ messages in thread
From: Segher Boessenkool @ 2014-09-01 19:56 UTC (permalink / raw)
  To: gcc-patches; +Cc: dje.gcc, Segher Boessenkool

Don't group the insns based on extended size; use source size instead.
Use the "andi." insn rather than "rldicl." and friends if possible.
The instructions guarded by TARGET_LFIWZX do not need that guard: the
constraints already guarantee the (correct!) condition.

Tested as usual; no regressions.  Okay to apply?


Segher


2014-09-01  Segher Boessenkool  <segher@kernel.crashing.org>

gcc/
	* config/rs6000/rs6000.md (QHSI): Delete.
	(EXTQI, EXTHI, EXTSI): New mode iterators.
	(zero_extend<mode>di2, *zero_extend<mode>di2_internal1,
	*zero_extend<mode>di2_internal2, *zero_extend<mode>di2_internal3,
	*zero_extendsidi2_lfiwzx, zero_extendqisi2, zero_extendhisi2,
	9 anonymous instructions, and 8 splitters): Delete.
	(zero_extendqi<mode>2, *zero_extendqi<mode>2_dot,
	*zero_extendqi<mode>2_dot2, zero_extendhi<mode>2,
	*zero_extendhi<mode>2_dot, *zero_extendhi<mode>2_dot2,
	zero_extendsi<mode>2, *zero_extendsi<mode>2_dot,
	*zero_extendsi<mode>2_dot2): New.

---
 gcc/config/rs6000/rs6000.md | 379 +++++++++++++++-----------------------------
 1 file changed, 131 insertions(+), 248 deletions(-)

diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index f9e1eba..6cd6404 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -309,8 +309,14 @@ (define_mode_iterator INT [QI HI SI DI TI PTI])
 ; Any supported integer mode that fits in one register.
 (define_mode_iterator INT1 [QI HI SI (DI "TARGET_POWERPC64")])
 
-; extend modes for DImode
-(define_mode_iterator QHSI [QI HI SI])
+; Everything we can extend QImode to.
+(define_mode_iterator EXTQI [HI SI (DI "TARGET_POWERPC64")])
+
+; Everything we can extend HImode to.
+(define_mode_iterator EXTHI [SI (DI "TARGET_POWERPC64")])
+
+; Everything we can extend SImode to.
+(define_mode_iterator EXTSI [(DI "TARGET_POWERPC64")])
 
 ; QImode or HImode for small atomic ops
 (define_mode_iterator QHI [QI HI])
@@ -564,79 +570,112 @@ (define_mode_attr BOOL_REGS_UNARY	[(TI	"r,0,0,wa,v")
 ;; Start with fixed-point load and store insns.  Here we put only the more
 ;; complex forms.  Basic data transfer is done later.
 
-(define_expand "zero_extend<mode>di2"
-  [(set (match_operand:DI 0 "gpc_reg_operand" "")
-	(zero_extend:DI (match_operand:QHSI 1 "gpc_reg_operand" "")))]
-  "TARGET_POWERPC64"
-  "")
-
-(define_insn "*zero_extend<mode>di2_internal1"
-  [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
-	(zero_extend:DI (match_operand:QHSI 1 "reg_or_mem_operand" "m,r")))]
-  "TARGET_POWERPC64 && (<MODE>mode != SImode || !TARGET_LFIWZX)"
+(define_insn "zero_extendqi<mode>2"
+  [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
+	(zero_extend:EXTQI (match_operand:QI 1 "reg_or_mem_operand" "m,r")))]
+  ""
   "@
-   l<wd>z%U1%X1 %0,%1
-   rldicl %0,%1,0,<dbits>"
+   lbz%U1%X1 %0,%1
+   rlwinm %0,%1,0,0xff"
   [(set_attr "type" "load,shift")])
 
-(define_insn "*zero_extend<mode>di2_internal2"
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
-	(compare:CC (zero_extend:DI (match_operand:QHSI 1 "gpc_reg_operand" "r,r"))
+(define_insn_and_split "*zero_extendqi<mode>2_dot"
+  [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
+	(compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
 		    (const_int 0)))
-   (clobber (match_scratch:DI 2 "=r,r"))]
-  "TARGET_64BIT"
+   (clobber (match_scratch:EXTQI 0 "=r,r"))]
+  "rs6000_gen_cell_microcode"
   "@
-   rldicl. %2,%1,0,<dbits>
+   andi. %0,%1,0xff
    #"
-  [(set_attr "type" "shift")
+  "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
+  [(set (match_dup 0)
+	(zero_extend:EXTQI (match_dup 1)))
+   (set (match_dup 2)
+	(compare:CC (match_dup 0)
+		    (const_int 0)))]
+  ""
+  [(set_attr "type" "logical")
    (set_attr "dot" "yes")
    (set_attr "length" "4,8")])
 
-(define_split
-  [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
-	(compare:CC (zero_extend:DI (match_operand:QHSI 1 "gpc_reg_operand" ""))
+(define_insn_and_split "*zero_extendqi<mode>2_dot2"
+  [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
+	(compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
 		    (const_int 0)))
-   (clobber (match_scratch:DI 2 ""))]
-  "TARGET_POWERPC64 && reload_completed"
-  [(set (match_dup 2)
-	(zero_extend:DI (match_dup 1)))
-   (set (match_dup 0)
-	(compare:CC (match_dup 2)
+   (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
+	(zero_extend:EXTQI (match_dup 1)))]
+  "rs6000_gen_cell_microcode"
+  "@
+   andi. %0,%1,0xff
+   #"
+  "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
+  [(set (match_dup 0)
+	(zero_extend:EXTQI (match_dup 1)))
+   (set (match_dup 2)
+	(compare:CC (match_dup 0)
 		    (const_int 0)))]
-  "")
+  ""
+  [(set_attr "type" "logical")
+   (set_attr "dot" "yes")
+   (set_attr "length" "4,8")])
+
+
+(define_insn "zero_extendhi<mode>2"
+  [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
+	(zero_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r")))]
+  ""
+  "@
+   lhz%U1%X1 %0,%1
+   rlwinm %0,%1,0,0xffff"
+  [(set_attr "type" "load,shift")])
 
-(define_insn "*zero_extend<mode>di2_internal3"
+(define_insn_and_split "*zero_extendhi<mode>2_dot"
   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
-	(compare:CC (zero_extend:DI (match_operand:QHSI 1 "gpc_reg_operand" "r,r"))
+	(compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
 		    (const_int 0)))
-   (set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
-	(zero_extend:DI (match_dup 1)))]
-  "TARGET_64BIT"
+   (clobber (match_scratch:EXTHI 0 "=r,r"))]
+  "rs6000_gen_cell_microcode"
   "@
-   rldicl. %0,%1,0,<dbits>
+   andi. %0,%1,0xffff
    #"
-  [(set_attr "type" "shift")
+  "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
+  [(set (match_dup 0)
+	(zero_extend:EXTHI (match_dup 1)))
+   (set (match_dup 2)
+	(compare:CC (match_dup 0)
+		    (const_int 0)))]
+  ""
+  [(set_attr "type" "logical")
    (set_attr "dot" "yes")
    (set_attr "length" "4,8")])
 
-(define_split
-  [(set (match_operand:CC 2 "cc_reg_not_micro_cr0_operand" "")
-	(compare:CC (zero_extend:DI (match_operand:QHSI 1 "gpc_reg_operand" ""))
+(define_insn_and_split "*zero_extendhi<mode>2_dot2"
+  [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
+	(compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
 		    (const_int 0)))
-   (set (match_operand:DI 0 "gpc_reg_operand" "")
-	(zero_extend:DI (match_dup 1)))]
-  "TARGET_POWERPC64 && reload_completed"
+   (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
+	(zero_extend:EXTHI (match_dup 1)))]
+  "rs6000_gen_cell_microcode"
+  "@
+   andi. %0,%1,0xffff
+   #"
+  "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
   [(set (match_dup 0)
-	(zero_extend:DI (match_dup 1)))
+	(zero_extend:EXTHI (match_dup 1)))
    (set (match_dup 2)
 	(compare:CC (match_dup 0)
 		    (const_int 0)))]
-  "")
+  ""
+  [(set_attr "type" "logical")
+   (set_attr "dot" "yes")
+   (set_attr "length" "4,8")])
 
-(define_insn "*zero_extendsidi2_lfiwzx"
-  [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,??wj,!wz,!wu")
-	(zero_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "m,r,r,Z,Z")))]
-  "TARGET_POWERPC64 && TARGET_LFIWZX"
+
+(define_insn "zero_extendsi<mode>2"
+  [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r,??wj,!wz,!wu")
+	(zero_extend:EXTSI (match_operand:SI 1 "reg_or_mem_operand" "m,r,r,Z,Z")))]
+  ""
   "@
    lwz%U1%X1 %0,%1
    rldicl %0,%1,0,32
@@ -645,6 +684,48 @@ (define_insn "*zero_extendsidi2_lfiwzx"
    lxsiwzx %x0,%y1"
   [(set_attr "type" "load,shift,mffgpr,fpload,fpload")])
 
+(define_insn_and_split "*zero_extendsi<mode>2_dot"
+  [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
+	(compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
+		    (const_int 0)))
+   (clobber (match_scratch:EXTSI 0 "=r,r"))]
+  "rs6000_gen_cell_microcode"
+  "@
+   rldicl. %0,%1,0,32
+   #"
+  "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
+  [(set (match_dup 0)
+	(zero_extend:DI (match_dup 1)))
+   (set (match_dup 2)
+	(compare:CC (match_dup 0)
+		    (const_int 0)))]
+  ""
+  [(set_attr "type" "shift")
+   (set_attr "dot" "yes")
+   (set_attr "length" "4,8")])
+
+(define_insn_and_split "*zero_extendsi<mode>2_dot2"
+  [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
+	(compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
+		    (const_int 0)))
+   (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r")
+	(zero_extend:EXTSI (match_dup 1)))]
+  "rs6000_gen_cell_microcode"
+  "@
+   rldicl. %0,%1,0,32
+   #"
+  "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
+  [(set (match_dup 0)
+	(zero_extend:EXTSI (match_dup 1)))
+   (set (match_dup 2)
+	(compare:CC (match_dup 0)
+		    (const_int 0)))]
+  ""
+  [(set_attr "type" "shift")
+   (set_attr "dot" "yes")
+   (set_attr "length" "4,8")])
+
+
 (define_insn "extendqidi2"
   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
 	(sign_extend:DI (match_operand:QI 1 "gpc_reg_operand" "r")))]
@@ -867,74 +948,6 @@ (define_split
 		    (const_int 0)))]
   "")
 
-(define_expand "zero_extendqisi2"
-  [(set (match_operand:SI 0 "gpc_reg_operand" "")
-	(zero_extend:SI (match_operand:QI 1 "gpc_reg_operand" "")))]
-  ""
-  "")
-
-(define_insn ""
-  [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
-	(zero_extend:SI (match_operand:QI 1 "reg_or_mem_operand" "m,r")))]
-  ""
-  "@
-   lbz%U1%X1 %0,%1
-   rlwinm %0,%1,0,0xff"
-  [(set_attr "type" "load,shift")])
-
-(define_insn ""
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
-	(compare:CC (zero_extend:SI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
-		    (const_int 0)))
-   (clobber (match_scratch:SI 2 "=r,r"))]
-  ""
-  "@
-   andi. %2,%1,0xff
-   #"
-  [(set_attr "type" "logical,compare")
-   (set_attr "dot" "yes")
-   (set_attr "length" "4,8")])
-
-(define_split
-  [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
-	(compare:CC (zero_extend:SI (match_operand:QI 1 "gpc_reg_operand" ""))
-		    (const_int 0)))
-   (clobber (match_scratch:SI 2 ""))]
-  "reload_completed"
-  [(set (match_dup 2)
-	(zero_extend:SI (match_dup 1)))
-   (set (match_dup 0)
-	(compare:CC (match_dup 2)
-		    (const_int 0)))]
-  "")
-
-(define_insn ""
-  [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
-	(compare:CC (zero_extend:SI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
-		    (const_int 0)))
-   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
-	(zero_extend:SI (match_dup 1)))]
-  ""
-  "@
-   andi. %0,%1,0xff
-   #"
-  [(set_attr "type" "logical,compare")
-   (set_attr "dot" "yes")
-   (set_attr "length" "4,8")])
-
-(define_split
-  [(set (match_operand:CC 2 "cc_reg_not_micro_cr0_operand" "")
-	(compare:CC (zero_extend:SI (match_operand:QI 1 "gpc_reg_operand" ""))
-		    (const_int 0)))
-   (set (match_operand:SI 0 "gpc_reg_operand" "")
-	(zero_extend:SI (match_dup 1)))]
-  "reload_completed"
-  [(set (match_dup 0)
-	(zero_extend:SI (match_dup 1)))
-   (set (match_dup 2)
-	(compare:CC (match_dup 0)
-		    (const_int 0)))]
-  "")
 
 (define_insn "extendqisi2"
   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
@@ -995,68 +1008,6 @@ (define_split
 		    (const_int 0)))]
   "")
 
-(define_insn ""
-  [(set (match_operand:HI 0 "gpc_reg_operand" "=r,r")
-	(zero_extend:HI (match_operand:QI 1 "reg_or_mem_operand" "m,r")))]
-  ""
-  "@
-   lbz%U1%X1 %0,%1
-   rlwinm %0,%1,0,0xff"
-  [(set_attr "type" "load,shift")])
-
-(define_insn ""
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
-	(compare:CC (zero_extend:HI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
-		    (const_int 0)))
-   (clobber (match_scratch:HI 2 "=r,r"))]
-  ""
-  "@
-   andi. %2,%1,0xff
-   #"
-  [(set_attr "type" "logical,compare")
-   (set_attr "dot" "yes")
-   (set_attr "length" "4,8")])
-
-(define_split
-  [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
-	(compare:CC (zero_extend:HI (match_operand:QI 1 "gpc_reg_operand" ""))
-		    (const_int 0)))
-   (clobber (match_scratch:HI 2 ""))]
-  "reload_completed"
-  [(set (match_dup 2)
-	(zero_extend:HI (match_dup 1)))
-   (set (match_dup 0)
-	(compare:CC (match_dup 2)
-		    (const_int 0)))]
-  "")
-
-(define_insn ""
-  [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
-	(compare:CC (zero_extend:HI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
-		    (const_int 0)))
-   (set (match_operand:HI 0 "gpc_reg_operand" "=r,r")
-	(zero_extend:HI (match_dup 1)))]
-  ""
-  "@
-   andi. %0,%1,0xff
-   #"
-  [(set_attr "type" "logical,compare")
-   (set_attr "dot" "yes")
-   (set_attr "length" "4,8")])
-
-(define_split
-  [(set (match_operand:CC 2 "cc_reg_not_micro_cr0_operand" "")
-	(compare:CC (zero_extend:HI (match_operand:QI 1 "gpc_reg_operand" ""))
-		    (const_int 0)))
-   (set (match_operand:HI 0 "gpc_reg_operand" "")
-	(zero_extend:HI (match_dup 1)))]
-  "reload_completed"
-  [(set (match_dup 0)
-	(zero_extend:HI (match_dup 1)))
-   (set (match_dup 2)
-	(compare:CC (match_dup 0)
-		    (const_int 0)))]
-  "")
 
 (define_insn "extendqihi2"
   [(set (match_operand:HI 0 "gpc_reg_operand" "=r")
@@ -1117,74 +1068,6 @@ (define_split
 		    (const_int 0)))]
   "")
 
-(define_expand "zero_extendhisi2"
-  [(set (match_operand:SI 0 "gpc_reg_operand" "")
-	(zero_extend:SI (match_operand:HI 1 "gpc_reg_operand" "")))]
-  ""
-  "")
-
-(define_insn ""
-  [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
-	(zero_extend:SI (match_operand:HI 1 "reg_or_mem_operand" "m,r")))]
-  ""
-  "@
-   lhz%U1%X1 %0,%1
-   rlwinm %0,%1,0,0xffff"
-  [(set_attr "type" "load,shift")])
-
-(define_insn ""
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
-	(compare:CC (zero_extend:SI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
-		    (const_int 0)))
-   (clobber (match_scratch:SI 2 "=r,r"))]
-  ""
-  "@
-   andi. %2,%1,0xffff
-   #"
-  [(set_attr "type" "logical,compare")
-   (set_attr "dot" "yes")
-   (set_attr "length" "4,8")])
-
-(define_split
-  [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
-	(compare:CC (zero_extend:SI (match_operand:HI 1 "gpc_reg_operand" ""))
-		    (const_int 0)))
-   (clobber (match_scratch:SI 2 ""))]
-  "reload_completed"
-  [(set (match_dup 2)
-	(zero_extend:SI (match_dup 1)))
-   (set (match_dup 0)
-	(compare:CC (match_dup 2)
-		    (const_int 0)))]
-  "")
-
-(define_insn ""
-  [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
-	(compare:CC (zero_extend:SI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
-		    (const_int 0)))
-   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
-	(zero_extend:SI (match_dup 1)))]
-  ""
-  "@
-   andi. %0,%1,0xffff
-   #"
-  [(set_attr "type" "logical,compare")
-   (set_attr "dot" "yes")
-   (set_attr "length" "4,8")])
-
-(define_split
-  [(set (match_operand:CC 2 "cc_reg_not_micro_cr0_operand" "")
-	(compare:CC (zero_extend:SI (match_operand:HI 1 "gpc_reg_operand" ""))
-		    (const_int 0)))
-   (set (match_operand:SI 0 "gpc_reg_operand" "")
-	(zero_extend:SI (match_dup 1)))]
-  "reload_completed"
-  [(set (match_dup 0)
-	(zero_extend:SI (match_dup 1)))
-   (set (match_dup 2)
-	(compare:CC (match_dup 0)
-		    (const_int 0)))]
-  "")
 
 (define_expand "extendhisi2"
   [(set (match_operand:SI 0 "gpc_reg_operand" "")
-- 
1.8.1.4

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH 2/4] rs6000: Merge and improve highpart and widening muls
  2014-09-01 19:53 [PATCH 1/4] rs6000: Merge mulsi3 and muldi3 Segher Boessenkool
  2014-09-01 19:56 ` [PATCH 3/4] rs6000: Merge zero_extend*si2 and zero_extend*di2 Segher Boessenkool
@ 2014-09-01 19:56 ` Segher Boessenkool
  2014-09-02  0:30   ` David Edelsohn
  2014-09-01 19:57 ` [PATCH 4/4] rs6000: Merge extend*si2 and extend*di2 Segher Boessenkool
  2014-09-02  0:30 ` [PATCH 1/4] rs6000: Merge mulsi3 and muldi3 David Edelsohn
  3 siblings, 1 reply; 8+ messages in thread
From: Segher Boessenkool @ 2014-09-01 19:56 UTC (permalink / raw)
  To: gcc-patches; +Cc: dje.gcc, Segher Boessenkool

This is a little more complex.  The highpart muls generate a "truncate
lshiftrt" pattern that is not canonical when widening to two registers,
so this doesn't optimise well with combine.  This patch changes it to use
the canonical subreg patterns instead, which means we need separate patterns
for LE mode.  Oh well.

Tested as usual.  This regresses gcc.dg/sms-8.c with -m32: SMS now _does_
succeed, from my shallow investigation because there now are subregs and
SMS explicitly looks for that.  I didn't look further because other SMS
tests are failing (without the patch) as well.

Is this okay to apply?


Segher


2014-09-01  Segher Boessenkool  <segher@kernel.crashing.org>

gcc/
	* config/rs6000/rs6000.md (any_extend): New code iterator.
	(u, su): New code attributes.
	(dmode, DMODE): New mode attributes.
	(<su>mul<mode>3_highpart): New.
	(*<su>mul<mode>3_highpart): New.
	(<su>mulsi3_highpart_le): New.
	(<su>muldi3_highpart_le): New.
	(<su>mulsi3_highpart_64): New.
	(<u>mul<mode><dmode>3): New.
	(mulsidi3, umulsidi3, smulsi3_highpart, umulsi3_highpart, and two
	splitters): Delete.
	(mulditi3, umulditi3, smuldi3_highpart, umuldi3_highpart, and two
	splitters): Delete.

---
 gcc/config/rs6000/rs6000.md | 247 ++++++++++++++++++--------------------------
 1 file changed, 103 insertions(+), 144 deletions(-)

diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index d903e4a..f9e1eba 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -431,6 +431,11 @@ (define_code_attr return_pred [(return "direct_return ()")
 			       (simple_return "1")])
 (define_code_attr return_str [(return "") (simple_return "simple_")])
 
+; Signed/unsigned variants of ops.
+(define_code_iterator any_extend [sign_extend zero_extend])
+(define_code_attr u [(sign_extend "") (zero_extend "u")])
+(define_code_attr su [(sign_extend "s") (zero_extend "u")])
+
 ; Various instructions that come in SI and DI forms.
 ; A generic w/d attribute, for things like cmpw/cmpd.
 (define_mode_attr wd [(QI    "b")
@@ -454,6 +459,10 @@ (define_mode_attr sel [(SI "") (DI "64")])
 ;; Bitmask for shift instructions
 (define_mode_attr hH [(SI "h") (DI "H")])
 
+;; A mode twice the size of the given mode
+(define_mode_attr dmode [(SI "di") (DI "ti")])
+(define_mode_attr DMODE [(SI "DI") (DI "TI")])
+
 ;; Suffix for reload patterns
 (define_mode_attr ptrsize [(SI "32bit")
 			   (DI "64bit")])
@@ -2767,6 +2776,100 @@ (define_insn_and_split "*mul<mode>3_dot2"
    (set_attr "length" "4,8")])
 
 
+(define_expand "<su>mul<mode>3_highpart"
+  [(set (match_operand:GPR 0 "gpc_reg_operand")
+	(subreg:GPR
+	  (mult:<DMODE> (any_extend:<DMODE>
+			  (match_operand:GPR 1 "gpc_reg_operand"))
+			(any_extend:<DMODE>
+			  (match_operand:GPR 2 "gpc_reg_operand")))
+	 0))]
+  ""
+{
+  if (<MODE>mode == SImode && TARGET_POWERPC64)
+    {
+      emit_insn (gen_<su>mulsi3_highpart_64 (operands[0], operands[1],
+					     operands[2]));
+      DONE;
+    }
+
+  if (!WORDS_BIG_ENDIAN)
+    {
+      emit_insn (gen_<su>mul<mode>3_highpart_le (operands[0], operands[1],
+						 operands[2]));
+      DONE;
+    }
+})
+
+(define_insn "*<su>mul<mode>3_highpart"
+  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
+	(subreg:GPR
+	  (mult:<DMODE> (any_extend:<DMODE>
+			  (match_operand:GPR 1 "gpc_reg_operand" "r"))
+			(any_extend:<DMODE>
+			  (match_operand:GPR 2 "gpc_reg_operand" "r")))
+	 0))]
+  "WORDS_BIG_ENDIAN && !(<MODE>mode == SImode && TARGET_POWERPC64)"
+  "mulh<wd><u> %0,%1,%2"
+  [(set_attr "type" "mul")
+   (set_attr "size" "<bits>")])
+
+(define_insn "<su>mulsi3_highpart_le"
+  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
+	(subreg:SI
+	  (mult:DI (any_extend:DI
+		     (match_operand:SI 1 "gpc_reg_operand" "r"))
+		   (any_extend:DI
+		     (match_operand:SI 2 "gpc_reg_operand" "r")))
+	 4))]
+  "!WORDS_BIG_ENDIAN && !TARGET_POWERPC64"
+  "mulhw<u> %0,%1,%2"
+  [(set_attr "type" "mul")])
+
+(define_insn "<su>muldi3_highpart_le"
+  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
+	(subreg:DI
+	  (mult:TI (any_extend:TI
+		     (match_operand:DI 1 "gpc_reg_operand" "r"))
+		   (any_extend:TI
+		     (match_operand:DI 2 "gpc_reg_operand" "r")))
+	 8))]
+  "!WORDS_BIG_ENDIAN && TARGET_POWERPC64"
+  "mulhd<u> %0,%1,%2"
+  [(set_attr "type" "mul")
+   (set_attr "size" "64")])
+
+(define_insn "<su>mulsi3_highpart_64"
+  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
+	(truncate:SI
+	  (lshiftrt:DI
+	    (mult:DI (any_extend:DI
+		       (match_operand:SI 1 "gpc_reg_operand" "r"))
+		     (any_extend:DI
+		       (match_operand:SI 2 "gpc_reg_operand" "r")))
+	    (const_int 32))))]
+  "TARGET_POWERPC64"
+  "mulhw<u> %0,%1,%2"
+  [(set_attr "type" "mul")])
+
+(define_expand "<u>mul<mode><dmode>3"
+  [(set (match_operand:<DMODE> 0 "gpc_reg_operand")
+	(mult:<DMODE> (any_extend:<DMODE>
+			(match_operand:GPR 1 "gpc_reg_operand"))
+		      (any_extend:<DMODE>
+			(match_operand:GPR 2 "gpc_reg_operand"))))]
+  "!(<MODE>mode == SImode && TARGET_POWERPC64)"
+{
+  rtx l = gen_reg_rtx (<MODE>mode);
+  rtx h = gen_reg_rtx (<MODE>mode);
+  emit_insn (gen_mul<mode>3 (l, operands[1], operands[2]));
+  emit_insn (gen_<su>mul<mode>3_highpart (h, operands[1], operands[2]));
+  emit_move_insn (gen_lowpart (<MODE>mode, operands[0]), l);
+  emit_move_insn (gen_highpart (<MODE>mode, operands[0]), h);
+  DONE;
+})
+
+
 (define_insn "udiv<mode>3"
   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
         (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
@@ -6622,96 +6725,6 @@ (define_insn "*negdi2_noppc64"
   [(set_attr "type" "two")
    (set_attr "length" "8")])
 
-(define_insn "mulsidi3"
-  [(set (match_operand:DI 0 "gpc_reg_operand" "=&r")
-	(mult:DI (sign_extend:DI (match_operand:SI 1 "gpc_reg_operand" "%r"))
-		 (sign_extend:DI (match_operand:SI 2 "gpc_reg_operand" "r"))))]
-  "! TARGET_POWERPC64"
-{
-  return (WORDS_BIG_ENDIAN)
-    ? \"mulhw %0,%1,%2\;mullw %L0,%1,%2\"
-    : \"mulhw %L0,%1,%2\;mullw %0,%1,%2\";
-}
-  [(set_attr "type" "mul")
-   (set_attr "length" "8")])
-
-(define_split
-  [(set (match_operand:DI 0 "gpc_reg_operand" "")
-	(mult:DI (sign_extend:DI (match_operand:SI 1 "gpc_reg_operand" ""))
-		 (sign_extend:DI (match_operand:SI 2 "gpc_reg_operand" ""))))]
-  "! TARGET_POWERPC64 && reload_completed"
-  [(set (match_dup 3)
-	(truncate:SI
-	 (lshiftrt:DI (mult:DI (sign_extend:DI (match_dup 1))
-			       (sign_extend:DI (match_dup 2)))
-		      (const_int 32))))
-   (set (match_dup 4)
-	(mult:SI (match_dup 1)
-		 (match_dup 2)))]
-  "
-{
-  int endian = (WORDS_BIG_ENDIAN == 0);
-  operands[3] = operand_subword (operands[0], endian, 0, DImode);
-  operands[4] = operand_subword (operands[0], 1 - endian, 0, DImode);
-}")
-
-(define_insn "umulsidi3"
-  [(set (match_operand:DI 0 "gpc_reg_operand" "=&r")
-	(mult:DI (zero_extend:DI (match_operand:SI 1 "gpc_reg_operand" "%r"))
-		 (zero_extend:DI (match_operand:SI 2 "gpc_reg_operand" "r"))))]
-  "! TARGET_POWERPC64"
-  "*
-{
-  return (WORDS_BIG_ENDIAN)
-    ? \"mulhwu %0,%1,%2\;mullw %L0,%1,%2\"
-    : \"mulhwu %L0,%1,%2\;mullw %0,%1,%2\";
-}"
-  [(set_attr "type" "mul")
-   (set_attr "length" "8")])
-
-(define_split
-  [(set (match_operand:DI 0 "gpc_reg_operand" "")
-	(mult:DI (zero_extend:DI (match_operand:SI 1 "gpc_reg_operand" ""))
-		 (zero_extend:DI (match_operand:SI 2 "gpc_reg_operand" ""))))]
-  "! TARGET_POWERPC64 && reload_completed"
-  [(set (match_dup 3)
-	(truncate:SI
-	 (lshiftrt:DI (mult:DI (zero_extend:DI (match_dup 1))
-			       (zero_extend:DI (match_dup 2)))
-		      (const_int 32))))
-   (set (match_dup 4)
-	(mult:SI (match_dup 1)
-		 (match_dup 2)))]
-  "
-{
-  int endian = (WORDS_BIG_ENDIAN == 0);
-  operands[3] = operand_subword (operands[0], endian, 0, DImode);
-  operands[4] = operand_subword (operands[0], 1 - endian, 0, DImode);
-}")
-
-(define_insn "smulsi3_highpart"
-  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
-	(truncate:SI
-	 (lshiftrt:DI (mult:DI (sign_extend:DI
-				(match_operand:SI 1 "gpc_reg_operand" "%r"))
-			       (sign_extend:DI
-				(match_operand:SI 2 "gpc_reg_operand" "r")))
-		      (const_int 32))))]
-  ""
-  "mulhw %0,%1,%2"
-  [(set_attr "type" "mul")])
-
-(define_insn "umulsi3_highpart"
-  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
-	(truncate:SI
-	 (lshiftrt:DI (mult:DI (zero_extend:DI
-				(match_operand:SI 1 "gpc_reg_operand" "%r"))
-			       (zero_extend:DI
-				(match_operand:SI 2 "gpc_reg_operand" "r")))
-		      (const_int 32))))]
-  ""
-  "mulhwu %0,%1,%2"
-  [(set_attr "type" "mul")])
 
 ;; Shift by a variable amount is too complex to be worth open-coding.  We
 ;; just handle shifts by constants.
@@ -6758,60 +6771,6 @@ (define_insn "*ashrdisi3_noppc64be"
 \f
 ;; PowerPC64 DImode operations.
 
-(define_insn "smuldi3_highpart"
-  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
-	(truncate:DI
-	 (lshiftrt:TI (mult:TI (sign_extend:TI
-				(match_operand:DI 1 "gpc_reg_operand" "%r"))
-			       (sign_extend:TI
-				(match_operand:DI 2 "gpc_reg_operand" "r")))
-		      (const_int 64))))]
-  "TARGET_POWERPC64"
-  "mulhd %0,%1,%2"
-  [(set_attr "type" "mul")
-   (set_attr "size" "64")])
-
-(define_insn "umuldi3_highpart"
-  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
-	(truncate:DI
-	 (lshiftrt:TI (mult:TI (zero_extend:TI
-				(match_operand:DI 1 "gpc_reg_operand" "%r"))
-			       (zero_extend:TI
-				(match_operand:DI 2 "gpc_reg_operand" "r")))
-		      (const_int 64))))]
-  "TARGET_POWERPC64"
-  "mulhdu %0,%1,%2"
-  [(set_attr "type" "mul")
-   (set_attr "size" "64")])
-
-(define_expand "mulditi3"
-  [(set (match_operand:TI 0 "gpc_reg_operand")
-	(mult:TI (sign_extend:TI (match_operand:DI 1 "gpc_reg_operand"))
-		 (sign_extend:TI (match_operand:DI 2 "gpc_reg_operand"))))]
-  "TARGET_POWERPC64"
-{
-  rtx l = gen_reg_rtx (DImode), h = gen_reg_rtx (DImode);
-  emit_insn (gen_muldi3 (l, operands[1], operands[2]));
-  emit_insn (gen_smuldi3_highpart (h, operands[1], operands[2]));
-  emit_move_insn (gen_lowpart (DImode, operands[0]), l);
-  emit_move_insn (gen_highpart (DImode, operands[0]), h);
-  DONE;
-})
-
-(define_expand "umulditi3"
-  [(set (match_operand:TI 0 "gpc_reg_operand")
-	(mult:TI (zero_extend:TI (match_operand:DI 1 "gpc_reg_operand"))
-		 (zero_extend:TI (match_operand:DI 2 "gpc_reg_operand"))))]
-  "TARGET_POWERPC64"
-{
-  rtx l = gen_reg_rtx (DImode), h = gen_reg_rtx (DImode);
-  emit_insn (gen_muldi3 (l, operands[1], operands[2]));
-  emit_insn (gen_umuldi3_highpart (h, operands[1], operands[2]));
-  emit_move_insn (gen_lowpart (DImode, operands[0]), l);
-  emit_move_insn (gen_highpart (DImode, operands[0]), h);
-  DONE;
-})
-
 (define_insn "*rotldi3_internal4"
   [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
 	(and:DI (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r")
-- 
1.8.1.4

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH 4/4] rs6000: Merge extend*si2 and extend*di2
  2014-09-01 19:53 [PATCH 1/4] rs6000: Merge mulsi3 and muldi3 Segher Boessenkool
  2014-09-01 19:56 ` [PATCH 3/4] rs6000: Merge zero_extend*si2 and zero_extend*di2 Segher Boessenkool
  2014-09-01 19:56 ` [PATCH 2/4] rs6000: Merge and improve highpart and widening muls Segher Boessenkool
@ 2014-09-01 19:57 ` Segher Boessenkool
  2014-09-02  0:33   ` David Edelsohn
  2014-09-02  0:30 ` [PATCH 1/4] rs6000: Merge mulsi3 and muldi3 David Edelsohn
  3 siblings, 1 reply; 8+ messages in thread
From: Segher Boessenkool @ 2014-09-01 19:57 UTC (permalink / raw)
  To: gcc-patches; +Cc: dje.gcc, Segher Boessenkool

Mostly like zero_extend, with two twists.  First, this patch allows to set
"dot" on insn type "exts".  Now we are almost ready to remove insn type
"compare".

Second, this makes lwa_operand reject memory if avoiding Cell microcode.
That way we can easily merge the various extendsidi2 patterns (two had
the same name already :-) ), and it's the right thing to do anyway.

Tested as usual, no regressions.  Is this okay?


Segher


2014-09-01  Segher Boessenkool  <segher@kernel.crashing.org>

gcc/
	* config/rs6000/40x.md (ppc403-integer): Move "exts" to "no dot".
	(ppc403-compare): Add "exts with dot" case.
	* config/rs6000/440.md (ppc440-integer, ppc440-compare): As above.
	* config/rs6000/476.md (ppc476-simple-integer, ppc476-compare): Ditto.
	* config/rs6000/601.md (ppc601-integer, ppc601-compare): Ditto.
	* config/rs6000/603.md (ppc603-integer, ppc603-compare): Ditto.
	* config/rs6000/6xx.md (ppc604-integer, ppc604-compare): Ditto.
	* config/rs6000/7450.md (ppc7450-integer, ppc7450-compare): Ditto.
	* config/rs6000/7xx.md (ppc750-integer, ppc750-compare): Ditto.
	* config/rs6000/cell.md (cell-integer, cell-fast-cmp,
	cell-cmp-microcoded): Similarly.
	* config/rs6000/e300c2c3.md (ppce300c3_iu, ppce300c3_cmp): As before.
	* config/rs6000/e500mc64.md (e500mc64_su, e500mc64_su2): Ditto.
	* config/rs6000/e5500.md (e5500_sfx, e5500_sfx2): Ditto.
	* config/rs6000/e6500.md (e6500_sfx, e6500_sfx2): Ditto.
	* config/rs6000/mpc.md (mpccore-integer, mpccore-compare): Ditto.
	* config/rs6000/power4.md (power4-integer, power4-compare): Ditto.
	* config/rs6000/power5.md (power5-integer, power5-compare): Ditto.
	* config/rs6000/power6.md (power6-exts): Add "no dot" condition.
	(power6-compare): Add "exts with dot" case.
	* config/rs6000/power7.md (power7-integer, power7-compare): As before.
	* config/rs6000/power8.md (power8-1cyc, power8-compare): Ditto.
	* config/rs6000/rs64.md (rs64a-integer, rs64a-compare): Ditto.

	* config/rs6000/predicates.md (lwa_operand): Don't allow memory
	if avoiding Cell microcode.
	* config/rs6000/rs6000.c (rs6000_adjust_cost): Handle exts+dot case.
	(is_cracked_insn): Ditto.
	(insn_must_be_first_in_group): Ditto.
	* config/rs6000/rs6000.md (dot): Adjust comment.
	(cell_micro): Handle exts+dot.
	(extendqidi2, extendhidi2, extendsidi2, *extendsidi2_lfiwax,
	*extendsidi2_nocell, *extendsidi2_nocell, extendqisi2, extendqihi2,
	extendhisi2, 16 anonymous instructions, and 12 splitters): Delete.
	(extendqi<mode>2, *extendqi<mode>2_dot, *extendqi<mode>2_dot2,
	extendhi<mode>2, *extendhi<mode>2, *extendhi<mode>2_noload,
	*extendhi<mode>2_dot, *extendhi<mode>2_dot2, extendsi<mode>2,
	*extendsi<mode>2_dot, *extendsi<mode>2_dot2): New.

---
 gcc/config/rs6000/40x.md        |   6 +-
 gcc/config/rs6000/440.md        |   6 +-
 gcc/config/rs6000/476.md        |   6 +-
 gcc/config/rs6000/601.md        |   6 +-
 gcc/config/rs6000/603.md        |   6 +-
 gcc/config/rs6000/6xx.md        |   6 +-
 gcc/config/rs6000/7450.md       |   6 +-
 gcc/config/rs6000/7xx.md        |   6 +-
 gcc/config/rs6000/cell.md       |   8 +-
 gcc/config/rs6000/e300c2c3.md   |   4 +-
 gcc/config/rs6000/e500mc64.md   |   6 +-
 gcc/config/rs6000/e5500.md      |   6 +-
 gcc/config/rs6000/e6500.md      |   6 +-
 gcc/config/rs6000/mpc.md        |   6 +-
 gcc/config/rs6000/power4.md     |   6 +-
 gcc/config/rs6000/power5.md     |   6 +-
 gcc/config/rs6000/power6.md     |   5 +-
 gcc/config/rs6000/power7.md     |   6 +-
 gcc/config/rs6000/power8.md     |   6 +-
 gcc/config/rs6000/predicates.md |   3 +
 gcc/config/rs6000/rs6000.c      |   5 +
 gcc/config/rs6000/rs6000.md     | 436 +++++++++-------------------------------
 gcc/config/rs6000/rs64.md       |   6 +-
 23 files changed, 162 insertions(+), 401 deletions(-)

diff --git a/gcc/config/rs6000/40x.md b/gcc/config/rs6000/40x.md
index b29e06a..0903536 100644
--- a/gcc/config/rs6000/40x.md
+++ b/gcc/config/rs6000/40x.md
@@ -36,8 +36,8 @@ (define_insn_reservation "ppc403-store" 2
   "iu_40x")
 
 (define_insn_reservation "ppc403-integer" 1
-  (and (ior (eq_attr "type" "integer,insert,trap,cntlz,exts,isel")
-	    (and (eq_attr "type" "add,logical,shift")
+  (and (ior (eq_attr "type" "integer,insert,trap,cntlz,isel")
+	    (and (eq_attr "type" "add,logical,shift,exts")
 		 (eq_attr "dot" "no")))
        (eq_attr "cpu" "ppc403,ppc405"))
   "iu_40x")
@@ -54,7 +54,7 @@ (define_insn_reservation "ppc403-three" 1
 
 (define_insn_reservation "ppc403-compare" 3
   (and (ior (eq_attr "type" "cmp,compare")
-	    (and (eq_attr "type" "add,logical,shift")
+	    (and (eq_attr "type" "add,logical,shift,exts")
 		 (eq_attr "dot" "yes")))
        (eq_attr "cpu" "ppc403,ppc405"))
   "iu_40x,nothing,bpu_40x")
diff --git a/gcc/config/rs6000/440.md b/gcc/config/rs6000/440.md
index f956bd6..ff91fdb 100644
--- a/gcc/config/rs6000/440.md
+++ b/gcc/config/rs6000/440.md
@@ -53,8 +53,8 @@ (define_insn_reservation "ppc440-fpstore" 3
   "ppc440_issue,ppc440_l_pipe")
 
 (define_insn_reservation "ppc440-integer" 1
-  (and (ior (eq_attr "type" "integer,insert,trap,cntlz,exts,isel")
-	    (and (eq_attr "type" "add,logical,shift")
+  (and (ior (eq_attr "type" "integer,insert,trap,cntlz,isel")
+	    (and (eq_attr "type" "add,logical,shift,exts")
 		 (eq_attr "dot" "no")))
        (eq_attr "cpu" "ppc440"))
   "ppc440_issue,ppc440_i_pipe|ppc440_j_pipe")
@@ -96,7 +96,7 @@ (define_insn_reservation "ppc440-branch" 1
 
 (define_insn_reservation "ppc440-compare" 2
   (and (ior (eq_attr "type" "cmp,compare,cr_logical,delayed_cr,mfcr")
-	    (and (eq_attr "type" "add,logical,shift")
+	    (and (eq_attr "type" "add,logical,shift,exts")
 		 (eq_attr "dot" "yes")))
        (eq_attr "cpu" "ppc440"))
   "ppc440_issue,ppc440_i_pipe")
diff --git a/gcc/config/rs6000/476.md b/gcc/config/rs6000/476.md
index 4c879f4..9bfd6b6 100644
--- a/gcc/config/rs6000/476.md
+++ b/gcc/config/rs6000/476.md
@@ -63,8 +63,8 @@ (define_insn_reservation "ppc476-fpstore" 4
    ppc476_lj_pipe")
 
 (define_insn_reservation "ppc476-simple-integer" 1
-  (and (ior (eq_attr "type" "integer,insert,exts")
-	    (and (eq_attr "type" "add,logical,shift")
+  (and (ior (eq_attr "type" "integer,insert")
+	    (and (eq_attr "type" "add,logical,shift,exts")
 		 (eq_attr "dot" "no")))
        (eq_attr "cpu" "ppc476"))
   "ppc476_issue,\
@@ -78,7 +78,7 @@ (define_insn_reservation "ppc476-complex-integer" 1
 
 (define_insn_reservation "ppc476-compare" 4
   (and (ior (eq_attr "type" "compare,mfcr,mfcrf,mtcr,mfjmpr,mtjmpr")
-	    (and (eq_attr "type" "add,logical,shift")
+	    (and (eq_attr "type" "add,logical,shift,exts")
 		 (eq_attr "dot" "yes")))
        (eq_attr "cpu" "ppc476"))
   "ppc476_issue,\
diff --git a/gcc/config/rs6000/601.md b/gcc/config/rs6000/601.md
index e8207a8..de51cbf 100644
--- a/gcc/config/rs6000/601.md
+++ b/gcc/config/rs6000/601.md
@@ -45,8 +45,8 @@ (define_insn_reservation "ppc601-fpstore" 3
   "iu_ppc601+fpu_ppc601")
 
 (define_insn_reservation "ppc601-integer" 1
-  (and (ior (eq_attr "type" "integer,add,insert,trap,cntlz,exts,isel")
-	    (and (eq_attr "type" "shift")
+  (and (ior (eq_attr "type" "integer,add,insert,trap,cntlz,isel")
+	    (and (eq_attr "type" "shift,exts")
 		 (eq_attr "dot" "no")))
        (eq_attr "cpu" "ppc601"))
   "iu_ppc601")
@@ -75,7 +75,7 @@ (define_insn_reservation "ppc601-idiv" 36
 ; execute on the branch unit.
 (define_insn_reservation "ppc601-compare" 3
   (and (ior (eq_attr "type" "cmp,compare")
-	    (and (eq_attr "type" "shift")
+	    (and (eq_attr "type" "shift,exts")
 		 (eq_attr "dot" "yes")))
        (eq_attr "cpu" "ppc601"))
   "iu_ppc601,nothing,bpu_ppc601")
diff --git a/gcc/config/rs6000/603.md b/gcc/config/rs6000/603.md
index 871957a..dc03018 100644
--- a/gcc/config/rs6000/603.md
+++ b/gcc/config/rs6000/603.md
@@ -58,8 +58,8 @@ (define_insn_reservation "ppc603-storec" 8
   "lsu_603")
 
 (define_insn_reservation "ppc603-integer" 1
-  (and (ior (eq_attr "type" "integer,insert,trap,cntlz,exts,isel")
-	    (and (eq_attr "type" "add,logical,shift")
+  (and (ior (eq_attr "type" "integer,insert,trap,cntlz,isel")
+	    (and (eq_attr "type" "add,logical,shift,exts")
 		 (eq_attr "dot" "no")))
        (eq_attr "cpu" "ppc603"))
   "iu_603")
@@ -94,7 +94,7 @@ (define_insn_reservation "ppc603-idiv" 37
 
 (define_insn_reservation "ppc603-compare" 3
   (and (ior (eq_attr "type" "cmp,compare")
-	    (and (eq_attr "type" "add,logical,shift")
+	    (and (eq_attr "type" "add,logical,shift,exts")
 		 (eq_attr "dot" "yes")))
        (eq_attr "cpu" "ppc603"))
   "iu_603,nothing,bpu_603")
diff --git a/gcc/config/rs6000/6xx.md b/gcc/config/rs6000/6xx.md
index 9d6ba05..db83469 100644
--- a/gcc/config/rs6000/6xx.md
+++ b/gcc/config/rs6000/6xx.md
@@ -73,8 +73,8 @@ (define_insn_reservation "ppc630-llsc" 4
   "lsu_6xx")
   
 (define_insn_reservation "ppc604-integer" 1
-  (and (ior (eq_attr "type" "integer,insert,trap,cntlz,exts,isel")
-	    (and (eq_attr "type" "add,logical,shift")
+  (and (ior (eq_attr "type" "integer,insert,trap,cntlz,isel")
+	    (and (eq_attr "type" "add,logical,shift,exts")
 		 (eq_attr "dot" "no")))
        (eq_attr "cpu" "ppc604,ppc604e,ppc620,ppc630"))
   "iu1_6xx|iu2_6xx")
@@ -148,7 +148,7 @@ (define_insn_reservation "ppc620-ldiv" 37
 
 (define_insn_reservation "ppc604-compare" 3
   (and (ior (eq_attr "type" "cmp,compare")
-	    (and (eq_attr "type" "add,logical,shift")
+	    (and (eq_attr "type" "add,logical,shift,exts")
 		 (eq_attr "dot" "yes")))
        (eq_attr "cpu" "ppc604,ppc604e,ppc620,ppc630"))
   "(iu1_6xx|iu2_6xx)")
diff --git a/gcc/config/rs6000/7450.md b/gcc/config/rs6000/7450.md
index 4271efa..3679c79 100644
--- a/gcc/config/rs6000/7450.md
+++ b/gcc/config/rs6000/7450.md
@@ -73,8 +73,8 @@ (define_insn_reservation "ppc7450-sync" 35
   "ppc7450_du,lsu_7450")
 
 (define_insn_reservation "ppc7450-integer" 1
-  (and (ior (eq_attr "type" "integer,insert,trap,cntlz,exts,isel")
-	    (and (eq_attr "type" "add,logical,shift")
+  (and (ior (eq_attr "type" "integer,insert,trap,cntlz,isel")
+	    (and (eq_attr "type" "add,logical,shift,exts")
 		 (eq_attr "dot" "no")))
        (eq_attr "cpu" "ppc7450"))
   "ppc7450_du,iu1_7450|iu2_7450|iu3_7450")
@@ -109,7 +109,7 @@ (define_insn_reservation "ppc7450-idiv" 23
 
 (define_insn_reservation "ppc7450-compare" 2
   (and (ior (eq_attr "type" "cmp,compare")
-	    (and (eq_attr "type" "add,logical,shift")
+	    (and (eq_attr "type" "add,logical,shift,exts")
 		 (eq_attr "dot" "yes")))
        (eq_attr "cpu" "ppc7450"))
   "ppc7450_du,(iu1_7450|iu2_7450|iu3_7450)")
diff --git a/gcc/config/rs6000/7xx.md b/gcc/config/rs6000/7xx.md
index aba4a77..b27fe35 100644
--- a/gcc/config/rs6000/7xx.md
+++ b/gcc/config/rs6000/7xx.md
@@ -61,8 +61,8 @@ (define_insn_reservation "ppc750-storec" 8
   "ppc750_du,lsu_7xx")
 
 (define_insn_reservation "ppc750-integer" 1
-  (and (ior (eq_attr "type" "integer,insert,trap,cntlz,exts,isel")
-	    (and (eq_attr "type" "add,logical,shift")
+  (and (ior (eq_attr "type" "integer,insert,trap,cntlz,isel")
+	    (and (eq_attr "type" "add,logical,shift,exts")
 		 (eq_attr "dot" "no")))
        (eq_attr "cpu" "ppc750,ppc7400"))
   "ppc750_du,iu1_7xx|iu2_7xx")
@@ -102,7 +102,7 @@ (define_insn_reservation "ppc750-idiv" 19
 
 (define_insn_reservation "ppc750-compare" 2
   (and (ior (eq_attr "type" "cmp,compare")
-	    (and (eq_attr "type" "add,logical,shift")
+	    (and (eq_attr "type" "add,logical,shift,exts")
 		 (eq_attr "dot" "yes")))
        (eq_attr "cpu" "ppc750,ppc7400"))
   "ppc750_du,(iu1_7xx|iu2_7xx)")
diff --git a/gcc/config/rs6000/cell.md b/gcc/config/rs6000/cell.md
index b37cdba..f1ce352 100644
--- a/gcc/config/rs6000/cell.md
+++ b/gcc/config/rs6000/cell.md
@@ -166,8 +166,8 @@ (define_insn_reservation "cell-vecstore" 1
 
 ;; Integer latency is 2 cycles
 (define_insn_reservation "cell-integer" 2
-  (and (ior (eq_attr "type" "integer,trap,cntlz,exts,isel")
-	    (and (eq_attr "type" "add,logical,shift")
+  (and (ior (eq_attr "type" "integer,trap,cntlz,isel")
+	    (and (eq_attr "type" "add,logical,shift,exts")
 		 (eq_attr "dot" "no"))
 	    (and (eq_attr "type" "insert")
 		 (eq_attr "size" "64")))
@@ -202,7 +202,7 @@ (define_insn_reservation "cell-cmp" 1
 ;; add, addo, sub, subo, alter cr0, rldcli, rlwinm 
 (define_insn_reservation "cell-fast-cmp" 2
   (and (ior (eq_attr "type" "compare")
-	    (and (eq_attr "type" "add,logical,shift")
+	    (and (eq_attr "type" "add,logical,shift,exts")
 		 (eq_attr "dot" "yes")))
        (eq_attr "cpu" "cell")
        (eq_attr "cell_micro" "not"))
@@ -210,7 +210,7 @@ (define_insn_reservation "cell-fast-cmp" 2
 
 (define_insn_reservation "cell-cmp-microcoded" 9
   (and (ior (eq_attr "type" "compare")
-	    (and (eq_attr "type" "add,logical,shift")
+	    (and (eq_attr "type" "add,logical,shift,exts")
 		 (eq_attr "dot" "yes")))
        (eq_attr "cpu" "cell")
        (eq_attr "cell_micro" "always"))
diff --git a/gcc/config/rs6000/e300c2c3.md b/gcc/config/rs6000/e300c2c3.md
index f80ef30..276b9e9 100644
--- a/gcc/config/rs6000/e300c2c3.md
+++ b/gcc/config/rs6000/e300c2c3.md
@@ -84,7 +84,7 @@ (define_reservation "ppce300c3_iu_stage0"
 ;; Compares can be executed either one of the IU or SRU
 (define_insn_reservation "ppce300c3_cmp" 1
   (and (ior (eq_attr "type" "cmp,compare")
-	    (and (eq_attr "type" "add,logical,shift")
+	    (and (eq_attr "type" "add,logical,shift,exts")
 		 (eq_attr "dot" "yes")))
        (ior (eq_attr "cpu" "ppce300c2") (eq_attr "cpu" "ppce300c3")))
   "ppce300c3_decode,ppce300c3_issue+(ppce300c3_iu_stage0|ppce300c3_sru_stage0) \
@@ -93,7 +93,7 @@ (define_insn_reservation "ppce300c3_cmp" 1
 ;; Other one cycle IU insns
 (define_insn_reservation "ppce300c3_iu" 1
   (and (ior (eq_attr "type" "integer,insert,isel")
-	    (and (eq_attr "type" "add,logical,shift")
+	    (and (eq_attr "type" "add,logical,shift,exts")
 		 (eq_attr "dot" "no")))
        (ior (eq_attr "cpu" "ppce300c2") (eq_attr "cpu" "ppce300c3")))
   "ppce300c3_decode,ppce300c3_issue+ppce300c3_iu_stage0+ppce300c3_retire")
diff --git a/gcc/config/rs6000/e500mc64.md b/gcc/config/rs6000/e500mc64.md
index 4582334..dc3eb6a 100644
--- a/gcc/config/rs6000/e500mc64.md
+++ b/gcc/config/rs6000/e500mc64.md
@@ -69,8 +69,8 @@ (define_reservation "e500mc64_su_stage0"
 
 ;; Simple SU insns.
 (define_insn_reservation "e500mc64_su" 1
-  (and (ior (eq_attr "type" "integer,insert,cntlz,exts")
-	    (and (eq_attr "type" "add,logical")
+  (and (ior (eq_attr "type" "integer,insert,cntlz")
+	    (and (eq_attr "type" "add,logical,exts")
 		 (eq_attr "dot" "no"))
 	    (and (eq_attr "type" "shift")
 		 (eq_attr "dot" "no")
@@ -80,7 +80,7 @@ (define_insn_reservation "e500mc64_su" 1
 
 (define_insn_reservation "e500mc64_su2" 2
   (and (ior (eq_attr "type" "cmp,compare,trap")
-	    (and (eq_attr "type" "add,logical")
+	    (and (eq_attr "type" "add,logical,exts")
 		 (eq_attr "dot" "yes"))
 	    (and (eq_attr "type" "shift")
 		 (eq_attr "dot" "yes")
diff --git a/gcc/config/rs6000/e5500.md b/gcc/config/rs6000/e5500.md
index 8d784e0..3cad8bd 100644
--- a/gcc/config/rs6000/e5500.md
+++ b/gcc/config/rs6000/e5500.md
@@ -56,8 +56,8 @@ (define_reservation "e5500_sfx"
 
 ;; SFX.
 (define_insn_reservation "e5500_sfx" 1
-  (and (ior (eq_attr "type" "integer,insert,cntlz,exts")
-	    (and (eq_attr "type" "add,logical")
+  (and (ior (eq_attr "type" "integer,insert,cntlz")
+	    (and (eq_attr "type" "add,logical,exts")
 		 (eq_attr "dot" "no"))
 	    (and (eq_attr "type" "shift")
 		 (eq_attr "var_shift" "no")))
@@ -66,7 +66,7 @@ (define_insn_reservation "e5500_sfx" 1
 
 (define_insn_reservation "e5500_sfx2" 2
   (and (ior (eq_attr "type" "cmp,compare,trap")
-	    (and (eq_attr "type" "add,logical")
+	    (and (eq_attr "type" "add,logical,exts")
 		 (eq_attr "dot"  "yes"))
 	    (and (eq_attr "type" "shift")
 		 (eq_attr "dot"  "yes")
diff --git a/gcc/config/rs6000/e6500.md b/gcc/config/rs6000/e6500.md
index a013a94..9d4b483 100644
--- a/gcc/config/rs6000/e6500.md
+++ b/gcc/config/rs6000/e6500.md
@@ -59,8 +59,8 @@ (define_reservation "e6500_sfx"
 
 ;; SFX.
 (define_insn_reservation "e6500_sfx" 1
-  (and (ior (eq_attr "type" "integer,insert,cntlz,exts")
-	    (and (eq_attr "type" "add,logical")
+  (and (ior (eq_attr "type" "integer,insert,cntlz")
+	    (and (eq_attr "type" "add,logical,exts")
 		 (eq_attr "dot"  "no"))
 	    (and (eq_attr "type" "shift")
 		 (eq_attr "dot"  "no")
@@ -70,7 +70,7 @@ (define_insn_reservation "e6500_sfx" 1
 
 (define_insn_reservation "e6500_sfx2" 2
   (and (ior (eq_attr "type" "cmp,compare,trap")
-	    (and (eq_attr "type" "add,logical")
+	    (and (eq_attr "type" "add,logical,exts")
 		 (eq_attr "dot"  "yes"))
 	    (and (eq_attr "type" "shift")
 		 (eq_attr "dot"  "yes")
diff --git a/gcc/config/rs6000/mpc.md b/gcc/config/rs6000/mpc.md
index 2f11a86..9ac611a 100644
--- a/gcc/config/rs6000/mpc.md
+++ b/gcc/config/rs6000/mpc.md
@@ -41,8 +41,8 @@ (define_insn_reservation "mpccore-fpload" 2
   "lsu_mpc")
 
 (define_insn_reservation "mpccore-integer" 1
-  (and (ior (eq_attr "type" "integer,insert,trap,cntlz,exts,isel")
-	    (and (eq_attr "type" "add,logical,shift")
+  (and (ior (eq_attr "type" "integer,insert,trap,cntlz,isel")
+	    (and (eq_attr "type" "add,logical,shift,exts")
 		 (eq_attr "dot" "no")))
        (eq_attr "cpu" "mpccore"))
   "iu_mpc")
@@ -70,7 +70,7 @@ (define_insn_reservation "mpccore-idiv" 6
 
 (define_insn_reservation "mpccore-compare" 3
   (and (ior (eq_attr "type" "cmp,compare")
-	    (and (eq_attr "type" "add,logical,shift")
+	    (and (eq_attr "type" "add,logical,shift,exts")
 		 (eq_attr "dot" "yes")))
        (eq_attr "cpu" "mpccore"))
   "iu_mpc,nothing,bpu_mpc")
diff --git a/gcc/config/rs6000/power4.md b/gcc/config/rs6000/power4.md
index e46914e..a436ec7 100644
--- a/gcc/config/rs6000/power4.md
+++ b/gcc/config/rs6000/power4.md
@@ -210,8 +210,8 @@ (define_insn_reservation "power4-llsc" 11
 
 ; Integer latency is 2 cycles
 (define_insn_reservation "power4-integer" 2
-  (and (ior (eq_attr "type" "integer,trap,cntlz,exts,isel")
-	    (and (eq_attr "type" "add,logical,shift")
+  (and (ior (eq_attr "type" "integer,trap,cntlz,isel")
+	    (and (eq_attr "type" "add,logical,shift,exts")
 		 (eq_attr "dot" "no"))
 	    (and (eq_attr "type" "insert")
 		 (eq_attr "size" "64")))
@@ -258,7 +258,7 @@ (define_insn_reservation "power4-cmp" 3
 
 (define_insn_reservation "power4-compare" 2
   (and (ior (eq_attr "type" "compare")
-	    (and (eq_attr "type" "shift")
+	    (and (eq_attr "type" "shift,exts")
 		 (eq_attr "dot" "yes")))
        (eq_attr "cpu" "power4"))
   "(du1_power4+du2_power4|du2_power4+du3_power4|du3_power4+du4_power4),\
diff --git a/gcc/config/rs6000/power5.md b/gcc/config/rs6000/power5.md
index 198db82..530c255 100644
--- a/gcc/config/rs6000/power5.md
+++ b/gcc/config/rs6000/power5.md
@@ -166,8 +166,8 @@ (define_insn_reservation "power5-llsc" 11
 
 ; Integer latency is 2 cycles
 (define_insn_reservation "power5-integer" 2
-  (and (ior (eq_attr "type" "integer,trap,cntlz,exts,isel,popcnt")
-	    (and (eq_attr "type" "add,logical,shift")
+  (and (ior (eq_attr "type" "integer,trap,cntlz,isel,popcnt")
+	    (and (eq_attr "type" "add,logical,shift,exts")
 		 (eq_attr "dot" "no"))
 	    (and (eq_attr "type" "insert")
 		 (eq_attr "size" "64")))
@@ -211,7 +211,7 @@ (define_insn_reservation "power5-cmp" 3
 
 (define_insn_reservation "power5-compare" 2
   (and (ior (eq_attr "type" "compare")
-	    (and (eq_attr "type" "shift")
+	    (and (eq_attr "type" "shift,exts")
 		 (eq_attr "dot" "yes")))
        (eq_attr "cpu" "power5"))
   "du1_power5+du2_power5,iu1_power5,iu2_power5")
diff --git a/gcc/config/rs6000/power6.md b/gcc/config/rs6000/power6.md
index e4a82a2..695f642 100644
--- a/gcc/config/rs6000/power6.md
+++ b/gcc/config/rs6000/power6.md
@@ -235,6 +235,7 @@ (define_insn_reservation "power6-isel" 1
 
 (define_insn_reservation "power6-exts" 1
   (and (eq_attr "type" "exts")
+       (eq_attr "dot" "no")
        (eq_attr "cpu" "power6"))
   "FXU_power6")
 
@@ -333,7 +334,9 @@ (define_insn_reservation "power6-cmp" 1
   "FXU_power6")
 
 (define_insn_reservation "power6-compare" 1
-  (and (eq_attr "type" "compare")
+  (and (ior (eq_attr "type" "compare")
+            (and (eq_attr "type" "exts")
+                 (eq_attr "dot" "yes")))
        (eq_attr "cpu" "power6"))
   "FXU_power6")
 
diff --git a/gcc/config/rs6000/power7.md b/gcc/config/rs6000/power7.md
index b2a0caf..8be2879 100644
--- a/gcc/config/rs6000/power7.md
+++ b/gcc/config/rs6000/power7.md
@@ -174,8 +174,8 @@ (define_insn_reservation "power7-sync" 11
 
 ; FX Unit
 (define_insn_reservation "power7-integer" 1
-  (and (ior (eq_attr "type" "integer,insert,trap,exts,isel,popcnt")
-	    (and (eq_attr "type" "add,logical,shift")
+  (and (ior (eq_attr "type" "integer,insert,trap,isel,popcnt")
+	    (and (eq_attr "type" "add,logical,shift,exts")
 		 (eq_attr "dot" "no")))
        (eq_attr "cpu" "power7"))
   "DU_power7,FXU_power7")
@@ -204,7 +204,7 @@ (define_insn_reservation "power7-cmp" 1
 
 (define_insn_reservation "power7-compare" 2
   (and (ior (eq_attr "type" "compare")
-	    (and (eq_attr "type" "shift")
+	    (and (eq_attr "type" "shift,exts")
 		 (eq_attr "dot" "yes")))
        (eq_attr "cpu" "power7"))
   "DU2F_power7,FXU_power7,FXU_power7")
diff --git a/gcc/config/rs6000/power8.md b/gcc/config/rs6000/power8.md
index c7c0aa9..4b03ac2 100644
--- a/gcc/config/rs6000/power8.md
+++ b/gcc/config/rs6000/power8.md
@@ -168,8 +168,8 @@ (define_insn_reservation "power8-sync" 1
 
 ; FX Unit
 (define_insn_reservation "power8-1cyc" 1
-  (and (ior (eq_attr "type" "integer,insert,trap,exts,isel")
-	    (and (eq_attr "type" "add,logical,shift")
+  (and (ior (eq_attr "type" "integer,insert,trap,isel")
+	    (and (eq_attr "type" "add,logical,shift,exts")
 		 (eq_attr "dot" "no")))
        (eq_attr "cpu" "power8"))
   "DU_any_power8,FXU_power8")
@@ -216,7 +216,7 @@ (define_insn_reservation "power8-fast-compare" 2
 ; shift with dot : rlwinm./slwi./rlwnm./slw./etc
 (define_insn_reservation "power8-compare" 2
   (and (ior (eq_attr "type" "compare")
-	    (and (eq_attr "type" "shift")
+	    (and (eq_attr "type" "shift,exts")
 		 (eq_attr "dot" "yes")))
        (eq_attr "cpu" "power8"))
   "DU_cracked_power8,FXU_power8,FXU_power8")
diff --git a/gcc/config/rs6000/predicates.md b/gcc/config/rs6000/predicates.md
index 0c5b996..ef7bc69 100644
--- a/gcc/config/rs6000/predicates.md
+++ b/gcc/config/rs6000/predicates.md
@@ -1022,6 +1022,9 @@ (define_predicate "lwa_operand"
     return true;
   if (!memory_operand (inner, mode))
     return false;
+  if (!rs6000_gen_cell_microcode)
+    return false;
+
   addr = XEXP (inner, 0);
   if (GET_CODE (addr) == PRE_INC
       || GET_CODE (addr) == PRE_DEC
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index d13e71e..5b1aa55 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -26444,6 +26444,7 @@ rs6000_adjust_cost (rtx_insn *insn, rtx link, rtx_insn *dep_insn, int cost)
                 case TYPE_CR_LOGICAL:
                 case TYPE_DELAYED_CR:
 		  return cost + 2;
+                case TYPE_EXTS:
                 case TYPE_MUL:
 		  if (get_attr_dot (dep_insn) == DOT_YES)
 		    return cost + 2;
@@ -26736,6 +26737,8 @@ is_cracked_insn (rtx insn)
 	      && get_attr_update (insn) == UPDATE_YES)
 	  || type == TYPE_DELAYED_CR
 	  || type == TYPE_COMPARE
+	  || (type == TYPE_EXTS
+	      && get_attr_dot (insn) == DOT_YES)
 	  || (type == TYPE_SHIFT
 	      && get_attr_dot (insn) == DOT_YES
 	      && get_attr_var_shift (insn) == VAR_SHIFT_NO)
@@ -27624,6 +27627,7 @@ insn_must_be_first_in_group (rtx insn)
           return true;
         case TYPE_MUL:
         case TYPE_SHIFT:
+        case TYPE_EXTS:
           if (get_attr_dot (insn) == DOT_YES)
             return true;
           else
@@ -27665,6 +27669,7 @@ insn_must_be_first_in_group (rtx insn)
         case TYPE_MTJMPR:
           return true;
         case TYPE_SHIFT:
+        case TYPE_EXTS:
         case TYPE_MUL:
           if (get_attr_dot (insn) == DOT_YES)
             return true;
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index 6cd6404..d2bc07d 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -181,7 +181,7 @@ (define_attr "type"
 (define_attr "size" "8,16,32,64" (const_string "32"))
 
 ;; Is this instruction record form ("dot", signed compare to 0, writing CR0)?
-;; This is used for add, logical, shift, mul.
+;; This is used for add, logical, shift, exts, mul.
 (define_attr "dot" "no,yes" (const_string "no"))
 
 ;; Does this instruction sign-extend its result?
@@ -254,7 +254,7 @@ (define_attr "cpu"
 ; The default for load extended, the recorded instructions and rotate/shifts by a variable is always microcoded
 (define_attr "cell_micro" "not,conditional,always"
   (if_then_else (ior (eq_attr "type" "compare")
-		     (and (eq_attr "type" "shift,mul")
+		     (and (eq_attr "type" "shift,exts,mul")
 			  (eq_attr "dot" "yes"))
 		     (and (eq_attr "type" "load")
 			  (eq_attr "sign_extend" "yes"))
@@ -726,150 +726,124 @@ (define_insn_and_split "*zero_extendsi<mode>2_dot2"
    (set_attr "length" "4,8")])
 
 
-(define_insn "extendqidi2"
-  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
-	(sign_extend:DI (match_operand:QI 1 "gpc_reg_operand" "r")))]
-  "TARGET_POWERPC64"
+(define_insn "extendqi<mode>2"
+  [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r")
+	(sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r")))]
+  ""
   "extsb %0,%1"
   [(set_attr "type" "exts")])
 
-(define_insn ""
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
-	(compare:CC (sign_extend:DI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
+(define_insn_and_split "*extendqi<mode>2_dot"
+  [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
+	(compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
 		    (const_int 0)))
-   (clobber (match_scratch:DI 2 "=r,r"))]
-  "TARGET_64BIT"
+   (clobber (match_scratch:EXTQI 0 "=r,r"))]
+  "rs6000_gen_cell_microcode"
   "@
-   extsb. %2,%1
+   extsb. %0,%1
    #"
-  [(set_attr "type" "compare")
-   (set_attr "length" "4,8")])
-
-(define_split
-  [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
-	(compare:CC (sign_extend:DI (match_operand:QI 1 "gpc_reg_operand" ""))
-		    (const_int 0)))
-   (clobber (match_scratch:DI 2 ""))]
-  "TARGET_POWERPC64 && reload_completed"
-  [(set (match_dup 2)
-	(sign_extend:DI (match_dup 1)))
-   (set (match_dup 0)
-	(compare:CC (match_dup 2)
+  "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
+  [(set (match_dup 0)
+	(sign_extend:EXTQI (match_dup 1)))
+   (set (match_dup 2)
+	(compare:CC (match_dup 0)
 		    (const_int 0)))]
-  "")
+  ""
+  [(set_attr "type" "exts")
+   (set_attr "dot" "yes")
+   (set_attr "length" "4,8")])
 
-(define_insn ""
+(define_insn_and_split "*extendqi<mode>2_dot2"
   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
-	(compare:CC (sign_extend:DI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
+	(compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
 		    (const_int 0)))
-   (set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
-	(sign_extend:DI (match_dup 1)))]
-  "TARGET_64BIT"
+   (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
+	(sign_extend:EXTQI (match_dup 1)))]
+  "rs6000_gen_cell_microcode"
   "@
    extsb. %0,%1
    #"
-  [(set_attr "type" "compare")
-   (set_attr "length" "4,8")])
-
-(define_split
-  [(set (match_operand:CC 2 "cc_reg_not_micro_cr0_operand" "")
-	(compare:CC (sign_extend:DI (match_operand:QI 1 "gpc_reg_operand" ""))
-		    (const_int 0)))
-   (set (match_operand:DI 0 "gpc_reg_operand" "")
-	(sign_extend:DI (match_dup 1)))]
-  "TARGET_POWERPC64 && reload_completed"
+  "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
   [(set (match_dup 0)
-	(sign_extend:DI (match_dup 1)))
+	(sign_extend:EXTQI (match_dup 1)))
    (set (match_dup 2)
 	(compare:CC (match_dup 0)
 		    (const_int 0)))]
-  "")
+  ""
+  [(set_attr "type" "exts")
+   (set_attr "dot" "yes")
+   (set_attr "length" "4,8")])
 
-(define_expand "extendhidi2"
-  [(set (match_operand:DI 0 "gpc_reg_operand" "")
-	(sign_extend:DI (match_operand:HI 1 "gpc_reg_operand" "")))]
-  "TARGET_POWERPC64"
+
+(define_expand "extendhi<mode>2"
+  [(set (match_operand:EXTHI 0 "gpc_reg_operand" "")
+	(sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "")))]
+  ""
   "")
 
-(define_insn ""
-  [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
-	(sign_extend:DI (match_operand:HI 1 "reg_or_mem_operand" "m,r")))]
-  "TARGET_POWERPC64 && rs6000_gen_cell_microcode"
+(define_insn "*extendhi<mode>2"
+  [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
+	(sign_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r")))]
+  "rs6000_gen_cell_microcode"
   "@
    lha%U1%X1 %0,%1
    extsh %0,%1"
   [(set_attr "type" "load,exts")
    (set_attr "sign_extend" "yes")])
 
-(define_insn ""
-  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
-	(sign_extend:DI (match_operand:HI 1 "gpc_reg_operand" "r")))]
-  "TARGET_POWERPC64 && !rs6000_gen_cell_microcode"
+(define_insn "*extendhi<mode>2_noload"
+  [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r")
+        (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r")))]
+  "!rs6000_gen_cell_microcode"
   "extsh %0,%1"
   [(set_attr "type" "exts")])
 
-(define_insn ""
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
-	(compare:CC (sign_extend:DI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
+(define_insn_and_split "*extendhi<mode>2_dot"
+  [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
+	(compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
 		    (const_int 0)))
-   (clobber (match_scratch:DI 2 "=r,r"))]
-  "TARGET_64BIT"
+   (clobber (match_scratch:EXTHI 0 "=r,r"))]
+  "rs6000_gen_cell_microcode"
   "@
-   extsh. %2,%1
+   extsh. %0,%1
    #"
-  [(set_attr "type" "compare")
-   (set_attr "length" "4,8")])
-
-(define_split
-  [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
-	(compare:CC (sign_extend:DI (match_operand:HI 1 "gpc_reg_operand" ""))
-		    (const_int 0)))
-   (clobber (match_scratch:DI 2 ""))]
-  "TARGET_POWERPC64 && reload_completed"
-  [(set (match_dup 2)
-	(sign_extend:DI (match_dup 1)))
-   (set (match_dup 0)
-	(compare:CC (match_dup 2)
+  "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
+  [(set (match_dup 0)
+	(sign_extend:EXTHI (match_dup 1)))
+   (set (match_dup 2)
+	(compare:CC (match_dup 0)
 		    (const_int 0)))]
-  "")
+  ""
+  [(set_attr "type" "exts")
+   (set_attr "dot" "yes")
+   (set_attr "length" "4,8")])
 
-(define_insn ""
+(define_insn_and_split "*extendhi<mode>2_dot2"
   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
-	(compare:CC (sign_extend:DI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
+	(compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
 		    (const_int 0)))
-   (set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
-	(sign_extend:DI (match_dup 1)))]
-  "TARGET_64BIT"
+   (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
+	(sign_extend:EXTHI (match_dup 1)))]
+  "rs6000_gen_cell_microcode"
   "@
    extsh. %0,%1
    #"
-  [(set_attr "type" "compare")
-   (set_attr "length" "4,8")])
-
-(define_split
-  [(set (match_operand:CC 2 "cc_reg_not_micro_cr0_operand" "")
-	(compare:CC (sign_extend:DI (match_operand:HI 1 "gpc_reg_operand" ""))
-		    (const_int 0)))
-   (set (match_operand:DI 0 "gpc_reg_operand" "")
-	(sign_extend:DI (match_dup 1)))]
-  "TARGET_POWERPC64 && reload_completed"
+  "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
   [(set (match_dup 0)
-	(sign_extend:DI (match_dup 1)))
+	(sign_extend:EXTHI (match_dup 1)))
    (set (match_dup 2)
 	(compare:CC (match_dup 0)
 		    (const_int 0)))]
-  "")
+  ""
+  [(set_attr "type" "exts")
+   (set_attr "dot" "yes")
+   (set_attr "length" "4,8")])
 
-(define_expand "extendsidi2"
-  [(set (match_operand:DI 0 "gpc_reg_operand" "")
-	(sign_extend:DI (match_operand:SI 1 "gpc_reg_operand" "")))]
-  "TARGET_POWERPC64"
-  "")
 
-(define_insn "*extendsidi2_lfiwax"
-  [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,??wj,!wl,!wu")
-	(sign_extend:DI (match_operand:SI 1 "lwa_operand" "Y,r,r,Z,Z")))]
-  "TARGET_POWERPC64 && TARGET_LFIWAX"
+(define_insn "extendsi<mode>2"
+  [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r,??wj,!wl,!wu")
+	(sign_extend:EXTSI (match_operand:SI 1 "lwa_operand" "Y,r,r,Z,Z")))]
+  ""
   "@
    lwa%U1%X1 %0,%1
    extsw %0,%1
@@ -879,270 +853,46 @@ (define_insn "*extendsidi2_lfiwax"
   [(set_attr "type" "load,exts,mffgpr,fpload,fpload")
    (set_attr "sign_extend" "yes")])
 
-(define_insn "*extendsidi2_nocell"
-  [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
-	(sign_extend:DI (match_operand:SI 1 "lwa_operand" "Y,r")))]
-  "TARGET_POWERPC64 && rs6000_gen_cell_microcode && !TARGET_LFIWAX"
-  "@
-   lwa%U1%X1 %0,%1
-   extsw %0,%1"
-  [(set_attr "type" "load,exts")
-   (set_attr "sign_extend" "yes")])
-
-(define_insn "*extendsidi2_nocell"
-  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
-	(sign_extend:DI (match_operand:SI 1 "gpc_reg_operand" "r")))]
-  "TARGET_POWERPC64 && !rs6000_gen_cell_microcode"
-  "extsw %0,%1"
-  [(set_attr "type" "exts")])
-
-(define_insn ""
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
-	(compare:CC (sign_extend:DI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
-		    (const_int 0)))
-   (clobber (match_scratch:DI 2 "=r,r"))]
-  "TARGET_64BIT"
-  "@
-   extsw. %2,%1
-   #"
-  [(set_attr "type" "compare")
-   (set_attr "length" "4,8")])
-
-(define_split
-  [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
-	(compare:CC (sign_extend:DI (match_operand:SI 1 "gpc_reg_operand" ""))
-		    (const_int 0)))
-   (clobber (match_scratch:DI 2 ""))]
-  "TARGET_POWERPC64 && reload_completed"
-  [(set (match_dup 2)
-	(sign_extend:DI (match_dup 1)))
-   (set (match_dup 0)
-	(compare:CC (match_dup 2)
-		    (const_int 0)))]
-  "")
-
-(define_insn ""
+(define_insn_and_split "*extendsi<mode>2_dot"
   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
-	(compare:CC (sign_extend:DI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
+	(compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
 		    (const_int 0)))
-   (set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
-	(sign_extend:DI (match_dup 1)))]
-  "TARGET_64BIT"
+   (clobber (match_scratch:EXTSI 0 "=r,r"))]
+  "rs6000_gen_cell_microcode"
   "@
    extsw. %0,%1
    #"
-  [(set_attr "type" "compare")
-   (set_attr "length" "4,8")])
-
-(define_split
-  [(set (match_operand:CC 2 "cc_reg_not_micro_cr0_operand" "")
-	(compare:CC (sign_extend:DI (match_operand:SI 1 "gpc_reg_operand" ""))
-		    (const_int 0)))
-   (set (match_operand:DI 0 "gpc_reg_operand" "")
-	(sign_extend:DI (match_dup 1)))]
-  "TARGET_POWERPC64 && reload_completed"
-  [(set (match_dup 0)
-	(sign_extend:DI (match_dup 1)))
-   (set (match_dup 2)
-	(compare:CC (match_dup 0)
-		    (const_int 0)))]
-  "")
-
-
-(define_insn "extendqisi2"
-  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
-	(sign_extend:SI (match_operand:QI 1 "gpc_reg_operand" "r")))]
-  ""
-  "extsb %0,%1"
-  [(set_attr "type" "exts")])
-
-(define_insn ""
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
-	(compare:CC (sign_extend:SI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
-		    (const_int 0)))
-   (clobber (match_scratch:SI 2 "=r,r"))]
-  ""
-  "@
-   extsb. %2,%1
-   #"
-  [(set_attr "type" "compare")
-   (set_attr "length" "4,8")])
-
-(define_split
-  [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
-	(compare:CC (sign_extend:SI (match_operand:QI 1 "gpc_reg_operand" ""))
-		    (const_int 0)))
-   (clobber (match_scratch:SI 2 ""))]
-  "reload_completed"
-  [(set (match_dup 2)
-	(sign_extend:SI (match_dup 1)))
-   (set (match_dup 0)
-	(compare:CC (match_dup 2)
-		    (const_int 0)))]
-  "")
-
-(define_insn ""
-  [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
-	(compare:CC (sign_extend:SI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
-		    (const_int 0)))
-   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
-	(sign_extend:SI (match_dup 1)))]
-  ""
-  "@
-   extsb. %0,%1
-   #"
-  [(set_attr "type" "compare")
-   (set_attr "length" "4,8")])
-
-(define_split
-  [(set (match_operand:CC 2 "cc_reg_not_micro_cr0_operand" "")
-	(compare:CC (sign_extend:SI (match_operand:QI 1 "gpc_reg_operand" ""))
-		    (const_int 0)))
-   (set (match_operand:SI 0 "gpc_reg_operand" "")
-	(sign_extend:SI (match_dup 1)))]
-  "reload_completed"
+  "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
   [(set (match_dup 0)
-	(sign_extend:SI (match_dup 1)))
+	(sign_extend:EXTSI (match_dup 1)))
    (set (match_dup 2)
 	(compare:CC (match_dup 0)
 		    (const_int 0)))]
-  "")
-
-
-(define_insn "extendqihi2"
-  [(set (match_operand:HI 0 "gpc_reg_operand" "=r")
-	(sign_extend:HI (match_operand:QI 1 "gpc_reg_operand" "r")))]
-  ""
-  "extsb %0,%1"
-  [(set_attr "type" "exts")])
-
-(define_insn ""
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
-	(compare:CC (sign_extend:HI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
-		    (const_int 0)))
-   (clobber (match_scratch:HI 2 "=r,r"))]
   ""
-  "@
-   extsb. %2,%1
-   #"
-  [(set_attr "type" "compare")
+  [(set_attr "type" "exts")
+   (set_attr "dot" "yes")
    (set_attr "length" "4,8")])
 
-(define_split
-  [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
-	(compare:CC (sign_extend:HI (match_operand:QI 1 "gpc_reg_operand" ""))
-		    (const_int 0)))
-   (clobber (match_scratch:HI 2 ""))]
-  "reload_completed"
-  [(set (match_dup 2)
-	(sign_extend:HI (match_dup 1)))
-   (set (match_dup 0)
-	(compare:CC (match_dup 2)
-		    (const_int 0)))]
-  "")
-
-(define_insn ""
+(define_insn_and_split "*extendsi<mode>2_dot2"
   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
-	(compare:CC (sign_extend:HI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
+	(compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
 		    (const_int 0)))
-   (set (match_operand:HI 0 "gpc_reg_operand" "=r,r")
-	(sign_extend:HI (match_dup 1)))]
-  ""
+   (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r")
+	(sign_extend:EXTSI (match_dup 1)))]
+  "rs6000_gen_cell_microcode"
   "@
-   extsb. %0,%1
+   extsw. %0,%1
    #"
-  [(set_attr "type" "compare")
-   (set_attr "length" "4,8")])
-
-(define_split
-  [(set (match_operand:CC 2 "cc_reg_not_micro_cr0_operand" "")
-	(compare:CC (sign_extend:HI (match_operand:QI 1 "gpc_reg_operand" ""))
-		    (const_int 0)))
-   (set (match_operand:HI 0 "gpc_reg_operand" "")
-	(sign_extend:HI (match_dup 1)))]
-  "reload_completed"
+  "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
   [(set (match_dup 0)
-	(sign_extend:HI (match_dup 1)))
+	(sign_extend:EXTSI (match_dup 1)))
    (set (match_dup 2)
 	(compare:CC (match_dup 0)
 		    (const_int 0)))]
-  "")
-
-
-(define_expand "extendhisi2"
-  [(set (match_operand:SI 0 "gpc_reg_operand" "")
-	(sign_extend:SI (match_operand:HI 1 "gpc_reg_operand" "")))]
-  ""
-  "")
-
-(define_insn ""
-  [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
-	(sign_extend:SI (match_operand:HI 1 "reg_or_mem_operand" "m,r")))]
-  "rs6000_gen_cell_microcode"
-  "@
-   lha%U1%X1 %0,%1
-   extsh %0,%1"
-  [(set_attr "type" "load,exts")
-   (set_attr "sign_extend" "yes")])
-
-(define_insn ""
-  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
-        (sign_extend:SI (match_operand:HI 1 "gpc_reg_operand" "r")))]
-  "!rs6000_gen_cell_microcode"
-  "extsh %0,%1"
-  [(set_attr "type" "exts")])
-
-(define_insn ""
-  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
-	(compare:CC (sign_extend:SI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
-		    (const_int 0)))
-   (clobber (match_scratch:SI 2 "=r,r"))]
   ""
-  "@
-   extsh. %2,%1
-   #"
-  [(set_attr "type" "compare")
-   (set_attr "length" "4,8")])
-
-(define_split
-  [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "")
-	(compare:CC (sign_extend:SI (match_operand:HI 1 "gpc_reg_operand" ""))
-		    (const_int 0)))
-   (clobber (match_scratch:SI 2 ""))]
-  "reload_completed"
-  [(set (match_dup 2)
-	(sign_extend:SI (match_dup 1)))
-   (set (match_dup 0)
-	(compare:CC (match_dup 2)
-		    (const_int 0)))]
-  "")
-
-(define_insn ""
-  [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
-	(compare:CC (sign_extend:SI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
-		    (const_int 0)))
-   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
-	(sign_extend:SI (match_dup 1)))]
-  ""
-  "@
-   extsh. %0,%1
-   #"
-  [(set_attr "type" "compare")
+  [(set_attr "type" "exts")
+   (set_attr "dot" "yes")
    (set_attr "length" "4,8")])
-
-(define_split
-  [(set (match_operand:CC 2 "cc_reg_not_micro_cr0_operand" "")
-	(compare:CC (sign_extend:SI (match_operand:HI 1 "gpc_reg_operand" ""))
-		    (const_int 0)))
-   (set (match_operand:SI 0 "gpc_reg_operand" "")
-	(sign_extend:SI (match_dup 1)))]
-  "reload_completed"
-  [(set (match_dup 0)
-	(sign_extend:SI (match_dup 1)))
-   (set (match_dup 2)
-	(compare:CC (match_dup 0)
-		    (const_int 0)))]
-  "")
 \f
 ;; IBM 405, 440, 464 and 476 half-word multiplication operations.
 
diff --git a/gcc/config/rs6000/rs64.md b/gcc/config/rs6000/rs64.md
index c891ac4..8925f38 100644
--- a/gcc/config/rs6000/rs64.md
+++ b/gcc/config/rs6000/rs64.md
@@ -46,8 +46,8 @@ (define_insn_reservation "rs64a-llsc" 2
   "lsu_rs64")
 
 (define_insn_reservation "rs64a-integer" 1
-  (and (ior (eq_attr "type" "integer,insert,trap,cntlz,exts,isel")
-	    (and (eq_attr "type" "add,logical,shift")
+  (and (ior (eq_attr "type" "integer,insert,trap,cntlz,isel")
+	    (and (eq_attr "type" "add,logical,shift,exts")
 		 (eq_attr "dot" "no")))
        (eq_attr "cpu" "rs64a"))
   "iu_rs64")
@@ -100,7 +100,7 @@ (define_insn_reservation "rs64a-ldiv" 66
 
 (define_insn_reservation "rs64a-compare" 3
   (and (ior (eq_attr "type" "cmp,compare")
-	    (and (eq_attr "type" "add,logical,shift")
+	    (and (eq_attr "type" "add,logical,shift,exts")
 		 (eq_attr "dot" "yes")))
        (eq_attr "cpu" "rs64a"))
   "iu_rs64,nothing,bpu_rs64")
-- 
1.8.1.4

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH 1/4] rs6000: Merge mulsi3 and muldi3
  2014-09-01 19:53 [PATCH 1/4] rs6000: Merge mulsi3 and muldi3 Segher Boessenkool
                   ` (2 preceding siblings ...)
  2014-09-01 19:57 ` [PATCH 4/4] rs6000: Merge extend*si2 and extend*di2 Segher Boessenkool
@ 2014-09-02  0:30 ` David Edelsohn
  3 siblings, 0 replies; 8+ messages in thread
From: David Edelsohn @ 2014-09-02  0:30 UTC (permalink / raw)
  To: Segher Boessenkool; +Cc: GCC Patches

On Mon, Sep 1, 2014 at 3:49 PM, Segher Boessenkool
<segher@kernel.crashing.org> wrote:
> Nothing noteworthy in this patch, sorry.
>
> Tested as usual (powerpc64-linux, -m64,-m32,-m32/-mpowerpc64), no
> regressions.  Is this okay to apply?
>
>
> Segher
>
>
> 2014-09-01  Segher Boessenkool  <segher@kernel.crashing.org>
>
> gcc/
>         * config/rs6000/rs6000.md (mulsi3, *mulsi3_internal1,
>         *mulsi3_internal2, and two splitters): Delete.
>         (muldi3, *muldi3_internal1, *muldi3_internal2, and two splitters):
>         Delete.
>         (mul<mode>3, mul<mode>3_dot, mul<mode>3_dot2): New.

Okay.

Thanks, David

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH 2/4] rs6000: Merge and improve highpart and widening muls
  2014-09-01 19:56 ` [PATCH 2/4] rs6000: Merge and improve highpart and widening muls Segher Boessenkool
@ 2014-09-02  0:30   ` David Edelsohn
  0 siblings, 0 replies; 8+ messages in thread
From: David Edelsohn @ 2014-09-02  0:30 UTC (permalink / raw)
  To: Segher Boessenkool; +Cc: GCC Patches

On Mon, Sep 1, 2014 at 3:49 PM, Segher Boessenkool
<segher@kernel.crashing.org> wrote:
> This is a little more complex.  The highpart muls generate a "truncate
> lshiftrt" pattern that is not canonical when widening to two registers,
> so this doesn't optimise well with combine.  This patch changes it to use
> the canonical subreg patterns instead, which means we need separate patterns
> for LE mode.  Oh well.
>
> Tested as usual.  This regresses gcc.dg/sms-8.c with -m32: SMS now _does_
> succeed, from my shallow investigation because there now are subregs and
> SMS explicitly looks for that.  I didn't look further because other SMS
> tests are failing (without the patch) as well.
>
> Is this okay to apply?
>
>
> Segher
>
>
> 2014-09-01  Segher Boessenkool  <segher@kernel.crashing.org>
>
> gcc/
>         * config/rs6000/rs6000.md (any_extend): New code iterator.
>         (u, su): New code attributes.
>         (dmode, DMODE): New mode attributes.
>         (<su>mul<mode>3_highpart): New.
>         (*<su>mul<mode>3_highpart): New.
>         (<su>mulsi3_highpart_le): New.
>         (<su>muldi3_highpart_le): New.
>         (<su>mulsi3_highpart_64): New.
>         (<u>mul<mode><dmode>3): New.
>         (mulsidi3, umulsidi3, smulsi3_highpart, umulsi3_highpart, and two
>         splitters): Delete.
>         (mulditi3, umulditi3, smuldi3_highpart, umuldi3_highpart, and two
>         splitters): Delete.

Okay.

Thanks, David

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH 3/4] rs6000: Merge zero_extend*si2 and zero_extend*di2
  2014-09-01 19:56 ` [PATCH 3/4] rs6000: Merge zero_extend*si2 and zero_extend*di2 Segher Boessenkool
@ 2014-09-02  0:32   ` David Edelsohn
  0 siblings, 0 replies; 8+ messages in thread
From: David Edelsohn @ 2014-09-02  0:32 UTC (permalink / raw)
  To: Segher Boessenkool; +Cc: GCC Patches

On Mon, Sep 1, 2014 at 3:49 PM, Segher Boessenkool
<segher@kernel.crashing.org> wrote:
> Don't group the insns based on extended size; use source size instead.
> Use the "andi." insn rather than "rldicl." and friends if possible.
> The instructions guarded by TARGET_LFIWZX do not need that guard: the
> constraints already guarantee the (correct!) condition.
>
> Tested as usual; no regressions.  Okay to apply?
>
>
> Segher
>
>
> 2014-09-01  Segher Boessenkool  <segher@kernel.crashing.org>
>
> gcc/
>         * config/rs6000/rs6000.md (QHSI): Delete.
>         (EXTQI, EXTHI, EXTSI): New mode iterators.
>         (zero_extend<mode>di2, *zero_extend<mode>di2_internal1,
>         *zero_extend<mode>di2_internal2, *zero_extend<mode>di2_internal3,
>         *zero_extendsidi2_lfiwzx, zero_extendqisi2, zero_extendhisi2,
>         9 anonymous instructions, and 8 splitters): Delete.
>         (zero_extendqi<mode>2, *zero_extendqi<mode>2_dot,
>         *zero_extendqi<mode>2_dot2, zero_extendhi<mode>2,
>         *zero_extendhi<mode>2_dot, *zero_extendhi<mode>2_dot2,
>         zero_extendsi<mode>2, *zero_extendsi<mode>2_dot,
>         *zero_extendsi<mode>2_dot2): New.

Okay.

Thanks, David

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH 4/4] rs6000: Merge extend*si2 and extend*di2
  2014-09-01 19:57 ` [PATCH 4/4] rs6000: Merge extend*si2 and extend*di2 Segher Boessenkool
@ 2014-09-02  0:33   ` David Edelsohn
  0 siblings, 0 replies; 8+ messages in thread
From: David Edelsohn @ 2014-09-02  0:33 UTC (permalink / raw)
  To: Segher Boessenkool; +Cc: GCC Patches

On Mon, Sep 1, 2014 at 3:49 PM, Segher Boessenkool
<segher@kernel.crashing.org> wrote:
> Mostly like zero_extend, with two twists.  First, this patch allows to set
> "dot" on insn type "exts".  Now we are almost ready to remove insn type
> "compare".
>
> Second, this makes lwa_operand reject memory if avoiding Cell microcode.
> That way we can easily merge the various extendsidi2 patterns (two had
> the same name already :-) ), and it's the right thing to do anyway.
>
> Tested as usual, no regressions.  Is this okay?
>
>
> Segher
>
>
> 2014-09-01  Segher Boessenkool  <segher@kernel.crashing.org>
>
> gcc/
>         * config/rs6000/40x.md (ppc403-integer): Move "exts" to "no dot".
>         (ppc403-compare): Add "exts with dot" case.
>         * config/rs6000/440.md (ppc440-integer, ppc440-compare): As above.
>         * config/rs6000/476.md (ppc476-simple-integer, ppc476-compare): Ditto.
>         * config/rs6000/601.md (ppc601-integer, ppc601-compare): Ditto.
>         * config/rs6000/603.md (ppc603-integer, ppc603-compare): Ditto.
>         * config/rs6000/6xx.md (ppc604-integer, ppc604-compare): Ditto.
>         * config/rs6000/7450.md (ppc7450-integer, ppc7450-compare): Ditto.
>         * config/rs6000/7xx.md (ppc750-integer, ppc750-compare): Ditto.
>         * config/rs6000/cell.md (cell-integer, cell-fast-cmp,
>         cell-cmp-microcoded): Similarly.
>         * config/rs6000/e300c2c3.md (ppce300c3_iu, ppce300c3_cmp): As before.
>         * config/rs6000/e500mc64.md (e500mc64_su, e500mc64_su2): Ditto.
>         * config/rs6000/e5500.md (e5500_sfx, e5500_sfx2): Ditto.
>         * config/rs6000/e6500.md (e6500_sfx, e6500_sfx2): Ditto.
>         * config/rs6000/mpc.md (mpccore-integer, mpccore-compare): Ditto.
>         * config/rs6000/power4.md (power4-integer, power4-compare): Ditto.
>         * config/rs6000/power5.md (power5-integer, power5-compare): Ditto.
>         * config/rs6000/power6.md (power6-exts): Add "no dot" condition.
>         (power6-compare): Add "exts with dot" case.
>         * config/rs6000/power7.md (power7-integer, power7-compare): As before.
>         * config/rs6000/power8.md (power8-1cyc, power8-compare): Ditto.
>         * config/rs6000/rs64.md (rs64a-integer, rs64a-compare): Ditto.
>
>         * config/rs6000/predicates.md (lwa_operand): Don't allow memory
>         if avoiding Cell microcode.
>         * config/rs6000/rs6000.c (rs6000_adjust_cost): Handle exts+dot case.
>         (is_cracked_insn): Ditto.
>         (insn_must_be_first_in_group): Ditto.
>         * config/rs6000/rs6000.md (dot): Adjust comment.
>         (cell_micro): Handle exts+dot.
>         (extendqidi2, extendhidi2, extendsidi2, *extendsidi2_lfiwax,
>         *extendsidi2_nocell, *extendsidi2_nocell, extendqisi2, extendqihi2,
>         extendhisi2, 16 anonymous instructions, and 12 splitters): Delete.
>         (extendqi<mode>2, *extendqi<mode>2_dot, *extendqi<mode>2_dot2,
>         extendhi<mode>2, *extendhi<mode>2, *extendhi<mode>2_noload,
>         *extendhi<mode>2_dot, *extendhi<mode>2_dot2, extendsi<mode>2,
>         *extendsi<mode>2_dot, *extendsi<mode>2_dot2): New.

Okay.

Thanks, David

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2014-09-02  0:33 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-09-01 19:53 [PATCH 1/4] rs6000: Merge mulsi3 and muldi3 Segher Boessenkool
2014-09-01 19:56 ` [PATCH 3/4] rs6000: Merge zero_extend*si2 and zero_extend*di2 Segher Boessenkool
2014-09-02  0:32   ` David Edelsohn
2014-09-01 19:56 ` [PATCH 2/4] rs6000: Merge and improve highpart and widening muls Segher Boessenkool
2014-09-02  0:30   ` David Edelsohn
2014-09-01 19:57 ` [PATCH 4/4] rs6000: Merge extend*si2 and extend*di2 Segher Boessenkool
2014-09-02  0:33   ` David Edelsohn
2014-09-02  0:30 ` [PATCH 1/4] rs6000: Merge mulsi3 and muldi3 David Edelsohn

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).