]> git.donarmstrong.com Git - lilypond.git/blob - guile18/qt/md/vax.h
Import guile-1.8 as multiple upstream tarball component
[lilypond.git] / guile18 / qt / md / vax.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_VAX_H
15 #define QT_VAX_H
16
17 typedef unsigned long qt_word_t;
18
19 /* Thread's initial stack layout on the VAX:
20
21    non-varargs:
22
23    +---
24    | arg[2]     === `userf' on startup
25    | arg[1]     === `pt' on startup
26    | arg[0]     === `pu' on startup
27    | ...        === `only' on startup.
28    +---
29    | ret pc     === `qt_start' on startup
30    | fp         === 0 on startup
31    | ap         === 0 on startup
32    | <mask>
33    | 0 (handler)                        <--- qt_t.sp
34    +---
35
36    When a non-varargs thread is started, it ``returns'' to the start
37    routine, which calls the client's `only' function.
38
39    The varargs case is clearly bad code.  The various values should be
40    stored in a save area and snarfed in to callee-save registers on
41    startup.  However, it's too painful to figure out the register
42    mask (right now), so do it the slow way.
43
44    +---
45    | arg[n-1]
46    | ..
47    | arg[0]
48    | nargs
49    +---
50    |            === `cleanup'
51    |            === `vuserf'
52    |            === `startup'
53    |            === `pt'
54    +---
55    | ret pc     === `qt_start' on startup
56    | fp         === 0 on startup
57    | ap         === 0 on startup
58    | <mask>
59    | 0 (handler)                        <--- qt_t.sp
60    +---
61
62    When a varargs thread is started, it ``returns'' to the `qt_vstart'
63    startup code.  The startup code pops all the extra arguments, then
64    calls the appropriate functions. */
65
66
67 /* What to do to start a thread running. */
68 extern void qt_start (void);
69 extern void qt_vstart (void);
70
71
72 /* Initial call frame for non-varargs and varargs cases. */
73 #define QT_STKBASE      (10 * 4)
74 #define QT_VSTKBASE     (9 * 4)
75
76
77 /* Stack "must be" 4-byte aligned.  (Actually, no, but it's
78    easiest and probably fastest to do so.) */
79
80 #define QT_STKALIGN     (4)
81
82
83 /* Where to place various arguments. */
84 #define QT_ONLY_INDEX   (5)
85 #define QT_USER_INDEX   (8)
86 #define QT_ARGT_INDEX   (7)
87 #define QT_ARGU_INDEX   (6)
88
89 #define QT_VSTARTUP_INDEX       (6)
90 #define QT_VUSERF_INDEX         (7)
91 #define QT_VCLEANUP_INDEX       (8)
92 #define QT_VARGT_INDEX          (5)
93
94
95 /* Stack grows down.  The top of the stack is the first thing to
96    pop off (predecrement, postincrement). */
97 #define QT_GROW_DOWN
98
99
100 extern void qt_error (void);
101
102 #define QT_VAX_GMASK_NOREGS     (0)
103
104 /* Push on the error return address, null termination to call chains,
105    number of arguments to `only', register save mask (save no
106    registers). */
107
108 #define QT_ARGS_MD(sto) \
109     (QT_SPUT (sto, 0, 0), \
110      QT_SPUT (sto, 1, QT_VAX_GMASK_NOREGS), \
111      QT_SPUT (sto, 2, 0), \
112      QT_SPUT (sto, 3, 0), \
113      QT_SPUT (sto, 4, qt_start))
114
115 #define QT_VARGS_MD0(sto, nbytes) \
116     (QT_SPUT (sto, (-(nbytes)/4)-1, (nbytes)/4), \
117      ((char *)(((sto)-4) - QT_STKROUNDUP(nbytes))))
118
119 #define QT_VARGS_ADJUST(sp)     ((char *)sp + 4)
120
121 #define QT_VARGS_MD1(sto) \
122     (QT_SPUT (sto, 0, 0), \
123      QT_SPUT (sto, 1, QT_VAX_GMASK_NOREGS), \
124      QT_SPUT (sto, 2, 0), \
125      QT_SPUT (sto, 3, 0), \
126      QT_SPUT (sto, 4, qt_vstart))
127
128 #define QT_VARGS_DEFAULT
129
130 #endif /* QT_VAX_H */