1/* 2 * QuickThreads -- Threads-building toolkit. 3 * Copyright (c) 1993 by David Keppel 4 * 5 * Permission to use, copy, modify and distribute this software and 6 * its documentation for any purpose and without fee is hereby 7 * granted, provided that the above copyright notice and this notice 8 * appear in all copies. This software is provided as a 9 * proof-of-concept and for demonstration purposes; there is no 10 * representation about the suitability of this software for any 11 * purpose. 12 */ 13 14#ifndef QUICKTHREADS_SPARC_H 15#define QUICKTHREADS_SPARC_H 16 17typedef unsigned long qt_word_t; 18 19/* Stack layout on the sparc: 20 21 non-varargs: 22 23 +--- 24 | <blank space for alignment> 25 | %o7 == return address -> qt_start 26 | %i7 27 | %i6 == frame pointer -> 0 (NULL-terminated stack frame chain) 28 | %i5 -> only 29 | %i4 -> userf 30 | %i3 31 | %i2 -> pt 32 | %i1 -> pu 33 | %i0 34 | %l7 35 | %l6 36 | %l5 37 | %l4 38 | %l3 39 | %l2 40 | %l1 41 | %l0 <--- qt_t.sp 42 +--- 43 44 varargs: 45 46 | : 47 | : 48 | argument list 49 | one-word aggregate return pointer 50 +--- 51 | <blank space for alignment> 52 | %o7 == return address -> qt_vstart 53 | %i7 54 | %i6 == frame pointer -> 0 (NULL-terminated stack frame chain) 55 | %i5 -> startup 56 | %i4 -> userf 57 | %i3 -> cleanup 58 | %i2 -> pt 59 | %i1 60 | %i0 61 | %l7 62 | %l6 63 | %l5 64 | %l4 65 | %l3 66 | %l2 67 | %l1 68 | %l0 <--- qt_t.sp 69 +--- 70 71 */ 72 73 74/* What to do to start a thread running. */ 75extern void qt_start (void); 76extern void qt_vstart (void); 77 78 79/* Hold 17 saved registers + 1 word for alignment. */ 80#define QUICKTHREADS_STKBASE (18 * 4) 81#define QUICKTHREADS_VSTKBASE QUICKTHREADS_STKBASE 82 83 84/* Stack must be doubleword aligned. */ 85#define QUICKTHREADS_STKALIGN (8) /* Doubleword aligned. */ 86 87#define QUICKTHREADS_ONLY_INDEX (QUICKTHREADS_I5) 88#define QUICKTHREADS_USER_INDEX (QUICKTHREADS_I4) 89#define QUICKTHREADS_ARGT_INDEX (QUICKTHREADS_I2) 90#define QUICKTHREADS_ARGU_INDEX (QUICKTHREADS_I1) 91 92#define QUICKTHREADS_VSTARTUP_INDEX (QUICKTHREADS_I5) 93#define QUICKTHREADS_VUSERF_INDEX (QUICKTHREADS_I4) 94#define QUICKTHREADS_VCLEANUP_INDEX (QUICKTHREADS_I3) 95#define QUICKTHREADS_VARGT_INDEX (QUICKTHREADS_I2) 96 97#define QUICKTHREADS_O7 (16) 98#define QUICKTHREADS_I6 (14) 99#define QUICKTHREADS_I5 (13) 100#define QUICKTHREADS_I4 (12) 101#define QUICKTHREADS_I3 (11) 102#define QUICKTHREADS_I2 (10) 103#define QUICKTHREADS_I1 ( 9) 104 105 106/* The thread will ``return'' to the `qt_start' routine to get things 107 going. The normal return sequence takes us to QUICKTHREADS_O7+8, so we 108 pre-subtract 8. The frame pointer chain is 0-terminated to prevent 109 the trap handler from chasing off in to random memory when flushing 110 stack windows. */ 111 112#define QUICKTHREADS_ARGS_MD(top) \ 113 (QUICKTHREADS_SPUT ((top), QUICKTHREADS_O7, ((void *)(((int)qt_start)-8))), \ 114 QUICKTHREADS_SPUT ((top), QUICKTHREADS_I6, 0)) 115 116 117/* The varargs startup routine always reads 6 words of arguments 118 (6 argument registers) from the stack, offset by one word to 119 allow for an aggregate return area pointer. If the varargs 120 routine actually pushed fewer words than that, qt_vstart could read 121 off the top of the stack. To prevent errors, we always allocate 8 122 words. The space is often just wasted. */ 123 124#define QUICKTHREADS_VARGS_MD0(sp, vabytes) \ 125 ((qt_t *)(((char *)(sp)) - 8*4 - QUICKTHREADS_STKROUNDUP(vabytes))) 126 127#define QUICKTHREADS_VARGS_MD1(sp) \ 128 (QUICKTHREADS_SPUT (sp, QUICKTHREADS_O7, ((void *)(((int)qt_vstart)-8)))) 129 130/* The SPARC has wierdo calling conventions which stores a hidden 131 parameter for returning aggregate values, so the rest of the 132 parameters are shoved up the stack by one place. */ 133#define QUICKTHREADS_VARGS_ADJUST(sp) (((char *)sp)+4) 134 135#define QUICKTHREADS_VARGS_DEFAULT 136 137 138#define QUICKTHREADS_GROW_DOWN 139 140#endif /* ndef QUICKTHREADS_SPARC_H */ 141