📄 powerpc_sys5.s
字号:
.if 0#endif}#if 0.endif#endif/* Block the current thread saving all non volatile registers and start * a new thread. */#if 0.if 0#endifvoid *qt_block (void *helper, void *a0, void *a1, void *newthread);asm void *qt_block (void *helper, void *a0, void *a1, void *newthread){#if 0.endif#endif# if 0qt_block:_qt_block:#endif/* prolog code */ stwu %r1,-BLOCK_FSIZE(%r1) /* allocate the stack frame */ mflr %r0 /* return addr in r0 */ stw %r0,LR_SAVE+BLOCK_FSIZE(%r1) /* save return addr in the stack *//* save non-volatile fp reg */ stfd %f31,FPR_SAVE_31(%r1) stfd %f30,FPR_SAVE_30(%r1) stfd %f29,FPR_SAVE_29(%r1) stfd %f28,FPR_SAVE_28(%r1) stfd %f27,FPR_SAVE_27(%r1) stfd %f26,FPR_SAVE_26(%r1) stfd %f25,FPR_SAVE_25(%r1) stfd %f24,FPR_SAVE_24(%r1) stfd %f23,FPR_SAVE_23(%r1) stfd %f22,FPR_SAVE_22(%r1) stfd %f21,FPR_SAVE_21(%r1) stfd %f20,FPR_SAVE_20(%r1) stfd %f19,FPR_SAVE_19(%r1) stfd %f18,FPR_SAVE_18(%r1) stfd %f17,FPR_SAVE_17(%r1) stfd %f16,FPR_SAVE_16(%r1) stfd %f15,FPR_SAVE_15(%r1) stfd %f14,FPR_SAVE_14(%r1)/* block the thread */ bl qt_blocki/* the thread is going to be resumed *//* restore non-volatile fp reg */ lfd %f31,FPR_SAVE_31(%r1) lfd %f30,FPR_SAVE_30(%r1) lfd %f29,FPR_SAVE_29(%r1) lfd %f28,FPR_SAVE_28(%r1) lfd %f27,FPR_SAVE_27(%r1) lfd %f26,FPR_SAVE_26(%r1) lfd %f25,FPR_SAVE_25(%r1) lfd %f24,FPR_SAVE_24(%r1) lfd %f23,FPR_SAVE_23(%r1) lfd %f22,FPR_SAVE_22(%r1) lfd %f21,FPR_SAVE_21(%r1) lfd %f20,FPR_SAVE_20(%r1) lfd %f19,FPR_SAVE_19(%r1) lfd %f18,FPR_SAVE_18(%r1) lfd %f17,FPR_SAVE_17(%r1) lfd %f16,FPR_SAVE_16(%r1) lfd %f15,FPR_SAVE_15(%r1) lfd %f14,FPR_SAVE_14(%r1) lwz %r0,LR_SAVE+BLOCK_FSIZE(%r1) /* recover return addr */ mtlr %r0 /* return address in the link reg */ addi %r1,%r1,BLOCK_FSIZE /* free the stack frame */ blr /* return */#if 0.if 0#endif}#if 0.endif#endif /* Start a single argument thread using parameters preloaded in the stack * during thread initialization (see comments on stack initialization in the * heather file). * * Executes: * * only(u, t, userf); */#if 0.if 0#endifvoid qt_start(void);asm void qt_start(void){#if 0.endif#endif#if 0qt_start:_qt_start:#endif lwz %r3,PAR_0(%r1) /* "u" in r3 */ lwz %r4,PAR_1(%r1) /* "t" in r4 */ lwz %r5,PAR_2(%r1) /* "userf" in r5 */ lwz %r6,PAR_3(%r1) /* "only" in r6 */ mtlr %r6 /* "only" address in the link reg *//* call only(u, t, userf) */ blrl /* jump to "only" *//* error if it returns */ b qt_error/* dead code (some inline asm "wants" the epilog, or they genetare it) */ blr#if 0.if 0#endif}#if 0.endif#endif/* Start a variant argument thread using parameters preloaded in the stack * during thread initialization (see comments on stack initialization in the * heather file). * * Executes: * * startup(t); * userf_return = userf(...); * cleanup(pt, userf_return); * ***** Stack layout on start ***** backchain -> STACK BOTTOM (higher address) +==========================+ backchain - 4 -> | | + LOCAL VARIABLES AREA + .............. + + | | +--------------------------+ | | + ALIGNMEBNT PAD + .............. + (if needed) + | | +--------------------------+ | | arg(n) + + | | + VARIABLE ARGUMENT LIST + .............. + for userf call + SP + PAR(5) -> | | arg(1) + + SP + PAR(4) -> | | arg(0) +--------------------------+ SP + PAR(3) -> | | cleanup par + + SP + PAR(2) -> | | userf par + PARAMETER AREA + SP + PAR(1) -> | | startup par + + SP + PAR(0) -> | | t par +--------------------------+ | | + LINKAGE AREA + SP -> | | +==========================+ STACK TOP (lower address) Stack grows down | V ***** Stack layout before call userf ***** backchain -> STACK BOTTOM (higher address) +==========================+ backchain - 4 -> | | + LOCAL VARIABLES AREA + .............. + + | | +--------------------------+ | | + ALIGNMEBNT PAD + .............. + (if needed) + | | +--------------------------+ | | arg(n) + + | | + VARIABLE ARGUMENT LIST + .............. + for userf call + SP + PAR(1) -> | | arg(1) + + SP + PAR(0) -> | | arg(0) +--------------------------+ | | + LINKAGE AREA + SP -> | | +==========================+ STACK TOP (lower address) Stack grows down | V * To call "userf(...)", the argument list must be adiacent to the linkage * area. Instead of copy the argument list, we move back the linkage area * (actually, we just increase the SP and copy the backchain). "t" and * "cleanup" are saved in a local variable area in order to call * cleanup(pt, userf_return).*/ #if 0.if 0#endifvoid qt_vstart(void);asm void qt_vstart(void){#if 0.endif#endif#if 0qt_vstart:_qt_vstart:#endif/* NOTICE: the callee routines could save parameter registers in the caller's * stack parameter area. We put "t" in PAR(0) in such a way, if startup(t) * will save "t", it will be saved on the same location thus not delething * any other parameter. *//* since we will move back the linckage area (to make it adiacent to the * parameter list), we need to save "t" and "cleanup". We have made room for * this on the bottom of the stack frame. */ /* save parameters in the local variable area */ lwz %r11,0(%r1) /* get the backchain */ lwz %r3,P_T(%r1) lwz %r4,P_CLEANUP(%r1) stw %r3,P_T_SAVE(%r11) /* save "pt" */ stw %r4,P_CLEANUP_SAVE(%r11) /* save "cleanup" */ /* call startup(t) */ lwz %r5,P_STARTUP(%r1) mtlr %r5 blrl /* call "startup" *//* call userf(...) */ lwz %r11,0(%r1) /* reload backchain (r11 is volatile) */ lwz %r4,P_USERF(%r1) /* load "userf" */ mtlr %r4 /* first eight parameter of the variant list must be copyed in * GPR3-GPR10. There is a four places offset due to "t", "startup", * userf" and "cleanup" */ lwz %r3,PAR_4(%r1) lwz %r4,PAR_5(%r1) lwz %r5,PAR_6(%r1) lwz %r6,PAR_7(%r1) lwz %r7,PAR_8(%r1) lwz %r8,PAR_9(%r1) lwz %r9,PAR_10(%r1) lwz %r10,PAR_11(%r1) /* move the linkage area to be adiacent to the argument list */ stw %r11,VARGS_BKOFF(%r1) /* copy backchain */ addi %r1,%r1,VARGS_BKOFF /* move back the stack */ blrl /* call "userf" */ /* call qt_cleanup(void *pt, void *vuserf_return) */ lwz %r11,0(%r1) /* reload backchain (r11 is volatile) */ mr %r4,%r3 /* push "userf" return as 2nd parameter */ lwz %r3,P_T_SAVE(%r11) /* reload "pt" */ lwz %r5,P_CLEANUP_SAVE(%r11) /* reload "cleanup" */ mtlr %r5 blrl b qt_error/* dead code (some inline asm "wants" the epilog, or they genetare it) */ blr#if 0.if 0#endif}#if 0.endif#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -