]> git.donarmstrong.com Git - lilypond.git/blob - guile18/qt/md/m88k.h
Import guile-1.8 as multiple upstream tarball component
[lilypond.git] / guile18 / qt / md / m88k.h
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 QT_M88K_H
15 #define QT_M88K_H
16
17 typedef unsigned long qt_word_t;
18
19 #define QT_GROW_DOWN
20
21 /* Stack layout on the mips:
22
23    Callee-save registers are: $16-$23, $30; $f20-$f30.
24    Also save $31, return pc.
25
26    Non-varargs:
27
28    +---
29    | r30 (fp)   on startup === 0
30    | r25
31    | r24
32    | r23
33    | r22
34    | r21
35    | r20
36    | r19
37    | r18
38    | r17        on startup === `only'
39    | r16        on startup === `userf'
40    | r15        on startup === `pt'
41    | r14        on startup === `pu'
42    | r1         on startup === `qt_start'
43    | 0
44    | 0
45    +---
46    | 0
47    | ... (8 regs worth === 32 bytes of homing area)
48    | 0                                          <--- sp
49    +---
50
51    Conventions for varargs:
52
53    |  :
54    | arg8
55    +---
56    | r30 (fp)   arg7
57    | r25        arg6
58    | r24        arg5
59    | r23        arg4
60    | r22        arg3
61    | r21        arg2
62    | r20        arg1
63    | r19        arg0
64    | r18
65    | r17        on startup === `startup'
66    | r16        on startup === `vuserf'
67    | r15        on startup === `pt'
68    | r14        on startup === `cleanup'
69    | r1         on startup === `qt_vstart'
70    | 0
71    | 0
72    +---
73    | 0
74    | ... (8 regs worth === 32 bytes of homing area)
75    | 0                                          <--- sp
76    +---
77
78    */
79
80
81 /* Stack must be doubleword aligned. */
82 #define QT_STKALIGN     (16)    /* Doubleword aligned. */
83
84 /* How much space is allocated to hold all the crud for
85    initialization: saved registers plus padding to keep the stack
86    aligned plus 8 words of padding to use as a `homing area' (for
87    r2-r9) when calling helper functions on the stack of the (not yet
88    started) thread.  The varargs save area is small because it gets
89    overlapped with the top of the parameter list.  In case the
90    parameter list is less than 8 args, QT_ARGS_MD0 adds some dead
91    space at the top of the stack. */
92
93 #define QT_STKBASE      (16*4 + 8*4)
94 #define QT_VSTKBASE     (8*4 + 8*4)
95
96
97 /* Index of various registers. */
98 #define QT_1    (8+2)
99 #define QT_14   (8+3)
100 #define QT_15   (8+4)
101 #define QT_16   (8+5)
102 #define QT_17   (8+6)
103 #define QT_30   (8+15)
104
105
106 /* When a never-before-run thread is restored, the return pc points
107    to a fragment of code that starts the thread running.  For
108    non-vargs functions, it sets up arguments and calls the client's
109    `only' function.  For varargs functions, the startup code calls the
110    startup, user, and cleanup functions.
111
112    For non-varargs functions, we set the frame pointer to 0 to
113    null-terminate the call chain.
114
115    For varargs functions, the frame pointer register is used to hold
116    one of the arguments, so that all arguments can be laid out in
117    memory by the conventional `qt_vargs' varargs initialization
118    routine.
119
120    The varargs startup routine always reads 8 words of arguments from
121    the stack.  If there are less than 8 words of arguments, then the
122    arg list could call off the top of the stack.  To prevent fall-off,
123    always allocate 8 words. */
124
125 extern void qt_start(void);
126 #define QT_ARGS_MD(sp) \
127   (QT_SPUT (sp, QT_1, qt_start), \
128    QT_SPUT (sp, QT_30, 0))
129
130
131 /* The m88k uses a struct for `va_list', so pass a pointer to the
132    struct. */
133
134 typedef void (qt_function_t)(void);
135
136 struct qt_t;
137 extern struct qt_t *qt_vargs (struct qt_t *sp, int nbytes,
138                               void *vargs, void *pt,
139                               qt_function_t *startup,
140                               qt_function_t *vuserf,
141                               qt_function_t *cleanup);
142
143 #define QT_VARGS(sp, nbytes, vargs, pt, startup, vuserf, cleanup) \
144   (qt_vargs (sp, nbytes, &(vargs), pt, (qt_function_t *)startup, \
145              (qt_function_t *)vuserf, (qt_function_t *)cleanup))
146
147
148 /* The *index* (positive offset) of where to put each value. */
149 #define QT_ONLY_INDEX   (QT_17)
150 #define QT_USER_INDEX   (QT_16)
151 #define QT_ARGT_INDEX   (QT_15)
152 #define QT_ARGU_INDEX   (QT_14)
153
154 #define QT_VCLEANUP_INDEX       (QT_14)
155 #define QT_VUSERF_INDEX         (QT_16)
156 #define QT_VSTARTUP_INDEX       (QT_17)
157 #define QT_VARGT_INDEX          (QT_15)
158
159 #endif /* ndef QT_M88K_H */