;; ---------------------------------------------------------------------- ;; ADD INSTRUCTIONS ;; ----------------------------------------------------------------------

(define_expand “add3” [(set (match_operand:QHSI 0 “register_operand” "") (plus:QHSI (match_operand:QHSI 1 “register_operand” "") (match_operand:QHSI 2 “h8300_src_operand” "")))] "" "")

(define_insn_and_split “*addqi3” [(set (match_operand:QI 0 “h8300_dst_operand” “=rQ”) (plus:QI (match_operand:QI 1 “h8300_dst_operand” “%0”) (match_operand:QI 2 “h8300_src_operand” “rQi”)))] “h8300_operands_match_p (operands)” “#” “&& reload_completed” [(parallel [(set (match_dup 0) (plus:QI (match_dup 1) (match_dup 2))) (clobber (reg:CC CC_REG))])])

(define_insn “*addqi3_flags” [(set (match_operand:QI 0 “h8300_dst_operand” “=rQ”) (plus:QI (match_operand:QI 1 “h8300_dst_operand” “%0”) (match_operand:QI 2 “h8300_src_operand” “rQi”))) (clobber (reg:CC CC_REG))] “reload_completed && h8300_operands_match_p (operands)” “add.b %X2,%X0” [(set_attr “length_table” “add”)])

(define_insn_and_split “*addhi” [(set (match_operand:HI 0 “register_operand” “=r,r,r,r,r”) (plus:HI (match_operand:HI 1 “register_operand” “%0,0,0,0,0”) (match_operand:HI 2 “h8300_src_operand” “L,N,J,n,r”)))] “!TARGET_H8300SX” “#” “&& reload_completed” [(parallel [(set (match_dup 0) (plus:HI (match_dup 1) (match_dup 2))) (clobber (reg:CC CC_REG))])])

(define_insn “*addhi3_flags” [(set (match_operand:HI 0 “register_operand” “=r,r,r,r,r”) (plus:HI (match_operand:HI 1 “register_operand” “%0,0,0,0,0”) (match_operand:HI 2 “h8300_src_operand” “M,O,J,n,r”))) (clobber (reg:CC CC_REG))] “reload_completed && !TARGET_H8300SX” “* { switch (which_alternative) { case 0: return "inc %T2,%T0"; case 1: return "dec %G2,%T0"; case 2: return "add.b %t2,%t0"; case 3: { /* If the constant is 4 or -4 and we do not need the flags, then we can use adds/subs which is two bytes shorter. */ rtx x = XVECEXP (PATTERN (insn), 0, 1); bool clobber = GET_CODE (x) == CLOBBER; if (clobber && INTVAL (operands[2]) == 4) return "adds %2,%S0"; if (clobber && INTVAL (operands[2]) == -4) return "subs %G2,%S0"; return "add.w %T2,%T0"; } case 4: return "add.w %T2,%T0"; default: gcc_unreachable (); } }” [(set_attr “length” “2,2,2,4,2”)])

(define_insn_and_split “*addhi3_h8sx” [(set (match_operand:HI 0 “h8300_dst_operand” “=rU,rU,r,rQ”) (plus:HI (match_operand:HI 1 “h8300_dst_operand” “%0,0,0,0”) (match_operand:HI 2 “h8300_src_operand” “P3>X,P3<X,J,rQi”)))] “TARGET_H8300SX && h8300_operands_match_p (operands)” “#” “&& reload_completed” [(parallel [(set (match_dup 0) (plus:HI (match_dup 1) (match_dup 2))) (clobber (reg:CC CC_REG))])])

(define_insn “*addhi3_h8sx_flags” [(set (match_operand:HI 0 “h8300_dst_operand” “=rU,rU,r,rQ”) (plus:HI (match_operand:HI 1 “h8300_dst_operand” “%0,0,0,0”) (match_operand:HI 2 “h8300_src_operand” “P3>X,P3<X,J,rQi”))) (clobber (reg:CC CC_REG))] “reload_completed && TARGET_H8300SX && h8300_operands_match_p (operands)” “@ add.w %T2:3,%T0 sub.w %G2:3,%T0 add.b %t2,%t0 add.w %T2,%T0” [(set_attr “length_table” “short_immediate,short_immediate,*,add”) (set_attr “length” “,,2,*”)])

(define_split [(set (match_operand:HSI 0 “register_operand” "") (plus:HSI (match_dup 0) (match_operand:HSI 1 “two_insn_adds_subs_operand” "")))] “!reload_completed” [(const_int 0)] { split_adds_subs (mode, operands); DONE; })

(define_insn_and_split “*addsi” [(set (match_operand:SI 0 “h8300_dst_operand” “=rQ,rQ”) (plus:SI (match_operand:SI 1 “h8300_dst_operand” “%0,0”) (match_operand:SI 2 “h8300_src_operand” “i,rQ”)))] “h8300_operands_match_p (operands)” “#” “&& reload_completed” [(parallel [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2))) (clobber (reg:CC CC_REG))])])

(define_insn “*addsi_flags” [(set (match_operand:SI 0 “h8300_dst_operand” “=rQ,rQ”) (plus:SI (match_operand:SI 1 “h8300_dst_operand” “%0,0”) (match_operand:SI 2 “h8300_src_operand” “i,rQ”))) (clobber (reg:CC CC_REG))] “reload_completed && h8300_operands_match_p (operands)” { rtx x = XVECEXP (PATTERN (insn), 0, 1); return output_plussi (operands, GET_CODE (x) != CLOBBER); } [(set (attr “length”) (symbol_ref “compute_plussi_length (operands, false)”))])

;; ---------------------------------------------------------------------- ;; SUBTRACT INSTRUCTIONS ;; ----------------------------------------------------------------------

(define_expand “sub3” [(set (match_operand:QHSI 0 “register_operand” "") (minus:QHSI (match_operand:QHSI 1 “register_operand” "") (match_operand:QHSI 2 “h8300_src_operand” "")))] "")

(define_insn_and_split “*subqi3” [(set (match_operand:QI 0 “h8300_dst_operand” “=rQ”) (minus:QI (match_operand:QI 1 “h8300_dst_operand” “0”) (match_operand:QI 2 “h8300_dst_operand” “rQ”)))] “h8300_operands_match_p (operands)” “#” “&& reload_completed” [(parallel [(set (match_dup 0) (minus:QI (match_dup 1) (match_dup 2))) (clobber (reg:CC CC_REG))])])

(define_insn “*subqi3_flags” [(set (match_operand:QI 0 “h8300_dst_operand” “=rQ”) (minus:QI (match_operand:QI 1 “h8300_dst_operand” “0”) (match_operand:QI 2 “h8300_dst_operand” “rQ”))) (clobber (reg:CC CC_REG))] “reload_completed && h8300_operands_match_p (operands)” “sub.b %X2,%X0” [(set_attr “length_table” “add”)])

(define_insn_and_split “*sub3” [(set (match_operand:HSI 0 “h8300_dst_operand” “=rQ,rQ”) (minus:HSI (match_operand:HSI 1 “h8300_dst_operand” “0,0”) (match_operand:HSI 2 “h8300_src_operand” “rQ,i”)))] “h8300_operands_match_p (operands)” “#” “&& reload_completed” [(parallel [(set (match_dup 0) (minus:HSI (match_dup 1) (match_dup 2))) (clobber (reg:CC CC_REG))])])

(define_insn “*sub3_flags” [(set (match_operand:HSI 0 “h8300_dst_operand” “=rQ,rQ”) (minus:HSI (match_operand:HSI 1 “h8300_dst_operand” “0,0”) (match_operand:HSI 2 “h8300_src_operand” “rQ,i”))) (clobber (reg:CC CC_REG))] “reload_completed && h8300_operands_match_p (operands)” { if (mode == HImode) return “sub.w %T2,%T0”; else if (mode == SImode) return “sub.l %S2,%S0”; gcc_unreachable (); } [(set_attr “length_table” “add”)])

;; ---------------------------------------------------------------------- ;; NEGATION INSTRUCTIONS ;; ----------------------------------------------------------------------

(define_expand “neg2” [(set (match_operand:QHSIF 0 “register_operand” "") (neg:QHSIF (match_operand:QHSIF 1 “register_operand” "")))] "" "")

(define_insn_and_split “*neg2” [(set (match_operand:QHSI 0 “h8300_dst_operand” “=rQ”) (neg:QHSI (match_operand:QHSI 1 “h8300_dst_operand” “0”)))] "" “#” “&& reload_completed” [(parallel [(set (match_dup 0) (neg:QHSI (match_dup 1))) (clobber (reg:CC CC_REG))])])

(define_insn “*neg2_flags” [(set (match_operand:QHSI 0 “h8300_dst_operand” “=rQ”) (neg:QHSI (match_operand:QHSI 1 “h8300_dst_operand” “0”))) (clobber (reg:CC CC_REG))] “reload_completed” { if (mode == E_QImode) return “neg %X0”; if (mode == E_HImode) return “neg.w %T0”; if (mode == E_SImode) return “neg.l %S0”; gcc_unreachable (); } [(set_attr “length_table” “unary”)])

(define_insn_and_split “*negsf2” [(set (match_operand:SF 0 “register_operand” “=r”) (neg:SF (match_operand:SF 1 “register_operand” “0”)))] "" “#” “&& reload_completed” [(parallel [(set (match_dup 0) (neg:SF (match_dup 1))) (clobber (reg:CC CC_REG))])])

(define_insn “*negsf2_clobber_flags” [(set (match_operand:SF 0 “register_operand” “=r”) (neg:SF (match_operand:SF 1 “register_operand” “0”))) (clobber (reg:CC CC_REG))] “reload_completed” “xor.w\t#32768,%e0” [(set_attr “length” “4”)])