;; ----------------------------------------------------------------- ;; PEEPHOLE PATTERNS ;; -----------------------------------------------------------------

;; Convert (A >> B) & C to (A & 255) >> B if C == 255 >> B.

(define_peephole2 [(parallel [(set (match_operand:HI 0 “register_operand” "") (lshiftrt:HI (match_dup 0) (match_operand:HI 1 “const_int_operand” ""))) (clobber (match_operand:HI 2 "" ""))]) (set (match_dup 0) (and:HI (match_dup 0) (match_operand:HI 3 “const_int_operand” "")))] “INTVAL (operands[3]) == (255 >> INTVAL (operands[1]))” [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255))) (parallel [(set (match_dup 0) (lshiftrt:HI (match_dup 0) (match_dup 1))) (clobber (match_dup 2))])] "")

;; Convert (A << B) & C to (A & 255) << B if C == 255 << B.

(define_peephole2 [(parallel [(set (match_operand:HI 0 “register_operand” "") (ashift:HI (match_dup 0) (match_operand:HI 1 “const_int_operand” ""))) (clobber (match_operand:HI 2 "" ""))]) (set (match_dup 0) (and:HI (match_dup 0) (match_operand:HI 3 “const_int_operand” "")))] “INTVAL (operands[3]) == (255 << INTVAL (operands[1]))” [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255))) (parallel [(set (match_dup 0) (ashift:HI (match_dup 0) (match_dup 1))) (clobber (match_dup 2))])] "")

;; Convert (A >> B) & C to (A & 255) >> B if C == 255 >> B.

(define_peephole2 [(parallel [(set (match_operand:SI 0 “register_operand” "") (lshiftrt:SI (match_dup 0) (match_operand:SI 1 “const_int_operand” ""))) (clobber (match_operand:SI 2 "" ""))]) (set (match_dup 0) (and:SI (match_dup 0) (match_operand:SI 3 “const_int_operand” "")))] “INTVAL (operands[3]) == (255 >> INTVAL (operands[1]))” [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255))) (parallel [(set (match_dup 0) (lshiftrt:SI (match_dup 0) (match_dup 1))) (clobber (match_dup 2))])] "")

;; Convert (A << B) & C to (A & 255) << B if C == 255 << B.

(define_peephole2 [(parallel [(set (match_operand:SI 0 “register_operand” "") (ashift:SI (match_dup 0) (match_operand:SI 1 “const_int_operand” ""))) (clobber (match_operand:SI 2 "" ""))]) (set (match_dup 0) (and:SI (match_dup 0) (match_operand:SI 3 “const_int_operand” "")))] “INTVAL (operands[3]) == (255 << INTVAL (operands[1]))” [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255))) (parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 1))) (clobber (match_dup 2))])] "")

;; Convert (A >> B) & C to (A & 65535) >> B if C == 65535 >> B.

(define_peephole2 [(parallel [(set (match_operand:SI 0 “register_operand” "") (lshiftrt:SI (match_dup 0) (match_operand:SI 1 “const_int_operand” ""))) (clobber (match_operand:SI 2 "" ""))]) (set (match_dup 0) (and:SI (match_dup 0) (match_operand:SI 3 “const_int_operand” "")))] “INTVAL (operands[3]) == (65535 >> INTVAL (operands[1]))” [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535))) (parallel [(set (match_dup 0) (lshiftrt:SI (match_dup 0) (match_dup 1))) (clobber (match_dup 2))])] "")

;; Convert (A << B) & C to (A & 65535) << B if C == 65535 << B.

(define_peephole2 [(parallel [(set (match_operand:SI 0 “register_operand” "") (ashift:SI (match_dup 0) (match_operand:SI 1 “const_int_operand” ""))) (clobber (match_operand:SI 2 "" ""))]) (set (match_dup 0) (and:SI (match_dup 0) (match_operand:SI 3 “const_int_operand” "")))] “INTVAL (operands[3]) == (65535 << INTVAL (operands[1]))” [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535))) (parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 1))) (clobber (match_dup 2))])] "")

