Patchwork [7/7] s390: Generate rnsbg

login
register
mail settings
Submitter Richard Henderson
Date Aug. 10, 2012, 2:32 a.m.
Message ID <1344565921-27852-8-git-send-email-rth@redhat.com>
Download mbox | patch
Permalink /patch/176332/
State New
Headers show

Comments

Richard Henderson - Aug. 10, 2012, 2:32 a.m.
---
 gcc/config/s390/s390.md |   55 +++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 55 insertions(+), 0 deletions(-)
Andreas Krebbel - Dec. 14, 2012, 2:02 p.m.
I did the change suggested by Uli in the *insv_rnsbg_srl pattern.

Tested on s390 and s390x with z196 and zEC12.

Please apply to mainline. Thanks!

Bye,

-Andreas-

 gcc/config/s390/s390.md |   55 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 55 insertions(+)

Index: gcc/config/s390/s390.md
===================================================================
*** gcc/config/s390/s390.md.orig
--- gcc/config/s390/s390.md
***************
*** 3534,3539 ****
--- 3534,3594 ----
    "r<noxa>sbg\t%0,%1,%<bfstart>2,%<bfend>2,%3"
    [(set_attr "op_type" "RIE")])
  
+ ;; These two are generated by combine for s.bf &= val.
+ ;; ??? For bitfields smaller than 32-bits, we wind up with SImode
+ ;; shifts and ands, which results in some truly awful patterns
+ ;; including subregs of operations.  Rather unnecessisarily, IMO.
+ ;; Instead of
+ ;;
+ ;; (set (zero_extract:DI (reg/v:DI 50 [ s ])
+ ;;        (const_int 24 [0x18])
+ ;;        (const_int 0 [0]))
+ ;;    (subreg:DI (and:SI (subreg:SI (lshiftrt:DI (reg/v:DI 50 [ s ])
+ ;;                    (const_int 40 [0x28])) 4)
+ ;;            (reg:SI 4 %r4 [ y+4 ])) 0))
+ ;;
+ ;; we should instead generate
+ ;;
+ ;; (set (zero_extract:DI (reg/v:DI 50 [ s ])
+ ;;        (const_int 24 [0x18])
+ ;;        (const_int 0 [0]))
+ ;;    (and:DI (lshiftrt:DI (reg/v:DI 50 [ s ])
+ ;;                    (const_int 40 [0x28]))
+ ;;            (subreg:DI (reg:SI 4 %r4 [ y+4 ]) 0)))
+ ;;
+ ;; by noticing that we can push down the outer paradoxical subreg
+ ;; into the operation.
+ 
+ (define_insn "*insv_rnsbg_noshift"
+   [(set (zero_extract:DI
+ 	  (match_operand:DI 0 "nonimmediate_operand" "+d")
+ 	  (match_operand 1 "const_int_operand" "")
+ 	  (match_operand 2 "const_int_operand" ""))
+ 	(and:DI
+ 	  (match_dup 0)
+ 	  (match_operand:DI 3 "nonimmediate_operand" "d")))
+    (clobber (reg:CC CC_REGNUM))]
+   "TARGET_Z10
+    && INTVAL (operands[1]) + INTVAL (operands[2]) == 64"
+   "rnsbg\t%0,%3,%2,63,0"
+   [(set_attr "op_type" "RIE")])
+ 
+ (define_insn "*insv_rnsbg_srl"
+   [(set (zero_extract:DI
+ 	  (match_operand:DI 0 "nonimmediate_operand" "+d")
+ 	  (match_operand 1 "const_int_operand" "")
+ 	  (match_operand 2 "const_int_operand" ""))
+ 	(and:DI
+ 	  (lshiftrt:DI
+ 	    (match_dup 0)
+ 	    (match_operand 3 "const_int_operand" ""))
+ 	  (match_operand:DI 4 "nonimmediate_operand" "d")))
+    (clobber (reg:CC CC_REGNUM))]
+   "TARGET_Z10
+    && INTVAL (operands[3]) == 64 - INTVAL (operands[1]) - INTVAL (operands[2])"
+   "rnsbg\t%0,%4,%2,%2+%1-1,%3"
+   [(set_attr "op_type" "RIE")])
+ 
  (define_insn "*insv<mode>_mem_reg"
    [(set (zero_extract:W (match_operand:QI 0 "memory_operand" "+Q,S")
  			(match_operand 1 "const_int_operand" "n,n")

Patch

diff --git a/gcc/config/s390/s390.md b/gcc/config/s390/s390.md
index d733062..182e7b1 100644
--- a/gcc/config/s390/s390.md
+++ b/gcc/config/s390/s390.md
@@ -3462,6 +3462,61 @@ 
   "r<noxa>sbg\t%0,%1,%<bfstart>2,%<bfend>2,%3"
   [(set_attr "op_type" "RIE")])
 
+;; These two are generated by combine for s.bf &= val.
+;; ??? For bitfields smaller than 32-bits, we wind up with SImode
+;; shifts and ands, which results in some truly awful patterns
+;; including subregs of operations.  Rather unnecessisarily, IMO.
+;; Instead of
+;;
+;; (set (zero_extract:DI (reg/v:DI 50 [ s ])
+;;        (const_int 24 [0x18])
+;;        (const_int 0 [0]))
+;;    (subreg:DI (and:SI (subreg:SI (lshiftrt:DI (reg/v:DI 50 [ s ])
+;;                    (const_int 40 [0x28])) 4)
+;;            (reg:SI 4 %r4 [ y+4 ])) 0))
+;;
+;; we should instead generate
+;;
+;; (set (zero_extract:DI (reg/v:DI 50 [ s ])
+;;        (const_int 24 [0x18])
+;;        (const_int 0 [0]))
+;;    (and:DI (lshiftrt:DI (reg/v:DI 50 [ s ])
+;;                    (const_int 40 [0x28]))
+;;            (subreg:DI (reg:SI 4 %r4 [ y+4 ]) 0)))
+;;
+;; by noticing that we can push down the outer paradoxical subreg
+;; into the operation.
+
+(define_insn "*insv_rnsbg_noshift"
+  [(set (zero_extract:DI
+	  (match_operand:DI 0 "nonimmediate_operand" "+d")
+	  (match_operand 1 "const_int_operand" "")
+	  (match_operand 2 "const_int_operand" ""))
+	(and:DI
+	  (match_dup 0)
+	  (match_operand:DI 3 "nonimmediate_operand" "d")))
+   (clobber (reg:CC CC_REGNUM))]
+  "TARGET_Z10
+   && INTVAL (operands[1]) + INTVAL (operands[2]) == 64"
+  "rnsbg\t%0,%3,%2,63,0"
+  [(set_attr "op_type" "RIE")])
+
+(define_insn "*insv_rnsbg_srl"
+  [(set (zero_extract:DI
+	  (match_operand:DI 0 "nonimmediate_operand" "+d")
+	  (match_operand 1 "const_int_operand" "")
+	  (match_operand 2 "const_int_operand" ""))
+	(and:DI
+	  (lshiftrt:DI
+	    (match_dup 0)
+	    (match_operand 3 "const_int_operand" ""))
+	  (match_operand:DI 4 "nonimmediate_operand" "d")))
+   (clobber (reg:CC CC_REGNUM))]
+  "TARGET_Z10
+   && INTVAL (operands[3]) == 64 - INTVAL (operands[1]) - INTVAL (operands[2])"
+  "rnsbg\t%0,%4,%2,%2+%1-1,64-%2,%1"
+  [(set_attr "op_type" "RIE")])
+
 (define_insn "*insv<mode>_mem_reg"
   [(set (zero_extract:W (match_operand:QI 0 "memory_operand" "+Q,S")
 			(match_operand 1 "const_int_operand" "n,n")