X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=ghc%2Fincludes%2FRegs.h;h=614499e89fb537ceaa6d798bacabd79e8f9beabf;hb=027587234cb35e5c9d9ace090c2fe8d1d8df93f4;hp=4c2f911eb517f3c362214d100d4d580618771bf3;hpb=111cee3f1ad93816cb828e38b38521d85c3bcebb;p=ghc-hetmet.git diff --git a/ghc/includes/Regs.h b/ghc/includes/Regs.h index 4c2f911..614499e 100644 --- a/ghc/includes/Regs.h +++ b/ghc/includes/Regs.h @@ -1,20 +1,27 @@ /* ----------------------------------------------------------------------------- - * $Id: Regs.h,v 1.9 2000/03/23 17:45:31 simonpj Exp $ * - * (c) The GHC Team, 1998-1999 + * (c) The GHC Team, 1998-2004 * - * Registers used in STG code. Might or might not correspond to - * actual machine registers. + * Registers in the STG machine. + * + * The STG machine has a collection of "registers", each one of which + * may or may not correspond to an actual machine register when + * running code. + * + * The register set is backed by a table in memory (struct + * StgRegTable). If a particular STG register is not mapped to a + * machine register, then the apprpriate slot in this table is used + * instead. + * + * This table is itself pointed to by another register, BaseReg. If + * BaseReg is not in a machine register, then the register table is + * used from an absolute location (MainCapability). * * ---------------------------------------------------------------------------*/ #ifndef REGS_H #define REGS_H -/* - * This file should do the right thing if we have no machine-registers - * defined, i.e. everything lives in the RegTable. - */ /* * This is the table that holds shadow-locations for all the STG @@ -32,6 +39,30 @@ typedef struct StgSparkPool_ { StgClosure **tl; } StgSparkPool; +typedef struct { + StgFunPtr stgGCEnter1; + StgFunPtr stgGCFun; +} StgFunTable; + +/* + * Vanilla registers are given this union type, which is purely so + * that we can cast the vanilla reg to a variety of types with the + * minimum of syntax. eg. R1.w instead of (StgWord)R1. + */ +typedef union { + StgWord w; + StgAddr a; + StgChar c; + StgInt8 i8; + StgFloat f; + StgInt i; + StgPtr p; + StgClosurePtr cl; + StgStackOffset offset; /* unused? */ + StgByteArray b; + StgTSOPtr t; +} StgUnion; + typedef struct StgRegTable_ { StgUnion rR1; StgUnion rR2; @@ -41,8 +72,8 @@ typedef struct StgRegTable_ { 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; @@ -51,26 +82,41 @@ typedef struct StgRegTable_ { StgDouble rD2; StgWord64 rL1; StgPtr rSp; - StgUpdateFrame *rSu; StgPtr rSpLim; StgPtr rHp; StgPtr rHpLim; - StgTSO *rCurrentTSO; - struct _bdescr *rNursery; - struct _bdescr *rCurrentNursery; + struct StgTSO_ *rCurrentTSO; + struct bdescr_ *rNursery; + struct bdescr_ *rCurrentNursery; + StgWord rHpAlloc; // number of *bytes* being allocated in heap #if defined(SMP) || defined(PAR) - StgSparkPool rSparks; /* per-task spark pool */ + StgSparkPool rSparks; // per-task spark pool #endif +} StgRegTable; + + +/* 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 StgRegTable_ *link; /* per-task register tables are linked together */ + struct Capability_ *link; /* per-task register tables are linked together */ #endif -} StgRegTable; +} Capability; -/* No such thing as a MainRegTable under SMP - each thread must - * have its own MainRegTable. +/* No such thing as a MainCapability under SMP - each thread must have + * its own Capability. */ #ifndef SMP -extern DLL_IMPORT_RTS StgRegTable MainRegTable; +#if IN_STG_CODE +extern W_ MainCapability[]; +#else +extern DLL_IMPORT_RTS Capability MainCapability; +#endif #endif #if IN_STG_CODE @@ -79,7 +125,7 @@ extern DLL_IMPORT_RTS StgRegTable MainRegTable; * 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 @@ -105,7 +151,6 @@ extern DLL_IMPORT_RTS StgRegTable MainRegTable; */ #define SAVE_Sp (CurrentTSO->sp) -#define SAVE_Su (CurrentTSO->su) #define SAVE_SpLim (CurrentTSO->splim) #define SAVE_Hp (BaseReg->rHp) @@ -113,12 +158,11 @@ extern DLL_IMPORT_RTS StgRegTable MainRegTable; #define SAVE_CurrentTSO (BaseReg->rCurrentTSO) #define SAVE_CurrentNursery (BaseReg->rCurrentNursery) -#if defined(SMP) || defined(PAR) +#define SAVE_HpAlloc (BaseReg->rHpAlloc) #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 @@ -159,105 +203,109 @@ extern DLL_IMPORT_RTS StgRegTable MainRegTable; * again for no good reason (on register-poor architectures). */ +/* define NO_REGS to omit register declarations - used in RTS C code + * that needs all the STG definitions but not the global register + * settings. + */ #define GLOBAL_REG_DECL(type,name,reg) register type name REG(reg); -#ifdef REG_R1 +#if defined(REG_R1) && !defined(NO_GLOBAL_REG_DECLS) GLOBAL_REG_DECL(StgUnion,R1,REG_R1) #else -#define R1 (BaseReg->rR1) +# define R1 (BaseReg->rR1) #endif -#ifdef REG_R2 +#if defined(REG_R2) && !defined(NO_GLOBAL_REG_DECLS) GLOBAL_REG_DECL(StgUnion,R2,REG_R2) #else -#define R2 (BaseReg->rR2) +# define R2 (BaseReg->rR2) #endif -#ifdef REG_R3 +#if defined(REG_R3) && !defined(NO_GLOBAL_REG_DECLS) GLOBAL_REG_DECL(StgUnion,R3,REG_R3) #else # define R3 (BaseReg->rR3) #endif -#ifdef REG_R4 +#if defined(REG_R4) && !defined(NO_GLOBAL_REG_DECLS) GLOBAL_REG_DECL(StgUnion,R4,REG_R4) #else # define R4 (BaseReg->rR4) #endif -#ifdef REG_R5 +#if defined(REG_R5) && !defined(NO_GLOBAL_REG_DECLS) GLOBAL_REG_DECL(StgUnion,R5,REG_R5) #else # define R5 (BaseReg->rR5) #endif -#ifdef REG_R6 +#if defined(REG_R6) && !defined(NO_GLOBAL_REG_DECLS) GLOBAL_REG_DECL(StgUnion,R6,REG_R6) #else # define R6 (BaseReg->rR6) #endif -#ifdef REG_R7 +#if defined(REG_R7) && !defined(NO_GLOBAL_REG_DECLS) GLOBAL_REG_DECL(StgUnion,R7,REG_R7) #else # define R7 (BaseReg->rR7) #endif -#ifdef REG_R8 +#if defined(REG_R8) && !defined(NO_GLOBAL_REG_DECLS) GLOBAL_REG_DECL(StgUnion,R8,REG_R8) #else # define R8 (BaseReg->rR8) #endif -#ifdef REG_R9 +#if defined(REG_R9) && !defined(NO_GLOBAL_REG_DECLS) GLOBAL_REG_DECL(StgUnion,R9,REG_R9) #else # define R9 (BaseReg->rR9) #endif -#ifdef REG_R10 +#if defined(REG_R10) && !defined(NO_GLOBAL_REG_DECLS) GLOBAL_REG_DECL(StgUnion,R10,REG_R10) #else # define R10 (BaseReg->rR10) #endif -#ifdef REG_F1 +#if defined(REG_F1) && !defined(NO_GLOBAL_REG_DECLS) GLOBAL_REG_DECL(StgFloat,F1,REG_F1) #else #define F1 (BaseReg->rF1) #endif -#ifdef REG_F2 +#if defined(REG_F2) && !defined(NO_GLOBAL_REG_DECLS) GLOBAL_REG_DECL(StgFloat,F2,REG_F2) #else #define F2 (BaseReg->rF2) #endif -#ifdef REG_F3 +#if defined(REG_F3) && !defined(NO_GLOBAL_REG_DECLS) GLOBAL_REG_DECL(StgFloat,F3,REG_F3) #else #define F3 (BaseReg->rF3) #endif -#ifdef REG_F4 +#if defined(REG_F4) && !defined(NO_GLOBAL_REG_DECLS) GLOBAL_REG_DECL(StgFloat,F4,REG_F4) #else #define F4 (BaseReg->rF4) #endif -#ifdef REG_D1 +#if defined(REG_D1) && !defined(NO_GLOBAL_REG_DECLS) GLOBAL_REG_DECL(StgDouble,D1,REG_D1) #else #define D1 (BaseReg->rD1) #endif -#ifdef REG_D2 +#if defined(REG_D2) && !defined(NO_GLOBAL_REG_DECLS) GLOBAL_REG_DECL(StgDouble,D2,REG_D2) #else #define D2 (BaseReg->rD2) #endif -#ifdef REG_L1 +#if defined(REG_L1) && !defined(NO_GLOBAL_REG_DECLS) GLOBAL_REG_DECL(StgWord64,L1,REG_L1) #else #define L1 (BaseReg->rL1) @@ -269,82 +317,113 @@ GLOBAL_REG_DECL(StgWord64,L1,REG_L1) * concurrent Haskell, MainRegTable otherwise). */ -#ifdef REG_Base +#if defined(REG_Base) && !defined(NO_GLOBAL_REG_DECLS) GLOBAL_REG_DECL(StgRegTable *,BaseReg,REG_Base) #else #ifdef SMP #error BaseReg must be in a register for SMP #endif -#define BaseReg (&MainRegTable) +#define BaseReg (&((Capability *)MainCapability)[0].r) #endif -#ifdef REG_Sp +#if defined(REG_Sp) && !defined(NO_GLOBAL_REG_DECLS) GLOBAL_REG_DECL(P_,Sp,REG_Sp) #else #define Sp (BaseReg->rSp) #endif -#ifdef REG_Su -GLOBAL_REG_DECL(StgUpdateFrame *,Su,REG_Su) -#else -#define Su (BaseReg->rSu) -#endif - -#ifdef REG_SpLim +#if defined(REG_SpLim) && !defined(NO_GLOBAL_REG_DECLS) GLOBAL_REG_DECL(P_,SpLim,REG_SpLim) #else #define SpLim (BaseReg->rSpLim) #endif -#ifdef REG_Hp +#if defined(REG_Hp) && !defined(NO_GLOBAL_REG_DECLS) GLOBAL_REG_DECL(P_,Hp,REG_Hp) #else #define Hp (BaseReg->rHp) #endif -#ifdef REG_HpLim +#if defined(REG_HpLim) && !defined(NO_GLOBAL_REG_DECLS) GLOBAL_REG_DECL(P_,HpLim,REG_HpLim) #else #define HpLim (BaseReg->rHpLim) #endif -#ifdef REG_CurrentTSO -GLOBAL_REG_DECL(StgTSO *,CurrentTSO,REG_CurrentTSO) +#if defined(REG_CurrentTSO) && !defined(NO_GLOBAL_REG_DECLS) +GLOBAL_REG_DECL(struct _StgTSO *,CurrentTSO,REG_CurrentTSO) #else #define CurrentTSO (BaseReg->rCurrentTSO) #endif -#ifdef REG_CurrentNursery +#if defined(REG_CurrentNursery) && !defined(NO_GLOBAL_REG_DECLS) GLOBAL_REG_DECL(bdescr *,CurrentNursery,REG_CurrentNursery) #else #define CurrentNursery (BaseReg->rCurrentNursery) #endif -#ifdef REG_SparkHd +#if defined(REG_HpAlloc) && !defined(NO_GLOBAL_REG_DECLS) +GLOBAL_REG_DECL(bdescr *,HpAlloc,REG_HpAlloc) +#else +#define HpAlloc (BaseReg->rHpAlloc) +#endif + +#if defined(REG_SparkHd) && !defined(NO_GLOBAL_REG_DECLS) GLOBAL_REG_DECL(bdescr *,SparkHd,REG_SparkHd) #else #define SparkHd (BaseReg->rSparks.hd) #endif -#ifdef REG_SparkTl +#if defined(REG_SparkTl) && !defined(NO_GLOBAL_REG_DECLS) GLOBAL_REG_DECL(bdescr *,SparkTl,REG_SparkTl) #else #define SparkTl (BaseReg->rSparks.tl) #endif -#ifdef REG_SparkBase +#if defined(REG_SparkBase) && !defined(NO_GLOBAL_REG_DECLS) GLOBAL_REG_DECL(bdescr *,SparkBase,REG_SparkBase) #else #define SparkBase (BaseReg->rSparks.base) #endif -#ifdef REG_SparkLim +#if defined(REG_SparkLim) && !defined(NO_GLOBAL_REG_DECLS) 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 calls. @@ -494,14 +573,6 @@ GLOBAL_REG_DECL(bdescr *,SparkLim,REG_SparkLim) #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; @@ -553,6 +624,14 @@ GLOBAL_REG_DECL(bdescr *,SparkLim,REG_SparkLim) #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; @@ -614,7 +693,6 @@ GLOBAL_REG_DECL(bdescr *,SparkLim,REG_SparkLim) be addressed relative to it */ #define CALLER_SAVE_SYSTEM \ CALLER_SAVE_Sp \ - CALLER_SAVE_Su \ CALLER_SAVE_SpLim \ CALLER_SAVE_Hp \ CALLER_SAVE_HpLim \ @@ -648,7 +726,6 @@ GLOBAL_REG_DECL(bdescr *,SparkLim,REG_SparkLim) #define CALLER_RESTORE_SYSTEM \ CALLER_RESTORE_Base \ CALLER_RESTORE_Sp \ - CALLER_RESTORE_Su \ CALLER_RESTORE_SpLim \ CALLER_RESTORE_Hp \ CALLER_RESTORE_HpLim \ @@ -667,7 +744,6 @@ GLOBAL_REG_DECL(bdescr *,SparkLim,REG_SparkLim) #define CALLER_RESTORE_SYSTEM /* nothing */ #endif /* IN_STG_CODE */ - #define CALLER_SAVE_ALL \ CALLER_SAVE_SYSTEM \ CALLER_SAVE_USER @@ -677,4 +753,3 @@ GLOBAL_REG_DECL(bdescr *,SparkLim,REG_SparkLim) CALLER_RESTORE_USER #endif /* REGS_H */ -