X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=ghc%2Frts%2FStgStartup.cmm;fp=ghc%2Frts%2FStgStartup.hc;h=d9308d6e52988a415ea6b6f695f020dab78c900a;hb=423d477bfecd490de1449c59325c8776f91d7aac;hp=d3e4c2f0ed79f5c0b6e05f2432712f2d1c2c51cf;hpb=553e90d9a32ee1b1809430f260c401cc4169c6c7;p=ghc-hetmet.git diff --git a/ghc/rts/StgStartup.hc b/ghc/rts/StgStartup.cmm similarity index 53% rename from ghc/rts/StgStartup.hc rename to ghc/rts/StgStartup.cmm index d3e4c2f..d9308d6 100644 --- a/ghc/rts/StgStartup.hc +++ b/ghc/rts/StgStartup.cmm @@ -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 @@ -25,10 +25,10 @@ */ #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; }