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