📄 v850.md
字号:
(define_insn "jump" [(set (pc) (label_ref (match_operand 0 "" "")))] "" "*{ if (get_attr_length (insn) == 2) return \"br %0\"; else return \"jr %0\";}" [(set (attr "length") (if_then_else (lt (abs (minus (match_dup 0) (pc))) (const_int 256)) (const_int 2) (const_int 4))) (set_attr "cc" "none")])(define_insn "indirect_jump" [(set (pc) (match_operand:SI 0 "register_operand" "r"))] "" "jmp %0" [(set_attr "length" "2") (set_attr "cc" "none")])(define_insn "tablejump" [(set (pc) (match_operand:SI 0 "register_operand" "r")) (use (label_ref (match_operand 1 "" "")))] "" "jmp %0" [(set_attr "length" "2") (set_attr "cc" "none")])(define_expand "casesi" [(match_operand:SI 0 "register_operand" "") (match_operand:SI 1 "register_operand" "") (match_operand:SI 2 "register_operand" "") (match_operand 3 "" "") (match_operand 4 "" "")] "" "{ rtx reg = gen_reg_rtx (SImode); rtx tableaddress = gen_reg_rtx (SImode); rtx mem; /* Subtract the lower bound from the index. */ emit_insn (gen_subsi3 (reg, operands[0], operands[1])); /* Compare the result against the number of table entries. */ emit_insn (gen_cmpsi (reg, operands[2])); /* Branch to the default label if out of range of the table. */ emit_jump_insn (gen_bgtu (operands[4])); /* Shift index for the table array access. */ emit_insn (gen_ashlsi3 (reg, reg, GEN_INT (TARGET_BIG_SWITCH ? 2 : 1))); /* Load the table address into a pseudo. */ emit_insn (gen_movsi (tableaddress, gen_rtx (LABEL_REF, VOIDmode, operands[3]))); /* Add the table address to the index. */ emit_insn (gen_addsi3 (reg, reg, tableaddress)); /* Load the table entry. */ mem = gen_rtx (MEM, CASE_VECTOR_MODE, reg); RTX_UNCHANGING_P (mem); if (! TARGET_BIG_SWITCH) { rtx reg2 = gen_reg_rtx (HImode); emit_insn (gen_movhi (reg2, mem)); emit_insn (gen_extendhisi2 (reg, reg2)); } else emit_insn (gen_movsi (reg, mem)); /* Add the table address. */ emit_insn (gen_addsi3 (reg, reg, tableaddress)); /* Branch to the switch label. */ emit_jump_insn (gen_tablejump (reg, operands[3])); DONE;}");; Call subroutine with no return value.(define_expand "call" [(call (match_operand:QI 0 "general_operand" "") (match_operand:SI 1 "general_operand" ""))] "" "{ if (! call_address_operand (XEXP (operands[0], 0)) || TARGET_LONG_CALLS) XEXP (operands[0], 0) = force_reg (SImode, XEXP (operands[0], 0)); if (TARGET_LONG_CALLS) emit_call_insn (gen_call_internal_long (XEXP (operands[0], 0), operands[1])); else emit_call_insn (gen_call_internal_short (XEXP (operands[0], 0), operands[1])); DONE;}")(define_insn "call_internal_short" [(call (mem:QI (match_operand:SI 0 "call_address_operand" "S,r")) (match_operand:SI 1 "general_operand" "g,g")) (clobber (reg:SI 31))] "! TARGET_LONG_CALLS" "@ jarl %0,r31 jarl .+4,r31\\;add 4,r31\\;jmp %0" [(set_attr "length" "4,8")])(define_insn "call_internal_long" [(call (mem:QI (match_operand:SI 0 "call_address_operand" "S,r")) (match_operand:SI 1 "general_operand" "g,g")) (clobber (reg:SI 31))] "TARGET_LONG_CALLS" "* { if (which_alternative == 0) { if (GET_CODE (operands[0]) == REG) return \"jarl %0,r31\"; else return \"movhi hi(%0), r0, r11\\;movea lo(%0), r11, r11\\;jarl .+4,r31\\;add 4, r31\\;jmp r11\"; } else return \"jarl .+4,r31\\;add 4,r31\\;jmp %0\"; }" [(set_attr "length" "16,8")]);; Call subroutine, returning value in operand 0;; (which must be a hard register).(define_expand "call_value" [(set (match_operand 0 "" "") (call (match_operand:QI 1 "general_operand" "") (match_operand:SI 2 "general_operand" "")))] "" "{ if (! call_address_operand (XEXP (operands[1], 0)) || TARGET_LONG_CALLS) XEXP (operands[1], 0) = force_reg (SImode, XEXP (operands[1], 0)); if (TARGET_LONG_CALLS) emit_call_insn (gen_call_value_internal_long (operands[0], XEXP (operands[1], 0), operands[2])); else emit_call_insn (gen_call_value_internal_short (operands[0], XEXP (operands[1], 0), operands[2])); DONE;}")(define_insn "call_value_internal_short" [(set (match_operand 0 "" "=r,r") (call (mem:QI (match_operand:SI 1 "call_address_operand" "S,r")) (match_operand:SI 2 "general_operand" "g,g"))) (clobber (reg:SI 31))] "! TARGET_LONG_CALLS" "@ jarl %1,r31 jarl .+4,r31\\;add 4,r31\\;jmp %1" [(set_attr "length" "4,8")])(define_insn "call_value_internal_long" [(set (match_operand 0 "" "=r,r") (call (mem:QI (match_operand:SI 1 "call_address_operand" "S,r")) (match_operand:SI 2 "general_operand" "g,g"))) (clobber (reg:SI 31))] "TARGET_LONG_CALLS" "* { if (which_alternative == 0) { if (GET_CODE (operands[1]) == REG) return \"jarl %1, r31\"; else /* Reload can generate this pattern... */ return \"movhi hi(%1), r0, r11\\;movea lo(%1), r11, r11\\;jarl .+4, r31\\;add 4, r31\\;jmp r11\"; } else return \"jarl .+4, r31\\;add 4, r31\\;jmp %1\"; }" [(set_attr "length" "16,8")])(define_insn "nop" [(const_int 0)] "" "nop" [(set_attr "length" "2") (set_attr "cc" "none")]);; ----------------------------------------------------------------------;; EXTEND INSTRUCTIONS;; ----------------------------------------------------------------------(define_insn "zero_extendhisi2" [(set (match_operand:SI 0 "register_operand" "=r") (zero_extend:SI (match_operand:HI 1 "register_operand" "r")))] "" "andi 65535,%1,%0" [(set_attr "length" "4") (set_attr "cc" "set_znv")])(define_insn "zero_extendqisi2" [(set (match_operand:SI 0 "register_operand" "=r") (zero_extend:SI (match_operand:QI 1 "register_operand" "r")))] "" "andi 255,%1,%0" [(set_attr "length" "4") (set_attr "cc" "set_znv")]);;- sign extension instructions;; ??? This is missing a sign extend from memory pattern to match the ld.h;; instruction.(define_expand "extendhisi2" [(set (match_dup 2) (ashift:SI (match_operand:HI 1 "register_operand" "") (const_int 16))) (set (match_operand:SI 0 "register_operand" "") (ashiftrt:SI (match_dup 2) (const_int 16)))] "" "{ operands[1] = gen_lowpart (SImode, operands[1]); operands[2] = gen_reg_rtx (SImode);}");; ??? This is missing a sign extend from memory pattern to match the ld.b;; instruction.(define_expand "extendqisi2" [(set (match_dup 2) (ashift:SI (match_operand:QI 1 "register_operand" "") (const_int 24))) (set (match_operand:SI 0 "register_operand" "") (ashiftrt:SI (match_dup 2) (const_int 24)))] "" "{ operands[1] = gen_lowpart (SImode, operands[1]); operands[2] = gen_reg_rtx (SImode);}");; ----------------------------------------------------------------------;; SHIFTS;; ----------------------------------------------------------------------(define_insn "ashlsi3" [(set (match_operand:SI 0 "register_operand" "=r,r") (ashift:SI (match_operand:SI 1 "register_operand" "0,0") (match_operand:SI 2 "nonmemory_operand" "r,N")))] "" "@ shl %2,%0 shl %2,%0" [(set_attr "length" "4,2") (set_attr "cc" "set_znv")])(define_insn "lshrsi3" [(set (match_operand:SI 0 "register_operand" "=r,r") (lshiftrt:SI (match_operand:SI 1 "register_operand" "0,0") (match_operand:SI 2 "nonmemory_operand" "r,N")))] "" "@ shr %2,%0 shr %2,%0" [(set_attr "length" "4,2") (set_attr "cc" "set_znv")])(define_insn "ashrsi3" [(set (match_operand:SI 0 "register_operand" "=r,r") (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0") (match_operand:SI 2 "nonmemory_operand" "r,N")))] "" "@ sar %2,%0 sar %2,%0" [(set_attr "length" "4,2") (set_attr "cc" "set_znv")]);; ----------------------------------------------------------------------;; PROLOGUE/EPILOGUE;; ----------------------------------------------------------------------(define_expand "prologue" [(const_int 0)] "" "expand_prologue (); DONE;")(define_expand "epilogue" [(return)] "" "{ /* Try to use the trivial return first. Else use the full epilogue. */ if (0) emit_jump_insn (gen_return ()); else expand_epilogue (); DONE;}")(define_insn "return" [(return)] "reload_completed && compute_frame_size (get_frame_size (), (long *)0) == 0" "jmp [r31]" [(set_attr "length" "2") (set_attr "cc" "none")])(define_insn "return_internal" [(return) (use (reg:SI 31))] "" "jmp [r31]" [(set_attr "length" "2") (set_attr "cc" "none")]);; ----------------------------------------------------------------------;; HELPER INSTRUCTIONS for saving the prologue and epilog registers;; ----------------------------------------------------------------------;; This pattern will match a stack adjust RTX followed by any number of push;; RTXs. These RTXs will then be turned into a suitable call to a worker;; function.(define_insn "" [(match_parallel 0 "pattern_is_ok_for_prologue" [(set (reg:SI 3) (plus:SI (reg:SI 3) (match_operand:SI 1 "immediate_operand" "i"))) (set (mem:SI (plus:SI (reg:SI 3) (match_operand:SI 2 "immediate_operand" "i"))) (match_operand:SI 3 "register_is_ok_for_epilogue" "r"))])] "TARGET_PROLOG_FUNCTION" "* return construct_save_jarl (operands[0]); " [(set (attr "length") (if_then_else (eq_attr "long_calls" "yes") (const_string "16") (const_string "4"))) (set_attr "cc" "clobber")]);; This pattern will match a return RTX followed by any number of pop RTXs;; and possible a stack adjustment as well. These RTXs will be turned into;; a suitable call to a worker function.(define_insn ""[(match_parallel 0 "pattern_is_ok_for_epilogue" [(return) (set (reg:SI 3) (plus:SI (reg:SI 3) (match_operand:SI 1 "immediate_operand" "i"))) (set (match_operand:SI 2 "register_is_ok_for_epilogue" "r") (mem:SI (plus:SI (reg:SI 3) (match_operand:SI 3 "immediate_operand" "i"))))])] "TARGET_PROLOG_FUNCTION && TARGET_V850" "* return construct_restore_jr (operands[0]); " [(set (attr "length") (if_then_else (eq_attr "long_calls" "yes") (const_string "12") (const_string "4"))) (set_attr "cc" "clobber")]);; Initialize an interrupt function. Do not depend on TARGET_PROLOG_FUNCTION.(define_insn "save_interrupt" [(set (reg:SI 3) (plus:SI (reg:SI 3) (const_int -16))) (set (mem:SI (reg:SI 3)) (reg:SI 30)) (set (mem:SI (plus:SI (reg:SI 3) (const_int -4))) (reg:SI 10)) (set (mem:SI (plus:SI (reg:SI 3) (const_int -8))) (reg:SI 4)) (set (mem:SI (plus:SI (reg:SI 3) (const_int -12))) (reg:SI 1))] "TARGET_V850 && ! TARGET_LONG_CALLS" "add -16,sp\;st.w r10,12[sp]\;jarl __save_interrupt,r10" [(set_attr "length" "12") (set_attr "cc" "clobber")]);; Restore r1, r4, r10, and return from the interrupt(define_insn "restore_interrupt" [(return) (set (reg:SI 3) (plus:SI (reg:SI 3) (const_int 16))) (set (reg:SI 30) (mem:SI (plus:SI (reg:SI 3) (const_int 12)))) (set (reg:SI 10) (mem:SI (plus:SI (reg:SI 3) (const_int 8)))) (set (reg:SI 4) (mem:SI (plus:SI (reg:SI 3) (const_int 4)))) (set (reg:SI 1) (mem:SI (reg:SI 3)))] "" "jr __return_interrupt" [(set_attr "length" "4") (set_attr "cc" "clobber")]);; Save all registers except for the registers saved in save_interrupt when;; an interrupt function makes a call.;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and;; all of memory. This blocks insns from being moved across this point.;; This is needed because the rest of the compiler is not ready to handle;; insns this complicated.(define_insn "save_all_interrupt" [(unspec_volatile [(const_int 0)] 0)] "TARGET_V850 && ! TARGET_LONG_CALLS" "jarl __save_all_interrupt,r10" [(set_attr "length" "4") (set_attr "cc" "clobber")]);; Restore all registers saved when an interrupt function makes a call.;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and;; all of memory. This blocks insns from being moved across this point.;; This is needed because the rest of the compiler is not ready to handle;; insns this complicated.(define_insn "restore_all_interrupt" [(unspec_volatile [(const_int 0)] 1)] "TARGET_V850 && ! TARGET_LONG_CALLS" "jarl __restore_all_interrupt,r10" [(set_attr "length" "4") (set_attr "cc" "clobber")]);; Save r6-r9 for a variable argument function(define_insn "save_r6_r9" [(set (mem:SI (reg:SI 3)) (reg:SI 6)) (set (mem:SI (plus:SI (reg:SI 3) (const_int 4))) (reg:SI 7)) (set (mem:SI (plus:SI (reg:SI 3) (const_int 8))) (reg:SI 8)) (set (mem:SI (plus:SI (reg:SI 3) (const_int 12))) (reg:SI 9)) (clobber (reg:SI 10))] "TARGET_PROLOG_FUNCTION && ! TARGET_LONG_CALLS" "jarl __save_r6_r9,r10" [(set_attr "length" "4") (set_attr "cc" "clobber")])
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -