📄 sh.md
字号:
;; there is nothing to prevent reload from using r0 to reload the address.;; This reload would clobber the value in r0 we are trying to store.;; If we let reload allocate r0, then this problem can never happen.(define_insn "udivsi3_i1" [(set (match_operand:SI 0 "register_operand" "=z") (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG))) (clobber (reg:SI T_REG)) (clobber (reg:SI PR_REG)) (clobber (reg:SI R4_REG)) (use (match_operand:SI 1 "arith_reg_operand" "r"))] "TARGET_SH1 && ! TARGET_SH4" "jsr @%1%#" [(set_attr "type" "sfunc") (set_attr "needs_delay_slot" "yes")]); Since shmedia-nofpu code could be linked against shcompact code, and; the udivsi3 libcall has the same name, we must consider all registers; clobbered that are in the union of the registers clobbered by the; shmedia and the shcompact implementation. Note, if the shcompact; implementation actually used shcompact code, we'd need to clobber; also r23 and fr23.(define_insn "udivsi3_i1_media" [(set (match_operand:SI 0 "register_operand" "=z") (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG))) (clobber (reg:SI T_MEDIA_REG)) (clobber (reg:SI PR_MEDIA_REG)) (clobber (reg:SI R20_REG)) (clobber (reg:SI R21_REG)) (clobber (reg:SI R22_REG)) (clobber (reg:DI TR0_REG)) (clobber (reg:DI TR1_REG)) (clobber (reg:DI TR2_REG)) (use (match_operand:DI 1 "target_operand" "b"))] "TARGET_SHMEDIA && ! TARGET_SHMEDIA_FPU" "blink %1, r18" [(set_attr "type" "sfunc") (set_attr "needs_delay_slot" "yes")])(define_expand "udivsi3_i4_media" [(set (match_dup 3) (zero_extend:DI (match_operand:SI 1 "register_operand" ""))) (set (match_dup 4) (zero_extend:DI (match_operand:SI 2 "register_operand" ""))) (set (match_dup 5) (float:DF (match_dup 3))) (set (match_dup 6) (float:DF (match_dup 4))) (set (match_dup 7) (div:DF (match_dup 5) (match_dup 6))) (set (match_dup 8) (fix:DI (match_dup 7))) (set (match_operand:SI 0 "register_operand" "") (truncate:SI (match_dup 8)))] "TARGET_SHMEDIA_FPU" "{ operands[3] = gen_reg_rtx (DImode); operands[4] = gen_reg_rtx (DImode); operands[5] = gen_reg_rtx (DFmode); operands[6] = gen_reg_rtx (DFmode); operands[7] = gen_reg_rtx (DFmode); operands[8] = gen_reg_rtx (DImode);}")(define_insn "udivsi3_i4" [(set (match_operand:SI 0 "register_operand" "=y") (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG))) (clobber (reg:SI T_REG)) (clobber (reg:SI PR_REG)) (clobber (reg:DF DR0_REG)) (clobber (reg:DF DR2_REG)) (clobber (reg:DF DR4_REG)) (clobber (reg:SI R0_REG)) (clobber (reg:SI R1_REG)) (clobber (reg:SI R4_REG)) (clobber (reg:SI R5_REG)) (use (reg:PSI FPSCR_REG)) (use (match_operand:SI 1 "arith_reg_operand" "r"))] "TARGET_SH4 && ! TARGET_FPU_SINGLE" "jsr @%1%#" [(set_attr "type" "sfunc") (set_attr "fp_mode" "double") (set_attr "needs_delay_slot" "yes")])(define_insn "udivsi3_i4_single" [(set (match_operand:SI 0 "register_operand" "=y") (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG))) (clobber (reg:SI T_REG)) (clobber (reg:SI PR_REG)) (clobber (reg:DF DR0_REG)) (clobber (reg:DF DR2_REG)) (clobber (reg:DF DR4_REG)) (clobber (reg:SI R0_REG)) (clobber (reg:SI R1_REG)) (clobber (reg:SI R4_REG)) (clobber (reg:SI R5_REG)) (use (match_operand:SI 1 "arith_reg_operand" "r"))] "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE" "jsr @%1%#" [(set_attr "type" "sfunc") (set_attr "needs_delay_slot" "yes")])(define_expand "udivsi3" [(set (match_dup 3) (symbol_ref:SI "__udivsi3")) (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" "") (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG))) (clobber (reg:SI T_REG)) (clobber (reg:SI PR_REG)) (clobber (reg:SI R4_REG)) (use (match_dup 3))])] "" "{ rtx first, last; operands[3] = gen_reg_rtx (Pmode); /* Emit the move of the address to a pseudo outside of the libcall. */ if (TARGET_HARD_SH4 && TARGET_SH2E) { emit_move_insn (operands[3], function_symbol (\"__udivsi3_i4\")); if (TARGET_FPU_SINGLE) last = gen_udivsi3_i4_single (operands[0], operands[3]); else last = gen_udivsi3_i4 (operands[0], operands[3]); } else if (TARGET_SHMEDIA_FPU) { operands[1] = force_reg (SImode, operands[1]); operands[2] = force_reg (SImode, operands[2]); emit_insn (gen_udivsi3_i4_media (operands[0], operands[1], operands[2])); DONE; } else if (TARGET_SH2A) { operands[1] = force_reg (SImode, operands[1]); operands[2] = force_reg (SImode, operands[2]); emit_insn (gen_udivsi3_sh2a (operands[0], operands[1], operands[2])); DONE; } else if (TARGET_SH5) { emit_move_insn (operands[3], function_symbol (TARGET_FPU_ANY ? \"__udivsi3_i4\" : \"__udivsi3\")); if (TARGET_SHMEDIA) last = gen_udivsi3_i1_media (operands[0], Pmode == DImode ? operands[3] : gen_rtx_SUBREG (DImode, operands[3], 0)); else if (TARGET_FPU_ANY) last = gen_udivsi3_i4_single (operands[0], operands[3]); else last = gen_udivsi3_i1 (operands[0], operands[3]); } else { emit_move_insn (operands[3], function_symbol (\"__udivsi3\")); last = gen_udivsi3_i1 (operands[0], operands[3]); } first = emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]); emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]); last = emit_insn (last); /* 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 "divsi3_sh2a" [(set (match_operand:SI 0 "arith_reg_operand" "=r") (div:SI (match_operand:SI 1 "arith_reg_operand" "0") (match_operand:SI 2 "arith_reg_operand" "z")))] "TARGET_SH2A" "divs %2,%1" [(set_attr "type" "arith") (set_attr "in_delay_slot" "no")])(define_insn "divsi3_i1" [(set (match_operand:SI 0 "register_operand" "=z") (div:SI (reg:SI R4_REG) (reg:SI R5_REG))) (clobber (reg:SI T_REG)) (clobber (reg:SI PR_REG)) (clobber (reg:SI R1_REG)) (clobber (reg:SI R2_REG)) (clobber (reg:SI R3_REG)) (use (match_operand:SI 1 "arith_reg_operand" "r"))] "TARGET_SH1 && ! TARGET_SH4" "jsr @%1%#" [(set_attr "type" "sfunc") (set_attr "needs_delay_slot" "yes")]); Since shmedia-nofpu code could be linked against shcompact code, and; the sdivsi3 libcall has the same name, we must consider all registers; clobbered that are in the union of the registers clobbered by the; shmedia and the shcompact implementation. Note, if the shcompact; implementation actually used shcompact code, we'd need to clobber; also r22, r23 and fr23.(define_insn "divsi3_i1_media" [(set (match_operand:SI 0 "register_operand" "=z") (div:SI (reg:SI R4_REG) (reg:SI R5_REG))) (clobber (reg:SI T_MEDIA_REG)) (clobber (reg:SI PR_MEDIA_REG)) (clobber (reg:SI R1_REG)) (clobber (reg:SI R2_REG)) (clobber (reg:SI R3_REG)) (clobber (reg:SI R20_REG)) (clobber (reg:SI R21_REG)) (clobber (reg:DI TR0_REG)) (clobber (reg:DI TR1_REG)) (clobber (reg:DI TR2_REG)) (use (match_operand:DI 1 "target_operand" "b"))] "TARGET_SHMEDIA && ! TARGET_SHMEDIA_FPU" "blink %1, r18" [(set_attr "type" "sfunc")])(define_expand "divsi3_i4_media" [(set (match_dup 3) (float:DF (match_operand:SI 1 "register_operand" "r"))) (set (match_dup 4) (float:DF (match_operand:SI 2 "register_operand" "r"))) (set (match_dup 5) (div:DF (match_dup 3) (match_dup 4))) (set (match_operand:SI 0 "register_operand" "=r") (fix:SI (match_dup 5)))] "TARGET_SHMEDIA_FPU" "{ operands[3] = gen_reg_rtx (DFmode); operands[4] = gen_reg_rtx (DFmode); operands[5] = gen_reg_rtx (DFmode);}")(define_insn "divsi3_i4" [(set (match_operand:SI 0 "register_operand" "=y") (div:SI (reg:SI R4_REG) (reg:SI R5_REG))) (clobber (reg:SI PR_REG)) (clobber (reg:DF DR0_REG)) (clobber (reg:DF DR2_REG)) (use (reg:PSI FPSCR_REG)) (use (match_operand:SI 1 "arith_reg_operand" "r"))] "TARGET_SH4 && ! TARGET_FPU_SINGLE" "jsr @%1%#" [(set_attr "type" "sfunc") (set_attr "fp_mode" "double") (set_attr "needs_delay_slot" "yes")])(define_insn "divsi3_i4_single" [(set (match_operand:SI 0 "register_operand" "=y") (div:SI (reg:SI R4_REG) (reg:SI R5_REG))) (clobber (reg:SI PR_REG)) (clobber (reg:DF DR0_REG)) (clobber (reg:DF DR2_REG)) (clobber (reg:SI R2_REG)) (use (match_operand:SI 1 "arith_reg_operand" "r"))] "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE" "jsr @%1%#" [(set_attr "type" "sfunc") (set_attr "needs_delay_slot" "yes")])(define_expand "divsi3" [(set (match_dup 3) (symbol_ref:SI "__sdivsi3")) (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" "") (div:SI (reg:SI R4_REG) (reg:SI R5_REG))) (clobber (reg:SI T_REG)) (clobber (reg:SI PR_REG)) (clobber (reg:SI R1_REG)) (clobber (reg:SI R2_REG)) (clobber (reg:SI R3_REG)) (use (match_dup 3))])] "" "{ rtx first, last; operands[3] = gen_reg_rtx (Pmode); /* Emit the move of the address to a pseudo outside of the libcall. */ if (TARGET_HARD_SH4 && TARGET_SH2E) { emit_move_insn (operands[3], function_symbol (\"__sdivsi3_i4\")); if (TARGET_FPU_SINGLE) last = gen_divsi3_i4_single (operands[0], operands[3]); else last = gen_divsi3_i4 (operands[0], operands[3]); } else if (TARGET_SH2A) { operands[1] = force_reg (SImode, operands[1]); operands[2] = force_reg (SImode, operands[2]); emit_insn (gen_divsi3_sh2a (operands[0], operands[1], operands[2])); DONE; } else if (TARGET_SHMEDIA_FPU) { operands[1] = force_reg (SImode, operands[1]); operands[2] = force_reg (SImode, operands[2]); emit_insn (gen_divsi3_i4_media (operands[0], operands[1], operands[2])); DONE; } else if (TARGET_SH5) { emit_move_insn (operands[3], function_symbol (TARGET_FPU_ANY ? \"__sdivsi3_i4\" : \"__sdivsi3\")); if (TARGET_SHMEDIA) last = gen_divsi3_i1_media (operands[0], Pmode == DImode ? operands[3] : gen_rtx_SUBREG (DImode, operands[3], 0)); else if (TARGET_FPU_ANY) last = gen_divsi3_i4_single (operands[0], operands[3]); else last = gen_divsi3_i1 (operands[0], operands[3]); } else { emit_move_insn (operands[3], function_symbol (\"__sdivsi3\")); last = gen_divsi3_i1 (operands[0], operands[3]); } first = emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]); emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]); last = emit_insn (last); /* 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;}");; -------------------------------------------------------------------------;; 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)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -