X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=ghc%2Fincludes%2FRegs.h;h=8afc6c98176754ad902a418483548ab6b0177613;hb=272a418428beede04a9c4ae027474878c59d6ca1;hp=a4908201384b6ad56ad3292b7ac51896d8fb7a16;hpb=438596897ebbe25a07e1c82085cfbc5bdb00f09e;p=ghc-hetmet.git diff --git a/ghc/includes/Regs.h b/ghc/includes/Regs.h index a490820..8afc6c9 100644 --- a/ghc/includes/Regs.h +++ b/ghc/includes/Regs.h @@ -1,5 +1,7 @@ /* ----------------------------------------------------------------------------- - * $Id: Regs.h,v 1.2 1998/12/02 13:21:20 simonm Exp $ + * $Id: Regs.h,v 1.14 2003/11/14 14:28:08 stolz Exp $ + * + * (c) The GHC Team, 1998-1999 * * Registers used in STG code. Might or might not correspond to * actual machine registers. @@ -23,7 +25,19 @@ * 2) caller-saves registers are saved across a CCall */ +typedef struct StgSparkPool_ { + StgClosure **base; + StgClosure **lim; + StgClosure **hd; + StgClosure **tl; +} StgSparkPool; + typedef struct { + StgFunPtr stgGCEnter1; + StgFunPtr stgGCFun; +} StgFunTable; + +typedef struct StgRegTable_ { StgUnion rR1; StgUnion rR2; StgUnion rR3; @@ -32,29 +46,56 @@ typedef struct { StgUnion rR6; StgUnion rR7; StgUnion rR8; - StgUnion rR9; /* used occasionally by heap/stack checks */ - StgUnion rR10; /* used occasionally by heap/stack checks */ + StgUnion rR9; // used occasionally by heap/stack checks + StgUnion rR10; // used occasionally by heap/stack checks StgFloat rF1; StgFloat rF2; StgFloat rF3; StgFloat rF4; StgDouble rD1; StgDouble rD2; - StgNat64 rL1; + StgWord64 rL1; StgPtr rSp; - StgUpdateFrame *rSu; StgPtr rSpLim; StgPtr rHp; StgPtr rHpLim; + StgTSO *rCurrentTSO; + struct _bdescr *rNursery; + struct _bdescr *rCurrentNursery; + StgWord rHpAlloc; // number of words being allocated in heap +#if defined(SMP) || defined(PAR) + StgSparkPool rSparks; // per-task spark pool +#endif } StgRegTable; -extern StgRegTable MainRegTable; + +/* A capability is a combination of a FunTable and a RegTable. In STG + * code, BaseReg normally points to the RegTable portion of this + * structure, so that we can index both forwards and backwards to take + * advantage of shorter instruction forms on some archs (eg. x86). + */ +typedef struct Capability_ { + StgFunTable f; + StgRegTable r; +#if defined(SMP) + struct Capability_ *link; /* per-task register tables are linked together */ +#endif +} Capability; + +/* No such thing as a MainRegTable under SMP - each thread must + * have its own MainRegTable. + */ +#ifndef SMP +extern DLL_IMPORT_RTS Capability MainCapability; +#endif + +#if IN_STG_CODE /* * Registers Hp and HpLim are global across the entire system, and are * copied into the RegTable before executing a thread. * - * Registers Sp, Su, and SpLim are saved in the TSO for the + * Registers Sp and SpLim are saved in the TSO for the * thread, but are copied into the RegTable before executing a thread. * * All other registers are "general purpose", and are used for passing @@ -80,35 +121,44 @@ extern StgRegTable MainRegTable; */ #define SAVE_Sp (CurrentTSO->sp) -#define SAVE_Su (CurrentTSO->su) #define SAVE_SpLim (CurrentTSO->splim) -#define SAVE_Hp (MainRegTable.rHp) -#define SAVE_HpLim (MainRegTable.rHpLim) +#define SAVE_Hp (BaseReg->rHp) +#define SAVE_HpLim (BaseReg->rHpLim) + +#define SAVE_CurrentTSO (BaseReg->rCurrentTSO) +#define SAVE_CurrentNursery (BaseReg->rCurrentNursery) +#define SAVE_HpAlloc (BaseReg->rHpAlloc) +#if defined(SMP) || defined(PAR) +#define SAVE_SparkHd (BaseReg->rSparks.hd) +#define SAVE_SparkTl (BaseReg->rSparks.tl) +#define SAVE_SparkBase (BaseReg->rSparks.base) +#define SAVE_SparkLim (BaseReg->rSparks.lim) +#endif /* We sometimes need to save registers across a C-call, eg. if they * are clobbered in the standard calling convention. We define the * save locations for all registers in the register table. */ -#define SAVE_R1 (MainRegTable.rR1) -#define SAVE_R2 (MainRegTable.rR2) -#define SAVE_R3 (MainRegTable.rR3) -#define SAVE_R4 (MainRegTable.rR4) -#define SAVE_R5 (MainRegTable.rR5) -#define SAVE_R6 (MainRegTable.rR6) -#define SAVE_R7 (MainRegTable.rR7) -#define SAVE_R8 (MainRegTable.rR8) +#define SAVE_R1 (BaseReg->rR1) +#define SAVE_R2 (BaseReg->rR2) +#define SAVE_R3 (BaseReg->rR3) +#define SAVE_R4 (BaseReg->rR4) +#define SAVE_R5 (BaseReg->rR5) +#define SAVE_R6 (BaseReg->rR6) +#define SAVE_R7 (BaseReg->rR7) +#define SAVE_R8 (BaseReg->rR8) -#define SAVE_F1 (MainRegTable.rF1) -#define SAVE_F2 (MainRegTable.rF2) -#define SAVE_F3 (MainRegTable.rF3) -#define SAVE_F4 (MainRegTable.rF4) +#define SAVE_F1 (BaseReg->rF1) +#define SAVE_F2 (BaseReg->rF2) +#define SAVE_F3 (BaseReg->rF3) +#define SAVE_F4 (BaseReg->rF4) -#define SAVE_D1 (MainRegTable.rD1) -#define SAVE_D2 (MainRegTable.rD2) +#define SAVE_D1 (BaseReg->rD1) +#define SAVE_D2 (BaseReg->rD2) -#define SAVE_L1 (MainRegTable.rL1) +#define SAVE_L1 (BaseReg->rL1) /* ----------------------------------------------------------------------------- * Emit the GCC-specific register declarations for each machine @@ -224,7 +274,7 @@ GLOBAL_REG_DECL(StgDouble,D2,REG_D2) #endif #ifdef REG_L1 -GLOBAL_REG_DECL(StgNat64,L1,REG_L1) +GLOBAL_REG_DECL(StgWord64,L1,REG_L1) #else #define L1 (BaseReg->rL1) #endif @@ -238,7 +288,10 @@ GLOBAL_REG_DECL(StgNat64,L1,REG_L1) #ifdef REG_Base GLOBAL_REG_DECL(StgRegTable *,BaseReg,REG_Base) #else -#define BaseReg (&MainRegTable) +#ifdef SMP +#error BaseReg must be in a register for SMP +#endif +#define BaseReg (&MainCapability.r) #endif #ifdef REG_Sp @@ -247,12 +300,6 @@ GLOBAL_REG_DECL(P_,Sp,REG_Sp) #define Sp (BaseReg->rSp) #endif -#ifdef REG_Su -GLOBAL_REG_DECL(StgUpdateFrame *,Su,REG_Su) -#else -#define Su (BaseReg->rSu) -#endif - #ifdef REG_SpLim GLOBAL_REG_DECL(P_,SpLim,REG_SpLim) #else @@ -271,6 +318,79 @@ GLOBAL_REG_DECL(P_,HpLim,REG_HpLim) #define HpLim (BaseReg->rHpLim) #endif +#ifdef REG_CurrentTSO +GLOBAL_REG_DECL(StgTSO *,CurrentTSO,REG_CurrentTSO) +#else +#define CurrentTSO (BaseReg->rCurrentTSO) +#endif + +#ifdef REG_CurrentNursery +GLOBAL_REG_DECL(bdescr *,CurrentNursery,REG_CurrentNursery) +#else +#define CurrentNursery (BaseReg->rCurrentNursery) +#endif + +#ifdef REG_HpAlloc +GLOBAL_REG_DECL(bdescr *,HpAlloc,REG_HpAlloc) +#else +#define HpAlloc (BaseReg->rHpAlloc) +#endif + +#ifdef REG_SparkHd +GLOBAL_REG_DECL(bdescr *,SparkHd,REG_SparkHd) +#else +#define SparkHd (BaseReg->rSparks.hd) +#endif + +#ifdef REG_SparkTl +GLOBAL_REG_DECL(bdescr *,SparkTl,REG_SparkTl) +#else +#define SparkTl (BaseReg->rSparks.tl) +#endif + +#ifdef REG_SparkBase +GLOBAL_REG_DECL(bdescr *,SparkBase,REG_SparkBase) +#else +#define SparkBase (BaseReg->rSparks.base) +#endif + +#ifdef REG_SparkLim +GLOBAL_REG_DECL(bdescr *,SparkLim,REG_SparkLim) +#else +#define SparkLim (BaseReg->rSparks.lim) +#endif + +/* ----------------------------------------------------------------------------- + Get absolute function pointers from the register table, to save + code space. On x86, + + jmp *-12(%ebx) + + is shorter than + + jmp absolute_address + + as long as the offset is within the range of a signed byte + (-128..+127). So we pick some common absolute_addresses and put + them in the register table. As a bonus, linking time should also + be reduced. + + Other possible candidates in order of importance: + + stg_upd_frame_info + stg_CAF_BLACKHOLE_info + stg_IND_STATIC_info + + anything else probably isn't worth the effort. + + -------------------------------------------------------------------------- */ + + +#define FunReg ((StgFunTable *)((void *)BaseReg - sizeof(StgFunTable))) + +#define stg_gc_enter_1 (FunReg->stgGCEnter1) +#define stg_gc_fun (FunReg->stgGCFun) + /* ----------------------------------------------------------------------------- For any registers which are denoted "caller-saves" by the C calling convention, we have to emit code to save and restore them across C @@ -421,14 +541,6 @@ GLOBAL_REG_DECL(P_,HpLim,REG_HpLim) #define CALLER_RESTORE_Sp /* nothing */ #endif -#ifdef CALLER_SAVES_Su -#define CALLER_SAVE_Su SAVE_Su = Su; -#define CALLER_RESTORE_Su Su = SAVE_Su; -#else -#define CALLER_SAVE_Su /* nothing */ -#define CALLER_RESTORE_Su /* nothing */ -#endif - #ifdef CALLER_SAVES_SpLim #define CALLER_SAVE_SpLim SAVE_SpLim = SpLim; #define CALLER_RESTORE_SpLim SpLim = SAVE_SpLim; @@ -454,6 +566,9 @@ GLOBAL_REG_DECL(P_,HpLim,REG_HpLim) #endif #ifdef CALLER_SAVES_Base +#ifdef SMP +#error "Can't have caller-saved BaseReg with SMP" +#endif #define CALLER_SAVE_Base /* nothing */ #define CALLER_RESTORE_Base BaseReg = &MainRegTable; #else @@ -461,10 +576,70 @@ GLOBAL_REG_DECL(P_,HpLim,REG_HpLim) #define CALLER_RESTORE_Base /* nothing */ #endif +#ifdef CALLER_SAVES_CurrentTSO +#define CALLER_SAVE_CurrentTSO SAVE_CurrentTSO = CurrentTSO; +#define CALLER_RESTORE_CurrentTSO CurrentTSO = SAVE_CurrentTSO; +#else +#define CALLER_SAVE_CurrentTSO /* nothing */ +#define CALLER_RESTORE_CurrentTSO /* nothing */ +#endif + +#ifdef CALLER_SAVES_CurrentNursery +#define CALLER_SAVE_CurrentNursery SAVE_CurrentNursery = CurrentNursery; +#define CALLER_RESTORE_CurrentNursery CurrentNursery = SAVE_CurrentNursery; +#else +#define CALLER_SAVE_CurrentNursery /* nothing */ +#define CALLER_RESTORE_CurrentNursery /* nothing */ +#endif + +#ifdef CALLER_SAVES_HpAlloc +#define CALLER_SAVE_HpAlloc SAVE_HpAlloc = HpAlloc; +#define CALLER_RESTORE_HpAlloc HpAlloc = SAVE_HpAlloc; +#else +#define CALLER_SAVE_HpAlloc /* nothing */ +#define CALLER_RESTORE_HpAlloc /* nothing */ +#endif + +#ifdef CALLER_SAVES_SparkHd +#define CALLER_SAVE_SparkHd SAVE_SparkHd = SparkHd; +#define CALLER_RESTORE_SparkHd SparkHd = SAVE_SparkHd; +#else +#define CALLER_SAVE_SparkHd /* nothing */ +#define CALLER_RESTORE_SparkHd /* nothing */ +#endif + +#ifdef CALLER_SAVES_SparkTl +#define CALLER_SAVE_SparkTl SAVE_SparkTl = SparkTl; +#define CALLER_RESTORE_SparkTl SparkTl = SAVE_SparkTl; +#else +#define CALLER_SAVE_SparkTl /* nothing */ +#define CALLER_RESTORE_SparkTl /* nothing */ +#endif + +#ifdef CALLER_SAVES_SparkBase +#define CALLER_SAVE_SparkBase SAVE_SparkBase = SparkBase; +#define CALLER_RESTORE_SparkBase SparkBase = SAVE_SparkBase; +#else +#define CALLER_SAVE_SparkBase /* nothing */ +#define CALLER_RESTORE_SparkBase /* nothing */ +#endif + +#ifdef CALLER_SAVES_SparkLim +#define CALLER_SAVE_SparkLim SAVE_SparkLim = SparkLim; +#define CALLER_RESTORE_SparkLim SparkLim = SAVE_SparkLim; +#else +#define CALLER_SAVE_SparkLim /* nothing */ +#define CALLER_RESTORE_SparkLim /* nothing */ +#endif + +#endif /* IN_STG_CODE */ + /* ---------------------------------------------------------------------------- Handy bunches of saves/restores ------------------------------------------------------------------------ */ +#if IN_STG_CODE + #define CALLER_SAVE_USER \ CALLER_SAVE_R1 \ CALLER_SAVE_R2 \ @@ -482,12 +657,20 @@ GLOBAL_REG_DECL(P_,HpLim,REG_HpLim) CALLER_SAVE_D2 \ CALLER_SAVE_L1 + /* Save Base last, since the others may + be addressed relative to it */ #define CALLER_SAVE_SYSTEM \ CALLER_SAVE_Sp \ - CALLER_SAVE_Su \ CALLER_SAVE_SpLim \ CALLER_SAVE_Hp \ - CALLER_SAVE_HpLim + CALLER_SAVE_HpLim \ + CALLER_SAVE_CurrentTSO \ + CALLER_SAVE_CurrentNursery \ + CALLER_SAVE_SparkHd \ + CALLER_SAVE_SparkTl \ + CALLER_SAVE_SparkBase \ + CALLER_SAVE_SparkLim \ + CALLER_SAVE_Base #define CALLER_RESTORE_USER \ CALLER_RESTORE_R1 \ @@ -506,13 +689,29 @@ GLOBAL_REG_DECL(P_,HpLim,REG_HpLim) CALLER_RESTORE_D2 \ CALLER_RESTORE_L1 + /* Restore Base first, since the others may + be addressed relative to it */ #define CALLER_RESTORE_SYSTEM \ CALLER_RESTORE_Base \ CALLER_RESTORE_Sp \ - CALLER_RESTORE_Su \ CALLER_RESTORE_SpLim \ CALLER_RESTORE_Hp \ - CALLER_RESTORE_HpLim + CALLER_RESTORE_HpLim \ + CALLER_RESTORE_CurrentTSO \ + CALLER_RESTORE_CurrentNursery \ + CALLER_RESTORE_SparkHd \ + CALLER_RESTORE_SparkTl \ + CALLER_RESTORE_SparkBase \ + CALLER_RESTORE_SparkLim + +#else /* not IN_STG_CODE */ + +#define CALLER_SAVE_USER /* nothing */ +#define CALLER_SAVE_SYSTEM /* nothing */ +#define CALLER_RESTORE_USER /* nothing */ +#define CALLER_RESTORE_SYSTEM /* nothing */ + +#endif /* IN_STG_CODE */ #define CALLER_SAVE_ALL \ CALLER_SAVE_SYSTEM \