m88k.c revision 12027
112027Sjungma@eit.uni-kl.de/* 212027Sjungma@eit.uni-kl.de * QuickThreads -- Threads-building toolkit. 312027Sjungma@eit.uni-kl.de * Copyright (c) 1993 by David Keppel 412027Sjungma@eit.uni-kl.de * 512027Sjungma@eit.uni-kl.de * Permission to use, copy, modify and distribute this software and 612027Sjungma@eit.uni-kl.de * its documentation for any purpose and without fee is hereby 712027Sjungma@eit.uni-kl.de * granted, provided that the above copyright notice and this notice 812027Sjungma@eit.uni-kl.de * appear in all copies. This software is provided as a 912027Sjungma@eit.uni-kl.de * proof-of-concept and for demonstration purposes; there is no 1012027Sjungma@eit.uni-kl.de * representation about the suitability of this software for any 1112027Sjungma@eit.uni-kl.de * purpose. 1212027Sjungma@eit.uni-kl.de */ 1312027Sjungma@eit.uni-kl.de 1412027Sjungma@eit.uni-kl.de#include <stdarg.h> 1512027Sjungma@eit.uni-kl.de#include "qt.h" 1612027Sjungma@eit.uni-kl.de 1712027Sjungma@eit.uni-kl.de/* Varargs is harder on the m88k. Parameters are saved on the stack as 1812027Sjungma@eit.uni-kl.de something like (stack grows down to low memory; low at bottom of 1912027Sjungma@eit.uni-kl.de picture): 2012027Sjungma@eit.uni-kl.de 2112027Sjungma@eit.uni-kl.de | : 2212027Sjungma@eit.uni-kl.de | arg8 <-- va_list.__va_stk 2312027Sjungma@eit.uni-kl.de +--- 2412027Sjungma@eit.uni-kl.de | : 2512027Sjungma@eit.uni-kl.de +--- 2612027Sjungma@eit.uni-kl.de | arg7 2712027Sjungma@eit.uni-kl.de | : 2812027Sjungma@eit.uni-kl.de | iarg0 <-- va_list.__va_reg 2912027Sjungma@eit.uni-kl.de +--- 3012027Sjungma@eit.uni-kl.de | : 3112027Sjungma@eit.uni-kl.de | va_list { __va_arg, __va_stk, __va_reg } 3212027Sjungma@eit.uni-kl.de | : 3312027Sjungma@eit.uni-kl.de +--- 3412027Sjungma@eit.uni-kl.de 3512027Sjungma@eit.uni-kl.de Here, `va_list.__va_arg' is the number of word-size arguments 3612027Sjungma@eit.uni-kl.de that have already been skipped. Doubles must be double-arligned. 3712027Sjungma@eit.uni-kl.de 3812027Sjungma@eit.uni-kl.de What this means for us is that the user's routine needs to be 3912027Sjungma@eit.uni-kl.de called with an arg list where some of the words in the `__va_stk' 4012027Sjungma@eit.uni-kl.de part of the parameter list have to be promoted to registers. 4112027Sjungma@eit.uni-kl.de 4212027Sjungma@eit.uni-kl.de BUG: doubleword register arguments must be double-aligned. If 4312027Sjungma@eit.uni-kl.de something is passed as an even # arg and used as an odd # arg or 4412027Sjungma@eit.uni-kl.de vice-versa, the code in the called routine (in the new thread) that 4512027Sjungma@eit.uni-kl.de decides how to adjust the index will get it wrong, because it will 4612027Sjungma@eit.uni-kl.de be expect it to be, say, doubleword aligned and it will really be 4712027Sjungma@eit.uni-kl.de singleword aligned. 4812027Sjungma@eit.uni-kl.de 4912027Sjungma@eit.uni-kl.de I'm not sure you can solve this without knowing the types of all 5012027Sjungma@eit.uni-kl.de the arguments. All in all, we never promised varargs would work 5112027Sjungma@eit.uni-kl.de reliably. */ 5212027Sjungma@eit.uni-kl.de 5312027Sjungma@eit.uni-kl.de 5412027Sjungma@eit.uni-kl.de 5512027Sjungma@eit.uni-kl.de#define QUICKTHREADS_VADJ(sp) (((char *)sp) - QUICKTHREADS_VSTKBASE) 5612027Sjungma@eit.uni-kl.de 5712027Sjungma@eit.uni-kl.de/* Always allocate at least enough space for 8 args; waste some space 5812027Sjungma@eit.uni-kl.de at the base of the stack to ensure the startup routine doesn't read 5912027Sjungma@eit.uni-kl.de off the end of the stack. */ 6012027Sjungma@eit.uni-kl.de 6112027Sjungma@eit.uni-kl.de#define QUICKTHREADS_VARGS_MD0(sp, vabytes) \ 6212027Sjungma@eit.uni-kl.de ((qt_t *)(((char *)(sp)) - 8*4 - QUICKTHREADS_STKROUNDUP(vabytes))) 6312027Sjungma@eit.uni-kl.de 6412027Sjungma@eit.uni-kl.deextern void qt_vstart(void); 6512027Sjungma@eit.uni-kl.de#define QUICKTHREADS_VARGS_MD1(sp) (QUICKTHREADS_SPUT (sp, QUICKTHREADS_1, qt_vstart)) 6612027Sjungma@eit.uni-kl.de 6712027Sjungma@eit.uni-kl.de 6812027Sjungma@eit.uni-kl.de struct qt_t * 6912027Sjungma@eit.uni-kl.deqt_vargs (struct qt_t *qsp, int nbytes, void *vargs, 7012027Sjungma@eit.uni-kl.de void *pt, qt_function_t *startup, 7112027Sjungma@eit.uni-kl.de qt_function_t *vuserf, qt_function_t *cleanup) 7212027Sjungma@eit.uni-kl.de{ 7312027Sjungma@eit.uni-kl.de va_list ap; 7412027Sjungma@eit.uni-kl.de int i; 7512027Sjungma@eit.uni-kl.de int n; /* Number of words into original arg list. */ 7612027Sjungma@eit.uni-kl.de qt_word_t *sp; 7712027Sjungma@eit.uni-kl.de int *reg; /* Where to read passed-in-reg args. */ 7812027Sjungma@eit.uni-kl.de int *stk; /* Where to read passed-on-stk args. */ 7912027Sjungma@eit.uni-kl.de 8012027Sjungma@eit.uni-kl.de ap = *(va_list *)vargs; 8112027Sjungma@eit.uni-kl.de qsp = QUICKTHREADS_VARGS_MD0 (qsp, nbytes); 8212027Sjungma@eit.uni-kl.de sp = (qt_word_t *)qsp; 8312027Sjungma@eit.uni-kl.de 8412027Sjungma@eit.uni-kl.de reg = (ap.__va_arg < 8) 8512027Sjungma@eit.uni-kl.de ? &ap.__va_reg[ap.__va_arg] 8612027Sjungma@eit.uni-kl.de : 0; 8712027Sjungma@eit.uni-kl.de stk = &ap.__va_stk[8]; 8812027Sjungma@eit.uni-kl.de n = ap.__va_arg; 8912027Sjungma@eit.uni-kl.de for (i=0; i<nbytes/sizeof(qt_word_t) && n<8; ++i,++n) { 9012027Sjungma@eit.uni-kl.de sp[i] = *reg++; 9112027Sjungma@eit.uni-kl.de } 9212027Sjungma@eit.uni-kl.de for (; i<nbytes/sizeof(qt_word_t); ++i) { 9312027Sjungma@eit.uni-kl.de sp[i] = *stk++; 9412027Sjungma@eit.uni-kl.de } 9512027Sjungma@eit.uni-kl.de 9612027Sjungma@eit.uni-kl.de#ifdef QUICKTHREADS_NDEF 9712027Sjungma@eit.uni-kl.de for (i=0; i<nbytes/sizeof(qt_word_t); ++i) { 9812027Sjungma@eit.uni-kl.de sp[i] = (n < 8) 9912027Sjungma@eit.uni-kl.de ? *reg++ 10012027Sjungma@eit.uni-kl.de : *stk++; 10112027Sjungma@eit.uni-kl.de ++n; 10212027Sjungma@eit.uni-kl.de } 10312027Sjungma@eit.uni-kl.de#endif 10412027Sjungma@eit.uni-kl.de 10512027Sjungma@eit.uni-kl.de QUICKTHREADS_VARGS_MD1 (QUICKTHREADS_VADJ(sp)); 10612027Sjungma@eit.uni-kl.de QUICKTHREADS_SPUT (QUICKTHREADS_VADJ(sp), QUICKTHREADS_VARGT_INDEX, pt); 10712027Sjungma@eit.uni-kl.de QUICKTHREADS_SPUT (QUICKTHREADS_VADJ(sp), QUICKTHREADS_VSTARTUP_INDEX, startup); 10812027Sjungma@eit.uni-kl.de QUICKTHREADS_SPUT (QUICKTHREADS_VADJ(sp), QUICKTHREADS_VUSERF_INDEX, vuserf); 10912027Sjungma@eit.uni-kl.de QUICKTHREADS_SPUT (QUICKTHREADS_VADJ(sp), QUICKTHREADS_VCLEANUP_INDEX, cleanup); 11012027Sjungma@eit.uni-kl.de return ((qt_t *)QUICKTHREADS_VADJ(sp)); 11112027Sjungma@eit.uni-kl.de} 112