summaryrefslogtreecommitdiff
path: root/compiler/codeGen
diff options
context:
space:
mode:
authorPeter Trommler <ptrommler@acm.org>2017-04-25 18:37:16 -0400
committerBen Gamari <ben@smart-cactus.org>2017-04-25 18:39:50 -0400
commit89a3241f708502e8fbcfaddbbe634790ad9cd02a (patch)
tree9264c8bb53a229ea2a6a55debd0088bb88354bd2 /compiler/codeGen
parent9373994acaf1b73fe0e7cf8e03594c63cec8d235 (diff)
downloadhaskell-89a3241f708502e8fbcfaddbbe634790ad9cd02a.tar.gz
PPC NCG: Implement callish prim ops
Provide PowerPC optimised implementations of callish prim ops. MO_?_QuotRem The generic implementation of quotient remainder prim ops uses a division and a remainder operation. There is no remainder on PowerPC and so we need to implement remainder "by hand" which results in a duplication of the divide operation when using the generic code. Avoid this duplication by implementing the prim op in the native code generator. MO_U_Mul2 Use PowerPC's instructions for long multiplication. Addition and subtraction Use PowerPC add/subtract with carry/overflow instructions MO_Clz and MO_Ctz Use PowerPC's CNTLZ instruction and implement count trailing zeros using count leading zeros MO_QuotRem2 Implement an algorithm given by Henry Warren in "Hacker's Delight" using PowerPC divide instruction. TODO: Use long division instructions when available (POWER7 and later). Test Plan: validate on AIX and 32-bit Linux Reviewers: simonmar, erikd, hvr, austin, bgamari Reviewed By: erikd, hvr, bgamari Subscribers: trofi, kgardas, thomie Differential Revision: https://phabricator.haskell.org/D2973
Diffstat (limited to 'compiler/codeGen')
-rw-r--r--compiler/codeGen/StgCmmPrim.hs28
1 files changed, 20 insertions, 8 deletions
diff --git a/compiler/codeGen/StgCmmPrim.hs b/compiler/codeGen/StgCmmPrim.hs
index 0edde0659f..235109ffe9 100644
--- a/compiler/codeGen/StgCmmPrim.hs
+++ b/compiler/codeGen/StgCmmPrim.hs
@@ -815,33 +815,41 @@ type GenericOp = [CmmFormal] -> [CmmActual] -> FCode ()
callishPrimOpSupported :: DynFlags -> PrimOp -> Either CallishMachOp GenericOp
callishPrimOpSupported dflags op
= case op of
- IntQuotRemOp | ncg && x86ish -> Left (MO_S_QuotRem (wordWidth dflags))
+ IntQuotRemOp | ncg && (x86ish
+ || ppc) -> Left (MO_S_QuotRem (wordWidth dflags))
| otherwise -> Right (genericIntQuotRemOp dflags)
- WordQuotRemOp | ncg && x86ish -> Left (MO_U_QuotRem (wordWidth dflags))
+ WordQuotRemOp | ncg && (x86ish
+ || ppc) -> Left (MO_U_QuotRem (wordWidth dflags))
| otherwise -> Right (genericWordQuotRemOp dflags)
- WordQuotRem2Op | (ncg && x86ish)
+ WordQuotRem2Op | (ncg && (x86ish
+ || ppc))
|| llvm -> Left (MO_U_QuotRem2 (wordWidth dflags))
| otherwise -> Right (genericWordQuotRem2Op dflags)
- WordAdd2Op | (ncg && x86ish)
+ WordAdd2Op | (ncg && (x86ish
+ || ppc))
|| llvm -> Left (MO_Add2 (wordWidth dflags))
| otherwise -> Right genericWordAdd2Op
- WordSubCOp | (ncg && x86ish)
+ WordSubCOp | (ncg && (x86ish
+ || ppc))
|| llvm -> Left (MO_SubWordC (wordWidth dflags))
| otherwise -> Right genericWordSubCOp
- IntAddCOp | (ncg && x86ish)
+ IntAddCOp | (ncg && (x86ish
+ || ppc))
|| llvm -> Left (MO_AddIntC (wordWidth dflags))
| otherwise -> Right genericIntAddCOp
- IntSubCOp | (ncg && x86ish)
+ IntSubCOp | (ncg && (x86ish
+ || ppc))
|| llvm -> Left (MO_SubIntC (wordWidth dflags))
| otherwise -> Right genericIntSubCOp
- WordMul2Op | ncg && x86ish
+ WordMul2Op | ncg && (x86ish
+ || ppc)
|| llvm -> Left (MO_U_Mul2 (wordWidth dflags))
| otherwise -> Right genericWordMul2Op
FloatFabsOp | (ncg && x86ish)
@@ -863,6 +871,10 @@ callishPrimOpSupported dflags op
ArchX86 -> True
ArchX86_64 -> True
_ -> False
+ ppc = case platformArch (targetPlatform dflags) of
+ ArchPPC -> True
+ ArchPPC_64 _ -> True
+ _ -> False
genericIntQuotRemOp :: DynFlags -> GenericOp
genericIntQuotRemOp dflags [res_q, res_r] [arg_x, arg_y]