Fix minor bugs in H8 port logical ops. Prepare for more compare/test removal
gcc/ * config/h8300/h8300-protos.h (compute_a_shift_length): Drop unused argument from prototype. (output_logical_op): Add rtx_code argument. (compute_logical_op_length): Likewise. * config/h8300/h8300.c (h8300_and_costs): Pass additional argument to compute_a_shift_length. (output_logical_op); New argument with the rtx code rather than extracting it from an operand. Handle QImode too. (compute_logical_op_length): Similary. (compute_a_shift_length): Drop unused argument. * config/h8300/h8300.md (logicals): New code iterator. * config/h8300/logical.md (<code><mode>3 expander): Combine the "and" expander with the "ior"/"xor" expander. (bclr<mode>msx): Combine the QI/HI mode patterns. (<logical><mode>3 insns): Use code iterator rather than match_operator. Handle QImode as well. Update call to output_logical_op and compute_logical_op_length to pass in rtx_code Fix split condition on all define_insn_and_split patterns. (one_cmpl<mode>2<cczn>): Use <cczn> to support both clobbering the flags and setting ZN via existing define_subst. * config/h8300/shiftrotate.md: Drop unused argument from calls to compute_a_shift_length. Signed-off-by: Jeff Law <jeffreyalaw@gmail.com>
This commit is contained in:
parent
b75978d14f
commit
4ea5fe8b40
5 changed files with 55 additions and 64 deletions
|
@ -29,16 +29,15 @@ extern unsigned int compute_mov_length (rtx *);
|
|||
extern const char *output_plussi (rtx *, bool);
|
||||
extern unsigned int compute_plussi_length (rtx *, bool);
|
||||
extern const char *output_a_shift (rtx *);
|
||||
extern unsigned int compute_a_shift_length (rtx, rtx *);
|
||||
extern unsigned int compute_a_shift_length (rtx *);
|
||||
extern const char *output_a_rotate (enum rtx_code, rtx *);
|
||||
extern unsigned int compute_a_rotate_length (rtx *);
|
||||
extern const char *output_simode_bld (int, rtx[]);
|
||||
extern void final_prescan_insn (rtx_insn *, rtx *, int);
|
||||
extern int h8300_expand_movsi (rtx[]);
|
||||
extern machine_mode h8300_select_cc_mode (RTX_CODE, rtx, rtx);
|
||||
extern const char *output_logical_op (machine_mode, rtx *);
|
||||
extern unsigned int compute_logical_op_length (machine_mode,
|
||||
rtx *);
|
||||
extern const char *output_logical_op (machine_mode, rtx_code code, rtx *);
|
||||
extern unsigned int compute_logical_op_length (machine_mode, rtx_code, rtx *);
|
||||
|
||||
extern int compute_logical_op_cc (machine_mode, rtx *);
|
||||
extern int compute_a_shift_cc (rtx, rtx *);
|
||||
|
|
|
@ -1100,7 +1100,7 @@ h8300_and_costs (rtx x)
|
|||
operands[1] = XEXP (x, 0);
|
||||
operands[2] = XEXP (x, 1);
|
||||
operands[3] = x;
|
||||
return compute_logical_op_length (GET_MODE (x), operands) / 2;
|
||||
return compute_logical_op_length (GET_MODE (x), AND, operands) / 2;
|
||||
}
|
||||
|
||||
/* Compute the cost of a shift insn. */
|
||||
|
@ -1119,7 +1119,7 @@ h8300_shift_costs (rtx x)
|
|||
operands[1] = NULL;
|
||||
operands[2] = XEXP (x, 1);
|
||||
operands[3] = x;
|
||||
return compute_a_shift_length (NULL, operands) / 2;
|
||||
return compute_a_shift_length (operands) / 2;
|
||||
}
|
||||
|
||||
/* Worker function for TARGET_RTX_COSTS. */
|
||||
|
@ -2879,10 +2879,8 @@ compute_plussi_cc (rtx *operands)
|
|||
/* Output a logical insn. */
|
||||
|
||||
const char *
|
||||
output_logical_op (machine_mode mode, rtx *operands)
|
||||
output_logical_op (machine_mode mode, rtx_code code, rtx *operands)
|
||||
{
|
||||
/* Figure out the logical op that we need to perform. */
|
||||
enum rtx_code code = GET_CODE (operands[3]);
|
||||
/* Pretend that every byte is affected if both operands are registers. */
|
||||
const unsigned HOST_WIDE_INT intval =
|
||||
(unsigned HOST_WIDE_INT) ((GET_CODE (operands[2]) == CONST_INT)
|
||||
|
@ -2923,6 +2921,10 @@ output_logical_op (machine_mode mode, rtx *operands)
|
|||
|
||||
switch (mode)
|
||||
{
|
||||
case E_QImode:
|
||||
sprintf (insn_buf, "%s.b\t%%X2,%%X0", opname);
|
||||
output_asm_insn (insn_buf, operands);
|
||||
break;
|
||||
case E_HImode:
|
||||
/* First, see if we can finish with one insn. */
|
||||
if (b0 != 0 && b1 != 0)
|
||||
|
@ -3033,10 +3035,8 @@ output_logical_op (machine_mode mode, rtx *operands)
|
|||
/* Compute the length of a logical insn. */
|
||||
|
||||
unsigned int
|
||||
compute_logical_op_length (machine_mode mode, rtx *operands)
|
||||
compute_logical_op_length (machine_mode mode, rtx_code code, rtx *operands)
|
||||
{
|
||||
/* Figure out the logical op that we need to perform. */
|
||||
enum rtx_code code = GET_CODE (operands[3]);
|
||||
/* Pretend that every byte is affected if both operands are registers. */
|
||||
const unsigned HOST_WIDE_INT intval =
|
||||
(unsigned HOST_WIDE_INT) ((GET_CODE (operands[2]) == CONST_INT)
|
||||
|
@ -3061,6 +3061,9 @@ compute_logical_op_length (machine_mode mode, rtx *operands)
|
|||
|
||||
switch (mode)
|
||||
{
|
||||
case E_QImode:
|
||||
return 2;
|
||||
|
||||
case E_HImode:
|
||||
/* First, see if we can finish with one insn. */
|
||||
if (b0 != 0 && b1 != 0)
|
||||
|
@ -4189,7 +4192,7 @@ h8300_asm_insn_count (const char *templ)
|
|||
/* Compute the length of a shift insn. */
|
||||
|
||||
unsigned int
|
||||
compute_a_shift_length (rtx insn ATTRIBUTE_UNUSED, rtx *operands)
|
||||
compute_a_shift_length (rtx *operands)
|
||||
{
|
||||
rtx shift = operands[3];
|
||||
machine_mode mode = GET_MODE (shift);
|
||||
|
|
|
@ -229,6 +229,8 @@
|
|||
|
||||
(define_code_iterator shifts [ashift ashiftrt lshiftrt])
|
||||
|
||||
(define_code_iterator logicals [ior xor and])
|
||||
|
||||
(define_code_iterator ors [ior xor])
|
||||
|
||||
(include "movepush.md")
|
||||
|
|
|
@ -1,11 +1,20 @@
|
|||
;; Generic for binary logicals across the supported integer modes
|
||||
(define_expand "<code><mode>3"
|
||||
[(set (match_operand:QHSI 0 "register_operand" "")
|
||||
(logicals:QHSI (match_operand:QHSI 1 "register_operand" "")
|
||||
(match_operand:QHSI 2 "h8300_src_operand" "")))]
|
||||
""
|
||||
"")
|
||||
|
||||
;; There's a ton of cleanup to do from here below.
|
||||
;; ----------------------------------------------------------------------
|
||||
;; AND INSTRUCTIONS
|
||||
;; ----------------------------------------------------------------------
|
||||
|
||||
(define_insn "bclrqi_msx"
|
||||
[(set (match_operand:QI 0 "bit_register_indirect_operand" "=WU")
|
||||
(and:QI (match_operand:QI 1 "bit_register_indirect_operand" "%0")
|
||||
(match_operand:QI 2 "single_zero_operand" "Y0")))]
|
||||
(define_insn "bclr<mode>_msx"
|
||||
[(set (match_operand:QHI 0 "bit_register_indirect_operand" "=WU")
|
||||
(and:QHI (match_operand:QHI 1 "bit_register_indirect_operand" "%0")
|
||||
(match_operand:QHI 2 "single_zero_operand" "Y0")))]
|
||||
"TARGET_H8300SX && rtx_equal_p (operands[0], operands[1])"
|
||||
"bclr\\t%W2,%0"
|
||||
[(set_attr "length" "8")])
|
||||
|
@ -24,21 +33,13 @@
|
|||
operands[2] = GEN_INT ((INTVAL (operands[2])) >> 8);
|
||||
})
|
||||
|
||||
(define_insn "bclrhi_msx"
|
||||
[(set (match_operand:HI 0 "bit_register_indirect_operand" "=m")
|
||||
(and:HI (match_operand:HI 1 "bit_register_indirect_operand" "%0")
|
||||
(match_operand:HI 2 "single_zero_operand" "Y0")))]
|
||||
"TARGET_H8300SX"
|
||||
"bclr\\t%W2,%0"
|
||||
[(set_attr "length" "8")])
|
||||
|
||||
(define_insn_and_split "*andqi3_2"
|
||||
[(set (match_operand:QI 0 "bit_operand" "=U,rQ,r")
|
||||
(and:QI (match_operand:QI 1 "bit_operand" "%0,0,WU")
|
||||
(match_operand:QI 2 "h8300_src_operand" "Y0,rQi,IP1>X")))]
|
||||
"TARGET_H8300SX"
|
||||
"#"
|
||||
"reload_completed"
|
||||
"&& reload_completed"
|
||||
[(parallel [(set (match_dup 0) (and:QI (match_dup 1) (match_dup 2)))
|
||||
(clobber (reg:CC CC_REG))])])
|
||||
|
||||
|
@ -62,7 +63,7 @@
|
|||
"register_operand (operands[0], QImode)
|
||||
|| single_zero_operand (operands[2], QImode)"
|
||||
"#"
|
||||
"reload_completed"
|
||||
"&& reload_completed"
|
||||
[(parallel [(set (match_dup 0) (and:QI (match_dup 1) (match_dup 2)))
|
||||
(clobber (reg:CC CC_REG))])])
|
||||
|
||||
|
@ -78,13 +79,6 @@
|
|||
and %X2,%X0"
|
||||
[(set_attr "length" "2,8")])
|
||||
|
||||
(define_expand "and<mode>3"
|
||||
[(set (match_operand:QHSI 0 "register_operand" "")
|
||||
(and:QHSI (match_operand:QHSI 1 "register_operand" "")
|
||||
(match_operand:QHSI 2 "h8300_src_operand" "")))]
|
||||
""
|
||||
"")
|
||||
|
||||
(define_insn_and_split "*andor<mode>3"
|
||||
[(set (match_operand:QHSI 0 "register_operand" "=r")
|
||||
(ior:QHSI (and:QHSI (match_operand:QHSI 2 "register_operand" "r")
|
||||
|
@ -95,7 +89,7 @@
|
|||
|| (<MODE>mode == SImode
|
||||
&& (INTVAL (operands[3]) & 0xffff) != 0))"
|
||||
"#"
|
||||
"reload_completed"
|
||||
"&& reload_completed"
|
||||
[(parallel [(set (match_dup 0) (ior:QHSI (and:QHSI (match_dup 2)
|
||||
(match_dup 3))
|
||||
(match_dup 1)))
|
||||
|
@ -150,7 +144,7 @@
|
|||
(match_operand:SI 1 "register_operand" "0")))]
|
||||
""
|
||||
"#"
|
||||
"reload_completed"
|
||||
"&& reload_completed"
|
||||
[(parallel [(set (match_dup 0) (ior:SI (and:SI (ashift:SI (match_dup 2)
|
||||
(const_int 8))
|
||||
(const_int 65280))
|
||||
|
@ -195,7 +189,7 @@
|
|||
"TARGET_H8300SX || register_operand (operands[0], QImode)
|
||||
|| single_one_operand (operands[2], QImode)"
|
||||
"#"
|
||||
"reload_completed"
|
||||
"&& reload_completed"
|
||||
[(parallel [(set (match_dup 0) (ors:QI (match_dup 1) (match_dup 2)))
|
||||
(clobber (reg:CC CC_REG))])])
|
||||
|
||||
|
@ -216,39 +210,32 @@
|
|||
[(set_attr "length" "8,*")
|
||||
(set_attr "length_table" "*,logicb")])
|
||||
|
||||
(define_expand "<code><mode>3"
|
||||
[(set (match_operand:QHSI 0 "register_operand" "")
|
||||
(ors:QHSI (match_operand:QHSI 1 "register_operand" "")
|
||||
(match_operand:QHSI 2 "h8300_src_operand" "")))]
|
||||
""
|
||||
"")
|
||||
|
||||
;; ----------------------------------------------------------------------
|
||||
;; {AND,IOR,XOR}{HI3,SI3} PATTERNS
|
||||
;; ----------------------------------------------------------------------
|
||||
|
||||
(define_insn_and_split "*logical<mode>3"
|
||||
[(set (match_operand:HSI 0 "h8300_dst_operand" "=rQ")
|
||||
(match_operator:HSI 3 "bit_operator"
|
||||
[(match_operand:HSI 1 "h8300_dst_operand" "%0")
|
||||
(match_operand:HSI 2 "h8300_src_operand" "rQi")]))]
|
||||
[(set (match_operand:QHSI 0 "h8300_dst_operand" "=rQ")
|
||||
(logicals:QHSI
|
||||
(match_operand:QHSI 1 "h8300_dst_operand" "%0")
|
||||
(match_operand:QHSI 2 "h8300_src_operand" "rQi")))]
|
||||
"h8300_operands_match_p (operands)"
|
||||
"#"
|
||||
"reload_completed"
|
||||
"&& reload_completed"
|
||||
[(parallel [(set (match_dup 0)
|
||||
(match_op_dup 3 [(match_dup 1) (match_dup 2)]))
|
||||
(clobber (reg:CC CC_REG))])])
|
||||
|
||||
(define_insn "*logical<mode>3_clobber_flags"
|
||||
[(set (match_operand:HSI 0 "h8300_dst_operand" "=rQ")
|
||||
(match_operator:HSI 3 "bit_operator"
|
||||
[(match_operand:HSI 1 "h8300_dst_operand" "%0")
|
||||
(match_operand:HSI 2 "h8300_src_operand" "rQi")]))
|
||||
(define_insn "*<code><mode>3_clobber_flags"
|
||||
[(set (match_operand:QHSI 0 "h8300_dst_operand" "=rQ")
|
||||
(logicals:QHSI
|
||||
(match_operand:QHSI 1 "h8300_dst_operand" "%0")
|
||||
(match_operand:QHSI 2 "h8300_src_operand" "rQi")))
|
||||
(clobber (reg:CC CC_REG))]
|
||||
"h8300_operands_match_p (operands)"
|
||||
{ return output_logical_op (<MODE>mode, operands); }
|
||||
{ return output_logical_op (<MODE>mode, <CODE>, operands); }
|
||||
[(set (attr "length")
|
||||
(symbol_ref "compute_logical_op_length (<MODE>mode, operands)"))])
|
||||
(symbol_ref "compute_logical_op_length (<MODE>mode, <CODE>, operands)"))])
|
||||
|
||||
|
||||
;; ----------------------------------------------------------------------
|
||||
|
@ -260,11 +247,11 @@
|
|||
(not:QHSI (match_operand:QHSI 1 "h8300_dst_operand" "0")))]
|
||||
""
|
||||
"#"
|
||||
"reload_completed"
|
||||
"&& reload_completed"
|
||||
[(parallel [(set (match_dup 0) (not:QHSI (match_dup 1)))
|
||||
(clobber (reg:CC CC_REG))])])
|
||||
|
||||
(define_insn "one_cmpl<mode>2_clobber_flags"
|
||||
(define_insn "one_cmpl<mode>2_<cczn>"
|
||||
[(set (match_operand:QHSI 0 "h8300_dst_operand" "=rQ")
|
||||
(not:QHSI (match_operand:QHSI 1 "h8300_dst_operand" "0")))
|
||||
(clobber (reg:CC CC_REG))]
|
||||
|
|
|
@ -175,7 +175,7 @@
|
|||
return output_a_shift (operands);
|
||||
}
|
||||
[(set (attr "length")
|
||||
(symbol_ref "compute_a_shift_length (insn, operands)"))])
|
||||
(symbol_ref "compute_a_shift_length (operands)"))])
|
||||
|
||||
(define_insn_and_split "*shiftqi_noscratch"
|
||||
[(set (match_operand:QI 0 "register_operand" "=r,r")
|
||||
|
@ -203,7 +203,7 @@
|
|||
return output_a_shift (operands);
|
||||
}
|
||||
[(set (attr "length")
|
||||
(symbol_ref "compute_a_shift_length (insn, operands)"))])
|
||||
(symbol_ref "compute_a_shift_length (operands)"))])
|
||||
|
||||
(define_insn_and_split "*shifthi"
|
||||
[(set (match_operand:HI 0 "register_operand" "=r,r")
|
||||
|
@ -230,7 +230,7 @@
|
|||
return output_a_shift (operands);
|
||||
}
|
||||
[(set (attr "length")
|
||||
(symbol_ref "compute_a_shift_length (insn, operands)"))])
|
||||
(symbol_ref "compute_a_shift_length (operands)"))])
|
||||
|
||||
(define_insn_and_split "*shifthi_noscratch"
|
||||
[(set (match_operand:HI 0 "register_operand" "=r,r")
|
||||
|
@ -258,7 +258,7 @@
|
|||
return output_a_shift (operands);
|
||||
}
|
||||
[(set (attr "length")
|
||||
(symbol_ref "compute_a_shift_length (insn, operands)"))])
|
||||
(symbol_ref "compute_a_shift_length (operands)"))])
|
||||
|
||||
(define_insn_and_split "*shiftsi"
|
||||
[(set (match_operand:SI 0 "register_operand" "=r,r")
|
||||
|
@ -285,7 +285,7 @@
|
|||
return output_a_shift (operands);
|
||||
}
|
||||
[(set (attr "length")
|
||||
(symbol_ref "compute_a_shift_length (insn, operands)"))])
|
||||
(symbol_ref "compute_a_shift_length (operands)"))])
|
||||
|
||||
(define_insn_and_split "*shiftsi_noscratch"
|
||||
[(set (match_operand:SI 0 "register_operand" "=r,r")
|
||||
|
@ -313,7 +313,7 @@
|
|||
return output_a_shift (operands);
|
||||
}
|
||||
[(set (attr "length")
|
||||
(symbol_ref "compute_a_shift_length (insn, operands)"))])
|
||||
(symbol_ref "compute_a_shift_length (operands)"))])
|
||||
|
||||
;; Split a variable shift into a loop. If the register containing
|
||||
;; the shift count dies, then we just use that register.
|
||||
|
|
Loading…
Add table
Reference in a new issue