;; dead 1 eq/ne dec.l
;; dead 2 eq/ne dec.l
;;
+;; dead 1 ge/lt shar.l
+;; dead 3 (H8S) ge/lt shar.l
+;;
;; dead 1 geu/ltu shar.l
;; dead 3 (H8S) geu/ltu shar.l
;;
+;; ---- 255 ge/lt mov.b
+;;
;; ---- 255 geu/ltu mov.b
;; Transform
(set (cc0)
(match_dup 0))
(set (pc)
- (if_then_else (match_dup 5)
+ (if_then_else (match_dup 2)
(label_ref (match_dup 3))
(pc)))]
- "switch (GET_CODE (operands[2]))
- {
- case GTU:
- operands[5] = gen_rtx_NE (VOIDmode, cc0_rtx, const0_rtx);
- break;
- case LEU:
- operands[5] = gen_rtx_EQ (VOIDmode, cc0_rtx, const0_rtx);
- break;
- default:
- operands[5] = operands[2];
- break;
- }
- operands[4] = GEN_INT (exact_log2 (INTVAL (operands[1]) + 1));")
+ "operands[4] = GEN_INT (exact_log2 (INTVAL (operands[1]) + 1));")
;; Transform
;;
;; shar.w r0
;; bne .L1
-;; TODO: Split the above peephole2.
+(define_peephole2
+ [(set (cc0)
+ (compare (match_operand:HI 0 "register_operand" "")
+ (match_operand:HI 1 "const_int_operand" "")))
+ (set (pc)
+ (if_then_else (match_operator 2 "gtuleu_operator"
+ [(cc0) (const_int 0)])
+ (label_ref (match_operand 3 "" ""))
+ (pc)))]
+ "(TARGET_H8300H || TARGET_H8300S)
+ && peep2_reg_dead_p (1, operands[0])
+ && (INTVAL (operands[1]) == 1
+ || (TARGET_H8300S && INTVAL (operands[1]) == 3))"
+ [(parallel [(set (match_dup 0)
+ (ashiftrt:HI (match_dup 0)
+ (match_dup 4)))
+ (clobber (scratch:QI))])
+ (set (cc0)
+ (match_dup 0))
+ (set (pc)
+ (if_then_else (match_dup 5)
+ (label_ref (match_dup 3))
+ (pc)))]
+{
+ operands[4] = GEN_INT (exact_log2 (INTVAL (operands[1]) + 1));
+ operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[2]) == GTU ? NE : EQ,
+ VOIDmode,
+ cc0_rtx,
+ const0_rtx);
+})
;; Transform
;;
(and:HI (match_dup 0)
(const_int -256)))
(set (pc)
- (if_then_else (match_dup 3)
+ (if_then_else (match_dup 1)
(label_ref (match_dup 2))
(pc)))]
- "switch (GET_CODE (operands[1]))
- {
- case GTU:
- operands[3] = gen_rtx_NE (VOIDmode, cc0_rtx, const0_rtx);
- break;
- case LEU:
- operands[3] = gen_rtx_EQ (VOIDmode, cc0_rtx, const0_rtx);
- break;
- default:
- operands[3] = operands[1];
- break;
- }")
+ "")
;; Transform
;;
;; mov.b r0h,r0h
;; bne .L1
-;; TODO: Split the above peephole2.
+(define_peephole2
+ [(set (cc0)
+ (compare (match_operand:HI 0 "register_operand" "")
+ (const_int 255)))
+ (set (pc)
+ (if_then_else (match_operator 1 "gtuleu_operator"
+ [(cc0) (const_int 0)])
+ (label_ref (match_operand 2 "" ""))
+ (pc)))]
+ "TARGET_H8300H || TARGET_H8300S"
+ [(set (cc0)
+ (and:HI (match_dup 0)
+ (const_int -256)))
+ (set (pc)
+ (if_then_else (match_dup 3)
+ (label_ref (match_dup 2))
+ (pc)))]
+{
+ operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[1]) == GTU ? NE : EQ,
+ VOIDmode,
+ cc0_rtx,
+ const0_rtx);
+})
;; (compare (reg:SI) (const_int)) takes 6 bytes, so we try to achieve
;; the equivalent with shorter sequences. Here is the summary. Cases
;; dead 0x40000000 (H8S) eq/ne rotl.l and dec.l
;; dead 0x80000000 eq/ne rotl.l and dec.l
;;
+;; live 1 ge/lt copy and shar.l
+;; live 3 (H8S) ge/lt copy and shar.l
+;;
;; live 1 geu/ltu copy and shar.l
;; live 3 (H8S) geu/ltu copy and shar.l
;;
+;; dead 1 ge/lt shar.l
+;; dead 3 (H8S) ge/lt shar.l
+;;
;; dead 1 geu/ltu shar.l
;; dead 3 (H8S) geu/ltu shar.l
;;
+;; dead 3 (H8/300H) ge/lt and.b and test
+;; dead 7 ge/lt and.b and test
+;; dead 15 ge/lt and.b and test
+;; dead 31 ge/lt and.b and test
+;; dead 63 ge/lt and.b and test
+;; dead 127 ge/lt and.b and test
+;; dead 255 ge/lt and.b and test
+;;
;; dead 3 (H8/300H) geu/ltu and.b and test
;; dead 7 geu/ltu and.b and test
;; dead 15 geu/ltu and.b and test
;; dead 127 geu/ltu and.b and test
;; dead 255 geu/ltu and.b and test
;;
+;; ---- 65535 ge/lt mov.w
+;;
;; ---- 65535 geu/ltu mov.w
;; For a small constant, it is cheaper to actually do the subtraction
(set (cc0)
(match_dup 4))
(set (pc)
- (if_then_else (match_dup 6)
+ (if_then_else (match_dup 2)
(label_ref (match_dup 3))
(pc)))]
- "switch (GET_CODE (operands[2]))
- {
- case GTU:
- operands[6] = gen_rtx_NE (VOIDmode, cc0_rtx, const0_rtx);
- break;
- case LEU:
- operands[6] = gen_rtx_EQ (VOIDmode, cc0_rtx, const0_rtx);
- break;
- default:
- operands[6] = operands[2];
- break;
- }
- operands[5] = GEN_INT (exact_log2 (INTVAL (operands[1]) + 1));")
+ "operands[5] = GEN_INT (exact_log2 (INTVAL (operands[1]) + 1));")
;; Transform
;;
;; shar.l er1
;; bne .L1
-;; TODO: Split the above peephole2.
+;; We avoid this transformation if we see more than one copy of the
+;; same compare insn immediately before this one.
+
+(define_peephole2
+ [(match_scratch:SI 4 "r")
+ (set (cc0)
+ (compare (match_operand:SI 0 "register_operand" "")
+ (match_operand:SI 1 "const_int_operand" "")))
+ (set (pc)
+ (if_then_else (match_operator 2 "gtuleu_operator"
+ [(cc0) (const_int 0)])
+ (label_ref (match_operand 3 "" ""))
+ (pc)))]
+ "(TARGET_H8300H || TARGET_H8300S)
+ && !peep2_reg_dead_p (1, operands[0])
+ && (INTVAL (operands[1]) == 1
+ || (TARGET_H8300S && INTVAL (operands[1]) == 3))
+ && !same_cmp_preceding_p (insn)"
+ [(set (match_dup 4)
+ (match_dup 0))
+ (parallel [(set (match_dup 4)
+ (ashiftrt:SI (match_dup 4)
+ (match_dup 5)))
+ (clobber (scratch:QI))])
+ (set (cc0)
+ (match_dup 4))
+ (set (pc)
+ (if_then_else (match_dup 6)
+ (label_ref (match_dup 3))
+ (pc)))]
+{
+ operands[5] = GEN_INT (exact_log2 (INTVAL (operands[1]) + 1));
+ operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[2]) == GTU ? NE : EQ,
+ VOIDmode,
+ cc0_rtx,
+ const0_rtx);
+})
;; Transform
;;
(set (cc0)
(match_dup 0))
(set (pc)
- (if_then_else (match_dup 5)
+ (if_then_else (match_dup 2)
(label_ref (match_dup 3))
(pc)))]
- "switch (GET_CODE (operands[2]))
- {
- case GTU:
- operands[5] = gen_rtx_NE (VOIDmode, cc0_rtx, const0_rtx);
- break;
- case LEU:
- operands[5] = gen_rtx_EQ (VOIDmode, cc0_rtx, const0_rtx);
- break;
- default:
- operands[5] = operands[2];
- break;
- }
- operands[4] = GEN_INT (exact_log2 (INTVAL (operands[1]) + 1));")
+ "operands[4] = GEN_INT (exact_log2 (INTVAL (operands[1]) + 1));")
;; Transform
;;
;; shar.l er0
;; bne .L1
-;; TODO: Split the above peephole2.
+(define_peephole2
+ [(set (cc0)
+ (compare (match_operand:SI 0 "register_operand" "")
+ (match_operand:SI 1 "const_int_operand" "")))
+ (set (pc)
+ (if_then_else (match_operator 2 "gtuleu_operator"
+ [(cc0) (const_int 0)])
+ (label_ref (match_operand 3 "" ""))
+ (pc)))]
+ "(TARGET_H8300H || TARGET_H8300S)
+ && peep2_reg_dead_p (1, operands[0])
+ && (INTVAL (operands[1]) == 1
+ || (TARGET_H8300S && INTVAL (operands[1]) == 3))"
+ [(parallel [(set (match_dup 0)
+ (ashiftrt:SI (match_dup 0)
+ (match_dup 4)))
+ (clobber (scratch:QI))])
+ (set (cc0)
+ (match_dup 0))
+ (set (pc)
+ (if_then_else (match_dup 5)
+ (label_ref (match_dup 3))
+ (pc)))]
+{
+ operands[4] = GEN_INT (exact_log2 (INTVAL (operands[1]) + 1));
+ operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[2]) == GTU ? NE : EQ,
+ VOIDmode,
+ cc0_rtx,
+ const0_rtx);
+})
;; Transform
;;
(set (cc0)
(match_dup 0))
(set (pc)
- (if_then_else (match_dup 5)
+ (if_then_else (match_dup 2)
(label_ref (match_dup 3))
(pc)))]
- "switch (GET_CODE (operands[2]))
- {
- case GTU:
- operands[5] = gen_rtx_NE (VOIDmode, cc0_rtx, const0_rtx);
- break;
- case LEU:
- operands[5] = gen_rtx_EQ (VOIDmode, cc0_rtx, const0_rtx);
- break;
- default:
- operands[5] = operands[2];
- break;
- }
- operands[4] = GEN_INT (~INTVAL (operands[1]));")
+ "operands[4] = GEN_INT (~INTVAL (operands[1]));")
;; Transform
;;
;; mov.l er0,er0
;; bne .L1
-;; TODO: Split the above peephole2.
+(define_peephole2
+ [(set (cc0)
+ (compare (match_operand:SI 0 "register_operand" "")
+ (match_operand:SI 1 "const_int_operand" "")))
+ (set (pc)
+ (if_then_else (match_operator 2 "gtuleu_operator"
+ [(cc0) (const_int 0)])
+ (label_ref (match_operand 3 "" ""))
+ (pc)))]
+ "(TARGET_H8300H || TARGET_H8300S)
+ && peep2_reg_dead_p (1, operands[0])
+ && ((TARGET_H8300H && INTVAL (operands[1]) == 3)
+ || INTVAL (operands[1]) == 7
+ || INTVAL (operands[1]) == 15
+ || INTVAL (operands[1]) == 31
+ || INTVAL (operands[1]) == 63
+ || INTVAL (operands[1]) == 127
+ || INTVAL (operands[1]) == 255)"
+ [(set (match_dup 0)
+ (and:SI (match_dup 0)
+ (match_dup 4)))
+ (set (cc0)
+ (match_dup 0))
+ (set (pc)
+ (if_then_else (match_dup 5)
+ (label_ref (match_dup 3))
+ (pc)))]
+{
+ operands[4] = GEN_INT (~INTVAL (operands[1]));
+ operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[2]) == GTU ? NE : EQ,
+ VOIDmode,
+ cc0_rtx,
+ const0_rtx);
+})
;; Transform
;;
(and:SI (match_dup 0)
(const_int -65536)))
(set (pc)
- (if_then_else (match_dup 3)
+ (if_then_else (match_dup 1)
(label_ref (match_dup 2))
(pc)))]
- "switch (GET_CODE (operands[1]))
- {
- case GTU:
- operands[3] = gen_rtx_NE (VOIDmode, cc0_rtx, const0_rtx);
- break;
- case LEU:
- operands[3] = gen_rtx_EQ (VOIDmode, cc0_rtx, const0_rtx);
- break;
- default:
- operands[3] = operands[1];
- break;
- }")
+ "")
;; Transform
;;
;; mov.l e0,e0
;; bne .L1
-;; TODO: Split the above peephole2.
+(define_peephole2
+ [(set (cc0)
+ (compare (match_operand:SI 0 "register_operand" "")
+ (const_int 65535)))
+ (set (pc)
+ (if_then_else (match_operator 1 "gtuleu_operator"
+ [(cc0) (const_int 0)])
+ (label_ref (match_operand 2 "" ""))
+ (pc)))]
+ "TARGET_H8300H || TARGET_H8300S"
+ [(set (cc0)
+ (and:SI (match_dup 0)
+ (const_int -65536)))
+ (set (pc)
+ (if_then_else (match_dup 3)
+ (label_ref (match_dup 2))
+ (pc)))]
+{
+ operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[1]) == GTU ? NE : EQ,
+ VOIDmode,
+ cc0_rtx,
+ const0_rtx);
+})
;; For constants like -1, -2, 1, 2, it is still cheaper to make a copy
;; of the register being tested, do the subtraction on the copy, and