| /* | |
| * 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_SPARC_H | |
| #define QUICKTHREADS_SPARC_H | |
| typedef unsigned long qt_word_t; | |
| /* Stack layout on the sparc: | |
| non-varargs: | |
| +--- | |
| | <blank space for alignment> | |
| | %o7 == return address -> qt_start | |
| | %i7 | |
| | %i6 == frame pointer -> 0 (NULL-terminated stack frame chain) | |
| | %i5 -> only | |
| | %i4 -> userf | |
| | %i3 | |
| | %i2 -> pt | |
| | %i1 -> pu | |
| | %i0 | |
| | %l7 | |
| | %l6 | |
| | %l5 | |
| | %l4 | |
| | %l3 | |
| | %l2 | |
| | %l1 | |
| | %l0 <--- qt_t.sp | |
| +--- | |
| varargs: | |
| | : | |
| | : | |
| | argument list | |
| | one-word aggregate return pointer | |
| +--- | |
| | <blank space for alignment> | |
| | %o7 == return address -> qt_vstart | |
| | %i7 | |
| | %i6 == frame pointer -> 0 (NULL-terminated stack frame chain) | |
| | %i5 -> startup | |
| | %i4 -> userf | |
| | %i3 -> cleanup | |
| | %i2 -> pt | |
| | %i1 | |
| | %i0 | |
| | %l7 | |
| | %l6 | |
| | %l5 | |
| | %l4 | |
| | %l3 | |
| | %l2 | |
| | %l1 | |
| | %l0 <--- qt_t.sp | |
| +--- | |
| */ | |
| /* What to do to start a thread running. */ | |
| extern void qt_start (void); | |
| extern void qt_vstart (void); | |
| /* Hold 17 saved registers + 1 word for alignment. */ | |
| #define QUICKTHREADS_STKBASE (18 * 4) | |
| #define QUICKTHREADS_VSTKBASE QUICKTHREADS_STKBASE | |
| /* Stack must be doubleword aligned. */ | |
| #define QUICKTHREADS_STKALIGN (8) /* Doubleword aligned. */ | |
| #define QUICKTHREADS_ONLY_INDEX (QUICKTHREADS_I5) | |
| #define QUICKTHREADS_USER_INDEX (QUICKTHREADS_I4) | |
| #define QUICKTHREADS_ARGT_INDEX (QUICKTHREADS_I2) | |
| #define QUICKTHREADS_ARGU_INDEX (QUICKTHREADS_I1) | |
| #define QUICKTHREADS_VSTARTUP_INDEX (QUICKTHREADS_I5) | |
| #define QUICKTHREADS_VUSERF_INDEX (QUICKTHREADS_I4) | |
| #define QUICKTHREADS_VCLEANUP_INDEX (QUICKTHREADS_I3) | |
| #define QUICKTHREADS_VARGT_INDEX (QUICKTHREADS_I2) | |
| #define QUICKTHREADS_O7 (16) | |
| #define QUICKTHREADS_I6 (14) | |
| #define QUICKTHREADS_I5 (13) | |
| #define QUICKTHREADS_I4 (12) | |
| #define QUICKTHREADS_I3 (11) | |
| #define QUICKTHREADS_I2 (10) | |
| #define QUICKTHREADS_I1 ( 9) | |
| /* The thread will ``return'' to the `qt_start' routine to get things | |
| going. The normal return sequence takes us to QUICKTHREADS_O7+8, so we | |
| pre-subtract 8. The frame pointer chain is 0-terminated to prevent | |
| the trap handler from chasing off in to random memory when flushing | |
| stack windows. */ | |
| #define QUICKTHREADS_ARGS_MD(top) \ | |
| (QUICKTHREADS_SPUT ((top), QUICKTHREADS_O7, ((void *)(((int)qt_start)-8))), \ | |
| QUICKTHREADS_SPUT ((top), QUICKTHREADS_I6, 0)) | |
| /* The varargs startup routine always reads 6 words of arguments | |
| (6 argument registers) from the stack, offset by one word to | |
| allow for an aggregate return area pointer. If the varargs | |
| routine actually pushed fewer words than that, qt_vstart could read | |
| off the top of the stack. To prevent errors, we always allocate 8 | |
| words. The space is often just wasted. */ | |
| #define QUICKTHREADS_VARGS_MD0(sp, vabytes) \ | |
| ((qt_t *)(((char *)(sp)) - 8*4 - QUICKTHREADS_STKROUNDUP(vabytes))) | |
| #define QUICKTHREADS_VARGS_MD1(sp) \ | |
| (QUICKTHREADS_SPUT (sp, QUICKTHREADS_O7, ((void *)(((int)qt_vstart)-8)))) | |
| /* The SPARC has wierdo calling conventions which stores a hidden | |
| parameter for returning aggregate values, so the rest of the | |
| parameters are shoved up the stack by one place. */ | |
| #define QUICKTHREADS_VARGS_ADJUST(sp) (((char *)sp)+4) | |
| #define QUICKTHREADS_VARGS_DEFAULT | |
| #define QUICKTHREADS_GROW_DOWN | |
| #endif /* ndef QUICKTHREADS_SPARC_H */ |