;; Cram four pushes into stm.l.

(define_peephole2 [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_operand:SI 0 “register_operand” "")) (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_operand:SI 1 “register_operand” "")) (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_operand:SI 2 “register_operand” "")) (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_operand:SI 3 “register_operand” ""))] “TARGET_H8300S && !TARGET_NORMAL_MODE && (REGNO_REG_CLASS (REGNO (operands[3])) == GENERAL_REGS && REGNO (operands[1]) == REGNO (operands[0]) + 1 && REGNO (operands[2]) == REGNO (operands[0]) + 2 && REGNO (operands[3]) == REGNO (operands[0]) + 3 && (TARGET_H8300SX || REGNO (operands[0]) == 0))” [(parallel [(set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -4))) (match_dup 0)) (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -8))) (match_dup 1)) (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -12))) (match_dup 2)) (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -16))) (match_dup 3)) (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -16)))])] "")

(define_peephole2 [(set (mem:SI (pre_dec:HI (reg:HI SP_REG))) (match_operand:SI 0 “register_operand” "")) (set (mem:SI (pre_dec:HI (reg:HI SP_REG))) (match_operand:SI 1 “register_operand” "")) (set (mem:SI (pre_dec:HI (reg:HI SP_REG))) (match_operand:SI 2 “register_operand” "")) (set (mem:SI (pre_dec:HI (reg:HI SP_REG))) (match_operand:SI 3 “register_operand” ""))] “TARGET_H8300S && TARGET_NORMAL_MODE && (REGNO_REG_CLASS (REGNO (operands[3])) == GENERAL_REGS && REGNO (operands[1]) == REGNO (operands[0]) + 1 && REGNO (operands[2]) == REGNO (operands[0]) + 2 && REGNO (operands[3]) == REGNO (operands[0]) + 3 && (TARGET_H8300SX || REGNO (operands[0]) == 0))” [(parallel [(set (mem:SI (plus:HI (reg:HI SP_REG) (const_int -4))) (match_dup 0)) (set (mem:SI (plus:HI (reg:HI SP_REG) (const_int -8))) (match_dup 1)) (set (mem:SI (plus:HI (reg:HI SP_REG) (const_int -12))) (match_dup 2)) (set (mem:SI (plus:HI (reg:HI SP_REG) (const_int -16))) (match_dup 3)) (set (reg:HI SP_REG) (plus:HI (reg:HI SP_REG) (const_int -16)))])] "")

;; Cram three pushes into stm.l.

(define_peephole2 [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_operand:SI 0 “register_operand” "")) (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_operand:SI 1 “register_operand” "")) (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_operand:SI 2 “register_operand” ""))] “TARGET_H8300S && !TARGET_NORMAL_MODE && (REGNO_REG_CLASS (REGNO (operands[2])) == GENERAL_REGS && REGNO (operands[1]) == REGNO (operands[0]) + 1 && REGNO (operands[2]) == REGNO (operands[0]) + 2 && (TARGET_H8300SX || (REGNO (operands[0]) & 3) == 0))” [(parallel [(set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -4))) (match_dup 0)) (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -8))) (match_dup 1)) (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -12))) (match_dup 2)) (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -12)))])] "")

(define_peephole2 [(set (mem:SI (pre_dec:HI (reg:HI SP_REG))) (match_operand:SI 0 “register_operand” "")) (set (mem:SI (pre_dec:HI (reg:HI SP_REG))) (match_operand:SI 1 “register_operand” "")) (set (mem:SI (pre_dec:HI (reg:HI SP_REG))) (match_operand:SI 2 “register_operand” ""))] “TARGET_H8300S && TARGET_NORMAL_MODE && (REGNO_REG_CLASS (REGNO (operands[2])) == GENERAL_REGS && REGNO (operands[1]) == REGNO (operands[0]) + 1 && REGNO (operands[2]) == REGNO (operands[0]) + 2 && (TARGET_H8300SX || (REGNO (operands[0]) & 3) == 0))” [(parallel [(set (mem:SI (plus:HI (reg:HI SP_REG) (const_int -4))) (match_dup 0)) (set (mem:SI (plus:HI (reg:HI SP_REG) (const_int -8))) (match_dup 1)) (set (mem:SI (plus:HI (reg:HI SP_REG) (const_int -12))) (match_dup 2)) (set (reg:HI SP_REG) (plus:HI (reg:HI SP_REG) (const_int -12)))])] "")

