S/390: movdf improvements
[gcc.git] / gcc / config / s390 / s390.md
index 7148c682ef0f5fd6205acdee74fb92e34622e223..554fb37a1c6e463cc6ea116b56427d452edd1f6a 100644 (file)
@@ -1,5 +1,5 @@
 ;;- Machine description for GNU compiler -- S/390 / zSeries version.
-;;  Copyright (C) 1999-2016 Free Software Foundation, Inc.
+;;  Copyright (C) 1999-2017 Free Software Foundation, Inc.
 ;;  Contributed by Hartmut Penner (hpenner@de.ibm.com) and
 ;;                 Ulrich Weigand (uweigand@de.ibm.com) and
 ;;                 Andreas Krebbel (Andreas.Krebbel@de.ibm.com)
    ; Split stack support
    UNSPECV_SPLIT_STACK_CALL
    UNSPECV_SPLIT_STACK_DATA
+
+   UNSPECV_OSC_BREAK
   ])
 
 ;;
   (const (symbol_ref "s390_tune_attr")))
 
 (define_attr "cpu_facility"
-  "standard,ieee,zarch,cpu_zarch,longdisp,extimm,dfp,z10,z196,zEC12,vec,z13"
+  "standard,ieee,zarch,cpu_zarch,longdisp,extimm,dfp,z10,z196,zEC12,vx,z13"
   (const_string "standard"))
 
 (define_attr "enabled" ""
               (match_test "TARGET_ZEC12"))
         (const_int 1)
 
-         (and (eq_attr "cpu_facility" "vec")
+         (and (eq_attr "cpu_facility" "vx")
               (match_test "TARGET_VX"))
         (const_int 1)
 
 ; Used with VFCMP to expand part of the mnemonic
 ; For fp we have a mismatch: eq in the insn name - e in asm
 (define_mode_attr asm_fcmp [(CCVEQ "e") (CCVFH "h") (CCVFHE "he")])
-(define_mode_attr insn_cmp [(CCVEQ "eq") (CCVH "h") (CCVHU "hl") (CCVFH "h") (CCVFHE "he")])
+(define_mode_attr insn_cmp [(CCVEQ "eq") (CCVIH "h") (CCVIHU "hl") (CCVFH "h") (CCVFHE "he")])
 
 ;; Subst pattern definitions
 (include "subst.md")
 
 ; (TF|DF|SF|TD|DD|SD) instructions
 
+
+; load and test instructions turn SNaN into QNaN what is not
+; acceptable if the target will be used afterwards.  On the other hand
+; they are quite convenient for implementing comparisons with 0.0. So
+; try to enable them via splitter if the value isn't needed anymore.
+
 ; ltxbr, ltdbr, ltebr, ltxtr, ltdtr
 (define_insn "*cmp<mode>_ccs_0"
   [(set (reg CC_REGNUM)
-        (compare (match_operand:FP 0 "register_operand" "f")
-                 (match_operand:FP 1 "const0_operand"   "")))]
+       (compare (match_operand:FP 0 "register_operand"  "f")
+                (match_operand:FP 1 "const0_operand"    "")))
+   (clobber (match_operand:FP      2 "register_operand" "=0"))]
   "s390_match_ccmode(insn, CCSmode) && TARGET_HARD_FLOAT"
   "lt<xde><bt>r\t%0,%0"
    [(set_attr "op_type" "RRE")
     (set_attr "type"  "fsimp<mode>")])
 
+(define_split
+  [(set (match_operand 0 "cc_reg_operand")
+       (compare (match_operand:FP 1 "register_operand")
+                (match_operand:FP 2 "const0_operand")))]
+  "TARGET_HARD_FLOAT && REG_P (operands[1]) && dead_or_set_p (insn, operands[1])"
+  [(parallel
+    [(set (match_dup 0) (match_dup 3))
+     (clobber (match_dup 1))])]
+ {
+   /* s390_match_ccmode requires the compare to have the same CC mode
+      as the CC destination register.  */
+   operands[3] = gen_rtx_COMPARE (GET_MODE (operands[0]),
+                                 operands[1], operands[2]);
+ })
+
+
 ; cxtr, cxbr, cdtr, cdbr, cebr, cdb, ceb
 (define_insn "*cmp<mode>_ccs"
   [(set (reg CC_REGNUM)
    #"
   [(set_attr "op_type" "RSY,RSY,VRR,VRI,VRI,VRR,*,VRX,VRX,*,*")
    (set_attr "type" "lm,stm,*,*,*,*,*,*,*,*,*")
-   (set_attr "cpu_facility" "*,*,vec,vec,vec,vec,vec,vec,vec,*,*")])
+   (set_attr "cpu_facility" "*,*,vx,vx,vx,vx,vx,vx,vx,*,*")])
 
 (define_split
   [(set (match_operand:TI 0 "nonimmediate_operand" "")
         (match_operand:TI 1 "general_operand" ""))]
   "TARGET_ZARCH && reload_completed
+   && !s_operand (operands[0], TImode)
+   && !s_operand (operands[1], TImode)
    && s390_split_ok_p (operands[0], operands[1], TImode, 0)"
   [(set (match_dup 2) (match_dup 4))
    (set (match_dup 3) (match_dup 5))]
   [(set (match_operand:TI 0 "nonimmediate_operand" "")
         (match_operand:TI 1 "general_operand" ""))]
   "TARGET_ZARCH && reload_completed
+   && !s_operand (operands[0], TImode)
+   && !s_operand (operands[1], TImode)
    && s390_split_ok_p (operands[0], operands[1], TImode, 1)"
   [(set (match_dup 2) (match_dup 4))
    (set (match_dup 3) (match_dup 5))]
                      *,*,*,*,*,*,*")
    (set_attr "cpu_facility" "*,*,*,*,*,extimm,extimm,extimm,dfp,dfp,longdisp,
                              z10,*,*,*,*,*,longdisp,*,longdisp,
-                             z10,z10,*,*,*,*,vec,vec,vec,vec,vec,vec")
+                             z10,z10,*,*,*,*,vx,vx,vx,vx,vx,vx")
    (set_attr "z10prop" "z10_fwd_A1,
                         z10_fwd_E1,
                         z10_fwd_E1,
   [(set (match_operand:DI 0 "nonimmediate_operand" "")
         (match_operand:DI 1 "general_operand" ""))]
   "!TARGET_ZARCH && reload_completed
+   && !s_operand (operands[0], DImode)
+   && !s_operand (operands[1], DImode)
    && s390_split_ok_p (operands[0], operands[1], DImode, 0)"
   [(set (match_dup 2) (match_dup 4))
    (set (match_dup 3) (match_dup 5))]
   [(set (match_operand:DI 0 "nonimmediate_operand" "")
         (match_operand:DI 1 "general_operand" ""))]
   "!TARGET_ZARCH && reload_completed
+   && !s_operand (operands[0], DImode)
+   && !s_operand (operands[1], DImode)
    && s390_split_ok_p (operands[0], operands[1], DImode, 1)"
   [(set (match_dup 2) (match_dup 4))
    (set (match_dup 3) (match_dup 5))]
                      *,
                      *,*,*,*,*,*,*")
    (set_attr "cpu_facility" "*,*,*,extimm,longdisp,z10,*,*,longdisp,*,longdisp,
-                             vec,*,vec,*,longdisp,*,longdisp,*,*,*,z10,z10,*,vec,vec,vec,vec,vec,vec")
+                             vx,*,vx,*,longdisp,*,longdisp,*,*,*,z10,z10,*,vx,vx,vx,vx,vx,vx")
    (set_attr "z10prop" "z10_fwd_A1,
                         z10_fwd_E1,
                         z10_fwd_E1,
    (set_attr "type" "*,lr,load,store,floadsf,floadsf,floadsf,floadsf,fstoresf,*,*,*,*")
    (set_attr "z10prop" "z10_fwd_A1,z10_fr_E1,z10_fwd_A3,z10_rec,*,*,*,*,*,z10_super_E1,
                         z10_super,*,*")
-   (set_attr "cpu_facility" "*,*,*,*,vec,*,vec,*,*,*,*,*,*")
+   (set_attr "cpu_facility" "*,*,*,*,vx,*,vx,*,*,*,*,*,*")
 ])
 
 (define_peephole2
    vsteh\t%v1,%0,0"
   [(set_attr "op_type"      "RR,RI,RX,RXY,RIL,RX,RXY,RIL,SIL,VRI,VRR,VRS,VRS,VRX,VRX")
    (set_attr "type"         "lr,*,*,*,larl,store,store,store,*,*,*,*,*,*,*")
-   (set_attr "cpu_facility" "*,*,*,longdisp,z10,*,longdisp,z10,z10,vec,vec,vec,vec,vec,vec")
+   (set_attr "cpu_facility" "*,*,*,longdisp,z10,*,longdisp,z10,z10,vx,vx,vx,vx,vx,vx")
    (set_attr "z10prop" "z10_fr_E1,
                        z10_fwd_A1,
                        z10_super_E1,
    vsteb\t%v1,%0,0"
   [(set_attr "op_type" "RR,RI,RX,RXY,RX,RXY,SI,SIY,SS,VRI,VRR,VRS,VRS,VRX,VRX")
    (set_attr "type" "lr,*,*,*,store,store,store,store,*,*,*,*,*,*,*")
-   (set_attr "cpu_facility" "*,*,*,longdisp,*,longdisp,*,longdisp,*,vec,vec,vec,vec,vec,vec")
+   (set_attr "cpu_facility" "*,*,*,longdisp,*,longdisp,*,longdisp,*,vx,vx,vx,vx,vx,vx")
    (set_attr "z10prop" "z10_fr_E1,
                         z10_fwd_A1,
                         z10_super_E1,
   [(set (match_operand:TD_TF 0 "nonimmediate_operand" "")
         (match_operand:TD_TF 1 "general_operand"      ""))]
   "TARGET_ZARCH && reload_completed
+   && !s_operand (operands[0], <MODE>mode)
+   && !s_operand (operands[1], <MODE>mode)
    && s390_split_ok_p (operands[0], operands[1], <MODE>mode, 0)"
   [(set (match_dup 2) (match_dup 4))
    (set (match_dup 3) (match_dup 5))]
   [(set (match_operand:TD_TF 0 "nonimmediate_operand" "")
         (match_operand:TD_TF 1 "general_operand"      ""))]
   "TARGET_ZARCH && reload_completed
+   && !s_operand (operands[0], <MODE>mode)
+   && !s_operand (operands[1], <MODE>mode)
    && s390_split_ok_p (operands[0], operands[1], <MODE>mode, 1)"
   [(set (match_dup 2) (match_dup 4))
    (set (match_dup 3) (match_dup 5))]
 
 (define_insn "*mov<mode>_64dfp"
   [(set (match_operand:DD_DF 0 "nonimmediate_operand"
-                              "=f,f,f,d,f,f,R,T,d,d,d,d,b,T,v,v,d,v,R")
+                              "=f,f,f,d,f,f,R,T,d,d,d,d,b,T,v,v,v,d,v,R")
         (match_operand:DD_DF 1 "general_operand"
-                              " G,f,d,f,R,T,f,f,G,d,b,T,d,d,v,d,v,R,v"))]
+                              " G,f,d,f,R,T,f,f,G,d,b,T,d,d,v,G,d,v,R,v"))]
   "TARGET_DFP"
   "@
    lzdr\t%0
    stgrl\t%1,%0
    stg\t%1,%0
    vlr\t%v0,%v1
+   vleig\t%v0,0,0
    vlvgg\t%v0,%1,0
    vlgvg\t%0,%v1,0
    vleg\t%0,%1,0
    vsteg\t%1,%0,0"
-  [(set_attr "op_type" "RRE,RR,RRE,RRE,RX,RXY,RX,RXY,RI,RRE,RIL,RXY,RIL,RXY,VRR,VRS,VRS,VRX,VRX")
+  [(set_attr "op_type" "RRE,RR,RRE,RRE,RX,RXY,RX,RXY,RI,RRE,RIL,RXY,RIL,RXY,VRR,VRI,VRS,VRS,VRX,VRX")
    (set_attr "type" "fsimpdf,floaddf,floaddf,floaddf,floaddf,floaddf,
-                     fstoredf,fstoredf,*,lr,load,load,store,store,*,*,*,load,store")
-   (set_attr "z10prop" "*,*,*,*,*,*,*,*,z10_fwd_A1,z10_fr_E1,z10_fwd_A3,z10_fwd_A3,z10_rec,z10_rec,*,*,*,*,*")
-   (set_attr "cpu_facility" "z196,*,*,*,*,longdisp,*,longdisp,*,*,z10,*,z10,*,vec,vec,vec,vec,vec")])
+                     fstoredf,fstoredf,*,lr,load,load,store,store,*,*,*,*,load,store")
+   (set_attr "z10prop" "*,*,*,*,*,*,*,*,z10_fwd_A1,z10_fr_E1,z10_fwd_A3,z10_fwd_A3,z10_rec,z10_rec,*,*,*,*,*,*")
+   (set_attr "cpu_facility" "z196,*,*,*,*,longdisp,*,longdisp,*,*,z10,*,z10,*,vx,vx,vx,vx,vx,vx")])
 
 (define_insn "*mov<mode>_64"
-  [(set (match_operand:DD_DF 0 "nonimmediate_operand" "=f,f,f,f,R,T,d,d,d,d,b,T,v,v,R")
-        (match_operand:DD_DF 1 "general_operand"      " G,f,R,T,f,f,G,d,b,T,d,d,v,R,v"))]
+  [(set (match_operand:DD_DF 0 "nonimmediate_operand" "=f,f,f,f,R,T,d,d,d,d,b,T")
+        (match_operand:DD_DF 1 "general_operand"      " G,f,R,T,f,f,G,d,b,T,d,d"))]
   "TARGET_ZARCH"
   "@
    lzdr\t%0
    lgrl\t%0,%1
    lg\t%0,%1
    stgrl\t%1,%0
-   stg\t%1,%0
-   vlr\t%v0,%v1
-   vleg\t%v0,%1,0
-   vsteg\t%v1,%0,0"
-  [(set_attr "op_type" "RRE,RR,RX,RXY,RX,RXY,RI,RRE,RIL,RXY,RIL,RXY,VRR,VRX,VRX")
+   stg\t%1,%0"
+  [(set_attr "op_type" "RRE,RR,RX,RXY,RX,RXY,RI,RRE,RIL,RXY,RIL,RXY")
    (set_attr "type"    "fsimpdf,fload<mode>,fload<mode>,fload<mode>,
-                        fstore<mode>,fstore<mode>,*,lr,load,load,store,store,*,load,store")
-   (set_attr "z10prop" "*,*,*,*,*,*,z10_fwd_A1,z10_fr_E1,z10_fwd_A3,z10_fwd_A3,z10_rec,z10_rec,*,*,*")
-   (set_attr "cpu_facility" "z196,*,*,longdisp,*,longdisp,*,*,z10,*,z10,*,vec,vec,vec")])
+                        fstore<mode>,fstore<mode>,*,lr,load,load,store,store")
+   (set_attr "z10prop" "*,*,*,*,*,*,z10_fwd_A1,z10_fr_E1,z10_fwd_A3,z10_fwd_A3,z10_rec,z10_rec")
+   (set_attr "cpu_facility" "z196,*,*,longdisp,*,longdisp,*,*,z10,*,z10,*")])
 
 (define_insn "*mov<mode>_31"
   [(set (match_operand:DD_DF 0 "nonimmediate_operand"
   [(set (match_operand:DD_DF 0 "nonimmediate_operand" "")
         (match_operand:DD_DF 1 "general_operand" ""))]
   "!TARGET_ZARCH && reload_completed
+   && !s_operand (operands[0], <MODE>mode)
+   && !s_operand (operands[1], <MODE>mode)
    && s390_split_ok_p (operands[0], operands[1], <MODE>mode, 0)"
   [(set (match_dup 2) (match_dup 4))
    (set (match_dup 3) (match_dup 5))]
   [(set (match_operand:DD_DF 0 "nonimmediate_operand" "")
         (match_operand:DD_DF 1 "general_operand" ""))]
   "!TARGET_ZARCH && reload_completed
+   && !s_operand (operands[0], <MODE>mode)
+   && !s_operand (operands[1], <MODE>mode)
    && s390_split_ok_p (operands[0], operands[1], <MODE>mode, 1)"
   [(set (match_dup 2) (match_dup 4))
    (set (match_dup 3) (match_dup 5))]
    st\t%1,%0
    sty\t%1,%0
    vlr\t%v0,%v1
-   vleif\t%v0,0
+   vleif\t%v0,0,0
    vlvgf\t%v0,%1,0
    vlgvf\t%0,%v1,0
-   vleg\t%0,%1,0
-   vsteg\t%1,%0,0"
+   vlef\t%0,%1,0
+   vstef\t%1,%0,0"
   [(set_attr "op_type" "RRE,RR,RR,RXE,RX,RXY,RX,RXY,RI,RR,RIL,RX,RXY,RIL,RX,RXY,VRR,VRI,VRS,VRS,VRX,VRX")
    (set_attr "type"    "fsimpsf,fsimpsf,fload<mode>,fload<mode>,fload<mode>,fload<mode>,
                         fstore<mode>,fstore<mode>,*,lr,load,load,load,store,store,store,*,*,*,*,load,store")
    (set_attr "z10prop" "*,*,*,*,*,*,*,*,z10_fwd_A1,z10_fr_E1,z10_fr_E1,z10_fwd_A3,z10_fwd_A3,z10_rec,z10_rec,z10_rec,*,*,*,*,*,*")
-   (set_attr "cpu_facility" "z196,vec,*,vec,*,longdisp,*,longdisp,*,*,z10,*,longdisp,z10,*,longdisp,vec,vec,vec,vec,vec,vec")])
+   (set_attr "cpu_facility" "z196,vx,*,vx,*,longdisp,*,longdisp,*,*,z10,*,longdisp,z10,*,longdisp,vx,vx,vx,vx,vx,vx")])
 
 ;
 ; movcc instruction pattern
 (define_insn "*setmem_long_and"
   [(clobber (match_operand:<DBL> 0 "register_operand" "=d"))
    (set (mem:BLK (subreg:P (match_operand:<DBL> 3 "register_operand" "0") 0))
-        (unspec:BLK [(and:P
-                     (match_operand:P 2 "setmem_operand" "Y")
-                     (match_operand:P 4 "const_int_operand"             "n"))
+        (unspec:BLK [(zero_extend:P (match_operand:QI 2 "setmem_operand" "Y"))
                    (subreg:P (match_dup 3) <modesize>)]
                    UNSPEC_REPLICATE_BYTE))
    (use (match_operand:<DBL> 1 "register_operand" "d"))
    (clobber (reg:CC CC_REGNUM))]
-  "(TARGET_64BIT || !TARGET_ZARCH) &&
-   (INTVAL (operands[4]) & 255) == 255"
+  "(TARGET_64BIT || !TARGET_ZARCH)"
   "mvcle\t%0,%1,%Y2\;jo\t.-4"
   [(set_attr "length" "8")
    (set_attr "type" "vs")])
 (define_insn "*setmem_long_and_31z"
   [(clobber (match_operand:TI 0 "register_operand" "=d"))
    (set (mem:BLK (subreg:SI (match_operand:TI 3 "register_operand" "0") 4))
-        (unspec:BLK [(and:SI
-                     (match_operand:SI 2 "setmem_operand" "Y")
-                     (match_operand:SI 4 "const_int_operand" "n"))
+        (unspec:BLK [(zero_extend:SI (match_operand:QI 2 "setmem_operand" "Y"))
                    (subreg:SI (match_dup 3) 12)] UNSPEC_REPLICATE_BYTE))
    (use (match_operand:TI 1 "register_operand" "d"))
    (clobber (reg:CC CC_REGNUM))]
-  "(!TARGET_64BIT && TARGET_ZARCH) &&
-   (INTVAL (operands[4]) & 255) == 255"
+  "(!TARGET_64BIT && TARGET_ZARCH)"
   "mvcle\t%0,%1,%Y2\;jo\t.-4"
   [(set_attr "length" "8")
    (set_attr "type" "vs")])
      (clobber (reg:CC CC_REGNUM))])]
   "TARGET_Z10"
 {
+  if (! EXTRACT_ARGS_IN_RANGE (INTVAL (operands[2]), INTVAL (operands[3]), 64))
+    FAIL;
   /* Starting with zEC12 there is risbgn not clobbering CC.  */
   if (TARGET_ZEC12)
     {
         (match_operand 2 "const_int_operand" "")   ; size
         (match_operand 3 "const_int_operand" ""))) ; start
   ]
-  "<z10_or_zEC12_cond>"
+  "<z10_or_zEC12_cond>
+   && EXTRACT_ARGS_IN_RANGE (INTVAL (operands[2]), INTVAL (operands[3]),
+                            GET_MODE_BITSIZE (<MODE>mode))"
   "<risbg_n>\t%0,%1,64-%2,128+63,<bitoff_plus>%3+%2" ; dst, src, start, end, shift
   [(set_attr "op_type" "RIE")
    (set_attr "z10prop" "z10_super_E1")])
        (lshiftrt:DI (match_operand:DI 3 "register_operand" "d")
                     (match_operand:DI 4 "nonzero_shift_count_operand" "")))]
   "<z10_or_zEC12_cond>
+   && EXTRACT_ARGS_IN_RANGE (INTVAL (operands[1]), INTVAL (operands[2]), 64)
    && 64 - UINTVAL (operands[4]) >= UINTVAL (operands[1])"
   "<risbg_n>\t%0,%3,%2,%2+%1-1,128-%2-%1-%4"
   [(set_attr "op_type" "RIE")
                  (match_operand 5 "const_int_operand" "")) ; start
                 4)))]
   "<z10_or_zEC12_cond>
+   && EXTRACT_ARGS_IN_RANGE (INTVAL (operands[4]), INTVAL (operands[5]), 64)
    && UINTVAL (operands[2]) == (~(0ULL) << UINTVAL (operands[4]))"
   "<risbg_n>\t%0,%3,64-%4,63,%4+%5"
   [(set_attr "op_type" "RIE")
                (const_int 1)  ; size
                (match_operand 2 "const_int_operand" "")) ; start
               (const_int 0)))]
-  "<z10_or_zEC12_cond>"
+  "<z10_or_zEC12_cond>
+   && EXTRACT_ARGS_IN_RANGE (1, INTVAL (operands[2]), 64)"
   "<risbg_n>\t%0,%1,64-1,128+63,%2+1" ; dst, src, start, end, shift
   [(set_attr "op_type" "RIE")
    (set_attr "z10prop" "z10_super_E1")])
                          (match_operand 2 "const_int_operand"    "I")) ; pos
        (match_operand:GPR 3 "nonimmediate_operand" "d"))]
   "<z10_or_zEC12_cond>
+   && EXTRACT_ARGS_IN_RANGE (INTVAL (operands[1]), INTVAL (operands[2]),
+                            GET_MODE_BITSIZE (<MODE>mode))
    && (INTVAL (operands[1]) + INTVAL (operands[2])) <= <bitsize>"
   "<risbg_n>\t%0,%3,<bitoff_plus>%2,<bitoff_plus>%2+%1-1,<bitsize>-%2-%1"
   [(set_attr "op_type" "RIE")
     operands[6] = operands[0];
 })
 
+; rosbg, rxsbg
 (define_insn "*r<noxa>sbg_<mode>_noshift"
   [(set (match_operand:GPR 0 "nonimmediate_operand" "=d")
        (IXOR:GPR
   "r<noxa>sbg\t%0,%1,%<bfstart>2,%<bfend>2,0"
   [(set_attr "op_type" "RIE")])
 
+; rosbg, rxsbg
 (define_insn "*r<noxa>sbg_di_rotl"
   [(set (match_operand:DI 0 "nonimmediate_operand" "=d")
        (IXOR:DI
   "r<noxa>sbg\t%0,%1,%<bfstart>2,%<bfend>2,%b3"
   [(set_attr "op_type" "RIE")])
 
+; rosbg, rxsbg
 (define_insn "*r<noxa>sbg_<mode>_srl_bitmask"
   [(set (match_operand:GPR 0 "nonimmediate_operand" "=d")
        (IXOR:GPR
            (lshiftrt:GPR
               (match_operand:GPR 1 "nonimmediate_operand" "d")
               (match_operand:GPR 3 "nonzero_shift_count_operand" ""))
-            (match_operand:GPR 2 "contiguous_bitmask_operand" ""))
+            (match_operand:GPR 2 "contiguous_bitmask_nowrap_operand" ""))
          (match_operand:GPR 4 "nonimmediate_operand" "0")))
    (clobber (reg:CC CC_REGNUM))]
   "TARGET_Z10
   "r<noxa>sbg\t%0,%1,%<bfstart>2,%<bfend>2,64-%3"
   [(set_attr "op_type" "RIE")])
 
+; rosbg, rxsbg
 (define_insn "*r<noxa>sbg_<mode>_sll_bitmask"
   [(set (match_operand:GPR 0 "nonimmediate_operand" "=d")
        (IXOR:GPR
            (ashift:GPR
               (match_operand:GPR 1 "nonimmediate_operand" "d")
               (match_operand:GPR 3 "nonzero_shift_count_operand" ""))
-            (match_operand:GPR 2 "contiguous_bitmask_operand" ""))
+            (match_operand:GPR 2 "contiguous_bitmask_nowrap_operand" ""))
          (match_operand:GPR 4 "nonimmediate_operand" "0")))
    (clobber (reg:CC CC_REGNUM))]
   "TARGET_Z10
 ;; unsigned {int,long} a, b
 ;; a = a | (b << const_int)
 ;; a = a ^ (b << const_int)
+; rosbg, rxsbg
 (define_insn "*r<noxa>sbg_<mode>_sll"
   [(set (match_operand:GPR 0 "nonimmediate_operand" "=d")
        (IXOR:GPR
 ;; unsigned {int,long} a, b
 ;; a = a | (b >> const_int)
 ;; a = a ^ (b >> const_int)
+; rosbg, rxsbg
 (define_insn "*r<noxa>sbg_<mode>_srl"
   [(set (match_operand:GPR 0 "nonimmediate_operand" "=d")
        (IXOR:GPR
          (match_operand:DI 3 "nonimmediate_operand" "d")))
    (clobber (reg:CC CC_REGNUM))]
   "TARGET_Z10
+   && EXTRACT_ARGS_IN_RANGE (INTVAL (operands[1]), INTVAL (operands[2]), 64)
    && INTVAL (operands[1]) + INTVAL (operands[2]) == 64"
   "rnsbg\t%0,%3,%2,63,0"
   [(set_attr "op_type" "RIE")])
          (match_operand:DI 4 "nonimmediate_operand" "d")))
    (clobber (reg:CC CC_REGNUM))]
   "TARGET_Z10
+   && EXTRACT_ARGS_IN_RANGE (INTVAL (operands[1]), INTVAL (operands[2]), 64)
    && INTVAL (operands[3]) == 64 - INTVAL (operands[1]) - INTVAL (operands[2])"
   "rnsbg\t%0,%4,%2,%2+%1-1,%3"
   [(set_attr "op_type" "RIE")])
                        (match_operand 1 "const_int_operand" "n,n")
                        (const_int 0))
        (match_operand:W 2 "register_operand" "d,d"))]
