s390: Generate rnsbg
authorrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 20 Dec 2012 18:05:26 +0000 (18:05 +0000)
committerrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 20 Dec 2012 18:05:26 +0000 (18:05 +0000)
        * config/s390/s390.md (*insv_rnsbg_noshift, *insv_rnsbg_srl): New.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@194646 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/config/s390/s390.md

index b01203f..1fb596f 100644 (file)
@@ -36,6 +36,8 @@
        (*r<IXOR>sbg_di_rotl, *r<IXOR>sbg_<GPR>_srl, *r<IXOR>sbg_<GPR>_sll):
        New patterns.
 
+       * config/s390/s390.md (*insv_rnsbg_noshift, *insv_rnsbg_srl): New.
+
 2012-12-20  Thomas Schwinge  <thomas@codesourcery.com>
 
        PR bootstrap/55202
index 3a1b4c0..4666122 100644 (file)
   "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")