;; Cram two pushes into stm.l.

(define_peephole2 [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_operand:SI 0 “register_operand” "")) (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_operand:SI 1 “register_operand” ""))] “TARGET_H8300S && !TARGET_NORMAL_MODE && (REGNO_REG_CLASS (REGNO (operands[1])) == GENERAL_REGS && REGNO (operands[1]) == REGNO (operands[0]) + 1 && (TARGET_H8300SX || (REGNO (operands[0]) & 1) == 0))” [(parallel [(set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -4))) (match_dup 0)) (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -8))) (match_dup 1)) (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))])] "")

(define_peephole2 [(set (mem:SI (pre_dec:HI (reg:HI SP_REG))) (match_operand:SI 0 “register_operand” "")) (set (mem:SI (pre_dec:HI (reg:HI SP_REG))) (match_operand:SI 1 “register_operand” ""))] “TARGET_H8300S && TARGET_NORMAL_MODE && (REGNO_REG_CLASS (REGNO (operands[1])) == GENERAL_REGS && REGNO (operands[1]) == REGNO (operands[0]) + 1 && (TARGET_H8300SX || (REGNO (operands[0]) & 1) == 0))” [(parallel [(set (mem:SI (plus:HI (reg:HI SP_REG) (const_int -4))) (match_dup 0)) (set (mem:SI (plus:HI (reg:HI SP_REG) (const_int -8))) (match_dup 1)) (set (reg:HI SP_REG) (plus:HI (reg:HI SP_REG) (const_int -8)))])] "")

;; Turn ;; ;; mov.w #2,r0 ;; add.w r7,r0 (6 bytes) ;; ;; into ;; ;; mov.w r7,r0 ;; adds #2,r0 (4 bytes)

(define_peephole2 [(set (match_operand:HI 0 “register_operand” "") (match_operand:HI 1 “const_int_operand” "")) (set (match_dup 0) (plus:HI (match_dup 0) (match_operand:HI 2 “register_operand” "")))] “REG_P (operands[0]) && REG_P (operands[2]) && REGNO (operands[0]) != REGNO (operands[2]) && (satisfies_constraint_J (operands[1]) || satisfies_constraint_L (operands[1]) || satisfies_constraint_N (operands[1]))” [(set (match_dup 0) (match_dup 2)) (set (match_dup 0) (plus:HI (match_dup 0) (match_dup 1)))] "")

;; Turn ;; ;; sub.l er0,er0 ;; add.b #4,r0l ;; add.l er7,er0 (6 bytes) ;; ;; into ;; ;; mov.l er7,er0 ;; adds #4,er0 (4 bytes)

(define_peephole2 [(set (match_operand:SI 0 “register_operand” "") (match_operand:SI 1 “const_int_operand” "")) (set (match_dup 0) (plus:SI (match_dup 0) (match_operand:SI 2 “register_operand” "")))] “REG_P (operands[0]) && REG_P (operands[2]) && REGNO (operands[0]) != REGNO (operands[2]) && (satisfies_constraint_L (operands[1]) || satisfies_constraint_N (operands[1]))” [(set (match_dup 0) (match_dup 2)) (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))] "")

;; Turn ;; ;; mov.l er7,er0 ;; add.l #10,er0 (takes 8 bytes) ;; ;; into ;; ;; sub.l er0,er0 ;; add.b #10,r0l ;; add.l er7,er0 (takes 6 bytes)

