gcc/ * config/h8300/addsub.md: Turn existing patterns into define_insn_and_split style patterns where the splitter adds a clobber of the condition code register. Drop "cc" attribute. Add _clobber_flags patterns to match output of the splitters. (add<mod>3_incdec): Remove pattern (adds/subs splitter): Only run before reload. * config/h8300/bitfield.md: Turn existing patterns into define_insn_and_split style patterns where the splitter adds a clobber of the condition code register. Drop "cc" attribute. Add _clobber_flags patterns to match output of the splitters. (cstoreqi4, cstorehi4, cstoresi4): Comment out (*bstzhireg, *cmpstz, *bstz, *bistz, *cmpcondset): Likewise (*condbset, *cmpcondbclr, *condbclr): Likewise. (*cmpcondbsetreg, *condbsetreg, *cmpcondbclrreg): Likewise. (*condbclrreg): Likewise. * config/h8300/combiner.md: Turn existing patterns into define_insn_and_split style patterns where the splitter adds a clobber of the condition code register. Drop "cc" attribute. Add _clobber_flags patterns to match output of the splitters. Add appropriate CC register clobbers to existing splitters. (*addsi3_and_r_1): Disable for now. (*addsi3_and_not_r_1, bit-test branches): Likewise. * config/h8300/divmod.md: Turn existing patterns into define_insn_and_split style patterns where the splitter adds a clobber of the condition code register. Drop "cc" attribute. Add _clobber_flags patterns to match output of the splitters. * config/h8300/extensions.md: Turn existing patterns into define_insn_and_split style patterns where the splitter adds a clobber of the condition code register. Drop "cc" attribute. Add _clobber_flags patterns to match output of the splitters. * config/h8300/genmova.sh: Drop "cc" attribute from patterns. * config/h8300/mova.md: Drop "cc" attribute from patterns. * config/h8300/h8300-modes.def: Add CCZN and CCZNV modes. * config/h8300/h8300-protos.h (output_plussi): Update prototype. (compute_plussi_length): Likewise. (h8300_select_cc_mode): Add prototype. (compute_a_shift_cc): Remove prototype (cmpute_logical_op_cc): Likewise. * config/h8300/h8300.c (names_big): Add "cc" register. (names_extended, names_upper_extended): Likewise. (h8300_emit_stack_adjustment): Be more selective about setting RTX_FRAME_RELATED_P. (h8300_print_operand): Handle CCZN mode (h8300_select_cc_mode): New function. (notice_update_cc): if-0 out. Only kept for reference purposes. (h8300_expand_store): Likewise. (h8300_binary_length): Handle new insn forms. (output_plussi): Add argument for NEED_FLAGS and handle that case. (compute_plussi_length): Likewise. (compute_logical_op_cc): Return integer. (TARGET_FLAGS_REGNUM): Define. * config/h8300/h8300.h (FIRST_PSEUDO_REGISTER): Bump for cc register. (FIXED_REGISTERS, CALL_USED_REGISTERS): Handle cc register. (REG_ALLOC_ORDER, REGISTER_NAMES): Likewise. (SELECT_CC_MODE): Define. * config/h8300/h8300.md: Add CC_REG. Do not include peepholes.md for now. * config/h8300/jumpcall.md (cbranchqi4): Consolidate into cbranch<mode>4. (cbranchhi4, cbranchsi4): Likewise. (cbranch<mode>4): New expander. (branch): New define_insn_and_split for use before reload. (branch_1, branch_1_false): New patterns to match splitter output. Remove code to manage cc_status.flags. * config/h8300/logical.md: Turn existing patterns into define_insn_and_split style patterns where the splitter adds a clobber of the condition code register. Drop "cc" attribute. Add _clobber_flags patterns to match output of the splitters. Move various peepholes into this file. * config/h8300/movepush.md: Turn existing patterns into define_insn_and_split style patterns where the splitter adds a clobber of the condition code register. Drop "cc" attribute. Add _clobber_flags patterns to match output of the splitters. * config/h8300/multiply.md: Turn existing patterns into define_insn_and_split style patterns where the splitter adds a clobber of the condition code register. Drop "cc" attribute. Add _clobber_flags patterns to match output of the splitters. * config/h8300/other.md: Turn existing patterns into define_insn_and_split style patterns where the splitter adds a clobber of the condition code register. Drop "cc" attribute. Add _clobber_flags patterns to match output of the splitters. * config/h8300/peepholes.md: Remove peepholes that were moved elsewhere. * config/h8300/predicates.md (simple_memory_operand): New. * config/h8300/proepi.md: Drop "cc" attribute setting. * config/h8300/shiftrotate.md: Turn existing patterns into define_insn_and_split style patterns where the splitter adds a clobber of the condition code register. Drop "cc" attribute. Add _clobber_flags patterns to match output of the splitters. * config/h8300/testcompare.md: Turn existing patterns into define_insn_and_split style patterns where the splitter adds a clobber of the condition code register. Drop "cc" attribute. Add _clobber_flags patterns to match output of the splitters. Disable various patterns for now. Move some peepholes that were previously in peepholes.md here.
8.8 KiB
;; ---------------------------------------------------------------------- ;; MULTIPLY INSTRUCTIONS ;; ----------------------------------------------------------------------
;; Note that the H8/300 can only handle umulqihi3.
(define_expand "mulqihi3" [(set (match_operand:HI 0 "register_operand" "") (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "")) ;; intentionally-mismatched modes (match_operand:QI 2 "reg_or_nibble_operand" "")))] "" { if (GET_MODE (operands[2]) != VOIDmode) operands[2] = gen_rtx_SIGN_EXTEND (HImode, operands[2]); })
(define_insn_and_split "*mulqihi3_const" [(set (match_operand:HI 0 "register_operand" "=r") (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "%0")) (match_operand:QI 2 "nibble_operand" "IP4>X")))] "TARGET_H8300SX" "#" "reload_completed" [(parallel [(set (match_dup 0) (mult:HI (sign_extend:HI (match_dup 1)) (match_dup 2))) (clobber (reg:CC CC_REG))])])
(define_insn "*mulqihi3_const_clobber_flags" [(set (match_operand:HI 0 "register_operand" "=r") (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "%0")) (match_operand:QI 2 "nibble_operand" "IP4>X"))) (clobber (reg:CC CC_REG))] "TARGET_H8300SX" "mulxs.b %X2,%T0" [(set_attr "length" "4")])
(define_insn_and_split "*mulqihi3" [(set (match_operand:HI 0 "register_operand" "=r") (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "%0")) (sign_extend:HI (match_operand:QI 2 "register_operand" "r"))))] "" "#" "reload_completed" [(parallel [(set (match_dup 0) (mult:HI (sign_extend:HI (match_dup 1)) (sign_extend:HI (match_dup 2)))) (clobber (reg:CC CC_REG))])])
(define_insn "*mulqihi3_clobber_flags" [(set (match_operand:HI 0 "register_operand" "=r") (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "%0")) (sign_extend:HI (match_operand:QI 2 "register_operand" "r")))) (clobber (reg:CC CC_REG))] "" "mulxs.b %X2,%T0" [(set_attr "length" "4")])
(define_expand "mulhisi3" [(set (match_operand:SI 0 "register_operand" "") (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" "")) ;; intentionally-mismatched modes (match_operand:HI 2 "reg_or_nibble_operand" "")))] "" { if (GET_MODE (operands[2]) != VOIDmode) operands[2] = gen_rtx_SIGN_EXTEND (SImode, operands[2]); })
(define_insn_and_split "*mulhisi3_const" [(set (match_operand:SI 0 "register_operand" "=r") (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" "%0")) (match_operand:SI 2 "nibble_operand" "IP4>X")))] "TARGET_H8300SX" "#" "reload_completed" [(parallel [(set (match_dup 0) (mult:SI (sign_extend:SI (match_dup 1)) (match_dup 2))) (clobber (reg:CC CC_REG))])])
(define_insn "*mulhisi3_const_clobber_flags" [(set (match_operand:SI 0 "register_operand" "=r") (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" "%0")) (match_operand:SI 2 "nibble_operand" "IP4>X"))) (clobber (reg:CC CC_REG))] "TARGET_H8300SX" "mulxs.w %T2,%S0" [(set_attr "length" "4")])
(define_insn_and_split "*mulhisi3" [(set (match_operand:SI 0 "register_operand" "=r") (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" "%0")) (sign_extend:SI (match_operand:HI 2 "register_operand" "r"))))] "" "#" "reload_completed" [(parallel [(set (match_dup 0) (mult:SI (sign_extend:SI (match_dup 1)) (sign_extend:SI (match_dup 2)))) (clobber (reg:CC CC_REG))])])
(define_insn "*mulhisi3_clobber_flags" [(set (match_operand:SI 0 "register_operand" "=r") (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" "%0")) (sign_extend:SI (match_operand:HI 2 "register_operand" "r")))) (clobber (reg:CC CC_REG))] "" "mulxs.w %T2,%S0" [(set_attr "length" "4")])
(define_expand "umulqihi3" [(set (match_operand:HI 0 "register_operand" "") (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "")) ;; intentionally-mismatched modes (match_operand:QI 2 "reg_or_nibble_operand" "")))] "" { if (GET_MODE (operands[2]) != VOIDmode) operands[2] = gen_rtx_ZERO_EXTEND (HImode, operands[2]); })
(define_insn "*umulqihi3_const" [(set (match_operand:HI 0 "register_operand" "=r") (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "%0")) (match_operand:QI 2 "nibble_operand" "IP4>X")))] "TARGET_H8300SX" "mulxu.b %X2,%T0" [(set_attr "length" "4")])
(define_insn "*umulqihi3" [(set (match_operand:HI 0 "register_operand" "=r") (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "%0")) (zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))] "" "mulxu.b %X2,%T0" [(set_attr "length" "2")])
(define_expand "umulhisi3" [(set (match_operand:SI 0 "register_operand" "") (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "")) ;; intentionally-mismatched modes (match_operand:HI 2 "reg_or_nibble_operand" "")))] "" { if (GET_MODE (operands[2]) != VOIDmode) operands[2] = gen_rtx_ZERO_EXTEND (SImode, operands[2]); })
(define_insn "*umulhisi3_const" [(set (match_operand:SI 0 "register_operand" "=r") (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "%0")) (match_operand:SI 2 "nibble_operand" "IP4>X")))] "TARGET_H8300SX" "mulxu.w %T2,%S0" [(set_attr "length" "4")])
(define_insn "*umulhisi3" [(set (match_operand:SI 0 "register_operand" "=r") (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "%0")) (zero_extend:SI (match_operand:HI 2 "register_operand" "r"))))] "" "mulxu.w %T2,%S0" [(set_attr "length" "2")])
;; We could have used mulu.[wl] here, but mulu.[lw] is only available ;; on a H8SX with a multiplier, whereas muls.w seems to be available ;; on all H8SX variants.
(define_insn_and_split "mul3" [(set (match_operand:HSI 0 "register_operand" "=r") (mult:HSI (match_operand:HSI 1 "register_operand" "%0") (match_operand:HSI 2 "reg_or_nibble_operand" "r IP4>X")))] "TARGET_H8300SX" "#" "reload_completed" [(parallel [(set (match_dup 0) (mult:HSI (match_dup 1) (match_dup 2))) (clobber (reg:CC CC_REG))])])
(define_insn "mul3_clobber_flags" [(set (match_operand:HSI 0 "register_operand" "=r") (mult:HSI (match_operand:HSI 1 "register_operand" "%0") (match_operand:HSI 2 "reg_or_nibble_operand" "r IP4>X"))) (clobber (reg:CC CC_REG))] "TARGET_H8300SX" { return mode == HImode ? "muls.w\t%T2,%T0" : "muls.l\t%S2,%S0"; } [(set_attr "length" "4")])
(define_insn_and_split "smulsi3_highpart" [(set (match_operand:SI 0 "register_operand" "=r") (truncate:SI (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "%0")) (sign_extend:DI (match_operand:SI 2 "reg_or_nibble_operand" "r IP4>X"))) (const_int 32))))] "TARGET_H8300SXMUL" "#" "reload_completed" [(parallel [(set (match_dup 0) (truncate:SI (lshiftrt:DI (mult:DI (sign_extend:DI (match_dup 1)) (sign_extend:DI (match_dup 2))) (const_int 32)))) (clobber (reg:CC CC_REG))])])
(define_insn "smulsi3_highpart_clobber_flags" [(set (match_operand:SI 0 "register_operand" "=r") (truncate:SI (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "%0")) (sign_extend:DI (match_operand:SI 2 "reg_or_nibble_operand" "r IP4>X"))) (const_int 32)))) (clobber (reg:CC CC_REG))] "TARGET_H8300SXMUL" "muls/u.l\t%S2,%S0" [(set_attr "length" "4")])
(define_insn "umulsi3_highpart" [(set (match_operand:SI 0 "register_operand" "=r") (truncate:SI (ashiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0")) (zero_extend:DI (match_operand:SI 2 "reg_or_nibble_operand" "r IP4>X"))) (const_int 32))))] "TARGET_H8300SX" "mulu/u.l\t%S2,%S0" [(set_attr "length" "4")])
;; This is a "bridge" instruction. Combine can't cram enough insns ;; together to crate a MAC instruction directly, but it can create ;; this instruction, which then allows combine to create the real ;; MAC insn. ;; ;; Unfortunately, if combine doesn't create a MAC instruction, this ;; insn must generate reasonably correct code. Egad.
(define_insn "" [(set (match_operand:SI 0 "register_operand" "=a") (mult:SI (sign_extend:SI (mem:HI (post_inc:SI (match_operand:SI 1 "register_operand" "r")))) (sign_extend:SI (mem:HI (post_inc:SI (match_operand:SI 2 "register_operand" "r"))))))] "TARGET_MAC" "clrmac;mac @%2+,@%1+" [(set_attr "length" "6")])
(define_insn "" [(set (match_operand:SI 0 "register_operand" "=a") (plus:SI (mult:SI (sign_extend:SI (mem:HI (post_inc:SI (match_operand:SI 1 "register_operand" "r")))) (sign_extend:SI (mem:HI (post_inc:SI (match_operand:SI 2 "register_operand" "r"))))) (match_operand:SI 3 "register_operand" "0")))] "TARGET_MAC" "mac @%2+,@%1+" [(set_attr "length" "4")])