[project @ 2000-06-27 09:18:04 by sewardj]
[ghc-hetmet.git] / ghc / includes / Assembler.h
1
2 /* -----------------------------------------------------------------------------
3  * $Id: Assembler.h,v 1.16 2000/06/27 09:18:04 sewardj Exp $
4  *
5  * (c) The GHC Team 1994-1998.
6  *
7  * Bytecode assembler
8  *
9  * NB This is one of the few files shared between Hugs and the runtime system,
10  * so it is very important that it not conflict with either and that it not
11  * rely on either.  
12  * (In fact, it might be fun to create a GreenCard interface to this file too.)
13  * ---------------------------------------------------------------------------*/
14
15 /* ToDo: put this somewhere more sensible */
16 extern void DEBUG_LoadSymbols( char *name );
17
18 /* This file is supposed to be somewhat self-contained because it is one
19  * of the major external interfaces to the runtime system.
20  * Keeping it self-contained reduces the chance of conflict with Hugs
21  * (or anything else that includes it).
22  * The big disadvantage of being self-contained is that definitions
23  * like AsmNat8, etc duplicate definitions in StgTypes.h.
24  * I'm not sure what we can do about this but, if you try to fix it,
25  * please remember why it was done this way in the first place.
26  * -- ADR
27  */
28
29 typedef unsigned char   AsmNat8;
30 typedef unsigned int    AsmNat;
31 typedef signed   int    AsmInt;
32 typedef int64           AsmInt64;  
33 typedef unsigned int    AsmWord;
34 typedef void*           AsmAddr;
35 typedef unsigned char   AsmChar;
36 typedef float           AsmFloat;       /* ToDo: not on Alphas! */
37 typedef double          AsmDouble;
38 typedef char*           AsmString;
39
40 typedef int   AsmSp;   /* stack offset                  */
41 typedef int   AsmPc;   /* program counter               */
42 typedef AsmSp AsmVar;  /* offset of a Var on the stack  */
43
44 /* I want to #include this file into the file that defines the
45  * functions but I don't want to expose the structures that
46  * these types point to.
47  * This hack is the best I could think of.  Surely there's a better way?
48  */
49 #ifdef INSIDE_ASSEMBLER_C
50 /* these types are defined in Assembler.c */
51 typedef 
52    enum { 
53      Asm_RefNoOp,    /* Pointer which needs no further messing with */
54      Asm_RefObject,   /* Reference to malloc'd AsmCAF/AsmBCO/AsmCon */
55      Asm_RefHugs,          /* Reference to Hugs name or tycon table */
56
57      Asm_NonPtrWord,                          /* A non-pointer word */
58      Asm_Insn8,                                /* One BCO insn byte */
59    }
60    Asm_Kind;
61
62 typedef
63    struct {
64       Asm_Kind  kind;
65       StgWord   val;   /* StgWord is allegedly big enough to also hold
66                           a pointer, on all platforms */
67    }
68    Asm_Entity;
69
70
71    struct AsmObject_ {
72       unsigned int magic;
73       struct AsmObject_* next;
74       enum { Asm_BCO, Asm_CAF, Asm_Con } kind;
75       int           sizeEntities;
76       int           usedEntities;
77       Asm_Entity*   entities;
78       StgClosure*   closure;
79
80       int           n_refs;          /* number of ptr words  */
81       int           n_words;         /* number of words      */
82       int           n_insns;         /* number of insn BYTES */
83
84       /* AsmCon specifics */
85       StgInfoTable* itbl;
86
87       /* AsmBCO specifics */
88       int /*StgExpr*/ stgexpr;       /* stg tree for debugging */
89       AsmSp           sp;            /* simulated sp */
90       AsmSp           max_sp;        /* high-tide of sp */
91       Instr           lastOpc;       /* last opcode, for peephole opt */
92    };
93    /* AsmObject_ is only mentioned in Assembler.c; clients use
94       AsmObject/AsmBCO/AsmCAF/AsmCon. 
95    */
96
97 typedef StgInfoTable*       AsmInfo;
98 typedef struct AsmObject_*  AsmBCO;
99 typedef struct AsmObject_*  AsmCAF;
100 typedef struct AsmObject_*  AsmCon;
101 typedef struct AsmObject_*  AsmObject;
102 typedef Instr               AsmInstr;
103 #else
104 /* the types we export are totally opaque */
105 typedef void*               AsmObject;
106 typedef void*               AsmBCO;
107 typedef void*               AsmCAF;
108 typedef void*               AsmCon;
109 typedef void*               AsmInfo;
110 typedef void*               AsmClosure;
111 typedef unsigned int        AsmInstr;
112 #endif
113
114
115
116 /* --------------------------------------------------------------------------
117  * "Types" used within the assembler
118  *
119  * Some of these types are synonyms for the same underlying representation
120  * to let Hugs (or whoever) generate useful Haskell types from the type
121  * of a primitive operation.
122  *
123  *  Extreme care should be taken if you change any of these - the
124  *  same constants are hardwired into Hugs (ILLEGAL_REP) and into
125  *  pieces of assembly language used to implement foreign import/export.
126  *  And, of course, you'll have to change the primop table in Assembler.c
127  * ------------------------------------------------------------------------*/
128
129 typedef enum {
130   ILLEGAL_REP = 0,
131
132   /* The following can be passed to C */
133   CHAR_REP    = 'C',     
134   INT_REP     = 'I',      
135   INTEGER_REP = 'Z',  
136   WORD_REP    = 'W',     
137   ADDR_REP    = 'A',     
138   FLOAT_REP   = 'F',    
139   DOUBLE_REP  = 'D',   
140   STABLE_REP  = 's',   /* StablePtr a */
141 #ifdef PROVIDE_FOREIGN
142   FOREIGN_REP = 'f',   /* ForeignObj  */
143 #endif
144 #ifdef PROVIDE_WEAK
145   WEAK_REP    = 'w',   /* Weak a      */
146 #endif
147   BARR_REP     = 'x',  /* PrimByteArray          a */
148   MUTBARR_REP  = 'm',  /* PrimMutableByteArray s a */
149
150   /* The following can't be passed to C */
151   PTR_REP      = 'P',      
152   ALPHA_REP    = 'a',  /* a                        */
153   BETA_REP     = 'b',  /* b                        */
154   GAMMA_REP    = 'c',  /* c                        */
155   DELTA_REP    = 'd',  /* d                        */
156   BOOL_REP     = 'B',  /* Bool                     */
157   IO_REP       = 'i',  /* IO a                     */
158   HANDLER_REP  = 'H',  /* Exception -> IO a        */
159   ERROR_REP    = 'E',  /* Exception                */
160   ARR_REP      = 'X',  /* PrimArray              a */
161   REF_REP      = 'R',  /* Ref                  s a */
162   MUTARR_REP   = 'M',  /* PrimMutableArray     s a */
163   THREADID_REP = 'T',  /* ThreadId                 */
164   MVAR_REP     = 'r',  /* MVar a                   */
165
166   /* Allegedly used in the IO monad */
167   VOID_REP     = 'v'      
168 } AsmRep;
169
170 /* --------------------------------------------------------------------------
171  * Top-level control of the BCO generation + linking mechanism
172  * ------------------------------------------------------------------------*/
173
174 extern void asmInitialise         ( void );
175 extern void asmAllocateHeapSpace  ( void );
176 extern void asmCopyAndLink        ( void );
177 extern void asmShutdown           ( void );
178
179 extern void* /* StgClosure* */ asmGetClosureOfObject ( AsmObject );
180
181 /* --------------------------------------------------------------------------
182  * Allocating (top level) heap objects
183  * ------------------------------------------------------------------------*/
184
185 extern AsmBCO     asmBeginBCO        ( int /*StgExpr*/ e );
186 extern void       asmEndBCO          ( AsmBCO bco );
187
188 extern AsmBCO     asmBeginContinuation ( AsmSp sp, int /*List*/ alts );
189 extern void       asmEndContinuation   ( AsmBCO bco );
190
191 extern AsmCAF     asmBeginCAF        ( void );
192 extern void       asmEndCAF          ( AsmCAF caf );
193
194 extern AsmInfo    asmMkInfo          ( AsmNat tag, AsmNat ptrs );
195 extern AsmCon     asmBeginCon        ( AsmInfo info );
196 extern void       asmEndCon          ( AsmCon con );
197
198 /* NB: we add ptrs to other objects in left-to-right order.
199  * This is different from pushing arguments on the stack which is done
200  * in right to left order.
201  */
202 extern void       asmAddPtr          ( AsmObject obj, AsmObject arg );
203 extern int        asmRepSizeW        ( AsmRep rep );
204
205 /* --------------------------------------------------------------------------
206  * Generating instruction streams
207  * ------------------------------------------------------------------------*/
208                                
209 extern AsmSp  asmBeginArgCheck ( AsmBCO bco );
210 extern void   asmEndArgCheck   ( AsmBCO bco, AsmSp last_arg );
211                                
212 extern AsmSp  asmBeginEnter    ( AsmBCO bco );
213 extern void   asmEndEnter      ( AsmBCO bco, AsmSp sp1, AsmSp sp2 );
214                                
215 extern AsmVar asmBind          ( AsmBCO bco, AsmRep rep );
216 extern void   asmVar           ( AsmBCO bco, AsmVar v, AsmRep rep );
217                                
218 extern AsmSp  asmBeginCase     ( AsmBCO bco );
219 extern void   asmEndCase       ( AsmBCO bco );
220 extern AsmSp  asmContinuation  ( AsmBCO bco, AsmBCO ret_addr );
221
222 extern AsmSp  asmBeginAlt      ( AsmBCO bco );
223 extern void   asmEndAlt        ( AsmBCO bco, AsmSp  sp );
224 extern AsmPc  asmTest          ( AsmBCO bco, AsmWord tag );
225 extern AsmPc  asmTestInt       ( AsmBCO bco, AsmVar v, AsmInt x );
226 extern void   asmFixBranch     ( AsmBCO bco, AsmPc pc );
227 extern void   asmPanic         ( AsmBCO bco );
228                                
229 extern AsmVar asmBox           ( AsmBCO bco, AsmRep rep );
230 extern AsmVar asmUnbox         ( AsmBCO bco, AsmRep rep );
231 extern void   asmReturnUnboxed ( AsmBCO bco, AsmRep rep );             
232
233 /* push unboxed Ints, Floats, etc */
234 extern void   asmConstInt      ( AsmBCO bco, AsmInt     x );
235 extern void   asmConstAddr     ( AsmBCO bco, AsmAddr    x );
236 extern void   asmConstWord     ( AsmBCO bco, AsmWord    x );
237 extern void   asmConstChar     ( AsmBCO bco, AsmChar    x );
238 extern void   asmConstFloat    ( AsmBCO bco, AsmFloat   x );
239 extern void   asmConstDouble   ( AsmBCO bco, AsmDouble  x );
240 extern void   asmConstInteger  ( AsmBCO bco, AsmString  x );
241              
242 /* Which monad (if any) does the primop live in? */
243 typedef enum {
244     MONAD_Id,  /* no monad (aka the identity monad) */
245     MONAD_ST,
246     MONAD_IO
247 } AsmMonad;
248
249 typedef struct {
250     char*    name;
251     char*    args;
252     char*    results;
253     AsmMonad monad;
254     AsmNat8  prefix; /* should be StgInstr           */
255     AsmNat8  opcode; /* should be Primop1 or Primop2 */
256 } AsmPrim;
257
258 extern AsmPrim asmPrimOps[]; /* null terminated list */
259
260 extern AsmPrim* asmFindPrim      ( char* s );
261 extern AsmPrim* asmFindPrimop    ( AsmInstr prefix, AsmInstr op );
262 extern AsmSp    asmBeginPrim     ( AsmBCO bco );
263 extern void     asmEndPrim       ( AsmBCO bco, const AsmPrim* prim, 
264                                                AsmSp base );
265 extern char*    asmGetPrimopName ( AsmPrim* p );
266
267 extern void* /* StgBCO* */ asm_BCO_catch    ( void );
268 extern void* /* StgBCO* */ asm_BCO_raise    ( void );
269 extern void* /* StgBCO* */ asm_BCO_seq      ( void );
270 extern void* /* StgBCO* */ asm_BCO_takeMVar ( void );
271
272
273 /* --------------------------------------------------------------------------
274  * Heap manipulation
275  * ------------------------------------------------------------------------*/
276
277 extern AsmVar asmPushRefHugs   ( AsmBCO bco, int /*Name*/ n );
278 extern AsmVar asmPushRefObject ( AsmBCO bco, AsmObject p );
279 extern AsmVar asmPushRefNoOp   ( AsmBCO bco, StgPtr p );
280
281 extern void   asmAddRefObject  ( AsmObject obj, AsmObject p );
282 extern void   asmAddRefNoOp    ( AsmObject obj, StgPtr p );
283 extern void   asmAddRefHugs    ( AsmObject obj,int /*Name*/ n );
284
285 extern AsmVar asmAllocCONSTR   ( AsmBCO bco, AsmInfo info );
286
287 extern AsmSp  asmBeginPack     ( AsmBCO bco );
288 extern void   asmEndPack       ( AsmBCO bco, AsmVar v, AsmSp start, 
289                                                        AsmInfo info );
290
291 extern void   asmBeginUnpack   ( AsmBCO bco );
292 extern void   asmEndUnpack     ( AsmBCO bco );
293
294 extern AsmVar asmAllocAP       ( AsmBCO bco, AsmNat size );
295 extern AsmSp  asmBeginMkAP     ( AsmBCO bco );
296 extern void   asmEndMkAP       ( AsmBCO bco, AsmVar v, AsmSp start );
297
298 extern AsmVar asmAllocPAP      ( AsmBCO bco, AsmNat size );
299 extern AsmSp  asmBeginMkPAP    ( AsmBCO bco );
300 extern void   asmEndMkPAP      ( AsmBCO bco, AsmVar v, AsmSp start );
301
302 #ifdef XMLAMBDA
303 /*------------------------------------------------------------------------
304  XMlambda primitives.
305 ------------------------------------------------------------------------*/
306 typedef AsmInt  AsmIndex;
307
308 /* Rows */
309 extern AsmVar asmAllocRow      ( AsmBCO bco, AsmNat /*number of fields*/ n );
310
311 extern AsmSp  asmBeginPackRow  ( AsmBCO bco );
312 extern void   asmEndPackRow    ( AsmBCO bco, AsmVar v, AsmSp start, 
313                                              AsmNat /*number of fields*/ n );
314
315 extern void   asmBeginUnpackRow( AsmBCO bco );
316 extern void   asmEndUnpackRow  ( AsmBCO bco );
317
318 extern AsmPrim primRowRemoveAtN;
319 extern AsmPrim primRowIndexAtN;
320
321 /* Inj */
322 extern AsmVar asmInj( AsmBCO bco, AsmVar var );
323 extern AsmVar asmInjConst( AsmBCO bco, AsmIndex i );
324 extern AsmVar asmUnInj( AsmBCO bco );
325 extern AsmPc  asmTestInj( AsmBCO bco, AsmVar var );
326 extern AsmPc  asmTestInjConst( AsmBCO, AsmIndex i );
327 extern AsmVar asmConstIndex( AsmBCO bco, AsmIndex x );
328 #endif
329
330 /* --------------------------------------------------------------------------
331  * C-call and H-call
332  * ------------------------------------------------------------------------*/
333
334 extern AsmPrim ccall_ccall_Id;
335 extern AsmPrim ccall_ccall_IO;
336 extern AsmPrim ccall_stdcall_Id;
337 extern AsmPrim ccall_stdcall_IO;
338
339 typedef struct {
340   unsigned int  num_args;
341   char*         arg_tys;
342   unsigned int  num_results;
343   char*         result_tys;
344 } CFunDescriptor;
345
346 CFunDescriptor* mkDescriptor( char* as, char* rs );
347
348 /*-------------------------------------------------------------------------*/