diff options
-rw-r--r-- | compiler/cmm/CLabel.hs | 8 | ||||
-rw-r--r-- | compiler/cmm/PprC.hs | 5 | ||||
-rw-r--r-- | includes/Stg.h | 20 | ||||
-rw-r--r-- | includes/stg/MiscClosures.h | 15 |
4 files changed, 40 insertions, 8 deletions
diff --git a/compiler/cmm/CLabel.hs b/compiler/cmm/CLabel.hs index 9304d66323..15c5ff3481 100644 --- a/compiler/cmm/CLabel.hs +++ b/compiler/cmm/CLabel.hs @@ -88,8 +88,9 @@ module CLabel ( mkForeignLabel, addLabelSize, - foreignLabelStdcallInfo, + foreignLabelStdcallInfo, + isForeignLabel, mkCCLabel, mkCCSLabel, DynamicLinkerLabelInfo(..), @@ -492,6 +493,11 @@ addLabelSize (ForeignLabel str _ src fod) sz addLabelSize label _ = label +-- | Whether label is a non-haskell label (defined in C code) +isForeignLabel :: CLabel -> Bool +isForeignLabel (ForeignLabel _ _ _ _) = True +isForeignLabel _lbl = False + -- | Get the label size field from a ForeignLabel foreignLabelStdcallInfo :: CLabel -> Maybe Int foreignLabelStdcallInfo (ForeignLabel _ info _ _) = info diff --git a/compiler/cmm/PprC.hs b/compiler/cmm/PprC.hs index c269530409..673ac2d5bd 100644 --- a/compiler/cmm/PprC.hs +++ b/compiler/cmm/PprC.hs @@ -264,7 +264,7 @@ pprStmt stmt = -- We also need to cast mem primops to prevent conflicts with GCC -- builtins (see bug #5967). | Just _align <- machOpMemcpyishAlign op - = (text ";EF_(" <> fn <> char ')' <> semi) $$ + = (text ";EFF_(" <> fn <> char ')' <> semi) $$ pprForeignCall fn cconv hresults hargs | otherwise = pprCall fn cconv hresults hargs @@ -1005,7 +1005,8 @@ pprExternDecl _in_srt lbl hcat [ visibility, label_type lbl, lparen, ppr lbl, text ");" ] where - label_type lbl | isCFunctionLabel lbl = text "F_" + label_type lbl | isForeignLabel lbl && isCFunctionLabel lbl = text "FF_" + | isCFunctionLabel lbl = text "F_" | otherwise = text "I_" visibility diff --git a/includes/Stg.h b/includes/Stg.h index 899e685635..a8ab5ca8e8 100644 --- a/includes/Stg.h +++ b/includes/Stg.h @@ -222,11 +222,21 @@ typedef StgFunPtr F_; #define II_(X) static StgWordArray (X) GNU_ATTRIBUTE(aligned (8)) #define IF_(f) static StgFunPtr GNUC3_ATTRIBUTE(used) f(void) #define FN_(f) StgFunPtr f(void) -#define EF_(f) extern StgFunPtr f() /* See Note [External function prototypes] */ +#define EF_(f) StgFunPtr f(void) /* External Cmm functions */ +#define EFF_(f) void f() /* See Note [External function prototypes] */ -/* Note [External function prototypes] See Trac #8965 +/* Note [External function prototypes] See Trac #8965, #11395 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -The external-function macro EF_(F) used to be defined as +In generated C code we need to distinct between two types +of external symbols: +1. Cmm functions declared by 'EF_' macro (External Functions) +2. C functions declared by 'EFF_' macro (External Foreign Functions) + +Cmm functions are simple as they are internal to GHC. + +C functions are trickier: + +The external-function macro EFF_(F) used to be defined as extern StgFunPtr f(void) i.e a function of zero arguments. On most platforms this doesn't matter very much: calls to these functions put the parameters in the @@ -249,6 +259,10 @@ unspecified argument list rather than a void argument list. This is no worse for platforms that don't care either way, and allows a successful bootstrap of GHC 7.8 on little-endian Linux ppc64 (which uses the ELFv2 ABI). + +Another case is m68k ABI where 'void*' return type is returned by 'a0' +register while 'long' return type is returned by 'd0'. Thus we trick +external prototype return neither of these types to workaround #11395. */ diff --git a/includes/stg/MiscClosures.h b/includes/stg/MiscClosures.h index 5f5e0d6a1d..3fd412820b 100644 --- a/includes/stg/MiscClosures.h +++ b/includes/stg/MiscClosures.h @@ -490,8 +490,19 @@ extern StgWord RTS_VAR(CCS_LIST); /* registered CCS list */ extern StgWord CCS_SYSTEM[]; extern unsigned int RTS_VAR(CC_ID); /* global ids */ extern unsigned int RTS_VAR(CCS_ID); -RTS_FUN_DECL(enterFunCCS); -RTS_FUN_DECL(pushCostCentre); + +// Calls to these rts functions are generated directly +// by codegen (see compiler/codeGen/StgCmmProf.hs) +// and don't require (don't emit) forward declarations. +// +// In unregisterised mode (when building via .hc files) +// the calls are ordinary C calls. Functions must be in +// scope and must match prototype assumed by +// 'compiler/codeGen/StgCmmProf.hs' +// as opposed to real prototype declared in +// 'includes/rts/prof/CCS.h' +void enterFunCCS (void *reg, void *ccsfn); +void * pushCostCentre (void *ccs, void *cc); // Capability.c extern unsigned int n_capabilities; |