00001 /* 00002 * QuickThreads -- Threads-building toolkit. 00003 * Copyright (c) 1993 by David Keppel 00004 * 00005 * Permission to use, copy, modify and distribute this software and 00006 * its documentation for any purpose and without fee is hereby 00007 * granted, provided that the above copyright notice and this notice 00008 * appear in all copies. This software is provided as a 00009 * proof-of-concept and for demonstration purposes; there is no 00010 * representation about the suitability of this software for any 00011 * purpose. 00012 */ 00013 00014 #ifndef QUICKTHREADS_M88K_H 00015 #define QUICKTHREADS_M88K_H 00016 00017 typedef unsigned long qt_word_t; 00018 00019 #define QUICKTHREADS_GROW_DOWN 00020 00021 /* Stack layout on the mips: 00022 00023 Callee-save registers are: $16-$23, $30; $f20-$f30. 00024 Also save $31, return pc. 00025 00026 Non-varargs: 00027 00028 +--- 00029 | r30 (fp) on startup === 0 00030 | r25 00031 | r24 00032 | r23 00033 | r22 00034 | r21 00035 | r20 00036 | r19 00037 | r18 00038 | r17 on startup === `only' 00039 | r16 on startup === `userf' 00040 | r15 on startup === `pt' 00041 | r14 on startup === `pu' 00042 | r1 on startup === `qt_start' 00043 | 0 00044 | 0 00045 +--- 00046 | 0 00047 | ... (8 regs worth === 32 bytes of homing area) 00048 | 0 <--- sp 00049 +--- 00050 00051 Conventions for varargs: 00052 00053 | : 00054 | arg8 00055 +--- 00056 | r30 (fp) arg7 00057 | r25 arg6 00058 | r24 arg5 00059 | r23 arg4 00060 | r22 arg3 00061 | r21 arg2 00062 | r20 arg1 00063 | r19 arg0 00064 | r18 00065 | r17 on startup === `startup' 00066 | r16 on startup === `vuserf' 00067 | r15 on startup === `pt' 00068 | r14 on startup === `cleanup' 00069 | r1 on startup === `qt_vstart' 00070 | 0 00071 | 0 00072 +--- 00073 | 0 00074 | ... (8 regs worth === 32 bytes of homing area) 00075 | 0 <--- sp 00076 +--- 00077 00078 */ 00079 00080 00081 /* Stack must be doubleword aligned. */ 00082 #define QUICKTHREADS_STKALIGN (16) /* Doubleword aligned. */ 00083 00084 /* How much space is allocated to hold all the crud for 00085 initialization: saved registers plus padding to keep the stack 00086 aligned plus 8 words of padding to use as a `homing area' (for 00087 r2-r9) when calling helper functions on the stack of the (not yet 00088 started) thread. The varargs save area is small because it gets 00089 overlapped with the top of the parameter list. In case the 00090 parameter list is less than 8 args, QUICKTHREADS_ARGS_MD0 adds some dead 00091 space at the top of the stack. */ 00092 00093 #define QUICKTHREADS_STKBASE (16*4 + 8*4) 00094 #define QUICKTHREADS_VSTKBASE (8*4 + 8*4) 00095 00096 00097 /* Index of various registers. */ 00098 #define QUICKTHREADS_1 (8+2) 00099 #define QUICKTHREADS_14 (8+3) 00100 #define QUICKTHREADS_15 (8+4) 00101 #define QUICKTHREADS_16 (8+5) 00102 #define QUICKTHREADS_17 (8+6) 00103 #define QUICKTHREADS_30 (8+15) 00104 00105 00106 /* When a never-before-run thread is restored, the return pc points 00107 to a fragment of code that starts the thread running. For 00108 non-vargs functions, it sets up arguments and calls the client's 00109 `only' function. For varargs functions, the startup code calls the 00110 startup, user, and cleanup functions. 00111 00112 For non-varargs functions, we set the frame pointer to 0 to 00113 null-terminate the call chain. 00114 00115 For varargs functions, the frame pointer register is used to hold 00116 one of the arguments, so that all arguments can be laid out in 00117 memory by the conventional `qt_vargs' varargs initialization 00118 routine. 00119 00120 The varargs startup routine always reads 8 words of arguments from 00121 the stack. If there are less than 8 words of arguments, then the 00122 arg list could call off the top of the stack. To prevent fall-off, 00123 always allocate 8 words. */ 00124 00125 extern void qt_start(void); 00126 #define QUICKTHREADS_ARGS_MD(sp) \ 00127 (QUICKTHREADS_SPUT (sp, QUICKTHREADS_1, qt_start), \ 00128 QUICKTHREADS_SPUT (sp, QUICKTHREADS_30, 0)) 00129 00130 00131 /* The m88k uses a struct for `va_list', so pass a pointer to the 00132 struct. */ 00133 00134 typedef void (qt_function_t)(void); 00135 00136 struct qt_t; 00137 extern struct qt_t *qt_vargs (struct qt_t *sp, int nbytes, 00138 void *vargs, void *pt, 00139 qt_function_t *startup, 00140 qt_function_t *vuserf, 00141 qt_function_t *cleanup); 00142 00143 #define QUICKTHREADS_VARGS(sp, nbytes, vargs, pt, startup, vuserf, cleanup) \ 00144 (qt_vargs (sp, nbytes, &(vargs), pt, (qt_function_t *)startup, \ 00145 (qt_function_t *)vuserf, (qt_function_t *)cleanup)) 00146 00147 00148 /* The *index* (positive offset) of where to put each value. */ 00149 #define QUICKTHREADS_ONLY_INDEX (QUICKTHREADS_17) 00150 #define QUICKTHREADS_USER_INDEX (QUICKTHREADS_16) 00151 #define QUICKTHREADS_ARGT_INDEX (QUICKTHREADS_15) 00152 #define QUICKTHREADS_ARGU_INDEX (QUICKTHREADS_14) 00153 00154 #define QUICKTHREADS_VCLEANUP_INDEX (QUICKTHREADS_14) 00155 #define QUICKTHREADS_VUSERF_INDEX (QUICKTHREADS_16) 00156 #define QUICKTHREADS_VSTARTUP_INDEX (QUICKTHREADS_17) 00157 #define QUICKTHREADS_VARGT_INDEX (QUICKTHREADS_15) 00158 00159 #endif /* ndef QUICKTHREADS_M88K_H */
1.2.18