summaryrefslogtreecommitdiff
path: root/compiler/llvmGen/Llvm
diff options
context:
space:
mode:
authorAdam Gundry <adam@well-typed.com>2015-10-16 13:58:52 +0100
committerAdam Gundry <adam@well-typed.com>2015-10-16 13:58:52 +0100
commit5a1b4f814f74ec1c48152d97523744518e212777 (patch)
tree7c2207ecacbd37f12c78dbcf9d4334827164e0fb /compiler/llvmGen/Llvm
parent6757950cdd8bb0af0355539987ee78401a6a8f6b (diff)
parent808bbdf08058785ae5bc59b5b4f2b04951d4cbbf (diff)
downloadhaskell-wip/orf-reboot.tar.gz
Merge remote-tracking branch 'origin/master' into wip/orf-rebootwip/orf-reboot
Conflicts: compiler/rename/RnNames.hs compiler/typecheck/TcRnMonad.hs utils/haddock
Diffstat (limited to 'compiler/llvmGen/Llvm')
-rw-r--r--compiler/llvmGen/Llvm/AbsSyn.hs42
-rw-r--r--compiler/llvmGen/Llvm/PpLlvm.hs46
-rw-r--r--compiler/llvmGen/Llvm/Types.hs5
3 files changed, 83 insertions, 10 deletions
diff --git a/compiler/llvmGen/Llvm/AbsSyn.hs b/compiler/llvmGen/Llvm/AbsSyn.hs
index 8a53df00fe..774e555170 100644
--- a/compiler/llvmGen/Llvm/AbsSyn.hs
+++ b/compiler/llvmGen/Llvm/AbsSyn.hs
@@ -87,6 +87,22 @@ data LlvmSyncOrdering
| SyncSeqCst
deriving (Show, Eq)
+-- | LLVM atomic operations. Please see the @atomicrmw@ instruction in
+-- the LLVM documentation for a complete description.
+data LlvmAtomicOp
+ = LAO_Xchg
+ | LAO_Add
+ | LAO_Sub
+ | LAO_And
+ | LAO_Nand
+ | LAO_Or
+ | LAO_Xor
+ | LAO_Max
+ | LAO_Min
+ | LAO_Umax
+ | LAO_Umin
+ deriving (Show, Eq)
+
-- | Llvm Statements
data LlvmStatement
{- |
@@ -250,8 +266,8 @@ data LlvmExpression
| GetElemPtr Bool LlvmVar [LlvmVar]
{- |
- Cast the variable from to the to type. This is an abstraction of three
- cast operators in Llvm, inttoptr, prttoint and bitcast.
+ Cast the variable from to the to type. This is an abstraction of three
+ cast operators in Llvm, inttoptr, prttoint and bitcast.
* cast: Cast type
* from: Variable to cast
* to: type to cast to
@@ -259,6 +275,28 @@ data LlvmExpression
| Cast LlvmCastOp LlvmVar LlvmType
{- |
+ Atomic read-modify-write operation
+ * op: Atomic operation
+ * addr: Address to modify
+ * operand: Operand to operation
+ * ordering: Ordering requirement
+ -}
+ | AtomicRMW LlvmAtomicOp LlvmVar LlvmVar LlvmSyncOrdering
+
+ {- |
+ Compare-and-exchange operation
+ * addr: Address to modify
+ * old: Expected value
+ * new: New value
+ * suc_ord: Ordering required in success case
+ * fail_ord: Ordering required in failure case, can be no stronger than
+ suc_ord
+
+ Result is an @i1@, true if store was successful.
+ -}
+ | CmpXChg LlvmVar LlvmVar LlvmVar LlvmSyncOrdering LlvmSyncOrdering
+
+ {- |
Call a function. The result is the value of the expression.
* tailJumps: CallType to signal if the function should be tail called
* fnptrval: An LLVM value containing a pointer to a function to be
diff --git a/compiler/llvmGen/Llvm/PpLlvm.hs b/compiler/llvmGen/Llvm/PpLlvm.hs
index db9ef1fccf..cdaf962c4a 100644
--- a/compiler/llvmGen/Llvm/PpLlvm.hs
+++ b/compiler/llvmGen/Llvm/PpLlvm.hs
@@ -117,6 +117,7 @@ ppLlvmMeta (MetaNamed n m)
-- | Print out an LLVM metadata value.
ppLlvmMetaExpr :: MetaExpr -> SDoc
+ppLlvmMetaExpr (MetaVar (LMLitVar (LMNullLit _))) = text "null"
ppLlvmMetaExpr (MetaStr s ) = text "!" <> doubleQuotes (ftext s)
ppLlvmMetaExpr (MetaNode n ) = text "!" <> int n
ppLlvmMetaExpr (MetaVar v ) = ppr v
@@ -245,6 +246,8 @@ ppLlvmExpression expr
Load ptr -> ppLoad ptr
ALoad ord st ptr -> ppALoad ord st ptr
Malloc tp amount -> ppMalloc tp amount
+ AtomicRMW aop tgt src ordering -> ppAtomicRMW aop tgt src ordering
+ CmpXChg addr old new s_ord f_ord -> ppCmpXChg addr old new s_ord f_ord
Phi tp precessors -> ppPhi tp precessors
Asm asm c ty v se sk -> ppAsm asm c ty v se sk
MExpr meta expr -> ppMetaExpr meta expr
@@ -278,7 +281,7 @@ ppCall ct fptr args attrs = case fptr of
(case argTy of
VarArgs -> text ", ..."
FixedArgs -> empty)
- fnty = space <> lparen <> ppArgTy <> rparen <> char '*'
+ fnty = space <> lparen <> ppArgTy <> rparen
attrDoc = ppSpaceJoin attrs
in tc <> text "call" <+> ppr cc <+> ppr ret
<> fnty <+> ppName fptr <> lparen <+> ppValues
@@ -327,6 +330,30 @@ ppSyncOrdering SyncRelease = text "release"
ppSyncOrdering SyncAcqRel = text "acq_rel"
ppSyncOrdering SyncSeqCst = text "seq_cst"
+ppAtomicOp :: LlvmAtomicOp -> SDoc
+ppAtomicOp LAO_Xchg = text "xchg"
+ppAtomicOp LAO_Add = text "add"
+ppAtomicOp LAO_Sub = text "sub"
+ppAtomicOp LAO_And = text "and"
+ppAtomicOp LAO_Nand = text "nand"
+ppAtomicOp LAO_Or = text "or"
+ppAtomicOp LAO_Xor = text "xor"
+ppAtomicOp LAO_Max = text "max"
+ppAtomicOp LAO_Min = text "min"
+ppAtomicOp LAO_Umax = text "umax"
+ppAtomicOp LAO_Umin = text "umin"
+
+ppAtomicRMW :: LlvmAtomicOp -> LlvmVar -> LlvmVar -> LlvmSyncOrdering -> SDoc
+ppAtomicRMW aop tgt src ordering =
+ text "atomicrmw" <+> ppAtomicOp aop <+> ppr tgt <> comma
+ <+> ppr src <+> ppSyncOrdering ordering
+
+ppCmpXChg :: LlvmVar -> LlvmVar -> LlvmVar
+ -> LlvmSyncOrdering -> LlvmSyncOrdering -> SDoc
+ppCmpXChg addr old new s_ord f_ord =
+ text "cmpxchg" <+> ppr addr <> comma <+> ppr old <> comma <+> ppr new
+ <+> ppSyncOrdering s_ord <+> ppSyncOrdering f_ord
+
-- XXX: On x86, vector types need to be 16-byte aligned for aligned access, but
-- we have no way of guaranteeing that this is true with GHC (we would need to
-- modify the layout of the stack and closures, change the storage manager,
@@ -336,8 +363,9 @@ ppSyncOrdering SyncSeqCst = text "seq_cst"
-- of specifying alignment.
ppLoad :: LlvmVar -> SDoc
-ppLoad var = text "load" <+> ppr var <> align
+ppLoad var = text "load" <+> ppr derefType <> comma <+> ppr var <> align
where
+ derefType = pLower $ getVarType var
align | isVector . pLower . getVarType $ var = text ", align 1"
| otherwise = empty
@@ -347,7 +375,9 @@ ppALoad ord st var = sdocWithDynFlags $ \dflags ->
align = text ", align" <+> ppr alignment
sThreaded | st = text " singlethread"
| otherwise = empty
- in text "load atomic" <+> ppr var <> sThreaded <+> ppSyncOrdering ord <> align
+ derefType = pLower $ getVarType var
+ in text "load atomic" <+> ppr derefType <> comma <+> ppr var <> sThreaded
+ <+> ppSyncOrdering ord <> align
ppStore :: LlvmVar -> LlvmVar -> SDoc
ppStore val dst
@@ -360,10 +390,10 @@ ppStore val dst
ppCast :: LlvmCastOp -> LlvmVar -> LlvmType -> SDoc
-ppCast op from to
- = ppr op
+ppCast op from to
+ = ppr op
<+> ppr (getVarType from) <+> ppName from
- <+> text "to"
+ <+> text "to"
<+> ppr to
@@ -383,7 +413,9 @@ ppGetElementPtr :: Bool -> LlvmVar -> [LlvmVar] -> SDoc
ppGetElementPtr inb ptr idx =
let indexes = comma <+> ppCommaJoin idx
inbound = if inb then text "inbounds" else empty
- in text "getelementptr" <+> inbound <+> ppr ptr <> indexes
+ derefType = pLower $ getVarType ptr
+ in text "getelementptr" <+> inbound <+> ppr derefType <> comma <+> ppr ptr
+ <> indexes
ppReturn :: Maybe LlvmVar -> SDoc
diff --git a/compiler/llvmGen/Llvm/Types.hs b/compiler/llvmGen/Llvm/Types.hs
index b3b173096b..d533b4a993 100644
--- a/compiler/llvmGen/Llvm/Types.hs
+++ b/compiler/llvmGen/Llvm/Types.hs
@@ -262,7 +262,7 @@ pLift LMVoid = error "Voids are unliftable"
pLift LMMetadata = error "Metadatas are unliftable"
pLift x = LMPointer x
--- | Lower a variable of 'LMPointer' type.
+-- | Lift a variable to 'LMPointer' type.
pVarLift :: LlvmVar -> LlvmVar
pVarLift (LMGlobalVar s t l x a c) = LMGlobalVar s (pLift t) l x a c
pVarLift (LMLocalVar s t ) = LMLocalVar s (pLift t)
@@ -568,6 +568,8 @@ data LlvmCallConvention
-- does not support varargs and requires the prototype of all callees to
-- exactly match the prototype of the function definition.
| CC_Coldcc
+ -- | The GHC-specific 'registerised' calling convention.
+ | CC_Ghc
-- | Any calling convention may be specified by number, allowing
-- target-specific calling conventions to be used. Target specific calling
-- conventions start at 64.
@@ -581,6 +583,7 @@ instance Outputable LlvmCallConvention where
ppr CC_Ccc = text "ccc"
ppr CC_Fastcc = text "fastcc"
ppr CC_Coldcc = text "coldcc"
+ ppr CC_Ghc = text "ghccc"
ppr (CC_Ncc i) = text "cc " <> ppr i
ppr CC_X86_Stdcc = text "x86_stdcallcc"