summaryrefslogtreecommitdiff
path: root/compiler/GHC
diff options
context:
space:
mode:
authorBen Gamari <ben@well-typed.com>2022-01-20 13:50:20 -0500
committerBen Gamari <ben@smart-cactus.org>2022-04-06 15:24:01 -0400
commit52deee64d222d2bada5bda1c1e6a77f505f98656 (patch)
tree5733e01feb2f92d9870d2216787c7fe1f5f477df /compiler/GHC
parentce8745952f99174ad9d3bdc7697fd086b47cdfb5 (diff)
downloadhaskell-52deee64d222d2bada5bda1c1e6a77f505f98656.tar.gz
Generate LEA for label expressions
Diffstat (limited to 'compiler/GHC')
-rw-r--r--compiler/GHC/CmmToAsm/X86/CodeGen.hs16
1 files changed, 16 insertions, 0 deletions
diff --git a/compiler/GHC/CmmToAsm/X86/CodeGen.hs b/compiler/GHC/CmmToAsm/X86/CodeGen.hs
index d3902dad84..34f907b4f2 100644
--- a/compiler/GHC/CmmToAsm/X86/CodeGen.hs
+++ b/compiler/GHC/CmmToAsm/X86/CodeGen.hs
@@ -1158,6 +1158,22 @@ getRegister' _ is32Bit (CmmLit (CmmInt 0 width))
in
return (Any format code)
+-- Handle symbol references with LEA and %rip-relative addressing.
+-- See Note [%rip-relative addressing on x86-64].
+getRegister' platform is32Bit (CmmLit lit)
+ | is_label lit
+ , not is32Bit
+ = do let format = cmmTypeFormat (cmmLitType platform lit)
+ imm = litToImm lit
+ op = OpAddr (AddrBaseIndex EABaseRip EAIndexNone imm)
+ code dst = unitOL (LEA format op (OpReg dst))
+ return (Any format code)
+ where
+ is_label (CmmLabel {}) = True
+ is_label (CmmLabelOff {}) = True
+ is_label (CmmLabelDiffOff {}) = True
+ is_label _ = False
+
-- optimisation for loading small literals on x86_64: take advantage
-- of the automatic zero-extension from 32 to 64 bits, because the 32-bit
-- instruction forms are shorter.