| 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
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")