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_MIPS_H 00015 #define QUICKTHREADS_MIPS_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 | $f30 The first clump is only saved if `qt_block' 00030 | $f28 is called, in which case it saves the fp regs 00031 | $f26 then calls `qt_blocki' to save the int regs. 00032 | $f24 00033 | $f22 00034 | $f20 00035 | $31 === return pc in `qt_block' 00036 +--- 00037 | $31 === return pc; on startup == qt_start 00038 | $30 00039 | $23 00040 | $22 00041 | $21 00042 | $20 00043 | $19 on startup === only 00044 | $18 on startup === $a2 === userf 00045 | $17 on startup === $a1 === pt 00046 | $16 on startup === $a0 === pu 00047 | <a3> save area req'd by MIPS calling convention 00048 | <a2> save area req'd by MIPS calling convention 00049 | <a1> save area req'd by MIPS calling convention 00050 | <a0> save area req'd by MIPS calling convention <--- sp 00051 +--- 00052 00053 Conventions for varargs: 00054 00055 | args ... 00056 +--- 00057 | : 00058 | : 00059 | $21 00060 | $20 00061 | $19 on startup === `userf' 00062 | $18 on startup === `startup' 00063 | $17 on startup === `pt' 00064 | $16 on startup === `cleanup' 00065 | <a3> 00066 | <a2> 00067 | <a1> 00068 | <a0> <--- sp 00069 +--- 00070 00071 Note: if we wanted to, we could muck about and try to get the 4 00072 argument registers loaded in to, e.g., $22, $23, $30, and $31, 00073 and the return pc in, say, $20. Then, the first 4 args would 00074 not need to be loaded from memory, they could just use 00075 register-to-register copies. */ 00076 00077 00078 /* Stack must be doubleword aligned. */ 00079 #define QUICKTHREADS_STKALIGN (8) /* Doubleword aligned. */ 00080 00081 /* How much space is allocated to hold all the crud for 00082 initialization: $16-$23, $30, $31. Just do an integer restore, 00083 no need to restore floating-point. Four words are needed for the 00084 argument save area for the helper function that will be called for 00085 the old thread, just before the new thread starts to run. */ 00086 00087 #define QUICKTHREADS_STKBASE (14 * 4) 00088 #define QUICKTHREADS_VSTKBASE QUICKTHREADS_STKBASE 00089 00090 00091 /* Offsets of various registers. */ 00092 #define QUICKTHREADS_31 (9+4) 00093 #define QUICKTHREADS_19 (3+4) 00094 #define QUICKTHREADS_18 (2+4) 00095 #define QUICKTHREADS_17 (1+4) 00096 #define QUICKTHREADS_16 (0+4) 00097 00098 00099 /* When a never-before-run thread is restored, the return pc points 00100 to a fragment of code that starts the thread running. For 00101 non-vargs functions, it just calls the client's `only' function. 00102 For varargs functions, it calls the startup, user, and cleanup 00103 functions. 00104 00105 The varargs startup routine always reads 4 words of arguments from 00106 the stack. If there are less than 4 words of arguments, then the 00107 startup routine can read off the top of the stack. To prevent 00108 errors we always allocate 4 words. If there are more than 3 words 00109 of arguments, the 4 preallocated words are simply wasted. */ 00110 00111 extern void qt_start(void); 00112 #define QUICKTHREADS_ARGS_MD(sp) (QUICKTHREADS_SPUT (sp, QUICKTHREADS_31, qt_start)) 00113 00114 #define QUICKTHREADS_VARGS_MD0(sp, vabytes) \ 00115 ((qt_t *)(((char *)(sp)) - 4*4 - QUICKTHREADS_STKROUNDUP(vabytes))) 00116 00117 extern void qt_vstart(void); 00118 #define QUICKTHREADS_VARGS_MD1(sp) (QUICKTHREADS_SPUT (sp, QUICKTHREADS_31, qt_vstart)) 00119 00120 #define QUICKTHREADS_VARGS_DEFAULT 00121 00122 00123 /* The *index* (positive offset) of where to put each value. */ 00124 #define QUICKTHREADS_ONLY_INDEX (QUICKTHREADS_19) 00125 #define QUICKTHREADS_USER_INDEX (QUICKTHREADS_18) 00126 #define QUICKTHREADS_ARGT_INDEX (QUICKTHREADS_17) 00127 #define QUICKTHREADS_ARGU_INDEX (QUICKTHREADS_16) 00128 00129 #define QUICKTHREADS_VCLEANUP_INDEX (QUICKTHREADS_16) 00130 #define QUICKTHREADS_VUSERF_INDEX (QUICKTHREADS_19) 00131 #define QUICKTHREADS_VSTARTUP_INDEX (QUICKTHREADS_18) 00132 #define QUICKTHREADS_VARGT_INDEX (QUICKTHREADS_17) 00133 00134 #endif /* ndef QUICKTHREADS_MIPS_H */
1.2.18