⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 powerpc_mach.s

📁 system C源码 一种替代verilog的语言
💻 S
📖 第 1 页 / 共 2 页
字号:
/* powerpc_mach.s -- assembly support. *//* * QuickThreads -- Threads-building toolkit. * Copyright (c) 1993 by David Keppel * * Permission to use, copy, modify and distribute this software and * its documentation for any purpose and without fee is hereby * granted, provided that the above copyright notice and this notice * appear in all copies.  This software is provided as a * proof-of-concept and for demonstration purposes; there is no * representation about the suitability of this software for any * purpose. * PowerPC-Mach thread switching module. * Darwin (MacOS X) assembly  *  * NOTICE: Syntax for register names is not the GNU one. Register are * named "rx" and "fx", not "%rx" and "%fx" as usual for the GNU "as" tool. * Darwin "as" tool is based on GNU "as" but follows the "official" PowerPC * syntax. * * * This software is largely based on the original PowerPC-Linux porting * developed by Ken Aaker <kenaaker@silverbacksystems.com> * * Marco Bucci <marco.bucci@inwind.it> * December 2002 * *//* *  * PowerPC Register convections: *  *  r0			volatile *  r1			SP *  r2			system reserved *  r3-r4		volatile for parameter passing and function return *  r5-r10		volatile for parameter passing *  r11-r12		volatile *  r13-r14		non volatile registers *  f0			volatile *  f1			volatile for parameter passing and function return	 *  f2-f13		volatile for parameter passing *  f14-f31		non volatile *  *  cr2-cr4		non volatile *  *  * See on the heather file for more documentation. * * *  * IMPLEMENTATION NOTES * * * 1) Condition register saving * On most machines, the condition code register is caller-save. * On the PPC, the condition code register is callee-save, so the * thread context switch must preserve it. *  *  * 2) Floating point registers saving * On resuming a thread, floating point registers are or not restored just * depending on which block routine suspended the thread (i.e. regardless * whether "qt_block", "qt_blocki" or "qt_abort" is used to resume it).  * This behaviour is obtained by implementing "qt_block" by means af a nested * call to "qt_blocki". As a result, the blocking of a thread always goes * and returns through "qt_blocki and, if a thread was blocked by "qt_block", * its execution resumes from the floating point restoring code on exit * of "qt_block". * * Thanks to David Keppel that explained me this "simple" trick. * * * 3) C languace code debugging * This software was developed and debugged using the Metrowerks * Code Warrior PPC integrated assembler. It can be still used with the  * Code Warrior compiler by means of the file "powerpc_mach_asm_debug.c" * that include it. * In order to avoid "copy and paste" bugs, and make easyer the maintaining, * I made the minimal changes, so you can find some strange code as: *  *   #if 0 *   .if 0 *      C code here *   .endif *   #endif * * This is just to embed some C code that is needed by the Code Warrior  * integrated assembler. * * * 4) Assembly constants generation * Constants used in the assembly code are generated by running  * the C code in the sequel (commented). It uses the C macros declared in * the C heather in order to guarantee that the C interface and the assebly * code are "aligned". I avoided the use of an assebler preprocessor since * they are not so standard and moreover using macro espressions makes the  * assembly debugging more difficult. * *#include <iostream>#include "powerpc_mach.h"int main(){	using namespace std;		int i;		cout << ".set LR_SAVE, " << PPC_LR_SAVE << endl;	cout << ".set CR_SAVE, " << PPC_CR_SAVE << endl;	cout << ".set BLOCKI_FSIZE, " << QUICKTHREADS_BLOCKI_FRAME_SIZE << endl;	cout << ".set BLOCK_FSIZE, " << QUICKTHREADS_BLOCK_FRAME_SIZE << endl;	cout << endl;	for(i=0; i<12; i++)	 	cout << ".set PAR_" << i << ", " << PPC_PAR(i) << endl;	cout << endl;	i = 13;	cout << ".set GPR_SAVE_" << i << ", " << QUICKTHREADS_BLOCKI_GPR_SAVE(i) << endl;	cout << endl;	for(i=31; i>13; i--)	 	cout << ".set FPR_SAVE_" << i << ", " << QUICKTHREADS_BLOCK_FPR_SAVE(i) << endl;	cout << endl;	cout << ".set VARGS_BKOFF, " << QUICKTHREADS_VARGS_BKOFF << endl;		cout << endl << endl << endl;		for(i=31; i>13; i--)	 	cout << "\tstfd\tf" << i << ",FPR_SAVE_" << i << "(r1)" << endl;	 		cout << endl;	for(i=31; i>13; i--)	 	cout << "\tlfd \tf" << i << ",FPR_SAVE_" << i << "(r1)" << endl;	 		cout << endl << endl << endl;				return 0;} * * * */	#if 0	.text	.align 4		.globl qt_block	.globl _qt_block	.globl qt_blocki	.globl _qt_blocki	.globl qt_abort	.globl _qt_abort	.globl qt_start	.globl _qt_start	.globl qt_vstart	.globl _qt_vstart.set LR_SAVE, 8.set CR_SAVE, 4.set BLOCKI_FSIZE, 128.set BLOCK_FSIZE, 192.set PAR_0, 24.set PAR_1, 28.set PAR_2, 32.set PAR_3, 36.set PAR_4, 40.set PAR_5, 44.set PAR_6, 48.set PAR_7, 52.set PAR_8, 56.set PAR_9, 60.set PAR_10, 64.set PAR_11, 68.set GPR_SAVE_13, 52.set FPR_SAVE_31, 184.set FPR_SAVE_30, 176.set FPR_SAVE_29, 168.set FPR_SAVE_28, 160.set FPR_SAVE_27, 152.set FPR_SAVE_26, 144.set FPR_SAVE_25, 136.set FPR_SAVE_24, 128.set FPR_SAVE_23, 120.set FPR_SAVE_22, 112.set FPR_SAVE_21, 104.set FPR_SAVE_20, 96.set FPR_SAVE_19, 88.set FPR_SAVE_18, 80.set FPR_SAVE_17, 72.set FPR_SAVE_16, 64.set FPR_SAVE_15, 56.set FPR_SAVE_14, 48/* various offsets used by "qt_varg" */.set P_T, PAR_0.set P_STARTUP, PAR_1.set P_USERF, PAR_2.set P_CLEANUP, PAR_3		/* the offset used to move back the linkage area to be adiacent to		 * the variant argument list  before  calling "userf(...) */.set VARGS_BKOFF, 16		/* skip "t", "startup", "userf" and "cleanup" */		/* location where "t" and "cleanup" are saved (with respect of		 * the stack frame base) */.set P_T_SAVE, -4.set P_CLEANUP_SAVE, -8#endif/* Block the current thread saving all integer non volatile registers and * start a new thread. */#if 0.if 0#endifvoid *qt_blocki (void *helper, void *a0, void *a1, void *newthread);asm void *qt_blocki (void *helper, void *a0, void *a1, void *newthread){#if 0.endif#endif#if 0qt_blocki:_qt_blocki:#endif/* prolog code */	stwu	r1,-BLOCKI_FSIZE(r1)		/* allocate the stack frame */	mflr	r0							/* return addr in r0 */	mfcr	r11							/* CR in r11 */	stw		r0,LR_SAVE+BLOCKI_FSIZE(r1)	/* save return addr in the stack */	stw		r11,CR_SAVE+BLOCKI_FSIZE(r1)	/* save CR in the stack */	stmw	r13,GPR_SAVE_13(r1)	 		/* save non-volatile reg *//* call helper(qt_t *old, void *a0, void *a1) */	mtlr	r3				/* "helper" addr in the link reg */	mr		r3,r1			/* current thread (i.e. the SP) in arg "old" */	mr		r1,r6         	/* swap to the new thread (i.e. to its SP) */	blrl								/* jump to "helper" *//* the "helper" return value is returned (since r3 is not changed) *//* epilog code: return to the new thread's "qt_blocki" caller */	lmw     r13,GPR_SAVE_13(r1)			/* restore non-volatile reg */	lwz		r0,LR_SAVE+BLOCKI_FSIZE(r1)	/* recover return addr */	lwz		r11,CR_SAVE+BLOCKI_FSIZE(r1)	/* recover CR */	mtlr	r0							/* return address in the link reg */	mtcr	r11							/* restore CR */	addi    r1,r1,BLOCKI_FSIZE			/* free the stack frame */	blr									/* return */#if 0.if 0#endif}#if 0.endif#endif/* Abort the current thread and start a new thread. */#if 0.if 0#endifvoid qt_abort (void *helper, void *a0, void *a1, void *newthread);asm void qt_abort (void *helper, void *a0, void *a1, void *newthread){#if 0.endif#endif#if 0qt_abort:_qt_abort:#endif/* prolog code *//* there is no prolog. It will never come back *//* call helper(qt_t *old, void *a0, void *a1) */	mtlr	r3					/* "helper" addr in the link reg */	mr		r1,r6         		/* swap to the new thread (i.e. to its SP) *//* we don't need to set "old", we can pass just garbage. Actually, since r3 is not changed, "old" is set to "helper" (don't care) */	blrl								/* call "helper" *//* the "helper" return value is returned (since r3 is not changed) *//* epilog code: return to the new thread's "qt_blocki" caller */	lmw     r13,GPR_SAVE_13(r1)			/* restore non-volatile reg */	lwz		r0,LR_SAVE+BLOCKI_FSIZE(r1)	/* recover return addr */	lwz		r11,CR_SAVE+BLOCKI_FSIZE(r1)	/* recover CR */	mtlr	r0							/* return address in the link reg */	mtcr	r11							/* restore CR */	addi    r1,r1,BLOCKI_FSIZE			/* free the stack frame */	blr									/* return */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -