📄 v850.md
字号:
(zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,r,T,m")))] "TARGET_V850E" "@ zxb %0 andi 255,%1,%0 sld.bu %1,%0 ld.bu %1,%0" [(set_attr "length" "2,4,2,4") (set_attr "cc" "none_0hit,set_znv,none_0hit,none_0hit")])(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;; ??? The extendhisi2 pattern should not emit shifts for v850e?(define_insn "*extendhisi_insn" [(set (match_operand:SI 0 "register_operand" "=r,r,r") (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0,Q,m")))] "TARGET_V850E" "@ sxh %0 sld.h %1,%0 ld.h %1,%0" [(set_attr "length" "2,2,4") (set_attr "cc" "none_0hit,none_0hit,none_0hit")]);; ??? 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);}");; ??? The extendqisi2 pattern should not emit shifts for v850e?(define_insn "*extendqisi_insn" [(set (match_operand:SI 0 "register_operand" "=r,r,r") (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,Q,m")))] "TARGET_V850E" "@ sxb %0 sld.b %1,%0 ld.b %1,%0" [(set_attr "length" "2,2,4") (set_attr "cc" "none_0hit,none_0hit,none_0hit")]);; ??? 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.;;;; Actually, convert the RTXs into a PREPARE instruction.;;(define_insn "" [(match_parallel 0 "pattern_is_ok_for_prepare" [(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 && TARGET_V850E" "* return construct_prepare_instruction (operands[0]); " [(set_attr "length" "4") (set_attr "cc" "none")])(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")]);;;; Actually, turn the RTXs into a DISPOSE instruction.;;(define_insn "" [(match_parallel 0 "pattern_is_ok_for_dispose" [(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_V850E" "* return construct_dispose_instruction (operands[0]); " [(set_attr "length" "4") (set_attr "cc" "none")]);; 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 "callt_save_interrupt" [(unspec_volatile [(const_int 0)] 2)] "TARGET_V850E && !TARGET_DISABLE_CALLT" ;; The CALLT instruction stores the next address of CALLT to CTPC register ;; without saving its previous value. So if the interrupt handler ;; or its caller could possibily execute the CALLT insn, save_interrupt ;; MUST NOT be called via CALLT. "*{ output_asm_insn (\"addi -24, sp, sp\", operands); output_asm_insn (\"st.w r10, 12[sp]\", operands); output_asm_insn (\"stsr ctpc, r10\", operands); output_asm_insn (\"st.w r10, 16[sp]\", operands); output_asm_insn (\"stsr ctpsw, r10\", operands); output_asm_insn (\"st.w r10, 20[sp]\", operands); output_asm_insn (\"callt ctoff(__callt_save_interrupt)\", operands); return \"\";}" [(set_attr "length" "26") (set_attr "cc" "none")])(define_insn "callt_return_interrupt" [(unspec_volatile [(const_int 0)] 3)] "TARGET_V850E && !TARGET_DISABLE_CALLT" "callt ctoff(__callt_return_interrupt)" [(set_attr "length" "2") (set_attr "cc" "clobber")])(define_insn "save_interrupt" [(set (reg:SI 3) (plus:SI (reg:SI 3) (const_int -16))) (set (mem:SI (plus:SI (reg:SI 3) (const_int -16))) (reg:SI 30)) (set (mem:SI (plus:SI (reg:SI 3) (const_int -12))) (reg:SI 4)) (set (mem:SI (plus:SI (reg:SI 3) (const_int -8))) (reg:SI 1)) (set (mem:SI (plus:SI (reg:SI 3) (const_int -4))) (reg:SI 10))] "" "*{ if (TARGET_PROLOG_FUNCTION && !TARGET_LONG_CALLS) return \"add -16,sp\;st.w r10,12[sp]\;jarl __save_interrupt,r10\"; else { output_asm_insn (\"add -16, sp\", operands); output_asm_insn (\"st.w r10, 12[sp]\", operands); output_asm_insn (\"st.w ep, 0[sp]\", operands); output_asm_insn (\"st.w gp, 4[sp]\", operands); output_asm_insn (\"st.w r1, 8[sp]\", operands); output_asm_insn (\"movhi hi(__ep), r0, ep\", operands); output_asm_insn (\"movea lo(__ep), ep, ep\", operands); output_asm_insn (\"movhi hi(__gp), r0, gp\", operands); output_asm_insn (\"movea lo(__gp), gp, gp\", operands); return \"\"; }}" [(set (attr "length") (if_then_else (ne (symbol_ref "TARGET_LONG_CALLS") (const_int 0)) (const_int 10) (const_int 34))) (set_attr "cc" "clobber")]) ;; Restore r1, r4, r10, and return from the interrupt(define_insn "return_interrupt" [(return) (set (reg:SI 3) (plus:SI (reg:SI 3) (const_int 16))) (set (reg:SI 10) (mem:SI (plus:SI (reg:SI 3) (const_int 12)))) (set (reg:SI 1) (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 30) (mem:SI (reg:SI 3)))] "" "*{ if (TARGET_PROLOG_FUNCTION && !TARGET_LONG_CALLS) return \"jr __return_interrupt\"; else { output_asm_insn (\"ld.w 0[sp], ep\", operands); output_asm_insn (\"ld.w 4[sp], gp\", operands); output_asm_insn (\"ld.w 8[sp], r1\", operands); output_asm_insn (\"ld.w 12[sp], r10\", operands); output_asm_insn (\"addi 16, sp, sp\", operands); output_asm_insn (\"reti\", operands); return \"\"; }}" [(set (attr "length") (if_then_else (ne (symbol_ref "TARGET_LONG_CALLS") (const_int 0)) (const_int 4) (const_int 24))) (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 "callt_save_all_interrupt" [(unspec_volatile [(const_int 0)] 0)] "TARGET_V850E && !TARGET_DISABLE_CALLT" "callt ctoff(__callt_save_all_interrupt)" [(set_attr "length" "2") (set_attr "cc" "none")])(define_insn "save_all_interrupt" [(unspec_volatile [(const_int 0)] 0)] "" "*{ if (TARGET_PROLOG_FUNCTION && !TARGET_LONG_CALLS) return \"jarl __save_all_interrupt,r10\"; output_asm_insn (\"addi -120, sp, sp\", operands); output_asm_insn (\"mov ep, r1\", operands); output_asm_insn (\"mov sp, ep\", operands); output_asm_insn (\"sst.w r31, 116[ep]\", operands); output_asm_insn (\"sst.w r2, 112[ep]\", operands); output_asm_insn (\"sst.w gp, 108[ep]\", operands); output_asm_insn (\"sst.w r6, 104[ep]\", operands); output_asm_insn (\"sst.w r7, 100[ep]\", operands); output_asm_insn (\"sst.w r8, 96[ep]\", operands); output_asm_insn (\"sst.w r9, 92[ep]\", operands); output_asm_insn (\"sst.w r11, 88[ep]\", operands); output_asm_insn (\"sst.w r12, 84[ep]\", operands); output_asm_insn (\"sst.w r13, 80[ep]\", operands); output_asm_insn (\"sst.w r14, 76[ep]\", operands); output_asm_insn (\"sst.w r15, 72[ep]\", operands); output_asm_insn (\"sst.w r16, 68[ep]\", operands); output_asm_insn (\"sst.w r17, 64[ep]\", operands); output_asm_insn (\"sst.w r18, 60[ep]\", operands); output_asm_insn (\"sst.w r19, 56[ep]\", operands); output_asm_insn (\"sst.w r20, 52[ep]\", operands); output_asm_insn (\"sst.w r21, 48[ep]\", operands); output_asm_insn (\"sst.w r22, 44[ep]\", operands); output_asm_insn (\"sst.w r23, 40[ep]\", operands); output_asm_insn (\"sst.w r24, 36[ep]\", operands); output_asm_insn (\"sst.w r25, 32[ep]\", operands); output_asm_insn (\"sst.w r26, 28[ep]\", operands); output_asm_insn (\"sst.w r27, 24[ep]\", operands); output_asm_insn (\"sst.w r28, 20[ep]\", operands); output_asm_insn (\"sst.w r29, 16[ep]\", operands); output_asm_insn (\"mov r1, ep\", operands); return \"\";}" [(set (attr "length") (if_then_else (ne (symbol_ref "TARGET_LONG_CALLS") (const_int 0)) (const_int 4) (const_int 62) )) (set_attr "cc" "clobber")])(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 "callt_restore_all_interrupt" [(unspec_volatile [(const_int 0)] 1)] "TARGET_V850E && !TARGET_DISABLE_CALLT" "callt ctoff(__callt_restore_all_interrupt)" [(set_attr "length" "2") (set_attr "cc" "none")])(define_insn "restore_all_interrupt" [(unspec_volatile [(const_int 0)] 1)] "" "*{ if (TARGET_PROLOG_FUNCTION && !TARGET_LONG_CALLS) return \"jarl __restore_all_interrupt,r10\"; else { output_asm_insn (\"mov ep, r1\", operands); output_asm_insn (\"mov sp, ep\", operands); output_asm_insn (\"sld.w 116[ep], r31\", operands); output_asm_insn (\"sld.w 112[ep], r2\", operands); output_asm_insn (\"sld.w 108[ep], gp\", operands); output_asm_insn (\"sld.w 104[ep], r6\", operands); output_asm_insn (\"sld.w 100[ep], r7\", operands); output_asm_insn (\"sld.w 96[ep], r8\", operands); output_asm_insn (\"sld.w 92[ep], r9\", operands); output_asm_insn (\"sld.w 88[ep], r11\", operands); output_asm_insn (\"sld.w 84[ep], r12\", operands); output_asm_insn (\"sld.w 80[ep], r13\", operands); output_asm_insn (\"sld.w 76[ep], r14\", operands); output_asm_insn (\"sld.w 72[ep], r15\", operands); output_asm_insn (\"sld.w 68[ep], r16\", operands); output_asm_insn (\"sld.w 64[ep], r17\", operands); output_asm_insn (\"sld.w 60[ep], r18\", operands); output_asm_insn (\"sld.w 56[ep], r19\", operands); output_asm_insn (\"sld.w 52[ep], r20\", operands); output_asm_insn (\"sld.w 48[ep], r21\", operands); output_asm_insn (\"sld.w 44[ep], r22\", operands); output_asm_insn (\"sld.w 40[ep], r23\", operands); output_asm_insn (\"sld.w 36[ep], r24\", operands); output_asm_insn (\"sld.w 32[ep], r25\", operands); output_asm_insn (\"sld.w 28[ep], r26\", operands); output_asm_insn (\"sld.w 24[ep], r27\", operands); output_asm_insn (\"sld.w 20[ep], r28\", operands); output_asm_insn (\"sld.w 16[ep], r29\", operands); output_asm_insn (\"mov r1, ep\", operands); output_asm_insn (\"addi 120, sp, sp\", operands); return \"\"; }}" [(set (attr "length") (if_then_else (ne (symbol_ref "TARGET_LONG_CALLS") (const_int 0)) (const_int 4) (const_int 62) )) (set_attr "cc" "clobber")])(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_v850e" [(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)) ] "TARGET_PROLOG_FUNCTION && TARGET_V850E && !TARGET_DISABLE_CALLT" "callt ctoff(__callt_save_r6_r9)" [(set_attr "length" "2") (set_attr "cc" "none")])(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 + -