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_AXP_H 00015 #define QUICKTHREADS_AXP_H 00016 00017 #define QUICKTHREADS_GROW_DOWN 00018 00019 typedef unsigned long qt_word_t; 00020 00021 00022 /* Stack layout on the Alpha: 00023 00024 Integer: 00025 00026 Caller-save: r0..r8, r22..r25, r27..r29 00027 argument/caller-save: r16..r21 00028 callee-save: r9..r15 00029 return pc *callee-save*: r26 00030 stack pointer: r30 00031 zero: r31 00032 00033 Floating-point: 00034 00035 Caller-save: f0..f1, f10..f15 00036 argument/caller-save: f16..f21, f22..f30 00037 callee-save: f2..f9 00038 zero: f31 00039 00040 Non-varargs: 00041 00042 +--- 00043 | padding 00044 | f9 00045 | f8 00046 | f7 00047 | f6 00048 | f5 00049 | f4 00050 | f3 00051 | f2 00052 | r26 00053 +--- 00054 | padding 00055 | r29 00056 | r15 00057 | r14 00058 | r13 00059 | r12 on startup === `only' 00060 | r11 on startup === `userf' 00061 | r10 on startup === `qt' 00062 | r9 on startup === `qu' 00063 | r26 on startup === qt_start <--- qt.sp 00064 +--- 00065 00066 Conventions for varargs startup: 00067 00068 | : 00069 | arg6 00070 | iarg5 00071 | : 00072 | iarg0 00073 | farg5 00074 | : 00075 | farg0 00076 +--- 00077 | padding 00078 | r29 00079 | r15 00080 | r14 00081 | r13 00082 | r12 on startup === `startup' 00083 | r11 on startup === `vuserf' 00084 | r10 on startup === `cleanup' 00085 | r9 on startup === `qt' 00086 | r26 on startup === qt_vstart <--- qt.sp 00087 +--- 00088 00089 Note: this is a pretty cheap/sleazy way to get things going, 00090 but ``there must be a better way.'' For instance, some varargs 00091 parameters could be loaded in to integer registers, or the return 00092 address could be stored on top of the stack. */ 00093 00094 00095 /* Stack must be 16-byte aligned. */ 00096 #define QUICKTHREADS_STKALIGN (16) 00097 00098 /* How much space is allocated to hold all the crud for 00099 initialization: 7 registers times 8 bytes/register. */ 00100 00101 #define QUICKTHREADS_STKBASE (10 * 8) 00102 #define QUICKTHREADS_VSTKBASE QUICKTHREADS_STKBASE 00103 00104 00105 /* Offsets of various registers. */ 00106 #define QUICKTHREADS_R26 0 00107 #define QUICKTHREADS_R9 1 00108 #define QUICKTHREADS_R10 2 00109 #define QUICKTHREADS_R11 3 00110 #define QUICKTHREADS_R12 4 00111 00112 00113 /* When a never-before-run thread is restored, the return pc points 00114 to a fragment of code that starts the thread running. For 00115 non-vargs functions, it just calls the client's `only' function. 00116 For varargs functions, it calls the startup, user, and cleanup 00117 functions. 00118 00119 The varargs startup routine always reads 12 8-byte arguments from 00120 the stack. If fewer argumets were pushed, the startup routine 00121 would read off the top of the stack. To prevent errors we always 00122 allocate enough space. When there are fewer args, the preallocated 00123 words are simply wasted. */ 00124 00125 extern void qt_start(void); 00126 #define QUICKTHREADS_ARGS_MD(sp) (QUICKTHREADS_SPUT (sp, QUICKTHREADS_R26, qt_start)) 00127 00128 00129 /* The AXP uses a struct for `va_list', so pass a pointer to the 00130 struct. This may break some uses of `QUICKTHREADS_VARGS', but then we never 00131 claimed it was totally portable. */ 00132 00133 typedef void (qt_function_t)(void); 00134 00135 struct qt_t; 00136 struct va_list; 00137 extern struct qt_t *qt_vargs (struct qt_t *sp, int nbytes, 00138 struct va_list *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, (struct va_list *)(&(vargs)), pt, \ 00145 (qt_function_t *) startup, (qt_function_t *)vuserf, \ 00146 (qt_function_t *)cleanup)); 00147 00148 00149 /* The *index* (positive offset) of where to put each value. */ 00150 #define QUICKTHREADS_ONLY_INDEX (QUICKTHREADS_R12) 00151 #define QUICKTHREADS_USER_INDEX (QUICKTHREADS_R11) 00152 #define QUICKTHREADS_ARGT_INDEX (QUICKTHREADS_R10) 00153 #define QUICKTHREADS_ARGU_INDEX (QUICKTHREADS_R9) 00154 00155 #define QUICKTHREADS_VCLEANUP_INDEX (QUICKTHREADS_R10) 00156 #define QUICKTHREADS_VUSERF_INDEX (QUICKTHREADS_R11) 00157 #define QUICKTHREADS_VSTARTUP_INDEX (QUICKTHREADS_R12) 00158 #define QUICKTHREADS_VARGT_INDEX (QUICKTHREADS_R9) 00159 00160 #endif /* ndef QUICKTHREADS_AXP_H */
1.2.18