270a6ee90630c3bfc31740f4ecdfa737619e700a
[ghc-hetmet.git] / ghc / includes / Assembler.h
1
2 /* -----------------------------------------------------------------------------
3  * $Id: Assembler.h,v 1.19 2000/11/13 14:40:36 simonmar 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 HsInt64         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 AsmWord      AsmWitness;
307 #define WITNESS_REP  WORD_REP
308
309 /* insert/remove primitives on rows */
310 extern void   asmEndPrimRowChainInsert( AsmBCO bco, AsmSp base, AsmWord n /* number of args */ );
311 extern void   asmEndPrimRowChainBuild ( AsmBCO bco, AsmSp base, AsmWord n /* number of args */ );
312 extern void   asmEndPrimRowChainRemove( AsmBCO bco, AsmSp base, AsmWord n /* number of args */ );
313 extern void   asmEndPrimRowChainSelect( AsmBCO bco, AsmSp base, AsmWord n /* number of args */ );
314
315 /* pack/unpack instructions for rows */
316 extern AsmVar asmAllocRow      ( AsmBCO bco, AsmWord /*number of fields*/ n );
317 extern AsmSp  asmBeginPackRow  ( AsmBCO bco );
318 extern void   asmEndPackRow    ( AsmBCO bco, AsmVar v, AsmSp start, 
319                                              AsmWord /*number of fields*/ n );
320
321 extern void   asmBeginUnpackRow( AsmBCO bco );
322 extern void   asmEndUnpackRow  ( AsmBCO bco );
323
324 extern void   asmConstRowTriv  ( AsmBCO bco );
325
326 /* Inj primitives */
327 extern AsmVar asmInjRel( AsmBCO bco, AsmVar var, AsmWitness w );
328 extern AsmVar asmInjConst( AsmBCO bco, AsmWitness w );
329
330 extern AsmPc  asmTestInjRel( AsmBCO bco, AsmVar var, AsmWitness w );
331 extern AsmPc  asmTestInjConst( AsmBCO, AsmWitness w );
332
333 extern void   asmWitnessRel( AsmBCO bco, AsmVar var, AsmWitness w );
334 extern void   asmWitnessConst( AsmBCO bco, AsmWitness w );
335
336 extern AsmVar asmUnInj( AsmBCO bco );
337
338 #endif
339
340 /* --------------------------------------------------------------------------
341  * C-call and H-call
342  * ------------------------------------------------------------------------*/
343
344 extern AsmPrim ccall_ccall_Id;
345 extern AsmPrim ccall_ccall_IO;
346 extern AsmPrim ccall_stdcall_Id;
347 extern AsmPrim ccall_stdcall_IO;
348
349 typedef struct {
350   unsigned int  num_args;
351   char*         arg_tys;
352   unsigned int  num_results;
353   char*         result_tys;
354 } CFunDescriptor;
355
356 CFunDescriptor* mkDescriptor( char* as, char* rs );
357
358 #ifdef XMLAMBDA
359
360 typedef enum _CallType
361 { CCall    = 'c'  /* C calling convention */
362 , StdCall  = 's'  /* Standard calling convention */
363 } CallType;
364
365 /* The asmEndPrimCall*** functions call external functions.
366   Just start with "asmBeginPrim", push the arguments
367   and end with one of these functions. The argument and
368   result types are given as an argument string containing
369   the character representation of AsmRep's. */
370
371 /* asmEndPrimCallDynamic calls a function defined in a dynamic link library. 
372   If decorate is true, the funName will be decorated according to its
373   calling convention, for example, with CCall an underscore is prefixed */
374 extern void asmEndPrimCallDynamic(  AsmBCO       bco
375                                   , AsmSp        base
376                                   , const char*  libName
377                                   , const char*  funName
378                                   , const char*  argTypes
379                                   , const char*  resultTypes
380                                   , CallType     callType
381                                   , int /*bool*/ decorate);
382
383 /* asmEndPrimCallIndirect calls the function given by its first
384   argument. (ie. push the address just before calling) */
385 extern void asmEndPrimCallIndirect(  AsmBCO      bco
386                                    , AsmSp       base
387                                    , const char* argTypes
388                                    , const char* resultTypes
389                                    , CallType    callType );
390
391
392 #endif
393
394 /*-------------------------------------------------------------------------*/