[project @ 2004-08-13 13:04:50 by simonmar]
[ghc-hetmet.git] / ghc / rts / StgStartup.cmm
similarity index 53%
rename from ghc/rts/StgStartup.hc
rename to ghc/rts/StgStartup.cmm
index d3e4c2f..d9308d6 100644 (file)
@@ -1,16 +1,16 @@
 /* -----------------------------------------------------------------------------
- * $Id: StgStartup.hc,v 1.21 2003/05/14 09:14:00 simonmar Exp $
  *
- * (c) The GHC Team, 1998-2002
+ * (c) The GHC Team, 1998-2004
  *
  * Code for starting, stopping and restarting threads.
  *
+ * This file is written in a subset of C--, extended with various
+ * features specific to GHC.  It is compiled by GHC directly.  For the
+ * syntax of .cmm files, see the parser in ghc/compiler/cmm/CmmParse.y.
+ *
  * ---------------------------------------------------------------------------*/
 
-#include "Stg.h"
-#include "Rts.h"
-#include "StgRun.h" /* StgReturn */
-#include "StgStartup.h"
+#include "Cmm.h"
 
 /*
  * This module contains the two entry points and the final exit point
  */
 
 #define CHECK_SENSIBLE_REGS() \
-    ASSERT(Hp != (P_)0);                       \
-    ASSERT(Sp != (P_)0);                       \
-    ASSERT(SpLim != (P_)0);                    \
-    ASSERT(HpLim != (P_)0);                    \
+    ASSERT(Hp != 0);                   \
+    ASSERT(Sp != 0);                   \
+    ASSERT(SpLim != 0);                        \
+    ASSERT(HpLim != 0);                        \
     ASSERT(SpLim - RESERVED_STACK_WORDS <= Sp); \
     ASSERT(HpLim >= Hp);
 
@@ -41,8 +41,6 @@
    slot 0).
    -------------------------------------------------------------------------- */
 
-EXTFUN(stg_stop_thread_ret);
-
 #if defined(PROFILING)
 #define STOP_THREAD_BITMAP 3
 #define STOP_THREAD_WORDS  2
@@ -51,58 +49,53 @@ EXTFUN(stg_stop_thread_ret);
 #define STOP_THREAD_WORDS  0
 #endif
 
-/* VEC_POLY_INFO expects to see these names - but they should all be the same. */
-#define stg_stop_thread_0_ret stg_stop_thread_ret 
-#define stg_stop_thread_1_ret stg_stop_thread_ret 
-#define stg_stop_thread_2_ret stg_stop_thread_ret 
-#define stg_stop_thread_3_ret stg_stop_thread_ret 
-#define stg_stop_thread_4_ret stg_stop_thread_ret 
-#define stg_stop_thread_5_ret stg_stop_thread_ret 
-#define stg_stop_thread_6_ret stg_stop_thread_ret 
-#define stg_stop_thread_7_ret stg_stop_thread_ret 
-
-VEC_POLY_INFO_TABLE( stg_stop_thread,
-                    MK_SMALL_BITMAP(STOP_THREAD_WORDS, STOP_THREAD_BITMAP),
-                    0,0,0,STOP_FRAME,,EF_);
-
-STGFUN(stg_stop_thread_ret)
+/* A polymorhpic return address, where all the vector slots point to the
+   direct entry point. */
+INFO_TABLE_RET( stg_stop_thread, STOP_THREAD_WORDS, STOP_THREAD_BITMAP,
+               STOP_FRAME, 
+               RET_LBL(stg_stop_thread),
+               RET_LBL(stg_stop_thread),
+               RET_LBL(stg_stop_thread),
+               RET_LBL(stg_stop_thread),
+               RET_LBL(stg_stop_thread),
+               RET_LBL(stg_stop_thread),
+               RET_LBL(stg_stop_thread),
+               RET_LBL(stg_stop_thread) )
 {
-    FB_
-    // 
-    // The final exit.
-    //
-    // The top-top-level closures (e.g., "main") are of type "IO a".
-    // When entered, they perform an IO action and return an 'a' in R1.
-    //
-    // We save R1 on top of the stack where the scheduler can find it,
-    // tidy up the registers and return to the scheduler.
-    //
-    // We Leave the stack looking like this:
-    //
-    //         +----------------+
-    //          |      -------------------> return value
-    //         +----------------+
-    //         | stg_enter_info |
-    //         +----------------+
-    //
-    // The stg_enter_info is just a dummy info table so that the
-    // garbage collector can understand the stack (there must always
-    // be an info table on top of the stack).
-    //
-
-    Sp += sizeofW(StgStopFrame) - 2;
-    Sp[1] = R1.w;
-    Sp[0] = (W_)&stg_enter_info;
-
-    CurrentTSO->what_next = ThreadComplete;
-
-    SaveThreadState(); // inline!
-
-    // R1 contains the return value of the thread
-    R1.i = ThreadFinished;
-
-    JMP_(StgReturn);
-    FE_
+    /* 
+       The final exit.
+      
+       The top-top-level closures (e.g., "main") are of type "IO a".
+       When entered, they perform an IO action and return an 'a' in R1.
+      
+       We save R1 on top of the stack where the scheduler can find it,
+       tidy up the registers and return to the scheduler.
+      
+       We Leave the stack looking like this:
+      
+               +----------------+
+                |      -------------------> return value
+               +----------------+
+               | stg_enter_info |
+               +----------------+
+      
+       The stg_enter_info is just a dummy info table so that the
+       garbage collector can understand the stack (there must always
+       be an info table on top of the stack).
+    */
+
+    Sp = Sp + SIZEOF_StgStopFrame - WDS(2);
+    Sp(1) = R1;
+    Sp(0) = stg_enter_info;
+
+    StgTSO_what_next(CurrentTSO) = ThreadComplete::I16;
+
+    SAVE_THREAD_STATE();
+
+    /* R1 contains the return value of the thread */
+    R1 = ThreadFinished;
+
+    jump StgReturn;
 }
 
 /* -----------------------------------------------------------------------------
@@ -111,13 +104,11 @@ STGFUN(stg_stop_thread_ret)
    from C land.
    -------------------------------------------------------------------------- */
 
