112027Sjungma@eit.uni-kl.de/* powerpc_mach.s -- assembly support. */
212027Sjungma@eit.uni-kl.de
312027Sjungma@eit.uni-kl.de/*
412027Sjungma@eit.uni-kl.de * QuickThreads -- Threads-building toolkit.
512027Sjungma@eit.uni-kl.de * Copyright (c) 1993 by David Keppel
612027Sjungma@eit.uni-kl.de *
712027Sjungma@eit.uni-kl.de * Permission to use, copy, modify and distribute this software and
812027Sjungma@eit.uni-kl.de * its documentation for any purpose and without fee is hereby
912027Sjungma@eit.uni-kl.de * granted, provided that the above copyright notice and this notice
1012027Sjungma@eit.uni-kl.de * appear in all copies.  This software is provided as a
1112027Sjungma@eit.uni-kl.de * proof-of-concept and for demonstration purposes; there is no
1212027Sjungma@eit.uni-kl.de * representation about the suitability of this software for any
1312027Sjungma@eit.uni-kl.de * purpose.
1412027Sjungma@eit.uni-kl.de
1512027Sjungma@eit.uni-kl.de
1612027Sjungma@eit.uni-kl.de * PowerPC-Mach thread switching module.
1712027Sjungma@eit.uni-kl.de * Darwin (MacOS X) assembly
1812027Sjungma@eit.uni-kl.de *
1912027Sjungma@eit.uni-kl.de * NOTICE: Syntax for register names is not the GNU one. Register are
2012027Sjungma@eit.uni-kl.de * named "rx" and "fx", not "%rx" and "%fx" as usual for the GNU "as" tool.
2112027Sjungma@eit.uni-kl.de * Darwin "as" tool is based on GNU "as" but follows the "official" PowerPC
2212027Sjungma@eit.uni-kl.de * syntax.
2312027Sjungma@eit.uni-kl.de *
2412027Sjungma@eit.uni-kl.de *
2512027Sjungma@eit.uni-kl.de * This software is largely based on the original PowerPC-Linux porting
2612027Sjungma@eit.uni-kl.de * developed by Ken Aaker <kenaaker@silverbacksystems.com>
2712027Sjungma@eit.uni-kl.de *
2812027Sjungma@eit.uni-kl.de * Marco Bucci <marco.bucci@inwind.it>
2912027Sjungma@eit.uni-kl.de * December 2002
3012027Sjungma@eit.uni-kl.de *
3112027Sjungma@eit.uni-kl.de */
3212027Sjungma@eit.uni-kl.de
3312027Sjungma@eit.uni-kl.de
3412027Sjungma@eit.uni-kl.de/*
3512027Sjungma@eit.uni-kl.de *
3612027Sjungma@eit.uni-kl.de * PowerPC Register convections:
3712027Sjungma@eit.uni-kl.de *
3812027Sjungma@eit.uni-kl.de *  r0			volatile
3912027Sjungma@eit.uni-kl.de *  r1			SP
4012027Sjungma@eit.uni-kl.de *  r2			system reserved
4112027Sjungma@eit.uni-kl.de *  r3-r4		volatile for parameter passing and function return
4212027Sjungma@eit.uni-kl.de *  r5-r10		volatile for parameter passing
4312027Sjungma@eit.uni-kl.de *  r11-r12		volatile
4412027Sjungma@eit.uni-kl.de *  r13-r14		non volatile registers
4512027Sjungma@eit.uni-kl.de *  f0			volatile
4612027Sjungma@eit.uni-kl.de *  f1			volatile for parameter passing and function return
4712027Sjungma@eit.uni-kl.de *  f2-f13		volatile for parameter passing
4812027Sjungma@eit.uni-kl.de *  f14-f31		non volatile
4912027Sjungma@eit.uni-kl.de *
5012027Sjungma@eit.uni-kl.de *  cr2-cr4		non volatile
5112027Sjungma@eit.uni-kl.de *
5212027Sjungma@eit.uni-kl.de *
5312027Sjungma@eit.uni-kl.de * See on the heather file for more documentation.
5412027Sjungma@eit.uni-kl.de *
5512027Sjungma@eit.uni-kl.de *
5612027Sjungma@eit.uni-kl.de *
5712027Sjungma@eit.uni-kl.de * IMPLEMENTATION NOTES
5812027Sjungma@eit.uni-kl.de *
5912027Sjungma@eit.uni-kl.de *
6012027Sjungma@eit.uni-kl.de * 1) Condition register saving
6112027Sjungma@eit.uni-kl.de * On most machines, the condition code register is caller-save.
6212027Sjungma@eit.uni-kl.de * On the PPC, the condition code register is callee-save, so the
6312027Sjungma@eit.uni-kl.de * thread context switch must preserve it.
6412027Sjungma@eit.uni-kl.de *
6512027Sjungma@eit.uni-kl.de *
6612027Sjungma@eit.uni-kl.de * 2) Floating point registers saving
6712027Sjungma@eit.uni-kl.de * On resuming a thread, floating point registers are or not restored just
6812027Sjungma@eit.uni-kl.de * depending on which block routine suspended the thread (i.e. regardless
6912027Sjungma@eit.uni-kl.de * whether "qt_block", "qt_blocki" or "qt_abort" is used to resume it).
7012027Sjungma@eit.uni-kl.de * This behaviour is obtained by implementing "qt_block" by means af a nested
7112027Sjungma@eit.uni-kl.de * call to "qt_blocki". As a result, the blocking of a thread always goes
7212027Sjungma@eit.uni-kl.de * and returns through "qt_blocki and, if a thread was blocked by "qt_block",
7312027Sjungma@eit.uni-kl.de * its execution resumes from the floating point restoring code on exit
7412027Sjungma@eit.uni-kl.de * of "qt_block".
7512027Sjungma@eit.uni-kl.de *
7612027Sjungma@eit.uni-kl.de * Thanks to David Keppel that explained me this "simple" trick.
7712027Sjungma@eit.uni-kl.de *
7812027Sjungma@eit.uni-kl.de *
7912027Sjungma@eit.uni-kl.de * 3) C languace code debugging
8012027Sjungma@eit.uni-kl.de * This software was developed and debugged using the Metrowerks
8112027Sjungma@eit.uni-kl.de * Code Warrior PPC integrated assembler. It can be still used with the
8212027Sjungma@eit.uni-kl.de * Code Warrior compiler by means of the file "powerpc_mach_asm_debug.c"
8312027Sjungma@eit.uni-kl.de * that include it.
8412027Sjungma@eit.uni-kl.de * In order to avoid "copy and paste" bugs, and make easyer the maintaining,
8512027Sjungma@eit.uni-kl.de * I made the minimal changes, so you can find some strange code as:
8612027Sjungma@eit.uni-kl.de *
8712027Sjungma@eit.uni-kl.de *   #if 0
8812027Sjungma@eit.uni-kl.de *   .if 0
8912027Sjungma@eit.uni-kl.de *      C code here
9012027Sjungma@eit.uni-kl.de *   .endif
9112027Sjungma@eit.uni-kl.de *   #endif
9212027Sjungma@eit.uni-kl.de *
9312027Sjungma@eit.uni-kl.de * This is just to embed some C code that is needed by the Code Warrior
9412027Sjungma@eit.uni-kl.de * integrated assembler.
9512027Sjungma@eit.uni-kl.de *
9612027Sjungma@eit.uni-kl.de *
9712027Sjungma@eit.uni-kl.de * 4) Assembly constants generation
9812027Sjungma@eit.uni-kl.de * Constants used in the assembly code are generated by running
9912027Sjungma@eit.uni-kl.de * the C code in the sequel (commented). It uses the C macros declared in
10012027Sjungma@eit.uni-kl.de * the C heather in order to guarantee that the C interface and the assebly
10112027Sjungma@eit.uni-kl.de * code are "aligned". I avoided the use of an assebler preprocessor since
10212027Sjungma@eit.uni-kl.de * they are not so standard and moreover using macro espressions makes the
10312027Sjungma@eit.uni-kl.de * assembly debugging more difficult.
10412027Sjungma@eit.uni-kl.de *
10512027Sjungma@eit.uni-kl.de *
10612027Sjungma@eit.uni-kl.de
10712027Sjungma@eit.uni-kl.de
10812027Sjungma@eit.uni-kl.de#include <iostream>
10912027Sjungma@eit.uni-kl.de#include "powerpc_mach.h"
11012027Sjungma@eit.uni-kl.de
11112027Sjungma@eit.uni-kl.deint main()
11212027Sjungma@eit.uni-kl.de{
11312027Sjungma@eit.uni-kl.de	using namespace std;
11412027Sjungma@eit.uni-kl.de
11512027Sjungma@eit.uni-kl.de	int i;
11612027Sjungma@eit.uni-kl.de
11712027Sjungma@eit.uni-kl.de	cout << ".set LR_SAVE, " << PPC_LR_SAVE << endl;
11812027Sjungma@eit.uni-kl.de	cout << ".set CR_SAVE, " << PPC_CR_SAVE << endl;
11912027Sjungma@eit.uni-kl.de	cout << ".set BLOCKI_FSIZE, " << QUICKTHREADS_BLOCKI_FRAME_SIZE << endl;
12012027Sjungma@eit.uni-kl.de	cout << ".set BLOCK_FSIZE, " << QUICKTHREADS_BLOCK_FRAME_SIZE << endl;
12112027Sjungma@eit.uni-kl.de
12212027Sjungma@eit.uni-kl.de	cout << endl;
12312027Sjungma@eit.uni-kl.de	for(i=0; i<12; i++)
12412027Sjungma@eit.uni-kl.de	 	cout << ".set PAR_" << i << ", " << PPC_PAR(i) << endl;
12512027Sjungma@eit.uni-kl.de
12612027Sjungma@eit.uni-kl.de	cout << endl;
12712027Sjungma@eit.uni-kl.de	i = 13;
12812027Sjungma@eit.uni-kl.de	cout << ".set GPR_SAVE_" << i << ", " << QUICKTHREADS_BLOCKI_GPR_SAVE(i) << endl;
12912027Sjungma@eit.uni-kl.de
13012027Sjungma@eit.uni-kl.de	cout << endl;
13112027Sjungma@eit.uni-kl.de	for(i=31; i>13; i--)
13212027Sjungma@eit.uni-kl.de	 	cout << ".set FPR_SAVE_" << i << ", " << QUICKTHREADS_BLOCK_FPR_SAVE(i) << endl;
13312027Sjungma@eit.uni-kl.de
13412027Sjungma@eit.uni-kl.de	cout << endl;
13512027Sjungma@eit.uni-kl.de	cout << ".set VARGS_BKOFF, " << QUICKTHREADS_VARGS_BKOFF << endl;
13612027Sjungma@eit.uni-kl.de
13712027Sjungma@eit.uni-kl.de
13812027Sjungma@eit.uni-kl.de	cout << endl << endl << endl;
13912027Sjungma@eit.uni-kl.de
14012027Sjungma@eit.uni-kl.de	for(i=31; i>13; i--)
14112027Sjungma@eit.uni-kl.de	 	cout << "\tstfd\tf" << i << ",FPR_SAVE_" << i << "(r1)" << endl;
14212027Sjungma@eit.uni-kl.de
14312027Sjungma@eit.uni-kl.de	cout << endl;
14412027Sjungma@eit.uni-kl.de	for(i=31; i>13; i--)
14512027Sjungma@eit.uni-kl.de	 	cout << "\tlfd \tf" << i << ",FPR_SAVE_" << i << "(r1)" << endl;
14612027Sjungma@eit.uni-kl.de
14712027Sjungma@eit.uni-kl.de	cout << endl << endl << endl;
14812027Sjungma@eit.uni-kl.de
14912027Sjungma@eit.uni-kl.de
15012027Sjungma@eit.uni-kl.de	return 0;
15112027Sjungma@eit.uni-kl.de}
15212027Sjungma@eit.uni-kl.de
15312027Sjungma@eit.uni-kl.de
15412027Sjungma@eit.uni-kl.de *
15512027Sjungma@eit.uni-kl.de *
15612027Sjungma@eit.uni-kl.de *
15712027Sjungma@eit.uni-kl.de */
15812027Sjungma@eit.uni-kl.de
15912027Sjungma@eit.uni-kl.de
16012027Sjungma@eit.uni-kl.de#if 0
16112027Sjungma@eit.uni-kl.de
16212027Sjungma@eit.uni-kl.de	.text
16312027Sjungma@eit.uni-kl.de	.align 4
16412027Sjungma@eit.uni-kl.de
16512027Sjungma@eit.uni-kl.de	.globl qt_block
16612027Sjungma@eit.uni-kl.de	.globl _qt_block
16712027Sjungma@eit.uni-kl.de	.globl qt_blocki
16812027Sjungma@eit.uni-kl.de	.globl _qt_blocki
16912027Sjungma@eit.uni-kl.de	.globl qt_abort
17012027Sjungma@eit.uni-kl.de	.globl _qt_abort
17112027Sjungma@eit.uni-kl.de	.globl qt_start
17212027Sjungma@eit.uni-kl.de	.globl _qt_start
17312027Sjungma@eit.uni-kl.de	.globl qt_vstart
17412027Sjungma@eit.uni-kl.de	.globl _qt_vstart
17512027Sjungma@eit.uni-kl.de
17612027Sjungma@eit.uni-kl.de
17712027Sjungma@eit.uni-kl.de.set LR_SAVE, 8
17812027Sjungma@eit.uni-kl.de.set CR_SAVE, 4
17912027Sjungma@eit.uni-kl.de.set BLOCKI_FSIZE, 128
18012027Sjungma@eit.uni-kl.de.set BLOCK_FSIZE, 192
18112027Sjungma@eit.uni-kl.de
18212027Sjungma@eit.uni-kl.de.set PAR_0, 24
18312027Sjungma@eit.uni-kl.de.set PAR_1, 28
18412027Sjungma@eit.uni-kl.de.set PAR_2, 32
18512027Sjungma@eit.uni-kl.de.set PAR_3, 36
18612027Sjungma@eit.uni-kl.de.set PAR_4, 40
18712027Sjungma@eit.uni-kl.de.set PAR_5, 44
18812027Sjungma@eit.uni-kl.de.set PAR_6, 48
18912027Sjungma@eit.uni-kl.de.set PAR_7, 52
19012027Sjungma@eit.uni-kl.de.set PAR_8, 56
19112027Sjungma@eit.uni-kl.de.set PAR_9, 60
19212027Sjungma@eit.uni-kl.de.set PAR_10, 64
19312027Sjungma@eit.uni-kl.de.set PAR_11, 68
19412027Sjungma@eit.uni-kl.de
19512027Sjungma@eit.uni-kl.de.set GPR_SAVE_13, 52
19612027Sjungma@eit.uni-kl.de
19712027Sjungma@eit.uni-kl.de.set FPR_SAVE_31, 184
19812027Sjungma@eit.uni-kl.de.set FPR_SAVE_30, 176
19912027Sjungma@eit.uni-kl.de.set FPR_SAVE_29, 168
20012027Sjungma@eit.uni-kl.de.set FPR_SAVE_28, 160
20112027Sjungma@eit.uni-kl.de.set FPR_SAVE_27, 152
20212027Sjungma@eit.uni-kl.de.set FPR_SAVE_26, 144
20312027Sjungma@eit.uni-kl.de.set FPR_SAVE_25, 136
20412027Sjungma@eit.uni-kl.de.set FPR_SAVE_24, 128
20512027Sjungma@eit.uni-kl.de.set FPR_SAVE_23, 120
20612027Sjungma@eit.uni-kl.de.set FPR_SAVE_22, 112
20712027Sjungma@eit.uni-kl.de.set FPR_SAVE_21, 104
20812027Sjungma@eit.uni-kl.de.set FPR_SAVE_20, 96
20912027Sjungma@eit.uni-kl.de.set FPR_SAVE_19, 88
21012027Sjungma@eit.uni-kl.de.set FPR_SAVE_18, 80
21112027Sjungma@eit.uni-kl.de.set FPR_SAVE_17, 72
21212027Sjungma@eit.uni-kl.de.set FPR_SAVE_16, 64
21312027Sjungma@eit.uni-kl.de.set FPR_SAVE_15, 56
21412027Sjungma@eit.uni-kl.de.set FPR_SAVE_14, 48
21512027Sjungma@eit.uni-kl.de
21612027Sjungma@eit.uni-kl.de
21712027Sjungma@eit.uni-kl.de/* various offsets used by "qt_varg" */
21812027Sjungma@eit.uni-kl.de.set P_T, PAR_0
21912027Sjungma@eit.uni-kl.de.set P_STARTUP, PAR_1
22012027Sjungma@eit.uni-kl.de.set P_USERF, PAR_2
22112027Sjungma@eit.uni-kl.de.set P_CLEANUP, PAR_3
22212027Sjungma@eit.uni-kl.de		/* the offset used to move back the linkage area to be adiacent to
22312027Sjungma@eit.uni-kl.de		 * the variant argument list  before  calling "userf(...) */
22412027Sjungma@eit.uni-kl.de.set VARGS_BKOFF, 16		/* skip "t", "startup", "userf" and "cleanup" */
22512027Sjungma@eit.uni-kl.de
22612027Sjungma@eit.uni-kl.de		/* location where "t" and "cleanup" are saved (with respect of
22712027Sjungma@eit.uni-kl.de		 * the stack frame base) */
22812027Sjungma@eit.uni-kl.de.set P_T_SAVE, -4
22912027Sjungma@eit.uni-kl.de.set P_CLEANUP_SAVE, -8
23012027Sjungma@eit.uni-kl.de
23112027Sjungma@eit.uni-kl.de#endif
23212027Sjungma@eit.uni-kl.de
23312027Sjungma@eit.uni-kl.de
23412027Sjungma@eit.uni-kl.de
23512027Sjungma@eit.uni-kl.de/* Block the current thread saving all integer non volatile registers and
23612027Sjungma@eit.uni-kl.de * start a new thread.
23712027Sjungma@eit.uni-kl.de */
23812027Sjungma@eit.uni-kl.de#if 0
23912027Sjungma@eit.uni-kl.de.if 0
24012027Sjungma@eit.uni-kl.de#endif
24112027Sjungma@eit.uni-kl.devoid *qt_blocki (void *helper, void *a0, void *a1, void *newthread);
24212027Sjungma@eit.uni-kl.deasm void *qt_blocki (void *helper, void *a0, void *a1, void *newthread)
24312027Sjungma@eit.uni-kl.de{
24412027Sjungma@eit.uni-kl.de#if 0
24512027Sjungma@eit.uni-kl.de.endif
24612027Sjungma@eit.uni-kl.de#endif
24712027Sjungma@eit.uni-kl.de
24812027Sjungma@eit.uni-kl.de#if 0
24912027Sjungma@eit.uni-kl.deqt_blocki:
25012027Sjungma@eit.uni-kl.de_qt_blocki:
25112027Sjungma@eit.uni-kl.de#endif
25212027Sjungma@eit.uni-kl.de/* prolog code */
25312027Sjungma@eit.uni-kl.de	stwu	r1,-BLOCKI_FSIZE(r1)		/* allocate the stack frame */
25412027Sjungma@eit.uni-kl.de	mflr	r0							/* return addr in r0 */
25512027Sjungma@eit.uni-kl.de	mfcr	r11							/* CR in r11 */
25612027Sjungma@eit.uni-kl.de	stw		r0,LR_SAVE+BLOCKI_FSIZE(r1)	/* save return addr in the stack */
25712027Sjungma@eit.uni-kl.de	stw		r11,CR_SAVE+BLOCKI_FSIZE(r1)	/* save CR in the stack */
25812027Sjungma@eit.uni-kl.de	stmw	r13,GPR_SAVE_13(r1)	 		/* save non-volatile reg */
25912027Sjungma@eit.uni-kl.de
26012027Sjungma@eit.uni-kl.de/* call helper(qt_t *old, void *a0, void *a1) */
26112027Sjungma@eit.uni-kl.de	mtlr	r3				/* "helper" addr in the link reg */
26212027Sjungma@eit.uni-kl.de	mr		r3,r1			/* current thread (i.e. the SP) in arg "old" */
26312027Sjungma@eit.uni-kl.de	mr		r1,r6         	/* swap to the new thread (i.e. to its SP) */
26412027Sjungma@eit.uni-kl.de	blrl								/* jump to "helper" */
26512027Sjungma@eit.uni-kl.de/* the "helper" return value is returned (since r3 is not changed) */
26612027Sjungma@eit.uni-kl.de
26712027Sjungma@eit.uni-kl.de/* epilog code: return to the new thread's "qt_blocki" caller */
26812027Sjungma@eit.uni-kl.de	lmw     r13,GPR_SAVE_13(r1)			/* restore non-volatile reg */
26912027Sjungma@eit.uni-kl.de	lwz		r0,LR_SAVE+BLOCKI_FSIZE(r1)	/* recover return addr */
27012027Sjungma@eit.uni-kl.de	lwz		r11,CR_SAVE+BLOCKI_FSIZE(r1)	/* recover CR */
27112027Sjungma@eit.uni-kl.de	mtlr	r0							/* return address in the link reg */
27212027Sjungma@eit.uni-kl.de	mtcr	r11							/* restore CR */
27312027Sjungma@eit.uni-kl.de	addi    r1,r1,BLOCKI_FSIZE			/* free the stack frame */
27412027Sjungma@eit.uni-kl.de	blr									/* return */
27512027Sjungma@eit.uni-kl.de
27612027Sjungma@eit.uni-kl.de#if 0
27712027Sjungma@eit.uni-kl.de.if 0
27812027Sjungma@eit.uni-kl.de#endif
27912027Sjungma@eit.uni-kl.de}
28012027Sjungma@eit.uni-kl.de#if 0
28112027Sjungma@eit.uni-kl.de.endif
28212027Sjungma@eit.uni-kl.de#endif
28312027Sjungma@eit.uni-kl.de
28412027Sjungma@eit.uni-kl.de
28512027Sjungma@eit.uni-kl.de
28612027Sjungma@eit.uni-kl.de/* Abort the current thread and start a new thread.
28712027Sjungma@eit.uni-kl.de */
28812027Sjungma@eit.uni-kl.de#if 0
28912027Sjungma@eit.uni-kl.de.if 0
29012027Sjungma@eit.uni-kl.de#endif
29112027Sjungma@eit.uni-kl.devoid qt_abort (void *helper, void *a0, void *a1, void *newthread);
29212027Sjungma@eit.uni-kl.deasm void qt_abort (void *helper, void *a0, void *a1, void *newthread)
29312027Sjungma@eit.uni-kl.de{
29412027Sjungma@eit.uni-kl.de#if 0
29512027Sjungma@eit.uni-kl.de.endif
29612027Sjungma@eit.uni-kl.de#endif
29712027Sjungma@eit.uni-kl.de
29812027Sjungma@eit.uni-kl.de#if 0
29912027Sjungma@eit.uni-kl.deqt_abort:
30012027Sjungma@eit.uni-kl.de_qt_abort:
30112027Sjungma@eit.uni-kl.de#endif
30212027Sjungma@eit.uni-kl.de/* prolog code */
30312027Sjungma@eit.uni-kl.de/* there is no prolog. It will never come back */
30412027Sjungma@eit.uni-kl.de
30512027Sjungma@eit.uni-kl.de/* call helper(qt_t *old, void *a0, void *a1) */
30612027Sjungma@eit.uni-kl.de	mtlr	r3					/* "helper" addr in the link reg */
30712027Sjungma@eit.uni-kl.de	mr		r1,r6         		/* swap to the new thread (i.e. to its SP) */
30812027Sjungma@eit.uni-kl.de/* we don't need to set "old", we can pass just garbage. Actually, since r3
30912027Sjungma@eit.uni-kl.de is not changed, "old" is set to "helper" (don't care) */
31012027Sjungma@eit.uni-kl.de	blrl								/* call "helper" */
31112027Sjungma@eit.uni-kl.de/* the "helper" return value is returned (since r3 is not changed) */
31212027Sjungma@eit.uni-kl.de
31312027Sjungma@eit.uni-kl.de/* epilog code: return to the new thread's "qt_blocki" caller */
31412027Sjungma@eit.uni-kl.de	lmw     r13,GPR_SAVE_13(r1)			/* restore non-volatile reg */
31512027Sjungma@eit.uni-kl.de	lwz		r0,LR_SAVE+BLOCKI_FSIZE(r1)	/* recover return addr */
31612027Sjungma@eit.uni-kl.de	lwz		r11,CR_SAVE+BLOCKI_FSIZE(r1)	/* recover CR */
31712027Sjungma@eit.uni-kl.de	mtlr	r0							/* return address in the link reg */
31812027Sjungma@eit.uni-kl.de	mtcr	r11							/* restore CR */
31912027Sjungma@eit.uni-kl.de	addi    r1,r1,BLOCKI_FSIZE			/* free the stack frame */
32012027Sjungma@eit.uni-kl.de	blr									/* return */
32112027Sjungma@eit.uni-kl.de
32212027Sjungma@eit.uni-kl.de#if 0
32312027Sjungma@eit.uni-kl.de.if 0
32412027Sjungma@eit.uni-kl.de#endif
32512027Sjungma@eit.uni-kl.de}
32612027Sjungma@eit.uni-kl.de#if 0
32712027Sjungma@eit.uni-kl.de.endif
32812027Sjungma@eit.uni-kl.de#endif
32912027Sjungma@eit.uni-kl.de
33012027Sjungma@eit.uni-kl.de
33112027Sjungma@eit.uni-kl.de
33212027Sjungma@eit.uni-kl.de/* Block the current thread saving all non volatile registers and start
33312027Sjungma@eit.uni-kl.de * a new thread.
33412027Sjungma@eit.uni-kl.de */
33512027Sjungma@eit.uni-kl.de#if 0
33612027Sjungma@eit.uni-kl.de.if 0
33712027Sjungma@eit.uni-kl.de#endif
33812027Sjungma@eit.uni-kl.devoid *qt_block (void *helper, void *a0, void *a1, void *newthread);
33912027Sjungma@eit.uni-kl.deasm void *qt_block (void *helper, void *a0, void *a1, void *newthread)
34012027Sjungma@eit.uni-kl.de{
34112027Sjungma@eit.uni-kl.de#if 0
34212027Sjungma@eit.uni-kl.de.endif
34312027Sjungma@eit.uni-kl.de#endif
34412027Sjungma@eit.uni-kl.de
34512027Sjungma@eit.uni-kl.de# if 0
34612027Sjungma@eit.uni-kl.deqt_block:
34712027Sjungma@eit.uni-kl.de_qt_block:
34812027Sjungma@eit.uni-kl.de#endif
34912027Sjungma@eit.uni-kl.de/* prolog code */
35012027Sjungma@eit.uni-kl.de	stwu	r1,-BLOCK_FSIZE(r1)			/* allocate the stack frame */
35112027Sjungma@eit.uni-kl.de	mflr	r0							/* return addr in r0 */
35212027Sjungma@eit.uni-kl.de	stw		r0,LR_SAVE+BLOCK_FSIZE(r1)	/* save return addr in the stack */
35312027Sjungma@eit.uni-kl.de
35412027Sjungma@eit.uni-kl.de/* save non-volatile fp reg */
35512027Sjungma@eit.uni-kl.de    stfd    f31,FPR_SAVE_31(r1)
35612027Sjungma@eit.uni-kl.de    stfd    f30,FPR_SAVE_30(r1)
35712027Sjungma@eit.uni-kl.de    stfd    f29,FPR_SAVE_29(r1)
35812027Sjungma@eit.uni-kl.de    stfd    f28,FPR_SAVE_28(r1)
35912027Sjungma@eit.uni-kl.de    stfd    f27,FPR_SAVE_27(r1)
36012027Sjungma@eit.uni-kl.de    stfd    f26,FPR_SAVE_26(r1)
36112027Sjungma@eit.uni-kl.de    stfd    f25,FPR_SAVE_25(r1)
36212027Sjungma@eit.uni-kl.de    stfd    f24,FPR_SAVE_24(r1)
36312027Sjungma@eit.uni-kl.de    stfd    f23,FPR_SAVE_23(r1)
36412027Sjungma@eit.uni-kl.de    stfd    f22,FPR_SAVE_22(r1)
36512027Sjungma@eit.uni-kl.de    stfd    f21,FPR_SAVE_21(r1)
36612027Sjungma@eit.uni-kl.de    stfd    f20,FPR_SAVE_20(r1)
36712027Sjungma@eit.uni-kl.de    stfd    f19,FPR_SAVE_19(r1)
36812027Sjungma@eit.uni-kl.de    stfd    f18,FPR_SAVE_18(r1)
36912027Sjungma@eit.uni-kl.de    stfd    f17,FPR_SAVE_17(r1)
37012027Sjungma@eit.uni-kl.de    stfd    f16,FPR_SAVE_16(r1)
37112027Sjungma@eit.uni-kl.de    stfd    f15,FPR_SAVE_15(r1)
37212027Sjungma@eit.uni-kl.de    stfd    f14,FPR_SAVE_14(r1)
37312027Sjungma@eit.uni-kl.de/* block the thread */
37412027Sjungma@eit.uni-kl.de	bl		qt_blocki
37512027Sjungma@eit.uni-kl.de/* the thread is going to be resumed */
37612027Sjungma@eit.uni-kl.de/* restore non-volatile fp reg */
37712027Sjungma@eit.uni-kl.de    lfd     f31,FPR_SAVE_31(r1)
37812027Sjungma@eit.uni-kl.de    lfd     f30,FPR_SAVE_30(r1)
37912027Sjungma@eit.uni-kl.de    lfd     f29,FPR_SAVE_29(r1)
38012027Sjungma@eit.uni-kl.de    lfd     f28,FPR_SAVE_28(r1)
38112027Sjungma@eit.uni-kl.de    lfd     f27,FPR_SAVE_27(r1)
38212027Sjungma@eit.uni-kl.de    lfd     f26,FPR_SAVE_26(r1)
38312027Sjungma@eit.uni-kl.de    lfd     f25,FPR_SAVE_25(r1)
38412027Sjungma@eit.uni-kl.de    lfd     f24,FPR_SAVE_24(r1)
38512027Sjungma@eit.uni-kl.de    lfd     f23,FPR_SAVE_23(r1)
38612027Sjungma@eit.uni-kl.de    lfd     f22,FPR_SAVE_22(r1)
38712027Sjungma@eit.uni-kl.de    lfd     f21,FPR_SAVE_21(r1)
38812027Sjungma@eit.uni-kl.de    lfd     f20,FPR_SAVE_20(r1)
38912027Sjungma@eit.uni-kl.de    lfd     f19,FPR_SAVE_19(r1)
39012027Sjungma@eit.uni-kl.de    lfd     f18,FPR_SAVE_18(r1)
39112027Sjungma@eit.uni-kl.de    lfd     f17,FPR_SAVE_17(r1)
39212027Sjungma@eit.uni-kl.de    lfd     f16,FPR_SAVE_16(r1)
39312027Sjungma@eit.uni-kl.de    lfd     f15,FPR_SAVE_15(r1)
39412027Sjungma@eit.uni-kl.de    lfd     f14,FPR_SAVE_14(r1)
39512027Sjungma@eit.uni-kl.de
39612027Sjungma@eit.uni-kl.de	lwz		r0,LR_SAVE+BLOCK_FSIZE(r1)	/* recover return addr */
39712027Sjungma@eit.uni-kl.de	mtlr	r0							/* return address in the link reg */
39812027Sjungma@eit.uni-kl.de	addi    r1,r1,BLOCK_FSIZE			/* free the stack frame */
39912027Sjungma@eit.uni-kl.de	blr									/* return */
40012027Sjungma@eit.uni-kl.de
40112027Sjungma@eit.uni-kl.de#if 0
40212027Sjungma@eit.uni-kl.de.if 0
40312027Sjungma@eit.uni-kl.de#endif
40412027Sjungma@eit.uni-kl.de}
40512027Sjungma@eit.uni-kl.de#if 0
40612027Sjungma@eit.uni-kl.de.endif
40712027Sjungma@eit.uni-kl.de#endif
40812027Sjungma@eit.uni-kl.de
40912027Sjungma@eit.uni-kl.de
41012027Sjungma@eit.uni-kl.de
41112027Sjungma@eit.uni-kl.de/* Start a single argument thread using parameters preloaded in the stack
41212027Sjungma@eit.uni-kl.de * during thread initialization (see comments on stack initialization in the
41312027Sjungma@eit.uni-kl.de * heather file).
41412027Sjungma@eit.uni-kl.de *
41512027Sjungma@eit.uni-kl.de * Executes:
41612027Sjungma@eit.uni-kl.de *
41712027Sjungma@eit.uni-kl.de *    only(u, t, userf);
41812027Sjungma@eit.uni-kl.de */
41912027Sjungma@eit.uni-kl.de#if 0
42012027Sjungma@eit.uni-kl.de.if 0
42112027Sjungma@eit.uni-kl.de#endif
42212027Sjungma@eit.uni-kl.devoid qt_start(void);
42312027Sjungma@eit.uni-kl.deasm void qt_start(void)
42412027Sjungma@eit.uni-kl.de{
42512027Sjungma@eit.uni-kl.de#if 0
42612027Sjungma@eit.uni-kl.de.endif
42712027Sjungma@eit.uni-kl.de#endif
42812027Sjungma@eit.uni-kl.de
42912027Sjungma@eit.uni-kl.de#if 0
43012027Sjungma@eit.uni-kl.deqt_start:
43112027Sjungma@eit.uni-kl.de_qt_start:
43212027Sjungma@eit.uni-kl.de#endif
43312027Sjungma@eit.uni-kl.de        lwz     r3,PAR_0(r1)	     	/* "u" in r3 */
43412027Sjungma@eit.uni-kl.de        lwz     r4,PAR_1(r1)	     	/* "t" in r4 */
43512027Sjungma@eit.uni-kl.de        lwz     r5,PAR_2(r1)	     	/* "userf" in r5 */
43612027Sjungma@eit.uni-kl.de        lwz     r6,PAR_3(r1)	     	/* "only" in r6 */
43712027Sjungma@eit.uni-kl.de        mtlr    r6						/* "only" address in the link reg */
43812027Sjungma@eit.uni-kl.de/*  call only(u, t, userf) */
43912027Sjungma@eit.uni-kl.de        blrl                    		/* jump to "only" */
44012027Sjungma@eit.uni-kl.de/* error if it returns */
44112027Sjungma@eit.uni-kl.de        b       _qt_error
44212027Sjungma@eit.uni-kl.de/* dead code (some inline asm "wants" the epilog, or they genetare it) */
44312027Sjungma@eit.uni-kl.de        blr
44412027Sjungma@eit.uni-kl.de
44512027Sjungma@eit.uni-kl.de#if 0
44612027Sjungma@eit.uni-kl.de.if 0
44712027Sjungma@eit.uni-kl.de#endif
44812027Sjungma@eit.uni-kl.de}
44912027Sjungma@eit.uni-kl.de#if 0
45012027Sjungma@eit.uni-kl.de.endif
45112027Sjungma@eit.uni-kl.de#endif
45212027Sjungma@eit.uni-kl.de
45312027Sjungma@eit.uni-kl.de
45412027Sjungma@eit.uni-kl.de
45512027Sjungma@eit.uni-kl.de/* Start a variant argument thread using parameters preloaded in the stack
45612027Sjungma@eit.uni-kl.de * during thread initialization (see comments on stack initialization in the
45712027Sjungma@eit.uni-kl.de * heather file).
45812027Sjungma@eit.uni-kl.de *
45912027Sjungma@eit.uni-kl.de * Executes:
46012027Sjungma@eit.uni-kl.de *
46112027Sjungma@eit.uni-kl.de *    startup(t);
46212027Sjungma@eit.uni-kl.de *    userf_return = userf(...);
46312027Sjungma@eit.uni-kl.de *    cleanup(pt, userf_return);
46412027Sjungma@eit.uni-kl.de *
46512027Sjungma@eit.uni-kl.de
46612027Sjungma@eit.uni-kl.de
46712027Sjungma@eit.uni-kl.de ***** Stack layout on start *****
46812027Sjungma@eit.uni-kl.de
46912027Sjungma@eit.uni-kl.de
47012027Sjungma@eit.uni-kl.de backchain ->           STACK BOTTOM (higher address)
47112027Sjungma@eit.uni-kl.de                        +==========================+
47212027Sjungma@eit.uni-kl.de backchain - 4 ->       |                          |
47312027Sjungma@eit.uni-kl.de                        +   LOCAL VARIABLES AREA   +
47412027Sjungma@eit.uni-kl.de                               ..............
47512027Sjungma@eit.uni-kl.de                        +                          +
47612027Sjungma@eit.uni-kl.de                        |                          |
47712027Sjungma@eit.uni-kl.de                        +--------------------------+
47812027Sjungma@eit.uni-kl.de                        |                          |
47912027Sjungma@eit.uni-kl.de                        +      ALIGNMEBNT PAD      +
48012027Sjungma@eit.uni-kl.de                               ..............
48112027Sjungma@eit.uni-kl.de                        +       (if needed)        +
48212027Sjungma@eit.uni-kl.de                        |                          |
48312027Sjungma@eit.uni-kl.de                        +--------------------------+
48412027Sjungma@eit.uni-kl.de                        |                          | arg(n)
48512027Sjungma@eit.uni-kl.de                        +                          +
48612027Sjungma@eit.uni-kl.de                        |                          |
48712027Sjungma@eit.uni-kl.de                        +  VARIABLE ARGUMENT LIST  +
48812027Sjungma@eit.uni-kl.de                               ..............
48912027Sjungma@eit.uni-kl.de                        +      for userf call      +
49012027Sjungma@eit.uni-kl.de SP + PAR(5) ->         |                          | arg(1)
49112027Sjungma@eit.uni-kl.de                        +                          +
49212027Sjungma@eit.uni-kl.de SP + PAR(4) ->         |                          | arg(0)
49312027Sjungma@eit.uni-kl.de                        +--------------------------+
49412027Sjungma@eit.uni-kl.de SP + PAR(3) ->         |                          | cleanup par
49512027Sjungma@eit.uni-kl.de                        +                          +
49612027Sjungma@eit.uni-kl.de SP + PAR(2) ->         |                          | userf par
49712027Sjungma@eit.uni-kl.de                        +      PARAMETER AREA      +
49812027Sjungma@eit.uni-kl.de SP + PAR(1) ->         |                          | startup par
49912027Sjungma@eit.uni-kl.de                        +                          +
50012027Sjungma@eit.uni-kl.de SP + PAR(0) ->         |                          | t par
50112027Sjungma@eit.uni-kl.de                        +--------------------------+
50212027Sjungma@eit.uni-kl.de                        |                          |
50312027Sjungma@eit.uni-kl.de                        +       LINKAGE AREA       +
50412027Sjungma@eit.uni-kl.de SP ->                  |                          |
50512027Sjungma@eit.uni-kl.de                        +==========================+
50612027Sjungma@eit.uni-kl.de                         STACK TOP (lower address)
50712027Sjungma@eit.uni-kl.de
50812027Sjungma@eit.uni-kl.de                             Stack grows down
50912027Sjungma@eit.uni-kl.de                                     |
51012027Sjungma@eit.uni-kl.de                                     V
51112027Sjungma@eit.uni-kl.de
51212027Sjungma@eit.uni-kl.de
51312027Sjungma@eit.uni-kl.de
51412027Sjungma@eit.uni-kl.de ***** Stack layout before call userf *****
51512027Sjungma@eit.uni-kl.de
51612027Sjungma@eit.uni-kl.de
51712027Sjungma@eit.uni-kl.de backchain ->           STACK BOTTOM (higher address)
51812027Sjungma@eit.uni-kl.de                        +==========================+
51912027Sjungma@eit.uni-kl.de backchain - 4 ->       |                          |
52012027Sjungma@eit.uni-kl.de                        +   LOCAL VARIABLES AREA   +
52112027Sjungma@eit.uni-kl.de                               ..............
52212027Sjungma@eit.uni-kl.de                        +                          +
52312027Sjungma@eit.uni-kl.de                        |                          |
52412027Sjungma@eit.uni-kl.de                        +--------------------------+
52512027Sjungma@eit.uni-kl.de                        |                          |
52612027Sjungma@eit.uni-kl.de                        +      ALIGNMEBNT PAD      +
52712027Sjungma@eit.uni-kl.de                               ..............
52812027Sjungma@eit.uni-kl.de                        +       (if needed)        +
52912027Sjungma@eit.uni-kl.de                        |                          |
53012027Sjungma@eit.uni-kl.de                        +--------------------------+
53112027Sjungma@eit.uni-kl.de                        |                          | arg(n)
53212027Sjungma@eit.uni-kl.de                        +                          +
53312027Sjungma@eit.uni-kl.de                        |                          |
53412027Sjungma@eit.uni-kl.de                        +  VARIABLE ARGUMENT LIST  +
53512027Sjungma@eit.uni-kl.de                               ..............
53612027Sjungma@eit.uni-kl.de                        +      for userf call      +
53712027Sjungma@eit.uni-kl.de SP + PAR(1) ->         |                          | arg(1)
53812027Sjungma@eit.uni-kl.de                        +                          +
53912027Sjungma@eit.uni-kl.de SP + PAR(0) ->         |                          | arg(0)
54012027Sjungma@eit.uni-kl.de                        +--------------------------+
54112027Sjungma@eit.uni-kl.de                        |                          |
54212027Sjungma@eit.uni-kl.de                        +       LINKAGE AREA       +
54312027Sjungma@eit.uni-kl.de SP ->                  |                          |
54412027Sjungma@eit.uni-kl.de                        +==========================+
54512027Sjungma@eit.uni-kl.de                         STACK TOP (lower address)
54612027Sjungma@eit.uni-kl.de
54712027Sjungma@eit.uni-kl.de                             Stack grows down
54812027Sjungma@eit.uni-kl.de                                     |
54912027Sjungma@eit.uni-kl.de                                     V
55012027Sjungma@eit.uni-kl.de
55112027Sjungma@eit.uni-kl.de
55212027Sjungma@eit.uni-kl.de * To call "userf(...)", the argument list must be adiacent to the linkage
55312027Sjungma@eit.uni-kl.de * area. Instead of copy the argument list, we move back the linkage area
55412027Sjungma@eit.uni-kl.de * (actually, we just increase the SP and copy the backchain). "t" and
55512027Sjungma@eit.uni-kl.de * "cleanup" are saved in a local variable area in order to call
55612027Sjungma@eit.uni-kl.de * cleanup(pt, userf_return).
55712027Sjungma@eit.uni-kl.de
55812027Sjungma@eit.uni-kl.de*/
55912027Sjungma@eit.uni-kl.de
56012027Sjungma@eit.uni-kl.de
56112027Sjungma@eit.uni-kl.de#if 0
56212027Sjungma@eit.uni-kl.de.if 0
56312027Sjungma@eit.uni-kl.de#endif
56412027Sjungma@eit.uni-kl.devoid qt_vstart(void);
56512027Sjungma@eit.uni-kl.deasm void qt_vstart(void)
56612027Sjungma@eit.uni-kl.de{
56712027Sjungma@eit.uni-kl.de#if 0
56812027Sjungma@eit.uni-kl.de.endif
56912027Sjungma@eit.uni-kl.de#endif
57012027Sjungma@eit.uni-kl.de
57112027Sjungma@eit.uni-kl.de#if 0
57212027Sjungma@eit.uni-kl.deqt_vstart:
57312027Sjungma@eit.uni-kl.de_qt_vstart:
57412027Sjungma@eit.uni-kl.de#endif
57512027Sjungma@eit.uni-kl.de/* NOTICE: the callee routines could save parameter registers in the caller's
57612027Sjungma@eit.uni-kl.de * stack parameter area. We put "t" in PAR(0) in such a way, if startup(t)
57712027Sjungma@eit.uni-kl.de * will save "t", it will be saved on the same location thus not delething
57812027Sjungma@eit.uni-kl.de * any other parameter.
57912027Sjungma@eit.uni-kl.de */
58012027Sjungma@eit.uni-kl.de
58112027Sjungma@eit.uni-kl.de/* since we will move back the linckage area (to make it adiacent to the
58212027Sjungma@eit.uni-kl.de * parameter list), we need to save "t" and "cleanup". We have made room for
58312027Sjungma@eit.uni-kl.de * this on the bottom of the stack frame. */
58412027Sjungma@eit.uni-kl.de
58512027Sjungma@eit.uni-kl.de/* save parameters in the local variable area */
58612027Sjungma@eit.uni-kl.de	lwz		r11,0(r1)				/* get the backchain */
58712027Sjungma@eit.uni-kl.de 	lwz     r3,P_T(r1)
58812027Sjungma@eit.uni-kl.de 	lwz     r4,P_CLEANUP(r1)
58912027Sjungma@eit.uni-kl.de	stw		r3,P_T_SAVE(r11)		/* save "pt" */
59012027Sjungma@eit.uni-kl.de	stw		r4,P_CLEANUP_SAVE(r11)	/* save "cleanup" */
59112027Sjungma@eit.uni-kl.de
59212027Sjungma@eit.uni-kl.de/* call startup(t) */
59312027Sjungma@eit.uni-kl.de    lwz     r5,P_STARTUP(r1)
59412027Sjungma@eit.uni-kl.de	mtlr    r5
59512027Sjungma@eit.uni-kl.de    blrl                    		/* call "startup" */
59612027Sjungma@eit.uni-kl.de
59712027Sjungma@eit.uni-kl.de/* call userf(...) */
59812027Sjungma@eit.uni-kl.de	lwz		r11,0(r1)				/* reload backchain (r11 is volatile) */
59912027Sjungma@eit.uni-kl.de	lwz		r4,P_USERF(r1)			/* load "userf"  */
60012027Sjungma@eit.uni-kl.de    mtlr    r4
60112027Sjungma@eit.uni-kl.de
60212027Sjungma@eit.uni-kl.de	/* first eight parameter of the variant list must be copyed in
60312027Sjungma@eit.uni-kl.de	 * GPR3-GPR10. There is a four places offset due to "t", "startup",
60412027Sjungma@eit.uni-kl.de	 * userf" and "cleanup" */
60512027Sjungma@eit.uni-kl.de
60612027Sjungma@eit.uni-kl.de	lwz		r3,PAR_4(r1)
60712027Sjungma@eit.uni-kl.de	lwz		r4,PAR_5(r1)
60812027Sjungma@eit.uni-kl.de	lwz		r5,PAR_6(r1)
60912027Sjungma@eit.uni-kl.de	lwz		r6,PAR_7(r1)
61012027Sjungma@eit.uni-kl.de	lwz		r7,PAR_8(r1)
61112027Sjungma@eit.uni-kl.de	lwz		r8,PAR_9(r1)
61212027Sjungma@eit.uni-kl.de	lwz		r9,PAR_10(r1)
61312027Sjungma@eit.uni-kl.de	lwz		r10,PAR_11(r1)
61412027Sjungma@eit.uni-kl.de
61512027Sjungma@eit.uni-kl.de
61612027Sjungma@eit.uni-kl.de	/* move the linkage area to be adiacent to the argument list */
61712027Sjungma@eit.uni-kl.de	stw		r11,VARGS_BKOFF(r1)		/* copy backchain */
61812027Sjungma@eit.uni-kl.de	addi	r1,r1,VARGS_BKOFF			/* move back the stack */
61912027Sjungma@eit.uni-kl.de
62012027Sjungma@eit.uni-kl.de	blrl							/* call "userf" */
62112027Sjungma@eit.uni-kl.de
62212027Sjungma@eit.uni-kl.de/* call qt_cleanup(void *pt, void *vuserf_return) */
62312027Sjungma@eit.uni-kl.de	lwz		r11,0(r1)				/* reload backchain (r11 is volatile) */
62412027Sjungma@eit.uni-kl.de
62512027Sjungma@eit.uni-kl.de	mr		r4,r3					/* push "userf" return as 2nd parameter */
62612027Sjungma@eit.uni-kl.de	lwz		r3,P_T_SAVE(r11)		/* reload "pt" */
62712027Sjungma@eit.uni-kl.de	lwz		r5,P_CLEANUP_SAVE(r11)	/* reload "cleanup" */
62812027Sjungma@eit.uni-kl.de	mtlr	r5
62912027Sjungma@eit.uni-kl.de	blrl
63012027Sjungma@eit.uni-kl.de	b       _qt_error
63112027Sjungma@eit.uni-kl.de/* dead code (some inline asm "wanst" the epilog, or they genetare it) */
63212027Sjungma@eit.uni-kl.de	blr
63312027Sjungma@eit.uni-kl.de
63412027Sjungma@eit.uni-kl.de#if 0
63512027Sjungma@eit.uni-kl.de.if 0
63612027Sjungma@eit.uni-kl.de#endif
63712027Sjungma@eit.uni-kl.de}
63812027Sjungma@eit.uni-kl.de#if 0
63912027Sjungma@eit.uni-kl.de.endif
64012027Sjungma@eit.uni-kl.de#endif
64112027Sjungma@eit.uni-kl.de
642