+2017-09-26 Andreas Krebbel <krebbel@linux.vnet.ibm.com>
+
+ * config/s390/predicates.md ("const_shift_by_byte_operand"): New
+ predicate.
+ * config/s390/vector.md ("*vec_srb<mode>"): Change modes to V_128
+ and V16QI.
+ ("*vec_slb<mode>"): New insn pattern.
+ ("vec_shr_<mode>"): New expander.
+ * config/s390/vx-builtins.md ("vec_slb<mode>"): Turn into expander
+ and force the shift count operand to V16QImode.
+ ("vec_srb<mode>"): Set shift count mode to V16QI.
+
2017-09-26 Andreas Krebbel <krebbel@linux.vnet.ibm.com>
* config/s390/vector.md ("vec_widen_umult_lo_<mode>")
}
return true;
})
+
+(define_predicate "const_shift_by_byte_operand"
+ (match_code "const_int")
+{
+ unsigned HOST_WIDE_INT val = INTVAL (op);
+ return val <= 128 && val % 8 == 0;
+})
; Pattern used by e.g. popcount
(define_insn "*vec_srb<mode>"
- [(set (match_operand:V_HW 0 "register_operand" "=v")
- (unspec:V_HW [(match_operand:V_HW 1 "register_operand" "v")
- (match_operand:<tointvec> 2 "register_operand" "v")]
- UNSPEC_VEC_SRLB))]
+ [(set (match_operand:V_128 0 "register_operand" "=v")
+ (unspec:V_128 [(match_operand:V_128 1 "register_operand" "v")
+ (match_operand:V16QI 2 "register_operand" "v")]
+ UNSPEC_VEC_SRLB))]
"TARGET_VX"
"vsrlb\t%v0,%v1,%v2"
[(set_attr "op_type" "VRR")])
+; Vector shift left by byte
+
+(define_insn "*vec_slb<mode>"
+ [(set (match_operand:V_128 0 "register_operand" "=v")
+ (unspec:V_128 [(match_operand:V_128 1 "register_operand" "v")
+ (match_operand:V16QI 2 "register_operand" "v")]
+ UNSPEC_VEC_SLB))]
+ "TARGET_VX"
+ "vslb\t%v0,%v1,%v2"
+ [(set_attr "op_type" "VRR")])
+
+; vec_shr is defined as shift towards element 0
+; this means it is a left shift on BE targets!
+(define_expand "vec_shr_<mode>"
+ [(set (match_dup 3)
+ (unspec:V16QI [(match_operand:SI 2 "const_shift_by_byte_operand" "")
+ (const_int 7)
+ (match_dup 3)]
+ UNSPEC_VEC_SET))
+ (set (match_operand:V_128 0 "register_operand" "")
+ (unspec:V_128 [(match_operand:V_128 1 "register_operand" "")
+ (match_dup 3)]
+ UNSPEC_VEC_SLB))]
+ "TARGET_VX"
+ {
+ operands[3] = gen_reg_rtx(V16QImode);
+ })
+
; vmnb, vmnh, vmnf, vmng
(define_insn "smin<mode>3"
[(set (match_operand:VI 0 "register_operand" "=v")
; reduc_umin
; reduc_umax
-; vec_shl vrep + vsl
-; vec_shr
-
; vec_pack_sfix_trunc: convert + pack ?
; vec_pack_ufix_trunc
; vec_unpacks_float_hi
; Vector shift left by byte
-(define_insn "vec_slb<mode>"
- [(set (match_operand:V_HW 0 "register_operand" "=v")
- (unspec:V_HW [(match_operand:V_HW 1 "register_operand" "v")
- (match_operand:<tointvec> 2 "register_operand" "v")]
+; Pattern definition in vector.md, see vec_vslb
+(define_expand "vec_slb<mode>"
+ [(set (match_operand:V_HW 0 "register_operand" "")
+ (unspec:V_HW [(match_operand:V_HW 1 "register_operand" "")
+ (match_operand:<tointvec> 2 "register_operand" "")]
UNSPEC_VEC_SLB))]
"TARGET_VX"
- "vslb\t%v0,%v1,%v2"
- [(set_attr "op_type" "VRR")])
-
+{
+ PUT_MODE (operands[2], V16QImode);
+})
; Vector shift left double by byte
; Vector shift right logical by byte
-; Pattern definition in vector.md
+; Pattern definition in vector.md, see vec_vsrb
(define_expand "vec_srb<mode>"
[(set (match_operand:V_HW 0 "register_operand" "")
(unspec:V_HW [(match_operand:V_HW 1 "register_operand" "")
(match_operand:<tointvec> 2 "register_operand" "")]
UNSPEC_VEC_SRLB))]
- "TARGET_VX")
-
+ "TARGET_VX"
+{
+ PUT_MODE (operands[2], V16QImode);
+})
; Vector subtract