📄 sh.md
字号:
[(set (reg:SI 18) (geu: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, GEU);")(define_expand "bleu" [(set (reg:SI 18) (gtu: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, LEU);");; ------------------------------------------------------------------------;; Jump and linkage insns;; ------------------------------------------------------------------------(define_insn "jump" [(set (pc) (label_ref (match_operand 0 "" "")))] "" "*{ /* The length is 16 if the delay slot is unfilled. */ if (get_attr_length(insn) >= 14) return output_far_jump(insn, operands[0]); else return \"bra %l0%#\";}" [(set_attr "type" "jump") (set_attr "needs_delay_slot" "yes")])(define_insn "calli" [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r")) (match_operand 1 "" "")) (clobber (reg:SI 17))] "" "jsr @%0%#" [(set_attr "type" "call") (set_attr "needs_delay_slot" "yes")])(define_insn "call_valuei" [(set (match_operand 0 "" "=rf") (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r")) (match_operand 2 "" ""))) (clobber (reg:SI 17))] "" "jsr @%1%#" [(set_attr "type" "call") (set_attr "needs_delay_slot" "yes")])(define_expand "call" [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" "")) (match_operand 1 "" "")) (clobber (reg:SI 17))])] "" "operands[0] = force_reg (SImode, XEXP (operands[0], 0));")(define_expand "call_value" [(parallel [(set (match_operand 0 "arith_reg_operand" "") (call (mem:SI (match_operand 1 "arith_reg_operand" "")) (match_operand 2 "" ""))) (clobber (reg:SI 17))])] "" "operands[1] = force_reg (SImode, XEXP (operands[1], 0));")(define_insn "indirect_jump" [(set (pc) (match_operand:SI 0 "arith_reg_operand" "r"))] "" "jmp @%0%#" [(set_attr "needs_delay_slot" "yes")]);; ------------------------------------------------------------------------;; Misc insns;; ------------------------------------------------------------------------;; ??? This combiner pattern does not work, because combine does not combine;; instructions that set a hard register when SMALL_REGISTER_CLASSES is;; defined. Perhaps use a pseudo-reg for the T bit?(define_insn "dect" [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "=r") (plus:SI (match_dup 0) (const_int -1))) (set (reg:SI 18) (eq:SI (plus:SI (match_dup 0) (const_int -1)) (const_int 0)))])] "TARGET_SH2" "dt %0")(define_insn "nop" [(const_int 0)] "" "nop");; Load address of a label. This is only generated by the casesi expand.;; This must use unspec, because this only works immediately before a casesi.(define_insn "mova" [(set (reg:SI 0) (unspec [(label_ref (match_operand 0 "" ""))] 1))] "" "mova %O0,r0" [(set_attr "in_delay_slot" "no")]);; case instruction for switch statements.;; Operand 0 is index;; operand 1 is the minimum bound;; operand 2 is the maximum bound - minimum bound + 1;; operand 3 is CODE_LABEL for the table;;; operand 4 is the CODE_LABEL to go to if index out of range.;; ??? There should be a barrier after the jump at the end.(define_expand "casesi" [(set (match_dup 5) (match_operand:SI 0 "arith_reg_operand" "")) (set (match_dup 5) (minus:SI (match_dup 5) (match_operand:SI 1 "arith_operand" ""))) (set (reg:SI 18) (gtu:SI (match_dup 5) (match_operand:SI 2 "arith_reg_operand" ""))) (set (pc) (if_then_else (eq (reg:SI 18) (const_int 1)) (label_ref (match_operand 4 "" "")) (pc))) (set (match_dup 6) (match_dup 5)) (set (match_dup 6) (ashift:SI (match_dup 6) (match_dup 7))) (set (reg:SI 0) (unspec [(label_ref (match_operand 3 "" ""))] 1)) (parallel [(set (reg:SI 0) (plus:SI (reg:SI 0) (mem:HI (plus:SI (reg:SI 0) (match_dup 6))))) (set (match_dup 6) (mem:HI (plus:SI (reg:SI 0) (match_dup 6))))]) (set (pc) (reg:SI 0))] "" "{ operands[1] = copy_to_mode_reg (SImode, operands[1]); operands[2] = copy_to_mode_reg (SImode, operands[2]); operands[5] = gen_reg_rtx (SImode); operands[6] = gen_reg_rtx (SImode); operands[7] = GEN_INT (TARGET_BIGTABLE ? 2 : 1);}")(define_insn "casesi_worker" [(set (reg:SI 0) (plus:SI (reg:SI 0) (mem:HI (plus:SI (reg:SI 0) (match_operand:SI 0 "arith_reg_operand" "+r"))))) (set (match_dup 0) (mem:HI (plus:SI (reg:SI 0) (match_dup 0))))] "" "*{ if (TARGET_BIGTABLE) return \"mov.l @(r0,%0),%0\;add %0,r0\"; else return \"mov.w @(r0,%0),%0\;add %0,r0\";}" [(set_attr "length" "4")])(define_insn "return" [(return)] "reload_completed" "%@ %#" [(set_attr "type" "return") (set_attr "needs_delay_slot" "yes")])(define_expand "prologue" [(const_int 0)] "" "sh_expand_prologue (); DONE;")(define_expand "epilogue" [(return)] "" "sh_expand_epilogue ();")(define_insn "blockage" [(unspec_volatile [(const_int 0)] 0)] "" "" [(set_attr "length" "0")]);; ------------------------------------------------------------------------;; Scc instructions;; ------------------------------------------------------------------------(define_insn "movt" [(set (match_operand:SI 0 "arith_reg_operand" "=r") (eq:SI (reg:SI 18) (const_int 1)))] "" "movt %0")(define_expand "seq" [(set (match_operand:SI 0 "arith_reg_operand" "") (match_dup 1))] "" "operands[1] = prepare_scc_operands (EQ);")(define_expand "slt" [(set (match_operand:SI 0 "arith_reg_operand" "") (match_dup 1))] "" "operands[1] = prepare_scc_operands (LT);")(define_expand "sle" [(set (match_operand:SI 0 "arith_reg_operand" "") (match_dup 1))] "" "operands[1] = prepare_scc_operands (LE);")(define_expand "sgt" [(set (match_operand:SI 0 "arith_reg_operand" "") (match_dup 1))] "" "operands[1] = prepare_scc_operands (GT);")(define_expand "sge" [(set (match_operand:SI 0 "arith_reg_operand" "") (match_dup 1))] "" "operands[1] = prepare_scc_operands (GE);")(define_expand "sgtu" [(set (match_operand:SI 0 "arith_reg_operand" "") (match_dup 1))] "" "operands[1] = prepare_scc_operands (GTU);")(define_expand "sltu" [(set (match_operand:SI 0 "arith_reg_operand" "") (match_dup 1))] "" "operands[1] = prepare_scc_operands (LTU);")(define_expand "sleu" [(set (match_operand:SI 0 "arith_reg_operand" "") (match_dup 1))] "" "operands[1] = prepare_scc_operands (LEU);")(define_expand "sgeu" [(set (match_operand:SI 0 "arith_reg_operand" "") (match_dup 1))] "" "operands[1] = prepare_scc_operands (GEU);")(define_expand "sne" [(set (match_operand:SI 0 "arith_reg_operand" "") (match_dup 1)) (set (match_dup 0) (xor:SI (match_dup 0) (const_int 1)))] "" "operands[1] = prepare_scc_operands (EQ);");; -------------------------------------------------------------------------;; Instructions to cope with inline literal tables;; -------------------------------------------------------------------------; 2 byte integer in line(define_insn "consttable_2" [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")] 2)] "" "*{ assemble_integer (operands[0], 2, 1); return \"\";}" [(set_attr "length" "2") (set_attr "in_delay_slot" "no")]); 4 byte integer in line(define_insn "consttable_4" [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")] 4)] "" "*{ assemble_integer (operands[0], 4, 1); return \"\";}" [(set_attr "length" "4") (set_attr "in_delay_slot" "no")]); 8 byte integer in line(define_insn "consttable_8" [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")] 6)] "" "*{ assemble_integer (operands[0], 8, 1); return \"\";}" [(set_attr "length" "8") (set_attr "in_delay_slot" "no")]); align to a two byte boundary(define_insn "align_2" [(unspec_volatile [(const_int 0)] 10)] "" ".align 1" [(set_attr "length" "0") (set_attr "in_delay_slot" "no")]); align to a four byte boundary(define_insn "align_4" [(unspec_volatile [(const_int 0)] 5)] "" ".align 2" [(set_attr "in_delay_slot" "no")]); emitted at the end of the literal table, used to emit the; 32bit branch labels if needed.(define_insn "consttable_end" [(unspec_volatile [(const_int 0)] 11)] "" "* return output_jump_label_table ();" [(set_attr "in_delay_slot" "no")]);; -------------------------------------------------------------------------;; Misc;; -------------------------------------------------------------------------;; String/block move insn.(define_expand "movstrsi" [(parallel [(set (mem:BLK (match_operand:BLK 0 "" "")) (mem:BLK (match_operand:BLK 1 "" ""))) (use (match_operand:SI 2 "nonmemory_operand" "")) (use (match_operand:SI 3 "immediate_operand" "")) (clobber (reg:SI 17)) (clobber (reg:SI 4)) (clobber (reg:SI 5)) (clobber (reg:SI 0))])] "" "{ if(expand_block_move (operands)) DONE; else FAIL;}")(define_insn "block_move_real" [(parallel [(set (mem:BLK (reg:SI 4)) (mem:BLK (reg:SI 5))) (use (match_operand:SI 0 "arith_reg_operand" "r")) (clobber (reg:SI 17)) (clobber (reg:SI 0))])] "" "jsr @%0%#" [(set_attr "type" "sfunc") (set_attr "needs_delay_slot" "yes")])(define_insn "block_lump_real" [(parallel [(set (mem:BLK (reg:SI 4)) (mem:BLK (reg:SI 5))) (use (match_operand:SI 0 "arith_reg_operand" "r")) (use (reg:SI 6)) (clobber (reg:SI 17)) (clobber (reg:SI 4)) (clobber (reg:SI 5)) (clobber (reg:SI 6)) (clobber (reg:SI 0))])] "" "jsr @%0%#" [(set_attr "type" "sfunc") (set_attr "needs_delay_slot" "yes")]);; -------------------------------------------------------------------------;; Peepholes;; -------------------------------------------------------------------------;; This matches cases where a stack pointer increment at the start of the;; epilogue combines with a stack slot read loading the return value.(define_peephole [(set (match_operand:SI 0 "arith_reg_operand" "") (mem:SI (match_operand:SI 1 "arith_reg_operand" ""))) (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))] "REGNO (operands[1]) != REGNO (operands[0])" "mov.l @%1+,%0");; See the comment on the dt combiner pattern above.(define_peephole [(set (match_operand:SI 0 "arith_reg_operand" "=r") (plus:SI (match_dup 0) (const_int -1))) (set (reg:SI 18) (eq:SI (match_dup 0) (const_int 0)))] "TARGET_SH2" "dt %0");; These convert sequences such as `mov #k,r0; add r15,r0; mov.l @r0,rn';; to `mov #k,r0; mov.l @(r0,r15),rn'. These sequences are generated by;; reload when the constant is too large for a reg+offset address.;; ??? We would get much better code if this was done in reload. This would;; require modifying find_reloads_address to recognize that if the constant;; is out-of-range for an immediate add, then we get better code by reloading;; the constant into a register than by reloading the sum into a register,;; since the former is one instruction shorter if the address does not need;; to be offsettable. Unfortunately this does not work, because there is;; only one register, r0, that can be used as an index register. This register;; is also the function return value register. So, if we try to force reload;; to use double-reg addresses, then we end up with some instructions that;; need to use r0 twice. The only way to fix this is to change the calling;; convention so that r0 is not used to return values.(define_peephole [(set (match_operand:SI 0 "register_operand" "=r") (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r"))) (set (mem:SI (match_dup 0)) (match_operand:SI 2 "general_movsrc_operand" ""))] "REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)" "mov.l %2,@(%0,%1)")(define_peephole [(set (match_operand:SI 0 "register_operand" "=r") (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r"))) (set (match_operand:SI 2 "general_movdst_operand" "") (mem:SI (match_dup 0)))] "REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)" "mov.l @(%0,%1),%2")(define_peephole [(set (match_operand:SI 0 "register_operand" "=r") (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r"))) (set (mem:HI (match_dup 0)) (match_operand:HI 2 "general_movsrc_operand" ""))] "REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)" "mov.w %2,@(%0,%1)")(define_peephole [(set (match_operand:SI 0 "register_operand" "=r") (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r"))) (set (match_operand:HI 2 "general_movdst_operand" "") (mem:HI (match_dup 0)))] "REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)" "mov.w @(%0,%1),%2")(define_peephole [(set (match_operand:SI 0 "register_operand" "=r") (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r"))) (set (mem:QI (match_dup 0)) (match_operand:QI 2 "general_movsrc_operand" ""))] "REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)" "mov.b %2,@(%0,%1)")(define_peephole [(set (match_operand:SI 0 "register_operand" "=r") (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r"))) (set (match_operand:QI 2 "general_movdst_operand" "") (mem:QI (match_dup 0)))] "REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)" "mov.b @(%0,%1),%2")(define_peephole [(set (match_operand:SI 0 "register_operand" "=r") (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r"))) (set (mem:SF (match_dup 0)) (match_operand:SF 2 "general_movsrc_operand" ""))] "REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)" "mov.l %2,@(%0,%1)")(define_peephole [(set (match_operand:SI 0 "register_operand" "=r") (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r"))) (set (match_operand:SF 2 "general_movdst_operand" "") (mem:SF (match_dup 0)))] "REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)" "mov.l @(%0,%1),%2")
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -