diff options
author | Jeff Law <jeffreyalaw@gmail.com> | 2021-07-02 11:58:47 -0400 |
---|---|---|
committer | Jeff Law <jeffreyalaw@gmail.com> | 2021-07-02 12:02:31 -0400 |
commit | 7aa5fb17a30ff0ce9928e5eac35b892d95e7eba5 (patch) | |
tree | 6dd7cbabbc404d1b6d45a45e0b07d66cfc034ab3 /gcc | |
parent | 84f7bab89279ca1234fef88929c74caeda8cb55e (diff) | |
download | gcc-7aa5fb17a30ff0ce9928e5eac35b892d95e7eba5.zip gcc-7aa5fb17a30ff0ce9928e5eac35b892d95e7eba5.tar.gz gcc-7aa5fb17a30ff0ce9928e5eac35b892d95e7eba5.tar.bz2 |
Use shift instructions to eliminate redundant compare/test instructions on the H8
gcc/ChangeLog
* config/h8300/h8300-protos.h (compute_a_shift_cc): Accept
additional argument for the code.
* config/h8300/h8300.c (compute_a_shift_cc): Accept additional
argument for the code. Just return if the ZN bits are useful or
not rather than the old style CC_* enums.
* config/h8300/shiftrotate.md (shiftqi_noscratch): Move before
more generic shiftqi patterns.
(shifthi_noscratch, shiftsi_noscratch): Similarly.
(shiftqi_noscratch_set_flags): New pattern.
(shifthi_noscratch_set_flags, shiftsi_noscratch_set_flags): Likewise.
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/config/h8300/h8300-protos.h | 2 | ||||
-rw-r--r-- | gcc/config/h8300/h8300.c | 20 | ||||
-rw-r--r-- | gcc/config/h8300/shiftrotate.md | 153 |
3 files changed, 116 insertions, 59 deletions
diff --git a/gcc/config/h8300/h8300-protos.h b/gcc/config/h8300/h8300-protos.h index 86bcc3f..744337d 100644 --- a/gcc/config/h8300/h8300-protos.h +++ b/gcc/config/h8300/h8300-protos.h @@ -41,7 +41,7 @@ extern const char *output_logical_op (machine_mode, rtx_code code, extern unsigned int compute_logical_op_length (machine_mode, rtx_code, rtx *, rtx_insn *); -extern int compute_a_shift_cc (rtx, rtx *); +extern int compute_a_shift_cc (rtx *, rtx_code); #ifdef HAVE_ATTR_cc extern enum attr_cc compute_plussi_cc (rtx *); #endif diff --git a/gcc/config/h8300/h8300.c b/gcc/config/h8300/h8300.c index 0fdc68b..d2f6548 100644 --- a/gcc/config/h8300/h8300.c +++ b/gcc/config/h8300/h8300.c @@ -4297,11 +4297,9 @@ compute_a_shift_length (rtx operands[3], rtx_code code) /* Compute which flag bits are valid after a shift insn. */ int -compute_a_shift_cc (rtx insn ATTRIBUTE_UNUSED, rtx *operands) +compute_a_shift_cc (rtx operands[3], rtx_code code) { - rtx shift = operands[3]; - machine_mode mode = GET_MODE (shift); - enum rtx_code code = GET_CODE (shift); + machine_mode mode = GET_MODE (operands[0]); enum shift_type shift_type; enum shift_mode shift_mode; struct shift_info info; @@ -4358,16 +4356,18 @@ compute_a_shift_cc (rtx insn ATTRIBUTE_UNUSED, rtx *operands) { case SHIFT_SPECIAL: if (info.remainder == 0) - return info.cc_special; + return (info.cc_special == OLD_CC_SET_ZN + || info.cc_special == OLD_CC_SET_ZNV); /* Fall through. */ case SHIFT_INLINE: - return info.cc_inline; + return (info.cc_inline == OLD_CC_SET_ZN + || info.cc_inline == OLD_CC_SET_ZNV); case SHIFT_ROT_AND: /* This case always ends with an and instruction. */ - return OLD_CC_SET_ZNV; + return true; case SHIFT_LOOP: /* A loop to shift by a "large" constant value. @@ -4375,9 +4375,11 @@ compute_a_shift_cc (rtx insn ATTRIBUTE_UNUSED, rtx *operands) if (info.shift2 != NULL) { if (n % 2) - return info.cc_inline; + return (info.cc_inline == OLD_CC_SET_ZN + || info.cc_inline == OLD_CC_SET_ZNV); + } - return OLD_CC_CLOBBER; + return false; default: gcc_unreachable (); diff --git a/gcc/config/h8300/shiftrotate.md b/gcc/config/h8300/shiftrotate.md index c5d32cd..0476324 100644 --- a/gcc/config/h8300/shiftrotate.md +++ b/gcc/config/h8300/shiftrotate.md @@ -150,33 +150,6 @@ } [(set_attr "length" "4")]) -(define_insn_and_split "*shiftqi" - [(set (match_operand:QI 0 "register_operand" "=r,r") - (shifts:QI - (match_operand:QI 1 "register_operand" "0,0") - (match_operand:QI 2 "nonmemory_operand" "R,rn"))) - (clobber (match_scratch:QI 3 "=X,&r"))] - "" - "#" - "&& reload_completed" - [(parallel [(set (match_dup 0) (shifts:QI (match_dup 1) (match_dup 2))) - (clobber (match_dup 3)) - (clobber (reg:CC CC_REG))])]) - -(define_insn "*shiftqi_clobber_flags" - [(set (match_operand:QI 0 "register_operand" "=r,r") - (shifts:QI - (match_operand:QI 1 "register_operand" "0,0") - (match_operand:QI 2 "nonmemory_operand" "R,rn"))) - (clobber (match_scratch:QI 3 "=X,&r")) - (clobber (reg:CC CC_REG))] - "" -{ - return output_a_shift (operands, <CODE>); -} - [(set (attr "length") - (symbol_ref "compute_a_shift_length (operands, <CODE>)"))]) - (define_insn_and_split "*shiftqi_noscratch" [(set (match_operand:QI 0 "register_operand" "=r,r") (shifts:QI @@ -204,24 +177,43 @@ [(set (attr "length") (symbol_ref "compute_a_shift_length (operands, <CODE>)"))]) -(define_insn_and_split "*shifthi" - [(set (match_operand:HI 0 "register_operand" "=r,r") - (shifts:HI - (match_operand:HI 1 "register_operand" "0,0") - (match_operand:QI 2 "nonmemory_operand" "S,rn"))) +(define_insn "*shiftqi_noscratch_set_flags" + [(set (reg:CCZN CC_REG) + (compare:CCZN + (shifts:QI + (match_operand:QI 1 "register_operand" "0,0") + (match_operand:QI 2 "nonmemory_operand" "R,rn")) + (const_int 0))) + (set (match_operand:QI 0 "register_operand" "=r,r") + (shifts:QI (match_dup 1) (match_dup 2)))] + "(GET_CODE (operands[2]) == CONST_INT + && !h8300_shift_needs_scratch_p (INTVAL (operands[2]), QImode, <CODE>) + && compute_a_shift_cc (operands, <CODE>))" +{ + return output_a_shift (operands, <CODE>); +} + [(set (attr "length") + (symbol_ref "compute_a_shift_length (operands, <CODE>)"))]) + + +(define_insn_and_split "*shiftqi" + [(set (match_operand:QI 0 "register_operand" "=r,r") + (shifts:QI + (match_operand:QI 1 "register_operand" "0,0") + (match_operand:QI 2 "nonmemory_operand" "R,rn"))) (clobber (match_scratch:QI 3 "=X,&r"))] "" "#" "&& reload_completed" - [(parallel [(set (match_dup 0) (shifts:HI (match_dup 1) (match_dup 2))) + [(parallel [(set (match_dup 0) (shifts:QI (match_dup 1) (match_dup 2))) (clobber (match_dup 3)) (clobber (reg:CC CC_REG))])]) -(define_insn "*shifthi_clobber_flags" - [(set (match_operand:HI 0 "register_operand" "=r,r") - (shifts:HI - (match_operand:HI 1 "register_operand" "0,0") - (match_operand:QI 2 "nonmemory_operand" "S,rn"))) +(define_insn "*shiftqi_clobber_flags" + [(set (match_operand:QI 0 "register_operand" "=r,r") + (shifts:QI + (match_operand:QI 1 "register_operand" "0,0") + (match_operand:QI 2 "nonmemory_operand" "R,rn"))) (clobber (match_scratch:QI 3 "=X,&r")) (clobber (reg:CC CC_REG))] "" @@ -257,24 +249,41 @@ [(set (attr "length") (symbol_ref "compute_a_shift_length (operands, <CODE>)"))]) -(define_insn_and_split "*shiftsi" - [(set (match_operand:SI 0 "register_operand" "=r,r") - (shifts:SI - (match_operand:SI 1 "register_operand" "0,0") - (match_operand:QI 2 "nonmemory_operand" "T,rn"))) +(define_insn "*shifthi_noscratch_setzn" + [(set (reg:CCZN CC_REG) + (compare:CCZN + (shifts:HI (match_operand:HI 1 "register_operand" "0,0") + (match_operand:HI 2 "nonmemory_operand" "S,rn")) + (const_int 0))) + (set (match_operand:HI 0 "register_operand" "=r,r") + (shifts:HI (match_dup 1) (match_dup 2)))] + "(GET_CODE (operands[2]) == CONST_INT + && !h8300_shift_needs_scratch_p (INTVAL (operands[2]), HImode, <CODE>) + && compute_a_shift_cc (operands, <CODE>))" +{ + return output_a_shift (operands, <CODE>); +} + [(set (attr "length") + (symbol_ref "compute_a_shift_length (operands, <CODE>)"))]) + +(define_insn_and_split "*shifthi" + [(set (match_operand:HI 0 "register_operand" "=r,r") + (shifts:HI + (match_operand:HI 1 "register_operand" "0,0") + (match_operand:QI 2 "nonmemory_operand" "S,rn"))) (clobber (match_scratch:QI 3 "=X,&r"))] "" "#" "&& reload_completed" - [(parallel [(set (match_dup 0) (shifts:SI (match_dup 1) (match_dup 2))) + [(parallel [(set (match_dup 0) (shifts:HI (match_dup 1) (match_dup 2))) (clobber (match_dup 3)) (clobber (reg:CC CC_REG))])]) -(define_insn "*shiftsi_clobber_flags" - [(set (match_operand:SI 0 "register_operand" "=r,r") - (shifts:SI - (match_operand:SI 1 "register_operand" "0,0") - (match_operand:QI 2 "nonmemory_operand" "T,rn"))) +(define_insn "*shifthi_clobber_flags" + [(set (match_operand:HI 0 "register_operand" "=r,r") + (shifts:HI + (match_operand:HI 1 "register_operand" "0,0") + (match_operand:QI 2 "nonmemory_operand" "S,rn"))) (clobber (match_scratch:QI 3 "=X,&r")) (clobber (reg:CC CC_REG))] "" @@ -310,9 +319,55 @@ [(set (attr "length") (symbol_ref "compute_a_shift_length (operands, <CODE>)"))]) +(define_insn "*shiftsi_noscratch_cczn" + [(set (reg:CCZN CC_REG) + (compare:CCZN + (shifts:SI + (match_operand:SI 1 "register_operand" "0,0") + (match_operand:SI 2 "nonmemory_operand" "T,rn")) + (const_int 0))) + (set (match_operand:SI 0 "register_operand" "=r,r") + (shifts:SI (match_dup 1) (match_dup 2)))] + "(GET_CODE (operands[2]) == CONST_INT + && !h8300_shift_needs_scratch_p (INTVAL (operands[2]), SImode, <CODE>) + && compute_a_shift_cc (operands, <CODE>))" +{ + return output_a_shift (operands, <CODE>); +} + [(set (attr "length") + (symbol_ref "compute_a_shift_length (operands, <CODE>)"))]) + ;; Split a variable shift into a loop. If the register containing ;; the shift count dies, then we just use that register. + +(define_insn_and_split "*shiftsi" + [(set (match_operand:SI 0 "register_operand" "=r,r") + (shifts:SI + (match_operand:SI 1 "register_operand" "0,0") + (match_operand:QI 2 "nonmemory_operand" "T,rn"))) + (clobber (match_scratch:QI 3 "=X,&r"))] + "" + "#" + "&& reload_completed" + [(parallel [(set (match_dup 0) (shifts:SI (match_dup 1) (match_dup 2))) + (clobber (match_dup 3)) + (clobber (reg:CC CC_REG))])]) + +(define_insn "*shiftsi_clobber_flags" + [(set (match_operand:SI 0 "register_operand" "=r,r") + (shifts:SI + (match_operand:SI 1 "register_operand" "0,0") + (match_operand:QI 2 "nonmemory_operand" "T,rn"))) + (clobber (match_scratch:QI 3 "=X,&r")) + (clobber (reg:CC CC_REG))] + "" +{ + return output_a_shift (operands, <CODE>); +} + [(set (attr "length") + (symbol_ref "compute_a_shift_length (operands, <CODE>)"))]) + (define_split [(set (match_operand 0 "register_operand" "") (match_operator 2 "nshift_operator" |