primops.txt.pp: add missing type application in description of GHC.Prim.Any
[ghc-hetmet.git] / compiler / prelude / primops.txt.pp
index 13b4b6c..49f7a97 100644 (file)
@@ -1,7 +1,11 @@
 -----------------------------------------------------------------------
--- $Id: primops.txt.pp,v 1.37 2005/11/25 09:46:19 simonmar Exp $
+-- 
+-- (c) 2010 The University of Glasgow
 --
--- Primitive Operations
+-- Primitive Operations and Types
+--
+-- For more information on PrimOps, see
+--   http://hackage.haskell.org/trac/ghc/wiki/Commentary/PrimOps
 --
 -----------------------------------------------------------------------
 
 --
 -- 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:
@@ -48,7 +37,7 @@
 -- text between curly brackets.  This is a kludge to enable 
 -- processors of this file to easily get hold of simple info
 -- (eg, out_of_line), whilst avoiding parsing complex expressions
--- needed for strictness and usage info.
+-- needed for strictness info.
 
 defaults
    has_side_effects = False
@@ -57,7 +46,6 @@ defaults
    needs_wrapper    = False
    can_fail         = 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
@@ -114,8 +102,8 @@ section "The word size story."
         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\# ->
+        \texttt{indexInt32Array\#} has type {\tt ByteArray\# -> Int\#
+        -> Int\#}; otherwise it has type {\tt ByteArray\# -> 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.
@@ -150,6 +138,7 @@ section "Char#"
        {Operations on 31-bit characters.}
 ------------------------------------------------------------------------
 
+primtype Char#
 
 primop   CharGtOp  "gtChar#"   Compare   Char# -> Char# -> Bool
 primop   CharGeOp  "geChar#"   Compare   Char# -> Char# -> Bool
@@ -172,6 +161,8 @@ section "Int#"
        {Operations on native-size integers (30+ bits).}
 ------------------------------------------------------------------------
 
+primtype Int#
+
 primop   IntAddOp    "+#"    Dyadic
    Int# -> Int# -> Int#
    with commutable = True
@@ -203,7 +194,7 @@ primop   IntMulMayOfloOp  "mulIntMayOflo#"
 
     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.
+    \texttt{(*) :: Integer -> Integer -> Integer} will be poor.
    }
    with commutable = True
 
@@ -217,9 +208,6 @@ primop   IntRemOp    "remInt#"    Dyadic
    {Satisfies \texttt{(quotInt\# x y) *\# y +\# (remInt\# x y) == x}.}
    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; 
@@ -248,10 +236,6 @@ primop   Int2WordOp "int2Word#" GenPrimOp Int# -> Word#
 primop   Int2FloatOp   "int2Float#"      GenPrimOp  Int# -> Float#
 primop   Int2DoubleOp   "int2Double#"          GenPrimOp  Int# -> Double#
 
-primop   Int2IntegerOp    "int2Integer#"
-   GenPrimOp Int# -> (# Int#, ByteArr# #)
-   with out_of_line = True
-
 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.}
@@ -267,6 +251,8 @@ section "Word#"
        {Operations on native-sized unsigned words (30+ bits).}
 ------------------------------------------------------------------------
 
+primtype Word#
+
 primop   WordAddOp   "plusWord#"   Dyadic   Word# -> Word# -> Word#
    with commutable = True
 
@@ -301,10 +287,6 @@ primop   SrlOp   "uncheckedShiftRL#"   GenPrimOp   Word# -> Int# -> Word#
 
 primop   Word2IntOp   "word2Int#"   GenPrimOp   Word# -> Int#
 
-primop   Word2IntegerOp   "word2Integer#"   GenPrimOp 
-   Word# -> (# Int#, ByteArr# #)
-   with out_of_line = True
-
 primop   WordGtOp   "gtWord#"   Compare   Word# -> Word# -> Bool
 primop   WordGeOp   "geWord#"   Compare   Word# -> Word# -> Bool
 primop   WordEqOp   "eqWord#"   Compare   Word# -> Word# -> Bool
@@ -328,27 +310,21 @@ primop   Narrow32WordOp    "narrow32Word#"    Monadic   Word# -> Word#
 #if WORD_SIZE_IN_BITS < 32
 ------------------------------------------------------------------------
 section "Int32#"
-       {Operations on 32-bit integers (Int32\#).  This type is only used
-         if plain Int\# has less than 32 bits.  In any case, the operations
+       {Operations on 32-bit integers ({\tt Int32\#}).  This type is only used
+         if plain {\tt Int\#} has less than 32 bits.  In any case, the operations
         are not primops; they are implemented (if needed) as ccalls instead.}
 ------------------------------------------------------------------------
 
-primop   Int32ToIntegerOp   "int32ToInteger#" GenPrimOp 
-   Int32# -> (# Int#, ByteArr# #)
-   with out_of_line = True
-
+primtype Int32#
 
 ------------------------------------------------------------------------
 section "Word32#"
        {Operations on 32-bit unsigned words. This type is only used 
-        if plain Word\# has less than 32 bits. In any case, the operations
+        if plain {\tt Word\#} has less than 32 bits. In any case, the operations
         are not primops; they are implemented (if needed) as ccalls instead.}
 ------------------------------------------------------------------------
 
-primop   Word32ToIntegerOp   "word32ToInteger#" GenPrimOp
-   Word32# -> (# Int#, ByteArr# #)
-   with out_of_line = True
-
+primtype Word32#
 
 #endif 
 
@@ -357,149 +333,30 @@ primop   Word32ToIntegerOp   "word32ToInteger#" GenPrimOp
 ------------------------------------------------------------------------
 section "Int64#"
        {Operations on 64-bit unsigned words. This type is only used 
-        if plain Int\# has less than 64 bits. In any case, the operations
+        if plain {\tt Int\#} has less than 64 bits. In any case, the operations
         are not primops; they are implemented (if needed) as ccalls instead.}
 ------------------------------------------------------------------------
 
-primop   Int64ToIntegerOp   "int64ToInteger#" GenPrimOp 
-   Int64# -> (# Int#, ByteArr# #)
-   with out_of_line = True
+primtype Int64#
 
 ------------------------------------------------------------------------
 section "Word64#"
        {Operations on 64-bit unsigned words. This type is only used 
-        if plain Word\# has less than 64 bits. In any case, the operations
+        if plain {\tt Word\#} has less than 64 bits. In any case, the operations
         are not primops; they are implemented (if needed) as ccalls instead.}
 ------------------------------------------------------------------------
 
-primop   Word64ToIntegerOp   "word64ToInteger#" GenPrimOp
-   Word64# -> (# Int#, ByteArr# #)
-   with out_of_line = True
+primtype Word64#
 
 #endif
 
 ------------------------------------------------------------------------
-section "Integer#"
-       {Operations on arbitrary-precision integers. These operations are 
-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.
-
-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
-        out_of_line = True
-
-primop   IntegerSubOp   "minusInteger#" GenPrimOp  
-   Int# -> ByteArr# -> Int# -> ByteArr# -> (# Int#, ByteArr# #)
-   with out_of_line = True
-
-primop   IntegerMulOp   "timesInteger#" GenPrimOp   
-   Int# -> ByteArr# -> Int# -> ByteArr# -> (# Int#, ByteArr# #)
-   with commutable = True
-        out_of_line = True
-
-primop   IntegerGcdOp   "gcdInteger#" GenPrimOp    
-   Int# -> ByteArr# -> Int# -> ByteArr# -> (# Int#, ByteArr# #)
-   {Greatest common divisor.}
-   with commutable = True
-        out_of_line = True
-
-primop   IntegerIntGcdOp   "gcdIntegerInt#" GenPrimOp
-   Int# -> ByteArr# -> Int# -> Int#
-   {Greatest common divisor, where second argument is an ordinary Int\#.}
-   with out_of_line = True
-
-primop   IntegerDivExactOp   "divExactInteger#" GenPrimOp
-   Int# -> ByteArr# -> Int# -> ByteArr# -> (# Int#, ByteArr# #)
-   {Divisor is guaranteed to be a factor of dividend.}
-   with out_of_line = True
-
-primop   IntegerQuotOp   "quotInteger#" GenPrimOp
-   Int# -> ByteArr# -> Int# -> ByteArr# -> (# Int#, ByteArr# #)
-   {Rounds towards zero.}
-   with out_of_line = True
-
-primop   IntegerRemOp   "remInteger#" GenPrimOp
-   Int# -> ByteArr# -> Int# -> ByteArr# -> (# Int#, ByteArr# #)
-   {Satisfies \texttt{plusInteger\# (timesInteger\# (quotInteger\# x y) y) (remInteger\# x y) == x}.}
-   with out_of_line = True
-
-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# #)
-   {Compute quot and rem simulaneously.}
-   with can_fail = True
-        out_of_line = True
-
-primop   IntegerDivModOp    "divModInteger#"  GenPrimOp
-   Int# -> ByteArr# -> Int# -> ByteArr# -> (# Int#, ByteArr#, Int#, ByteArr# #)
-   {Compute div and mod simultaneously, where div rounds towards negative infinity
-    and\texttt{(q,r) = divModInteger\#(x,y)} implies \texttt{plusInteger\# (timesInteger\# q y) r = x}.}
-   with can_fail = True
-        out_of_line = True
-
-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
-   Int# -> ByteArr# -> Int32#
-
-primop   IntegerToWord32Op   "integerToWord32#" GenPrimOp
-   Int# -> ByteArr# -> Word32#
-#endif
-
-primop   IntegerAndOp  "andInteger#" GenPrimOp
-   Int# -> ByteArr# -> Int# -> ByteArr# -> (# Int#, ByteArr# #)
-   with out_of_line = True
-
-primop   IntegerOrOp  "orInteger#" GenPrimOp
-   Int# -> ByteArr# -> Int# -> ByteArr# -> (# Int#, ByteArr# #)
-   with out_of_line = True
-
-primop   IntegerXorOp  "xorInteger#" GenPrimOp
-   Int# -> ByteArr# -> Int# -> ByteArr# -> (# Int#, ByteArr# #)
-   with out_of_line = True
-
-primop   IntegerComplementOp  "complementInteger#" GenPrimOp
-   Int# -> ByteArr# -> (# Int#, ByteArr# #)
-   with out_of_line = True
-
-#endif /* ndef ILX */
-
-------------------------------------------------------------------------
 section "Double#"
        {Operations on double-precision (64 bit) floating-point numbers.}
 ------------------------------------------------------------------------
 
+primtype Double#
+
 primop   DoubleGtOp ">##"   Compare   Double# -> Double# -> Bool
 primop   DoubleGeOp ">=##"   Compare   Double# -> Double# -> Bool
 
@@ -531,6 +388,10 @@ primop   DoubleDivOp   "/##"   Dyadic
 primop   DoubleNegOp   "negateDouble#"  Monadic   Double# -> Double#
 
 primop   Double2IntOp   "double2Int#"          GenPrimOp  Double# -> Int#
+   {Truncates a {\tt Double#} value to the nearest {\tt Int#}.
+    Results are undefined if the truncation if truncation yields
+    a value outside the range of {\tt Int#}.}
+
 primop   Double2FloatOp   "double2Float#" GenPrimOp Double# -> Float#
 
 primop   DoubleExpOp   "expDouble#"      Monadic
@@ -593,11 +454,12 @@ primop   DoublePowerOp   "**##" Dyadic
    {Exponentiation.}
    with needs_wrapper = True
 
-primop   DoubleDecodeOp   "decodeDouble#" GenPrimOp    
-   Double# -> (# Int#, Int#, ByteArr# #)
-   {Convert to arbitrary-precision integer.
-    First Int\# in result is the exponent; second Int\# and ByteArr\# represent an Integer\# 
-    holding the mantissa.}
+primop   DoubleDecode_2IntOp   "decodeDouble_2Int#" GenPrimOp    
+   Double# -> (# Int#, Word#, Word#, Int# #)
+   {Convert to integer.
+    First component of the result is -1 or 1, indicating the sign of the
+    mantissa. The next two are the high and low 32 bits of the mantissa
+    respectively, and the last is the exponent.}
    with out_of_line = True
 
 ------------------------------------------------------------------------
@@ -605,6 +467,8 @@ section "Float#"
        {Operations on single-precision (32-bit) floating-point numbers.}
 ------------------------------------------------------------------------
 
+primtype Float#
+
 primop   FloatGtOp  "gtFloat#"   Compare   Float# -> Float# -> Bool
 primop   FloatGeOp  "geFloat#"   Compare   Float# -> Float# -> Bool
 
@@ -636,6 +500,9 @@ primop   FloatDivOp   "divideFloat#"      Dyadic
 primop   FloatNegOp   "negateFloat#"      Monadic    Float# -> Float#
 
 primop   Float2IntOp   "float2Int#"      GenPrimOp  Float# -> Int#
+   {Truncates a {\tt Float#} value to the nearest {\tt Int#}.
+    Results are undefined if the truncation if truncation yields
+    a value outside the range of {\tt Int#}.}
 
 primop   FloatExpOp   "expFloat#"      Monadic          
    Float# -> Float#
@@ -694,293 +561,330 @@ primop   FloatPowerOp   "powerFloat#"      Dyadic
 
 primop   Float2DoubleOp   "float2Double#" GenPrimOp  Float# -> Double#
 
-primop   FloatDecodeOp   "decodeFloat#" GenPrimOp
-   Float# -> (# Int#, Int#, ByteArr# #)
-   {Convert to arbitrary-precision integer.
-    First Int\# in result is the exponent; second Int\# and ByteArr\# represent an Integer\# 
-    holding the mantissa.}
+primop   FloatDecode_IntOp   "decodeFloat_Int#" GenPrimOp
+   Float# -> (# Int#, Int# #)
+   {Convert to integers.
+    First {\tt Int\#} in result is the mantissa; second is the exponent.}
    with out_of_line = True
 
 ------------------------------------------------------------------------
 section "Arrays"
-       {Operations on Array\#.}
+       {Operations on {\tt Array\#}.}
 ------------------------------------------------------------------------
 
+primtype Array# a
+
+primtype MutableArray# s a
+
 primop  NewArrayOp "newArray#" GenPrimOp
-   Int# -> a -> State# s -> (# State# s, MutArr# s a #)
-   {Create a new mutable array of specified size (in bytes),
+   Int# -> a -> State# s -> (# State# s, MutableArray# s a #)
+   {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
-   usage       = { mangle NewArrayOp [mkP, mkM, mkP] mkM }
    out_of_line = True
+   has_side_effects = True
 
 primop  SameMutableArrayOp "sameMutableArray#" GenPrimOp
-   MutArr# s a -> MutArr# s a -> Bool
-   with
-   usage = { mangle SameMutableArrayOp [mkP, mkP] mkM }
+   MutableArray# s a -> MutableArray# s a -> Bool
 
 primop  ReadArrayOp "readArray#" GenPrimOp
-   MutArr# s a -> Int# -> State# s -> (# State# s, a #)
+   MutableArray# s a -> Int# -> State# s -> (# State# s, a #)
    {Read from specified index of mutable array. Result is not yet evaluated.}
    with
-   usage = { mangle ReadArrayOp [mkM, mkP, mkP] mkM }
+   has_side_effects = True
 
 primop  WriteArrayOp "writeArray#" GenPrimOp
-   MutArr# s a -> Int# -> a -> State# s -> State# s
+   MutableArray# s a -> Int# -> a -> State# s -> State# s
    {Write to specified index of mutable array.}
    with
-   usage            = { mangle WriteArrayOp [mkM, mkP, mkM, mkP] mkR }
    has_side_effects = True
 
+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 #)
    {Read from specified index of immutable array. Result is packaged into
     an unboxed singleton; the result itself is not yet evaluated.}
-   with
-   usage = { mangle  IndexArrayOp [mkM, mkP] mkM }
 
 primop  UnsafeFreezeArrayOp "unsafeFreezeArray#" GenPrimOp
-   MutArr# s a -> State# s -> (# State# s, Array# a #)
+   MutableArray# s a -> State# s -> (# State# s, Array# a #)
    {Make a mutable array immutable, without copying.}
    with
-   usage            = { mangle UnsafeFreezeArrayOp [mkM, mkP] mkM }
    has_side_effects = True
 
 primop  UnsafeThawArrayOp  "unsafeThawArray#" GenPrimOp
-   Array# a -> State# s -> (# State# s, MutArr# s a #)
+   Array# a -> State# s -> (# State# s, MutableArray# s a #)
    {Make an immutable array mutable, without copying.}
    with
-   usage       = { mangle UnsafeThawArrayOp [mkM, mkP] mkM }
    out_of_line = True
+   has_side_effects = True
 
 ------------------------------------------------------------------------
 section "Byte Arrays"
-       {Operations on ByteArray\#. A 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.}
+       {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.}
 
 ------------------------------------------------------------------------
 
+primtype ByteArray#
+
+primtype MutableByteArray# s
+
 primop  NewByteArrayOp_Char "newByteArray#" GenPrimOp
-   Int# -> State# s -> (# State# s, MutByteArr# s #)
+   Int# -> State# s -> (# State# s, MutableByteArray# s #)
    {Create a new mutable byte array of specified size (in bytes), in
     the specified state thread.}
    with out_of_line = True
+        has_side_effects = True
 
 primop  NewPinnedByteArrayOp_Char "newPinnedByteArray#" GenPrimOp
-   Int# -> State# s -> (# State# s, MutByteArr# s #)
+   Int# -> State# s -> (# State# s, MutableByteArray# s #)
    {Create a mutable byte array that the GC guarantees not to move.}
    with out_of_line = True
+        has_side_effects = True
+
+primop  NewAlignedPinnedByteArrayOp_Char "newAlignedPinnedByteArray#" GenPrimOp
+   Int# -> Int# -> State# s -> (# State# s, MutableByteArray# s #)
+   {Create a mutable byte array, aligned by the specified amount, that the GC guarantees not to move.}
+   with out_of_line = True
+        has_side_effects = True
 
 primop  ByteArrayContents_Char "byteArrayContents#" GenPrimOp
-   ByteArr# -> Addr#
+   ByteArray# -> Addr#
    {Intended for use with pinned arrays; otherwise very unsafe!}
 
 primop  SameMutableByteArrayOp "sameMutableByteArray#" GenPrimOp
-   MutByteArr# s -> MutByteArr# s -> Bool
+   MutableByteArray# s -> MutableByteArray# s -> Bool
 
 primop  UnsafeFreezeByteArrayOp "unsafeFreezeByteArray#" GenPrimOp
-   MutByteArr# s -> State# s -> (# State# s, ByteArr# #)
+   MutableByteArray# s -> State# s -> (# State# s, ByteArray# #)
    {Make a mutable byte array immutable, without copying.}
    with
    has_side_effects = True
 
 primop  SizeofByteArrayOp "sizeofByteArray#" GenPrimOp  
-   ByteArr# -> Int#
+   ByteArray# -> Int#
+   {Return the size of the array in bytes.}
 
 primop  SizeofMutableByteArrayOp "sizeofMutableByteArray#" GenPrimOp
-   MutByteArr# s -> Int#
-
+   MutableByteArray# s -> Int#
+   {Return the size of the array in bytes.}
 
 primop IndexByteArrayOp_Char "indexCharArray#" GenPrimOp
-   ByteArr# -> Int# -> Char#
+   ByteArray# -> Int# -> Char#
    {Read 8-bit character; offset in bytes.}
 
 primop IndexByteArrayOp_WideChar "indexWideCharArray#" GenPrimOp
-   ByteArr# -> Int# -> Char#
+   ByteArray# -> Int# -> Char#
    {Read 31-bit character; offset in 4-byte words.}
 
 primop IndexByteArrayOp_Int "indexIntArray#" GenPrimOp
-   ByteArr# -> Int# -> Int#
+   ByteArray# -> Int# -> Int#
 
 primop IndexByteArrayOp_Word "indexWordArray#" GenPrimOp
-   ByteArr# -> Int# -> Word#
+   ByteArray# -> Int# -> Word#
 
 primop IndexByteArrayOp_Addr "indexAddrArray#" GenPrimOp
-   ByteArr# -> Int# -> Addr#
+   ByteArray# -> Int# -> Addr#
 
 primop IndexByteArrayOp_Float "indexFloatArray#" GenPrimOp
-   ByteArr# -> Int# -> Float#
+   ByteArray# -> Int# -> Float#
 
 primop IndexByteArrayOp_Double "indexDoubleArray#" GenPrimOp
-   ByteArr# -> Int# -> Double#
+   ByteArray# -> Int# -> Double#
 
 primop IndexByteArrayOp_StablePtr "indexStablePtrArray#" GenPrimOp
-   ByteArr# -> Int# -> StablePtr# a
+   ByteArray# -> Int# -> StablePtr# a
 
 primop IndexByteArrayOp_Int8 "indexInt8Array#" GenPrimOp
-   ByteArr# -> Int# -> Int#
+   ByteArray# -> Int# -> Int#
 
 primop IndexByteArrayOp_Int16 "indexInt16Array#" GenPrimOp
-   ByteArr# -> Int# -> Int#
+   ByteArray# -> Int# -> Int#
 
 primop IndexByteArrayOp_Int32 "indexInt32Array#" GenPrimOp
-   ByteArr# -> Int# -> INT32
+   ByteArray# -> Int# -> INT32
 
 primop IndexByteArrayOp_Int64 "indexInt64Array#" GenPrimOp
-   ByteArr# -> Int# -> INT64
+   ByteArray# -> Int# -> INT64
 
 primop IndexByteArrayOp_Word8 "indexWord8Array#" GenPrimOp
-   ByteArr# -> Int# -> Word#
+   ByteArray# -> Int# -> Word#
 
 primop IndexByteArrayOp_Word16 "indexWord16Array#" GenPrimOp
-   ByteArr# -> Int# -> Word#
+   ByteArray# -> Int# -> Word#
 
 primop IndexByteArrayOp_Word32 "indexWord32Array#" GenPrimOp
-   ByteArr# -> Int# -> WORD32
+   ByteArray# -> Int# -> WORD32
 
 primop IndexByteArrayOp_Word64 "indexWord64Array#" GenPrimOp
-   ByteArr# -> Int# -> WORD64
+   ByteArray# -> Int# -> WORD64
 
 primop  ReadByteArrayOp_Char "readCharArray#" GenPrimOp
-   MutByteArr# s -> Int# -> State# s -> (# State# s, Char# #)
+   MutableByteArray# s -> Int# -> State# s -> (# State# s, Char# #)
    {Read 8-bit character; offset in bytes.}
+   with has_side_effects = True
 
 primop  ReadByteArrayOp_WideChar "readWideCharArray#" GenPrimOp
-   MutByteArr# s -> Int# -> State# s -> (# State# s, Char# #)
+   MutableByteArray# s -> Int# -> State# s -> (# State# s, Char# #)
    {Read 31-bit character; offset in 4-byte words.}
+   with has_side_effects = True
 
 primop  ReadByteArrayOp_Int "readIntArray#" GenPrimOp
-   MutByteArr# s -> Int# -> State# s -> (# State# s, Int# #)
+   MutableByteArray# s -> Int# -> State# s -> (# State# s, Int# #)
+   with has_side_effects = True
 
 primop  ReadByteArrayOp_Word "readWordArray#" GenPrimOp
-   MutByteArr# s -> Int# -> State# s -> (# State# s, Word# #)
+   MutableByteArray# s -> Int# -> State# s -> (# State# s, Word# #)
+   with has_side_effects = True
 
 primop  ReadByteArrayOp_Addr "readAddrArray#" GenPrimOp
-   MutByteArr# s -> Int# -> State# s -> (# State# s, Addr# #)
+   MutableByteArray# s -> Int# -> State# s -> (# State# s, Addr# #)
+   with has_side_effects = True
 
 primop  ReadByteArrayOp_Float "readFloatArray#" GenPrimOp
-   MutByteArr# s -> Int# -> State# s -> (# State# s, Float# #)
+   MutableByteArray# s -> Int# -> State# s -> (# State# s, Float# #)
+   with has_side_effects = True
 
 primop  ReadByteArrayOp_Double "readDoubleArray#" GenPrimOp
-   MutByteArr# s -> Int# -> State# s -> (# State# s, Double# #)
+   MutableByteArray# s -> Int# -> State# s -> (# State# s, Double# #)
+   with has_side_effects = True
 
 primop  ReadByteArrayOp_StablePtr "readStablePtrArray#" GenPrimOp
-   MutByteArr# s -> Int# -> State# s -> (# State# s, StablePtr# a #)
+   MutableByteArray# s -> Int# -> State# s -> (# State# s, StablePtr# a #)
+   with has_side_effects = True
 
 primop  ReadByteArrayOp_Int8 "readInt8Array#" GenPrimOp
-   MutByteArr# s -> Int# -> State# s -> (# State# s, Int# #)
+   MutableByteArray# s -> Int# -> State# s -> (# State# s, Int# #)
+   with has_side_effects = True
 
 primop  ReadByteArrayOp_Int16 "readInt16Array#" GenPrimOp
-   MutByteArr# s -> Int# -> State# s -> (# State# s, Int# #)
+   MutableByteArray# s -> Int# -> State# s -> (# State# s, Int# #)
+   with has_side_effects = True
 
 primop  ReadByteArrayOp_Int32 "readInt32Array#" GenPrimOp
-   MutByteArr# s -> Int# -> State# s -> (# State# s, INT32 #)
+   MutableByteArray# s -> Int# -> State# s -> (# State# s, INT32 #)
+   with has_side_effects = True
 
 primop  ReadByteArrayOp_Int64 "readInt64Array#" GenPrimOp
-   MutByteArr# s -> Int# -> State# s -> (# State# s, INT64 #)
+   MutableByteArray# s -> Int# -> State# s -> (# State# s, INT64 #)
+   with has_side_effects = True
 
 primop  ReadByteArrayOp_Word8 "readWord8Array#" GenPrimOp
-   MutByteArr# s -> Int# -> State# s -> (# State# s, Word# #)
+   MutableByteArray# s -> Int# -> State# s -> (# State# s, Word# #)
+   with has_side_effects = True
 
 primop  ReadByteArrayOp_Word16 "readWord16Array#" GenPrimOp
-   MutByteArr# s -> Int# -> State# s -> (# State# s, Word# #)
+   MutableByteArray# s -> Int# -> State# s -> (# State# s, Word# #)
+   with has_side_effects = True
 
 primop  ReadByteArrayOp_Word32 "readWord32Array#" GenPrimOp
-   MutByteArr# s -> Int# -> State# s -> (# State# s, WORD32 #)
+   MutableByteArray# s -> Int# -> State# s -> (# State# s, WORD32 #)
+   with has_side_effects = True
 
 primop  ReadByteArrayOp_Word64 "readWord64Array#" GenPrimOp
-   MutByteArr# s -> Int# -> State# s -> (# State# s, WORD64 #)
+   MutableByteArray# s -> Int# -> State# s -> (# State# s, WORD64 #)
+   with has_side_effects = True
 
 primop  WriteByteArrayOp_Char "writeCharArray#" GenPrimOp
-   MutByteArr# s -> Int# -> Char# -> State# s -> State# s
+   MutableByteArray# s -> Int# -> Char# -> State# s -> State# s
    {Write 8-bit character; offset in bytes.}
    with has_side_effects = True
 
 primop  WriteByteArrayOp_WideChar "writeWideCharArray#" GenPrimOp
-   MutByteArr# s -> Int# -> Char# -> State# s -> State# s
+   MutableByteArray# s -> Int# -> Char# -> State# s -> State# s
    {Write 31-bit character; offset in 4-byte words.}
    with has_side_effects = True
 
 primop  WriteByteArrayOp_Int "writeIntArray#" GenPrimOp
-   MutByteArr# s -> Int# -> Int# -> State# s -> State# s
+   MutableByteArray# s -> Int# -> Int# -> State# s -> State# s
    with has_side_effects = True
 
 primop  WriteByteArrayOp_Word "writeWordArray#" GenPrimOp
-   MutByteArr# s -> Int# -> Word# -> State# s -> State# s
+   MutableByteArray# s -> Int# -> Word# -> State# s -> State# s
    with has_side_effects = True
 
 primop  WriteByteArrayOp_Addr "writeAddrArray#" GenPrimOp
-   MutByteArr# s -> Int# -> Addr# -> State# s -> State# s
+   MutableByteArray# s -> Int# -> Addr# -> State# s -> State# s
    with has_side_effects = True
 
 primop  WriteByteArrayOp_Float "writeFloatArray#" GenPrimOp
-   MutByteArr# s -> Int# -> Float# -> State# s -> State# s
+   MutableByteArray# s -> Int# -> Float# -> State# s -> State# s
    with has_side_effects = True
 
 primop  WriteByteArrayOp_Double "writeDoubleArray#" GenPrimOp
-   MutByteArr# s -> Int# -> Double# -> State# s -> State# s
+   MutableByteArray# s -> Int# -> Double# -> State# s -> State# s
    with has_side_effects = True
 
 primop  WriteByteArrayOp_StablePtr "writeStablePtrArray#" GenPrimOp
-   MutByteArr# s -> Int# -> StablePtr# a -> State# s -> State# s
+   MutableByteArray# s -> Int# -> StablePtr# a -> State# s -> State# s
    with has_side_effects = True
 
 primop  WriteByteArrayOp_Int8 "writeInt8Array#" GenPrimOp
-   MutByteArr# s -> Int# -> Int# -> State# s -> State# s
+   MutableByteArray# s -> Int# -> Int# -> State# s -> State# s
    with has_side_effects = True
 
 primop  WriteByteArrayOp_Int16 "writeInt16Array#" GenPrimOp
-   MutByteArr# s -> Int# -> Int# -> State# s -> State# s
+   MutableByteArray# s -> Int# -> Int# -> State# s -> State# s
    with has_side_effects = True
 
 primop  WriteByteArrayOp_Int32 "writeInt32Array#" GenPrimOp
-   MutByteArr# s -> Int# -> INT32 -> State# s -> State# s
+   MutableByteArray# s -> Int# -> INT32 -> State# s -> State# s
    with has_side_effects = True
 
 primop  WriteByteArrayOp_Int64 "writeInt64Array#" GenPrimOp
-   MutByteArr# s -> Int# -> INT64 -> State# s -> State# s
+   MutableByteArray# s -> Int# -> INT64 -> State# s -> State# s
    with has_side_effects = True
 
 primop  WriteByteArrayOp_Word8 "writeWord8Array#" GenPrimOp
-   MutByteArr# s -> Int# -> Word# -> State# s -> State# s
+   MutableByteArray# s -> Int# -> Word# -> State# s -> State# s
    with has_side_effects = True
 
 primop  WriteByteArrayOp_Word16 "writeWord16Array#" GenPrimOp
-   MutByteArr# s -> Int# -> Word# -> State# s -> State# s
+   MutableByteArray# s -> Int# -> Word# -> State# s -> State# s
    with has_side_effects = True
 
 primop  WriteByteArrayOp_Word32 "writeWord32Array#" GenPrimOp
-   MutByteArr# s -> Int# -> WORD32 -> State# s -> State# s
+   MutableByteArray# s -> Int# -> WORD32 -> State# s -> State# s
    with has_side_effects = True
 
 primop  WriteByteArrayOp_Word64 "writeWord64Array#" GenPrimOp
-   MutByteArr# s -> Int# -> WORD64 -> State# s -> State# s
+   MutableByteArray# s -> Int# -> WORD64 -> State# s -> State# s
    with has_side_effects = True
 
 ------------------------------------------------------------------------
 section "Addr#"
-       {Addr\# is an arbitrary machine address assumed to point outside
-        the garbage-collected heap.  
-
-        NB: {\tt nullAddr\#::Addr\#} is not a primop, but is defined in MkId.lhs.
-        It is the null address.}
 ------------------------------------------------------------------------
 
+primtype Addr#
+       { An arbitrary machine address assumed to point outside
+        the garbage-collected heap. }
+
+pseudoop "nullAddr#" Addr#
+       { The null address. }
+
 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
-        difference doesn't fit in an Int\#.}
+        {Result is meaningless if two {\tt Addr\#}s are so far apart that their
+        difference doesn't fit in an {\tt Int\#}.}
 primop  AddrRemOp "remAddr#" GenPrimOp Addr# -> Int# -> Int#
-        {Return the remainder when the Addr\# arg, treated like an Int\#,
-         is divided by the Int\# arg.}
+        {Return the remainder when the {\tt Addr\#} arg, treated like an {\tt Int\#},
+         is divided by the {\tt Int\#} arg.}
 #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.}
@@ -1048,52 +952,68 @@ primop IndexOffAddrOp_Word64 "indexWord64OffAddr#" GenPrimOp
 primop ReadOffAddrOp_Char "readCharOffAddr#" GenPrimOp
    Addr# -> Int# -> State# s -> (# State# s, Char# #)
    {Reads 8-bit character; offset in bytes.}
+   with has_side_effects = True
 
 primop ReadOffAddrOp_WideChar "readWideCharOffAddr#" GenPrimOp
    Addr# -> Int# -> State# s -> (# State# s, Char# #)
    {Reads 31-bit character; offset in 4-byte words.}
+   with has_side_effects = True
 
 primop ReadOffAddrOp_Int "readIntOffAddr#" GenPrimOp
    Addr# -> Int# -> State# s -> (# State# s, Int# #)
+   with has_side_effects = True
 
 primop ReadOffAddrOp_Word "readWordOffAddr#" GenPrimOp
    Addr# -> Int# -> State# s -> (# State# s, Word# #)
+   with has_side_effects = True
 
 primop ReadOffAddrOp_Addr "readAddrOffAddr#" GenPrimOp
    Addr# -> Int# -> State# s -> (# State# s, Addr# #)
+   with has_side_effects = True
 
 primop ReadOffAddrOp_Float "readFloatOffAddr#" GenPrimOp
    Addr# -> Int# -> State# s -> (# State# s, Float# #)
+   with has_side_effects = True
 
 primop ReadOffAddrOp_Double "readDoubleOffAddr#" GenPrimOp
    Addr# -> Int# -> State# s -> (# State# s, Double# #)
+   with has_side_effects = True
 
 primop ReadOffAddrOp_StablePtr "readStablePtrOffAddr#" GenPrimOp
    Addr# -> Int# -> State# s -> (# State# s, StablePtr# a #)
+   with has_side_effects = True
 
 primop ReadOffAddrOp_Int8 "readInt8OffAddr#" GenPrimOp
    Addr# -> Int# -> State# s -> (# State# s, Int# #)
+   with has_side_effects = True
 
 primop ReadOffAddrOp_Int16 "readInt16OffAddr#" GenPrimOp
    Addr# -> Int# -> State# s -> (# State# s, Int# #)
+   with has_side_effects = True
 
 primop ReadOffAddrOp_Int32 "readInt32OffAddr#" GenPrimOp
    Addr# -> Int# -> State# s -> (# State# s, INT32 #)
+   with has_side_effects = True
 
 primop ReadOffAddrOp_Int64 "readInt64OffAddr#" GenPrimOp
    Addr# -> Int# -> State# s -> (# State# s, INT64 #)
+   with has_side_effects = True
 
 primop ReadOffAddrOp_Word8 "readWord8OffAddr#" GenPrimOp
    Addr# -> Int# -> State# s -> (# State# s, Word# #)
+   with has_side_effects = True
 
 primop ReadOffAddrOp_Word16 "readWord16OffAddr#" GenPrimOp
    Addr# -> Int# -> State# s -> (# State# s, Word# #)
+   with has_side_effects = True
 
 primop ReadOffAddrOp_Word32 "readWord32OffAddr#" GenPrimOp
    Addr# -> Int# -> State# s -> (# State# s, WORD32 #)
+   with has_side_effects = True
 
 primop ReadOffAddrOp_Word64 "readWord64OffAddr#" GenPrimOp
    Addr# -> Int# -> State# s -> (# State# s, WORD64 #)
+   with has_side_effects = True
 
 
 primop  WriteOffAddrOp_Char "writeCharOffAddr#" GenPrimOp
@@ -1162,33 +1082,33 @@ primop  WriteOffAddrOp_Word64 "writeWord64OffAddr#" GenPrimOp
 
 ------------------------------------------------------------------------
 section "Mutable variables"
-       {Operations on MutVar\#s, which behave like single-element mutable arrays.}
+       {Operations on MutVar\#s.}
 ------------------------------------------------------------------------
 
+primtype MutVar# s a
+       {A {\tt MutVar\#} behaves like a single-element mutable array.}
+
 primop  NewMutVarOp "newMutVar#" GenPrimOp
    a -> State# s -> (# State# s, MutVar# s a #)
-   {Create MutVar\# with specified initial value in specified state thread.}
+   {Create {\tt MutVar\#} with specified initial value in specified state thread.}
    with
-   usage       = { mangle NewMutVarOp [mkM, mkP] mkM }
    out_of_line = True
+   has_side_effects = True
 
 primop  ReadMutVarOp "readMutVar#" GenPrimOp
    MutVar# s a -> State# s -> (# State# s, a #)
-   {Read contents of MutVar\#. Result is not yet evaluated.}
+   {Read contents of {\tt MutVar\#}. Result is not yet evaluated.}
    with
-   usage = { mangle ReadMutVarOp [mkM, mkP] mkM }
+   has_side_effects = True
 
 primop  WriteMutVarOp "writeMutVar#"  GenPrimOp
    MutVar# s a -> a -> State# s -> State# s
-   {Write contents of MutVar\#.}
+   {Write contents of {\tt MutVar\#}.}
    with
-   usage            = { mangle WriteMutVarOp [mkM, mkM, mkP] mkR }
    has_side_effects = True
 
 primop  SameMutVarOp "sameMutVar#" GenPrimOp
    MutVar# s a -> MutVar# s a -> Bool
-   with
-   usage = { mangle SameMutVarOp [mkP, mkP] mkM }
 
 -- not really the right type, but we don't know about pairs here.  The
 -- correct type is
@@ -1198,9 +1118,14 @@ primop  SameMutVarOp "sameMutVar#" GenPrimOp
 primop  AtomicModifyMutVarOp "atomicModifyMutVar#" GenPrimOp
    MutVar# s a -> (a -> b) -> State# s -> (# State# s, c #)
    with
-   usage = { mangle AtomicModifyMutVarOp [mkP, mkM, mkP] mkM }
+   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"
@@ -1215,44 +1140,64 @@ primop  CatchOp "catch#" GenPrimOp
        -- Catch is actually strict in its first argument
        -- but we don't want to tell the strictness
        -- analyser about that!
-   usage = { mangle CatchOp [mkM, mkM . (inFun CatchOp mkM mkM), mkP] mkM }
-        --     [mkO, mkO . (inFun mkM mkO)] mkO
         -- might use caught action multiply
    out_of_line = True
+   has_side_effects = True
 
 primop  RaiseOp "raise#" GenPrimOp
    a -> b
    with
-   strictness  = { \ arity -> mkStrictSig (mkTopDmdType [lazyDmd] BotRes) }
+   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.
+--
+-- 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  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
+   has_side_effects = True
 
 ------------------------------------------------------------------------
 section "STM-accessible Mutable Variables"
 ------------------------------------------------------------------------
 
+primtype TVar# s a
+
 primop AtomicallyOp "atomically#" GenPrimOp
       (State# RealWorld -> (# State# RealWorld, a #) )
    -> State# RealWorld -> (# State# RealWorld, a #)
@@ -1282,25 +1227,42 @@ primop  CatchSTMOp "catchSTM#" GenPrimOp
    out_of_line = True
    has_side_effects = True
 
+primop  Check "check#" GenPrimOp
+      (State# RealWorld -> (# State# RealWorld, a #) )
+   -> (State# RealWorld -> (# State# RealWorld, () #) )
+   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.}
+   {Create a new {\tt TVar\#} holding a specified initial value.}
    with
    out_of_line  = True
+   has_side_effects = True
 
 primop ReadTVarOp "readTVar#" GenPrimOp
        TVar# s a
     -> State# s -> (# State# s, a #)
-   {Read contents of TVar\#.  Result is not yet evaluated.}
+   {Read contents of {\tt TVar\#}.  Result is not yet evaluated.}
    with
    out_of_line = True
+   has_side_effects = True
+
+primop ReadTVarIOOp "readTVarIO#" GenPrimOp
+       TVar# s a
+    -> State# s -> (# State# s, a #)
+   {Read contents of {\tt TVar\#} outside an STM transaction}
+   with
+   out_of_line = True
+   has_side_effects = True
 
 primop WriteTVarOp "writeTVar#" GenPrimOp
        TVar# s a
     -> a
     -> State# s -> State# s
-   {Write contents of TVar\#.}
+   {Write contents of {\tt TVar\#}.}
    with
    out_of_line     = True
    has_side_effects = True
@@ -1311,66 +1273,62 @@ primop  SameTVarOp "sameTVar#" GenPrimOp
 
 ------------------------------------------------------------------------
 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,
-       (MVar\# a) can be represented by (MutVar\# (Maybe a)).)}
+       {Operations on {\tt MVar\#}s. }
 ------------------------------------------------------------------------
 
+primtype MVar# s a
+       { A shared mutable variable ({\it not} the same as a {\tt MutVar\#}!).
+       (Note: in a non-concurrent implementation, {\tt (MVar\# a)} can be
+       represented by {\tt (MutVar\# (Maybe a))}.) }
 
 primop  NewMVarOp "newMVar#"  GenPrimOp
    State# s -> (# State# s, MVar# s a #)
-   {Create new mvar; initially empty.}
+   {Create new {\tt MVar\#}; initially empty.}
    with
-   usage       = { mangle NewMVarOp [mkP] mkR }
    out_of_line = True
+   has_side_effects = True
 
 primop  TakeMVarOp "takeMVar#" GenPrimOp
    MVar# s a -> State# s -> (# State# s, a #)
-   {If mvar is empty, block until it becomes full.
+   {If {\tt MVar\#} is empty, block until it becomes full.
    Then remove and return its contents, and set it empty.}
    with
-   usage            = { mangle TakeMVarOp [mkM, mkP] mkM }
-   has_side_effects = True
    out_of_line      = True
+   has_side_effects = True
 
 primop  TryTakeMVarOp "tryTakeMVar#" GenPrimOp
    MVar# s a -> State# s -> (# State# s, Int#, a #)
-   {If mvar is empty, immediately return with integer 0 and value undefined.
-   Otherwise, return with integer 1 and contents of mvar, and set mvar empty.}
+   {If {\tt MVar\#} is empty, immediately return with integer 0 and value undefined.
+   Otherwise, return with integer 1 and contents of {\tt MVar\#}, and set {\tt MVar\#} empty.}
    with
-   usage            = { mangle TryTakeMVarOp [mkM, mkP] mkM }
-   has_side_effects = True
    out_of_line      = True
+   has_side_effects = True
 
 primop  PutMVarOp "putMVar#" GenPrimOp
    MVar# s a -> a -> State# s -> State# s
-   {If mvar is full, block until it becomes empty.
+   {If {\tt MVar\#} is full, block until it becomes empty.
    Then store value arg as its new contents.}
    with
-   usage            = { mangle PutMVarOp [mkM, mkM, mkP] mkR }
-   has_side_effects = True
    out_of_line      = True
+   has_side_effects = True
 
 primop  TryPutMVarOp "tryPutMVar#" GenPrimOp
    MVar# s a -> a -> State# s -> (# State# s, Int# #)
-   {If mvar is full, immediately return with integer 0.
-    Otherwise, store value arg as mvar's new contents, and return with integer 1.}
+   {If {\tt MVar\#} is full, immediately return with integer 0.
+    Otherwise, store value arg as {\tt MVar\#}'s new contents, and return with integer 1.}
    with
-   usage            = { mangle TryPutMVarOp [mkM, mkM, mkP] mkR }
-   has_side_effects = True
    out_of_line      = True
+   has_side_effects = True
 
 primop  SameMVarOp "sameMVar#" GenPrimOp
    MVar# s a -> MVar# s a -> Bool
-   with
-   usage = { mangle SameMVarOp [mkP, mkP] mkM }
 
 primop  IsEmptyMVarOp "isEmptyMVar#" GenPrimOp
    MVar# s a -> State# s -> (# State# s, Int# #)
-   {Return 1 if mvar is empty; 0 otherwise.}
+   {Return 1 if {\tt MVar\#} is empty; 0 otherwise.}
    with
-   usage = { mangle IsEmptyMVarOp [mkP, mkP] mkM }
    out_of_line = True
+   has_side_effects = True
 
 ------------------------------------------------------------------------
 section "Delay/wait operations"
@@ -1429,29 +1387,40 @@ primop  AsyncDoProcOp "asyncDoProc#" GenPrimOp
 
 ------------------------------------------------------------------------
 section "Concurrency primitives"
-       {(In a non-concurrent implementation, ThreadId\# can be as singleton
-       type, whose (unique) value is returned by myThreadId\#.  The 
-       other operations can be omitted.)}
 ------------------------------------------------------------------------
 
+primtype State# s
+       { {\tt State\#} is the primitive, unlifted type of states.  It has
+       one type parameter, thus {\tt State\# RealWorld}, or {\tt State\# s},
+       where s is a type variable. The only purpose of the type parameter
+       is to keep different state threads separate.  It is represented by
+       nothing at all. }
+
+primtype RealWorld
+       { {\tt RealWorld} is deeply magical.  It is {\it primitive}, but it is not
+       {\it unlifted} (hence {\tt ptrArg}).  We never manipulate values of type
+       {\tt RealWorld}; it's only used in the type system, to parameterise {\tt State\#}. }
+
+primtype ThreadId#
+       {(In a non-concurrent implementation, this can be a singleton
+       type, whose (unique) value is returned by {\tt myThreadId\#}.  The 
+       other operations can be omitted.)}
+
 primop  ForkOp "fork#" GenPrimOp
    a -> State# RealWorld -> (# State# RealWorld, ThreadId# #)
    with
-   usage            = { mangle ForkOp [mkO, mkP] mkR }
    has_side_effects = True
    out_of_line      = True
 
 primop  ForkOnOp "forkOn#" GenPrimOp
    Int# -> a -> State# RealWorld -> (# State# RealWorld, ThreadId# #)
    with
-   usage            = { mangle ForkOnOp [mkO, mkP] mkR }
    has_side_effects = True
    out_of_line      = True
 
 primop  KillThreadOp "killThread#"  GenPrimOp
    ThreadId# -> a -> State# RealWorld -> State# RealWorld
    with
-   usage            = { mangle KillThreadOp [mkP, mkM, mkP] mkR }
    has_side_effects = True
    out_of_line      = True
 
@@ -1465,6 +1434,7 @@ primop  MyThreadIdOp "myThreadId#" GenPrimOp
    State# RealWorld -> (# State# RealWorld, ThreadId# #)
    with
    out_of_line = True
+   has_side_effects = True
 
 primop LabelThreadOp "labelThread#" GenPrimOp
    ThreadId# -> Addr# -> State# RealWorld -> State# RealWorld
@@ -1476,24 +1446,43 @@ primop  IsCurrentThreadBoundOp "isCurrentThreadBound#" GenPrimOp
    State# RealWorld -> (# State# RealWorld, Int# #)
    with
    out_of_line = True
+   has_side_effects = True
+
+primop  NoDuplicateOp "noDuplicate#" GenPrimOp
+   State# RealWorld -> State# RealWorld
+   with
+   out_of_line = True
+   has_side_effects = True
+
+primop  ThreadStatusOp "threadStatus#" GenPrimOp
+   ThreadId# -> State# RealWorld -> (# State# RealWorld, Int#, Int#, Int# #)
+   with
+   out_of_line = True
+   has_side_effects = True
 
 ------------------------------------------------------------------------
 section "Weak pointers"
 ------------------------------------------------------------------------
 
+primtype Weak# b
+
 -- note that tyvar "o" denotes openAlphaTyVar
 
 primop  MkWeakOp "mkWeak#" GenPrimOp
    o -> b -> c -> State# RealWorld -> (# State# RealWorld, Weak# b #)
    with
-   usage            = { mangle MkWeakOp [mkZ, mkM, mkM, mkP] mkM }
+   has_side_effects = True
+   out_of_line      = True
+
+primop  MkWeakForeignEnvOp "mkWeakForeignEnv#" GenPrimOp
+   o -> b -> Addr# -> Addr# -> Int# -> Addr# -> State# RealWorld -> (# State# RealWorld, Weak# b #)
+   with
    has_side_effects = True
    out_of_line      = True
 
 primop  DeRefWeakOp "deRefWeak#" GenPrimOp
    Weak# a -> State# RealWorld -> (# State# RealWorld, Int#, a #)
    with
-   usage            = { mangle DeRefWeakOp [mkM, mkP] mkM }
    has_side_effects = True
    out_of_line      = True
 
@@ -1501,9 +1490,6 @@ primop  FinalizeWeakOp "finalizeWeak#" GenPrimOp
    Weak# a -> State# RealWorld -> (# State# RealWorld, Int#, 
               (State# RealWorld -> (# State# RealWorld, () #)) #)
    with
-   usage            = { mangle FinalizeWeakOp [mkM, mkP] 
-                               (mkR . (inUB FinalizeWeakOp 
-                                            [id,id,inFun FinalizeWeakOp mkR mkM])) }
    has_side_effects = True
    out_of_line      = True
 
@@ -1516,17 +1502,19 @@ primop TouchOp "touch#" GenPrimOp
 section "Stable pointers and names"
 ------------------------------------------------------------------------
 
+primtype StablePtr# a
+
+primtype StableName# a
+
 primop  MakeStablePtrOp "makeStablePtr#" GenPrimOp
    a -> State# RealWorld -> (# State# RealWorld, StablePtr# a #)
    with
-   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 #)
    with
-   usage            = { mangle DeRefStablePtrOp [mkM, mkP] mkM }
    needs_wrapper    = True
    has_side_effects = True
    out_of_line      = True
@@ -1534,26 +1522,20 @@ primop  DeRefStablePtrOp "deRefStablePtr#" GenPrimOp
 primop  EqStablePtrOp "eqStablePtr#" GenPrimOp
    StablePtr# a -> StablePtr# a -> Int#
    with
-   usage            = { mangle EqStablePtrOp [mkP, mkP] mkR }
    has_side_effects = True
 
 primop  MakeStableNameOp "makeStableName#" GenPrimOp
    a -> State# RealWorld -> (# State# RealWorld, StableName# a #)
    with
-   usage            = { mangle MakeStableNameOp [mkZ, mkP] mkR }
    needs_wrapper    = True
    has_side_effects = True
    out_of_line      = True
 
 primop  EqStableNameOp "eqStableName#" GenPrimOp
    StableName# a -> StableName# a -> Int#
-   with
-   usage = { mangle EqStableNameOp [mkP, mkP] mkR }
 
 primop  StableNameToIntOp "stableNameToInt#" GenPrimOp
    StableName# a -> Int#
-   with
-   usage = { mangle StableNameToIntOp [mkP] mkR }
 
 ------------------------------------------------------------------------
 section "Unsafe pointer equality"
@@ -1562,8 +1544,6 @@ section "Unsafe pointer equality"
 
 primop  ReallyUnsafePtrEqualityOp "reallyUnsafePtrEquality#" GenPrimOp
    a -> a -> Int#
-   with
-   usage = { mangle ReallyUnsafePtrEqualityOp [mkZ, mkZ] mkR }
 
 ------------------------------------------------------------------------
 section "Parallelism"
@@ -1572,11 +1552,23 @@ section "Parallelism"
 primop  ParOp "par#" GenPrimOp
    a -> Int#
    with
-   usage            = { mangle ParOp [mkO] mkR }
       -- Note that Par is lazy to avoid that the sparked thing
       -- gets evaluted strictly, which it should *not* be
    has_side_effects = True
 
+primop GetSparkOp "getSpark#" GenPrimOp
+   State# s -> (# State# s, Int#, a #)
+   with
+   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#
@@ -1586,37 +1578,31 @@ primop  ParOp "par#" GenPrimOp
 primop  ParGlobalOp  "parGlobal#"  GenPrimOp
    a -> Int# -> Int# -> Int# -> Int# -> b -> Int#
    with
-   usage            = { mangle ParGlobalOp [mkO, mkP, mkP, mkP, mkP, mkM] mkM }
    has_side_effects = True
 
 primop  ParLocalOp  "parLocal#"  GenPrimOp
    a -> Int# -> Int# -> Int# -> Int# -> b -> Int#
    with
-   usage            = { mangle ParLocalOp [mkO, mkP, mkP, mkP, mkP, mkM] mkM }
    has_side_effects = True
 
 primop  ParAtOp  "parAt#"  GenPrimOp
    b -> a -> Int# -> Int# -> Int# -> Int# -> c -> Int#
    with
-   usage            = { mangle ParAtOp [mkO, mkZ, mkP, mkP, mkP, mkP, mkM] mkM }
    has_side_effects = True
 
 primop  ParAtAbsOp  "parAtAbs#"  GenPrimOp
    a -> Int# -> Int# -> Int# -> Int# -> Int# -> b -> Int#
    with
-   usage            = { mangle ParAtAbsOp [mkO, mkP, mkP, mkP, mkP, mkM] mkM }
    has_side_effects = True
 
 primop  ParAtRelOp  "parAtRel#" GenPrimOp
    a -> Int# -> Int# -> Int# -> Int# -> Int# -> b -> Int#
    with
-   usage            = { mangle ParAtRelOp [mkO, mkP, mkP, mkP, mkP, mkM] mkM }
    has_side_effects = True
 
 primop  ParAtForNowOp  "parAtForNow#" GenPrimOp
    b -> a -> Int# -> Int# -> Int# -> Int# -> c -> Int#
    with
-   usage            = { mangle ParAtForNowOp [mkO, mkZ, mkP, mkP, mkP, mkP, mkM] mkM }
    has_side_effects = True
 
 -- copyable# and noFollow# are yet to be implemented (for GpH)
@@ -1624,13 +1610,11 @@ primop  ParAtForNowOp  "parAtForNow#" GenPrimOp
 --primop  CopyableOp  "copyable#" GenPrimOp
 --   a -> Int#
 --   with
---   usage            = { mangle CopyableOp [mkZ] mkR }
 --   has_side_effects = True
 --
 --primop  NoFollowOp "noFollow#" GenPrimOp
 --   a -> Int#
 --   with
---   usage            = { mangle NoFollowOp [mkZ] mkR }
 --   has_side_effects = True
 
 
@@ -1643,7 +1627,7 @@ section "Tag to enum stuff"
 primop  DataToTagOp "dataToTag#" GenPrimOp
    a -> Int#
    with
-   strictness  = { \ arity -> mkStrictSig (mkTopDmdType [seqDmd] TopRes) }
+   strictness  = { \ _arity -> mkStrictSig (mkTopDmdType [seqDmd] TopRes) }
        -- dataToTag# must have an evaluated argument
 
 primop  TagToEnumOp "tagToEnum#" GenPrimOp     
@@ -1654,10 +1638,12 @@ section "Bytecode operations"
        {Support for the bytecode interpreter and linker.}
 ------------------------------------------------------------------------
 
+primtype BCO#
+   {Primitive bytecode type.}
 
 primop   AddrToHValueOp "addrToHValue#" GenPrimOp
    Addr# -> (# a #)
-   {Convert an Addr\# to a followable type.}
+   {Convert an {\tt Addr\#} to a followable type.}
 
 primop   MkApUpd0_Op "mkApUpd0#" GenPrimOp
    BCO# -> (# a #)
@@ -1665,17 +1651,164 @@ primop   MkApUpd0_Op "mkApUpd0#" GenPrimOp
    out_of_line = True
 
 primop  NewBCOOp "newBCO#" GenPrimOp
-   ByteArr# -> ByteArr# -> Array# a -> ByteArr# -> Int# -> ByteArr# -> State# s -> (# State# s, BCO# #)
+   ByteArray# -> ByteArray# -> Array# a -> Int# -> ByteArray# -> State# s -> (# State# s, BCO# #)
    with
    has_side_effects = True
    out_of_line      = True
 
+primop  UnpackClosureOp "unpackClosure#" GenPrimOp
+   a -> (# Addr#, Array# b, ByteArray# #)
+   with
+   out_of_line = True
+
+primop  GetApStackValOp "getApStackVal#" GenPrimOp
+   a -> Int# -> (# Int#, b #)
+   with
+   out_of_line = True
+
+------------------------------------------------------------------------
+section "Misc"
+        {These aren't nearly as wired in as Etc...}
 ------------------------------------------------------------------------
-section "Coercion" 
-       {{\tt unsafeCoerce\# :: a -> b} is not a primop, but is defined in MkId.lhs.}
 
+primop  TraceCcsOp "traceCcs#" GenPrimOp
+   a -> b -> b
+   with
+   has_side_effects = True
+   out_of_line = True
+
+------------------------------------------------------------------------
+section "Etc" 
+       {Miscellaneous built-ins}
 ------------------------------------------------------------------------
 
+pseudoop   "seq"
+   a -> b -> b
+   { Evaluates its first argument to head normal form, and then returns its second
+       argument as the result. }
+
+pseudoop   "inline"
+   a -> a
+   { The call {\tt (inline f)} arranges that f is inlined, regardless of its size.
+       More precisely, the call {\tt (inline f)} rewrites to the right-hand side of
+       {\tt f}'s definition. This allows the programmer to control inlining from a
+       particular call site rather than the definition site of the function (c.f.
+       {\tt INLINE} pragmas in User's Guide, Section 7.10.3, "INLINE and NOINLINE
+       pragmas").
+
+       This inlining occurs regardless of the argument to the call or the size of
+       {\tt f}'s definition; it is unconditional. The main caveat is that {\tt f}'s
+       definition must be visible to the compiler. That is, {\tt f} must be
+       {\tt let}-bound in the current scope. If no inlining takes place, the
+       {\tt inline} function expands to the identity function in Phase zero; so its
+       use imposes no overhead.
+
+       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
+   { The {\tt lazy} function restrains strictness analysis a little. The call
+       {\tt (lazy e)} means the same as {\tt e}, but {\tt lazy} has a magical
+       property so far as strictness analysis is concerned: it is lazy in its first
+       argument, even though its semantics is strict. After strictness analysis has
+       run, calls to {\tt lazy} are inlined to be the identity function.
+
+       This behaviour is occasionally useful when controlling evaluation order.
+       Notably, {\tt lazy} is used in the library definition of {\tt Control.Parallel.par}:
+
+       {\tt par :: a -> b -> b}
+
+       {\tt par x y = case (par\# x) of \_ -> lazy y}
+
+       If {\tt lazy} were not lazy, {\tt par} would look strict in {\tt y} which
+       would defeat the whole purpose of {\tt par}.
+
+       Like {\tt seq}, the argument of {\tt lazy} can have an unboxed type. }
+
+primtype Any a
+       { The type constructor {\tt Any} is type to which you can unsafely coerce any
+       lifted type, and back. 
+
+         * It is lifted, and hence represented by a pointer
+
+         * It does not claim to be a {\it data} type, and that's important for
+           the code generator, because the code gen may {\it enter} a data value
+           but never enters a function value.  
+
+       It's also used to instantiate un-constrained type variables after type
+       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 ([] 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,
+       and make others up on the fly.  If any of these others end up being exported
+       into interface files, we'll get a crash; at least until we add interface-file
+       syntax to support them. }
+
+pseudoop   "unsafeCoerce#"
+   a -> b
+   { The function {\tt unsafeCoerce\#} allows you to side-step the typechecker entirely. That
+       is, it allows you to coerce any type into any other type. If you use this function,
+       you had better get it right, otherwise segmentation faults await. It is generally
+       used when you want to write a program that you know is well-typed, but where Haskell's
+       type system is not expressive enough to prove that it is well typed.
+
+        The following uses of {\tt unsafeCoerce\#} are supposed to work (i.e. not lead to
+        spurious compile-time or run-time crashes):
+
+         * Casting any lifted type to {\tt Any}
+
+         * Casting {\tt Any} back to the real type
+
+         * Casting an unboxed type to another unboxed type of the same size
+           (but not coercions between floating-point and integral types)
+
+         * Casting between two types that have the same runtime representation.  One case is when
+           the two types differ only in "phantom" type parameters, for example
+           {\tt Ptr Int} to {\tt Ptr Float}, or {\tt [Int]} to {\tt [Float]} when the list is 
+           known to be empty.  Also, a {\tt newtype} of a type {\tt T} has the same representation
+           at runtime as {\tt T}.
+
+        Other uses of {\tt unsafeCoerce\#} are undefined.  In particular, you should not use
+       {\tt unsafeCoerce\#} to cast a T to an algebraic data type D, unless T is also
+       an algebraic data type.  For example, do not cast {\tt Int->Int} to {\tt Bool}, even if
+        you later cast that {\tt Bool} back to {\tt Int->Int} before applying it.  The reasons
+        have to do with GHC's internal representation details (for the congnoscenti, data values
+       can be entered but function closures cannot).  If you want a safe type to cast things
+       to, use {\tt Any}, which is not an algebraic data type.
+       
+        }
+
+-- NB. It is tempting to think that casting a value to a type that it doesn't have is safe
+-- as long as you don't "do anything" with the value in its cast form, such as seq on it.  This
+-- isn't the case: the compiler can insert seqs itself, and if these happen at the wrong type,
+-- Bad Things Might Happen.  See bug #1616: in this case we cast a function of type (a,b) -> (a,b)
+-- to () -> () and back again.  The strictness analyser saw that the function was strict, but
+-- the wrapper had type () -> (), and hence the wrapper de-constructed the (), the worker re-constructed
+-- a new (), with the result that the code ended up with "case () of (a,b) -> ...".
+
+primop  TraceEventOp "traceEvent#" GenPrimOp
+   Addr# -> State# s -> State# s
+   { Emits an event via the RTS tracing framework.  The contents
+     of the event is the zero-terminated byte string passed as the first
+     argument.  The event will be emitted either to the .eventlog file,
+     or to stderr, depending on the runtime RTS flags. }
+   with
+   has_side_effects = True
+   out_of_line      = True
 
 ------------------------------------------------------------------------
 ---                                                                  ---