summaryrefslogtreecommitdiff
path: root/compiler/GHC/CmmToLlvm
diff options
context:
space:
mode:
authorAndreas Schwab <schwab@suse.de>2020-11-20 21:48:25 +0100
committerMarge Bot <ben+marge-bot@smart-cactus.org>2021-04-19 15:40:25 -0400
commit8b5e5b0524f614679a20ffaebab731c54dc6dee9 (patch)
treea9122d0912955c43b44cbe5734b32ba700af5c29 /compiler/GHC/CmmToLlvm
parent0b398d554f0cc2f5341ccf62f40347c9c025767f (diff)
downloadhaskell-8b5e5b0524f614679a20ffaebab731c54dc6dee9.tar.gz
Enable tables next to code for riscv64
This requires adding another rewrite to the mangler, to avoid generating PLT entries.
Diffstat (limited to 'compiler/GHC/CmmToLlvm')
-rw-r--r--compiler/GHC/CmmToLlvm/Mangler.hs23
1 files changed, 22 insertions, 1 deletions
diff --git a/compiler/GHC/CmmToLlvm/Mangler.hs b/compiler/GHC/CmmToLlvm/Mangler.hs
index 805f1b8074..4313294294 100644
--- a/compiler/GHC/CmmToLlvm/Mangler.hs
+++ b/compiler/GHC/CmmToLlvm/Mangler.hs
@@ -43,7 +43,7 @@ llvmFixupAsm logger dflags f1 f2 = {-# SCC "llvm_mangler" #-}
-- | These are the rewrites that the mangler will perform
rewrites :: [Rewrite]
-rewrites = [rewriteSymType, rewriteAVX]
+rewrites = [rewriteSymType, rewriteAVX, rewriteCall]
type Rewrite = DynFlags -> B.ByteString -> Maybe B.ByteString
@@ -107,6 +107,27 @@ rewriteAVX dflags s
isVmovdqa = B.isPrefixOf (B.pack "vmovdqa")
isVmovap = B.isPrefixOf (B.pack "vmovap")
+-- | This rewrites (tail) calls to avoid creating PLT entries for
+-- functions on riscv64. The replacement will load the address from the
+-- GOT, which is resolved to point to the real address of the function.
+rewriteCall :: Rewrite
+rewriteCall dflags l
+ | not isRISCV64 = Nothing
+ | isCall l = Just $ replaceCall "call" "jalr" "ra" l
+ | isTail l = Just $ replaceCall "tail" "jr" "t1" l
+ | otherwise = Nothing
+ where
+ isRISCV64 = platformArch (targetPlatform dflags) == ArchRISCV64
+ isCall = B.isPrefixOf (B.pack "call\t")
+ isTail = B.isPrefixOf (B.pack "tail\t")
+
+ replaceCall call jump reg l =
+ appendInsn (jump ++ "\t" ++ reg) $ removePlt $
+ replaceOnce (B.pack call) (B.pack ("la\t" ++ reg ++ ",")) l
+ where
+ removePlt = replaceOnce (B.pack "@plt") (B.pack "")
+ appendInsn i = (`B.append` B.pack ("\n\t" ++ i))
+
-- | @replaceOnce match replace bs@ replaces the first occurrence of the
-- substring @match@ in @bs@ with @replace@.
replaceOnce :: B.ByteString -> B.ByteString -> B.ByteString -> B.ByteString