import MachInstrs
import MachRegs
import NCGMonad
-import PositionIndependentCode ( cmmMakeDynamicReference, initializePicBase )
+import PositionIndependentCode
import RegAllocInfo ( mkBranchInstr )
-- Our intermediate code:
getRegister :: CmmExpr -> NatM Register
+#if !x86_64_TARGET_ARCH
+ -- on x86_64, we have %rip for PicBaseReg, but it's not a full-featured
+ -- register, it can only be used for rip-relative addressing.
getRegister (CmmReg (CmmGlobal PicBaseReg))
= do
reg <- getPicBaseNat wordRep
return (Fixed wordRep reg nilOL)
+#endif
getRegister (CmmReg reg)
= return (Fixed (cmmRegRep reg) (getRegisterReg reg) nilOL)
getRegister (CmmLit (CmmFloat f F32)) = do
lbl <- getNewLabelNat
- dynRef <- cmmMakeDynamicReference addImportNat False lbl
+ dynRef <- cmmMakeDynamicReference addImportNat DataReference lbl
Amode addr addr_code <- getAmode dynRef
let code dst =
LDATA ReadOnlyData
| otherwise = do
lbl <- getNewLabelNat
- dynRef <- cmmMakeDynamicReference addImportNat False lbl
+ dynRef <- cmmMakeDynamicReference addImportNat DataReference lbl
Amode addr addr_code <- getAmode dynRef
let code dst =
LDATA ReadOnlyData
#endif
#if x86_64_TARGET_ARCH
+getRegister (CmmMachOp (MO_Add I64) [CmmReg (CmmGlobal PicBaseReg),
+ CmmLit displacement])
+ = return $ Any I64 (\dst -> unitOL $
+ LEA I64 (OpAddr (ripRel (litToImm displacement))) (OpReg dst))
+#endif
+
+#if x86_64_TARGET_ARCH
getRegister (CmmMachOp (MO_S_Neg F32) [x]) = do
x_code <- getAnyReg x
lbl <- getNewLabelNat
getRegister (CmmLit (CmmFloat f frep)) = do
lbl <- getNewLabelNat
- dynRef <- cmmMakeDynamicReference addImportNat False lbl
+ dynRef <- cmmMakeDynamicReference addImportNat DataReference lbl
Amode addr addr_code <- getAmode dynRef
let code dst =
LDATA ReadOnlyData [CmmDataLabel lbl,
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+#if x86_64_TARGET_ARCH
+
+getAmode (CmmMachOp (MO_Add I64) [CmmReg (CmmGlobal PicBaseReg),
+ CmmLit displacement])
+ = return $ Amode (ripRel (litToImm displacement)) nilOL
+
+#endif
+
#if i386_TARGET_ARCH || x86_64_TARGET_ARCH
-- This is all just ridiculous, since it carefully undoes
-> Maybe [GlobalReg] -> NatM InstrBlock
outOfLineFloatOp mop res args vols
= do
- targetExpr <- cmmMakeDynamicReference addImportNat True lbl
+ targetExpr <- cmmMakeDynamicReference addImportNat CallReference lbl
let target = CmmForeignCall targetExpr CCallConv
if cmmRegRep res == F64
let
fp_regs_used = reverse (drop (length fregs) (reverse allFPArgRegs))
int_regs_used = reverse (drop (length aregs) (reverse allArgRegs))
- arg_regs = int_regs_used ++ fp_regs_used
+ arg_regs = [eax] ++ int_regs_used ++ fp_regs_used
-- for annotating the call instruction with
sse_regs = length fp_regs_used
)
outOfLineFloatOp mop =
do
- mopExpr <- cmmMakeDynamicReference addImportNat True $
+ mopExpr <- cmmMakeDynamicReference addImportNat CallReference $
mkForeignLabel functionName Nothing True
let mopLabelOrExpr = case mopExpr of
CmmLit (CmmLabel lbl) -> Left lbl
frame just before ccalling.
-}
+
+genCCall (CmmPrim MO_WriteBarrier) _ _ _
+ = return $ unitOL LWSYNC
+
genCCall target dest_regs argsAndHints vols
= ASSERT (not $ any (`elem` [I8,I16]) argReps)
-- we rely on argument promotion in the codeGen
outOfLineFloatOp mop =
do
- mopExpr <- cmmMakeDynamicReference addImportNat True $
+ mopExpr <- cmmMakeDynamicReference addImportNat CallReference $
mkForeignLabel functionName Nothing True
let mopLabelOrExpr = case mopExpr of
CmmLit (CmmLabel lbl) -> Left lbl
= do
(reg,e_code) <- getSomeReg expr
lbl <- getNewLabelNat
- dynRef <- cmmMakeDynamicReference addImportNat False lbl
+ dynRef <- cmmMakeDynamicReference addImportNat DataReference lbl
(tableReg,t_code) <- getSomeReg $ dynRef
let
jumpTable = map jumpTableEntryRel ids
op = OpAddr (AddrBaseIndex (EABaseReg tableReg)
(EAIndex reg wORD_SIZE) (ImmInt 0))
+#if x86_64_TARGET_ARCH && darwin_TARGET_OS
+ -- on Mac OS X/x86_64, put the jump table in the text section
+ -- to work around a limitation of the linker.
+ -- ld64 is unable to handle the relocations for
+ -- .quad L1 - L0
+ -- if L0 is not preceded by a non-anonymous label in its section.
+
+ code = e_code `appOL` t_code `appOL` toOL [
+ ADD wordRep op (OpReg tableReg),
+ JMP_TBL (OpReg tableReg) [ id | Just id <- ids ],
+ LDATA Text (CmmDataLabel lbl : jumpTable)
+ ]
+#else
code = e_code `appOL` t_code `appOL` toOL [
LDATA ReadOnlyData (CmmDataLabel lbl : jumpTable),
ADD wordRep op (OpReg tableReg),
JMP_TBL (OpReg tableReg) [ id | Just id <- ids ]
]
+#endif
return code
| otherwise
= do
(reg,e_code) <- getSomeReg expr
tmp <- getNewRegNat I32
lbl <- getNewLabelNat
- dynRef <- cmmMakeDynamicReference addImportNat False lbl
+ dynRef <- cmmMakeDynamicReference addImportNat DataReference lbl
(tableReg,t_code) <- getSomeReg $ dynRef
let
jumpTable = map jumpTableEntryRel ids
lbl <- getNewLabelNat
itmp <- getNewRegNat I32
ftmp <- getNewRegNat F64
- dynRef <- cmmMakeDynamicReference addImportNat False lbl
+ dynRef <- cmmMakeDynamicReference addImportNat DataReference lbl
Amode addr addr_code <- getAmode dynRef
let
code' dst = code `appOL` maybe_exts `appOL` toOL [