📄 sh.md
字号:
;; Multiplication instructions;; -------------------------------------------------------------------------(define_insn "umulhisi3_i" [(set (reg:SI MACL_REG) (mult:SI (zero_extend:SI (match_operand:HI 0 "arith_reg_operand" "r")) (zero_extend:SI (match_operand:HI 1 "arith_reg_operand" "r"))))] "TARGET_SH1" "mulu.w %1,%0" [(set_attr "type" "smpy")])(define_insn "mulhisi3_i" [(set (reg:SI MACL_REG) (mult:SI (sign_extend:SI (match_operand:HI 0 "arith_reg_operand" "r")) (sign_extend:SI (match_operand:HI 1 "arith_reg_operand" "r"))))] "TARGET_SH1" "muls.w %1,%0" [(set_attr "type" "smpy")])(define_expand "mulhisi3" [(set (reg:SI MACL_REG) (mult:SI (sign_extend:SI (match_operand:HI 1 "arith_reg_operand" "")) (sign_extend:SI (match_operand:HI 2 "arith_reg_operand" "")))) (set (match_operand:SI 0 "arith_reg_operand" "") (reg:SI MACL_REG))] "TARGET_SH1" "{ rtx first, last; first = emit_insn (gen_mulhisi3_i (operands[1], operands[2])); last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACL_REG)); /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop invariant code motion can move it. */ REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first)); REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last)); /* expand_binop can't find a suitable code in umul_widen_optab to make a REG_EQUAL note from, so make one here. See also smulsi3_highpart. ??? Alternatively, we could put this at the calling site of expand_binop, i.e. expand_expr. */ REG_NOTES (last) = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))), REG_NOTES (last)); DONE;}")(define_expand "umulhisi3" [(set (reg:SI MACL_REG) (mult:SI (zero_extend:SI (match_operand:HI 1 "arith_reg_operand" "")) (zero_extend:SI (match_operand:HI 2 "arith_reg_operand" "")))) (set (match_operand:SI 0 "arith_reg_operand" "") (reg:SI MACL_REG))] "TARGET_SH1" "{ rtx first, last; first = emit_insn (gen_umulhisi3_i (operands[1], operands[2])); last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACL_REG)); /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop invariant code motion can move it. */ REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first)); REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last)); /* expand_binop can't find a suitable code in umul_widen_optab to make a REG_EQUAL note from, so make one here. See also smulsi3_highpart. ??? Alternatively, we could put this at the calling site of expand_binop, i.e. expand_expr. */ REG_NOTES (last) = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))), REG_NOTES (last)); DONE;}");; mulsi3 on the SH2 can be done in one instruction, on the SH1 we generate;; a call to a routine which clobbers known registers.(define_insn "" [(set (match_operand:SI 1 "register_operand" "=z") (mult:SI (reg:SI R4_REG) (reg:SI R5_REG))) (clobber (reg:SI MACL_REG)) (clobber (reg:SI T_REG)) (clobber (reg:SI PR_REG)) (clobber (reg:SI R3_REG)) (clobber (reg:SI R2_REG)) (clobber (reg:SI R1_REG)) (use (match_operand:SI 0 "arith_reg_operand" "r"))] "TARGET_SH1" "jsr @%0%#" [(set_attr "type" "sfunc") (set_attr "needs_delay_slot" "yes")])(define_expand "mulsi3_call" [(set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" "")) (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" "")) (parallel[(set (match_operand:SI 0 "register_operand" "") (mult:SI (reg:SI R4_REG) (reg:SI R5_REG))) (clobber (reg:SI MACL_REG)) (clobber (reg:SI T_REG)) (clobber (reg:SI PR_REG)) (clobber (reg:SI R3_REG)) (clobber (reg:SI R2_REG)) (clobber (reg:SI R1_REG)) (use (match_operand:SI 3 "register_operand" ""))])] "TARGET_SH1" "")(define_insn "mul_l" [(set (reg:SI MACL_REG) (mult:SI (match_operand:SI 0 "arith_reg_operand" "r") (match_operand:SI 1 "arith_reg_operand" "r")))] "TARGET_SH2" "mul.l %1,%0" [(set_attr "type" "dmpy")])(define_expand "mulsi3" [(set (reg:SI MACL_REG) (mult:SI (match_operand:SI 1 "arith_reg_operand" "") (match_operand:SI 2 "arith_reg_operand" ""))) (set (match_operand:SI 0 "arith_reg_operand" "") (reg:SI MACL_REG))] "TARGET_SH1" "{ rtx first, last; if (!TARGET_SH2) { /* The address must be set outside the libcall, since it goes into a pseudo. */ rtx sym = gen_rtx_SYMBOL_REF (SImode, \"__mulsi3\"); rtx addr = force_reg (SImode, sym); rtx insns = gen_mulsi3_call (operands[0], operands[1], operands[2], addr); first = insns; last = emit_insn (insns); } else { rtx macl = gen_rtx_REG (SImode, MACL_REG); first = emit_insn (gen_mul_l (operands[1], operands[2])); /* consec_sets_giv can only recognize the first insn that sets a giv as the giv insn. So we must tag this also with a REG_EQUAL note. */ last = emit_insn (gen_movsi_i ((operands[0]), macl)); } /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop invariant code motion can move it. */ REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first)); REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last)); DONE;}")(define_insn "mulsidi3_i" [(set (reg:SI MACH_REG) (truncate:SI (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r")) (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))) (const_int 32)))) (set (reg:SI MACL_REG) (mult:SI (match_dup 0) (match_dup 1)))] "TARGET_SH2" "dmuls.l %1,%0" [(set_attr "type" "dmpy")])(define_expand "mulsidi3" [(set (match_operand:DI 0 "arith_reg_operand" "=r") (mult:DI (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")) (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))] "TARGET_SH2 || TARGET_SHMEDIA" "{ if (TARGET_SH2) { emit_insn (gen_mulsidi3_compact (operands[0], operands[1], operands[2])); DONE; }}")(define_insn "mulsidi3_media" [(set (match_operand:DI 0 "arith_reg_operand" "=r") (mult:DI (sign_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r")) (sign_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))] "TARGET_SHMEDIA" "muls.l %1, %2, %0" [(set_attr "type" "dmpy_media")])(define_insn "mulsidi3_compact" [(set (match_operand:DI 0 "arith_reg_operand" "=r") (mult:DI (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")) (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r")))) (clobber (reg:SI MACH_REG)) (clobber (reg:SI MACL_REG))] "TARGET_SH2" "#")(define_split [(set (match_operand:DI 0 "arith_reg_operand" "") (mult:DI (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "")) (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))) (clobber (reg:SI MACH_REG)) (clobber (reg:SI MACL_REG))] "TARGET_SH2" [(const_int 0)] "{ rtx low_dst = gen_lowpart (SImode, operands[0]); rtx high_dst = gen_highpart (SImode, operands[0]); emit_insn (gen_mulsidi3_i (operands[1], operands[2])); emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG)); emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG)); /* We need something to tag the possible REG_EQUAL notes on to. */ emit_move_insn (operands[0], operands[0]); DONE;}")(define_insn "umulsidi3_i" [(set (reg:SI MACH_REG) (truncate:SI (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r")) (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))) (const_int 32)))) (set (reg:SI MACL_REG) (mult:SI (match_dup 0) (match_dup 1)))] "TARGET_SH2" "dmulu.l %1,%0" [(set_attr "type" "dmpy")])(define_expand "umulsidi3" [(set (match_operand:DI 0 "arith_reg_operand" "=r") (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")) (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))] "TARGET_SH2 || TARGET_SHMEDIA" "{ if (TARGET_SH2) { emit_insn (gen_umulsidi3_compact (operands[0], operands[1], operands[2])); DONE; }}")(define_insn "umulsidi3_media" [(set (match_operand:DI 0 "arith_reg_operand" "=r") (mult:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r")) (zero_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))] "TARGET_SHMEDIA" "mulu.l %1, %2, %0" [(set_attr "type" "dmpy_media")])(define_insn "umulsidi3_compact" [(set (match_operand:DI 0 "arith_reg_operand" "=r") (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")) (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r")))) (clobber (reg:SI MACH_REG)) (clobber (reg:SI MACL_REG))] "TARGET_SH2" "#")(define_split [(set (match_operand:DI 0 "arith_reg_operand" "") (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "")) (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))) (clobber (reg:SI MACH_REG)) (clobber (reg:SI MACL_REG))] "TARGET_SH2" [(const_int 0)] "{ rtx low_dst = gen_lowpart (SImode, operands[0]); rtx high_dst = gen_highpart (SImode, operands[0]); emit_insn (gen_umulsidi3_i (operands[1], operands[2])); emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG)); emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG)); /* We need something to tag the possible REG_EQUAL notes on to. */ emit_move_insn (operands[0], operands[0]); DONE;}")(define_insn "smulsi3_highpart_i" [(set (reg:SI MACH_REG) (truncate:SI (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r")) (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))) (const_int 32)))) (clobber (reg:SI MACL_REG))] "TARGET_SH2" "dmuls.l %1,%0" [(set_attr "type" "dmpy")])(define_expand "smulsi3_highpart" [(parallel [(set (reg:SI MACH_REG) (truncate:SI (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "")) (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))) (const_int 32)))) (clobber (reg:SI MACL_REG))]) (set (match_operand:SI 0 "arith_reg_operand" "") (reg:SI MACH_REG))] "TARGET_SH2" "{ rtx first, last; first = emit_insn (gen_smulsi3_highpart_i (operands[1], operands[2])); last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACH_REG)); /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop invariant code motion can move it. */ REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first)); REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last)); /* expand_binop can't find a suitable code in mul_highpart_optab to make a REG_EQUAL note from, so make one here. See also {,u}mulhisi. ??? Alternatively, we could put this at the calling site of expand_binop, i.e. expand_mult_highpart. */ REG_NOTES (last) = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))), REG_NOTES (last)); DONE;}")(define_insn "umulsi3_highpart_i" [(set (reg:SI MACH_REG) (truncate:SI (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r")) (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))) (const_int 32)))) (clobber (reg:SI MACL_REG))] "TARGET_SH2" "dmulu.l %1,%0" [(set_attr "type" "dmpy")])(define_expand "umulsi3_highpart" [(parallel [(set (reg:SI MACH_REG) (truncate:SI (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "")) (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))) (const_int 32)))) (clobber (reg:SI MACL_REG))]) (set (match_operand:SI 0 "arith_reg_operand" "") (reg:SI MACH_REG))] "TARGET_SH2" "{ rtx first, last; first = emit_insn (gen_umulsi3_highpart_i (
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -