diff options
author | Sergei Trofimovich <slyfox@gentoo.org> | 2014-09-04 17:50:45 +0300 |
---|---|---|
committer | Austin Seipp <austin@well-typed.com> | 2014-10-27 10:57:20 -0500 |
commit | 04e21ae3c47fba6d2f6ca0ecdbea394fbe1d881c (patch) | |
tree | ca71cfc38ef887eb40e7620cdd6ff9d6fa517e42 | |
parent | 39d0cad37a91591ae5be22200753206b57d0f169 (diff) | |
download | haskell-04e21ae3c47fba6d2f6ca0ecdbea394fbe1d881c.tar.gz |
pprC: declare extern cmm primitives as functions, not data
Summary:
The commit fixes incorrect code generation of
integer-gmp package on ia64 due to C prototypes mismatch.
Before the patch prototypes for "foreign import prim" were:
StgWord poizh[];
After the patch they became:
StgFunPtr poizh();
Long story:
Consider the following simple example:
{-# LANGUAGE MagicHash, GHCForeignImportPrim, UnliftedFFITypes #-}
module M where
import GHC.Prim -- Int#
foreign import prim "poizh" poi# :: Int# -> Int#
Before the patch unregisterised build generated the
following 'poizh' reference:
EI_(poizh); /* StgWord poizh[]; */
FN_(M_poizh_entry) {
// ...
JMP_((W_)&poizh);
}
After the patch it looks this way:
EF_(poizh); /* StgFunPtr poizh(); */
FN_(M_poizh_entry) {
// ...
JMP_((W_)&poizh);
}
On ia64 it leads to different relocation types being generated:
incorrect one:
addl r14 = @ltoffx(poizh#)
ld8.mov r14 = [r14], poizh# ; r14 = address-of 'poizh#'
correct one:
addl r14 = @ltoff(@fptr(poizh#)), gp ; r14 = address-of-thunk 'poizh#'
ld8 r14 = [r14]
'@fptr(poizh#)' basically instructs assembler to creates
another obect consisting of real address to 'poizh' instructions
and module address. That '@fptr' object is used as a function "address"
This object is different for every module referencing 'poizh' symbol.
All indirect function calls expect '@fptr' object. That way
call site reads real destination address and set destination
module address in 'gp' register from '@fptr'.
Signed-off-by: Sergei Trofimovich <slyfox@gentoo.org>
(cherry picked from commit e18525fae273f4c1ad8d6cbe1dea4fc074cac721)
-rw-r--r-- | compiler/cmm/CLabel.hs | 1 |
1 files changed, 1 insertions, 0 deletions
diff --git a/compiler/cmm/CLabel.hs b/compiler/cmm/CLabel.hs index 65c597cb69..991fc57b17 100644 --- a/compiler/cmm/CLabel.hs +++ b/compiler/cmm/CLabel.hs @@ -801,6 +801,7 @@ labelType (CmmLabel _ _ CmmClosure) = GcPtrLabel labelType (CmmLabel _ _ CmmCode) = CodeLabel labelType (CmmLabel _ _ CmmInfo) = DataLabel labelType (CmmLabel _ _ CmmEntry) = CodeLabel +labelType (CmmLabel _ _ CmmPrimCall) = CodeLabel labelType (CmmLabel _ _ CmmRetInfo) = DataLabel labelType (CmmLabel _ _ CmmRet) = CodeLabel labelType (RtsLabel (RtsSelectorInfoTable _ _)) = DataLabel |