-  "INTVAL (operands[1]) > 0
+  "EXTRACT_ARGS_IN_RANGE (INTVAL (operands[1]), 0, 64)
+   && INTVAL (operands[1]) > 0
    && INTVAL (operands[1]) <= GET_MODE_BITSIZE (SImode)
    && INTVAL (operands[1]) % BITS_PER_UNIT == 0"
 {
        (lshiftrt:DI (match_operand:DI 2 "register_operand" "d")
                     (const_int 32)))]
   "TARGET_ZARCH
+   && EXTRACT_ARGS_IN_RANGE (INTVAL (operands[1]), 0, 64)
    && INTVAL (operands[1]) > 0
    && INTVAL (operands[1]) <= GET_MODE_BITSIZE (SImode)
    && INTVAL (operands[1]) % BITS_PER_UNIT == 0"
                         (match_operand 1 "const_int_operand" "n"))
        (match_operand:DI 2 "const_int_operand" "n"))]
   "TARGET_ZARCH
+   && EXTRACT_ARGS_IN_RANGE (16, INTVAL (operands[1]), 64)
    && INTVAL (operands[1]) >= 0
    && INTVAL (operands[1]) < BITS_PER_WORD
    && INTVAL (operands[1]) % 16 == 0"
    wcdgb\t%v0,%v1,0,0"
   [(set_attr "op_type"      "RRE,VRR")
    (set_attr "type"         "itof<mode>" )
-   (set_attr "cpu_facility" "*,vec")
+   (set_attr "cpu_facility" "*,vx")
    (set_attr "enabled"      "*,<DFDI>")])
 
 ; cxfbr, cdfbr, cefbr
                        ; According to BFP rounding mode
   [(set_attr "op_type"      "RRE,VRR")
    (set_attr "type"         "ftruncdf")
-   (set_attr "cpu_facility" "*,vec")])
+   (set_attr "cpu_facility" "*,vx")])
 
 ;
 ; trunctf(df|sf)2 instruction pattern(s).
 
 (define_expand "trunctdsd2"
   [(parallel
-    [(set (match_dup 3)
+    [(set (match_dup 2)
          (float_truncate:DD (match_operand:TD 1 "register_operand" "")))
      (unspec:DI [(const_int DFP_RND_PREP_FOR_SHORT_PREC)] UNSPEC_ROUND)
-     (clobber (match_scratch:TD 2 ""))])
+     (clobber (match_scratch:TD 3 ""))])
    (set (match_operand:SD 0 "register_operand" "")
-       (float_truncate:SD (match_dup 3)))]
+       (float_truncate:SD (match_dup 2)))]
   "TARGET_HARD_DFP"
 {
-  operands[3] = gen_reg_rtx (DDmode);
+  operands[2] = gen_reg_rtx (DDmode);
 })
 
 ;
    wfadb\t%v0,%v1,%v2"
   [(set_attr "op_type"      "RRF,RRE,RXE,VRR")
    (set_attr "type"         "fsimp<mode>")
-   (set_attr "cpu_facility" "*,*,*,vec")
+   (set_attr "cpu_facility" "*,*,*,vx")
    (set_attr "enabled"      "<nBFP>,<nDFP>,<DSF>,<DFDI>")])
 
 ; axbr, adbr, aebr, axb, adb, aeb, adtr, axtr
    wfsdb\t%v0,%v1,%v2"
   [(set_attr "op_type"      "RRF,RRE,RXE,VRR")
    (set_attr "type"         "fsimp<mode>")
-   (set_attr "cpu_facility" "*,*,*,vec")
+   (set_attr "cpu_facility" "*,*,*,vx")
    (set_attr "enabled"      "<nBFP>,<nDFP>,<DSF>,<DFDI>")])
 
 ; sxbr, sdbr, sebr, sdb, seb, sxtr, sdtr
    wfmdb\t%v0,%v1,%v2"
   [(set_attr "op_type"      "RRF,RRE,RXE,VRR")
    (set_attr "type"         "fmul<mode>")
-   (set_attr "cpu_facility" "*,*,*,vec")
+   (set_attr "cpu_facility" "*,*,*,vx")
    (set_attr "enabled"      "<nBFP>,<nDFP>,<DSF>,<DFDI>")])
 
 ; madbr, maebr, maxb, madb, maeb
    wfmadb\t%v0,%v1,%v2,%v3"
   [(set_attr "op_type"      "RRE,RXE,VRR")
    (set_attr "type"         "fmadd<mode>")
-   (set_attr "cpu_facility" "*,*,vec")
+   (set_attr "cpu_facility" "*,*,vx")
    (set_attr "enabled"      "*,*,<DFDI>")])
 
 ; msxbr, msdbr, msebr, msxb, msdb, mseb
    wfmsdb\t%v0,%v1,%v2,%v3"
   [(set_attr "op_type"      "RRE,RXE,VRR")
    (set_attr "type"         "fmadd<mode>")
-   (set_attr "cpu_facility" "*,*,vec")
+   (set_attr "cpu_facility" "*,*,vx")
    (set_attr "enabled"      "*,*,<DFDI>")])
 
 ;;
    (clobber (match_dup 4))]
   "TARGET_ZARCH"
 {
-  rtx insn, div_equal, mod_equal;
+  rtx div_equal, mod_equal;
+  rtx_insn *insn;
 
   div_equal = gen_rtx_DIV (DImode, operands[1], operands[2]);
   mod_equal = gen_rtx_MOD (DImode, operands[1], operands[2]);
    (clobber (match_dup 4))]
   "TARGET_ZARCH"
 {
-  rtx insn, div_equal, mod_equal, equal;
+  rtx div_equal, mod_equal, equal;
+  rtx_insn *insn;
 
   div_equal = gen_rtx_UDIV (DImode, operands[1], operands[2]);
   mod_equal = gen_rtx_UMOD (DImode, operands[1], operands[2]);
    (clobber (match_dup 4))]
   "!TARGET_ZARCH"
 {
-  rtx insn, div_equal, mod_equal, equal;
+  rtx div_equal, mod_equal, equal;
+  rtx_insn *insn;
 
   div_equal = gen_rtx_DIV (SImode, operands[1], operands[2]);
   mod_equal = gen_rtx_MOD (SImode, operands[1], operands[2]);
    (clobber (match_dup 4))]
   "!TARGET_ZARCH && TARGET_CPU_ZARCH"
 {
-  rtx insn, div_equal, mod_equal, equal;
+  rtx div_equal, mod_equal, equal;
+  rtx_insn *insn;
 
   div_equal = gen_rtx_UDIV (SImode, operands[1], operands[2]);
   mod_equal = gen_rtx_UMOD (SImode, operands[1], operands[2]);
    (clobber (match_dup 3))]
   "!TARGET_ZARCH && !TARGET_CPU_ZARCH"
 {
-  rtx insn, udiv_equal, umod_equal, equal;
+  rtx udiv_equal, umod_equal, equal;
+  rtx_insn *insn;
 
   udiv_equal = gen_rtx_UDIV (SImode, operands[1], operands[2]);
   umod_equal = gen_rtx_UMOD (SImode, operands[1], operands[2]);
    (clobber (match_dup 3))]
   "!TARGET_ZARCH && !TARGET_CPU_ZARCH"
 {
-  rtx insn, udiv_equal, umod_equal, equal;
+  rtx udiv_equal, umod_equal, equal;
+  rtx_insn *insn;
 
   udiv_equal = gen_rtx_UDIV (SImode, operands[1], operands[2]);
   umod_equal = gen_rtx_UMOD (SImode, operands[1], operands[2]);
    wfddb\t%v0,%v1,%v2"
   [(set_attr "op_type"      "RRF,RRE,RXE,VRR")
    (set_attr "type"         "fdiv<mode>")
-   (set_attr "cpu_facility" "*,*,*,vec")
+   (set_attr "cpu_facility" "*,*,*,vx")
    (set_attr "enabled"      "<nBFP>,<nDFP>,<DSF>,<DFDI>")])
 
 
        (and:GPR (lshiftrt:GPR
                   (match_operand:GPR 1 "register_operand" "d")
                   (match_operand:GPR 2 "nonzero_shift_count_operand" ""))
-               (match_operand:GPR 3 "contiguous_bitmask_operand" "")))]
+               (match_operand:GPR 3 "contiguous_bitmask_nowrap_operand" "")))]
   "<z10_or_zEC12_cond>
    /* Note that even for the SImode pattern, the rotate is always DImode.  */
    && s390_extzv_shift_ok (<bitsize>, -INTVAL (operands[2]),
        (and:GPR (ashift:GPR
                  (match_operand:GPR 1 "register_operand" "d")
                  (match_operand:GPR 2 "nonzero_shift_count_operand" ""))
-               (match_operand:GPR 3 "contiguous_bitmask_operand" "")))]
+               (match_operand:GPR 3 "contiguous_bitmask_nowrap_operand" "")))]
   "<z10_or_zEC12_cond>
    && s390_extzv_shift_ok (<bitsize>, INTVAL (operands[2]),
                           INTVAL (operands[3]))"
        (and:GPR (not:GPR (match_operand:GPR 1 "nonimmediate_operand" ""))
                 (match_operand:GPR 2 "general_operand" "")))
    (clobber (reg:CC CC_REGNUM))]
