📄 sh.md
字号:
(match_operand:DI 2 "arith_reg_or_0_operand" "rN") (match_operand:DI 3 "arith_reg_operand" "0")))] "TARGET_SHMEDIA" "cmveq %1, %N2, %0" [(set_attr "type" "arith_media")])(define_insn "movdicc_true" [(set (match_operand:DI 0 "arith_reg_dest" "=r") (if_then_else:DI (ne (match_operand:DI 1 "arith_reg_operand" "r") (const_int 0)) (match_operand:DI 2 "arith_reg_or_0_operand" "rN") (match_operand:DI 3 "arith_reg_operand" "0")))] "TARGET_SHMEDIA" "cmvne %1, %N2, %0" [(set_attr "type" "arith_media")])(define_expand "movdicc" [(set (match_operand:DI 0 "register_operand" "") (if_then_else:DI (match_operand 1 "comparison_operator" "") (match_operand:DI 2 "register_operand" "") (match_operand:DI 3 "register_operand" "")))] "TARGET_SHMEDIA" "{ if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE) && GET_MODE (sh_compare_op0) == DImode && sh_compare_op1 == const0_rtx) operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), VOIDmode, sh_compare_op0, sh_compare_op1); else { rtx tmp; if (no_new_pseudos) FAIL; tmp = gen_reg_rtx (DImode); switch (GET_CODE (operands[1])) { case EQ: emit_insn (gen_seq (tmp)); operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx); break; case NE: emit_insn (gen_seq (tmp)); operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx); break; case GT: emit_insn (gen_sgt (tmp)); operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx); break; case LT: emit_insn (gen_slt (tmp)); operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx); break; case GE: emit_insn (gen_slt (tmp)); operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx); break; case LE: emit_insn (gen_sgt (tmp)); operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx); break; case GTU: emit_insn (gen_sgtu (tmp)); operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx); break; case LTU: emit_insn (gen_sltu (tmp)); operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx); break; case GEU: emit_insn (gen_sltu (tmp)); operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx); break; case LEU: emit_insn (gen_sgtu (tmp)); operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx); break; case UNORDERED: emit_insn (gen_sunordered (tmp)); operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx); break; case ORDERED: emit_insn (gen_sunordered (tmp)); operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx); break; case UNEQ: case UNGE: case UNGT: case UNLE: case UNLT: case LTGT: FAIL; default: abort (); } }}");; -------------------------------------------------------------------------;; Addition instructions;; -------------------------------------------------------------------------(define_expand "adddi3" [(set (match_operand:DI 0 "arith_reg_operand" "") (plus:DI (match_operand:DI 1 "arith_reg_operand" "") (match_operand:DI 2 "arith_operand" "")))] "" "{ if (TARGET_SH1) { if (no_new_pseudos && ! arith_reg_operand (operands[2], DImode)) FAIL; operands[2] = force_reg (DImode, operands[2]); emit_insn (gen_adddi3_compact (operands[0], operands[1], operands[2])); DONE; }}")(define_insn "*adddi3_media" [(set (match_operand:DI 0 "arith_reg_operand" "=r,r") (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r") (match_operand:DI 2 "arith_operand" "r,I10")))] "TARGET_SHMEDIA" "@ add %1, %2, %0 addi %1, %2, %0" [(set_attr "type" "arith_media")])(define_insn "adddi3z_media" [(set (match_operand:DI 0 "arith_reg_operand" "=r") (zero_extend:DI (plus:SI (match_operand:SI 1 "extend_reg_operand" "r") (match_operand:SI 2 "extend_reg_or_0_operand" "rN"))))] "TARGET_SHMEDIA" "addz.l %1, %N2, %0" [(set_attr "type" "arith_media")])(define_insn "adddi3_compact" [(set (match_operand:DI 0 "arith_reg_operand" "=&r") (plus:DI (match_operand:DI 1 "arith_reg_operand" "%0") (match_operand:DI 2 "arith_reg_operand" "r"))) (clobber (reg:SI T_REG))] "TARGET_SH1" "#" [(set_attr "length" "6")])(define_split [(set (match_operand:DI 0 "arith_reg_operand" "") (plus:DI (match_operand:DI 1 "arith_reg_operand" "") (match_operand:DI 2 "arith_reg_operand" ""))) (clobber (reg:SI T_REG))] "TARGET_SH1 && reload_completed" [(const_int 0)] "{ rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]); high0 = gen_rtx_REG (SImode, true_regnum (operands[0]) + (TARGET_LITTLE_ENDIAN ? 1 : 0)); high2 = gen_rtx_REG (SImode, true_regnum (operands[2]) + (TARGET_LITTLE_ENDIAN ? 1 : 0)); emit_insn (gen_clrt ()); emit_insn (gen_addc (low0, low0, gen_lowpart (SImode, operands[2]))); emit_insn (gen_addc1 (high0, high0, high2)); DONE;}")(define_insn "addc" [(set (match_operand:SI 0 "arith_reg_operand" "=r") (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0") (match_operand:SI 2 "arith_reg_operand" "r")) (reg:SI T_REG))) (set (reg:SI T_REG) (ltu:SI (plus:SI (match_dup 1) (match_dup 2)) (match_dup 1)))] "TARGET_SH1" "addc %2,%0" [(set_attr "type" "arith")])(define_insn "addc1" [(set (match_operand:SI 0 "arith_reg_operand" "=r") (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0") (match_operand:SI 2 "arith_reg_operand" "r")) (reg:SI T_REG))) (clobber (reg:SI T_REG))] "TARGET_SH1" "addc %2,%0" [(set_attr "type" "arith")])(define_expand "addsi3" [(set (match_operand:SI 0 "arith_reg_operand" "") (plus:SI (match_operand:SI 1 "arith_operand" "") (match_operand:SI 2 "arith_operand" "")))] "" "{ if (TARGET_SHMEDIA) operands[1] = force_reg (SImode, operands[1]);}")(define_insn "addsi3_media" [(set (match_operand:SI 0 "arith_reg_operand" "=r,r") (plus:SI (match_operand:SI 1 "extend_reg_operand" "%r,r") (match_operand:SI 2 "arith_operand" "r,I10")))] "TARGET_SHMEDIA" "@ add.l %1, %2, %0 addi.l %1, %2, %0" [(set_attr "type" "arith_media")])(define_insn "*addsi3_compact" [(set (match_operand:SI 0 "arith_reg_operand" "=r") (plus:SI (match_operand:SI 1 "arith_operand" "%0") (match_operand:SI 2 "arith_operand" "rI08")))] "TARGET_SH1" "add %2,%0" [(set_attr "type" "arith")]);; -------------------------------------------------------------------------;; Subtraction instructions;; -------------------------------------------------------------------------(define_expand "subdi3" [(set (match_operand:DI 0 "arith_reg_operand" "") (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "") (match_operand:DI 2 "arith_reg_operand" "")))] "" "{ if (TARGET_SH1) { operands[1] = force_reg (DImode, operands[1]); emit_insn (gen_subdi3_compact (operands[0], operands[1], operands[2])); DONE; }}")(define_insn "*subdi3_media" [(set (match_operand:DI 0 "arith_reg_operand" "=r") (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN") (match_operand:DI 2 "arith_reg_operand" "r")))] "TARGET_SHMEDIA" "sub %N1, %2, %0" [(set_attr "type" "arith_media")])(define_insn "subdi3_compact" [(set (match_operand:DI 0 "arith_reg_operand" "=&r") (minus:DI (match_operand:DI 1 "arith_reg_operand" "0") (match_operand:DI 2 "arith_reg_operand" "r"))) (clobber (reg:SI T_REG))] "TARGET_SH1" "#" [(set_attr "length" "6")])(define_split [(set (match_operand:DI 0 "arith_reg_operand" "") (minus:DI (match_operand:DI 1 "arith_reg_operand" "") (match_operand:DI 2 "arith_reg_operand" ""))) (clobber (reg:SI T_REG))] "TARGET_SH1 && reload_completed" [(const_int 0)] "{ rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]); high0 = gen_rtx_REG (SImode, true_regnum (operands[0]) + (TARGET_LITTLE_ENDIAN ? 1 : 0)); high2 = gen_rtx_REG (SImode, true_regnum (operands[2]) + (TARGET_LITTLE_ENDIAN ? 1 : 0)); emit_insn (gen_clrt ()); emit_insn (gen_subc (low0, low0, gen_lowpart (SImode, operands[2]))); emit_insn (gen_subc1 (high0, high0, high2)); DONE;}")(define_insn "subc" [(set (match_operand:SI 0 "arith_reg_operand" "=r") (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0") (match_operand:SI 2 "arith_reg_operand" "r")) (reg:SI T_REG))) (set (reg:SI T_REG) (gtu:SI (minus:SI (minus:SI (match_dup 1) (match_dup 2)) (reg:SI T_REG)) (match_dup 1)))] "TARGET_SH1" "subc %2,%0" [(set_attr "type" "arith")])(define_insn "subc1" [(set (match_operand:SI 0 "arith_reg_operand" "=r") (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0") (match_operand:SI 2 "arith_reg_operand" "r")) (reg:SI T_REG))) (clobber (reg:SI T_REG))] "TARGET_SH1" "subc %2,%0" [(set_attr "type" "arith")])(define_insn "*subsi3_internal" [(set (match_operand:SI 0 "arith_reg_operand" "=r") (minus:SI (match_operand:SI 1 "arith_reg_operand" "0") (match_operand:SI 2 "arith_reg_operand" "r")))] "TARGET_SH1" "sub %2,%0" [(set_attr "type" "arith")])(define_insn "*subsi3_media" [(set (match_operand:SI 0 "arith_reg_operand" "=r") (minus:SI (match_operand:SI 1 "extend_reg_or_0_operand" "rN") (match_operand:SI 2 "extend_reg_operand" "r")))] "TARGET_SHMEDIA" "sub.l %N1, %2, %0" [(set_attr "type" "arith_media")]);; Convert `constant - reg' to `neg rX; add rX, #const' since this;; will sometimes save one instruction. Otherwise we might get;; `mov #const, rY; sub rY,rX; mov rX, rY' if the source and dest regs;; are the same.(define_expand "subsi3" [(set (match_operand:SI 0 "arith_reg_operand" "") (minus:SI (match_operand:SI 1 "arith_operand" "") (match_operand:SI 2 "arith_reg_operand" "")))] "" "{ if (TARGET_SH1 && GET_CODE (operands[1]) == CONST_INT) { emit_insn (gen_negsi2 (operands[0], operands[2])); emit_insn (gen_addsi3 (operands[0], operands[0], operands[1])); DONE; } if (TARGET_SHMEDIA) { if (no_new_pseudos && ! arith_reg_or_0_operand (operands[1], SImode)) FAIL; if (operands[1] != const0_rtx) operands[1] = force_reg (SImode, operands[1]); }}");; -------------------------------------------------------------------------;; Division instructions;; -------------------------------------------------------------------------;; We take advantage of the library routines which don't clobber as many;; registers as a normal function call would.;; The INSN_REFERENCES_ARE_DELAYED in sh.h is problematic because it;; also has an effect on the register that holds the address of the sfunc.;; To make this work, we have an extra dummy insn that shows the use;; of this register for reorg.(define_insn "use_sfunc_addr" [(set (reg:SI PR_REG) (unspec:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_SFUNC))] "TARGET_SH1 && check_use_sfunc_addr (insn, operands[0])" "" [(set_attr "length" "0")])(define_insn "udivsi3_sh2a" [(set (match_operand:SI 0 "arith_reg_operand" "=r") (udiv:SI (match_operand:SI 1 "arith_reg_operand" "0") (match_operand:SI 2 "arith_reg_operand" "z")))] "TARGET_SH2A" "divu %2,%1" [(set_attr "type" "arith") (set_attr "in_delay_slot" "no")]);; We must use a pseudo-reg forced to reg 0 in the SET_DEST rather than;; hard register 0. If we used hard register 0, then the next instruction;; would be a move from hard register 0 to a pseudo-reg. If the pseudo-reg;; gets allocated to a stack slot that needs its address reloaded, then
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -