blob: f9cab53272c48864eed70221c54e643885292513 [file] [log] [blame]
/*
* 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.
*/
#ifndef QUICKTHREADS_M88K_H
#define QUICKTHREADS_M88K_H
typedef unsigned long qt_word_t;
#define QUICKTHREADS_GROW_DOWN
/* Stack layout on the mips:
Callee-save registers are: $16-$23, $30; $f20-$f30.
Also save $31, return pc.
Non-varargs:
+---
| r30 (fp) on startup === 0
| r25
| r24
| r23
| r22
| r21
| r20
| r19
| r18
| r17 on startup === `only'
| r16 on startup === `userf'
| r15 on startup === `pt'
| r14 on startup === `pu'
| r1 on startup === `qt_start'
| 0
| 0
+---
| 0
| ... (8 regs worth === 32 bytes of homing area)
| 0 <--- sp
+---
Conventions for varargs:
| :
| arg8
+---
| r30 (fp) arg7
| r25 arg6
| r24 arg5
| r23 arg4
| r22 arg3
| r21 arg2
| r20 arg1
| r19 arg0
| r18
| r17 on startup === `startup'
| r16 on startup === `vuserf'
| r15 on startup === `pt'
| r14 on startup === `cleanup'
| r1 on startup === `qt_vstart'
| 0
| 0
+---
| 0
| ... (8 regs worth === 32 bytes of homing area)
| 0 <--- sp
+---
*/
/* Stack must be doubleword aligned. */
#define QUICKTHREADS_STKALIGN (16) /* Doubleword aligned. */
/* How much space is allocated to hold all the crud for
initialization: saved registers plus padding to keep the stack
aligned plus 8 words of padding to use as a `homing area' (for
r2-r9) when calling helper functions on the stack of the (not yet
started) thread. The varargs save area is small because it gets
overlapped with the top of the parameter list. In case the
parameter list is less than 8 args, QUICKTHREADS_ARGS_MD0 adds some dead
space at the top of the stack. */
#define QUICKTHREADS_STKBASE (16*4 + 8*4)
#define QUICKTHREADS_VSTKBASE (8*4 + 8*4)
/* Index of various registers. */
#define QUICKTHREADS_1 (8+2)
#define QUICKTHREADS_14 (8+3)
#define QUICKTHREADS_15 (8+4)
#define QUICKTHREADS_16 (8+5)
#define QUICKTHREADS_17 (8+6)
#define QUICKTHREADS_30 (8+15)
/* When a never-before-run thread is restored, the return pc points
to a fragment of code that starts the thread running. For
non-vargs functions, it sets up arguments and calls the client's
`only' function. For varargs functions, the startup code calls the
startup, user, and cleanup functions.
For non-varargs functions, we set the frame pointer to 0 to
null-terminate the call chain.
For varargs functions, the frame pointer register is used to hold
one of the arguments, so that all arguments can be laid out in
memory by the conventional `qt_vargs' varargs initialization
routine.
The varargs startup routine always reads 8 words of arguments from
the stack. If there are less than 8 words of arguments, then the
arg list could call off the top of the stack. To prevent fall-off,
always allocate 8 words. */
extern void qt_start(void);
#define QUICKTHREADS_ARGS_MD(sp) \
(QUICKTHREADS_SPUT (sp, QUICKTHREADS_1, qt_start), \
QUICKTHREADS_SPUT (sp, QUICKTHREADS_30, 0))
/* The m88k uses a struct for `va_list', so pass a pointer to the
struct. */
typedef void (qt_function_t)(void);
struct qt_t;
extern struct qt_t *qt_vargs (struct qt_t *sp, int nbytes,
void *vargs, void *pt,
qt_function_t *startup,
qt_function_t *vuserf,
qt_function_t *cleanup);
#define QUICKTHREADS_VARGS(sp, nbytes, vargs, pt, startup, vuserf, cleanup) \
(qt_vargs (sp, nbytes, &(vargs), pt, (qt_function_t *)startup, \
(qt_function_t *)vuserf, (qt_function_t *)cleanup))
/* The *index* (positive offset) of where to put each value. */
#define QUICKTHREADS_ONLY_INDEX (QUICKTHREADS_17)
#define QUICKTHREADS_USER_INDEX (QUICKTHREADS_16)
#define QUICKTHREADS_ARGT_INDEX (QUICKTHREADS_15)
#define QUICKTHREADS_ARGU_INDEX (QUICKTHREADS_14)
#define QUICKTHREADS_VCLEANUP_INDEX (QUICKTHREADS_14)
#define QUICKTHREADS_VUSERF_INDEX (QUICKTHREADS_16)
#define QUICKTHREADS_VSTARTUP_INDEX (QUICKTHREADS_17)
#define QUICKTHREADS_VARGT_INDEX (QUICKTHREADS_15)
#endif /* ndef QUICKTHREADS_M88K_H */