-  "! reload_completed && s390_logical_operator_ok_p (operands)"
+  "! reload_completed
+   && (GET_CODE (operands[0]) != MEM
+      /* Ensure that s390_logical_operator_ok_p will succeed even
+        on the split xor if (b & a) is stored into a pseudo.  */
+       || rtx_equal_p (operands[0], operands[2]))"
   "#"
   "&& 1"
   [
    lc<xde>br\t%0,%1
    wflcdb\t%0,%1"
   [(set_attr "op_type"      "RRE,VRR")
-   (set_attr "cpu_facility" "*,vec")
+   (set_attr "cpu_facility" "*,vx")
    (set_attr "type"         "fsimp<mode>,*")
    (set_attr "enabled"      "*,<DFDI>")])
 
     lp<xde>br\t%0,%1
     wflpdb\t%0,%1"
   [(set_attr "op_type"      "RRE,VRR")
-   (set_attr "cpu_facility" "*,vec")
+   (set_attr "cpu_facility" "*,vx")
    (set_attr "type"         "fsimp<mode>,*")
    (set_attr "enabled"      "*,<DFDI>")])
 
    ln<xde>br\t%0,%1
    wflndb\t%0,%1"
   [(set_attr "op_type"      "RRE,VRR")
-   (set_attr "cpu_facility" "*,vec")
+   (set_attr "cpu_facility" "*,vx")
    (set_attr "type"         "fsimp<mode>,*")
    (set_attr "enabled"      "*,<DFDI>")])
 
    wfsqdb\t%v0,%v1"
   [(set_attr "op_type"      "RRE,RXE,VRR")
    (set_attr "type"         "fsqrt<mode>")
-   (set_attr "cpu_facility" "*,*,vec")
+   (set_attr "cpu_facility" "*,*,vx")
    (set_attr "enabled"      "*,<DSF>,<DFDI>")])
 
 
        (clz:DI (match_operand:DI 1 "register_operand" "d")))]
   "TARGET_EXTIMM && TARGET_ZARCH"
 {
-  rtx insn, clz_equal;
+  rtx_insn *insn;
+  rtx clz_equal;
   rtx wide_reg = gen_reg_rtx (TImode);
-  rtx msb = gen_rtx_CONST_INT (DImode, (unsigned HOST_WIDE_INT) 1 << 63);
+  rtx msb = gen_rtx_CONST_INT (DImode, HOST_WIDE_INT_1U << 63);
 
   clz_equal = gen_rtx_CLZ (DImode, operands[1]);
 
            (const_int 64))
           (zero_extend:TI (clz:DI (match_dup 1)))))
    (clobber (reg:CC CC_REGNUM))]
