X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;ds=sidebyside;f=ghc%2Fcompiler%2Fprelude%2Fprimops.txt.pp;h=37c6c6f7a8d746643c6903e5fcdfa0a9cae512d6;hb=d89872a45b581ba3f086c636126a44d97ef45be6;hp=148473240fb00405d660afb9c8f23ab02d3aac17;hpb=630659b5d2fdfebb83859c762a89871fc5536f94;p=ghc-hetmet.git diff --git a/ghc/compiler/prelude/primops.txt.pp b/ghc/compiler/prelude/primops.txt.pp index 1484732..37c6c6f 100644 --- a/ghc/compiler/prelude/primops.txt.pp +++ b/ghc/compiler/prelude/primops.txt.pp @@ -1,5 +1,5 @@ ----------------------------------------------------------------------- --- $Id: primops.txt.pp,v 1.6 2001/09/11 09:02:43 simonpj Exp $ +-- $Id: primops.txt.pp,v 1.27 2003/06/19 10:42:26 simonmar Exp $ -- -- Primitive Operations -- @@ -13,39 +13,36 @@ -- -- To add a new primop, you currently need to update the following files: -- --- - this file (ghc/compiler/prelude/primops.txt), which includes +-- - this file (ghc/compiler/prelude/primops.txt.pp), which includes -- the type of the primop, and various other properties (its -- 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 -- --- This file is divided into named sections, each containing or more primop entries. --- Section headers have the format: +-- This file is divided into named sections, each containing or more +-- primop entries. Section headers have the format: -- -- section "section-name" {description} -- --- This information is used solely when producing documentation; it is otherwise ignored. --- The description is optional. +-- This information is used solely when producing documentation; it is +-- otherwise ignored. The description is optional. -- -- The format of each primop entry is as follows: -- -- primop internal-name "name-in-program-text" type category {description} attributes --- The description is optional. - -- The default attribute values which apply if you don't specify -- other ones. Attribute values can be True, False, or arbitrary -- text between curly brackets. This is a kludge to enable @@ -59,60 +56,75 @@ defaults commutable = False needs_wrapper = False can_fail = False - strictness = { \ arity -> StrictnessInfo (replicate arity wwPrim) False } + strictness = { \ arity -> mkStrictSig (mkTopDmdType (replicate arity lazyDmd) TopRes) } usage = { nomangle other } --- Currently, documentation is produced using latex, so contents of description fields --- should be legal latex. Descriptions can contain matched pairs of embedded curly brackets. +-- Currently, documentation is produced using latex, so contents of +-- description fields should be legal latex. Descriptions can contain +-- matched pairs of embedded curly brackets. #include "MachDeps.h" section "The word size story." - {Haskell98 specifies that signed integers (type {\tt Int}) must contain at least 30 - bits. GHC always implements {\tt Int} using the primitive type {\tt Int\#}, whose - size equals the {\tt MachDeps.h} constant {\tt WORD\_SIZE\_IN\_BITS}. This - is normally set based on the {\tt config.h} parameter {\tt SIZEOF\_LONG}, - i.e., 32 bits on 32-bit machines, 64 bits on 64-bit machines. However, it can - also be explicitly set to a smaller number, e.g., 31 bits, to allow the possibility - of using tag bits. Currently GHC itself has only 32-bit and 64-bit variants, - but 30 or 31-bit code can be exported as an external core file for use in - other back ends. - - GHC also implements a primitive unsigned integer type {\tt Word\#} which always - has the same number of bits as {\tt Int\#}. + {Haskell98 specifies that signed integers (type {\tt Int}) + must contain at least 30 bits. GHC always implements {\tt + Int} using the primitive type {\tt Int\#}, whose size equals + the {\tt MachDeps.h} constant {\tt WORD\_SIZE\_IN\_BITS}. + This is normally set based on the {\tt config.h} parameter + {\tt SIZEOF\_HSWORD}, i.e., 32 bits on 32-bit machines, 64 + bits on 64-bit machines. However, it can also be explicitly + set to a smaller number, e.g., 31 bits, to allow the + possibility of using tag bits. Currently GHC itself has only + 32-bit and 64-bit variants, but 30 or 31-bit code can be + exported as an external core file for use in other back ends. + + GHC also implements a primitive unsigned integer type {\tt + Word\#} which always has the same number of bits as {\tt + Int\#}. - In addition, GHC supports families of explicit-sized integers and words at - 8, 16, 32, and 64 bits, with the usual arithmetic operations, comparisons, - and a range of conversions. The 8-bit and 16-bit sizes are always represented as - {\tt Int\#} and {\tt Word\#}, and the operations implemented in terms of the - the primops on these types, with suitable range restrictions on the results - (using the {\tt narrow$n$Int\#} and {\tt narrow$n$Word\#} families of primops. - The 32-bit sizes are represented using {\tt Int\#} and {\tt Word\#} when - {\tt WORD\_SIZE\_IN\_BITS} $\geq$ 32; - otherwise, these are represented using distinct primitive types {\tt Int32\#} - and {\tt Word32\#}. These (when needed) have a complete set of corresponding - operations; however, nearly all of these are implemented as external C functions - rather than as primops. Exactly the same story applies to the 64-bit sizes. - All of these details are hidden under the {\tt PrelInt} and {\tt PrelWord} modules, - which use {\tt \#if}-defs to invoke the appropriate types and operators. - - Word size also matters for the families of primops - for indexing/reading/writing fixed-size quantities at offsets from - an array base, address, or foreign pointer. Here, a slightly different approach is taken. - The names of these primops are fixed, but their - {\it types} vary according to the value of {\tt WORD\_SIZE\_IN\_BITS}. For example, if - word size is at least 32 bits then an operator like \texttt{indexInt32Array\#} - has type {\tt ByteArr\# -> Int\# -> Int\#}; otherwise it has type - {\tt ByteArr\# -> Int\# -> Int32\#}. This approach confines the necessary {\tt \#if}-defs to this file; - no conditional compilation is needed in the files that expose these primops, namely \texttt{lib/std/PrelStorable.lhs}, - \texttt{hslibs/lang/ArrayBase.hs}, and (in deprecated fashion) in \texttt{hslibs/lang/ForeignObj.lhs} - and \texttt{hslibs/lang/Addr.lhs}. - - Finally, there are strongly deprecated primops for coercing between {\tt Addr\#}, the primitive - type of machine addresses, and {\tt Int\#}. These are pretty bogus anyway, but will work on - existing 32-bit and 64-bit GHC targets; they are completely bogus when tag bits are used in - {\tt Int\#}, so are not available in this case. -} + In addition, GHC supports families of explicit-sized integers + and words at 8, 16, 32, and 64 bits, with the usual + arithmetic operations, comparisons, and a range of + conversions. The 8-bit and 16-bit sizes are always + represented as {\tt Int\#} and {\tt Word\#}, and the + operations implemented in terms of the the primops on these + types, with suitable range restrictions on the results (using + the {\tt narrow$n$Int\#} and {\tt narrow$n$Word\#} families + of primops. The 32-bit sizes are represented using {\tt + Int\#} and {\tt Word\#} when {\tt WORD\_SIZE\_IN\_BITS} + $\geq$ 32; otherwise, these are represented using distinct + primitive types {\tt Int32\#} and {\tt Word32\#}. These (when + needed) have a complete set of corresponding operations; + however, nearly all of these are implemented as external C + functions rather than as primops. Exactly the same story + applies to the 64-bit sizes. All of these details are hidden + under the {\tt PrelInt} and {\tt PrelWord} modules, which use + {\tt \#if}-defs to invoke the appropriate types and + operators. + + Word size also matters for the families of primops for + indexing/reading/writing fixed-size quantities at offsets + from an array base, address, or foreign pointer. Here, a + slightly different approach is taken. The names of these + primops are fixed, but their {\it types} vary according to + the value of {\tt WORD\_SIZE\_IN\_BITS}. For example, if word + size is at least 32 bits then an operator like + \texttt{indexInt32Array\#} has type {\tt ByteArr\# -> Int\# + -> Int\#}; otherwise it has type {\tt ByteArr\# -> Int\# -> + Int32\#}. This approach confines the necessary {\tt + \#if}-defs to this file; no conditional compilation is needed + in the files that expose these primops, namely + \texttt{lib/std/PrelStorable.lhs}, + \texttt{hslibs/lang/ArrayBase.hs}, and (in deprecated + fashion) in \texttt{hslibs/lang/ForeignObj.lhs} and + \texttt{hslibs/lang/Addr.lhs}. + + Finally, there are strongly deprecated primops for coercing + between {\tt Addr\#}, the primitive type of machine + addresses, and {\tt Int\#}. These are pretty bogus anyway, + but will work on existing 32-bit and 64-bit GHC targets; they + are completely bogus when tag bits are used in {\tt Int\#}, + so are not available in this case. } -- Define synonyms for indexing ops. @@ -167,6 +179,31 @@ primop IntSubOp "-#" Dyadic Int# -> Int# -> Int# primop IntMulOp "*#" Dyadic Int# -> Int# -> Int# + {Low word of signed integer multiply.} + with commutable = True + +primop IntMulMayOfloOp "mulIntMayOflo#" + Dyadic Int# -> Int# -> Int# + {Return non-zero if there is any possibility that the upper word of a + signed integer multiply might contain useful information. Return + zero only if you are completely sure that no overflow can occur. + On a 32-bit platform, the recommmended implementation is to do a + 32 x 32 -> 64 signed multiply, and subtract result[63:32] from + (result[31] >>signed 31). If this is zero, meaning that the + upper word is merely a sign extension of the lower one, no + overflow can occur. + + On a 64-bit platform it is not always possible to + acquire the top 64 bits of the result. Therefore, a recommended + implementation is to take the absolute value of both operands, and + return 0 iff bits[63:31] of them are zero, since that means that their + magnitudes fit within 31 bits, so the magnitude of the product must fit + into 62 bits. + + If in doubt, return non-zero, but do make an effort to create the + correct answer for small args, since otherwise the performance of + (*) :: Integer -> Integer -> Integer will be poor. + } with commutable = True primop IntQuotOp "quotInt#" Dyadic @@ -180,13 +217,16 @@ primop IntRemOp "remInt#" Dyadic with can_fail = True primop IntGcdOp "gcdInt#" Dyadic Int# -> Int# -> Int# + with out_of_line = True + primop IntNegOp "negateInt#" Monadic Int# -> Int# primop IntAddCOp "addIntC#" GenPrimOp Int# -> Int# -> (# Int#, Int# #) - {Add with carry. First member of result is (wrapped) sum; second member is 0 iff no overflow occured.} + {Add with carry. First member of result is (wrapped) sum; + second member is 0 iff no overflow occured.} primop IntSubCOp "subIntC#" GenPrimOp Int# -> Int# -> (# Int#, Int# #) - {Subtract with carry. First member of result is (wrapped) difference; second member is 0 iff no overflow occured.} -primop IntMulCOp "mulIntC#" GenPrimOp Int# -> Int# -> (# Int#, Int# #) - {Multiply with carry. First member of result is (wrapped) product; second member is 0 iff no overflow occured.} + {Subtract with carry. First member of result is (wrapped) difference; + second member is 0 iff no overflow occured.} + primop IntGtOp ">#" Compare Int# -> Int# -> Bool primop IntGeOp ">=#" Compare Int# -> Int# -> Bool @@ -211,12 +251,15 @@ primop Int2IntegerOp "int2Integer#" GenPrimOp Int# -> (# Int#, ByteArr# #) with out_of_line = True -primop ISllOp "iShiftL#" GenPrimOp Int# -> Int# -> Int# - {Shift left. Return 0 if shifted by more than size of an Int\#.} -primop ISraOp "iShiftRA#" GenPrimOp Int# -> Int# -> Int# - {Shift right arithemetic. Return 0 if shifted by more than size of an Int\#.} -primop ISrlOp "iShiftRL#" GenPrimOp Int# -> Int# -> Int# - {Shift right logical. Return 0 if shifted by more than size of an Int\#.} +primop ISllOp "uncheckedIShiftL#" GenPrimOp Int# -> Int# -> Int# + {Shift left. Result undefined if shift amount is not + in the range 0 to word size - 1 inclusive.} +primop ISraOp "uncheckedIShiftRA#" GenPrimOp Int# -> Int# -> Int# + {Shift right arithmetic. Result undefined if shift amount is not + in the range 0 to word size - 1 inclusive.} +primop ISrlOp "uncheckedIShiftRL#" GenPrimOp Int# -> Int# -> Int# + {Shift right logical. Result undefined if shift amount is not + in the range 0 to word size - 1 inclusive.} ------------------------------------------------------------------------ section "Word#" @@ -248,10 +291,12 @@ primop XorOp "xor#" Dyadic Word# -> Word# -> Word# primop NotOp "not#" Monadic Word# -> Word# -primop SllOp "shiftL#" GenPrimOp Word# -> Int# -> Word# - {Shift left logical. Return 0 if shifted by more than number of bits in a Word\#.} -primop SrlOp "shiftRL#" GenPrimOp Word# -> Int# -> Word# - {Shift right logical. Return 0 if shifted by more than number of bits in a Word\#.} +primop SllOp "uncheckedShiftL#" GenPrimOp Word# -> Int# -> Word# + {Shift left logical. Result undefined if shift amount is not + in the range 0 to word size - 1 inclusive.} +primop SrlOp "uncheckedShiftRL#" GenPrimOp Word# -> Int# -> Word# + {Shift right logical. Result undefined if shift amount is not + in the range 0 to word size - 1 inclusive.} primop Word2IntOp "word2Int#" GenPrimOp Word# -> Int# @@ -338,9 +383,15 @@ section "Integer#" implemented via the GMP package. An integer is represented as a pair consisting of an Int\# representing the number of 'limbs' in use and the sign, and a ByteArr\# containing the 'limbs' themselves. Such pairs -are returned as unboxed pairs, but must be passed as separate components.} +are returned as unboxed pairs, but must be passed as separate +components. + +For .NET these operations are implemented by foreign imports, so the +primops are omitted.} ------------------------------------------------------------------------ +#ifndef ILX + primop IntegerAddOp "plusInteger#" GenPrimOp Int# -> ByteArr# -> Int# -> ByteArr# -> (# Int#, ByteArr# #) with commutable = True @@ -364,7 +415,7 @@ primop IntegerGcdOp "gcdInteger#" GenPrimOp primop IntegerIntGcdOp "gcdIntegerInt#" GenPrimOp Int# -> ByteArr# -> Int# -> Int# {Greatest common divisor, where second argument is an ordinary Int\#.} - -- with commutable = True (surely not? APT 8/01) + with out_of_line = True primop IntegerDivExactOp "divExactInteger#" GenPrimOp Int# -> ByteArr# -> Int# -> ByteArr# -> (# Int#, ByteArr# #) @@ -385,12 +436,14 @@ primop IntegerCmpOp "cmpInteger#" GenPrimOp Int# -> ByteArr# -> Int# -> ByteArr# -> Int# {Returns -1,0,1 according as first argument is less than, equal to, or greater than second argument.} with needs_wrapper = True + out_of_line = True primop IntegerCmpIntOp "cmpIntegerInt#" GenPrimOp Int# -> ByteArr# -> Int# -> Int# {Returns -1,0,1 according as first argument is less than, equal to, or greater than second argument, which is an ordinary Int\#.} with needs_wrapper = True + out_of_line = True primop IntegerQuotRemOp "quotRemInteger#" GenPrimOp Int# -> ByteArr# -> Int# -> ByteArr# -> (# Int#, ByteArr#, Int#, ByteArr# #) @@ -408,10 +461,12 @@ primop IntegerDivModOp "divModInteger#" GenPrimOp primop Integer2IntOp "integer2Int#" GenPrimOp Int# -> ByteArr# -> Int# with needs_wrapper = True + out_of_line = True primop Integer2WordOp "integer2Word#" GenPrimOp Int# -> ByteArr# -> Word# with needs_wrapper = True + out_of_line = True #if WORD_SIZE_IN_BITS < 32 primop IntegerToInt32Op "integerToInt32#" GenPrimOp @@ -421,14 +476,6 @@ primop IntegerToWord32Op "integerToWord32#" GenPrimOp Int# -> ByteArr# -> Word32# #endif -#if WORD_SIZE_IN_BITS < 64 -primop IntegerToInt64Op "integerToInt64#" GenPrimOp - Int# -> ByteArr# -> Int64# - -primop IntegerToWord64Op "integerToWord64#" GenPrimOp - Int# -> ByteArr# -> Word64# -#endif - primop IntegerAndOp "andInteger#" GenPrimOp Int# -> ByteArr# -> Int# -> ByteArr# -> (# Int#, ByteArr# #) with out_of_line = True @@ -445,6 +492,7 @@ primop IntegerComplementOp "complementInteger#" GenPrimOp Int# -> ByteArr# -> (# Int#, ByteArr# #) with out_of_line = True +#endif /* ndef ILX */ ------------------------------------------------------------------------ section "Double#" @@ -663,7 +711,6 @@ primop NewArrayOp "newArray#" GenPrimOp in the specified state thread, with each element containing the specified initial value.} with - strictness = { \ arity -> StrictnessInfo [wwPrim, wwLazy, wwPrim] False } usage = { mangle NewArrayOp [mkP, mkM, mkP] mkM } out_of_line = True @@ -683,7 +730,6 @@ primop WriteArrayOp "writeArray#" GenPrimOp {Write to specified index of mutable array.} with usage = { mangle WriteArrayOp [mkM, mkP, mkM, mkP] mkR } - strictness = { \ arity -> StrictnessInfo [wwPrim, wwPrim, wwLazy, wwPrim] False } has_side_effects = True primop IndexArrayOp "indexArray#" GenPrimOp @@ -921,12 +967,12 @@ primop WriteByteArrayOp_Word64 "writeWord64Array#" GenPrimOp ------------------------------------------------------------------------ section "Addr#" {Addr\# is an arbitrary machine address assumed to point outside - the garbage-collected heap.} + the garbage-collected heap. + + NB: {\tt nullAddr\#::Addr\#} is not a primop, but is defined in MkId.lhs. + It is the null address.} ------------------------------------------------------------------------ -primop AddrNullOp "nullAddr#" GenPrimOp Int# -> Addr# - {Returns null address. Argument is ignored (nullary primops - don't quite work!)} primop AddrAddOp "plusAddr#" GenPrimOp Addr# -> Int# -> Addr# primop AddrSubOp "minusAddr#" GenPrimOp Addr# -> Addr# -> Int# {Result is meaningless if two Addr\#s are so far apart that their @@ -1141,7 +1187,6 @@ primop TouchOp "touch#" GenPrimOp o -> State# RealWorld -> State# RealWorld with has_side_effects = True - strictness = { \ arity -> StrictnessInfo [wwLazy, wwPrim] False } primop EqForeignObj "eqForeignObj#" GenPrimOp ForeignObj# -> ForeignObj# -> Bool @@ -1209,7 +1254,6 @@ primop NewMutVarOp "newMutVar#" GenPrimOp {Create MutVar\# with specified initial value in specified state thread.} with usage = { mangle NewMutVarOp [mkM, mkP] mkM } - strictness = { \ arity -> StrictnessInfo [wwLazy, wwPrim] False } out_of_line = True primop ReadMutVarOp "readMutVar#" GenPrimOp @@ -1222,7 +1266,6 @@ primop WriteMutVarOp "writeMutVar#" GenPrimOp MutVar# s a -> a -> State# s -> State# s {Write contents of MutVar\#.} with - strictness = { \ arity -> StrictnessInfo [wwPrim, wwLazy, wwPrim] False } usage = { mangle WriteMutVarOp [mkM, mkM, mkP] mkR } has_side_effects = True @@ -1231,6 +1274,18 @@ primop SameMutVarOp "sameMutVar#" GenPrimOp 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" ------------------------------------------------------------------------ @@ -1241,7 +1296,6 @@ primop CatchOp "catch#" GenPrimOp -> State# RealWorld -> (# State# RealWorld, a #) with - strictness = { \ arity -> StrictnessInfo [wwLazy, wwLazy, wwPrim] False } -- Catch is actually strict in its first argument -- but we don't want to tell the strictness -- analyser about that! @@ -1253,23 +1307,30 @@ primop CatchOp "catch#" GenPrimOp primop RaiseOp "raise#" GenPrimOp a -> b with - strictness = { \ arity -> StrictnessInfo [wwLazy] True } - -- NB: True => result is bottom + strictness = { \ arity -> mkStrictSig (mkTopDmdType [lazyDmd] BotRes) } + -- NB: result is bottom 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 #)) with - strictness = { \ arity -> StrictnessInfo [wwLazy, wwPrim] False } out_of_line = True primop UnblockAsyncExceptionsOp "unblockAsyncExceptions#" GenPrimOp (State# RealWorld -> (# State# RealWorld, a #)) -> (State# RealWorld -> (# State# RealWorld, a #)) with - strictness = { \ arity -> StrictnessInfo [wwLazy, wwPrim] False } out_of_line = True ------------------------------------------------------------------------ @@ -1310,7 +1371,6 @@ primop PutMVarOp "putMVar#" GenPrimOp {If mvar is full, block until it becomes empty. Then store value arg as its new contents.} with - strictness = { \ arity -> StrictnessInfo [wwPrim, wwLazy, wwPrim] False } usage = { mangle PutMVarOp [mkM, mkM, mkP] mkR } has_side_effects = True out_of_line = True @@ -1320,7 +1380,6 @@ primop TryPutMVarOp "tryPutMVar#" GenPrimOp {If mvar is full, immediately return with integer 0. Otherwise, store value arg as mvar's new contents, and return with integer 1.} with - strictness = { \ arity -> StrictnessInfo [wwPrim, wwLazy, wwPrim] False } usage = { mangle TryPutMVarOp [mkM, mkM, mkP] mkR } has_side_effects = True out_of_line = True @@ -1335,7 +1394,7 @@ primop IsEmptyMVarOp "isEmptyMVar#" GenPrimOp {Return 1 if mvar is empty; 0 otherwise.} with usage = { mangle IsEmptyMVarOp [mkP, mkP] mkM } - + out_of_line = True ------------------------------------------------------------------------ section "Delay/wait operations" @@ -1365,6 +1424,24 @@ primop WaitWriteOp "waitWrite#" GenPrimOp 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 +#endif + ------------------------------------------------------------------------ section "Concurrency primitives" {(In a non-concurrent implementation, ThreadId\# can be as singleton @@ -1376,7 +1453,12 @@ primop ForkOp "fork#" GenPrimOp a -> State# RealWorld -> (# State# RealWorld, ThreadId# #) with usage = { mangle ForkOp [mkO, mkP] mkR } - strictness = { \ arity -> StrictnessInfo [wwLazy, wwPrim] False } + has_side_effects = True + out_of_line = True + +primop ForkProcessOp "forkProcess#" GenPrimOp + State# RealWorld -> (# State# RealWorld, Int# #) + with has_side_effects = True out_of_line = True @@ -1394,7 +1476,15 @@ primop YieldOp "yield#" GenPrimOp out_of_line = True primop MyThreadIdOp "myThreadId#" GenPrimOp - State# RealWorld -> (# State# RealWorld, ThreadId# #) + State# RealWorld -> (# State# RealWorld, ThreadId# #) + with + out_of_line = True + +primop LabelThreadOp "labelThread#" GenPrimOp + ThreadId# -> Addr# -> State# RealWorld -> State# RealWorld + with + has_side_effects = True + out_of_line = True ------------------------------------------------------------------------ section "Weak pointers" @@ -1405,7 +1495,6 @@ section "Weak pointers" primop MkWeakOp "mkWeak#" GenPrimOp o -> b -> c -> State# RealWorld -> (# State# RealWorld, Weak# b #) with - strictness = { \ arity -> StrictnessInfo [wwLazy, wwLazy, wwLazy, wwPrim] False } usage = { mangle MkWeakOp [mkZ, mkM, mkM, mkP] mkM } has_side_effects = True out_of_line = True @@ -1415,10 +1504,11 @@ primop DeRefWeakOp "deRefWeak#" GenPrimOp with usage = { mangle DeRefWeakOp [mkM, mkP] mkM } has_side_effects = True + out_of_line = True 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 @@ -1433,9 +1523,9 @@ section "Stable pointers and names" primop MakeStablePtrOp "makeStablePtr#" GenPrimOp a -> State# RealWorld -> (# State# RealWorld, StablePtr# a #) with - strictness = { \ arity -> StrictnessInfo [wwLazy, wwPrim] False } usage = { mangle MakeStablePtrOp [mkM, mkP] mkM } has_side_effects = True + out_of_line = True primop DeRefStablePtrOp "deRefStablePtr#" GenPrimOp StablePtr# a -> State# RealWorld -> (# State# RealWorld, a #) @@ -1443,6 +1533,7 @@ primop DeRefStablePtrOp "deRefStablePtr#" GenPrimOp usage = { mangle DeRefStablePtrOp [mkM, mkP] mkM } needs_wrapper = True has_side_effects = True + out_of_line = True primop EqStablePtrOp "eqStablePtr#" GenPrimOp StablePtr# a -> StablePtr# a -> Int# @@ -1454,7 +1545,6 @@ primop MakeStableNameOp "makeStableName#" GenPrimOp a -> State# RealWorld -> (# State# RealWorld, StableName# a #) with usage = { mangle MakeStableNameOp [mkZ, mkP] mkR } - strictness = { \ arity -> StrictnessInfo [wwLazy, wwPrim] False } needs_wrapper = True has_side_effects = True out_of_line = True @@ -1483,19 +1573,10 @@ primop ReallyUnsafePtrEqualityOp "reallyUnsafePtrEquality#" GenPrimOp section "Parallelism" ------------------------------------------------------------------------ -primop SeqOp "seq#" GenPrimOp - a -> Int# - with - usage = { mangle SeqOp [mkO] mkR } - strictness = { \ arity -> StrictnessInfo [wwStrict] False } - -- Seq is strict in its argument; see notes in ConFold.lhs - has_side_effects = True - primop ParOp "par#" GenPrimOp a -> Int# with usage = { mangle ParOp [mkO] mkR } - strictness = { \ arity -> StrictnessInfo [wwLazy] False } -- Note that Par is lazy to avoid that the sparked thing -- gets evaluted strictly, which it should *not* be has_side_effects = True @@ -1565,8 +1646,6 @@ section "Tag to enum stuff" primop DataToTagOp "dataToTag#" GenPrimOp a -> Int# - with - strictness = { \ arity -> StrictnessInfo [wwLazy] False } primop TagToEnumOp "tagToEnum#" GenPrimOp Int# -> a @@ -1582,17 +1661,24 @@ primop AddrToHValueOp "addrToHValue#" GenPrimOp {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.} + +------------------------------------------------------------------------ + + +------------------------------------------------------------------------ --- --- ------------------------------------------------------------------------