summaryrefslogtreecommitdiff
path: root/compiler/codeGen
diff options
context:
space:
mode:
authorIavor S. Diatchki <iavor.diatchki@gmail.com>2012-03-13 22:15:11 -0700
committerIavor S. Diatchki <iavor.diatchki@gmail.com>2012-03-13 22:15:11 -0700
commit1dd9b1ae1a5994a78ec1c4ca18c8df6e5b2ca9e0 (patch)
tree78e4df29214ffbb8076bd00183ab6fbf68e17ffb /compiler/codeGen
parentcfd89e12334e7dbcc8d9aaee898bcc38b77f549b (diff)
parent93299cce9a4f7bc65b8164f779a37ef7f9f7c4a0 (diff)
downloadhaskell-1dd9b1ae1a5994a78ec1c4ca18c8df6e5b2ca9e0.tar.gz
Merge remote-tracking branch 'origin/master' into type-nats
Conflicts: compiler/coreSyn/CoreLint.lhs compiler/deSugar/DsBinds.lhs compiler/hsSyn/HsTypes.lhs compiler/iface/IfaceType.lhs compiler/rename/RnHsSyn.lhs compiler/rename/RnTypes.lhs compiler/stgSyn/StgLint.lhs compiler/typecheck/TcHsType.lhs compiler/utils/ListSetOps.lhs
Diffstat (limited to 'compiler/codeGen')
-rw-r--r--compiler/codeGen/CgClosure.lhs2
-rw-r--r--compiler/codeGen/CgForeignCall.hs4
-rw-r--r--compiler/codeGen/CgPrimOp.hs117
-rw-r--r--compiler/codeGen/CgUtils.hs3
-rw-r--r--compiler/codeGen/StgCmmForeign.hs4
5 files changed, 121 insertions, 9 deletions
diff --git a/compiler/codeGen/CgClosure.lhs b/compiler/codeGen/CgClosure.lhs
index d6537c27e5..4d1ce50099 100644
--- a/compiler/codeGen/CgClosure.lhs
+++ b/compiler/codeGen/CgClosure.lhs
@@ -485,7 +485,7 @@ emitBlackHoleCode is_single_entry = do
stmtsC [
CmmStore (cmmOffsetW (CmmReg nodeReg) fixedHdrSize)
(CmmReg (CmmGlobal CurrentTSO)),
- CmmCall (CmmPrim MO_WriteBarrier) [] [] CmmMayReturn,
+ CmmCall (CmmPrim MO_WriteBarrier Nothing) [] [] CmmMayReturn,
CmmStore (CmmReg nodeReg) (CmmReg (CmmGlobal EagerBlackholeInfo))
]
\end{code}
diff --git a/compiler/codeGen/CgForeignCall.hs b/compiler/codeGen/CgForeignCall.hs
index 09636bc6b2..16e77eca35 100644
--- a/compiler/codeGen/CgForeignCall.hs
+++ b/compiler/codeGen/CgForeignCall.hs
@@ -78,9 +78,11 @@ emitForeignCall results (CCall (CCallSpec target cconv safety)) args live
where
(call_args, cmm_target)
= case target of
+ StaticTarget _ _ False ->
+ panic "emitForeignCall: unexpected FFI value import"
-- If the packageId is Nothing then the label is taken to be in the
-- package currently being compiled.
- StaticTarget lbl mPkgId
+ StaticTarget lbl mPkgId True
-> let labelSource
= case mPkgId of
Nothing -> ForeignLabelInThisPackage
diff --git a/compiler/codeGen/CgPrimOp.hs b/compiler/codeGen/CgPrimOp.hs
index b0865d69d9..3f1187f6be 100644
--- a/compiler/codeGen/CgPrimOp.hs
+++ b/compiler/codeGen/CgPrimOp.hs
@@ -33,6 +33,8 @@ import Outputable
import FastString
import StaticFlags
+import Control.Monad
+
-- ---------------------------------------------------------------------------
-- Code generation for PrimOps
@@ -430,7 +432,7 @@ emitPrimOp [res] op args live
= do vols <- getVolatileRegs live
emitForeignCall' PlayRisky
[CmmHinted res NoHint]
- (CmmPrim prim)
+ (CmmPrim prim Nothing)
[CmmHinted a NoHint | a<-args] -- ToDo: hints?
(Just vols)
NoC_SRT -- No SRT b/c we do PlayRisky
@@ -440,9 +442,114 @@ emitPrimOp [res] op args live
= let stmt = CmmAssign (CmmLocal res) (CmmMachOp mop args) in
stmtC stmt
+emitPrimOp [res_q, res_r] IntQuotRemOp [arg_x, arg_y] _
+ = let genericImpl
+ = [CmmAssign (CmmLocal res_q)
+ (CmmMachOp (MO_S_Quot wordWidth) [arg_x, arg_y]),
+ CmmAssign (CmmLocal res_r)
+ (CmmMachOp (MO_S_Rem wordWidth) [arg_x, arg_y])]
+ stmt = CmmCall (CmmPrim (MO_S_QuotRem wordWidth) (Just genericImpl))
+ [CmmHinted res_q NoHint,
+ CmmHinted res_r NoHint]
+ [CmmHinted arg_x NoHint,
+ CmmHinted arg_y NoHint]
+ CmmMayReturn
+ in stmtC stmt
+emitPrimOp [res_q, res_r] WordQuotRemOp [arg_x, arg_y] _
+ = let genericImpl
+ = [CmmAssign (CmmLocal res_q)
+ (CmmMachOp (MO_U_Quot wordWidth) [arg_x, arg_y]),
+ CmmAssign (CmmLocal res_r)
+ (CmmMachOp (MO_U_Rem wordWidth) [arg_x, arg_y])]
+ stmt = CmmCall (CmmPrim (MO_U_QuotRem wordWidth) (Just genericImpl))
+ [CmmHinted res_q NoHint,
+ CmmHinted res_r NoHint]
+ [CmmHinted arg_x NoHint,
+ CmmHinted arg_y NoHint]
+ CmmMayReturn
+ in stmtC stmt
+emitPrimOp [res_h, res_l] WordAdd2Op [arg_x, arg_y] _
+ = do r1 <- newLocalReg (cmmExprType arg_x)
+ r2 <- newLocalReg (cmmExprType arg_x)
+ -- This generic implementation is very simple and slow. We might
+ -- well be able to do better, but for now this at least works.
+ let genericImpl
+ = [CmmAssign (CmmLocal r1)
+ (add (bottomHalf arg_x) (bottomHalf arg_y)),
+ CmmAssign (CmmLocal r2)
+ (add (topHalf (CmmReg (CmmLocal r1)))
+ (add (topHalf arg_x) (topHalf arg_y))),
+ CmmAssign (CmmLocal res_h)
+ (topHalf (CmmReg (CmmLocal r2))),
+ CmmAssign (CmmLocal res_l)
+ (or (toTopHalf (CmmReg (CmmLocal r2)))
+ (bottomHalf (CmmReg (CmmLocal r1))))]
+ where topHalf x = CmmMachOp (MO_U_Shr wordWidth) [x, hww]
+ toTopHalf x = CmmMachOp (MO_Shl wordWidth) [x, hww]
+ bottomHalf x = CmmMachOp (MO_And wordWidth) [x, hwm]
+ add x y = CmmMachOp (MO_Add wordWidth) [x, y]
+ or x y = CmmMachOp (MO_Or wordWidth) [x, y]
+ hww = CmmLit (CmmInt (fromIntegral (widthInBits halfWordWidth))
+ wordWidth)
+ hwm = CmmLit (CmmInt halfWordMask wordWidth)
+ stmt = CmmCall (CmmPrim (MO_Add2 wordWidth) (Just genericImpl))
+ [CmmHinted res_h NoHint,
+ CmmHinted res_l NoHint]
+ [CmmHinted arg_x NoHint,
+ CmmHinted arg_y NoHint]
+ CmmMayReturn
+ stmtC stmt
+emitPrimOp [res_h, res_l] WordMul2Op [arg_x, arg_y] _
+ = do let t = cmmExprType arg_x
+ xlyl <- liftM CmmLocal $ newLocalReg t
+ xlyh <- liftM CmmLocal $ newLocalReg t
+ xhyl <- liftM CmmLocal $ newLocalReg t
+ r <- liftM CmmLocal $ newLocalReg t
+ -- This generic implementation is very simple and slow. We might
+ -- well be able to do better, but for now this at least works.
+ let genericImpl
+ = [CmmAssign xlyl
+ (mul (bottomHalf arg_x) (bottomHalf arg_y)),
+ CmmAssign xlyh
+ (mul (bottomHalf arg_x) (topHalf arg_y)),
+ CmmAssign xhyl
+ (mul (topHalf arg_x) (bottomHalf arg_y)),
+ CmmAssign r
+ (sum [topHalf (CmmReg xlyl),
+ bottomHalf (CmmReg xhyl),
+ bottomHalf (CmmReg xlyh)]),
+ CmmAssign (CmmLocal res_l)
+ (or (bottomHalf (CmmReg xlyl))
+ (toTopHalf (CmmReg r))),
+ CmmAssign (CmmLocal res_h)
+ (sum [mul (topHalf arg_x) (topHalf arg_y),
+ topHalf (CmmReg xhyl),
+ topHalf (CmmReg xlyh),
+ topHalf (CmmReg r)])]
+ where topHalf x = CmmMachOp (MO_U_Shr wordWidth) [x, hww]
+ toTopHalf x = CmmMachOp (MO_Shl wordWidth) [x, hww]
+ bottomHalf x = CmmMachOp (MO_And wordWidth) [x, hwm]
+ add x y = CmmMachOp (MO_Add wordWidth) [x, y]
+ sum = foldl1 add
+ mul x y = CmmMachOp (MO_Mul wordWidth) [x, y]
+ or x y = CmmMachOp (MO_Or wordWidth) [x, y]
+ hww = CmmLit (CmmInt (fromIntegral (widthInBits halfWordWidth))
+ wordWidth)
+ hwm = CmmLit (CmmInt halfWordMask wordWidth)
+ stmt = CmmCall (CmmPrim (MO_U_Mul2 wordWidth) (Just genericImpl))
+ [CmmHinted res_h NoHint,
+ CmmHinted res_l NoHint]
+ [CmmHinted arg_x NoHint,
+ CmmHinted arg_y NoHint]
+ CmmMayReturn
+ stmtC stmt
+
emitPrimOp _ op _ _
= pprPanic "emitPrimOp: can't translate PrimOp" (ppr op)
+newLocalReg :: CmmType -> FCode LocalReg
+newLocalReg t = do u <- newUnique
+ return $ LocalReg u t
-- These PrimOps are NOPs in Cmm
@@ -889,7 +996,7 @@ emitMemcpyCall dst src n align live = do
vols <- getVolatileRegs live
emitForeignCall' PlayRisky
[{-no results-}]
- (CmmPrim MO_Memcpy)
+ (CmmPrim MO_Memcpy Nothing)
[ (CmmHinted dst AddrHint)
, (CmmHinted src AddrHint)
, (CmmHinted n NoHint)
@@ -906,7 +1013,7 @@ emitMemmoveCall dst src n align live = do
vols <- getVolatileRegs live
emitForeignCall' PlayRisky
[{-no results-}]
- (CmmPrim MO_Memmove)
+ (CmmPrim MO_Memmove Nothing)
[ (CmmHinted dst AddrHint)
, (CmmHinted src AddrHint)
, (CmmHinted n NoHint)
@@ -924,7 +1031,7 @@ emitMemsetCall dst c n align live = do
vols <- getVolatileRegs live
emitForeignCall' PlayRisky
[{-no results-}]
- (CmmPrim MO_Memset)
+ (CmmPrim MO_Memset Nothing)
[ (CmmHinted dst AddrHint)
, (CmmHinted c NoHint)
, (CmmHinted n NoHint)
@@ -956,7 +1063,7 @@ emitPopCntCall res x width live = do
vols <- getVolatileRegs live
emitForeignCall' PlayRisky
[CmmHinted res NoHint]
- (CmmPrim (MO_PopCnt width))
+ (CmmPrim (MO_PopCnt width) Nothing)
[(CmmHinted x NoHint)]
(Just vols)
NoC_SRT -- No SRT b/c we do PlayRisky
diff --git a/compiler/codeGen/CgUtils.hs b/compiler/codeGen/CgUtils.hs
index 2bd35c8796..f971a0500a 100644
--- a/compiler/codeGen/CgUtils.hs
+++ b/compiler/codeGen/CgUtils.hs
@@ -1011,7 +1011,8 @@ fixStgRegStmt stmt
CmmCall target regs args returns ->
let target' = case target of
CmmCallee e conv -> CmmCallee (fixStgRegExpr e) conv
- other -> other
+ CmmPrim op mStmts ->
+ CmmPrim op (fmap (map fixStgRegStmt) mStmts)
args' = map (\(CmmHinted arg hint) ->
(CmmHinted (fixStgRegExpr arg) hint)) args
in CmmCall target' regs args' returns
diff --git a/compiler/codeGen/StgCmmForeign.hs b/compiler/codeGen/StgCmmForeign.hs
index af88ba848a..c41832a0ab 100644
--- a/compiler/codeGen/StgCmmForeign.hs
+++ b/compiler/codeGen/StgCmmForeign.hs
@@ -56,7 +56,9 @@ cgForeignCall results result_hints (CCall (CCallSpec target cconv safety)) stg_a
= do { cmm_args <- getFCallArgs stg_args
; let ((call_args, arg_hints), cmm_target)
= case target of
- StaticTarget lbl mPkgId
+ StaticTarget _ _ False ->
+ panic "cgForeignCall: unexpected FFI value import"
+ StaticTarget lbl mPkgId True
-> let labelSource
= case mPkgId of
Nothing -> ForeignLabelInThisPackage