112027Sjungma@eit.uni-kl.de/* m88k.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/* Callee-save r14..r25, r31(sp), r30(fp).  r1 === return pc.
1712027Sjungma@eit.uni-kl.de * Argument registers r2..r9, return value r2..r3.
1812027Sjungma@eit.uni-kl.de *
1912027Sjungma@eit.uni-kl.de * On startup, restore regs so retpc === call to a function to start.
2012027Sjungma@eit.uni-kl.de *
2112027Sjungma@eit.uni-kl.de * We're going to call a function (r2) from within the context switch
2212027Sjungma@eit.uni-kl.de * routine.  Call it on the new thread's stack on behalf of the old
2312027Sjungma@eit.uni-kl.de * thread.
2412027Sjungma@eit.uni-kl.de */
2512027Sjungma@eit.uni-kl.de
2612027Sjungma@eit.uni-kl.de	.globl _qt_block
2712027Sjungma@eit.uni-kl.de	.globl _qt_blocki
2812027Sjungma@eit.uni-kl.de	.globl _qt_abort
2912027Sjungma@eit.uni-kl.de	.globl _qt_start
3012027Sjungma@eit.uni-kl.de	.globl _qt_vstart
3112027Sjungma@eit.uni-kl.de
3212027Sjungma@eit.uni-kl.de	/*
3312027Sjungma@eit.uni-kl.de	** r2: ptr to function to call once curr is suspended
3412027Sjungma@eit.uni-kl.de	**	and control is on r5's stack.
3512027Sjungma@eit.uni-kl.de	** r3: 1'th arg to *r2.
3612027Sjungma@eit.uni-kl.de	** r4: 2'th arg to *r2.
3712027Sjungma@eit.uni-kl.de	** r5: sp of thread to suspend.
3812027Sjungma@eit.uni-kl.de	**
3912027Sjungma@eit.uni-kl.de	** The helper routine returns a value that is passed on as the
4012027Sjungma@eit.uni-kl.de	** return value from the blocking routine.  Since we don't
4112027Sjungma@eit.uni-kl.de	** touch r2 between the helper's return and the end of
4212027Sjungma@eit.uni-kl.de	** function, we get this behavior for free.
4312027Sjungma@eit.uni-kl.de	**
4412027Sjungma@eit.uni-kl.de	** Same entry for integer-only and floating-point, since there
4512027Sjungma@eit.uni-kl.de	** are no separate integer and floating-point registers.
4612027Sjungma@eit.uni-kl.de	**
4712027Sjungma@eit.uni-kl.de	** Each procedure call sets aside a ``home region'' of 8 regs
4812027Sjungma@eit.uni-kl.de	** for r2-r9 for varargs.  For context switches we don't use
4912027Sjungma@eit.uni-kl.de	** the ``home region'' for varargs so use it to save regs.
5012027Sjungma@eit.uni-kl.de	** Allocate 64 bytes of save space -- use 32 bytes of register
5112027Sjungma@eit.uni-kl.de	** save area passed in to us plus 32 bytes we allcated, use
5212027Sjungma@eit.uni-kl.de	** the other 32 bytes for save area for a save area to call
5312027Sjungma@eit.uni-kl.de	** the helper function.
5412027Sjungma@eit.uni-kl.de	*/
5512027Sjungma@eit.uni-kl.de_qt_block:
5612027Sjungma@eit.uni-kl.de_qt_blocki:
5712027Sjungma@eit.uni-kl.de	sub r31, r31,64		/* Allocate reg save space. */
5812027Sjungma@eit.uni-kl.de	st r1, r31,8+32		/* Save callee-save registers. */
5912027Sjungma@eit.uni-kl.de	st r14, r31,12+32
6012027Sjungma@eit.uni-kl.de	st.d r15, r31,16+32
6112027Sjungma@eit.uni-kl.de	st.d r17, r31,24+32
6212027Sjungma@eit.uni-kl.de	st.d r19, r31,32+32
6312027Sjungma@eit.uni-kl.de	st.d r21, r31,40+32
6412027Sjungma@eit.uni-kl.de	st.d r23, r31,48+32
6512027Sjungma@eit.uni-kl.de	st r25, r31,56+32
6612027Sjungma@eit.uni-kl.de	st r30, r31,60+32
6712027Sjungma@eit.uni-kl.de
6812027Sjungma@eit.uni-kl.de_qt_abort:
6912027Sjungma@eit.uni-kl.de	addu r14, r31,0		/* Remember old sp. */
7012027Sjungma@eit.uni-kl.de	addu r31, r5,0		/* Set new sp. */
7112027Sjungma@eit.uni-kl.de	jsr.n r2		/* Call helper. */
7212027Sjungma@eit.uni-kl.de	addu r2, r14,0		/* Pass old sp as an arg0 to helper. */
7312027Sjungma@eit.uni-kl.de
7412027Sjungma@eit.uni-kl.de	ld r1, r31,8+32		/* Restore callee-save registers. */
7512027Sjungma@eit.uni-kl.de	ld r14, r31,12+32
7612027Sjungma@eit.uni-kl.de	ld.d r15, r31,16+32
7712027Sjungma@eit.uni-kl.de	ld.d r17, r31,24+32
7812027Sjungma@eit.uni-kl.de	ld.d r19, r31,32+32
7912027Sjungma@eit.uni-kl.de	ld.d r21, r31,40+32
8012027Sjungma@eit.uni-kl.de	ld.d r23, r31,48+32
8112027Sjungma@eit.uni-kl.de	ld r25, r31,56+32
8212027Sjungma@eit.uni-kl.de	ld r30, r31,60+32
8312027Sjungma@eit.uni-kl.de
8412027Sjungma@eit.uni-kl.de	jmp.n r1		/* Return to new thread's caller. */
8512027Sjungma@eit.uni-kl.de	addu r31, r31,64	/* Free register save space. */
8612027Sjungma@eit.uni-kl.de
8712027Sjungma@eit.uni-kl.de
8812027Sjungma@eit.uni-kl.de	/*
8912027Sjungma@eit.uni-kl.de	** Non-varargs thread startup.
9012027Sjungma@eit.uni-kl.de	** See `m88k.h' for register use conventions.
9112027Sjungma@eit.uni-kl.de	*/
9212027Sjungma@eit.uni-kl.de_qt_start:
9312027Sjungma@eit.uni-kl.de	addu r2, r14,0		/* Set user arg `pu'. */
9412027Sjungma@eit.uni-kl.de	addu r3, r15,0		/* ... user function pt. */
9512027Sjungma@eit.uni-kl.de	jsr.n r17		/* Call `only'. */
9612027Sjungma@eit.uni-kl.de	addu r4, r16,0		/* ... user function userf. */
9712027Sjungma@eit.uni-kl.de
9812027Sjungma@eit.uni-kl.de	bsr _qt_error		/* `only' erroniously returned. */
9912027Sjungma@eit.uni-kl.de
10012027Sjungma@eit.uni-kl.de
10112027Sjungma@eit.uni-kl.de	/*
10212027Sjungma@eit.uni-kl.de	** Varargs thread startup.
10312027Sjungma@eit.uni-kl.de	** See `m88k.h' for register use conventions.
10412027Sjungma@eit.uni-kl.de	**
10512027Sjungma@eit.uni-kl.de	** Call the `startup' function with just argument `pt'.
10612027Sjungma@eit.uni-kl.de	** Then call `vuserf' with 8 register args plus any
10712027Sjungma@eit.uni-kl.de	** stack args.
10812027Sjungma@eit.uni-kl.de	** Then call `cleanup' with `pt' and the return value
10912027Sjungma@eit.uni-kl.de	** from `vuserf'.
11012027Sjungma@eit.uni-kl.de	*/
11112027Sjungma@eit.uni-kl.de_qt_vstart:
11212027Sjungma@eit.uni-kl.de	addu r18, r30,0		/* Remember arg7 to `vuserf'. */
11312027Sjungma@eit.uni-kl.de	addu r30, r0,0		/* Null-terminate call chain. */
11412027Sjungma@eit.uni-kl.de
11512027Sjungma@eit.uni-kl.de	jsr.n r17		/* Call `startup'. */
11612027Sjungma@eit.uni-kl.de	addu r2, r15,0		/* `pt' is arg0 to `startup'. */
11712027Sjungma@eit.uni-kl.de
11812027Sjungma@eit.uni-kl.de	addu r2, r19,0		/* Set arg0. */
11912027Sjungma@eit.uni-kl.de	addu r3, r20,0		/* Set arg1. */
12012027Sjungma@eit.uni-kl.de	addu r4, r21,0		/* Set arg2. */
12112027Sjungma@eit.uni-kl.de	addu r5, r22,0		/* Set arg3. */
12212027Sjungma@eit.uni-kl.de	addu r6, r23,0		/* Set arg4. */
12312027Sjungma@eit.uni-kl.de	addu r7, r24,0		/* Set arg5. */
12412027Sjungma@eit.uni-kl.de	addu r8, r25,0		/* Set arg6. */
12512027Sjungma@eit.uni-kl.de	jsr.n r16		/* Call `vuserf'. */
12612027Sjungma@eit.uni-kl.de	addu r9, r18,0		/* Set arg7. */
12712027Sjungma@eit.uni-kl.de
12812027Sjungma@eit.uni-kl.de	addu r3, r2,0		/* Ret. value is arg1 to `cleanup'. */
12912027Sjungma@eit.uni-kl.de	jsr.n r14		/* Call `cleanup'. */
13012027Sjungma@eit.uni-kl.de	addu r2, r15,0		/* `pt' is arg0 to `cleanup'. */
13112027Sjungma@eit.uni-kl.de
13212027Sjungma@eit.uni-kl.de	bsr _qt_error		/* `cleanup' erroniously returned. */
133