X-Git-Url: http://git.megacz.com/?p=ghc-hetmet.git;a=blobdiff_plain;f=compiler%2Fprelude%2Fprimops.txt.pp;h=4dfe0195a968918dbbb6ad13cf9c22aa519c433a;hp=3aa093a81793168175208796aa0b545c2dc7ac7d;hb=d0faaa6fa0cecd23c5670fd199e9206275313666;hpb=5407ad8e0a5c08ac5193c1a9ede2a12570baee0b diff --git a/compiler/prelude/primops.txt.pp b/compiler/prelude/primops.txt.pp index 3aa093a..4dfe019 100644 --- a/compiler/prelude/primops.txt.pp +++ b/compiler/prelude/primops.txt.pp @@ -1,8 +1,12 @@ ----------------------------------------------------------------------- --- $Id: primops.txt.pp,v 1.37 2005/11/25 09:46:19 simonmar Exp $ +-- +-- (c) 2010 The University of Glasgow -- -- Primitive Operations and Types -- +-- For more information on PrimOps, see +-- http://hackage.haskell.org/trac/ghc/wiki/Commentary/PrimOps +-- ----------------------------------------------------------------------- -- This file is processed by the utility program genprimopcode to produce @@ -11,25 +15,10 @@ -- -- It should first be preprocessed. -- --- To add a new primop, you currently need to update the following files: --- --- - 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.) --- --- - if the primop is inline (i.e. a macro), then: --- 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/StgMiscClosures.h (just add the declaration) --- ghc/rts/PrimOps.cmm (define it here) --- ghc/rts/Linker.c (declare the symbol for GHCi) --- --- - the User's Guide +-- Information on how PrimOps are implemented and the steps necessary to +-- add a new one can be found in the Commentary: -- +-- http://hackage.haskell.org/trac/ghc/wiki/Commentary/PrimOps -- This file is divided into named sections, each containing or more -- primop entries. Section headers have the format: @@ -54,7 +43,7 @@ defaults has_side_effects = False out_of_line = False commutable = False - needs_wrapper = False + code_size = { primOpCodeSizeDefault } can_fail = False strictness = { \ arity -> mkStrictSig (mkTopDmdType (replicate arity lazyDmd) TopRes) } @@ -166,6 +155,7 @@ primop CharLtOp "ltChar#" Compare Char# -> Char# -> Bool primop CharLeOp "leChar#" Compare Char# -> Char# -> Bool primop OrdOp "ord#" GenPrimOp Char# -> Int# + with code_size = 0 ------------------------------------------------------------------------ section "Int#" @@ -223,9 +213,12 @@ 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.} + with code_size = 2 + 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.} + with code_size = 2 primop IntGtOp ">#" Compare Int# -> Int# -> Bool primop IntGeOp ">=#" Compare Int# -> Int# -> Bool @@ -242,8 +235,11 @@ primop IntLtOp "<#" Compare Int# -> Int# -> Bool primop IntLeOp "<=#" Compare Int# -> Int# -> Bool primop ChrOp "chr#" GenPrimOp Int# -> Char# + with code_size = 0 primop Int2WordOp "int2Word#" GenPrimOp Int# -> Word# + with code_size = 0 + primop Int2FloatOp "int2Float#" GenPrimOp Int# -> Float# primop Int2DoubleOp "int2Double#" GenPrimOp Int# -> Double# @@ -297,6 +293,7 @@ primop SrlOp "uncheckedShiftRL#" GenPrimOp Word# -> Int# -> Word# in the range 0 to word size - 1 inclusive.} primop Word2IntOp "word2Int#" GenPrimOp Word# -> Int# + with code_size = 0 primop WordGtOp "gtWord#" Compare Word# -> Word# -> Bool primop WordGeOp "geWord#" Compare Word# -> Word# -> Bool @@ -407,63 +404,72 @@ primop Double2FloatOp "double2Float#" GenPrimOp Double# -> Float# primop DoubleExpOp "expDouble#" Monadic Double# -> Double# - with needs_wrapper = True + with + code_size = { primOpCodeSizeForeignCall } primop DoubleLogOp "logDouble#" Monadic Double# -> Double# with - needs_wrapper = True + code_size = { primOpCodeSizeForeignCall } can_fail = True primop DoubleSqrtOp "sqrtDouble#" Monadic Double# -> Double# - with needs_wrapper = True + with + code_size = { primOpCodeSizeForeignCall } primop DoubleSinOp "sinDouble#" Monadic Double# -> Double# - with needs_wrapper = True + with + code_size = { primOpCodeSizeForeignCall } primop DoubleCosOp "cosDouble#" Monadic Double# -> Double# - with needs_wrapper = True + with + code_size = { primOpCodeSizeForeignCall } primop DoubleTanOp "tanDouble#" Monadic Double# -> Double# - with needs_wrapper = True + with + code_size = { primOpCodeSizeForeignCall } primop DoubleAsinOp "asinDouble#" Monadic Double# -> Double# with - needs_wrapper = True + code_size = { primOpCodeSizeForeignCall } can_fail = True primop DoubleAcosOp "acosDouble#" Monadic Double# -> Double# with - needs_wrapper = True + code_size = { primOpCodeSizeForeignCall } can_fail = True primop DoubleAtanOp "atanDouble#" Monadic Double# -> Double# with - needs_wrapper = True + code_size = { primOpCodeSizeForeignCall } primop DoubleSinhOp "sinhDouble#" Monadic Double# -> Double# - with needs_wrapper = True + with + code_size = { primOpCodeSizeForeignCall } primop DoubleCoshOp "coshDouble#" Monadic Double# -> Double# - with needs_wrapper = True + with + code_size = { primOpCodeSizeForeignCall } primop DoubleTanhOp "tanhDouble#" Monadic Double# -> Double# - with needs_wrapper = True + with + code_size = { primOpCodeSizeForeignCall } primop DoublePowerOp "**##" Dyadic Double# -> Double# -> Double# {Exponentiation.} - with needs_wrapper = True + with + code_size = { primOpCodeSizeForeignCall } primop DoubleDecode_2IntOp "decodeDouble_2Int#" GenPrimOp Double# -> (# Int#, Word#, Word#, Int# #) @@ -517,58 +523,71 @@ primop Float2IntOp "float2Int#" GenPrimOp Float# -> Int# primop FloatExpOp "expFloat#" Monadic Float# -> Float# - with needs_wrapper = True + with + code_size = { primOpCodeSizeForeignCall } primop FloatLogOp "logFloat#" Monadic Float# -> Float# - with needs_wrapper = True - can_fail = True + with + code_size = { primOpCodeSizeForeignCall } + can_fail = True primop FloatSqrtOp "sqrtFloat#" Monadic Float# -> Float# - with needs_wrapper = True + with + code_size = { primOpCodeSizeForeignCall } primop FloatSinOp "sinFloat#" Monadic Float# -> Float# - with needs_wrapper = True + with + code_size = { primOpCodeSizeForeignCall } primop FloatCosOp "cosFloat#" Monadic Float# -> Float# - with needs_wrapper = True + with + code_size = { primOpCodeSizeForeignCall } primop FloatTanOp "tanFloat#" Monadic Float# -> Float# - with needs_wrapper = True + with + code_size = { primOpCodeSizeForeignCall } primop FloatAsinOp "asinFloat#" Monadic Float# -> Float# - with needs_wrapper = True - can_fail = True + with + code_size = { primOpCodeSizeForeignCall } + can_fail = True primop FloatAcosOp "acosFloat#" Monadic Float# -> Float# - with needs_wrapper = True - can_fail = True + with + code_size = { primOpCodeSizeForeignCall } + can_fail = True primop FloatAtanOp "atanFloat#" Monadic Float# -> Float# - with needs_wrapper = True + with + code_size = { primOpCodeSizeForeignCall } primop FloatSinhOp "sinhFloat#" Monadic Float# -> Float# - with needs_wrapper = True + with + code_size = { primOpCodeSizeForeignCall } primop FloatCoshOp "coshFloat#" Monadic Float# -> Float# - with needs_wrapper = True + with + code_size = { primOpCodeSizeForeignCall } primop FloatTanhOp "tanhFloat#" Monadic Float# -> Float# - with needs_wrapper = True + with + code_size = { primOpCodeSizeForeignCall } primop FloatPowerOp "powerFloat#" Dyadic Float# -> Float# -> Float# - with needs_wrapper = True + with + code_size = { primOpCodeSizeForeignCall } primop Float2DoubleOp "float2Double#" GenPrimOp Float# -> Double# @@ -589,7 +608,7 @@ primtype MutableArray# s a primop NewArrayOp "newArray#" GenPrimOp Int# -> a -> State# s -> (# State# s, MutableArray# s a #) - {Create a new mutable array of specified size (in bytes), + {Create a new mutable array with the specified number of elements, in the specified state thread, with each element containing the specified initial value.} with @@ -610,6 +629,15 @@ primop WriteArrayOp "writeArray#" GenPrimOp {Write to specified index of mutable array.} with has_side_effects = True + code_size = 2 -- card update too + +primop SizeofArrayOp "sizeofArray#" GenPrimOp + Array# a -> Int# + {Return the number of elements in the array.} + +primop SizeofMutableArrayOp "sizeofMutableArray#" GenPrimOp + MutableArray# s a -> Int# + {Return the number of elements in the array.} primop IndexArrayOp "indexArray#" GenPrimOp Array# a -> Int# -> (# a #) @@ -629,17 +657,67 @@ primop UnsafeThawArrayOp "unsafeThawArray#" GenPrimOp out_of_line = True has_side_effects = True +primop CopyArrayOp "copyArray#" GenPrimOp + Array# a -> Int# -> MutableArray# s a -> Int# -> Int# -> State# s -> State# s + {Copy a range of the Array# to the specified region in the MutableArray#. + Both arrays must fully contain the specified ranges, but this is not checked. + The two arrays must not be the same array in different states, but this is not checked either.} + with + has_side_effects = True + code_size = { primOpCodeSizeForeignCall + 4 } + +primop CopyMutableArrayOp "copyMutableArray#" GenPrimOp + MutableArray# s a -> Int# -> MutableArray# s a -> Int# -> Int# -> State# s -> State# s + {Copy a range of the first MutableArray# to the specified region in the second MutableArray#. + Both arrays must fully contain the specified ranges, but this is not checked.} + with + has_side_effects = True + code_size = { primOpCodeSizeForeignCall + 4 } + +primop CloneArrayOp "cloneArray#" GenPrimOp + Array# a -> Int# -> Int# -> Array# a + {Return a newly allocated Array# with the specified subrange of the provided Array#. + The provided Array# should contain the full subrange specified by the two Int#s, but this is not checked.} + with + has_side_effects = True + code_size = { primOpCodeSizeForeignCall + 4 } + +primop CloneMutableArrayOp "cloneMutableArray#" GenPrimOp + MutableArray# s a -> Int# -> Int# -> State# s -> (# State# s, MutableArray# s a #) + {Return a newly allocated Array# with the specified subrange of the provided Array#. + The provided MutableArray# should contain the full subrange specified by the two Int#s, but this is not checked.} + with + has_side_effects = True + code_size = { primOpCodeSizeForeignCall + 4 } + +primop FreezeArrayOp "freezeArray#" GenPrimOp + MutableArray# s a -> Int# -> Int# -> State# s -> (# State# s, Array# a #) + {Return a newly allocated Array# with the specified subrange of the provided MutableArray#. + The provided MutableArray# should contain the full subrange specified by the two Int#s, but this is not checked.} + with + has_side_effects = True + code_size = { primOpCodeSizeForeignCall + 4 } + +primop ThawArrayOp "thawArray#" GenPrimOp + Array# a -> Int# -> Int# -> State# s -> (# State# s, MutableArray# s a #) + {Return a newly allocated Array# with the specified subrange of the provided MutableArray#. + The provided Array# should contain the full subrange specified by the two Int#s, but this is not checked.} + with + has_side_effects = True + code_size = { primOpCodeSizeForeignCall + 4 } + ------------------------------------------------------------------------ section "Byte Arrays" {Operations on {\tt ByteArray\#}. A {\tt ByteArray\#} is a just a region of - raw memory in the garbage-collected heap, which is not scanned - for pointers. It carries its own size (in bytes). There are - three sets of operations for accessing byte array contents: - index for reading from immutable byte arrays, and read/write - for mutable byte arrays. Each set contains operations for - a range of useful primitive data types. Each operation takes - an offset measured in terms of the size fo the primitive type - being read or written.} + raw memory in the garbage-collected heap, which is not + scanned for pointers. It carries its own size (in bytes). + There are + three sets of operations for accessing byte array contents: + index for reading from immutable byte arrays, and read/write + for mutable byte arrays. Each set contains operations for a + range of useful primitive data types. Each operation takes + an offset measured in terms of the size fo the primitive type + being read or written.} ------------------------------------------------------------------------ @@ -681,10 +759,11 @@ primop UnsafeFreezeByteArrayOp "unsafeFreezeByteArray#" GenPrimOp primop SizeofByteArrayOp "sizeofByteArray#" GenPrimOp ByteArray# -> Int# + {Return the size of the array in bytes.} primop SizeofMutableByteArrayOp "sizeofMutableByteArray#" GenPrimOp MutableByteArray# s -> Int# - + {Return the size of the array in bytes.} primop IndexByteArrayOp_Char "indexCharArray#" GenPrimOp ByteArray# -> Int# -> Char# @@ -889,8 +968,10 @@ primop AddrRemOp "remAddr#" GenPrimOp Addr# -> Int# -> Int# #if (WORD_SIZE_IN_BITS == 32 || WORD_SIZE_IN_BITS == 64) primop Addr2IntOp "addr2Int#" GenPrimOp Addr# -> Int# {Coerce directly from address to int. Strongly deprecated.} + with code_size = 0 primop Int2AddrOp "int2Addr#" GenPrimOp Int# -> Addr# {Coerce directly from int to address. Strongly deprecated.} + with code_size = 0 #endif primop AddrGtOp "gtAddr#" Compare Addr# -> Addr# -> Bool @@ -1107,6 +1188,7 @@ primop WriteMutVarOp "writeMutVar#" GenPrimOp {Write contents of {\tt MutVar\#}.} with has_side_effects = True + code_size = { primOpCodeSizeForeignCall } -- for the write barrier primop SameMutVarOp "sameMutVar#" GenPrimOp MutVar# s a -> MutVar# s a -> Bool @@ -1122,6 +1204,12 @@ primop AtomicModifyMutVarOp "atomicModifyMutVar#" GenPrimOp out_of_line = True has_side_effects = True +primop CasMutVarOp "casMutVar#" GenPrimOp + MutVar# s a -> a -> a -> State# s -> (# State# s, Int#, a #) + with + out_of_line = True + has_side_effects = True + ------------------------------------------------------------------------ section "Exceptions" ------------------------------------------------------------------------ @@ -1149,28 +1237,39 @@ primop RaiseOp "raise#" GenPrimOp -- 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. +-- +-- But we *do* want to know that it returns bottom after +-- being applied to two arguments primop RaiseIOOp "raiseIO#" GenPrimOp a -> State# RealWorld -> (# State# RealWorld, b #) with + strictness = { \ _arity -> mkStrictSig (mkTopDmdType [lazyDmd,lazyDmd] BotRes) } out_of_line = True has_side_effects = True -primop BlockAsyncExceptionsOp "blockAsyncExceptions#" GenPrimOp +primop MaskAsyncExceptionsOp "maskAsyncExceptions#" GenPrimOp (State# RealWorld -> (# State# RealWorld, a #)) -> (State# RealWorld -> (# State# RealWorld, a #)) with out_of_line = True has_side_effects = True -primop UnblockAsyncExceptionsOp "unblockAsyncExceptions#" GenPrimOp +primop MaskUninterruptibleOp "maskUninterruptible#" GenPrimOp (State# RealWorld -> (# State# RealWorld, a #)) -> (State# RealWorld -> (# State# RealWorld, a #)) with out_of_line = True has_side_effects = True -primop AsyncExceptionsBlockedOp "asyncExceptionsBlocked#" GenPrimOp +primop UnmaskAsyncExceptionsOp "unmaskAsyncExceptions#" GenPrimOp + (State# RealWorld -> (# State# RealWorld, a #)) + -> (State# RealWorld -> (# State# RealWorld, a #)) + with + out_of_line = True + has_side_effects = True + +primop MaskStatus "getMaskingState#" GenPrimOp State# RealWorld -> (# State# RealWorld, Int# #) with out_of_line = True @@ -1322,7 +1421,6 @@ primop DelayOp "delay#" GenPrimOp Int# -> State# s -> State# s {Sleep specified number of microseconds.} with - needs_wrapper = True has_side_effects = True out_of_line = True @@ -1330,7 +1428,6 @@ primop WaitReadOp "waitRead#" GenPrimOp Int# -> State# s -> State# s {Block until input is available on specified file descriptor.} with - needs_wrapper = True has_side_effects = True out_of_line = True @@ -1338,7 +1435,6 @@ primop WaitWriteOp "waitWrite#" GenPrimOp Int# -> State# s -> State# s {Block until output is possible on specified file descriptor.} with - needs_wrapper = True has_side_effects = True out_of_line = True @@ -1347,7 +1443,6 @@ 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 @@ -1355,7 +1450,6 @@ 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 @@ -1363,7 +1457,6 @@ 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 @@ -1439,7 +1532,7 @@ primop NoDuplicateOp "noDuplicate#" GenPrimOp has_side_effects = True primop ThreadStatusOp "threadStatus#" GenPrimOp - ThreadId# -> State# RealWorld -> (# State# RealWorld, Int# #) + ThreadId# -> State# RealWorld -> (# State# RealWorld, Int#, Int#, Int# #) with out_of_line = True has_side_effects = True @@ -1480,6 +1573,7 @@ primop FinalizeWeakOp "finalizeWeak#" GenPrimOp primop TouchOp "touch#" GenPrimOp o -> State# RealWorld -> State# RealWorld with + code_size = { 0 } has_side_effects = True ------------------------------------------------------------------------ @@ -1499,7 +1593,6 @@ primop MakeStablePtrOp "makeStablePtr#" GenPrimOp primop DeRefStablePtrOp "deRefStablePtr#" GenPrimOp StablePtr# a -> State# RealWorld -> (# State# RealWorld, a #) with - needs_wrapper = True has_side_effects = True out_of_line = True @@ -1511,7 +1604,6 @@ primop EqStablePtrOp "eqStablePtr#" GenPrimOp primop MakeStableNameOp "makeStableName#" GenPrimOp a -> State# RealWorld -> (# State# RealWorld, StableName# a #) with - needs_wrapper = True has_side_effects = True out_of_line = True @@ -1539,6 +1631,7 @@ primop ParOp "par#" GenPrimOp -- Note that Par is lazy to avoid that the sparked thing -- gets evaluted strictly, which it should *not* be has_side_effects = True + code_size = { primOpCodeSizeForeignCall } primop GetSparkOp "getSpark#" GenPrimOp State# s -> (# State# s, Int#, a #) @@ -1546,6 +1639,13 @@ primop GetSparkOp "getSpark#" GenPrimOp has_side_effects = True out_of_line = True +primop NumSparks "numSparks#" GenPrimOp + State# s -> (# State# s, Int# #) + { Returns the number of sparks in the local spark pool. } + with + has_side_effects = True + out_of_line = True + -- HWL: The first 4 Int# in all par... annotations denote: -- name, granularity info, size of result, degree of parallelism -- Same structure as _seq_ i.e. returns Int# @@ -1621,6 +1721,8 @@ primtype BCO# primop AddrToHValueOp "addrToHValue#" GenPrimOp Addr# -> (# a #) {Convert an {\tt Addr\#} to a followable type.} + with + code_size = 0 primop MkApUpd0_Op "mkApUpd0#" GenPrimOp BCO# -> (# a #) @@ -1680,11 +1782,9 @@ pseudoop "inline" {\tt inline} function expands to the identity function in Phase zero; so its use imposes no overhead. - If the function is defined in another module, GHC only exposes its inlining - in the interface file if the function is sufficiently small that it might be - inlined by the automatic mechanism. There is currently no way to tell GHC to - expose arbitrarily-large functions in the interface file. (This shortcoming - is something that could be fixed, with some kind of pragma.) } + It is good practice to mark the function with an INLINABLE pragma at + its definition, (a) so that GHC guarantees to expose its unfolding regardless + of size, and (b) so that you have control over exactly what is inlined. } pseudoop "lazy" a -> a @@ -1717,9 +1817,19 @@ primtype Any a but never enters a function value. It's also used to instantiate un-constrained type variables after type - checking. For example + checking. For example, {\tt length} has type + + {\tt length :: forall a. [a] -> Int} + + and the list datacon for the empty list has type + + {\tt [] :: forall a. [a]} + + In order to compose these two terms as {\tt length []} a type + application is required, but there is no constraint on the + choice. In this situation GHC uses {\tt Any}: - {\tt length Any []} + {\tt length Any ([] Any)} Annoyingly, we sometimes need {\tt Any}s of other kinds, such as {\tt (* -> *)} etc. This is a bit like tuples. We define a couple of useful ones here,