-  "(unsigned HOST_WIDE_INT) INTVAL (operands[2])
-   == (unsigned HOST_WIDE_INT) 1 << 63
+  "UINTVAL (operands[2]) == HOST_WIDE_INT_1U << 63
    && TARGET_EXTIMM && TARGET_ZARCH"
   "flogr\t%0,%1"
   [(set_attr "op_type"  "RRE")])
 (define_insn "nop_2_byte"
   [(unspec_volatile [(const_int 0)] UNSPECV_NOP_2_BYTE)]
   ""
-  "nopr\t%%r7"
+  "nopr\t%%r0"
   [(set_attr "op_type" "RR")])
 
 (define_insn "nop_4_byte"
 
 ; FIXME: There is also mvcin but we cannot use it since src and target
 ; may overlap.
+; lrvr, lrv, strv, lrvgr, lrvg, strvg
 (define_insn "bswap<mode>2"
   [(set (match_operand:GPR 0            "nonimmediate_operand" "=d,d,T")
        (bswap:GPR (match_operand:GPR 1 "nonimmediate_operand" " d,T,d")))]
   if (CONST_INT_P (operands[0])
       && INTVAL (operands[0]) >= 0 && INTVAL (operands[0]) <= 255)
     {
-      error ("Invalid transaction abort code: " HOST_WIDE_INT_PRINT_DEC
+      error ("invalid transaction abort code: " HOST_WIDE_INT_PRINT_DEC
             ".  Values in range 0 through 255 are reserved.",
             INTVAL (operands[0]));
       FAIL;
   "jg%C1\t%0"
   [(set_attr "op_type" "RIL")
    (set_attr "type"  "branch")])
+
+(define_insn "osc_break"
+  [(unspec_volatile [(const_int 0)] UNSPECV_OSC_BREAK)]
+  ""
+  "bcr\t7,%%r0"
+  [(set_attr "op_type" "RR")])