diff options
Diffstat (limited to 'compiler')
-rw-r--r-- | compiler/cmm/CmmMachOp.hs | 29 | ||||
-rw-r--r-- | compiler/cmm/CmmParse.y | 37 | ||||
-rw-r--r-- | compiler/cmm/PprC.hs | 12 | ||||
-rw-r--r-- | compiler/codeGen/StgCmmPrim.hs | 49 | ||||
-rw-r--r-- | compiler/llvmGen/LlvmCodeGen/CodeGen.hs | 43 | ||||
-rw-r--r-- | compiler/nativeGen/PPC/CodeGen.hs | 20 | ||||
-rw-r--r-- | compiler/nativeGen/SPARC/CodeGen.hs | 21 | ||||
-rw-r--r-- | compiler/nativeGen/X86/CodeGen.hs | 25 |
8 files changed, 114 insertions, 122 deletions
diff --git a/compiler/cmm/CmmMachOp.hs b/compiler/cmm/CmmMachOp.hs index e9215d5021..f3f9e74a0b 100644 --- a/compiler/cmm/CmmMachOp.hs +++ b/compiler/cmm/CmmMachOp.hs @@ -21,6 +21,7 @@ module CmmMachOp -- CallishMachOp , CallishMachOp(..), callishMachOpHints , pprCallishMachOp + , machOpMemcpyishAlign -- Atomic read-modify-write , AtomicMachOp(..) @@ -565,12 +566,12 @@ data CallishMachOp -- would the majority of use cases in ghc anyways - -- Note that these three MachOps all take 1 extra parameter than the - -- standard C lib versions. The extra (last) parameter contains - -- alignment of the pointers. Used for optimisation in backends. - | MO_Memcpy - | MO_Memset - | MO_Memmove + -- These three MachOps are parameterised by the known alignment + -- of the destination and source (for memcpy/memmove) pointers. + -- This information may be used for optimisation in backends. + | MO_Memcpy Int + | MO_Memset Int + | MO_Memmove Int | MO_PopCnt Width | MO_Clz Width @@ -600,8 +601,16 @@ pprCallishMachOp mo = text (show mo) callishMachOpHints :: CallishMachOp -> ([ForeignHint], [ForeignHint]) callishMachOpHints op = case op of - MO_Memcpy -> ([], [AddrHint,AddrHint,NoHint,NoHint]) - MO_Memset -> ([], [AddrHint,NoHint,NoHint,NoHint]) - MO_Memmove -> ([], [AddrHint,AddrHint,NoHint,NoHint]) - _ -> ([],[]) + MO_Memcpy _ -> ([], [AddrHint,AddrHint,NoHint]) + MO_Memset _ -> ([], [AddrHint,NoHint,NoHint]) + MO_Memmove _ -> ([], [AddrHint,AddrHint,NoHint]) + _ -> ([],[]) -- empty lists indicate NoHint + +-- | The alignment of a 'memcpy'-ish operation. +machOpMemcpyishAlign :: CallishMachOp -> Maybe Int +machOpMemcpyishAlign op = case op of + MO_Memcpy align -> Just align + MO_Memset align -> Just align + MO_Memmove align -> Just align + _ -> Nothing diff --git a/compiler/cmm/CmmParse.y b/compiler/cmm/CmmParse.y index fca231e988..694d79ead9 100644 --- a/compiler/cmm/CmmParse.y +++ b/compiler/cmm/CmmParse.y @@ -975,22 +975,38 @@ machOps = listToUFM $ ( "i2f64", flip MO_SF_Conv W64 ) ] +callishMachOps :: UniqFM ([CmmExpr] -> (CallishMachOp, [CmmExpr])) callishMachOps = listToUFM $ map (\(x, y) -> (mkFastString x, y)) [ - ( "write_barrier", MO_WriteBarrier ), - ( "memcpy", MO_Memcpy ), - ( "memset", MO_Memset ), - ( "memmove", MO_Memmove ), + ( "write_barrier", (,) MO_WriteBarrier ), + ( "memcpy", memcpyLikeTweakArgs MO_Memcpy ), + ( "memset", memcpyLikeTweakArgs MO_Memset ), + ( "memmove", memcpyLikeTweakArgs MO_Memmove ), - ("prefetch0",MO_Prefetch_Data 0), - ("prefetch1",MO_Prefetch_Data 1), - ("prefetch2",MO_Prefetch_Data 2), - ("prefetch3",MO_Prefetch_Data 3) + ("prefetch0", (,) $ MO_Prefetch_Data 0), + ("prefetch1", (,) $ MO_Prefetch_Data 1), + ("prefetch2", (,) $ MO_Prefetch_Data 2), + ("prefetch3", (,) $ MO_Prefetch_Data 3) -- ToDo: the rest, maybe -- edit: which rest? -- also: how do we tell CMM Lint how to type check callish macops? ] + where + memcpyLikeTweakArgs :: (Int -> CallishMachOp) -> [CmmExpr] -> (CallishMachOp, [CmmExpr]) + memcpyLikeTweakArgs op [] = pgmError "memcpy-like function requires at least one argument" + memcpyLikeTweakArgs op args@(_:_) = + -- Force alignment with result to ensure pprPgmError fires + align `seq` (op align, args') + where + args' = init args + align = case last args of + CmmLit (CmmInt alignInteger _) -> fromInteger alignInteger + e -> pprPgmError "Non-constant alignment in memcpy-like function:" (ppr e) + -- The alignment of memcpy-ish operations must be a + -- compile-time constant. We verify this here, passing it around + -- in the MO_* constructor. In order to do this, however, we + -- must intercept the arguments in primCall. parseSafety :: String -> P Safety parseSafety "safe" = return PlaySafe @@ -1207,10 +1223,11 @@ primCall primCall results_code name args_code = case lookupUFM callishMachOps name of Nothing -> fail ("unknown primitive " ++ unpackFS name) - Just p -> return $ do + Just f -> return $ do results <- sequence results_code args <- sequence args_code - code (emitPrimCall (map fst results) p args) + let (p, args') = f args + code (emitPrimCall (map fst results) p args') doStore :: CmmType -> CmmParse CmmExpr -> CmmParse CmmExpr -> CmmParse () doStore rep addr_code val_code diff --git a/compiler/cmm/PprC.hs b/compiler/cmm/PprC.hs index 92c818242d..3703f0ae1f 100644 --- a/compiler/cmm/PprC.hs +++ b/compiler/cmm/PprC.hs @@ -238,13 +238,13 @@ pprStmt stmt = hargs = zip args arg_hints fn_call - -- The mem primops carry an extra alignment arg, must drop it. + -- The mem primops carry an extra alignment arg. -- We could maybe emit an alignment directive using this info. -- We also need to cast mem primops to prevent conflicts with GCC -- builtins (see bug #5967). - | op `elem` [MO_Memcpy, MO_Memset, MO_Memmove] + | Just _align <- machOpMemcpyishAlign op = (ptext (sLit ";EF_(") <> fn <> char ')' <> semi) $$ - pprForeignCall fn cconv hresults (init hargs) + pprForeignCall fn cconv hresults hargs | otherwise = pprCall fn cconv hresults hargs @@ -745,9 +745,9 @@ pprCallishMachOp_for_C mop MO_F32_Exp -> ptext (sLit "expf") MO_F32_Sqrt -> ptext (sLit "sqrtf") MO_WriteBarrier -> ptext (sLit "write_barrier") - MO_Memcpy -> ptext (sLit "memcpy") - MO_Memset -> ptext (sLit "memset") - MO_Memmove -> ptext (sLit "memmove") + MO_Memcpy _ -> ptext (sLit "memcpy") + MO_Memset _ -> ptext (sLit "memset") + MO_Memmove _ -> ptext (sLit "memmove") (MO_BSwap w) -> ptext (sLit $ bSwapLabel w) (MO_PopCnt w) -> ptext (sLit $ popCntLabel w) (MO_Clz w) -> ptext (sLit $ clzLabel w) diff --git a/compiler/codeGen/StgCmmPrim.hs b/compiler/codeGen/StgCmmPrim.hs index e208318e17..d812905594 100644 --- a/compiler/codeGen/StgCmmPrim.hs +++ b/compiler/codeGen/StgCmmPrim.hs @@ -1644,8 +1644,7 @@ doCopyByteArrayOp = emitCopyByteArray copy -- Copy data (we assume the arrays aren't overlapping since -- they're of different types) copy _src _dst dst_p src_p bytes = - do dflags <- getDynFlags - emitMemcpyCall dst_p src_p bytes (mkIntExpr dflags 1) + emitMemcpyCall dst_p src_p bytes 1 -- | Takes a source 'MutableByteArray#', an offset in the source -- array, a destination 'MutableByteArray#', an offset into the @@ -1662,8 +1661,8 @@ doCopyMutableByteArrayOp = emitCopyByteArray copy copy src dst dst_p src_p bytes = do dflags <- getDynFlags [moveCall, cpyCall] <- forkAlts [ - getCode $ emitMemmoveCall dst_p src_p bytes (mkIntExpr dflags 1), - getCode $ emitMemcpyCall dst_p src_p bytes (mkIntExpr dflags 1) + getCode $ emitMemmoveCall dst_p src_p bytes 1, + getCode $ emitMemcpyCall dst_p src_p bytes 1 ] emit =<< mkCmmIfThenElse (cmmEqWord dflags src dst) moveCall cpyCall @@ -1685,7 +1684,7 @@ doCopyByteArrayToAddrOp src src_off dst_p bytes = do -- Use memcpy (we are allowed to assume the arrays aren't overlapping) dflags <- getDynFlags src_p <- assignTempE $ cmmOffsetExpr dflags (cmmOffsetB dflags src (arrWordsHdrSize dflags)) src_off - emitMemcpyCall dst_p src_p bytes (mkIntExpr dflags 1) + emitMemcpyCall dst_p src_p bytes 1 -- | Takes a source 'MutableByteArray#', an offset in the source array, a -- destination 'Addr#', and the number of bytes to copy. Copies the given @@ -1702,7 +1701,7 @@ doCopyAddrToByteArrayOp src_p dst dst_off bytes = do -- Use memcpy (we are allowed to assume the arrays aren't overlapping) dflags <- getDynFlags dst_p <- assignTempE $ cmmOffsetExpr dflags (cmmOffsetB dflags dst (arrWordsHdrSize dflags)) dst_off - emitMemcpyCall dst_p src_p bytes (mkIntExpr dflags 1) + emitMemcpyCall dst_p src_p bytes 1 -- ---------------------------------------------------------------------------- @@ -1716,7 +1715,7 @@ doSetByteArrayOp :: CmmExpr -> CmmExpr -> CmmExpr -> CmmExpr doSetByteArrayOp ba off len c = do dflags <- getDynFlags p <- assignTempE $ cmmOffsetExpr dflags (cmmOffsetB dflags ba (arrWordsHdrSize dflags)) off - emitMemsetCall p c len (mkIntExpr dflags 1) + emitMemsetCall p c len 1 -- ---------------------------------------------------------------------------- -- Allocating arrays @@ -1789,7 +1788,7 @@ doCopyArrayOp = emitCopyArray copy copy _src _dst dst_p src_p bytes = do dflags <- getDynFlags emitMemcpyCall dst_p src_p (mkIntExpr dflags bytes) - (mkIntExpr dflags (wORD_SIZE dflags)) + (wORD_SIZE dflags) -- | Takes a source 'MutableArray#', an offset in the source array, a @@ -1807,9 +1806,9 @@ doCopyMutableArrayOp = emitCopyArray copy dflags <- getDynFlags [moveCall, cpyCall] <- forkAlts [ getCode $ emitMemmoveCall dst_p src_p (mkIntExpr dflags bytes) - (mkIntExpr dflags (wORD_SIZE dflags)), + (wORD_SIZE dflags), getCode $ emitMemcpyCall dst_p src_p (mkIntExpr dflags bytes) - (mkIntExpr dflags (wORD_SIZE dflags)) + (wORD_SIZE dflags) ] emit =<< mkCmmIfThenElse (cmmEqWord dflags src dst) moveCall cpyCall @@ -1856,7 +1855,7 @@ doCopySmallArrayOp = emitCopySmallArray copy copy _src _dst dst_p src_p bytes = do dflags <- getDynFlags emitMemcpyCall dst_p src_p (mkIntExpr dflags bytes) - (mkIntExpr dflags (wORD_SIZE dflags)) + (wORD_SIZE dflags) doCopySmallMutableArrayOp :: CmmExpr -> CmmExpr -> CmmExpr -> CmmExpr -> WordOff @@ -1870,9 +1869,9 @@ doCopySmallMutableArrayOp = emitCopySmallArray copy dflags <- getDynFlags [moveCall, cpyCall] <- forkAlts [ getCode $ emitMemmoveCall dst_p src_p (mkIntExpr dflags bytes) - (mkIntExpr dflags (wORD_SIZE dflags)) + (wORD_SIZE dflags) , getCode $ emitMemcpyCall dst_p src_p (mkIntExpr dflags bytes) - (mkIntExpr dflags (wORD_SIZE dflags)) + (wORD_SIZE dflags) ] emit =<< mkCmmIfThenElse (cmmEqWord dflags src dst) moveCall cpyCall @@ -1937,7 +1936,7 @@ emitCloneArray info_p res_r src src_off n = do (mkIntExpr dflags (arrPtrsHdrSizeW dflags)) src_off) emitMemcpyCall dst_p src_p (mkIntExpr dflags (wordsToBytes dflags n)) - (mkIntExpr dflags (wORD_SIZE dflags)) + (wORD_SIZE dflags) emit $ mkAssign (CmmLocal res_r) (CmmReg arr) @@ -1974,7 +1973,7 @@ emitCloneSmallArray info_p res_r src src_off n = do (mkIntExpr dflags (smallArrPtrsHdrSizeW dflags)) src_off) emitMemcpyCall dst_p src_p (mkIntExpr dflags (wordsToBytes dflags n)) - (mkIntExpr dflags (wORD_SIZE dflags)) + (wORD_SIZE dflags) emit $ mkAssign (CmmLocal res_r) (CmmReg arr) @@ -1993,7 +1992,7 @@ emitSetCards dst_start dst_cards_start n = do emitMemsetCall (cmmAddWord dflags dst_cards_start start_card) (mkIntExpr dflags 1) (cmmAddWord dflags (cmmSubWord dflags end_card start_card) (mkIntExpr dflags 1)) - (mkIntExpr dflags 1) -- no alignment (1 byte) + 1 -- no alignment (1 byte) -- Convert an element index to a card index cardCmm :: DynFlags -> CmmExpr -> CmmExpr @@ -2101,29 +2100,29 @@ doCasByteArray res mba idx idx_ty old new = do -- Helpers for emitting function calls -- | Emit a call to @memcpy@. -emitMemcpyCall :: CmmExpr -> CmmExpr -> CmmExpr -> CmmExpr -> FCode () +emitMemcpyCall :: CmmExpr -> CmmExpr -> CmmExpr -> Int -> FCode () emitMemcpyCall dst src n align = do emitPrimCall [ {-no results-} ] - MO_Memcpy - [ dst, src, n, align ] + (MO_Memcpy align) + [ dst, src, n ] -- | Emit a call to @memmove@. -emitMemmoveCall :: CmmExpr -> CmmExpr -> CmmExpr -> CmmExpr -> FCode () +emitMemmoveCall :: CmmExpr -> CmmExpr -> CmmExpr -> Int -> FCode () emitMemmoveCall dst src n align = do emitPrimCall [ {- no results -} ] - MO_Memmove - [ dst, src, n, align ] + (MO_Memmove align) + [ dst, src, n ] -- | Emit a call to @memset@. The second argument must fit inside an -- unsigned char. -emitMemsetCall :: CmmExpr -> CmmExpr -> CmmExpr -> CmmExpr -> FCode () +emitMemsetCall :: CmmExpr -> CmmExpr -> CmmExpr -> Int -> FCode () emitMemsetCall dst c n align = do emitPrimCall [ {- no results -} ] - MO_Memset - [ dst, c, n, align ] + (MO_Memset align) + [ dst, c, n ] emitBSwapCall :: LocalReg -> CmmExpr -> Width -> FCode () emitBSwapCall res x width = do diff --git a/compiler/llvmGen/LlvmCodeGen/CodeGen.hs b/compiler/llvmGen/LlvmCodeGen/CodeGen.hs index 2c48c28a28..ffe9d619f6 100644 --- a/compiler/llvmGen/LlvmCodeGen/CodeGen.hs +++ b/compiler/llvmGen/LlvmCodeGen/CodeGen.hs @@ -24,7 +24,8 @@ import Hoopl import DynFlags import FastString import ForeignCall -import Outputable +import Outputable hiding (panic, pprPanic) +import qualified Outputable import Platform import OrdList import UniqSupply @@ -230,16 +231,13 @@ genCall (PrimTarget (MO_AtomicRead _)) [dst] [addr] = do -- Handle memcpy function specifically since llvm's intrinsic version takes -- some extra parameters. -genCall t@(PrimTarget op) [] args' - | op == MO_Memcpy || - op == MO_Memset || - op == MO_Memmove = do +genCall t@(PrimTarget op) [] args + | Just align <- machOpMemcpyishAlign op = do dflags <- getDynFlags - let (args, alignVal) = splitAlignVal args' - isVolTy = [i1] + let isVolTy = [i1] isVolVal = [mkIntLit i1 0] - argTy | op == MO_Memset = [i8Ptr, i8, llvmWord dflags, i32] ++ isVolTy - | otherwise = [i8Ptr, i8Ptr, llvmWord dflags, i32] ++ isVolTy + argTy | MO_Memset _ <- op = [i8Ptr, i8, llvmWord dflags, i32] ++ isVolTy + | otherwise = [i8Ptr, i8Ptr, llvmWord dflags, i32] ++ isVolTy funTy = \name -> LMFunction $ LlvmFunctionDecl name ExternallyVisible CC_Ccc LMVoid FixedArgs (tysToParams argTy) Nothing @@ -250,21 +248,12 @@ genCall t@(PrimTarget op) [] args' (argVars', stmts3) <- castVars $ zip argVars argTy stmts4 <- getTrashStmts - let arguments = argVars' ++ (alignVal:isVolVal) + let alignVal = mkIntLit i32 align + arguments = argVars' ++ (alignVal:isVolVal) call = Expr $ Call StdCall fptr arguments [] stmts = stmts1 `appOL` stmts2 `appOL` stmts3 `appOL` stmts4 `snocOL` call return (stmts, top1 ++ top2) - where - splitAlignVal xs = (init xs, extractLit $ last xs) - - -- Fix for trac #6158. Since LLVM 3.1, opt fails when given anything other - -- than a direct constant (i.e. 'i32 8') as the alignment argument for the - -- memcpy & co llvm intrinsic functions. So we handle this directly now. - extractLit (CmmLit (CmmInt i _)) = mkIntLit i32 i - extractLit _other = trace ("WARNING: Non constant alignment value given" ++ - " for memcpy! Please report to GHC developers") - mkIntLit i32 0 -- Handle all other foreign calls and prim ops. genCall target res args = do @@ -534,9 +523,9 @@ cmmPrimOpFunctions mop = do MO_F64_Cosh -> fsLit "cosh" MO_F64_Tanh -> fsLit "tanh" - MO_Memcpy -> fsLit $ "llvm.memcpy." ++ intrinTy1 - MO_Memmove -> fsLit $ "llvm.memmove." ++ intrinTy1 - MO_Memset -> fsLit $ "llvm.memset." ++ intrinTy2 + MO_Memcpy _ -> fsLit $ "llvm.memcpy." ++ intrinTy1 + MO_Memmove _ -> fsLit $ "llvm.memmove." ++ intrinTy1 + MO_Memset _ -> fsLit $ "llvm.memset." ++ intrinTy2 (MO_PopCnt w) -> fsLit $ "llvm.ctpop." ++ showSDoc dflags (ppr $ widthToLlvmInt w) (MO_BSwap w) -> fsLit $ "llvm.bswap." ++ showSDoc dflags (ppr $ widthToLlvmInt w) @@ -1646,6 +1635,14 @@ toIWord :: Integral a => DynFlags -> a -> LlvmVar toIWord dflags = mkIntLit (llvmWord dflags) +-- | Error functions +panic :: String -> a +panic s = Outputable.panic $ "LlvmCodeGen.CodeGen." ++ s + +pprPanic :: String -> SDoc -> a +pprPanic s d = Outputable.pprPanic ("LlvmCodeGen.CodeGen." ++ s) d + + -- | Returns TBAA meta data by unique getTBAAMeta :: Unique -> LlvmM [MetaAnnot] getTBAAMeta u = do diff --git a/compiler/nativeGen/PPC/CodeGen.hs b/compiler/nativeGen/PPC/CodeGen.hs index a115980183..299d6b702b 100644 --- a/compiler/nativeGen/PPC/CodeGen.hs +++ b/compiler/nativeGen/PPC/CodeGen.hs @@ -923,7 +923,7 @@ genCCall' _ _ (PrimTarget MO_Touch) _ _ genCCall' _ _ (PrimTarget (MO_Prefetch_Data _)) _ _ = return $ nilOL -genCCall' dflags gcp target dest_regs args0 +genCCall' dflags gcp target dest_regs args = ASSERT(not $ any (`elem` [II16]) $ map cmmTypeSize argReps) -- we rely on argument promotion in the codeGen do @@ -978,17 +978,7 @@ genCCall' dflags gcp target dest_regs args0 map (widthInBytes . typeWidth) argReps GCPLinux -> roundTo 16 finalStack - -- need to remove alignment information - args | PrimTarget mop <- target, - (mop == MO_Memcpy || - mop == MO_Memset || - mop == MO_Memmove) - = init args0 - - | otherwise - = args0 - - argReps = map (cmmExprType dflags) args0 + argReps = map (cmmExprType dflags) args roundTo a x | x `mod` a == 0 = x | otherwise = x + a - (x `mod` a) @@ -1173,9 +1163,9 @@ genCCall' dflags gcp target dest_regs args0 MO_UF_Conv w -> (fsLit $ word2FloatLabel w, False) - MO_Memcpy -> (fsLit "memcpy", False) - MO_Memset -> (fsLit "memset", False) - MO_Memmove -> (fsLit "memmove", False) + MO_Memcpy _ -> (fsLit "memcpy", False) + MO_Memset _ -> (fsLit "memset", False) + MO_Memmove _ -> (fsLit "memmove", False) MO_BSwap w -> (fsLit $ bSwapLabel w, False) MO_PopCnt w -> (fsLit $ popCntLabel w, False) diff --git a/compiler/nativeGen/SPARC/CodeGen.hs b/compiler/nativeGen/SPARC/CodeGen.hs index a9d861946e..4792933366 100644 --- a/compiler/nativeGen/SPARC/CodeGen.hs +++ b/compiler/nativeGen/SPARC/CodeGen.hs @@ -404,19 +404,8 @@ genCCall (PrimTarget MO_WriteBarrier) _ _ genCCall (PrimTarget (MO_Prefetch_Data _)) _ _ = return $ nilOL -genCCall target dest_regs args0 - = do - -- need to remove alignment information - let args | PrimTarget mop <- target, - (mop == MO_Memcpy || - mop == MO_Memset || - mop == MO_Memmove) - = init args0 - - | otherwise - = args0 - - -- work out the arguments, and assign them to integer regs +genCCall target dest_regs args + = do -- work out the arguments, and assign them to integer regs argcode_and_vregs <- mapM arg_to_int_vregs args let (argcodes, vregss) = unzip argcode_and_vregs let vregs = concat vregss @@ -653,9 +642,9 @@ outOfLineMachOp_table mop MO_UF_Conv w -> fsLit $ word2FloatLabel w - MO_Memcpy -> fsLit "memcpy" - MO_Memset -> fsLit "memset" - MO_Memmove -> fsLit "memmove" + MO_Memcpy _ -> fsLit "memcpy" + MO_Memset _ -> fsLit "memset" + MO_Memmove _ -> fsLit "memmove" MO_BSwap w -> fsLit $ bSwapLabel w MO_PopCnt w -> fsLit $ popCntLabel w diff --git a/compiler/nativeGen/X86/CodeGen.hs b/compiler/nativeGen/X86/CodeGen.hs index 7b7cc54bbe..a052fdacdf 100644 --- a/compiler/nativeGen/X86/CodeGen.hs +++ b/compiler/nativeGen/X86/CodeGen.hs @@ -1645,10 +1645,8 @@ genCCall -- Unroll memcpy calls if the source and destination pointers are at -- least DWORD aligned and the number of bytes to copy isn't too -- large. Otherwise, call C's memcpy. -genCCall dflags is32Bit (PrimTarget MO_Memcpy) _ - [dst, src, - (CmmLit (CmmInt n _)), - (CmmLit (CmmInt align _))] +genCCall dflags is32Bit (PrimTarget (MO_Memcpy align)) _ + [dst, src, CmmLit (CmmInt n _)] | fromInteger insns <= maxInlineMemcpyInsns dflags && align .&. 3 == 0 = do code_dst <- getAnyReg dst dst_r <- getNewRegNat size @@ -1694,11 +1692,10 @@ genCCall dflags is32Bit (PrimTarget MO_Memcpy) _ dst_addr = AddrBaseIndex (EABaseReg dst) EAIndexNone (ImmInteger (n - i)) -genCCall dflags _ (PrimTarget MO_Memset) _ +genCCall dflags _ (PrimTarget (MO_Memset align)) _ [dst, CmmLit (CmmInt c _), - CmmLit (CmmInt n _), - CmmLit (CmmInt align _)] + CmmLit (CmmInt n _)] | fromInteger insns <= maxInlineMemsetInsns dflags && align .&. 3 == 0 = do code_dst <- getAnyReg dst dst_r <- getNewRegNat size @@ -2507,19 +2504,13 @@ outOfLineCmmOp mop res args let target = ForeignTarget targetExpr (ForeignConvention CCallConv [] [] CmmMayReturn) - stmtToInstrs (CmmUnsafeForeignCall target (catMaybes [res]) args') + stmtToInstrs (CmmUnsafeForeignCall target (catMaybes [res]) args) where -- Assume we can call these functions directly, and that they're not in a dynamic library. -- TODO: Why is this ok? Under linux this code will be in libm.so -- Is is because they're really implemented as a primitive instruction by the assembler?? -- BL 2009/12/31 lbl = mkForeignLabel fn Nothing ForeignLabelInThisPackage IsFunction - args' = case mop of - MO_Memcpy -> init args - MO_Memset -> init args - MO_Memmove -> init args - _ -> args - fn = case mop of MO_F32_Sqrt -> fsLit "sqrtf" MO_F32_Sin -> fsLit "sinf" @@ -2553,9 +2544,9 @@ outOfLineCmmOp mop res args MO_F64_Tanh -> fsLit "tanh" MO_F64_Pwr -> fsLit "pow" - MO_Memcpy -> fsLit "memcpy" - MO_Memset -> fsLit "memset" - MO_Memmove -> fsLit "memmove" + MO_Memcpy _ -> fsLit "memcpy" + MO_Memset _ -> fsLit "memset" + MO_Memmove _ -> fsLit "memmove" MO_PopCnt _ -> fsLit "popcnt" MO_BSwap _ -> fsLit "bswap" |