s390: Implement extzv for z10
* config/s390/predicates.md (nonzero_shift_count_operand): New. * config/s390/s390-protos.h (s390_extzv_shift_ok): Declare. * config/s390/s390.c (s390_extzv_shift_ok): New function. * config/s390/s390.md (extzv): New expander. (*extzv<GPR>_zEC12, *extzv<GPR>_z10): New insns. (*pre_z10_extzv<GPR>): Rename from *extzv<GPR>; simplify with nonzero_shift_count_operand. (*extzv_<mode>_srl, *extzv_<mode>_sll): New insns. Co-Authored-By: Andreas Krebbel <Andreas.Krebbel@de.ibm.com> From-SVN: r194644
This commit is contained in:
parent
2542ef057b
commit
1a2e356efe
5 changed files with 118 additions and 8 deletions
|
@ -21,6 +21,15 @@
|
|||
(extend<HQI><DSI>2, zero_extend<HQI>si2): Likewise.
|
||||
(zero_extend<HQI>di2, fixuns_trunc<BFP><GPR>2): Likewise.
|
||||
|
||||
* config/s390/predicates.md (nonzero_shift_count_operand): New.
|
||||
* config/s390/s390-protos.h (s390_extzv_shift_ok): Declare.
|
||||
* config/s390/s390.c (s390_extzv_shift_ok): New function.
|
||||
* config/s390/s390.md (extzv): New expander.
|
||||
(*extzv<GPR>_zEC12, *extzv<GPR>_z10): New insns.
|
||||
(*pre_z10_extzv<GPR>): Rename from *extzv<GPR>; simplify with
|
||||
nonzero_shift_count_operand.
|
||||
(*extzv_<mode>_srl, *extzv_<mode>_sll): New insns.
|
||||
|
||||
2012-12-20 Thomas Schwinge <thomas@codesourcery.com>
|
||||
|
||||
PR bootstrap/55202
|
||||
|
|
|
@ -101,6 +101,10 @@
|
|||
return true;
|
||||
})
|
||||
|
||||
(define_predicate "nonzero_shift_count_operand"
|
||||
(and (match_code "const_int")
|
||||
(match_test "IN_RANGE (INTVAL (op), 1, GET_MODE_BITSIZE (mode) - 1)")))
|
||||
|
||||
;; Return true if OP a valid operand for the LARL instruction.
|
||||
|
||||
(define_predicate "larl_operand"
|
||||
|
|
|
@ -109,5 +109,6 @@ extern bool s390_legitimate_address_without_index_p (rtx);
|
|||
extern bool s390_decompose_shift_count (rtx, rtx *, HOST_WIDE_INT *);
|
||||
extern int s390_branch_condition_mask (rtx);
|
||||
extern int s390_compare_and_branch_condition_mask (rtx);
|
||||
extern bool s390_extzv_shift_ok (int, int, unsigned HOST_WIDE_INT);
|
||||
|
||||
#endif /* RTX_CODE */
|
||||
|
|
|
@ -1347,6 +1347,24 @@ s390_contiguous_bitmask_p (unsigned HOST_WIDE_INT in, int size,
|
|||
return true;
|
||||
}
|
||||
|
||||
/* Check whether a rotate of ROTL followed by an AND of CONTIG is
|
||||
equivalent to a shift followed by the AND. In particular, CONTIG
|
||||
should not overlap the (rotated) bit 0/bit 63 gap. Negative values
|
||||
for ROTL indicate a rotate to the right. */
|
||||
|
||||
bool
|
||||
s390_extzv_shift_ok (int bitsize, int rotl, unsigned HOST_WIDE_INT contig)
|
||||
{
|
||||
int pos, len;
|
||||
bool ok;
|
||||
|
||||
ok = s390_contiguous_bitmask_p (contig, bitsize, &pos, &len);
|
||||
gcc_assert (ok);
|
||||
|
||||
return ((rotl >= 0 && rotl <= pos)
|
||||
|| (rotl < 0 && -rotl <= bitsize - len - pos));
|
||||
}
|
||||
|
||||
/* Check whether we can (and want to) split a double-word
|
||||
move in mode MODE from SRC to DST into two single-word
|
||||
moves, moving the subword FIRST_SUBWORD first. */
|
||||
|
|
|
@ -3307,15 +3307,64 @@
|
|||
[(set_attr "op_type" "RS,RSY")
|
||||
(set_attr "z10prop" "z10_super_E1,z10_super_E1")])
|
||||
|
||||
;
|
||||
; extv instruction patterns
|
||||
;
|
||||
|
||||
(define_insn_and_split "*extzv<mode>"
|
||||
; 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 "*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
|
||||
|
@ -3333,14 +3382,13 @@
|
|||
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
|
||||
|
@ -6067,6 +6115,36 @@
|
|||
(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).
|
||||
|
|
Loading…
Add table
Reference in a new issue