[(set_attr "op_type" "RS,RSY")
(set_attr "z10prop" "z10_super_E1,z10_super_E1")])
+;
+; extv instruction patterns
+;
+
+; FIXME: This expander needs to be converted from DI to GPR as well
+; after resolving some issues with it.
+
+(define_expand "extzv"
+ [(parallel
+ [(set (match_operand:DI 0 "register_operand" "=d")
+ (zero_extract:DI
+ (match_operand:DI 1 "register_operand" "d")
+ (match_operand 2 "const_int_operand" "") ; size
+ (match_operand 3 "const_int_operand" ""))) ; start
+ (clobber (reg:CC CC_REGNUM))])]
+ "TARGET_Z10"
+{
+ /* Starting with zEC12 there is risbgn not clobbering CC. */
+ if (TARGET_ZEC12)
+ {
+ emit_move_insn (operands[0],
+ gen_rtx_ZERO_EXTRACT (DImode,
+ operands[1],
+ operands[2],
+ operands[3]));
+ DONE;
+ }
+})
-(define_insn_and_split "*extzv<mode>"
+(define_insn "*extzv<mode>_zEC12"
+ [(set (match_operand:GPR 0 "register_operand" "=d")
+ (zero_extract:GPR
+ (match_operand:GPR 1 "register_operand" "d")
+ (match_operand 2 "const_int_operand" "") ; size
+ (match_operand 3 "const_int_operand" "")))] ; start]
+ "TARGET_ZEC12"
+ "risbgn\t%0,%1,64-%2,128+63,<bitsize>+%3+%2" ; dst, src, start, end, shift
+ [(set_attr "op_type" "RIE")])
+
+(define_insn "*extzv<mode>_z10"
+ [(set (match_operand:GPR 0 "register_operand" "=d")
+ (zero_extract:GPR
+ (match_operand:GPR 1 "register_operand" "d")
+ (match_operand 2 "const_int_operand" "") ; size
+ (match_operand 3 "const_int_operand" ""))) ; start
+ (clobber (reg:CC CC_REGNUM))]
+ "TARGET_Z10"
+ "risbg\t%0,%1,64-%2,128+63,<bitsize>+%3+%2" ; dst, src, start, end, shift
+ [(set_attr "op_type" "RIE")
+ (set_attr "z10prop" "z10_super_E1")])
+
+(define_insn_and_split "*pre_z10_extzv<mode>"
[(set (match_operand:GPR 0 "register_operand" "=d")
(zero_extract:GPR (match_operand:QI 1 "s_operand" "QS")
- (match_operand 2 "const_int_operand" "n")
+ (match_operand 2 "nonzero_shift_count_operand" "")
(const_int 0)))
(clobber (reg:CC CC_REGNUM))]
- "INTVAL (operands[2]) > 0
- && INTVAL (operands[2]) <= GET_MODE_BITSIZE (SImode)"
+ "!TARGET_Z10"
"#"
"&& reload_completed"
[(parallel
operands[3] = GEN_INT (mask);
})
-(define_insn_and_split "*extv<mode>"
+(define_insn_and_split "*pre_z10_extv<mode>"
[(set (match_operand:GPR 0 "register_operand" "=d")
(sign_extract:GPR (match_operand:QI 1 "s_operand" "QS")
- (match_operand 2 "const_int_operand" "n")
+ (match_operand 2 "nonzero_shift_count_operand" "")
(const_int 0)))
(clobber (reg:CC CC_REGNUM))]
- "INTVAL (operands[2]) > 0
- && INTVAL (operands[2]) <= GET_MODE_BITSIZE (SImode)"
+ ""
"#"
"&& reload_completed"
[(parallel
(clobber (reg:CC CC_REGNUM))])]
"s390_narrow_logical_operator (AND, &operands[0], &operands[1]);")
+;; These two are what combine generates for (ashift (zero_extract)).
+(define_insn "*extzv_<mode>_srl"
+ [(set (match_operand:GPR 0 "register_operand" "=d")
+ (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" "")))
+ (clobber (reg:CC CC_REGNUM))]
+ "TARGET_Z10
+ /* Note that even for the SImode pattern, the rotate is always DImode. */
+ && s390_extzv_shift_ok (<bitsize>, -INTVAL (operands[2]),
+ INTVAL (operands[3]))"
+ "risbg\t%0,%1,%<bfstart>3,128+%<bfend>3,64-%2"
+ [(set_attr "op_type" "RIE")
+ (set_attr "z10prop" "z10_super_E1")])
+
+(define_insn "*extzv_<mode>_sll"
+ [(set (match_operand:GPR 0 "register_operand" "=d")
+ (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" "")))
+ (clobber (reg:CC CC_REGNUM))]
+ "TARGET_Z10
+ && s390_extzv_shift_ok (<bitsize>, INTVAL (operands[2]),
+ INTVAL (operands[3]))"
+ "risbg\t%0,%1,%<bfstart>3,128+%<bfend>3,%2"
+ [(set_attr "op_type" "RIE")
+ (set_attr "z10prop" "z10_super_E1")])
+
;
; andsi3 instruction pattern(s).