[project @ 1998-11-26 09:17:22 by sof]
[ghc-hetmet.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 StgForeignObj   &       (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 #if HAVE_LONG_LONG
89 /* These types are only used to allow the passing of
90    64-bit ints from Haskell to ccalls and to ease
91    the implementation of the Int64 and Word64 libraries.
92 */
93 typedef unsigned long long int StgWord64;
94 typedef long long int          StgInt64;
95 typedef StgInt64               LI_;
96 typedef StgWord64              LW_;
97 #endif
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 /* seven shorthand forms: 
111      StgChar, StgWord, StgPtr, StgPtrPtr, StgInt, StgAddr, const StgPtr */
112
113 typedef StgChar         C_;
114 typedef StgWord         W_;
115 typedef StgPtr          P_;
116 typedef P_             *PP_;
117 typedef StgInt          I_;
118 typedef void           *A_;
119 typedef const unsigned long *D_;
120
121 /* Typedefs for the various sized ints
122    (ToDo: better.)
123 */
124
125 typedef unsigned char  StgWord8;
126 typedef signed char    StgInt8;
127 typedef unsigned short StgWord16;
128 typedef short          StgInt16;
129 typedef unsigned int   StgWord32;
130 typedef signed int     StgInt32;
131         
132
133 typedef StgPtr          StgArray;
134 typedef StgChar         *StgByteArray;
135 typedef StgByteArray    B_;
136
137 typedef I_              StgStablePtr;   /* Index into Stable Pointer Table */
138 typedef P_              StgForeignObj;  /* (Probably) Pointer to object in C Heap */
139 /* On any architecture, StgForeignObj should be big enough to hold
140    the largest possible pointer. */
141
142 /* These are used to pass the do_full_collection flag to RealPerformGC
143    and collectHeap.  (Is there a standard name for them?)
144    [ADR]
145
146    Why longs?  --JSM
147    No good reason (bad reason: same as StgInt) -- ADR
148    An abomination!  Death to StgBool!  --JSM
149 */
150 #define StgFalse 0
151 #define StgTrue  1
152 typedef long            StgBool;
153
154 typedef long            StgTag;
155
156 typedef StgWord         StgInfoEntry;
157 typedef StgWord        *StgInfoPtr;
158
159 \end{code}
160
161 Types for the generated C functions
162         take no arguments
163         return a pointer to the next function to be called
164    use: Ptr to Fun that returns a Ptr to Fun which returns Ptr to void
165
166 \begin{code}
167 typedef void  *(*(*StgFunPtr)(STG_NO_ARGS))(STG_NO_ARGS);
168
169 typedef StgFunPtr (StgFun)(STG_NO_ARGS);
170 typedef StgFunPtr sfp; /* shorthand, for less typing while debugging */
171
172 typedef StgFunPtr (*StgFunPtrFunPtr)(STG_NO_ARGS);
173
174 typedef StgFunPtr F_;
175 typedef StgFunPtrFunPtr *FP_;
176
177 typedef D_      StgRetAddr; /* for now ... */
178 #if 0
179 typedef union {
180     StgFunPtr d;                /* direct return */
181     D_ v;                       /* vectored return */
182 } StgRetAddr;
183 #endif
184
185 /* new union type, to eventually replace StgWord */
186 typedef union word {
187     B_ b;               /* pointer to byte array */
188     W_ c;               /* (unsigned) character; *not* StgChar type */
189     D_ d;               /* read-only data pointer */
190     StgFloat f;         /* single-precision float */
191     StgFunPtr fp;       /* function (code) pointer */
192     I_ i;               /* integer */
193     P_ p;               /* basic pointer */
194     StgRetAddr r;       /* return address or vector */
195     W_ w;               /* arbitrary word (needed?) */
196     void *v;            /* ??? (AddrKind) */
197 } StgUnion;
198
199
200 /* 
201    If a BitWord is anything other than an StgWord, you may have some problems.
202    In particular, be sure that the dynamic allocation of a BitWord array from the
203    heap is done properly.
204  */
205 typedef StgWord         BitWord;        /* Bit marking words */
206
207 /* Stuff for hashing */
208 typedef StgWord         hash_t;
209
210 #define UNHASHED (~0L)
211
212 /* ullong (64|128-bit) type: only include if needed (not ANSI) */
213 #if defined(__GNUC__) 
214 typedef unsigned long long ullong;   /* need prototypes */
215 #define LL(x) CAT2(x,LL)
216 #else
217 typedef unsigned long      ullong;
218 #define LL(x) CAT2(x,L)
219 #endif
220 \end{code}
221
222 Stuff for packed shorts; used in @StgMacros.h@.
223
224 \begin{code}
225 typedef struct __uw
226   { unsigned short s1;
227     unsigned short s2;
228   } unpacked_word;
229
230 typedef union __ps
231   { unsigned int u;
232     unpacked_word wu;
233   } packed_shorts;
234 \end{code}
235
236 Stuff for floats/doubles; used in @StgMacros.h@.
237 ToDo: looks pretty 64-bit unfriendly to me! [WDP]
238
239 \begin{code}
240 typedef struct __ud
241   { StgWord dhi;
242     StgWord dlo;
243   } unpacked_double;
244
245 typedef union __dt
246   { StgDouble d;
247     unpacked_double du;
248   } double_thing;
249
250 typedef StgWord unpacked_float;
251
252 typedef union __ft
253   { StgFloat f;
254     unpacked_float fu;
255   } float_thing;
256
257 #if HAVE_LONG_LONG
258 typedef union __it
259   { StgInt64 i;
260     unpacked_double iu;
261   } int64_thing;
262
263 typedef union __wt
264   { StgWord64 w;
265     unpacked_double wu;
266   } word64_thing;
267 #endif
268
269 \end{code}
270
271 Also include the RTS types for the runtime system modules.
272
273 \begin{code}
274
275 #include "RtsTypes.h"
276
277 #endif /* ! STGTYPES_H */
278 \end{code}