(define_peephole2 [(set (match_operand:SI 0 “register_operand” "") (match_operand:SI 1 “register_operand” "")) (set (match_dup 0) (plus:SI (match_dup 0) (match_operand:SI 2 “const_int_operand” "")))] “operands[0] != stack_pointer_rtx && REG_P (operands[0]) && REG_P (operands[1]) && REGNO (operands[0]) != REGNO (operands[1]) && !satisfies_constraint_L (operands[2]) && !satisfies_constraint_N (operands[2]) && ((INTVAL (operands[2]) & 0xff) == INTVAL (operands[2]) || (INTVAL (operands[2]) & 0xff00) == INTVAL (operands[2]) || INTVAL (operands[2]) == 0xffff || INTVAL (operands[2]) == 0xfffe)” [(set (match_dup 0) (match_dup 2)) (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))] "")

;; If a load of mem:SI is followed by an AND that turns off the upper ;; half, then we can load mem:HI instead.

(define_peephole2 [(set (match_operand:SI 0 “register_operand” "") (match_operand:SI 1 “memory_operand” "")) (set (match_dup 0) (and:SI (match_dup 0) (match_operand:SI 2 “const_int_operand” "")))] “!MEM_VOLATILE_P (operands[1]) && offsettable_memref_p (operands[1]) && (INTVAL (operands[2]) & ~0xffff) == 0 && INTVAL (operands[2]) != 255” [(set (match_dup 3) (match_dup 4)) (set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))] { operands[3] = gen_lowpart (HImode, operands[0]); operands[4] = gen_lowpart (HImode, operands[1]); })

;; These triggers right at the end of allocation of locals in the ;; prologue (and possibly at other places).

;; stack adjustment of -4, generate one push ;; ;; before : 6 bytes ;; after : 4 bytes

(define_peephole2 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4))) (set (mem:SFI (reg:SI SP_REG)) (match_operand:SFI 0 “register_operand” ""))] “!TARGET_NORMAL_MODE && REGNO (operands[0]) != SP_REG” [(set (mem:SFI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])

;; stack adjustment of -8, generate one push ;; ;; before : 8 bytes ;; after : 6 bytes

(define_peephole2 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8))) (set (mem:SFI (reg:SI SP_REG)) (match_operand:SFI 0 “register_operand” ""))] “!TARGET_NORMAL_MODE && REGNO (operands[0]) != SP_REG” [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4))) (set (mem:SFI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])

;; stack adjustment of -12, generate one push ;; ;; before : 10 bytes ;; after : 8 bytes

(define_peephole2 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -12))) (set (mem:SFI (reg:SI SP_REG)) (match_operand:SFI 0 “register_operand” ""))] “!TARGET_NORMAL_MODE && REGNO (operands[0]) != SP_REG” [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4))) (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4))) (set (mem:SFI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])

;; Transform ;; ;; mov dst,reg ;; op reg ;; mov reg,dst ;; ;; into ;; ;; op dst ;; ;; if “reg” dies at the end of the sequence.

(define_peephole2 [(set (match_operand 0 “register_operand” "") (match_operand 1 “memory_operand” "")) (set (match_dup 0) (match_operator 2 “h8sx_unary_memory_operator” [(match_dup 0)])) (set (match_operand 3 “memory_operand” "") (match_dup 0))] “TARGET_H8300SX && peep2_reg_dead_p (3, operands[0]) && !reg_overlap_mentioned_p (operands[0], operands[3]) && h8sx_mergeable_memrefs_p (operands[3], operands[1])” [(set (match_dup 3) (match_dup 4))] { operands[4] = shallow_copy_rtx (operands[2]); XEXP (operands[4], 0) = operands[1]; })

;; Combine two moves.

(define_peephole2 [(set (match_operand 0 “register_operand” "") (match_operand 1 “h8300_src_operand” "")) (set (match_operand 2 “h8300_dst_operand” "") (match_dup 0))] “TARGET_H8300SX && peep2_reg_dead_p (2, operands[0]) && !reg_overlap_mentioned_p (operands[0], operands[2])” [(set (match_dup 2) (match_dup 1))])