-----------------------------------------------------------------------
--- $Id: primops.txt.pp,v 1.15 2001/12/18 15:23:16 sewardj Exp $
+-- $Id: primops.txt.pp,v 1.35 2005/03/07 15:16:41 simonmar Exp $
--
-- Primitive Operations
--
-- strictness attributes, whether it is defined as a macro
-- or as out-of-line code, etc.)
--
--- - ghc/lib/std/PrelGHC.hi-boot, to declare the primop
---
-- - if the primop is inline (i.e. a macro), then:
--- ghc/includes/PrimOps.h
--- ghc/compiler/nativeGen/StixPrim.lhs
--- ghc/compiler/nativeGen/MachCode.lhs (if implementation is machine-dependent)
+-- ghc/compiler/AbsCUtils.lhs (dscCOpStmt)
+-- defines the translation of the primop into simpler
+-- abstract C operations.
--
-- - or, for an out-of-line primop:
-- ghc/includes/PrimOps.h (just add the declaration)
-- ghc/rts/PrimOps.hc (define it here)
+-- ghc/rts/Linker.c (declare the symbol for GHCi)
--
-- - the User's Guide
--
#include "MachDeps.h"
+-- We need platform defines (tests for mingw32 below). However, we only
+-- test the TARGET platform, which doesn't vary between stages, so the
+-- stage1 platform defines are fine:
+#include "../stage1/ghc_boot_platform.h"
+
section "The word size story."
{Haskell98 specifies that signed integers (type {\tt Int})
must contain at least 30 bits. GHC always implements {\tt
with
usage = { mangle SameMutVarOp [mkP, mkP] mkM }
+-- not really the right type, but we don't know about pairs here. The
+-- correct type is
+--
+-- MutVar# s a -> (a -> (a,b)) -> State# s -> (# State# s, b #)
+--
+primop AtomicModifyMutVarOp "atomicModifyMutVar#" GenPrimOp
+ MutVar# s a -> (a -> b) -> State# s -> (# State# s, c #)
+ with
+ usage = { mangle AtomicModifyMutVarOp [mkP, mkM, mkP] mkM }
+ has_side_effects = True
+ out_of_line = True
+
------------------------------------------------------------------------
section "Exceptions"
------------------------------------------------------------------------
usage = { mangle RaiseOp [mkM] mkM }
out_of_line = True
+-- raiseIO# needs to be a primop, because exceptions in the IO monad
+-- must be *precise* - we don't want the strictness analyser turning
+-- one kind of bottom into another, as it is allowed to do in pure code.
+
+primop RaiseIOOp "raiseIO#" GenPrimOp
+ a -> State# RealWorld -> (# State# RealWorld, b #)
+ with
+ out_of_line = True
+
primop BlockAsyncExceptionsOp "blockAsyncExceptions#" GenPrimOp
(State# RealWorld -> (# State# RealWorld, a #))
-> (State# RealWorld -> (# State# RealWorld, a #))
out_of_line = True
------------------------------------------------------------------------
+section "STM-accessible Mutable Variables"
+------------------------------------------------------------------------
+
+primop AtomicallyOp "atomically#" GenPrimOp
+ (State# RealWorld -> (# State# RealWorld, a #) )
+ -> State# RealWorld -> (# State# RealWorld, a #)
+ with
+ out_of_line = True
+ has_side_effects = True
+
+primop RetryOp "retry#" GenPrimOp
+ State# RealWorld -> (# State# RealWorld, a #)
+ with
+ out_of_line = True
+ has_side_effects = True
+
+primop CatchRetryOp "catchRetry#" GenPrimOp
+ (State# RealWorld -> (# State# RealWorld, a #) )
+ -> (State# RealWorld -> (# State# RealWorld, a #) )
+ -> (State# RealWorld -> (# State# RealWorld, a #) )
+ with
+ out_of_line = True
+ has_side_effects = True
+
+primop CatchSTMOp "catchSTM#" GenPrimOp
+ (State# RealWorld -> (# State# RealWorld, a #) )
+ -> (b -> State# RealWorld -> (# State# RealWorld, a #) )
+ -> (State# RealWorld -> (# State# RealWorld, a #) )
+ with
+ out_of_line = True
+ has_side_effects = True
+
+primop NewTVarOp "newTVar#" GenPrimOp
+ a
+ -> State# s -> (# State# s, TVar# s a #)
+ {Create a new Tar\# holding a specified initial value.}
+ with
+ out_of_line = True
+
+primop ReadTVarOp "readTVar#" GenPrimOp
+ TVar# s a
+ -> State# s -> (# State# s, a #)
+ {Read contents of TVar\#. Result is not yet evaluated.}
+ with
+ out_of_line = True
+
+primop WriteTVarOp "writeTVar#" GenPrimOp
+ TVar# s a
+ -> a
+ -> State# s -> State# s
+ {Write contents of TVar\#.}
+ with
+ out_of_line = True
+ has_side_effects = True
+
+primop SameTVarOp "sameTVar#" GenPrimOp
+ TVar# s a -> TVar# s a -> Bool
+
+
+------------------------------------------------------------------------
section "Synchronized Mutable Variables"
{Operations on MVar\#s, which are shared mutable variables
({\it not} the same as MutVar\#s!). (Note: in a non-concurrent implementation,
has_side_effects = True
out_of_line = True
+#ifdef mingw32_TARGET_OS
+primop AsyncReadOp "asyncRead#" GenPrimOp
+ Int# -> Int# -> Int# -> Addr# -> State# RealWorld-> (# State# RealWorld, Int#, Int# #)
+ {Asynchronously read bytes from specified file descriptor.}
+ with
+ needs_wrapper = True
+ has_side_effects = True
+ out_of_line = True
+
+primop AsyncWriteOp "asyncWrite#" GenPrimOp
+ Int# -> Int# -> Int# -> Addr# -> State# RealWorld-> (# State# RealWorld, Int#, Int# #)
+ {Asynchronously write bytes from specified file descriptor.}
+ with
+ needs_wrapper = True
+ has_side_effects = True
+ out_of_line = True
+
+primop AsyncDoProcOp "asyncDoProc#" GenPrimOp
+ Addr# -> Addr# -> State# RealWorld-> (# State# RealWorld, Int#, Int# #)
+ {Asynchronously perform procedure (first arg), passing it 2nd arg.}
+ with
+ needs_wrapper = True
+ has_side_effects = True
+ out_of_line = True
+
+#endif
+
------------------------------------------------------------------------
section "Concurrency primitives"
{(In a non-concurrent implementation, ThreadId\# can be as singleton
with
out_of_line = True
+primop LabelThreadOp "labelThread#" GenPrimOp
+ ThreadId# -> Addr# -> State# RealWorld -> State# RealWorld
+ with
+ has_side_effects = True
+ out_of_line = True
+
+primop IsCurrentThreadBoundOp "isCurrentThreadBound#" GenPrimOp
+ State# RealWorld -> (# State# RealWorld, Int# #)
+ with
+ out_of_line = True
+
------------------------------------------------------------------------
section "Weak pointers"
------------------------------------------------------------------------
primop FinalizeWeakOp "finalizeWeak#" GenPrimOp
Weak# a -> State# RealWorld -> (# State# RealWorld, Int#,
- (State# RealWorld -> (# State# RealWorld, Unit #)) #)
+ (State# RealWorld -> (# State# RealWorld, () #)) #)
with
usage = { mangle FinalizeWeakOp [mkM, mkP]
(mkR . (inUB FinalizeWeakOp
usage = { mangle StableNameToIntOp [mkP] mkR }
------------------------------------------------------------------------
-section "Parallelism"
+section "Unsafe pointer equality"
+-- (#1 Bad Guy: Alistair Reid :)
------------------------------------------------------------------------
-primop SeqOp "seq#" GenPrimOp
- a -> Int#
+primop ReallyUnsafePtrEqualityOp "reallyUnsafePtrEquality#" GenPrimOp
+ a -> a -> Int#
with
- usage = { mangle SeqOp [mkO] mkR }
- strictness = { \ arity -> mkStrictSig (mkTopDmdType [evalDmd] TopRes) }
- -- Seq is strict in its argument; see notes in ConFold.lhs
- has_side_effects = True
+ usage = { mangle ReallyUnsafePtrEqualityOp [mkZ, mkZ] mkR }
+
+------------------------------------------------------------------------
+section "Parallelism"
+------------------------------------------------------------------------
primop ParOp "par#" GenPrimOp
a -> Int#
primop DataToTagOp "dataToTag#" GenPrimOp
a -> Int#
+ with
+ strictness = { \ arity -> mkStrictSig (mkTopDmdType [seqDmd] TopRes) }
+ -- dataToTag# must have an evaluated argument
primop TagToEnumOp "tagToEnum#" GenPrimOp
Int# -> a
{Convert an Addr\# to a followable type.}
primop MkApUpd0_Op "mkApUpd0#" GenPrimOp
- a -> (# a #)
+ BCO# -> (# a #)
with
out_of_line = True
primop NewBCOOp "newBCO#" GenPrimOp
- ByteArr# -> ByteArr# -> Array# a -> ByteArr# -> State# s -> (# State# s, BCO# #)
+ ByteArr# -> ByteArr# -> Array# a -> ByteArr# -> Int# -> ByteArr# -> State# s -> (# State# s, BCO# #)
with
has_side_effects = True
out_of_line = True
------------------------------------------------------------------------
section "Coercion"
- {{\tt unsafeCoerce# :: a -> b} is not a primop, but is defined in MkId.lhs.}
+ {{\tt unsafeCoerce\# :: a -> b} is not a primop, but is defined in MkId.lhs.}
------------------------------------------------------------------------