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