summaryrefslogtreecommitdiff
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-02-09 12:47:19 -0500
commit8d19ad783e7a9451f489c622a3ac88be4c03da0c (patch)
tree206f5f3da17adb3669a30a6b061c29df9349bc53
parentbd2897b7a948293104eb7f41c8563e0914199341 (diff)
downloadhaskell-8d19ad783e7a9451f489c622a3ac88be4c03da0c.tar.gz
Generate LEA for label expressions
-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 635070b610..b920c7ec05 100644
--- a/compiler/GHC/CmmToAsm/X86/CodeGen.hs
+++ b/compiler/GHC/CmmToAsm/X86/CodeGen.hs
@@ -1177,6 +1177,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.