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