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 *);
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. */
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. */
/* 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)
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)
/* 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)
switch (mode)
{
+ case E_QImode:
+ return 2;
+
case E_HImode:
/* First, see if we can finish with one insn. */
if (b0 != 0 && b1 != 0)
/* 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);
+;; 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")])
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))])])
"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))])])
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")
|| (<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)))
(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))
"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))])])
[(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)"))])
\f
;; ----------------------------------------------------------------------
(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))]
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")
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")
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")
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")
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")
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.