📄 sh.md
字号:
[(set (match_operand:SI 0 "arith_reg_operand" "=r") (neg:SI (plus:SI (reg:SI 18) (match_operand:SI 1 "arith_reg_operand" "r")))) (set (reg:SI 18) (ne:SI (ior:SI (reg:SI 18) (match_dup 1)) (const_int 0)))] "" "negc %1,%0" [(set_attr "type" "arith")])(define_expand "negdi2" [(set (match_operand:DI 0 "arith_reg_operand" "") (neg:DI (match_operand:DI 1 "arith_reg_operand" ""))) (clobber (reg:SI 18))] "" "{ int low_word = (TARGET_LITTLE_ENDIAN ? 0 : 1); int high_word = (TARGET_LITTLE_ENDIAN ? 1 : 0); rtx low_src = operand_subword (operands[1], low_word, 0, DImode); rtx high_src = operand_subword (operands[1], high_word, 0, DImode); rtx low_dst = operand_subword (operands[0], low_word, 1, DImode); rtx high_dst = operand_subword (operands[0], high_word, 1, DImode); emit_insn (gen_clrt ()); emit_insn (gen_negc (low_dst, low_src)); emit_insn (gen_negc (high_dst, high_src)); DONE;}")(define_insn "negsi2" [(set (match_operand:SI 0 "arith_reg_operand" "=r") (neg:SI (match_operand:SI 1 "arith_reg_operand" "r")))] "" "neg %1,%0" [(set_attr "type" "arith")])(define_insn "one_cmplsi2" [(set (match_operand:SI 0 "arith_reg_operand" "=r") (not:SI (match_operand:SI 1 "arith_reg_operand" "r")))] "" "not %1,%0" [(set_attr "type" "arith")]);; -------------------------------------------------------------------------;; Zero extension instructions;; -------------------------------------------------------------------------(define_insn "zero_extendhisi2" [(set (match_operand:SI 0 "arith_reg_operand" "=r") (zero_extend:SI (match_operand:HI 1 "arith_reg_operand" "r")))] "" "extu.w %1,%0" [(set_attr "type" "arith")])(define_insn "zero_extendqisi2" [(set (match_operand:SI 0 "arith_reg_operand" "=r") (zero_extend:SI (match_operand:QI 1 "arith_reg_operand" "r")))] "" "extu.b %1,%0" [(set_attr "type" "arith")])(define_insn "zero_extendqihi2" [(set (match_operand:HI 0 "arith_reg_operand" "=r") (zero_extend:HI (match_operand:QI 1 "arith_reg_operand" "r")))] "" "extu.b %1,%0" [(set_attr "type" "arith")]);; -------------------------------------------------------------------------;; Sign extension instructions;; -------------------------------------------------------------------------;; ??? This should be a define expand.;; ??? Or perhaps it should be dropped?(define_insn "extendsidi2" [(set (match_operand:DI 0 "arith_reg_operand" "=r") (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))) (clobber (reg:SI 18))] "" "mov %1,%S0\;mov %1,%R0\;shll %S0\;subc %S0,%S0" [(set_attr "length" "8")])(define_insn "extendhisi2" [(set (match_operand:SI 0 "arith_reg_operand" "=r,r") (sign_extend:SI (match_operand:HI 1 "general_movsrc_operand" "r,m")))] "" "@ exts.w %1,%0 mov.w %1,%0" [(set_attr "type" "arith,load")])(define_insn "extendqisi2" [(set (match_operand:SI 0 "arith_reg_operand" "=r,r") (sign_extend:SI (match_operand:QI 1 "general_movsrc_operand" "r,m")))] "" "@ exts.b %1,%0 mov.b %1,%0" [(set_attr "type" "arith,load")])(define_insn "extendqihi2" [(set (match_operand:HI 0 "arith_reg_operand" "=r,r") (sign_extend:HI (match_operand:QI 1 "general_movsrc_operand" "r,m")))] "" "@ exts.b %1,%0 mov.b %1,%0" [(set_attr "type" "arith,load")]);; -------------------------------------------------------------------------;; Move instructions;; -------------------------------------------------------------------------;; define push and pop so it is easy for sh.c(define_insn "push" [(set (mem:SI (pre_dec:SI (reg:SI 15))) (match_operand:SI 0 "register_operand" "r,l,x"))] "" "@ mov.l %0,@-r15 sts.l %0,@-r15 sts.l %0,@-r15" [(set_attr "type" "store,pstore,store") (set_attr "hit_stack" "yes")])(define_insn "pop" [(set (match_operand:SI 0 "register_operand" "=r,l,x") (mem:SI (post_inc:SI (reg:SI 15))))] "" "@ mov.l @r15+,%0 lds.l @r15+,%0 lds.l @r15+,%0" [(set_attr "type" "load,pload,load") (set_attr "hit_stack" "yes")]);; These two patterns can happen as the result of optimization, when;; comparisons get simplified to a move of zero or 1 into the T reg.;; They don't disappear completely, because the T reg is a fixed hard reg.(define_insn "clrt" [(set (reg:SI 18) (const_int 0))] "" "clrt")(define_insn "sett" [(set (reg:SI 18) (const_int 1))] "" "sett");; t/z is first, so that it will be preferred over r/r when reloading a move;; of a pseudo-reg into the T reg(define_insn "movsi_i" [(set (match_operand:SI 0 "general_movdst_operand" "=t,r,r,r,r,r,m,<,xl,xl,r") (match_operand:SI 1 "general_movsrc_operand" "z,Q,rI,m,xl,t,r,xl,r,>,i"))] "register_operand (operands[0], SImode) || register_operand (operands[1], SImode)" "@ tst %1,%1\;rotcl %1\;xor #1,%1\;rotcr %1 mov.l %1,%0 mov %1,%0 mov.l %1,%0 sts %1,%0 movt %0 mov.l %1,%0 sts.l %1,%0 lds %1,%0 lds.l %1,%0 fake %1,%0" [(set_attr "type" "move,pcload,move,load,move,store,store,move,load,move,move") (set_attr "length" "8,*,*,*,*,*,*,*,*,*,*")])(define_expand "movsi" [(set (match_operand:SI 0 "general_movdst_operand" "") (match_operand:SI 1 "general_movsrc_operand" ""))] "" "{ if (prepare_move_operands (operands, SImode)) DONE; }")(define_insn "movqi_i" [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,m,r,r,l") (match_operand:QI 1 "general_movsrc_operand" "ri,m,r,t,l,r"))] "arith_reg_operand (operands[0], QImode) || arith_reg_operand (operands[1], QImode)" "@ mov %1,%0 mov.b %1,%0 mov.b %1,%0 movt %0 sts %1,%0 lds %1,%0" [(set_attr "type" "move,load,store,move,move,move")])(define_expand "movqi" [(set (match_operand:QI 0 "general_operand" "") (match_operand:QI 1 "general_operand" ""))] "" "{ if (prepare_move_operands (operands, QImode)) DONE; }")(define_insn "movhi_i" [(set (match_operand:HI 0 "general_movdst_operand" "=r,r,r,r,m,r,l,r") (match_operand:HI 1 "general_movsrc_operand" "Q,rI,m,t,r,l,r,i"))] "arith_reg_operand (operands[0], HImode) || arith_reg_operand (operands[1], HImode)" "@ mov.w %1,%0 mov %1,%0 mov.w %1,%0 movt %0 mov.w %1,%0 sts %1,%0 lds %1,%0 fake %1,%0" [(set_attr "type" "pcload,move,load,move,store,move,move,move")])(define_expand "movhi" [(set (match_operand:HI 0 "general_movdst_operand" "") (match_operand:HI 1 "general_movsrc_operand" ""))] "" "{ if (prepare_move_operands (operands, HImode)) DONE; }");; ??? This should be a define expand.(define_insn "" [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,m,r,r") (match_operand:DI 1 "general_movsrc_operand" "Q,r,m,r,i,x"))] "arith_reg_operand (operands[0], DImode) || arith_reg_operand (operands[1], DImode)" "* return output_movedouble (insn, operands, DImode);" [(set_attr "length" "4") (set_attr "type" "pcload,move,load,store,move,move")]);; If the output is a register and the input is memory or a register, we have;; to be careful and see which word needs to be loaded first. (define_split [(set (match_operand:DI 0 "general_movdst_operand" "") (match_operand:DI 1 "general_movsrc_operand" ""))] "reload_completed" [(set (match_dup 2) (match_dup 3)) (set (match_dup 4) (match_dup 5))] "{ int regno; if ((GET_CODE (operands[0]) == MEM && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC) || (GET_CODE (operands[1]) == MEM && GET_CODE (XEXP (operands[1], 0)) == POST_INC)) FAIL; if (GET_CODE (operands[0]) == REG) regno = REGNO (operands[0]); else if (GET_CODE (operands[0]) == SUBREG) regno = REGNO (SUBREG_REG (operands[0])) + SUBREG_WORD (operands[0]); else if (GET_CODE (operands[0]) == MEM) regno = -1; if (regno == -1 || ! refers_to_regno_p (regno, regno + 1, operands[1], 0)) { operands[2] = operand_subword (operands[0], 0, 0, DImode); operands[3] = operand_subword (operands[1], 0, 0, DImode); operands[4] = operand_subword (operands[0], 1, 0, DImode); operands[5] = operand_subword (operands[1], 1, 0, DImode); } else { operands[2] = operand_subword (operands[0], 1, 0, DImode); operands[3] = operand_subword (operands[1], 1, 0, DImode); operands[4] = operand_subword (operands[0], 0, 0, DImode); operands[5] = operand_subword (operands[1], 0, 0, DImode); } if (operands[2] == 0 || operands[3] == 0 || operands[4] == 0 || operands[5] == 0) FAIL;}")(define_expand "movdi" [(set (match_operand:DI 0 "general_movdst_operand" "") (match_operand:DI 1 "general_movsrc_operand" ""))] "" "{ if ( prepare_move_operands (operands, DImode)) DONE; }");; ??? This should be a define expand.(define_insn "movdf_k" [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,m") (match_operand:DF 1 "general_movsrc_operand" "r,m,r"))] "arith_reg_operand (operands[0], DFmode) || arith_reg_operand (operands[1], DFmode)" "* return output_movedouble (insn, operands, DFmode);" [(set_attr "length" "4") (set_attr "type" "move,load,store")]);; If the output is a register and the input is memory or a register, we have;; to be careful and see which word needs to be loaded first. (define_split [(set (match_operand:DF 0 "general_movdst_operand" "") (match_operand:DF 1 "general_movsrc_operand" ""))] "reload_completed" [(set (match_dup 2) (match_dup 3)) (set (match_dup 4) (match_dup 5))] "{ int regno; if ((GET_CODE (operands[0]) == MEM && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC) || (GET_CODE (operands[1]) == MEM && GET_CODE (XEXP (operands[1], 0)) == POST_INC)) FAIL; if (GET_CODE (operands[0]) == REG) regno = REGNO (operands[0]); else if (GET_CODE (operands[0]) == SUBREG) regno = REGNO (SUBREG_REG (operands[0])) + SUBREG_WORD (operands[0]); else if (GET_CODE (operands[0]) == MEM) regno = -1; if (regno == -1 || ! refers_to_regno_p (regno, regno + 1, operands[1], 0)) { operands[2] = operand_subword (operands[0], 0, 0, DFmode); operands[3] = operand_subword (operands[1], 0, 0, DFmode); operands[4] = operand_subword (operands[0], 1, 0, DFmode); operands[5] = operand_subword (operands[1], 1, 0, DFmode); } else { operands[2] = operand_subword (operands[0], 1, 0, DFmode); operands[3] = operand_subword (operands[1], 1, 0, DFmode); operands[4] = operand_subword (operands[0], 0, 0, DFmode); operands[5] = operand_subword (operands[1], 0, 0, DFmode); } if (operands[2] == 0 || operands[3] == 0 || operands[4] == 0 || operands[5] == 0) FAIL;}")(define_expand "movdf" [(set (match_operand:DF 0 "general_movdst_operand" "") (match_operand:DF 1 "general_movsrc_operand" ""))] "" "{ if (prepare_move_operands (operands, DFmode)) DONE; }")(define_insn "movsf_i" [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,m,l,r") (match_operand:SF 1 "general_movsrc_operand" "r,I,m,r,r,l"))] "arith_reg_operand (operands[0], SFmode) || arith_reg_operand (operands[1], SFmode)" "@ mov %1,%0 mov %1,%0 mov.l %1,%0 mov.l %1,%0 lds %1,%0 sts %1,%0" [(set_attr "type" "move,move,load,store,move,move")])(define_expand "movsf" [(set (match_operand:SF 0 "general_movdst_operand" "") (match_operand:SF 1 "general_movsrc_operand" ""))] "" "{ if (prepare_move_operands (operands, SFmode)) DONE; }");; ------------------------------------------------------------------------;; Define the real conditional branch instructions.;; ------------------------------------------------------------------------(define_insn "branch_true" [(set (pc) (if_then_else (eq (reg:SI 18) (const_int 1)) (label_ref (match_operand 0 "" "")) (pc)))] "" "* return output_branch (1, insn, operands);" [(set_attr "type" "cbranch")])(define_insn "branch_false" [(set (pc) (if_then_else (ne (reg:SI 18) (const_int 1)) (label_ref (match_operand 0 "" "")) (pc)))] "" "* return output_branch (0, insn, operands);" [(set_attr "type" "cbranch")])(define_insn "inverse_branch_true" [(set (pc) (if_then_else (eq (reg:SI 18) (const_int 1)) (pc) (label_ref (match_operand 0 "" ""))))] "" "* return output_branch (0, insn, operands);" [(set_attr "type" "cbranch")])(define_insn "inverse_branch_false" [(set (pc) (if_then_else (ne (reg:SI 18) (const_int 1)) (pc) (label_ref (match_operand 0 "" ""))))] "" "* return output_branch (1, insn, operands);" [(set_attr "type" "cbranch")]);; Conditional branch insns(define_expand "beq" [(set (reg:SI 18) (eq:SI (match_dup 1) (match_dup 2))) (set (pc) (if_then_else (eq (reg:SI 18) (const_int 1)) (label_ref (match_operand 0 "" "")) (pc)))] "" "from_compare (operands, EQ);"); There is no bne compare, so we reverse the branch arms.(define_expand "bne" [(set (reg:SI 18) (eq:SI (match_dup 1) (match_dup 2))) (set (pc) (if_then_else (eq (reg:SI 18) (const_int 1)) (pc) (label_ref (match_operand 0 "" ""))))] "" "from_compare (operands, NE);")(define_expand "bgt" [(set (reg:SI 18) (gt:SI (match_dup 1) (match_dup 2))) (set (pc) (if_then_else (eq (reg:SI 18) (const_int 1)) (label_ref (match_operand 0 "" "")) (pc)))] "" "from_compare (operands, GT);")(define_expand "blt" [(set (reg:SI 18) (ge:SI (match_dup 1) (match_dup 2))) (set (pc) (if_then_else (eq (reg:SI 18) (const_int 1)) (pc) (label_ref (match_operand 0 "" ""))))] "" "from_compare (operands, LT);")(define_expand "ble" [(set (reg:SI 18) (gt:SI (match_dup 1) (match_dup 2))) (set (pc) (if_then_else (eq (reg:SI 18) (const_int 1)) (pc) (label_ref (match_operand 0 "" ""))))] "" "from_compare (operands, LE);")(define_expand "bge" [(set (reg:SI 18) (ge:SI (match_dup 1) (match_dup 2))) (set (pc) (if_then_else (eq (reg:SI 18) (const_int 1)) (label_ref (match_operand 0 "" "")) (pc)))] "" "from_compare (operands, GE);")(define_expand "bgtu" [(set (reg:SI 18) (gtu:SI (match_dup 1) (match_dup 2))) (set (pc) (if_then_else (eq (reg:SI 18) (const_int 1)) (label_ref (match_operand 0 "" "")) (pc)))] "" "from_compare (operands, GTU); ")(define_expand "bltu" [(set (reg:SI 18) (geu:SI (match_dup 1) (match_dup 2))) (set (pc) (if_then_else (eq (reg:SI 18) (const_int 1)) (pc) (label_ref (match_operand 0 "" ""))))] "" "from_compare (operands, LTU);")(define_expand "bgeu"
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -