diff options
author | Sylvain Henry <sylvain@haskus.fr> | 2020-03-09 19:59:01 +0100 |
---|---|---|
committer | Marge Bot <ben+marge-bot@smart-cactus.org> | 2020-03-19 12:16:49 -0400 |
commit | 64f207566931469648e791df4f0f0384d45cddd0 (patch) | |
tree | 58e8a6e27d192368b1ddbc47e9bb89046b2a24a4 /compiler/GHC/CmmToAsm | |
parent | b03fd3bcd4ff14aed2942275c3b0db5392dc913c (diff) | |
download | haskell-64f207566931469648e791df4f0f0384d45cddd0.tar.gz |
Refactoring: use Platform instead of DynFlags when possible
Metric Decrease:
ManyConstructors
T12707
T13035
T1969
Diffstat (limited to 'compiler/GHC/CmmToAsm')
-rw-r--r-- | compiler/GHC/CmmToAsm/PIC.hs | 82 | ||||
-rw-r--r-- | compiler/GHC/CmmToAsm/PPC/CodeGen.hs | 153 | ||||
-rw-r--r-- | compiler/GHC/CmmToAsm/PPC/Ppr.hs | 3 | ||||
-rw-r--r-- | compiler/GHC/CmmToAsm/SPARC/CodeGen.hs | 54 | ||||
-rw-r--r-- | compiler/GHC/CmmToAsm/SPARC/CodeGen/Amode.hs | 4 | ||||
-rw-r--r-- | compiler/GHC/CmmToAsm/SPARC/CodeGen/Base.hs | 7 | ||||
-rw-r--r-- | compiler/GHC/CmmToAsm/SPARC/CodeGen/CondCode.hs | 6 | ||||
-rw-r--r-- | compiler/GHC/CmmToAsm/SPARC/CodeGen/Gen32.hs | 16 | ||||
-rw-r--r-- | compiler/GHC/CmmToAsm/SPARC/Ppr.hs | 19 | ||||
-rw-r--r-- | compiler/GHC/CmmToAsm/X86/CodeGen.hs | 480 | ||||
-rw-r--r-- | compiler/GHC/CmmToAsm/X86/Ppr.hs | 7 |
11 files changed, 414 insertions, 417 deletions
diff --git a/compiler/GHC/CmmToAsm/PIC.hs b/compiler/GHC/CmmToAsm/PIC.hs index d4d8b55e7e..a9668133fc 100644 --- a/compiler/GHC/CmmToAsm/PIC.hs +++ b/compiler/GHC/CmmToAsm/PIC.hs @@ -120,10 +120,12 @@ cmmMakeDynamicReference dflags referenceKind lbl | otherwise = do this_mod <- getThisModule + let config = initConfig dflags + platform = ncgPlatform config case howToAccessLabel dflags - (platformArch $ targetPlatform dflags) - (platformOS $ targetPlatform dflags) + (platformArch platform) + (platformOS platform) this_mod referenceKind lbl of @@ -135,11 +137,11 @@ cmmMakeDynamicReference dflags referenceKind lbl AccessViaSymbolPtr -> do let symbolPtr = mkDynamicLinkerLabel SymbolPtr lbl addImport symbolPtr - return $ CmmLoad (cmmMakePicReference dflags symbolPtr) (bWord dflags) + return $ CmmLoad (cmmMakePicReference config symbolPtr) (bWord platform) AccessDirectly -> case referenceKind of -- for data, we might have to make some calculations: - DataReference -> return $ cmmMakePicReference dflags lbl + DataReference -> return $ cmmMakePicReference config lbl -- all currently supported processors support -- PC-relative branch and call instructions, -- so just jump there if it's a call or a jump @@ -153,42 +155,44 @@ cmmMakeDynamicReference dflags referenceKind lbl -- offset to our base register; this offset is calculated by -- the function picRelative in the platform-dependent part below. -cmmMakePicReference :: DynFlags -> CLabel -> CmmExpr -cmmMakePicReference dflags lbl - - -- Windows doesn't need PIC, - -- everything gets relocated at runtime - | OSMinGW32 <- platformOS $ targetPlatform dflags - = CmmLit $ CmmLabel lbl - - | OSAIX <- platformOS $ targetPlatform dflags - = CmmMachOp (MO_Add W32) - [ CmmReg (CmmGlobal PicBaseReg) - , CmmLit $ picRelative (wordWidth dflags) - (platformArch $ targetPlatform dflags) - (platformOS $ targetPlatform dflags) - lbl ] - - -- both ABI versions default to medium code model - | ArchPPC_64 _ <- platformArch $ targetPlatform dflags - = CmmMachOp (MO_Add W32) -- code model medium - [ CmmReg (CmmGlobal PicBaseReg) - , CmmLit $ picRelative (wordWidth dflags) - (platformArch $ targetPlatform dflags) - (platformOS $ targetPlatform dflags) - lbl ] - - | (positionIndependent dflags || gopt Opt_ExternalDynamicRefs dflags) - && absoluteLabel lbl - = CmmMachOp (MO_Add (wordWidth dflags)) - [ CmmReg (CmmGlobal PicBaseReg) - , CmmLit $ picRelative (wordWidth dflags) - (platformArch $ targetPlatform dflags) - (platformOS $ targetPlatform dflags) - lbl ] +cmmMakePicReference :: NCGConfig -> CLabel -> CmmExpr +cmmMakePicReference config lbl + -- Windows doesn't need PIC, + -- everything gets relocated at runtime + | OSMinGW32 <- platformOS platform + = CmmLit $ CmmLabel lbl + + | OSAIX <- platformOS platform + = CmmMachOp (MO_Add W32) + [ CmmReg (CmmGlobal PicBaseReg) + , CmmLit $ picRelative (wordWidth platform) + (platformArch platform) + (platformOS platform) + lbl ] + + -- both ABI versions default to medium code model + | ArchPPC_64 _ <- platformArch platform + = CmmMachOp (MO_Add W32) -- code model medium + [ CmmReg (CmmGlobal PicBaseReg) + , CmmLit $ picRelative (wordWidth platform) + (platformArch platform) + (platformOS platform) + lbl ] + + | (ncgPIC config || ncgExternalDynamicRefs config) + && absoluteLabel lbl + = CmmMachOp (MO_Add (wordWidth platform)) + [ CmmReg (CmmGlobal PicBaseReg) + , CmmLit $ picRelative (wordWidth platform) + (platformArch platform) + (platformOS platform) + lbl ] + + | otherwise + = CmmLit $ CmmLabel lbl + where + platform = ncgPlatform config - | otherwise - = CmmLit $ CmmLabel lbl absoluteLabel :: CLabel -> Bool diff --git a/compiler/GHC/CmmToAsm/PPC/CodeGen.hs b/compiler/GHC/CmmToAsm/PPC/CodeGen.hs index 531efdde68..d597051b54 100644 --- a/compiler/GHC/CmmToAsm/PPC/CodeGen.hs +++ b/compiler/GHC/CmmToAsm/PPC/CodeGen.hs @@ -33,7 +33,7 @@ import GHC.CmmToAsm.CPrim import GHC.CmmToAsm.Monad ( NatM, getNewRegNat, getNewLabelNat , getBlockIdNat, getPicBaseNat, getNewRegPairNat - , getPicBaseMaybeNat, getPlatform + , getPicBaseMaybeNat, getPlatform, initConfig ) import GHC.CmmToAsm.Instr import GHC.CmmToAsm.PIC @@ -161,7 +161,7 @@ stmtToInstrs stmt = do | target32Bit platform && isWord64 ty -> assignReg_I64Code reg src | otherwise -> assignReg_IntCode format reg src - where ty = cmmRegType dflags reg + where ty = cmmRegType platform reg format = cmmTypeFormat ty CmmStore addr src @@ -169,7 +169,7 @@ stmtToInstrs stmt = do | target32Bit platform && isWord64 ty -> assignMem_I64Code addr src | otherwise -> assignMem_IntCode format addr src - where ty = cmmExprType dflags src + where ty = cmmExprType platform src format = cmmTypeFormat ty CmmUnsafeForeignCall target result_regs args @@ -240,10 +240,10 @@ jumpTableEntry _ (Just blockid) = CmmStaticLit (CmmLabel blockLabel) -- Expand CmmRegOff. ToDo: should we do it this way around, or convert -- CmmExprs into CmmRegOff? -mangleIndexTree :: DynFlags -> CmmExpr -> CmmExpr -mangleIndexTree dflags (CmmRegOff reg off) +mangleIndexTree :: Platform -> CmmExpr -> CmmExpr +mangleIndexTree platform (CmmRegOff reg off) = CmmMachOp (MO_Add width) [CmmReg reg, CmmLit (CmmInt (fromIntegral off) width)] - where width = typeWidth (cmmRegType dflags reg) + where width = typeWidth (cmmRegType platform reg) mangleIndexTree _ _ = panic "PPC.CodeGen.mangleIndexTree: no match" @@ -397,67 +397,68 @@ iselExpr64 (CmmMachOp (MO_SS_Conv W32 W64) [expr]) = do return $ ChildCode64 (expr_code `snocOL` mov_lo `snocOL` mov_hi) rlo iselExpr64 expr - = pprPanic "iselExpr64(powerpc)" (pprExpr expr) + = do + platform <- getPlatform + pprPanic "iselExpr64(powerpc)" (pprExpr platform expr) getRegister :: CmmExpr -> NatM Register getRegister e = do dflags <- getDynFlags - getRegister' dflags e + getRegister' dflags (targetPlatform dflags) e -getRegister' :: DynFlags -> CmmExpr -> NatM Register +getRegister' :: DynFlags -> Platform -> CmmExpr -> NatM Register -getRegister' dflags (CmmReg (CmmGlobal PicBaseReg)) - | OSAIX <- platformOS (targetPlatform dflags) = do +getRegister' _ platform (CmmReg (CmmGlobal PicBaseReg)) + | OSAIX <- platformOS platform = do let code dst = toOL [ LD II32 dst tocAddr ] tocAddr = AddrRegImm toc (ImmLit (text "ghc_toc_table[TC]")) return (Any II32 code) - | target32Bit (targetPlatform dflags) = do - reg <- getPicBaseNat $ archWordFormat (target32Bit (targetPlatform dflags)) - return (Fixed (archWordFormat (target32Bit (targetPlatform dflags))) + | target32Bit platform = do + reg <- getPicBaseNat $ archWordFormat (target32Bit platform) + return (Fixed (archWordFormat (target32Bit platform)) reg nilOL) | otherwise = return (Fixed II64 toc nilOL) -getRegister' dflags (CmmReg reg) - = return (Fixed (cmmTypeFormat (cmmRegType dflags reg)) - (getRegisterReg (targetPlatform dflags) reg) nilOL) +getRegister' _ platform (CmmReg reg) + = return (Fixed (cmmTypeFormat (cmmRegType platform reg)) + (getRegisterReg platform reg) nilOL) -getRegister' dflags tree@(CmmRegOff _ _) - = getRegister' dflags (mangleIndexTree dflags tree) +getRegister' dflags platform tree@(CmmRegOff _ _) + = getRegister' dflags platform (mangleIndexTree platform tree) -- for 32-bit architectures, support some 64 -> 32 bit conversions: -- TO_W_(x), TO_W_(x >> 32) -getRegister' dflags (CmmMachOp (MO_UU_Conv W64 W32) +getRegister' _ platform (CmmMachOp (MO_UU_Conv W64 W32) [CmmMachOp (MO_U_Shr W64) [x,CmmLit (CmmInt 32 _)]]) - | target32Bit (targetPlatform dflags) = do + | target32Bit platform = do ChildCode64 code rlo <- iselExpr64 x return $ Fixed II32 (getHiVRegFromLo rlo) code -getRegister' dflags (CmmMachOp (MO_SS_Conv W64 W32) +getRegister' _ platform (CmmMachOp (MO_SS_Conv W64 W32) [CmmMachOp (MO_U_Shr W64) [x,CmmLit (CmmInt 32 _)]]) - | target32Bit (targetPlatform dflags) = do + | target32Bit platform = do ChildCode64 code rlo <- iselExpr64 x return $ Fixed II32 (getHiVRegFromLo rlo) code -getRegister' dflags (CmmMachOp (MO_UU_Conv W64 W32) [x]) - | target32Bit (targetPlatform dflags) = do +getRegister' _ platform (CmmMachOp (MO_UU_Conv W64 W32) [x]) + | target32Bit platform = do ChildCode64 code rlo <- iselExpr64 x return $ Fixed II32 rlo code -getRegister' dflags (CmmMachOp (MO_SS_Conv W64 W32) [x]) - | target32Bit (targetPlatform dflags) = do +getRegister' _ platform (CmmMachOp (MO_SS_Conv W64 W32) [x]) + | target32Bit platform = do ChildCode64 code rlo <- iselExpr64 x return $ Fixed II32 rlo code -getRegister' dflags (CmmLoad mem pk) +getRegister' _ platform (CmmLoad mem pk) | not (isWord64 pk) = do - let platform = targetPlatform dflags Amode addr addr_code <- getAmode D mem let code dst = ASSERT((targetClassOfReg platform dst == RcDouble) == isFloatType pk) addr_code `snocOL` LD format dst addr return (Any format code) - | not (target32Bit (targetPlatform dflags)) = do + | not (target32Bit platform) = do Amode addr addr_code <- getAmode DS mem let code dst = addr_code `snocOL` LD II64 dst addr return (Any II64 code) @@ -465,50 +466,50 @@ getRegister' dflags (CmmLoad mem pk) where format = cmmTypeFormat pk -- catch simple cases of zero- or sign-extended load -getRegister' _ (CmmMachOp (MO_UU_Conv W8 W32) [CmmLoad mem _]) = do +getRegister' _ _ (CmmMachOp (MO_UU_Conv W8 W32) [CmmLoad mem _]) = do Amode addr addr_code <- getAmode D mem return (Any II32 (\dst -> addr_code `snocOL` LD II8 dst addr)) -getRegister' _ (CmmMachOp (MO_XX_Conv W8 W32) [CmmLoad mem _]) = do +getRegister' _ _ (CmmMachOp (MO_XX_Conv W8 W32) [CmmLoad mem _]) = do Amode addr addr_code <- getAmode D mem return (Any II32 (\dst -> addr_code `snocOL` LD II8 dst addr)) -getRegister' _ (CmmMachOp (MO_UU_Conv W8 W64) [CmmLoad mem _]) = do +getRegister' _ _ (CmmMachOp (MO_UU_Conv W8 W64) [CmmLoad mem _]) = do Amode addr addr_code <- getAmode D mem return (Any II64 (\dst -> addr_code `snocOL` LD II8 dst addr)) -getRegister' _ (CmmMachOp (MO_XX_Conv W8 W64) [CmmLoad mem _]) = do +getRegister' _ _ (CmmMachOp (MO_XX_Conv W8 W64) [CmmLoad mem _]) = do Amode addr addr_code <- getAmode D mem return (Any II64 (\dst -> addr_code `snocOL` LD II8 dst addr)) -- Note: there is no Load Byte Arithmetic instruction, so no signed case here -getRegister' _ (CmmMachOp (MO_UU_Conv W16 W32) [CmmLoad mem _]) = do +getRegister' _ _ (CmmMachOp (MO_UU_Conv W16 W32) [CmmLoad mem _]) = do Amode addr addr_code <- getAmode D mem return (Any II32 (\dst -> addr_code `snocOL` LD II16 dst addr)) -getRegister' _ (CmmMachOp (MO_SS_Conv W16 W32) [CmmLoad mem _]) = do +getRegister' _ _ (CmmMachOp (MO_SS_Conv W16 W32) [CmmLoad mem _]) = do Amode addr addr_code <- getAmode D mem return (Any II32 (\dst -> addr_code `snocOL` LA II16 dst addr)) -getRegister' _ (CmmMachOp (MO_UU_Conv W16 W64) [CmmLoad mem _]) = do +getRegister' _ _ (CmmMachOp (MO_UU_Conv W16 W64) [CmmLoad mem _]) = do Amode addr addr_code <- getAmode D mem return (Any II64 (\dst -> addr_code `snocOL` LD II16 dst addr)) -getRegister' _ (CmmMachOp (MO_SS_Conv W16 W64) [CmmLoad mem _]) = do +getRegister' _ _ (CmmMachOp (MO_SS_Conv W16 W64) [CmmLoad mem _]) = do Amode addr addr_code <- getAmode D mem return (Any II64 (\dst -> addr_code `snocOL` LA II16 dst addr)) -getRegister' _ (CmmMachOp (MO_UU_Conv W32 W64) [CmmLoad mem _]) = do +getRegister' _ _ (CmmMachOp (MO_UU_Conv W32 W64) [CmmLoad mem _]) = do Amode addr addr_code <- getAmode D mem return (Any II64 (\dst -> addr_code `snocOL` LD II32 dst addr)) -getRegister' _ (CmmMachOp (MO_SS_Conv W32 W64) [CmmLoad mem _]) = do +getRegister' _ _ (CmmMachOp (MO_SS_Conv W32 W64) [CmmLoad mem _]) = do -- lwa is DS-form. See Note [Power instruction format] Amode addr addr_code <- getAmode DS mem return (Any II64 (\dst -> addr_code `snocOL` LA II32 dst addr)) -getRegister' dflags (CmmMachOp mop [x]) -- unary MachOps +getRegister' dflags platform (CmmMachOp mop [x]) -- unary MachOps = case mop of MO_Not rep -> triv_ucode_int rep NOT @@ -538,19 +539,19 @@ getRegister' dflags (CmmMachOp mop [x]) -- unary MachOps triv_ucode_float width instr = trivialUCode (floatFormat width) instr x conversionNop new_format expr - = do e_code <- getRegister' dflags expr + = do e_code <- getRegister' dflags platform expr return (swizzleRegisterRep e_code new_format) clearLeft from to = do (src1, code1) <- getSomeReg x - let arch_fmt = intFormat (wordWidth dflags) - arch_bits = widthInBits (wordWidth dflags) + let arch_fmt = intFormat (wordWidth platform) + arch_bits = widthInBits (wordWidth platform) size = widthInBits from code dst = code1 `snocOL` CLRLI arch_fmt dst src1 (arch_bits - size) return (Any (intFormat to) code) -getRegister' _ (CmmMachOp mop [x, y]) -- dyadic PrimOps +getRegister' _ _ (CmmMachOp mop [x, y]) -- dyadic PrimOps = case mop of MO_F_Eq _ -> condFltReg EQQ x y MO_F_Ne _ -> condFltReg NE x y @@ -654,16 +655,15 @@ getRegister' _ (CmmMachOp mop [x, y]) -- dyadic PrimOps return (Any fmt code) -getRegister' _ (CmmLit (CmmInt i rep)) +getRegister' _ _ (CmmLit (CmmInt i rep)) | Just imm <- makeImmediate rep True i = let code dst = unitOL (LI dst imm) in return (Any (intFormat rep) code) -getRegister' _ (CmmLit (CmmFloat f frep)) = do +getRegister' dflags _ (CmmLit (CmmFloat f frep)) = do lbl <- getNewLabelNat - dflags <- getDynFlags dynRef <- cmmMakeDynamicReference dflags DataReference lbl Amode addr addr_code <- getAmode D dynRef let format = floatFormat frep @@ -673,9 +673,9 @@ getRegister' _ (CmmLit (CmmFloat f frep)) = do `consOL` (addr_code `snocOL` LD format dst addr) return (Any format code) -getRegister' dflags (CmmLit lit) - | target32Bit (targetPlatform dflags) - = let rep = cmmLitType dflags lit +getRegister' dflags platform (CmmLit lit) + | target32Bit platform + = let rep = cmmLitType platform lit imm = litToImm lit code dst = toOL [ LIS dst (HA imm), @@ -684,17 +684,16 @@ getRegister' dflags (CmmLit lit) in return (Any (cmmTypeFormat rep) code) | otherwise = do lbl <- getNewLabelNat - dflags <- getDynFlags dynRef <- cmmMakeDynamicReference dflags DataReference lbl Amode addr addr_code <- getAmode D dynRef - let rep = cmmLitType dflags lit + let rep = cmmLitType platform lit format = cmmTypeFormat rep code dst = LDATA (Section ReadOnlyData lbl) (RawCmmStatics lbl [CmmStaticLit lit]) `consOL` (addr_code `snocOL` LD format dst addr) return (Any format code) -getRegister' _ other = pprPanic "getRegister(ppc)" (pprExpr other) +getRegister' _ platform other = pprPanic "getRegister(ppc)" (pprExpr platform other) -- extend?Rep: wrap integer expression of type `from` -- in a conversion to `to` @@ -740,8 +739,8 @@ data InstrForm = D | DS getAmode :: InstrForm -> CmmExpr -> NatM Amode getAmode inf tree@(CmmRegOff _ _) - = do dflags <- getDynFlags - getAmode inf (mangleIndexTree dflags tree) + = do platform <- getPlatform + getAmode inf (mangleIndexTree platform tree) getAmode _ (CmmMachOp (MO_Sub W32) [x, CmmLit (CmmInt i _)]) | Just off <- makeImmediate W32 True (-i) @@ -1706,12 +1705,13 @@ genCCall' dflags gcp target dest_regs args `snocOL` BCTRL usedRegs `appOL` codeAfter) where - platform = targetPlatform dflags + config = initConfig dflags + platform = ncgPlatform config uses_pic_base_implicitly = do -- See Note [implicit register in PPC PIC code] -- on why we claim to use PIC register here - when (positionIndependent dflags && target32Bit platform) $ do + when (ncgPIC config && target32Bit platform) $ do _ <- getPicBaseNat $ archWordFormat True return () @@ -1737,7 +1737,7 @@ genCCall' dflags gcp target dest_regs args argReps _ -> panic "genCall': unknown calling conv." - argReps = map (cmmExprType dflags) args + argReps = map (cmmExprType platform) args (argHints, _) = foreignTargetHints target roundTo a x | x `mod` a == 0 = x @@ -1849,10 +1849,10 @@ genCCall' dflags gcp target dest_regs args accumUsed where arg_pro - | isBitsType rep = CmmMachOp (conv_op (typeWidth rep) (wordWidth dflags)) [arg] + | isBitsType rep = CmmMachOp (conv_op (typeWidth rep) (wordWidth platform)) [arg] | otherwise = arg format_pro - | isBitsType rep = intFormat (wordWidth dflags) + | isBitsType rep = intFormat (wordWidth platform) | otherwise = cmmTypeFormat rep conv_op = case hint of SignedHint -> MO_SS_Conv @@ -1935,11 +1935,11 @@ genCCall' dflags gcp target dest_regs args [dest] | reduceToFF32 && isFloat32 rep -> unitOL (FRSP r_dest f1) | isFloat32 rep || isFloat64 rep -> unitOL (MR r_dest f1) - | isWord64 rep && target32Bit (targetPlatform dflags) + | isWord64 rep && target32Bit platform -> toOL [MR (getHiVRegFromLo r_dest) r3, MR r_dest r4] | otherwise -> unitOL (MR r_dest r3) - where rep = cmmRegType dflags (CmmLocal dest) + where rep = cmmRegType platform (CmmLocal dest) r_dest = getRegisterReg platform (CmmLocal dest) _ -> panic "genCCall' moveResult: Bad dest_regs" @@ -2043,11 +2043,11 @@ genCCall' dflags gcp target dest_regs args genSwitch :: DynFlags -> CmmExpr -> SwitchTargets -> NatM InstrBlock genSwitch dflags expr targets - | OSAIX <- platformOS (targetPlatform dflags) + | OSAIX <- platformOS platform = do - (reg,e_code) <- getSomeReg (cmmOffset dflags expr offset) - let fmt = archWordFormat $ target32Bit $ targetPlatform dflags - sha = if target32Bit $ targetPlatform dflags then 2 else 3 + (reg,e_code) <- getSomeReg (cmmOffset platform expr offset) + let fmt = archWordFormat $ target32Bit platform + sha = if target32Bit platform then 2 else 3 tmp <- getNewRegNat fmt lbl <- getNewLabelNat dynRef <- cmmMakeDynamicReference dflags DataReference lbl @@ -2060,11 +2060,11 @@ genSwitch dflags expr targets ] return code - | (positionIndependent dflags) || (not $ target32Bit $ targetPlatform dflags) + | (ncgPIC config) || (not $ target32Bit platform) = do - (reg,e_code) <- getSomeReg (cmmOffset dflags expr offset) - let fmt = archWordFormat $ target32Bit $ targetPlatform dflags - sha = if target32Bit $ targetPlatform dflags then 2 else 3 + (reg,e_code) <- getSomeReg (cmmOffset platform expr offset) + let fmt = archWordFormat $ target32Bit platform + sha = if target32Bit platform then 2 else 3 tmp <- getNewRegNat fmt lbl <- getNewLabelNat dynRef <- cmmMakeDynamicReference dflags DataReference lbl @@ -2079,9 +2079,9 @@ genSwitch dflags expr targets return code | otherwise = do - (reg,e_code) <- getSomeReg (cmmOffset dflags expr offset) - let fmt = archWordFormat $ target32Bit $ targetPlatform dflags - sha = if target32Bit $ targetPlatform dflags then 2 else 3 + (reg,e_code) <- getSomeReg (cmmOffset platform expr offset) + let fmt = archWordFormat $ target32Bit platform + sha = if target32Bit platform then 2 else 3 tmp <- getNewRegNat fmt lbl <- getNewLabelNat let code = e_code `appOL` toOL [ @@ -2092,7 +2092,10 @@ genSwitch dflags expr targets BCTR ids (Just lbl) [] ] return code - where (offset, ids) = switchTargetsToTable targets + where + (offset, ids) = switchTargetsToTable targets + platform = ncgPlatform config + config = initConfig dflags generateJumpTableForInstr :: NCGConfig -> Instr -> Maybe (NatCmmDecl RawCmmStatics Instr) diff --git a/compiler/GHC/CmmToAsm/PPC/Ppr.hs b/compiler/GHC/CmmToAsm/PPC/Ppr.hs index 09f390163f..a66d1c2f99 100644 --- a/compiler/GHC/CmmToAsm/PPC/Ppr.hs +++ b/compiler/GHC/CmmToAsm/PPC/Ppr.hs @@ -294,8 +294,7 @@ pprAlignForSection platform seg = pprDataItem :: Platform -> CmmLit -> SDoc pprDataItem platform lit - = sdocWithDynFlags $ \dflags -> - vcat (ppr_item (cmmTypeFormat $ cmmLitType dflags lit) lit) + = vcat (ppr_item (cmmTypeFormat $ cmmLitType platform lit) lit) where imm = litToImm lit archPPC_64 = not $ target32Bit platform diff --git a/compiler/GHC/CmmToAsm/SPARC/CodeGen.hs b/compiler/GHC/CmmToAsm/SPARC/CodeGen.hs index 2580ea4014..67177ea0c6 100644 --- a/compiler/GHC/CmmToAsm/SPARC/CodeGen.hs +++ b/compiler/GHC/CmmToAsm/SPARC/CodeGen.hs @@ -36,7 +36,8 @@ import GHC.CmmToAsm.SPARC.Regs import GHC.CmmToAsm.SPARC.Stack import GHC.CmmToAsm.Instr import GHC.CmmToAsm.Format -import GHC.CmmToAsm.Monad ( NatM, getNewRegNat, getNewLabelNat ) +import GHC.CmmToAsm.Monad ( NatM, getNewRegNat, getNewLabelNat, getPlatform, getConfig ) +import GHC.CmmToAsm.Config -- Our intermediate code: import GHC.Cmm.BlockId @@ -123,7 +124,8 @@ stmtsToInstrs stmts stmtToInstrs :: CmmNode e x -> NatM InstrBlock stmtToInstrs stmt = do - dflags <- getDynFlags + platform <- getPlatform + config <- getConfig case stmt of CmmComment s -> return (unitOL (COMMENT s)) CmmTick {} -> return nilOL @@ -133,14 +135,14 @@ stmtToInstrs stmt = do | isFloatType ty -> assignReg_FltCode format reg src | isWord64 ty -> assignReg_I64Code reg src | otherwise -> assignReg_IntCode format reg src - where ty = cmmRegType dflags reg + where ty = cmmRegType platform reg format = cmmTypeFormat ty CmmStore addr src | isFloatType ty -> assignMem_FltCode format addr src | isWord64 ty -> assignMem_I64Code addr src | otherwise -> assignMem_IntCode format addr src - where ty = cmmExprType dflags src + where ty = cmmExprType platform src format = cmmTypeFormat ty CmmUnsafeForeignCall target result_regs args @@ -151,8 +153,7 @@ stmtToInstrs stmt = do b1 <- genCondJump true arg b2 <- genBranch false return (b1 `appOL` b2) - CmmSwitch arg ids -> do dflags <- getDynFlags - genSwitch dflags arg ids + CmmSwitch arg ids -> genSwitch config arg ids CmmCall { cml_target = arg } -> genJump arg _ @@ -180,8 +181,8 @@ temporary, then do the other computation, and then use the temporary: -- | Convert a BlockId to some CmmStatic data -jumpTableEntry :: DynFlags -> Maybe BlockId -> CmmStatic -jumpTableEntry dflags Nothing = CmmStaticLit (CmmInt 0 (wordWidth dflags)) +jumpTableEntry :: Platform -> Maybe BlockId -> CmmStatic +jumpTableEntry platform Nothing = CmmStaticLit (CmmInt 0 (wordWidth platform)) jumpTableEntry _ (Just blockid) = CmmStaticLit (CmmLabel blockLabel) where blockLabel = blockLbl blockid @@ -208,9 +209,9 @@ assignMem_IntCode pk addr src = do assignReg_IntCode :: Format -> CmmReg -> CmmExpr -> NatM InstrBlock assignReg_IntCode _ reg src = do - dflags <- getDynFlags + platform <- getPlatform r <- getRegister src - let dst = getRegisterReg (targetPlatform dflags) reg + let dst = getRegisterReg platform reg return $ case r of Any _ code -> code dst Fixed _ freg fcode -> fcode `snocOL` OR False g0 (RIReg freg) dst @@ -220,12 +221,12 @@ assignReg_IntCode _ reg src = do -- Floating point assignment to memory assignMem_FltCode :: Format -> CmmExpr -> CmmExpr -> NatM InstrBlock assignMem_FltCode pk addr src = do - dflags <- getDynFlags + platform <- getPlatform Amode dst__2 code1 <- getAmode addr (src__2, code2) <- getSomeReg src tmp1 <- getNewRegNat pk let - pk__2 = cmmExprType dflags src + pk__2 = cmmExprType platform src code__2 = code1 `appOL` code2 `appOL` if formatToWidth pk == typeWidth pk__2 then unitOL (ST pk src__2 dst__2) @@ -236,8 +237,7 @@ assignMem_FltCode pk addr src = do -- Floating point assignment to a register/temporary assignReg_FltCode :: Format -> CmmReg -> CmmExpr -> NatM InstrBlock assignReg_FltCode pk dstCmmReg srcCmmExpr = do - dflags <- getDynFlags - let platform = targetPlatform dflags + platform <- getPlatform srcRegister <- getRegister srcCmmExpr let dstReg = getRegisterReg platform dstCmmReg @@ -309,13 +309,13 @@ genCondJump bid bool = do -- ----------------------------------------------------------------------------- -- Generating a table-branch -genSwitch :: DynFlags -> CmmExpr -> SwitchTargets -> NatM InstrBlock -genSwitch dflags expr targets - | positionIndependent dflags +genSwitch :: NCGConfig -> CmmExpr -> SwitchTargets -> NatM InstrBlock +genSwitch config expr targets + | ncgPIC config = error "MachCodeGen: sparc genSwitch PIC not finished\n" | otherwise - = do (e_reg, e_code) <- getSomeReg (cmmOffset dflags expr offset) + = do (e_reg, e_code) <- getSomeReg (cmmOffset (ncgPlatform config) expr offset) base_reg <- getNewRegNat II32 offset_reg <- getNewRegNat II32 @@ -338,10 +338,10 @@ genSwitch dflags expr targets , NOP ] where (offset, ids) = switchTargetsToTable targets -generateJumpTableForInstr :: DynFlags -> Instr +generateJumpTableForInstr :: Platform -> Instr -> Maybe (NatCmmDecl RawCmmStatics Instr) -generateJumpTableForInstr dflags (JMP_TBL _ ids label) = - let jumpTable = map (jumpTableEntry dflags) ids +generateJumpTableForInstr platform (JMP_TBL _ ids label) = + let jumpTable = map (jumpTableEntry platform) ids in Just (CmmData (Section ReadOnlyData label) (RawCmmStatics label jumpTable)) generateJumpTableForInstr _ _ = Nothing @@ -469,21 +469,21 @@ genCCall target dest_regs args -- | Generate code to calculate an argument, and move it into one -- or two integer vregs. arg_to_int_vregs :: CmmExpr -> NatM (OrdList Instr, [Reg]) -arg_to_int_vregs arg = do dflags <- getDynFlags - arg_to_int_vregs' dflags arg +arg_to_int_vregs arg = do platform <- getPlatform + arg_to_int_vregs' platform arg -arg_to_int_vregs' :: DynFlags -> CmmExpr -> NatM (OrdList Instr, [Reg]) -arg_to_int_vregs' dflags arg +arg_to_int_vregs' :: Platform -> CmmExpr -> NatM (OrdList Instr, [Reg]) +arg_to_int_vregs' platform arg -- If the expr produces a 64 bit int, then we can just use iselExpr64 - | isWord64 (cmmExprType dflags arg) + | isWord64 (cmmExprType platform arg) = do (ChildCode64 code r_lo) <- iselExpr64 arg let r_hi = getHiVRegFromLo r_lo return (code, [r_hi, r_lo]) | otherwise = do (src, code) <- getSomeReg arg - let pk = cmmExprType dflags arg + let pk = cmmExprType platform arg case cmmTypeFormat pk of diff --git a/compiler/GHC/CmmToAsm/SPARC/CodeGen/Amode.hs b/compiler/GHC/CmmToAsm/SPARC/CodeGen/Amode.hs index d6c9d7b360..75eba25023 100644 --- a/compiler/GHC/CmmToAsm/SPARC/CodeGen/Amode.hs +++ b/compiler/GHC/CmmToAsm/SPARC/CodeGen/Amode.hs @@ -27,8 +27,8 @@ getAmode -> NatM Amode getAmode tree@(CmmRegOff _ _) - = do dflags <- getDynFlags - getAmode (mangleIndexTree dflags tree) + = do platform <- getPlatform + getAmode (mangleIndexTree platform tree) getAmode (CmmMachOp (MO_Sub _) [x, CmmLit (CmmInt i _)]) | fits13Bits (-i) diff --git a/compiler/GHC/CmmToAsm/SPARC/CodeGen/Base.hs b/compiler/GHC/CmmToAsm/SPARC/CodeGen/Base.hs index cf249303e4..f00e60ca93 100644 --- a/compiler/GHC/CmmToAsm/SPARC/CodeGen/Base.hs +++ b/compiler/GHC/CmmToAsm/SPARC/CodeGen/Base.hs @@ -23,7 +23,6 @@ import GHC.CmmToAsm.Format import GHC.Platform.Reg import GHC.Platform.Regs -import GHC.Driver.Session import GHC.Cmm import GHC.Cmm.Ppr.Expr () -- For Outputable instances import GHC.Platform @@ -109,11 +108,11 @@ getRegisterReg platform (CmmGlobal mid) -- Expand CmmRegOff. ToDo: should we do it this way around, or convert -- CmmExprs into CmmRegOff? -mangleIndexTree :: DynFlags -> CmmExpr -> CmmExpr +mangleIndexTree :: Platform -> CmmExpr -> CmmExpr -mangleIndexTree dflags (CmmRegOff reg off) +mangleIndexTree platform (CmmRegOff reg off) = CmmMachOp (MO_Add width) [CmmReg reg, CmmLit (CmmInt (fromIntegral off) width)] - where width = typeWidth (cmmRegType dflags reg) + where width = typeWidth (cmmRegType platform reg) mangleIndexTree _ _ = panic "SPARC.CodeGen.Base.mangleIndexTree: no match" diff --git a/compiler/GHC/CmmToAsm/SPARC/CodeGen/CondCode.hs b/compiler/GHC/CmmToAsm/SPARC/CodeGen/CondCode.hs index e501d799f2..3f8912a9c4 100644 --- a/compiler/GHC/CmmToAsm/SPARC/CodeGen/CondCode.hs +++ b/compiler/GHC/CmmToAsm/SPARC/CodeGen/CondCode.hs @@ -87,15 +87,15 @@ condIntCode cond x y = do condFltCode :: Cond -> CmmExpr -> CmmExpr -> NatM CondCode condFltCode cond x y = do - dflags <- getDynFlags + platform <- getPlatform (src1, code1) <- getSomeReg x (src2, code2) <- getSomeReg y tmp <- getNewRegNat FF64 let promote x = FxTOy FF32 FF64 x tmp - pk1 = cmmExprType dflags x - pk2 = cmmExprType dflags y + pk1 = cmmExprType platform x + pk2 = cmmExprType platform y code__2 = if pk1 `cmmEqType` pk2 then diff --git a/compiler/GHC/CmmToAsm/SPARC/CodeGen/Gen32.hs b/compiler/GHC/CmmToAsm/SPARC/CodeGen/Gen32.hs index ee67bd4a9d..8d2c6c33f6 100644 --- a/compiler/GHC/CmmToAsm/SPARC/CodeGen/Gen32.hs +++ b/compiler/GHC/CmmToAsm/SPARC/CodeGen/Gen32.hs @@ -26,7 +26,6 @@ import GHC.Platform.Reg import GHC.Cmm import Control.Monad (liftM) -import GHC.Driver.Session import OrdList import Outputable @@ -49,14 +48,13 @@ getSomeReg expr = do getRegister :: CmmExpr -> NatM Register getRegister (CmmReg reg) - = do dflags <- getDynFlags - let platform = targetPlatform dflags - return (Fixed (cmmTypeFormat (cmmRegType dflags reg)) + = do platform <- getPlatform + return (Fixed (cmmTypeFormat (cmmRegType platform reg)) (getRegisterReg platform reg) nilOL) getRegister tree@(CmmRegOff _ _) - = do dflags <- getDynFlags - getRegister (mangleIndexTree dflags tree) + = do platform <- getPlatform + getRegister (mangleIndexTree platform tree) getRegister (CmmMachOp (MO_UU_Conv W64 W32) [CmmMachOp (MO_U_Shr W64) [x,CmmLit (CmmInt 32 _)]]) = do @@ -483,15 +481,15 @@ trivialFCode -> NatM Register trivialFCode pk instr x y = do - dflags <- getDynFlags + platform <- getPlatform (src1, code1) <- getSomeReg x (src2, code2) <- getSomeReg y tmp <- getNewRegNat FF64 let promote x = FxTOy FF32 FF64 x tmp - pk1 = cmmExprType dflags x - pk2 = cmmExprType dflags y + pk1 = cmmExprType platform x + pk2 = cmmExprType platform y code__2 dst = if pk1 `cmmEqType` pk2 then diff --git a/compiler/GHC/CmmToAsm/SPARC/Ppr.hs b/compiler/GHC/CmmToAsm/SPARC/Ppr.hs index fc382a5c10..566b23c1d6 100644 --- a/compiler/GHC/CmmToAsm/SPARC/Ppr.hs +++ b/compiler/GHC/CmmToAsm/SPARC/Ppr.hs @@ -98,7 +98,7 @@ pprBasicBlock platform info_env (BasicBlock blockid instrs) Nothing -> empty Just (RawCmmStatics info_lbl info) -> pprAlignForSection Text $$ - vcat (map pprData info) $$ + vcat (map (pprData platform) info) $$ pprLabel platform info_lbl @@ -113,12 +113,12 @@ pprDatas _platform (RawCmmStatics alias [CmmStaticLit (CmmLabel lbl), CmmStaticL , alias `mayRedirectTo` ind' = pprGloblDecl alias $$ text ".equiv" <+> ppr alias <> comma <> ppr (CmmLabel ind') -pprDatas platform (RawCmmStatics lbl dats) = vcat (pprLabel platform lbl : map pprData dats) +pprDatas platform (RawCmmStatics lbl dats) = vcat (pprLabel platform lbl : map (pprData platform) dats) -pprData :: CmmStatic -> SDoc -pprData (CmmString str) = pprBytes str -pprData (CmmUninitialised bytes) = text ".skip " <> int bytes -pprData (CmmStaticLit lit) = pprDataItem lit +pprData :: Platform -> CmmStatic -> SDoc +pprData _ (CmmString str) = pprBytes str +pprData _ (CmmUninitialised bytes) = text ".skip " <> int bytes +pprData platform (CmmStaticLit lit) = pprDataItem platform lit pprGloblDecl :: CLabel -> SDoc pprGloblDecl lbl @@ -345,10 +345,9 @@ pprAlignForSection seg = OtherSection _ -> panic "PprMach.pprSectionHeader: unknown section") -- | Pretty print a data item. -pprDataItem :: CmmLit -> SDoc -pprDataItem lit - = sdocWithDynFlags $ \dflags -> - vcat (ppr_item (cmmTypeFormat $ cmmLitType dflags lit) lit) +pprDataItem :: Platform -> CmmLit -> SDoc +pprDataItem platform lit + = vcat (ppr_item (cmmTypeFormat $ cmmLitType platform lit) lit) where imm = litToImm lit diff --git a/compiler/GHC/CmmToAsm/X86/CodeGen.hs b/compiler/GHC/CmmToAsm/X86/CodeGen.hs index 17e246366b..bf282fcac4 100644 --- a/compiler/GHC/CmmToAsm/X86/CodeGen.hs +++ b/compiler/GHC/CmmToAsm/X86/CodeGen.hs @@ -332,7 +332,6 @@ stmtToInstrs :: BlockId -- ^ Basic block this statement will start to be placed -- ^ Instructions, and bid of new block if successive -- statements are placed in a different basic block. stmtToInstrs bid stmt = do - dflags <- getDynFlags is32Bit <- is32BitPlatform platform <- getPlatform case stmt of @@ -345,7 +344,7 @@ stmtToInstrs bid stmt = do CmmUnwind regs -> do let to_unwind_entry :: (GlobalReg, Maybe CmmExpr) -> UnwindTable - to_unwind_entry (reg, expr) = M.singleton reg (fmap toUnwindExpr expr) + to_unwind_entry (reg, expr) = M.singleton reg (fmap (toUnwindExpr platform) expr) case foldMap to_unwind_entry regs of tbl | M.null tbl -> return nilOL | otherwise -> do @@ -356,14 +355,14 @@ stmtToInstrs bid stmt = do | isFloatType ty -> assignReg_FltCode format reg src | is32Bit && isWord64 ty -> assignReg_I64Code reg src | otherwise -> assignReg_IntCode format reg src - where ty = cmmRegType dflags reg + where ty = cmmRegType platform reg format = cmmTypeFormat ty CmmStore addr src | isFloatType ty -> assignMem_FltCode format addr src | is32Bit && isWord64 ty -> assignMem_I64Code addr src | otherwise -> assignMem_IntCode format addr src - where ty = cmmExprType dflags src + where ty = cmmExprType platform src format = cmmTypeFormat ty CmmBranch id -> return $ genBranch id @@ -487,10 +486,10 @@ jumpTableEntry _ (Just blockid) = CmmStaticLit (CmmLabel blockLabel) -- Expand CmmRegOff. ToDo: should we do it this way around, or convert -- CmmExprs into CmmRegOff? -mangleIndexTree :: DynFlags -> CmmReg -> Int -> CmmExpr -mangleIndexTree dflags reg off +mangleIndexTree :: Platform -> CmmReg -> Int -> CmmExpr +mangleIndexTree platform reg off = CmmMachOp (MO_Add width) [CmmReg reg, CmmLit (CmmInt (fromIntegral off) width)] - where width = typeWidth (cmmRegType dflags reg) + where width = typeWidth (cmmRegType platform reg) -- | The dual to getAnyReg: compute an expression into a register, but -- we don't mind which one it is. @@ -637,13 +636,13 @@ iselExpr64 expr -------------------------------------------------------------------------------- getRegister :: CmmExpr -> NatM Register -getRegister e = do dflags <- getDynFlags +getRegister e = do platform <- getPlatform is32Bit <- is32BitPlatform - getRegister' dflags is32Bit e + getRegister' platform is32Bit e -getRegister' :: DynFlags -> Bool -> CmmExpr -> NatM Register +getRegister' :: Platform -> Bool -> CmmExpr -> NatM Register -getRegister' dflags is32Bit (CmmReg reg) +getRegister' platform is32Bit (CmmReg reg) = case reg of CmmGlobal PicBaseReg | is32Bit -> @@ -655,7 +654,7 @@ getRegister' dflags is32Bit (CmmReg reg) _ -> do let - fmt = cmmTypeFormat (cmmRegType dflags reg) + fmt = cmmTypeFormat (cmmRegType platform reg) format = fmt -- platform <- ncgPlatform <$> getConfig @@ -664,11 +663,11 @@ getRegister' dflags is32Bit (CmmReg reg) nilOL) -getRegister' dflags is32Bit (CmmRegOff r n) - = getRegister' dflags is32Bit $ mangleIndexTree dflags r n +getRegister' platform is32Bit (CmmRegOff r n) + = getRegister' platform is32Bit $ mangleIndexTree platform r n -getRegister' dflags is32Bit (CmmMachOp (MO_AlignmentCheck align _) [e]) - = addAlignmentCheck align <$> getRegister' dflags is32Bit e +getRegister' platform is32Bit (CmmMachOp (MO_AlignmentCheck align _) [e]) + = addAlignmentCheck align <$> getRegister' platform is32Bit e -- for 32-bit architectures, support some 64 -> 32 bit conversions: -- TO_W_(x), TO_W_(x >> 32) @@ -764,7 +763,7 @@ getRegister' _ is32Bit (CmmMachOp (MO_Add W64) [CmmReg (CmmGlobal PicBaseReg), return $ Any II64 (\dst -> unitOL $ LEA II64 (OpAddr (ripRel (litToImm displacement))) (OpReg dst)) -getRegister' dflags is32Bit (CmmMachOp mop [x]) = do -- unary MachOps +getRegister' platform is32Bit (CmmMachOp mop [x]) = do -- unary MachOps case mop of MO_F_Neg w -> sse2NegCode w x @@ -892,7 +891,7 @@ getRegister' dflags is32Bit (CmmMachOp mop [x]) = do -- unary MachOps conversionNop :: Format -> CmmExpr -> NatM Register conversionNop new_format expr - = do e_code <- getRegister' dflags is32Bit expr + = do e_code <- getRegister' platform is32Bit expr return (swizzleRegisterRep e_code new_format) @@ -1165,8 +1164,8 @@ getRegister' _ is32Bit (CmmLit (CmmInt 0 width)) -- 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. -getRegister' dflags is32Bit (CmmLit lit) - | not is32Bit, isWord64 (cmmLitType dflags lit), not (isBigLit lit) +getRegister' platform is32Bit (CmmLit lit) + | not is32Bit, isWord64 (cmmLitType platform lit), not (isBigLit lit) = let imm = litToImm lit code dst = unitOL (MOV II32 (OpImm imm) (OpReg dst)) @@ -1181,8 +1180,8 @@ getRegister' dflags is32Bit (CmmLit lit) -- note2: all labels are small, because we're assuming the -- small memory model (see gcc docs, -mcmodel=small). -getRegister' dflags _ (CmmLit lit) - = do let format = cmmTypeFormat (cmmLitType dflags lit) +getRegister' platform _ (CmmLit lit) + = do let format = cmmTypeFormat (cmmLitType platform lit) imm = litToImm lit code dst = unitOL (MOV format (OpImm imm) (OpReg dst)) return (Any format code) @@ -1260,8 +1259,8 @@ getAmode e = do is32Bit <- is32BitPlatform getAmode' is32Bit e getAmode' :: Bool -> CmmExpr -> NatM Amode -getAmode' _ (CmmRegOff r n) = do dflags <- getDynFlags - getAmode $ mangleIndexTree dflags r n +getAmode' _ (CmmRegOff r n) = do platform <- getPlatform + getAmode $ mangleIndexTree platform r n getAmode' is32Bit (CmmMachOp (MO_Add W64) [CmmReg (CmmGlobal PicBaseReg), CmmLit displacement]) @@ -1361,7 +1360,7 @@ x86_complex_amode base index shift offset getNonClobberedOperand :: CmmExpr -> NatM (Operand, InstrBlock) getNonClobberedOperand (CmmLit lit) = do - if isSuitableFloatingPointLit lit + if isSuitableFloatingPointLit lit then do let CmmFloat _ w = lit Amode addr code <- memConstant (mkAlignment $ widthInBytes w) lit @@ -1369,8 +1368,8 @@ getNonClobberedOperand (CmmLit lit) = do else do is32Bit <- is32BitPlatform - dflags <- getDynFlags - if is32BitLit is32Bit lit && not (isFloatType (cmmLitType dflags lit)) + platform <- getPlatform + if is32BitLit is32Bit lit && not (isFloatType (cmmLitType platform lit)) then return (OpImm (litToImm lit), nilOL) else getNonClobberedOperand_generic (CmmLit lit) @@ -1428,8 +1427,8 @@ getOperand (CmmLit lit) = do else do is32Bit <- is32BitPlatform - dflags <- getDynFlags - if is32BitLit is32Bit lit && not (isFloatType (cmmLitType dflags lit)) + platform <- getPlatform + if is32BitLit is32Bit lit && not (isFloatType (cmmLitType platform lit)) then return (OpImm (litToImm lit), nilOL) else getOperand_generic (CmmLit lit) @@ -1622,34 +1621,34 @@ condIntCode' _ cond x (CmmLit (CmmInt 0 pk)) = do -- anything vs operand condIntCode' is32Bit cond x y | isOperand is32Bit y = do - dflags <- getDynFlags + platform <- getPlatform (x_reg, x_code) <- getNonClobberedReg x (y_op, y_code) <- getOperand y let code = x_code `appOL` y_code `snocOL` - CMP (cmmTypeFormat (cmmExprType dflags x)) y_op (OpReg x_reg) + CMP (cmmTypeFormat (cmmExprType platform x)) y_op (OpReg x_reg) return (CondCode False cond code) -- operand vs. anything: invert the comparison so that we can use a -- single comparison instruction. | isOperand is32Bit x , Just revcond <- maybeFlipCond cond = do - dflags <- getDynFlags + platform <- getPlatform (y_reg, y_code) <- getNonClobberedReg y (x_op, x_code) <- getOperand x let code = y_code `appOL` x_code `snocOL` - CMP (cmmTypeFormat (cmmExprType dflags x)) x_op (OpReg y_reg) + CMP (cmmTypeFormat (cmmExprType platform x)) x_op (OpReg y_reg) return (CondCode False revcond code) -- anything vs anything condIntCode' _ cond x y = do - dflags <- getDynFlags + platform <- getPlatform (y_reg, y_code) <- getNonClobberedReg y (x_op, x_code) <- getRegOrMem x let code = y_code `appOL` x_code `snocOL` - CMP (cmmTypeFormat (cmmExprType dflags x)) (OpReg y_reg) x_op + CMP (cmmTypeFormat (cmmExprType platform x)) (OpReg y_reg) x_op return (CondCode False cond code) @@ -1666,13 +1665,13 @@ condFltCode cond x y -- an operand, but the right must be a reg. We can probably do better -- than this general case... condFltCode_sse2 = do - dflags <- getDynFlags + platform <- getPlatform (x_reg, x_code) <- getNonClobberedReg x (y_op, y_code) <- getOperand y let code = x_code `appOL` y_code `snocOL` - CMP (floatFormat $ cmmExprWidth dflags x) y_op (OpReg x_reg) + CMP (floatFormat $ cmmExprWidth platform x) y_op (OpReg x_reg) -- NB(1): we need to use the unsigned comparison operators on the -- result of this comparison. return (CondCode True (condToUnsigned cond) code) @@ -2529,7 +2528,7 @@ genCCall' _ is32Bit (PrimTarget (MO_Cmpxchg width)) [dst] [addr, old, new] _ = d where format = intFormat width -genCCall' dflags is32Bit target dest_regs args bid = do +genCCall' _ is32Bit target dest_regs args bid = do platform <- ncgPlatform <$> getConfig case (target, dest_regs) of -- void return type prim op @@ -2639,8 +2638,8 @@ genCCall' dflags is32Bit target dest_regs args bid = do _ -> panic "genCCall: Wrong number of arguments/results for imul2" _ -> if is32Bit - then genCCall32' dflags target dest_regs args - else genCCall64' dflags target dest_regs args + then genCCall32' target dest_regs args + else genCCall64' target dest_regs args where divOp1 platform signed width results [arg_x, arg_y] = divOp platform signed width results Nothing arg_x arg_y @@ -2719,22 +2718,82 @@ genCCall' dflags is32Bit target dest_regs args bid = do -- and get the results from %al, %dl. This is not optimal, but a few -- register moves are probably not a huge deal when doing division. -genCCall32' :: DynFlags - -> ForeignTarget -- function to call +genCCall32' :: ForeignTarget -- function to call -> [CmmFormal] -- where to put the result -> [CmmActual] -- arguments (of mixed type) -> NatM InstrBlock -genCCall32' dflags target dest_regs args = do - let - prom_args = map (maybePromoteCArg dflags W32) args +genCCall32' target dest_regs args = do + config <- getConfig + let platform = ncgPlatform config + prom_args = map (maybePromoteCArg platform W32) args + + -- If the size is smaller than the word, we widen things (see maybePromoteCArg) + arg_size_bytes :: CmmType -> Int + arg_size_bytes ty = max (widthInBytes (typeWidth ty)) (widthInBytes (wordWidth platform)) + + roundTo a x | x `mod` a == 0 = x + | otherwise = x + a - (x `mod` a) + push_arg :: CmmActual {-current argument-} + -> NatM InstrBlock -- code + + push_arg arg -- we don't need the hints on x86 + | isWord64 arg_ty = do + ChildCode64 code r_lo <- iselExpr64 arg + delta <- getDeltaNat + setDeltaNat (delta - 8) + let r_hi = getHiVRegFromLo r_lo + return ( code `appOL` + toOL [PUSH II32 (OpReg r_hi), DELTA (delta - 4), + PUSH II32 (OpReg r_lo), DELTA (delta - 8), + DELTA (delta-8)] + ) + + | isFloatType arg_ty = do + (reg, code) <- getSomeReg arg + delta <- getDeltaNat + setDeltaNat (delta-size) + return (code `appOL` + toOL [SUB II32 (OpImm (ImmInt size)) (OpReg esp), + DELTA (delta-size), + let addr = AddrBaseIndex (EABaseReg esp) + EAIndexNone + (ImmInt 0) + format = floatFormat (typeWidth arg_ty) + in + + -- assume SSE2 + MOV format (OpReg reg) (OpAddr addr) + + ] + ) + + | otherwise = do + -- Arguments can be smaller than 32-bit, but we still use @PUSH + -- II32@ - the usual calling conventions expect integers to be + -- 4-byte aligned. + ASSERT((typeWidth arg_ty) <= W32) return () + (operand, code) <- getOperand arg + delta <- getDeltaNat + setDeltaNat (delta-size) + return (code `snocOL` + PUSH II32 operand `snocOL` + DELTA (delta-size)) + + where + arg_ty = cmmExprType platform arg + size = arg_size_bytes arg_ty -- Byte size + + let -- Align stack to 16n for calls, assuming a starting stack -- alignment of 16n - word_size on procedure entry. Which we -- maintiain. See Note [rts/StgCRun.c : Stack Alignment on X86] - sizes = map (arg_size_bytes . cmmExprType dflags) (reverse args) - raw_arg_size = sum sizes + wORD_SIZE dflags + sizes = map (arg_size_bytes . cmmExprType platform) (reverse args) + raw_arg_size = sum sizes + platformWordSizeInBytes platform arg_pad_size = (roundTo 16 $ raw_arg_size) - raw_arg_size - tot_arg_size = raw_arg_size + arg_pad_size - wORD_SIZE dflags + tot_arg_size = raw_arg_size + arg_pad_size - platformWordSizeInBytes platform + + delta0 <- getDeltaNat setDeltaNat (delta0 - arg_pad_size) @@ -2751,7 +2810,7 @@ genCCall32' dflags target dest_regs args = do where fn_imm = ImmCLbl lbl ForeignTarget expr conv -> do { (dyn_r, dyn_c) <- getSomeReg expr - ; ASSERT( isWord32 (cmmExprType dflags expr) ) + ; ASSERT( isWord32 (cmmExprType platform expr) ) return (dyn_c `snocOL` CALL (Right dyn_r) [], conv) } PrimTarget _ -> panic $ "genCCall: Can't handle PrimTarget call type here, error " @@ -2783,8 +2842,6 @@ genCCall32' dflags target dest_regs args = do ) setDeltaNat delta0 - platform <- getPlatform - let -- assign the results, if necessary assign_code [] = nilOL @@ -2815,198 +2872,24 @@ genCCall32' dflags target dest_regs args = do w = typeWidth ty b = widthInBytes w r_dest_hi = getHiVRegFromLo r_dest - r_dest = getRegisterReg platform (CmmLocal dest) + r_dest = getRegisterReg platform (CmmLocal dest) assign_code many = pprPanic "genCCall.assign_code - too many return values:" (ppr many) return (push_code `appOL` call `appOL` assign_code dest_regs) - where - -- If the size is smaller than the word, we widen things (see maybePromoteCArg) - arg_size_bytes :: CmmType -> Int - arg_size_bytes ty = max (widthInBytes (typeWidth ty)) (widthInBytes (wordWidth dflags)) - - roundTo a x | x `mod` a == 0 = x - | otherwise = x + a - (x `mod` a) - - push_arg :: CmmActual {-current argument-} - -> NatM InstrBlock -- code - - push_arg arg -- we don't need the hints on x86 - | isWord64 arg_ty = do - ChildCode64 code r_lo <- iselExpr64 arg - delta <- getDeltaNat - setDeltaNat (delta - 8) - let r_hi = getHiVRegFromLo r_lo - return ( code `appOL` - toOL [PUSH II32 (OpReg r_hi), DELTA (delta - 4), - PUSH II32 (OpReg r_lo), DELTA (delta - 8), - DELTA (delta-8)] - ) - - | isFloatType arg_ty = do - (reg, code) <- getSomeReg arg - delta <- getDeltaNat - setDeltaNat (delta-size) - return (code `appOL` - toOL [SUB II32 (OpImm (ImmInt size)) (OpReg esp), - DELTA (delta-size), - let addr = AddrBaseIndex (EABaseReg esp) - EAIndexNone - (ImmInt 0) - format = floatFormat (typeWidth arg_ty) - in - - -- assume SSE2 - MOV format (OpReg reg) (OpAddr addr) - - ] - ) - - | otherwise = do - -- Arguments can be smaller than 32-bit, but we still use @PUSH - -- II32@ - the usual calling conventions expect integers to be - -- 4-byte aligned. - ASSERT((typeWidth arg_ty) <= W32) return () - (operand, code) <- getOperand arg - delta <- getDeltaNat - setDeltaNat (delta-size) - return (code `snocOL` - PUSH II32 operand `snocOL` - DELTA (delta-size)) - - where - arg_ty = cmmExprType dflags arg - size = arg_size_bytes arg_ty -- Byte size - -genCCall64' :: DynFlags - -> ForeignTarget -- function to call +genCCall64' :: ForeignTarget -- function to call -> [CmmFormal] -- where to put the result -> [CmmActual] -- arguments (of mixed type) -> NatM InstrBlock -genCCall64' dflags target dest_regs args = do +genCCall64' target dest_regs args = do config <- getConfig let platform = ncgPlatform config -- load up the register arguments - let prom_args = map (maybePromoteCArg dflags W32) args - - (stack_args, int_regs_used, fp_regs_used, load_args_code, assign_args_code) - <- - if platformOS platform == OSMinGW32 - then load_args_win prom_args [] [] (allArgRegs platform) nilOL - else do - (stack_args, aregs, fregs, load_args_code, assign_args_code) - <- load_args prom_args (allIntArgRegs platform) - (allFPArgRegs platform) - nilOL nilOL - let used_regs rs as = reverse (drop (length rs) (reverse as)) - fregs_used = used_regs fregs (allFPArgRegs platform) - aregs_used = used_regs aregs (allIntArgRegs platform) - return (stack_args, aregs_used, fregs_used, load_args_code - , assign_args_code) - - let - arg_regs_used = int_regs_used ++ fp_regs_used - arg_regs = [eax] ++ arg_regs_used - -- for annotating the call instruction with - sse_regs = length fp_regs_used - arg_stack_slots = if platformOS platform == OSMinGW32 - then length stack_args + length (allArgRegs platform) - else length stack_args - tot_arg_size = arg_size * arg_stack_slots - - - -- Align stack to 16n for calls, assuming a starting stack - -- alignment of 16n - word_size on procedure entry. Which we - -- maintain. See Note [rts/StgCRun.c : Stack Alignment on X86] - let word_size = platformWordSizeInBytes platform - (real_size, adjust_rsp) <- - if (tot_arg_size + word_size) `rem` 16 == 0 - then return (tot_arg_size, nilOL) - else do -- we need to adjust... - delta <- getDeltaNat - setDeltaNat (delta - word_size) - return (tot_arg_size + word_size, toOL [ - SUB II64 (OpImm (ImmInt word_size)) (OpReg rsp), - DELTA (delta - word_size) ]) - - -- push the stack args, right to left - push_code <- push_args (reverse stack_args) nilOL - -- On Win64, we also have to leave stack space for the arguments - -- that we are passing in registers - lss_code <- if platformOS platform == OSMinGW32 - then leaveStackSpace (length (allArgRegs platform)) - else return nilOL - delta <- getDeltaNat - - -- deal with static vs dynamic call targets - (callinsns,_cconv) <- - case target of - ForeignTarget (CmmLit (CmmLabel lbl)) conv - -> -- ToDo: stdcall arg sizes - return (unitOL (CALL (Left fn_imm) arg_regs), conv) - where fn_imm = ImmCLbl lbl - ForeignTarget expr conv - -> do (dyn_r, dyn_c) <- getSomeReg expr - return (dyn_c `snocOL` CALL (Right dyn_r) arg_regs, conv) - PrimTarget _ - -> panic $ "genCCall: Can't handle PrimTarget call type here, error " - ++ "probably because too many return values." - - let - -- The x86_64 ABI requires us to set %al to the number of SSE2 - -- registers that contain arguments, if the called routine - -- is a varargs function. We don't know whether it's a - -- varargs function or not, so we have to assume it is. - -- - -- It's not safe to omit this assignment, even if the number - -- of SSE2 regs in use is zero. If %al is larger than 8 - -- on entry to a varargs function, seg faults ensue. - assign_eax n = unitOL (MOV II32 (OpImm (ImmInt n)) (OpReg eax)) - - let call = callinsns `appOL` - toOL ( - -- Deallocate parameters after call for ccall; - -- stdcall has callee do it, but is not supported on - -- x86_64 target (see #3336) - (if real_size==0 then [] else - [ADD (intFormat (ncgWordWidth config)) (OpImm (ImmInt real_size)) (OpReg esp)]) - ++ - [DELTA (delta + real_size)] - ) - setDeltaNat (delta + real_size) - - let - -- assign the results, if necessary - assign_code [] = nilOL - assign_code [dest] = - case typeWidth rep of - W32 | isFloatType rep -> unitOL (MOV (floatFormat W32) - (OpReg xmm0) - (OpReg r_dest)) - W64 | isFloatType rep -> unitOL (MOV (floatFormat W64) - (OpReg xmm0) - (OpReg r_dest)) - _ -> unitOL (MOV (cmmTypeFormat rep) (OpReg rax) (OpReg r_dest)) - where - rep = localRegType dest - r_dest = getRegisterReg platform (CmmLocal dest) - assign_code _many = panic "genCCall.assign_code many" + let prom_args = map (maybePromoteCArg platform W32) args - return (adjust_rsp `appOL` - push_code `appOL` - load_args_code `appOL` - assign_args_code `appOL` - lss_code `appOL` - assign_eax sse_regs `appOL` - call `appOL` - assign_code dest_regs) - - where arg_size = 8 -- always, at the mo - - - load_args :: [CmmExpr] + let load_args :: [CmmExpr] -> [Reg] -- int regs avail for args -> [Reg] -- FP regs avail for args -> InstrBlock -- code computing args @@ -3064,7 +2947,7 @@ genCCall64' dflags target dest_regs args = do acode' = acode `snocOL` reg2reg arg_fmt tmp r return (code',acode') - arg_rep = cmmExprType dflags arg + arg_rep = cmmExprType platform arg arg_fmt = cmmTypeFormat arg_rep load_args_win :: [CmmExpr] @@ -3095,7 +2978,9 @@ genCCall64' dflags target dest_regs args = do load_args_win rest (ireg : usedInt) usedFP regs (code `appOL` arg_code ireg) where - arg_rep = cmmExprType dflags arg + arg_rep = cmmExprType platform arg + + arg_size = 8 -- always, at the mo push_args [] code = return code push_args (arg:rest) code @@ -3104,9 +2989,9 @@ genCCall64' dflags target dest_regs args = do delta <- getDeltaNat setDeltaNat (delta-arg_size) let code' = code `appOL` arg_code `appOL` toOL [ - SUB (intFormat (wordWidth dflags)) (OpImm (ImmInt arg_size)) (OpReg rsp), + SUB (intFormat (wordWidth platform)) (OpImm (ImmInt arg_size)) (OpReg rsp), DELTA (delta-arg_size), - MOV (floatFormat width) (OpReg arg_reg) (OpAddr (spRel (targetPlatform dflags) 0))] + MOV (floatFormat width) (OpReg arg_reg) (OpAddr (spRel platform 0))] push_args rest code' | otherwise = do @@ -3122,22 +3007,135 @@ genCCall64' dflags target dest_regs args = do DELTA (delta-arg_size)] push_args rest code' where - arg_rep = cmmExprType dflags arg + arg_rep = cmmExprType platform arg width = typeWidth arg_rep leaveStackSpace n = do delta <- getDeltaNat setDeltaNat (delta - n * arg_size) return $ toOL [ - SUB II64 (OpImm (ImmInt (n * wORD_SIZE dflags))) (OpReg rsp), + SUB II64 (OpImm (ImmInt (n * platformWordSizeInBytes platform))) (OpReg rsp), DELTA (delta - n * arg_size)] -maybePromoteCArg :: DynFlags -> Width -> CmmExpr -> CmmExpr -maybePromoteCArg dflags wto arg + (stack_args, int_regs_used, fp_regs_used, load_args_code, assign_args_code) + <- + if platformOS platform == OSMinGW32 + then load_args_win prom_args [] [] (allArgRegs platform) nilOL + else do + (stack_args, aregs, fregs, load_args_code, assign_args_code) + <- load_args prom_args (allIntArgRegs platform) + (allFPArgRegs platform) + nilOL nilOL + let used_regs rs as = reverse (drop (length rs) (reverse as)) + fregs_used = used_regs fregs (allFPArgRegs platform) + aregs_used = used_regs aregs (allIntArgRegs platform) + return (stack_args, aregs_used, fregs_used, load_args_code + , assign_args_code) + + let + arg_regs_used = int_regs_used ++ fp_regs_used + arg_regs = [eax] ++ arg_regs_used + -- for annotating the call instruction with + sse_regs = length fp_regs_used + arg_stack_slots = if platformOS platform == OSMinGW32 + then length stack_args + length (allArgRegs platform) + else length stack_args + tot_arg_size = arg_size * arg_stack_slots + + + -- Align stack to 16n for calls, assuming a starting stack + -- alignment of 16n - word_size on procedure entry. Which we + -- maintain. See Note [rts/StgCRun.c : Stack Alignment on X86] + let word_size = platformWordSizeInBytes (ncgPlatform config) + (real_size, adjust_rsp) <- + if (tot_arg_size + word_size) `rem` 16 == 0 + then return (tot_arg_size, nilOL) + else do -- we need to adjust... + delta <- getDeltaNat + setDeltaNat (delta - word_size) + return (tot_arg_size + word_size, toOL [ + SUB II64 (OpImm (ImmInt word_size)) (OpReg rsp), + DELTA (delta - word_size) ]) + + -- push the stack args, right to left + push_code <- push_args (reverse stack_args) nilOL + -- On Win64, we also have to leave stack space for the arguments + -- that we are passing in registers + lss_code <- if platformOS platform == OSMinGW32 + then leaveStackSpace (length (allArgRegs platform)) + else return nilOL + delta <- getDeltaNat + + -- deal with static vs dynamic call targets + (callinsns,_cconv) <- + case target of + ForeignTarget (CmmLit (CmmLabel lbl)) conv + -> -- ToDo: stdcall arg sizes + return (unitOL (CALL (Left fn_imm) arg_regs), conv) + where fn_imm = ImmCLbl lbl + ForeignTarget expr conv + -> do (dyn_r, dyn_c) <- getSomeReg expr + return (dyn_c `snocOL` CALL (Right dyn_r) arg_regs, conv) + PrimTarget _ + -> panic $ "genCCall: Can't handle PrimTarget call type here, error " + ++ "probably because too many return values." + + let + -- The x86_64 ABI requires us to set %al to the number of SSE2 + -- registers that contain arguments, if the called routine + -- is a varargs function. We don't know whether it's a + -- varargs function or not, so we have to assume it is. + -- + -- It's not safe to omit this assignment, even if the number + -- of SSE2 regs in use is zero. If %al is larger than 8 + -- on entry to a varargs function, seg faults ensue. + assign_eax n = unitOL (MOV II32 (OpImm (ImmInt n)) (OpReg eax)) + + let call = callinsns `appOL` + toOL ( + -- Deallocate parameters after call for ccall; + -- stdcall has callee do it, but is not supported on + -- x86_64 target (see #3336) + (if real_size==0 then [] else + [ADD (intFormat (ncgWordWidth config)) (OpImm (ImmInt real_size)) (OpReg esp)]) + ++ + [DELTA (delta + real_size)] + ) + setDeltaNat (delta + real_size) + + let + -- assign the results, if necessary + assign_code [] = nilOL + assign_code [dest] = + case typeWidth rep of + W32 | isFloatType rep -> unitOL (MOV (floatFormat W32) + (OpReg xmm0) + (OpReg r_dest)) + W64 | isFloatType rep -> unitOL (MOV (floatFormat W64) + (OpReg xmm0) + (OpReg r_dest)) + _ -> unitOL (MOV (cmmTypeFormat rep) (OpReg rax) (OpReg r_dest)) + where + rep = localRegType dest + r_dest = getRegisterReg platform (CmmLocal dest) + assign_code _many = panic "genCCall.assign_code many" + + return (adjust_rsp `appOL` + push_code `appOL` + load_args_code `appOL` + assign_args_code `appOL` + lss_code `appOL` + assign_eax sse_regs `appOL` + call `appOL` + assign_code dest_regs) + + +maybePromoteCArg :: Platform -> Width -> CmmExpr -> CmmExpr +maybePromoteCArg platform wto arg | wfrom < wto = CmmMachOp (MO_UU_Conv wfrom wto) [arg] | otherwise = arg where - wfrom = cmmExprWidth dflags arg + wfrom = cmmExprWidth platform arg outOfLineCmmOp :: BlockId -> CallishMachOp -> Maybe CmmFormal -> [CmmActual] -> NatM InstrBlock @@ -3257,7 +3255,7 @@ genSwitch expr targets = do let platform = ncgPlatform config if ncgPIC config then do - (reg,e_code) <- getNonClobberedReg (cmmOffset dflags expr offset) + (reg,e_code) <- getNonClobberedReg (cmmOffset platform expr offset) -- getNonClobberedReg because it needs to survive across t_code lbl <- getNewLabelNat let is32bit = target32Bit platform @@ -3298,7 +3296,7 @@ genSwitch expr targets = do JMP_TBL (OpReg tableReg) ids rosection lbl ] else do - (reg,e_code) <- getSomeReg (cmmOffset dflags expr offset) + (reg,e_code) <- getSomeReg (cmmOffset platform expr offset) lbl <- getNewLabelNat let op = OpAddr (AddrBaseIndex EABaseNone (EAIndex reg (platformWordSizeInBytes platform)) (ImmCLbl lbl)) code = e_code `appOL` toOL [ diff --git a/compiler/GHC/CmmToAsm/X86/Ppr.hs b/compiler/GHC/CmmToAsm/X86/Ppr.hs index 5aa216f6ba..0dfd394d8e 100644 --- a/compiler/GHC/CmmToAsm/X86/Ppr.hs +++ b/compiler/GHC/CmmToAsm/X86/Ppr.hs @@ -507,11 +507,8 @@ pprAlignForSection platform seg = _ -> int 8 pprDataItem :: NCGConfig -> CmmLit -> SDoc -pprDataItem config lit = sdocWithDynFlags $ \dflags -> pprDataItem' dflags config lit - -pprDataItem' :: DynFlags -> NCGConfig -> CmmLit -> SDoc -pprDataItem' dflags config lit - = vcat (ppr_item (cmmTypeFormat $ cmmLitType dflags lit) lit) +pprDataItem config lit + = vcat (ppr_item (cmmTypeFormat $ cmmLitType platform lit) lit) where platform = ncgPlatform config imm = litToImm lit |