[project @ 1996-01-08 20:28:12 by partain]
[ghc.git] / ghc / includes / StgTypes.lh
1 %
2 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1994
3 %
4 %************************************************************************
5 %*                                                                      *
6 \section{How data is handled, especially floats and doubles}
7 %*                                                                      *
8 %************************************************************************
9
10 \begin{code}
11 #ifndef STGTYPES_H
12 #define STGTYPES_H
13 \end{code}
14
15 Some variables (eg the A stack, the stack pointers, floating point
16 registers) can only contain data of a particular (machine type).
17
18 %partain:\begin{center}
19 \begin{tabular}{|l|l|} 
20 \hline
21 What we call it &       The C type which represents it  \\ \hline
22                 &                                       \\
23 StgInt          &       long                            \\
24 StgFloat        &       float                           \\
25 StgDouble       &       double                          \\
26 StgChar         &       unsigned char                   \\\hline
27 StgStablePtr    &       long                            \\
28 StgMallocPtr    &       (long *)                        \\
29 \end{tabular}
30 %partain:\end{center}
31
32 Others, notably the heap itself and the B stack, can contain various
33 kinds of data; pointers, floats, doubles, chars and so on.  These
34 structures are given C type @StgWord@, meaning ``I don't know''.
35
36 %partain:\begin{center}
37 \begin{tabular}{|l|l|}
38 \hline
39 StgWord         &       long                            \\\hline
40 \end{tabular}
41 %partain:\end{center}
42
43 % @StgWord@s only live in {\em memory locations}; there are no registers
44 % of type @StgWord@.
45
46 When we load/store things in the heap, or on the B stack, we therefore
47 have to coerce data in and out of the @StgWord@ type.  For @StgInt@
48 and @StgChar@ that's no problem; we just use a C cast.
49
50 Now here's the rub: we can't cast a @StgFloat@ to @StgWord@ because C
51 performs numeric conversions if you do!  Worse, we obviously can't
52 cast a @StgDouble@ to @StgWord@, because it's the wrong size.  The
53 solution we adopt is to provide functions/macros with the following
54 prototypes
55
56 \begin{pseudocode}
57         StgFloat     PK_FLT( StgWord * )
58         void     ASSIGN_FLT( StgWord [], StgFloat )
59
60         StgDouble    PK_DBL( StgWord * )
61         void     ASSIGN_DBL( StgWord [], StgDouble )
62 \end{pseudocode}
63
64 The @PK@ functions create a suitable float/double given a pointer to
65 some @StgWord@ memory locations; the @ASSIGN@ functions do the
66 reverse.  Notice that it is a private matter between @PK_DBL@ and
67 @ASSIGN_DBL@ how the words are acutally used to store the double (the
68 high word could go in the upper or lower memory location).
69
70 We implement these operations as inlined C functions; much
71 better than macros because they need a local variable which
72 macros don't give you.  There is probably more than one way
73 to implement them; we have cheated the type system using a
74 union type.
75
76 \begin{code}
77 typedef unsigned long   StgWord;        /* used for heap- and Bstk- words,
78                                            which can be of various types */
79
80 /* macro to round a number-of-bytes up to a sufficient number of words: */
81 #define BYTES_TO_STGWORDS(no_bytes) (((no_bytes)+sizeof(W_)-1)/sizeof(W_))
82
83 typedef unsigned long  *StgPtr;         /* StgPtr is a ptr to a heap object
84                                            or into the B stack */
85 typedef StgPtr         *StgPtrPtr;      /* used for A stack pointer */
86 typedef long            StgInt;
87
88 /* seven shorthand forms: 
89      StgChar, StgWord, StgPtr, StgPtrPtr, StgInt, StgAddr, const StgPtr */
90
91 typedef unsigned char   C_;
92 typedef unsigned long   W_;
93 typedef unsigned long  *P_;
94 typedef P_             *PP_;
95 typedef long            I_;
96 typedef void           *A_;
97 typedef const unsigned long *D_;
98
99 typedef unsigned char   StgChar;
100 typedef void           *StgAddr;
101
102 #if alpha_TARGET_ARCH
103 typedef double          StgFloat;
104 typedef double          StgDouble;
105 #else
106 typedef float           StgFloat;
107 typedef double          StgDouble;
108 #endif
109
110 typedef StgPtr          StgArray;
111 typedef StgChar         *StgByteArray;
112 typedef StgByteArray    B_;
113
114 typedef I_              StgStablePtr;   /* Index into Stable Pointer Table */
115 typedef P_              StgMallocPtr;   /* (Probably) Pointer to object in C Heap */
116 /* On any architecture, StgMallocPtr should be big enough to hold
117    the largest possible pointer. */
118
119 /* These are used to pass the do_full_collection flag to RealPerformGC
120    and collectHeap.  (Is there a standard name for them?)
121    [ADR]
122
123    Why longs?  --JSM
124    No good reason (bad reason: same as StgInt) -- ADR
125    An abomination!  Death to StgBool!  --JSM
126 */
127 #define StgFalse 0
128 #define StgTrue  1
129 typedef long            StgBool;
130
131 typedef long            StgTag;
132
133 typedef StgWord         StgInfoEntry;
134 typedef StgWord        *StgInfoPtr;
135
136 \end{code}
137
138 Types for the generated C functions
139         take no arguments
140         return a pointer to the next function to be called
141    use: Ptr to Fun that returns a Ptr to Fun which returns Ptr to void
142
143 \begin{code}
144 typedef void  *(*(*StgFunPtr)(STG_NO_ARGS))(STG_NO_ARGS);
145
146 typedef StgFunPtr (StgFun)(STG_NO_ARGS);
147 typedef StgFunPtr sfp; /* shorthand, for less typing while debugging */
148
149 typedef StgFunPtr (*StgFunPtrFunPtr)(STG_NO_ARGS);
150
151 typedef StgFunPtr F_;
152 typedef StgFunPtrFunPtr *FP_;
153
154 typedef D_      StgRetAddr; /* for now ... */
155 #if 0
156 typedef union {
157     StgFunPtr d;                /* direct return */
158     D_ v;                       /* vectored return */
159 } StgRetAddr;
160 #endif
161
162 /* new union type, to eventually replace StgWord */
163 typedef union word {
164     B_ b;               /* pointer to byte array */
165     W_ c;               /* (unsigned) character; *not* StgChar type */
166     D_ d;               /* read-only data pointer */
167     StgFloat f;         /* single-precision float */
168     StgFunPtr fp;       /* function (code) pointer */
169     I_ i;               /* integer */
170     P_ p;               /* basic pointer */
171     StgRetAddr r;       /* return address or vector */
172     W_ w;               /* arbitrary word (needed?) */
173     void *v;            /* ??? (AddrKind) */
174 } StgUnion;
175
176
177 /* 
178    If a BitWord is anything other than an StgWord, you may have some problems.
179    In particular, be sure that the dynamic allocation of a BitWord array from the
180    heap is done properly.
181  */
182 typedef StgWord         BitWord;        /* Bit marking words */
183
184 /* Stuff for hashing */
185 typedef StgWord         hash_t;
186
187 #define UNHASHED (~0L)
188
189 /* ullong (64|128-bit) type: only include if needed (not ANSI) */
190 #if defined(__GNUC__) 
191 typedef unsigned long long ullong;   /* need prototypes */
192 #define LL(x) CAT2(x,LL)
193 #else
194 typedef unsigned long      ullong;
195 #define LL(x) CAT2(x,L)
196 #endif
197 \end{code}
198
199 Stuff for packed shorts; used in @StgMacros.h@.
200
201 \begin{code}
202 typedef struct __uw
203   { unsigned short s1;
204     unsigned short s2;
205   } unpacked_word;
206
207 typedef union __ps
208   { unsigned int u;
209     unpacked_word wu;
210   } packed_shorts;
211 \end{code}
212
213 Stuff for floats/doubles; used in @StgMacros.h@.
214 ToDo: looks pretty 64-bit unfriendly to me! [WDP]
215
216 \begin{code}
217 typedef struct __ud
218   { StgWord dhi;
219     StgWord dlo;
220   } unpacked_double;
221
222 typedef union __dt
223   { StgDouble d;
224     unpacked_double du;
225   } double_thing;
226
227 typedef StgWord unpacked_float;
228
229 typedef union __ft
230   { StgFloat f;
231     unpacked_float fu;
232   } float_thing;
233
234 \end{code}
235
236 Also include the RTS types for the runtime system modules.
237
238 \begin{code}
239
240 #include "rtsTypes.h"
241
242 #endif /* ! STGTYPES_H */
243 \end{code}