-STGFUN(stg_returnToStackTop)
+stg_returnToStackTop
 {
-  FB_
-  LoadThreadState();
+  LOAD_THREAD_STATE();
   CHECK_SENSIBLE_REGS();
-  JMP_(ENTRY_CODE(Sp[0]));
-  FE_
+  jump %ENTRY_CODE(Sp(0));
 }
 
 /* -----------------------------------------------------------------------------
@@ -133,27 +124,18 @@ STGFUN(stg_returnToStackTop)
     results that comes back.
     ------------------------------------------------------------------------- */
 
-INFO_TABLE_RET( stg_forceIO_info,stg_forceIO_ret,
-               MK_SMALL_BITMAP(0/*size*/, 0/*BITMAP*/),
-               0/*SRT*/, 0/*SRT_OFF*/, 0/*SRT_BITMAP*/, 
-               RET_SMALL,, EF_, 0, 0);
+INFO_TABLE_RET( stg_forceIO, 0/*size*/, 0/*bitmap*/, RET_SMALL)
 
 #ifdef REG_R1
-STGFUN(stg_forceIO_ret)
 {
-  FB_
-  Sp++;
+  Sp_adj(1);
   ENTER();
-  FE_
 }
 #else
-STGFUN(stg_forceIO_ret)
 {
-  FB_
-  R1.w = Sp[0];
-  Sp += 2;
+  R1 = Sp(0);
+  Sp_adj(2);
   ENTER();
-  FE_
 }
 #endif
 
@@ -166,27 +148,18 @@ STGFUN(stg_forceIO_ret)
     is a register or not.
     ------------------------------------------------------------------------- */
 
-INFO_TABLE_RET( stg_noforceIO_info,stg_noforceIO_ret,
-               MK_SMALL_BITMAP(0/*size*/, 0/*BITMAP*/),
-               0/*SRT*/, 0/*SRT_OFF*/, 0/*SRT_BITMAP*/, 
-               RET_SMALL,, EF_, 0, 0);
+INFO_TABLE_RET( stg_noforceIO, 0/*size*/, 0/*bitmap*/, RET_SMALL )
 
 #ifdef REG_R1
-STGFUN(stg_noforceIO_ret)
 {
-  FB_
-  Sp++;
-  JMP_(ENTRY_CODE(Sp[0]));
-  FE_
+  Sp_adj(1);
+  jump %ENTRY_CODE(Sp(0));
 }
 #else
-STGFUN(stg_noforceIO_ret)
 {
-  FB_
-  R1.w = Sp[0];
-  Sp += 2;
-  JMP_(ENTRY_CODE(Sp[0]));
-  FE_
+  R1 = Sp(0);
+  Sp_adj(2);
+  jump %ENTRY_CODE(Sp(0));
 }
 #endif
 
@@ -194,23 +167,20 @@ STGFUN(stg_noforceIO_ret)
    Special STG entry points for module registration.
    -------------------------------------------------------------------------- */
 
-extern F_ *init_stack;
-
-STGFUN(stg_init_ret)
+stg_init_finish
 {
-  FB_
-  JMP_(StgReturn);
-  FE_
+  jump StgReturn;
 }
 
 /* On entry to stg_init:
  *    init_stack[0] = &stg_init_ret;
  *    init_stack[1] = __stginit_Something;
  */
-STGFUN(stg_init)
+stg_init
 {
-  FB_
-  Sp = BaseReg->rSp;
-  JMP_(POP_INIT_STACK());
-  FE_
+  W_ next;
+  Sp = W_[MainCapability + OFFSET_Capability_r + OFFSET_StgRegTable_rSp];
+  next = W_[Sp];
+  Sp_adj(1);
+  jump next;
 }