summaryrefslogtreecommitdiff
path: root/compiler/nativeGen/X86/CodeGen.hs
diff options
context:
space:
mode:
authorSimon Peyton Jones <simonpj@microsoft.com>2016-08-18 18:16:01 +0100
committerSimon Peyton Jones <simonpj@microsoft.com>2016-08-19 08:20:58 +0100
commitb2c5e4ce5c44a7be7c2b81c2600cae40c5b225ad (patch)
treeef56139032543cbef3ce4985501ff85421ce866c /compiler/nativeGen/X86/CodeGen.hs
parent113d50b791c469394d38fab6ce5b760e5e8c35e2 (diff)
downloadhaskell-b2c5e4ce5c44a7be7c2b81c2600cae40c5b225ad.tar.gz
Revert "codeGen: Remove binutils<2.17 hack, fixes T11758"
This reverts commit e3e2e49a8f6952e1c8a19321c729c17b294d8c92. I'm reverting because it makes ghc-stage2 seg-fault on 64-bit Windows machines. Even ghc-stage2 --version seg-faults.
Diffstat (limited to 'compiler/nativeGen/X86/CodeGen.hs')
-rw-r--r--compiler/nativeGen/X86/CodeGen.hs15
1 files changed, 14 insertions, 1 deletions
diff --git a/compiler/nativeGen/X86/CodeGen.hs b/compiler/nativeGen/X86/CodeGen.hs
index 2bfcd9a0c8..cd45d92418 100644
--- a/compiler/nativeGen/X86/CodeGen.hs
+++ b/compiler/nativeGen/X86/CodeGen.hs
@@ -2624,10 +2624,23 @@ genSwitch dflags expr targets
let op = OpAddr (AddrBaseIndex (EABaseReg tableReg)
(EAIndex reg (wORD_SIZE dflags)) (ImmInt 0))
- return $ e_code `appOL` t_code `appOL` toOL [
+ return $ if is32bit || os == OSDarwin
+ then e_code `appOL` t_code `appOL` toOL [
ADD (intFormat (wordWidth dflags)) op (OpReg tableReg),
JMP_TBL (OpReg tableReg) ids rosection lbl
]
+ else -- HACK: On x86_64 binutils<2.17 is only able to generate
+ -- PC32 relocations, hence we only get 32-bit offsets in
+ -- the jump table. As these offsets are always negative
+ -- we need to properly sign extend them to 64-bit. This
+ -- hack should be removed in conjunction with the hack in
+ -- PprMach.hs/pprDataItem once binutils 2.17 is standard.
+ e_code `appOL` t_code `appOL` toOL [
+ MOVSxL II32 op (OpReg reg),
+ ADD (intFormat (wordWidth dflags)) (OpReg reg)
+ (OpReg tableReg),
+ JMP_TBL (OpReg tableReg) ids rosection lbl
+ ]
| otherwise
= do
(reg,e_code) <- getSomeReg (cmmOffset dflags expr offset)