| 1 | ----------------------------------------------------------------------- |
|---|
| 2 | -- |
|---|
| 3 | -- (c) 2010 The University of Glasgow |
|---|
| 4 | -- |
|---|
| 5 | -- Primitive Operations and Types |
|---|
| 6 | -- |
|---|
| 7 | -- For more information on PrimOps, see |
|---|
| 8 | -- http://hackage.haskell.org/trac/ghc/wiki/Commentary/PrimOps |
|---|
| 9 | -- |
|---|
| 10 | ----------------------------------------------------------------------- |
|---|
| 11 | |
|---|
| 12 | -- This file is processed by the utility program genprimopcode to produce |
|---|
| 13 | -- a number of include files within the compiler and optionally to produce |
|---|
| 14 | -- human-readable documentation. |
|---|
| 15 | -- |
|---|
| 16 | -- It should first be preprocessed. |
|---|
| 17 | -- |
|---|
| 18 | -- Information on how PrimOps are implemented and the steps necessary to |
|---|
| 19 | -- add a new one can be found in the Commentary: |
|---|
| 20 | -- |
|---|
| 21 | -- http://hackage.haskell.org/trac/ghc/wiki/Commentary/PrimOps |
|---|
| 22 | |
|---|
| 23 | -- This file is divided into named sections, each containing or more |
|---|
| 24 | -- primop entries. Section headers have the format: |
|---|
| 25 | -- |
|---|
| 26 | -- section "section-name" {description} |
|---|
| 27 | -- |
|---|
| 28 | -- This information is used solely when producing documentation; it is |
|---|
| 29 | -- otherwise ignored. The description is optional. |
|---|
| 30 | -- |
|---|
| 31 | -- The format of each primop entry is as follows: |
|---|
| 32 | -- |
|---|
| 33 | -- primop internal-name "name-in-program-text" type category {description} attributes |
|---|
| 34 | |
|---|
| 35 | -- The default attribute values which apply if you don't specify |
|---|
| 36 | -- other ones. Attribute values can be True, False, or arbitrary |
|---|
| 37 | -- text between curly brackets. This is a kludge to enable |
|---|
| 38 | -- processors of this file to easily get hold of simple info |
|---|
| 39 | -- (eg, out_of_line), whilst avoiding parsing complex expressions |
|---|
| 40 | -- needed for strictness info. |
|---|
| 41 | |
|---|
| 42 | defaults |
|---|
| 43 | has_side_effects = False |
|---|
| 44 | out_of_line = False -- See Note Note [PrimOp can_fail and has_side_effects] in PrimOp |
|---|
| 45 | can_fail = False -- See Note Note [PrimOp can_fail and has_side_effects] in PrimOp |
|---|
| 46 | commutable = False |
|---|
| 47 | code_size = { primOpCodeSizeDefault } |
|---|
| 48 | strictness = { \ arity -> mkStrictSig (mkTopDmdType (replicate arity lazyDmd) TopRes) } |
|---|
| 49 | |
|---|
| 50 | |
|---|
| 51 | -- Currently, documentation is produced using latex, so contents of |
|---|
| 52 | -- description fields should be legal latex. Descriptions can contain |
|---|
| 53 | -- matched pairs of embedded curly brackets. |
|---|
| 54 | |
|---|
| 55 | #include "MachDeps.h" |
|---|
| 56 | |
|---|
| 57 | -- We need platform defines (tests for mingw32 below). However, we only |
|---|
| 58 | -- test the TARGET platform, which doesn't vary between stages, so the |
|---|
| 59 | -- stage1 platform defines are fine: |
|---|
| 60 | #include "../stage1/ghc_boot_platform.h" |
|---|
| 61 | |
|---|
| 62 | section "The word size story." |
|---|
| 63 | {Haskell98 specifies that signed integers (type {\tt Int}) |
|---|
| 64 | must contain at least 30 bits. GHC always implements {\tt |
|---|
| 65 | Int} using the primitive type {\tt Int\#}, whose size equals |
|---|
| 66 | the {\tt MachDeps.h} constant {\tt WORD\_SIZE\_IN\_BITS}. |
|---|
| 67 | This is normally set based on the {\tt config.h} parameter |
|---|
| 68 | {\tt SIZEOF\_HSWORD}, i.e., 32 bits on 32-bit machines, 64 |
|---|
| 69 | bits on 64-bit machines. However, it can also be explicitly |
|---|
| 70 | set to a smaller number, e.g., 31 bits, to allow the |
|---|
| 71 | possibility of using tag bits. Currently GHC itself has only |
|---|
| 72 | 32-bit and 64-bit variants, but 30 or 31-bit code can be |
|---|
| 73 | exported as an external core file for use in other back ends. |
|---|
| 74 | |
|---|
| 75 | GHC also implements a primitive unsigned integer type {\tt |
|---|
| 76 | Word\#} which always has the same number of bits as {\tt |
|---|
| 77 | Int\#}. |
|---|
| 78 | |
|---|
| 79 | In addition, GHC supports families of explicit-sized integers |
|---|
| 80 | and words at 8, 16, 32, and 64 bits, with the usual |
|---|
| 81 | arithmetic operations, comparisons, and a range of |
|---|
| 82 | conversions. The 8-bit and 16-bit sizes are always |
|---|
| 83 | represented as {\tt Int\#} and {\tt Word\#}, and the |
|---|
| 84 | operations implemented in terms of the the primops on these |
|---|
| 85 | types, with suitable range restrictions on the results (using |
|---|
| 86 | the {\tt narrow$n$Int\#} and {\tt narrow$n$Word\#} families |
|---|
| 87 | of primops. The 32-bit sizes are represented using {\tt |
|---|
| 88 | Int\#} and {\tt Word\#} when {\tt WORD\_SIZE\_IN\_BITS} |
|---|
| 89 | $\geq$ 32; otherwise, these are represented using distinct |
|---|
| 90 | primitive types {\tt Int32\#} and {\tt Word32\#}. These (when |
|---|
| 91 | needed) have a complete set of corresponding operations; |
|---|
| 92 | however, nearly all of these are implemented as external C |
|---|
| 93 | functions rather than as primops. Exactly the same story |
|---|
| 94 | applies to the 64-bit sizes. All of these details are hidden |
|---|
| 95 | under the {\tt PrelInt} and {\tt PrelWord} modules, which use |
|---|
| 96 | {\tt \#if}-defs to invoke the appropriate types and |
|---|
| 97 | operators. |
|---|
| 98 | |
|---|
| 99 | Word size also matters for the families of primops for |
|---|
| 100 | indexing/reading/writing fixed-size quantities at offsets |
|---|
| 101 | from an array base, address, or foreign pointer. Here, a |
|---|
| 102 | slightly different approach is taken. The names of these |
|---|
| 103 | primops are fixed, but their {\it types} vary according to |
|---|
| 104 | the value of {\tt WORD\_SIZE\_IN\_BITS}. For example, if word |
|---|
| 105 | size is at least 32 bits then an operator like |
|---|
| 106 | \texttt{indexInt32Array\#} has type {\tt ByteArray\# -> Int\# |
|---|
| 107 | -> Int\#}; otherwise it has type {\tt ByteArray\# -> Int\# -> |
|---|
| 108 | Int32\#}. This approach confines the necessary {\tt |
|---|
| 109 | \#if}-defs to this file; no conditional compilation is needed |
|---|
| 110 | in the files that expose these primops. |
|---|
| 111 | |
|---|
| 112 | Finally, there are strongly deprecated primops for coercing |
|---|
| 113 | between {\tt Addr\#}, the primitive type of machine |
|---|
| 114 | addresses, and {\tt Int\#}. These are pretty bogus anyway, |
|---|
| 115 | but will work on existing 32-bit and 64-bit GHC targets; they |
|---|
| 116 | are completely bogus when tag bits are used in {\tt Int\#}, |
|---|
| 117 | so are not available in this case. } |
|---|
| 118 | |
|---|
| 119 | -- Define synonyms for indexing ops. |
|---|
| 120 | |
|---|
| 121 | #if WORD_SIZE_IN_BITS < 32 |
|---|
| 122 | #define INT32 Int32# |
|---|
| 123 | #define WORD32 Word32# |
|---|
| 124 | #else |
|---|
| 125 | #define INT32 Int# |
|---|
| 126 | #define WORD32 Word# |
|---|
| 127 | #endif |
|---|
| 128 | |
|---|
| 129 | #if WORD_SIZE_IN_BITS < 64 |
|---|
| 130 | #define INT64 Int64# |
|---|
| 131 | #define WORD64 Word64# |
|---|
| 132 | #else |
|---|
| 133 | #define INT64 Int# |
|---|
| 134 | #define WORD64 Word# |
|---|
| 135 | #endif |
|---|
| 136 | |
|---|
| 137 | ------------------------------------------------------------------------ |
|---|
| 138 | section "Char#" |
|---|
| 139 | {Operations on 31-bit characters.} |
|---|
| 140 | ------------------------------------------------------------------------ |
|---|
| 141 | |
|---|
| 142 | primtype Char# |
|---|
| 143 | |
|---|
| 144 | primop CharGtOp "gtChar#" Compare Char# -> Char# -> Bool |
|---|
| 145 | primop CharGeOp "geChar#" Compare Char# -> Char# -> Bool |
|---|
| 146 | |
|---|
| 147 | primop CharEqOp "eqChar#" Compare |
|---|
| 148 | Char# -> Char# -> Bool |
|---|
| 149 | with commutable = True |
|---|
| 150 | |
|---|
| 151 | primop CharNeOp "neChar#" Compare |
|---|
| 152 | Char# -> Char# -> Bool |
|---|
| 153 | with commutable = True |
|---|
| 154 | |
|---|
| 155 | primop CharLtOp "ltChar#" Compare Char# -> Char# -> Bool |
|---|
| 156 | primop CharLeOp "leChar#" Compare Char# -> Char# -> Bool |
|---|
| 157 | |
|---|
| 158 | primop OrdOp "ord#" GenPrimOp Char# -> Int# |
|---|
| 159 | with code_size = 0 |
|---|
| 160 | |
|---|
| 161 | ------------------------------------------------------------------------ |
|---|
| 162 | section "Int#" |
|---|
| 163 | {Operations on native-size integers (30+ bits).} |
|---|
| 164 | ------------------------------------------------------------------------ |
|---|
| 165 | |
|---|
| 166 | primtype Int# |
|---|
| 167 | |
|---|
| 168 | primop IntAddOp "+#" Dyadic |
|---|
| 169 | Int# -> Int# -> Int# |
|---|
| 170 | with commutable = True |
|---|
| 171 | |
|---|
| 172 | primop IntSubOp "-#" Dyadic Int# -> Int# -> Int# |
|---|
| 173 | |
|---|
| 174 | primop IntMulOp "*#" |
|---|
| 175 | Dyadic Int# -> Int# -> Int# |
|---|
| 176 | {Low word of signed integer multiply.} |
|---|
| 177 | with commutable = True |
|---|
| 178 | |
|---|
| 179 | primop IntMulMayOfloOp "mulIntMayOflo#" |
|---|
| 180 | Dyadic Int# -> Int# -> Int# |
|---|
| 181 | {Return non-zero if there is any possibility that the upper word of a |
|---|
| 182 | signed integer multiply might contain useful information. Return |
|---|
| 183 | zero only if you are completely sure that no overflow can occur. |
|---|
| 184 | On a 32-bit platform, the recommmended implementation is to do a |
|---|
| 185 | 32 x 32 -> 64 signed multiply, and subtract result[63:32] from |
|---|
| 186 | (result[31] >>signed 31). If this is zero, meaning that the |
|---|
| 187 | upper word is merely a sign extension of the lower one, no |
|---|
| 188 | overflow can occur. |
|---|
| 189 | |
|---|
| 190 | On a 64-bit platform it is not always possible to |
|---|
| 191 | acquire the top 64 bits of the result. Therefore, a recommended |
|---|
| 192 | implementation is to take the absolute value of both operands, and |
|---|
| 193 | return 0 iff bits[63:31] of them are zero, since that means that their |
|---|
| 194 | magnitudes fit within 31 bits, so the magnitude of the product must fit |
|---|
| 195 | into 62 bits. |
|---|
| 196 | |
|---|
| 197 | If in doubt, return non-zero, but do make an effort to create the |
|---|
| 198 | correct answer for small args, since otherwise the performance of |
|---|
| 199 | \texttt{(*) :: Integer -> Integer -> Integer} will be poor. |
|---|
| 200 | } |
|---|
| 201 | with commutable = True |
|---|
| 202 | |
|---|
| 203 | primop IntQuotOp "quotInt#" Dyadic |
|---|
| 204 | Int# -> Int# -> Int# |
|---|
| 205 | {Rounds towards zero.} |
|---|
| 206 | with can_fail = True |
|---|
| 207 | |
|---|
| 208 | primop IntRemOp "remInt#" Dyadic |
|---|
| 209 | Int# -> Int# -> Int# |
|---|
| 210 | {Satisfies \texttt{(quotInt\# x y) *\# y +\# (remInt\# x y) == x}.} |
|---|
| 211 | with can_fail = True |
|---|
| 212 | |
|---|
| 213 | primop IntQuotRemOp "quotRemInt#" GenPrimOp |
|---|
| 214 | Int# -> Int# -> (# Int#, Int# #) |
|---|
| 215 | {Rounds towards zero.} |
|---|
| 216 | with can_fail = True |
|---|
| 217 | |
|---|
| 218 | primop IntNegOp "negateInt#" Monadic Int# -> Int# |
|---|
| 219 | primop IntAddCOp "addIntC#" GenPrimOp Int# -> Int# -> (# Int#, Int# #) |
|---|
| 220 | {Add with carry. First member of result is (wrapped) sum; |
|---|
| 221 | second member is 0 iff no overflow occured.} |
|---|
| 222 | with code_size = 2 |
|---|
| 223 | |
|---|
| 224 | primop IntSubCOp "subIntC#" GenPrimOp Int# -> Int# -> (# Int#, Int# #) |
|---|
| 225 | {Subtract with carry. First member of result is (wrapped) difference; |
|---|
| 226 | second member is 0 iff no overflow occured.} |
|---|
| 227 | with code_size = 2 |
|---|
| 228 | |
|---|
| 229 | primop IntGtOp ">#" Compare Int# -> Int# -> Bool |
|---|
| 230 | primop IntGeOp ">=#" Compare Int# -> Int# -> Bool |
|---|
| 231 | |
|---|
| 232 | primop IntEqOp "==#" Compare |
|---|
| 233 | Int# -> Int# -> Bool |
|---|
| 234 | with commutable = True |
|---|
| 235 | |
|---|
| 236 | primop IntNeOp "/=#" Compare |
|---|
| 237 | Int# -> Int# -> Bool |
|---|
| 238 | with commutable = True |
|---|
| 239 | |
|---|
| 240 | primop IntLtOp "<#" Compare Int# -> Int# -> Bool |
|---|
| 241 | primop IntLeOp "<=#" Compare Int# -> Int# -> Bool |
|---|
| 242 | |
|---|
| 243 | primop ChrOp "chr#" GenPrimOp Int# -> Char# |
|---|
| 244 | with code_size = 0 |
|---|
| 245 | |
|---|
| 246 | primop Int2WordOp "int2Word#" GenPrimOp Int# -> Word# |
|---|
| 247 | with code_size = 0 |
|---|
| 248 | |
|---|
| 249 | primop Int2FloatOp "int2Float#" GenPrimOp Int# -> Float# |
|---|
| 250 | primop Int2DoubleOp "int2Double#" GenPrimOp Int# -> Double# |
|---|
| 251 | |
|---|
| 252 | primop ISllOp "uncheckedIShiftL#" GenPrimOp Int# -> Int# -> Int# |
|---|
| 253 | {Shift left. Result undefined if shift amount is not |
|---|
| 254 | in the range 0 to word size - 1 inclusive.} |
|---|
| 255 | primop ISraOp "uncheckedIShiftRA#" GenPrimOp Int# -> Int# -> Int# |
|---|
| 256 | {Shift right arithmetic. Result undefined if shift amount is not |
|---|
| 257 | in the range 0 to word size - 1 inclusive.} |
|---|
| 258 | primop ISrlOp "uncheckedIShiftRL#" GenPrimOp Int# -> Int# -> Int# |
|---|
| 259 | {Shift right logical. Result undefined if shift amount is not |
|---|
| 260 | in the range 0 to word size - 1 inclusive.} |
|---|
| 261 | |
|---|
| 262 | ------------------------------------------------------------------------ |
|---|
| 263 | section "Word#" |
|---|
| 264 | {Operations on native-sized unsigned words (30+ bits).} |
|---|
| 265 | ------------------------------------------------------------------------ |
|---|
| 266 | |
|---|
| 267 | primtype Word# |
|---|
| 268 | |
|---|
| 269 | primop WordAddOp "plusWord#" Dyadic Word# -> Word# -> Word# |
|---|
| 270 | with commutable = True |
|---|
| 271 | |
|---|
| 272 | -- Returns (# high, low #) (or equivalently, (# carry, low #)) |
|---|
| 273 | primop WordAdd2Op "plusWord2#" GenPrimOp |
|---|
| 274 | Word# -> Word# -> (# Word#, Word# #) |
|---|
| 275 | with commutable = True |
|---|
| 276 | |
|---|
| 277 | primop WordSubOp "minusWord#" Dyadic Word# -> Word# -> Word# |
|---|
| 278 | |
|---|
| 279 | primop WordMulOp "timesWord#" Dyadic Word# -> Word# -> Word# |
|---|
| 280 | with commutable = True |
|---|
| 281 | |
|---|
| 282 | -- Returns (# high, low #) |
|---|
| 283 | primop WordMul2Op "timesWord2#" GenPrimOp |
|---|
| 284 | Word# -> Word# -> (# Word#, Word# #) |
|---|
| 285 | with commutable = True |
|---|
| 286 | |
|---|
| 287 | primop WordQuotOp "quotWord#" Dyadic Word# -> Word# -> Word# |
|---|
| 288 | with can_fail = True |
|---|
| 289 | |
|---|
| 290 | primop WordRemOp "remWord#" Dyadic Word# -> Word# -> Word# |
|---|
| 291 | with can_fail = True |
|---|
| 292 | |
|---|
| 293 | primop WordQuotRemOp "quotRemWord#" GenPrimOp |
|---|
| 294 | Word# -> Word# -> (# Word#, Word# #) |
|---|
| 295 | with can_fail = True |
|---|
| 296 | |
|---|
| 297 | -- Takes high word of dividend, then low word of dividend, then divisor. |
|---|
| 298 | -- Requires that high word is not divisible by divisor. |
|---|
| 299 | primop WordQuotRem2Op "quotRemWord2#" GenPrimOp |
|---|
| 300 | Word# -> Word# -> Word# -> (# Word#, Word# #) |
|---|
| 301 | with can_fail = True |
|---|
| 302 | |
|---|
| 303 | primop AndOp "and#" Dyadic Word# -> Word# -> Word# |
|---|
| 304 | with commutable = True |
|---|
| 305 | |
|---|
| 306 | primop OrOp "or#" Dyadic Word# -> Word# -> Word# |
|---|
| 307 | with commutable = True |
|---|
| 308 | |
|---|
| 309 | primop XorOp "xor#" Dyadic Word# -> Word# -> Word# |
|---|
| 310 | with commutable = True |
|---|
| 311 | |
|---|
| 312 | primop NotOp "not#" Monadic Word# -> Word# |
|---|
| 313 | |
|---|
| 314 | primop SllOp "uncheckedShiftL#" GenPrimOp Word# -> Int# -> Word# |
|---|
| 315 | {Shift left logical. Result undefined if shift amount is not |
|---|
| 316 | in the range 0 to word size - 1 inclusive.} |
|---|
| 317 | primop SrlOp "uncheckedShiftRL#" GenPrimOp Word# -> Int# -> Word# |
|---|
| 318 | {Shift right logical. Result undefined if shift amount is not |
|---|
| 319 | in the range 0 to word size - 1 inclusive.} |
|---|
| 320 | |
|---|
| 321 | primop Word2IntOp "word2Int#" GenPrimOp Word# -> Int# |
|---|
| 322 | with code_size = 0 |
|---|
| 323 | |
|---|
| 324 | primop WordGtOp "gtWord#" Compare Word# -> Word# -> Bool |
|---|
| 325 | primop WordGeOp "geWord#" Compare Word# -> Word# -> Bool |
|---|
| 326 | primop WordEqOp "eqWord#" Compare Word# -> Word# -> Bool |
|---|
| 327 | primop WordNeOp "neWord#" Compare Word# -> Word# -> Bool |
|---|
| 328 | primop WordLtOp "ltWord#" Compare Word# -> Word# -> Bool |
|---|
| 329 | primop WordLeOp "leWord#" Compare Word# -> Word# -> Bool |
|---|
| 330 | |
|---|
| 331 | primop PopCnt8Op "popCnt8#" Monadic Word# -> Word# |
|---|
| 332 | {Count the number of set bits in the lower 8 bits of a word.} |
|---|
| 333 | primop PopCnt16Op "popCnt16#" Monadic Word# -> Word# |
|---|
| 334 | {Count the number of set bits in the lower 16 bits of a word.} |
|---|
| 335 | primop PopCnt32Op "popCnt32#" Monadic Word# -> Word# |
|---|
| 336 | {Count the number of set bits in the lower 32 bits of a word.} |
|---|
| 337 | primop PopCnt64Op "popCnt64#" GenPrimOp WORD64 -> Word# |
|---|
| 338 | {Count the number of set bits in a 64-bit word.} |
|---|
| 339 | primop PopCntOp "popCnt#" Monadic Word# -> Word# |
|---|
| 340 | {Count the number of set bits in a word.} |
|---|
| 341 | |
|---|
| 342 | ------------------------------------------------------------------------ |
|---|
| 343 | section "Narrowings" |
|---|
| 344 | {Explicit narrowing of native-sized ints or words.} |
|---|
| 345 | ------------------------------------------------------------------------ |
|---|
| 346 | |
|---|
| 347 | primop Narrow8IntOp "narrow8Int#" Monadic Int# -> Int# |
|---|
| 348 | primop Narrow16IntOp "narrow16Int#" Monadic Int# -> Int# |
|---|
| 349 | primop Narrow32IntOp "narrow32Int#" Monadic Int# -> Int# |
|---|
| 350 | primop Narrow8WordOp "narrow8Word#" Monadic Word# -> Word# |
|---|
| 351 | primop Narrow16WordOp "narrow16Word#" Monadic Word# -> Word# |
|---|
| 352 | primop Narrow32WordOp "narrow32Word#" Monadic Word# -> Word# |
|---|
| 353 | |
|---|
| 354 | |
|---|
| 355 | #if WORD_SIZE_IN_BITS < 32 |
|---|
| 356 | ------------------------------------------------------------------------ |
|---|
| 357 | section "Int32#" |
|---|
| 358 | {Operations on 32-bit integers ({\tt Int32\#}). This type is only used |
|---|
| 359 | if plain {\tt Int\#} has less than 32 bits. In any case, the operations |
|---|
| 360 | are not primops; they are implemented (if needed) as ccalls instead.} |
|---|
| 361 | ------------------------------------------------------------------------ |
|---|
| 362 | |
|---|
| 363 | primtype Int32# |
|---|
| 364 | |
|---|
| 365 | ------------------------------------------------------------------------ |
|---|
| 366 | section "Word32#" |
|---|
| 367 | {Operations on 32-bit unsigned words. This type is only used |
|---|
| 368 | if plain {\tt Word\#} has less than 32 bits. In any case, the operations |
|---|
| 369 | are not primops; they are implemented (if needed) as ccalls instead.} |
|---|
| 370 | ------------------------------------------------------------------------ |
|---|
| 371 | |
|---|
| 372 | primtype Word32# |
|---|
| 373 | |
|---|
| 374 | #endif |
|---|
| 375 | |
|---|
| 376 | |
|---|
| 377 | #if WORD_SIZE_IN_BITS < 64 |
|---|
| 378 | ------------------------------------------------------------------------ |
|---|
| 379 | section "Int64#" |
|---|
| 380 | {Operations on 64-bit unsigned words. This type is only used |
|---|
| 381 | if plain {\tt Int\#} has less than 64 bits. In any case, the operations |
|---|
| 382 | are not primops; they are implemented (if needed) as ccalls instead.} |
|---|
| 383 | ------------------------------------------------------------------------ |
|---|
| 384 | |
|---|
| 385 | primtype Int64# |
|---|
| 386 | |
|---|
| 387 | ------------------------------------------------------------------------ |
|---|
| 388 | section "Word64#" |
|---|
| 389 | {Operations on 64-bit unsigned words. This type is only used |
|---|
| 390 | if plain {\tt Word\#} has less than 64 bits. In any case, the operations |
|---|
| 391 | are not primops; they are implemented (if needed) as ccalls instead.} |
|---|
| 392 | ------------------------------------------------------------------------ |
|---|
| 393 | |
|---|
| 394 | primtype Word64# |
|---|
| 395 | |
|---|
| 396 | #endif |
|---|
| 397 | |
|---|
| 398 | ------------------------------------------------------------------------ |
|---|
| 399 | section "Double#" |
|---|
| 400 | {Operations on double-precision (64 bit) floating-point numbers.} |
|---|
| 401 | ------------------------------------------------------------------------ |
|---|
| 402 | |
|---|
| 403 | primtype Double# |
|---|
| 404 | |
|---|
| 405 | primop DoubleGtOp ">##" Compare Double# -> Double# -> Bool |
|---|
| 406 | primop DoubleGeOp ">=##" Compare Double# -> Double# -> Bool |
|---|
| 407 | |
|---|
| 408 | primop DoubleEqOp "==##" Compare |
|---|
| 409 | Double# -> Double# -> Bool |
|---|
| 410 | with commutable = True |
|---|
| 411 | |
|---|
| 412 | primop DoubleNeOp "/=##" Compare |
|---|
| 413 | Double# -> Double# -> Bool |
|---|
| 414 | with commutable = True |
|---|
| 415 | |
|---|
| 416 | primop DoubleLtOp "<##" Compare Double# -> Double# -> Bool |
|---|
| 417 | primop DoubleLeOp "<=##" Compare Double# -> Double# -> Bool |
|---|
| 418 | |
|---|
| 419 | primop DoubleAddOp "+##" Dyadic |
|---|
| 420 | Double# -> Double# -> Double# |
|---|
| 421 | with commutable = True |
|---|
| 422 | |
|---|
| 423 | primop DoubleSubOp "-##" Dyadic Double# -> Double# -> Double# |
|---|
| 424 | |
|---|
| 425 | primop DoubleMulOp "*##" Dyadic |
|---|
| 426 | Double# -> Double# -> Double# |
|---|
| 427 | with commutable = True |
|---|
| 428 | |
|---|
| 429 | primop DoubleDivOp "/##" Dyadic |
|---|
| 430 | Double# -> Double# -> Double# |
|---|
| 431 | with can_fail = True |
|---|
| 432 | |
|---|
| 433 | primop DoubleNegOp "negateDouble#" Monadic Double# -> Double# |
|---|
| 434 | |
|---|
| 435 | primop Double2IntOp "double2Int#" GenPrimOp Double# -> Int# |
|---|
| 436 | {Truncates a {\tt Double#} value to the nearest {\tt Int#}. |
|---|
| 437 | Results are undefined if the truncation if truncation yields |
|---|
| 438 | a value outside the range of {\tt Int#}.} |
|---|
| 439 | |
|---|
| 440 | primop Double2FloatOp "double2Float#" GenPrimOp Double# -> Float# |
|---|
| 441 | |
|---|
| 442 | primop DoubleExpOp "expDouble#" Monadic |
|---|
| 443 | Double# -> Double# |
|---|
| 444 | with |
|---|
| 445 | code_size = { primOpCodeSizeForeignCall } |
|---|
| 446 | |
|---|
| 447 | primop DoubleLogOp "logDouble#" Monadic |
|---|
| 448 | Double# -> Double# |
|---|
| 449 | with |
|---|
| 450 | code_size = { primOpCodeSizeForeignCall } |
|---|
| 451 | can_fail = True |
|---|
| 452 | |
|---|
| 453 | primop DoubleSqrtOp "sqrtDouble#" Monadic |
|---|
| 454 | Double# -> Double# |
|---|
| 455 | with |
|---|
| 456 | code_size = { primOpCodeSizeForeignCall } |
|---|
| 457 | |
|---|
| 458 | primop DoubleSinOp "sinDouble#" Monadic |
|---|
| 459 | Double# -> Double# |
|---|
| 460 | with |
|---|
| 461 | code_size = { primOpCodeSizeForeignCall } |
|---|
| 462 | |
|---|
| 463 | primop DoubleCosOp "cosDouble#" Monadic |
|---|
| 464 | Double# -> Double# |
|---|
| 465 | with |
|---|
| 466 | code_size = { primOpCodeSizeForeignCall } |
|---|
| 467 | |
|---|
| 468 | primop DoubleTanOp "tanDouble#" Monadic |
|---|
| 469 | Double# -> Double# |
|---|
| 470 | with |
|---|
| 471 | code_size = { primOpCodeSizeForeignCall } |
|---|
| 472 | |
|---|
| 473 | primop DoubleAsinOp "asinDouble#" Monadic |
|---|
| 474 | Double# -> Double# |
|---|
| 475 | with |
|---|
| 476 | code_size = { primOpCodeSizeForeignCall } |
|---|
| 477 | can_fail = True |
|---|
| 478 | |
|---|
| 479 | primop DoubleAcosOp "acosDouble#" Monadic |
|---|
| 480 | Double# -> Double# |
|---|
| 481 | with |
|---|
| 482 | code_size = { primOpCodeSizeForeignCall } |
|---|
| 483 | can_fail = True |
|---|
| 484 | |
|---|
| 485 | primop DoubleAtanOp "atanDouble#" Monadic |
|---|
| 486 | Double# -> Double# |
|---|
| 487 | with |
|---|
| 488 | code_size = { primOpCodeSizeForeignCall } |
|---|
| 489 | |
|---|
| 490 | primop DoubleSinhOp "sinhDouble#" Monadic |
|---|
| 491 | Double# -> Double# |
|---|
| 492 | with |
|---|
| 493 | code_size = { primOpCodeSizeForeignCall } |
|---|
| 494 | |
|---|
| 495 | primop DoubleCoshOp "coshDouble#" Monadic |
|---|
| 496 | Double# -> Double# |
|---|
| 497 | with |
|---|
| 498 | code_size = { primOpCodeSizeForeignCall } |
|---|
| 499 | |
|---|
| 500 | primop DoubleTanhOp "tanhDouble#" Monadic |
|---|
| 501 | Double# -> Double# |
|---|
| 502 | with |
|---|
| 503 | code_size = { primOpCodeSizeForeignCall } |
|---|
| 504 | |
|---|
| 505 | primop DoublePowerOp "**##" Dyadic |
|---|
| 506 | Double# -> Double# -> Double# |
|---|
| 507 | {Exponentiation.} |
|---|
| 508 | with |
|---|
| 509 | code_size = { primOpCodeSizeForeignCall } |
|---|
| 510 | |
|---|
| 511 | primop DoubleDecode_2IntOp "decodeDouble_2Int#" GenPrimOp |
|---|
| 512 | Double# -> (# Int#, Word#, Word#, Int# #) |
|---|
| 513 | {Convert to integer. |
|---|
| 514 | First component of the result is -1 or 1, indicating the sign of the |
|---|
| 515 | mantissa. The next two are the high and low 32 bits of the mantissa |
|---|
| 516 | respectively, and the last is the exponent.} |
|---|
| 517 | with out_of_line = True |
|---|
| 518 | |
|---|
| 519 | ------------------------------------------------------------------------ |
|---|
| 520 | section "Float#" |
|---|
| 521 | {Operations on single-precision (32-bit) floating-point numbers.} |
|---|
| 522 | ------------------------------------------------------------------------ |
|---|
| 523 | |
|---|
| 524 | primtype Float# |
|---|
| 525 | |
|---|
| 526 | primop FloatGtOp "gtFloat#" Compare Float# -> Float# -> Bool |
|---|
| 527 | primop FloatGeOp "geFloat#" Compare Float# -> Float# -> Bool |
|---|
| 528 | |
|---|
| 529 | primop FloatEqOp "eqFloat#" Compare |
|---|
| 530 | Float# -> Float# -> Bool |
|---|
| 531 | with commutable = True |
|---|
| 532 | |
|---|
| 533 | primop FloatNeOp "neFloat#" Compare |
|---|
| 534 | Float# -> Float# -> Bool |
|---|
| 535 | with commutable = True |
|---|
| 536 | |
|---|
| 537 | primop FloatLtOp "ltFloat#" Compare Float# -> Float# -> Bool |
|---|
| 538 | primop FloatLeOp "leFloat#" Compare Float# -> Float# -> Bool |
|---|
| 539 | |
|---|
| 540 | primop FloatAddOp "plusFloat#" Dyadic |
|---|
| 541 | Float# -> Float# -> Float# |
|---|
| 542 | with commutable = True |
|---|
| 543 | |
|---|
| 544 | primop FloatSubOp "minusFloat#" Dyadic Float# -> Float# -> Float# |
|---|
| 545 | |
|---|
| 546 | primop FloatMulOp "timesFloat#" Dyadic |
|---|
| 547 | Float# -> Float# -> Float# |
|---|
| 548 | with commutable = True |
|---|
| 549 | |
|---|
| 550 | primop FloatDivOp "divideFloat#" Dyadic |
|---|
| 551 | Float# -> Float# -> Float# |
|---|
| 552 | with can_fail = True |
|---|
| 553 | |
|---|
| 554 | primop FloatNegOp "negateFloat#" Monadic Float# -> Float# |
|---|
| 555 | |
|---|
| 556 | primop Float2IntOp "float2Int#" GenPrimOp Float# -> Int# |
|---|
| 557 | {Truncates a {\tt Float#} value to the nearest {\tt Int#}. |
|---|
| 558 | Results are undefined if the truncation if truncation yields |
|---|
| 559 | a value outside the range of {\tt Int#}.} |
|---|
| 560 | |
|---|
| 561 | primop FloatExpOp "expFloat#" Monadic |
|---|
| 562 | Float# -> Float# |
|---|
| 563 | with |
|---|
| 564 | code_size = { primOpCodeSizeForeignCall } |
|---|
| 565 | |
|---|
| 566 | primop FloatLogOp "logFloat#" Monadic |
|---|
| 567 | Float# -> Float# |
|---|
| 568 | with |
|---|
| 569 | code_size = { primOpCodeSizeForeignCall } |
|---|
| 570 | can_fail = True |
|---|
| 571 | |
|---|
| 572 | primop FloatSqrtOp "sqrtFloat#" Monadic |
|---|
| 573 | Float# -> Float# |
|---|
| 574 | with |
|---|
| 575 | code_size = { primOpCodeSizeForeignCall } |
|---|
| 576 | |
|---|
| 577 | primop FloatSinOp "sinFloat#" Monadic |
|---|
| 578 | Float# -> Float# |
|---|
| 579 | with |
|---|
| 580 | code_size = { primOpCodeSizeForeignCall } |
|---|
| 581 | |
|---|
| 582 | primop FloatCosOp "cosFloat#" Monadic |
|---|
| 583 | Float# -> Float# |
|---|
| 584 | with |
|---|
| 585 | code_size = { primOpCodeSizeForeignCall } |
|---|
| 586 | |
|---|
| 587 | primop FloatTanOp "tanFloat#" Monadic |
|---|
| 588 | Float# -> Float# |
|---|
| 589 | with |
|---|
| 590 | code_size = { primOpCodeSizeForeignCall } |
|---|
| 591 | |
|---|
| 592 | primop FloatAsinOp "asinFloat#" Monadic |
|---|
| 593 | Float# -> Float# |
|---|
| 594 | with |
|---|
| 595 | code_size = { primOpCodeSizeForeignCall } |
|---|
| 596 | can_fail = True |
|---|
| 597 | |
|---|
| 598 | primop FloatAcosOp "acosFloat#" Monadic |
|---|
| 599 | Float# -> Float# |
|---|
| 600 | with |
|---|
| 601 | code_size = { primOpCodeSizeForeignCall } |
|---|
| 602 | can_fail = True |
|---|
| 603 | |
|---|
| 604 | primop FloatAtanOp "atanFloat#" Monadic |
|---|
| 605 | Float# -> Float# |
|---|
| 606 | with |
|---|
| 607 | code_size = { primOpCodeSizeForeignCall } |
|---|
| 608 | |
|---|
| 609 | primop FloatSinhOp "sinhFloat#" Monadic |
|---|
| 610 | Float# -> Float# |
|---|
| 611 | with |
|---|
| 612 | code_size = { primOpCodeSizeForeignCall } |
|---|
| 613 | |
|---|
| 614 | primop FloatCoshOp "coshFloat#" Monadic |
|---|
| 615 | Float# -> Float# |
|---|
| 616 | with |
|---|
| 617 | code_size = { primOpCodeSizeForeignCall } |
|---|
| 618 | |
|---|
| 619 | primop FloatTanhOp "tanhFloat#" Monadic |
|---|
| 620 | Float# -> Float# |
|---|
| 621 | with |
|---|
| 622 | code_size = { primOpCodeSizeForeignCall } |
|---|
| 623 | |
|---|
| 624 | primop FloatPowerOp "powerFloat#" Dyadic |
|---|
| 625 | Float# -> Float# -> Float# |
|---|
| 626 | with |
|---|
| 627 | code_size = { primOpCodeSizeForeignCall } |
|---|
| 628 | |
|---|
| 629 | primop Float2DoubleOp "float2Double#" GenPrimOp Float# -> Double# |
|---|
| 630 | |
|---|
| 631 | primop FloatDecode_IntOp "decodeFloat_Int#" GenPrimOp |
|---|
| 632 | Float# -> (# Int#, Int# #) |
|---|
| 633 | {Convert to integers. |
|---|
| 634 | First {\tt Int\#} in result is the mantissa; second is the exponent.} |
|---|
| 635 | with out_of_line = True |
|---|
| 636 | |
|---|
| 637 | ------------------------------------------------------------------------ |
|---|
| 638 | section "Arrays" |
|---|
| 639 | {Operations on {\tt Array\#}.} |
|---|
| 640 | ------------------------------------------------------------------------ |
|---|
| 641 | |
|---|
| 642 | primtype Array# a |
|---|
| 643 | |
|---|
| 644 | primtype MutableArray# s a |
|---|
| 645 | |
|---|
| 646 | primop NewArrayOp "newArray#" GenPrimOp |
|---|
| 647 | Int# -> a -> State# s -> (# State# s, MutableArray# s a #) |
|---|
| 648 | {Create a new mutable array with the specified number of elements, |
|---|
| 649 | in the specified state thread, |
|---|
| 650 | with each element containing the specified initial value.} |
|---|
| 651 | with |
|---|
| 652 | out_of_line = True |
|---|
| 653 | has_side_effects = True |
|---|
| 654 | |
|---|
| 655 | primop SameMutableArrayOp "sameMutableArray#" GenPrimOp |
|---|
| 656 | MutableArray# s a -> MutableArray# s a -> Bool |
|---|
| 657 | |
|---|
| 658 | primop ReadArrayOp "readArray#" GenPrimOp |
|---|
| 659 | MutableArray# s a -> Int# -> State# s -> (# State# s, a #) |
|---|
| 660 | {Read from specified index of mutable array. Result is not yet evaluated.} |
|---|
| 661 | with |
|---|
| 662 | has_side_effects = True |
|---|
| 663 | can_fail = True |
|---|
| 664 | |
|---|
| 665 | primop WriteArrayOp "writeArray#" GenPrimOp |
|---|
| 666 | MutableArray# s a -> Int# -> a -> State# s -> State# s |
|---|
| 667 | {Write to specified index of mutable array.} |
|---|
| 668 | with |
|---|
| 669 | has_side_effects = True |
|---|
| 670 | can_fail = True |
|---|
| 671 | code_size = 2 -- card update too |
|---|
| 672 | |
|---|
| 673 | primop SizeofArrayOp "sizeofArray#" GenPrimOp |
|---|
| 674 | Array# a -> Int# |
|---|
| 675 | {Return the number of elements in the array.} |
|---|
| 676 | |
|---|
| 677 | primop SizeofMutableArrayOp "sizeofMutableArray#" GenPrimOp |
|---|
| 678 | MutableArray# s a -> Int# |
|---|
| 679 | {Return the number of elements in the array.} |
|---|
| 680 | |
|---|
| 681 | primop IndexArrayOp "indexArray#" GenPrimOp |
|---|
| 682 | Array# a -> Int# -> (# a #) |
|---|
| 683 | {Read from specified index of immutable array. Result is packaged into |
|---|
| 684 | an unboxed singleton; the result itself is not yet evaluated.} |
|---|
| 685 | with |
|---|
| 686 | can_fail = True |
|---|
| 687 | |
|---|
| 688 | primop UnsafeFreezeArrayOp "unsafeFreezeArray#" GenPrimOp |
|---|
| 689 | MutableArray# s a -> State# s -> (# State# s, Array# a #) |
|---|
| 690 | {Make a mutable array immutable, without copying.} |
|---|
| 691 | with |
|---|
| 692 | has_side_effects = True |
|---|
| 693 | |
|---|
| 694 | primop UnsafeThawArrayOp "unsafeThawArray#" GenPrimOp |
|---|
| 695 | Array# a -> State# s -> (# State# s, MutableArray# s a #) |
|---|
| 696 | {Make an immutable array mutable, without copying.} |
|---|
| 697 | with |
|---|
| 698 | out_of_line = True |
|---|
| 699 | has_side_effects = True |
|---|
| 700 | |
|---|
| 701 | primop CopyArrayOp "copyArray#" GenPrimOp |
|---|
| 702 | Array# a -> Int# -> MutableArray# s a -> Int# -> Int# -> State# s -> State# s |
|---|
| 703 | {Copy a range of the Array# to the specified region in the MutableArray#. |
|---|
| 704 | Both arrays must fully contain the specified ranges, but this is not checked. |
|---|
| 705 | The two arrays must not be the same array in different states, but this is not checked either.} |
|---|
| 706 | with |
|---|
| 707 | has_side_effects = True |
|---|
| 708 | can_fail = True |
|---|
| 709 | code_size = { primOpCodeSizeForeignCall + 4 } |
|---|
| 710 | |
|---|
| 711 | primop CopyMutableArrayOp "copyMutableArray#" GenPrimOp |
|---|
| 712 | MutableArray# s a -> Int# -> MutableArray# s a -> Int# -> Int# -> State# s -> State# s |
|---|
| 713 | {Copy a range of the first MutableArray# to the specified region in the second MutableArray#. |
|---|
| 714 | Both arrays must fully contain the specified ranges, but this is not checked.} |
|---|
| 715 | with |
|---|
| 716 | has_side_effects = True |
|---|
| 717 | can_fail = True |
|---|
| 718 | code_size = { primOpCodeSizeForeignCall + 4 } |
|---|
| 719 | |
|---|
| 720 | primop CloneArrayOp "cloneArray#" GenPrimOp |
|---|
| 721 | Array# a -> Int# -> Int# -> Array# a |
|---|
| 722 | {Return a newly allocated Array# with the specified subrange of the provided Array#. |
|---|
| 723 | The provided Array# should contain the full subrange specified by the two Int#s, but this is not checked.} |
|---|
| 724 | with |
|---|
| 725 | has_side_effects = True |
|---|
| 726 | code_size = { primOpCodeSizeForeignCall + 4 } |
|---|
| 727 | |
|---|
| 728 | primop CloneMutableArrayOp "cloneMutableArray#" GenPrimOp |
|---|
| 729 | MutableArray# s a -> Int# -> Int# -> State# s -> (# State# s, MutableArray# s a #) |
|---|
| 730 | {Return a newly allocated Array# with the specified subrange of the provided Array#. |
|---|
| 731 | The provided MutableArray# should contain the full subrange specified by the two Int#s, but this is not checked.} |
|---|
| 732 | with |
|---|
| 733 | has_side_effects = True |
|---|
| 734 | code_size = { primOpCodeSizeForeignCall + 4 } |
|---|
| 735 | |
|---|
| 736 | primop FreezeArrayOp "freezeArray#" GenPrimOp |
|---|
| 737 | MutableArray# s a -> Int# -> Int# -> State# s -> (# State# s, Array# a #) |
|---|
| 738 | {Return a newly allocated Array# with the specified subrange of the provided MutableArray#. |
|---|
| 739 | The provided MutableArray# should contain the full subrange specified by the two Int#s, but this is not checked.} |
|---|
| 740 | with |
|---|
| 741 | has_side_effects = True |
|---|
| 742 | code_size = { primOpCodeSizeForeignCall + 4 } |
|---|
| 743 | |
|---|
| 744 | primop ThawArrayOp "thawArray#" GenPrimOp |
|---|
| 745 | Array# a -> Int# -> Int# -> State# s -> (# State# s, MutableArray# s a #) |
|---|
| 746 | {Return a newly allocated Array# with the specified subrange of the provided MutableArray#. |
|---|
| 747 | The provided Array# should contain the full subrange specified by the two Int#s, but this is not checked.} |
|---|
| 748 | with |
|---|
| 749 | has_side_effects = True |
|---|
| 750 | code_size = { primOpCodeSizeForeignCall + 4 } |
|---|
| 751 | |
|---|
| 752 | ------------------------------------------------------------------------ |
|---|
| 753 | section "Byte Arrays" |
|---|
| 754 | {Operations on {\tt ByteArray\#}. A {\tt ByteArray\#} is a just a region of |
|---|
| 755 | raw memory in the garbage-collected heap, which is not |
|---|
| 756 | scanned for pointers. It carries its own size (in bytes). |
|---|
| 757 | There are |
|---|
| 758 | three sets of operations for accessing byte array contents: |
|---|
| 759 | index for reading from immutable byte arrays, and read/write |
|---|
| 760 | for mutable byte arrays. Each set contains operations for a |
|---|
| 761 | range of useful primitive data types. Each operation takes |
|---|
| 762 | an offset measured in terms of the size of the primitive type |
|---|
| 763 | being read or written.} |
|---|
| 764 | |
|---|
| 765 | ------------------------------------------------------------------------ |
|---|
| 766 | |
|---|
| 767 | primtype ByteArray# |
|---|
| 768 | |
|---|
| 769 | primtype MutableByteArray# s |
|---|
| 770 | |
|---|
| 771 | primop NewByteArrayOp_Char "newByteArray#" GenPrimOp |
|---|
| 772 | Int# -> State# s -> (# State# s, MutableByteArray# s #) |
|---|
| 773 | {Create a new mutable byte array of specified size (in bytes), in |
|---|
| 774 | the specified state thread.} |
|---|
| 775 | with out_of_line = True |
|---|
| 776 | has_side_effects = True |
|---|
| 777 | |
|---|
| 778 | primop NewPinnedByteArrayOp_Char "newPinnedByteArray#" GenPrimOp |
|---|
| 779 | Int# -> State# s -> (# State# s, MutableByteArray# s #) |
|---|
| 780 | {Create a mutable byte array that the GC guarantees not to move.} |
|---|
| 781 | with out_of_line = True |
|---|
| 782 | has_side_effects = True |
|---|
| 783 | |
|---|
| 784 | primop NewAlignedPinnedByteArrayOp_Char "newAlignedPinnedByteArray#" GenPrimOp |
|---|
| 785 | Int# -> Int# -> State# s -> (# State# s, MutableByteArray# s #) |
|---|
| 786 | {Create a mutable byte array, aligned by the specified amount, that the GC guarantees not to move.} |
|---|
| 787 | with out_of_line = True |
|---|
| 788 | has_side_effects = True |
|---|
| 789 | |
|---|
| 790 | primop ByteArrayContents_Char "byteArrayContents#" GenPrimOp |
|---|
| 791 | ByteArray# -> Addr# |
|---|
| 792 | {Intended for use with pinned arrays; otherwise very unsafe!} |
|---|
| 793 | |
|---|
| 794 | primop SameMutableByteArrayOp "sameMutableByteArray#" GenPrimOp |
|---|
| 795 | MutableByteArray# s -> MutableByteArray# s -> Bool |
|---|
| 796 | |
|---|
| 797 | primop UnsafeFreezeByteArrayOp "unsafeFreezeByteArray#" GenPrimOp |
|---|
| 798 | MutableByteArray# s -> State# s -> (# State# s, ByteArray# #) |
|---|
| 799 | {Make a mutable byte array immutable, without copying.} |
|---|
| 800 | with |
|---|
| 801 | has_side_effects = True |
|---|
| 802 | |
|---|
| 803 | primop SizeofByteArrayOp "sizeofByteArray#" GenPrimOp |
|---|
| 804 | ByteArray# -> Int# |
|---|
| 805 | {Return the size of the array in bytes.} |
|---|
| 806 | |
|---|
| 807 | primop SizeofMutableByteArrayOp "sizeofMutableByteArray#" GenPrimOp |
|---|
| 808 | MutableByteArray# s -> Int# |
|---|
| 809 | {Return the size of the array in bytes.} |
|---|
| 810 | |
|---|
| 811 | primop IndexByteArrayOp_Char "indexCharArray#" GenPrimOp |
|---|
| 812 | ByteArray# -> Int# -> Char# |
|---|
| 813 | {Read 8-bit character; offset in bytes.} |
|---|
| 814 | with can_fail = True |
|---|
| 815 | |
|---|
| 816 | primop IndexByteArrayOp_WideChar "indexWideCharArray#" GenPrimOp |
|---|
| 817 | ByteArray# -> Int# -> Char# |
|---|
| 818 | {Read 31-bit character; offset in 4-byte words.} |
|---|
| 819 | with can_fail = True |
|---|
| 820 | |
|---|
| 821 | primop IndexByteArrayOp_Int "indexIntArray#" GenPrimOp |
|---|
| 822 | ByteArray# -> Int# -> Int# |
|---|
| 823 | with can_fail = True |
|---|
| 824 | |
|---|
| 825 | primop IndexByteArrayOp_Word "indexWordArray#" GenPrimOp |
|---|
| 826 | ByteArray# -> Int# -> Word# |
|---|
| 827 | with can_fail = True |
|---|
| 828 | |
|---|
| 829 | primop IndexByteArrayOp_Addr "indexAddrArray#" GenPrimOp |
|---|
| 830 | ByteArray# -> Int# -> Addr# |
|---|
| 831 | with can_fail = True |
|---|
| 832 | |
|---|
| 833 | primop IndexByteArrayOp_Float "indexFloatArray#" GenPrimOp |
|---|
| 834 | ByteArray# -> Int# -> Float# |
|---|
| 835 | with can_fail = True |
|---|
| 836 | |
|---|
| 837 | primop IndexByteArrayOp_Double "indexDoubleArray#" GenPrimOp |
|---|
| 838 | ByteArray# -> Int# -> Double# |
|---|
| 839 | with can_fail = True |
|---|
| 840 | |
|---|
| 841 | primop IndexByteArrayOp_StablePtr "indexStablePtrArray#" GenPrimOp |
|---|
| 842 | ByteArray# -> Int# -> StablePtr# a |
|---|
| 843 | with can_fail = True |
|---|
| 844 | |
|---|
| 845 | primop IndexByteArrayOp_Int8 "indexInt8Array#" GenPrimOp |
|---|
| 846 | ByteArray# -> Int# -> Int# |
|---|
| 847 | with can_fail = True |
|---|
| 848 | |
|---|
| 849 | primop IndexByteArrayOp_Int16 "indexInt16Array#" GenPrimOp |
|---|
| 850 | ByteArray# -> Int# -> Int# |
|---|
| 851 | with can_fail = True |
|---|
| 852 | |
|---|
| 853 | primop IndexByteArrayOp_Int32 "indexInt32Array#" GenPrimOp |
|---|
| 854 | ByteArray# -> Int# -> INT32 |
|---|
| 855 | with can_fail = True |
|---|
| 856 | |
|---|
| 857 | primop IndexByteArrayOp_Int64 "indexInt64Array#" GenPrimOp |
|---|
| 858 | ByteArray# -> Int# -> INT64 |
|---|
| 859 | with can_fail = True |
|---|
| 860 | |
|---|
| 861 | primop IndexByteArrayOp_Word8 "indexWord8Array#" GenPrimOp |
|---|
| 862 | ByteArray# -> Int# -> Word# |
|---|
| 863 | with can_fail = True |
|---|
| 864 | |
|---|
| 865 | primop IndexByteArrayOp_Word16 "indexWord16Array#" GenPrimOp |
|---|
| 866 | ByteArray# -> Int# -> Word# |
|---|
| 867 | with can_fail = True |
|---|
| 868 | |
|---|
| 869 | primop IndexByteArrayOp_Word32 "indexWord32Array#" GenPrimOp |
|---|
| 870 | ByteArray# -> Int# -> WORD32 |
|---|
| 871 | with can_fail = True |
|---|
| 872 | |
|---|
| 873 | primop IndexByteArrayOp_Word64 "indexWord64Array#" GenPrimOp |
|---|
| 874 | ByteArray# -> Int# -> WORD64 |
|---|
| 875 | with can_fail = True |
|---|
| 876 | |
|---|
| 877 | primop ReadByteArrayOp_Char "readCharArray#" GenPrimOp |
|---|
| 878 | MutableByteArray# s -> Int# -> State# s -> (# State# s, Char# #) |
|---|
| 879 | {Read 8-bit character; offset in bytes.} |
|---|
| 880 | with has_side_effects = True |
|---|
| 881 | can_fail = True |
|---|
| 882 | |
|---|
| 883 | primop ReadByteArrayOp_WideChar "readWideCharArray#" GenPrimOp |
|---|
| 884 | MutableByteArray# s -> Int# -> State# s -> (# State# s, Char# #) |
|---|
| 885 | {Read 31-bit character; offset in 4-byte words.} |
|---|
| 886 | with has_side_effects = True |
|---|
| 887 | can_fail = True |
|---|
| 888 | |
|---|
| 889 | primop ReadByteArrayOp_Int "readIntArray#" GenPrimOp |
|---|
| 890 | MutableByteArray# s -> Int# -> State# s -> (# State# s, Int# #) |
|---|
| 891 | with has_side_effects = True |
|---|
| 892 | can_fail = True |
|---|
| 893 | |
|---|
| 894 | primop ReadByteArrayOp_Word "readWordArray#" GenPrimOp |
|---|
| 895 | MutableByteArray# s -> Int# -> State# s -> (# State# s, Word# #) |
|---|
| 896 | with has_side_effects = True |
|---|
| 897 | can_fail = True |
|---|
| 898 | |
|---|
| 899 | primop ReadByteArrayOp_Addr "readAddrArray#" GenPrimOp |
|---|
| 900 | MutableByteArray# s -> Int# -> State# s -> (# State# s, Addr# #) |
|---|
| 901 | with has_side_effects = True |
|---|
| 902 | can_fail = True |
|---|
| 903 | |
|---|
| 904 | primop ReadByteArrayOp_Float "readFloatArray#" GenPrimOp |
|---|
| 905 | MutableByteArray# s -> Int# -> State# s -> (# State# s, Float# #) |
|---|
| 906 | with has_side_effects = True |
|---|
| 907 | can_fail = True |
|---|
| 908 | |
|---|
| 909 | primop ReadByteArrayOp_Double "readDoubleArray#" GenPrimOp |
|---|
| 910 | MutableByteArray# s -> Int# -> State# s -> (# State# s, Double# #) |
|---|
| 911 | with has_side_effects = True |
|---|
| 912 | can_fail = True |
|---|
| 913 | |
|---|
| 914 | primop ReadByteArrayOp_StablePtr "readStablePtrArray#" GenPrimOp |
|---|
| 915 | MutableByteArray# s -> Int# -> State# s -> (# State# s, StablePtr# a #) |
|---|
| 916 | with has_side_effects = True |
|---|
| 917 | can_fail = True |
|---|
| 918 | |
|---|
| 919 | primop ReadByteArrayOp_Int8 "readInt8Array#" GenPrimOp |
|---|
| 920 | MutableByteArray# s -> Int# -> State# s -> (# State# s, Int# #) |
|---|
| 921 | with has_side_effects = True |
|---|
| 922 | can_fail = True |
|---|
| 923 | |
|---|
| 924 | primop ReadByteArrayOp_Int16 "readInt16Array#" GenPrimOp |
|---|
| 925 | MutableByteArray# s -> Int# -> State# s -> (# State# s, Int# #) |
|---|
| 926 | with has_side_effects = True |
|---|
| 927 | can_fail = True |
|---|
| 928 | |
|---|
| 929 | primop ReadByteArrayOp_Int32 "readInt32Array#" GenPrimOp |
|---|
| 930 | MutableByteArray# s -> Int# -> State# s -> (# State# s, INT32 #) |
|---|
| 931 | with has_side_effects = True |
|---|
| 932 | can_fail = True |
|---|
| 933 | |
|---|
| 934 | primop ReadByteArrayOp_Int64 "readInt64Array#" GenPrimOp |
|---|
| 935 | MutableByteArray# s -> Int# -> State# s -> (# State# s, INT64 #) |
|---|
| 936 | with has_side_effects = True |
|---|
| 937 | can_fail = True |
|---|
| 938 | |
|---|
| 939 | primop ReadByteArrayOp_Word8 "readWord8Array#" GenPrimOp |
|---|
| 940 | MutableByteArray# s -> Int# -> State# s -> (# State# s, Word# #) |
|---|
| 941 | with has_side_effects = True |
|---|
| 942 | can_fail = True |
|---|
| 943 | |
|---|
| 944 | primop ReadByteArrayOp_Word16 "readWord16Array#" GenPrimOp |
|---|
| 945 | MutableByteArray# s -> Int# -> State# s -> (# State# s, Word# #) |
|---|
| 946 | with has_side_effects = True |
|---|
| 947 | can_fail = True |
|---|
| 948 | |
|---|
| 949 | primop ReadByteArrayOp_Word32 "readWord32Array#" GenPrimOp |
|---|
| 950 | MutableByteArray# s -> Int# -> State# s -> (# State# s, WORD32 #) |
|---|
| 951 | with has_side_effects = True |
|---|
| 952 | can_fail = True |
|---|
| 953 | |
|---|
| 954 | primop ReadByteArrayOp_Word64 "readWord64Array#" GenPrimOp |
|---|
| 955 | MutableByteArray# s -> Int# -> State# s -> (# State# s, WORD64 #) |
|---|
| 956 | with has_side_effects = True |
|---|
| 957 | can_fail = True |
|---|
| 958 | |
|---|
| 959 | primop WriteByteArrayOp_Char "writeCharArray#" GenPrimOp |
|---|
| 960 | MutableByteArray# s -> Int# -> Char# -> State# s -> State# s |
|---|
| 961 | {Write 8-bit character; offset in bytes.} |
|---|
| 962 | with has_side_effects = True |
|---|
| 963 | can_fail = True |
|---|
| 964 | |
|---|
| 965 | primop WriteByteArrayOp_WideChar "writeWideCharArray#" GenPrimOp |
|---|
| 966 | MutableByteArray# s -> Int# -> Char# -> State# s -> State# s |
|---|
| 967 | {Write 31-bit character; offset in 4-byte words.} |
|---|
| 968 | with has_side_effects = True |
|---|
| 969 | can_fail = True |
|---|
| 970 | |
|---|
| 971 | primop WriteByteArrayOp_Int "writeIntArray#" GenPrimOp |
|---|
| 972 | MutableByteArray# s -> Int# -> Int# -> State# s -> State# s |
|---|
| 973 | with has_side_effects = True |
|---|
| 974 | can_fail = True |
|---|
| 975 | |
|---|
| 976 | primop WriteByteArrayOp_Word "writeWordArray#" GenPrimOp |
|---|
| 977 | MutableByteArray# s -> Int# -> Word# -> State# s -> State# s |
|---|
| 978 | with has_side_effects = True |
|---|
| 979 | can_fail = True |
|---|
| 980 | |
|---|
| 981 | primop WriteByteArrayOp_Addr "writeAddrArray#" GenPrimOp |
|---|
| 982 | MutableByteArray# s -> Int# -> Addr# -> State# s -> State# s |
|---|
| 983 | with has_side_effects = True |
|---|
| 984 | can_fail = True |
|---|
| 985 | |
|---|
| 986 | primop WriteByteArrayOp_Float "writeFloatArray#" GenPrimOp |
|---|
| 987 | MutableByteArray# s -> Int# -> Float# -> State# s -> State# s |
|---|
| 988 | with has_side_effects = True |
|---|
| 989 | can_fail = True |
|---|
| 990 | |
|---|
| 991 | primop WriteByteArrayOp_Double "writeDoubleArray#" GenPrimOp |
|---|
| 992 | MutableByteArray# s -> Int# -> Double# -> State# s -> State# s |
|---|
| 993 | with has_side_effects = True |
|---|
| 994 | can_fail = True |
|---|
| 995 | |
|---|
| 996 | primop WriteByteArrayOp_StablePtr "writeStablePtrArray#" GenPrimOp |
|---|
| 997 | MutableByteArray# s -> Int# -> StablePtr# a -> State# s -> State# s |
|---|
| 998 | with has_side_effects = True |
|---|
| 999 | can_fail = True |
|---|
| 1000 | |
|---|
| 1001 | primop WriteByteArrayOp_Int8 "writeInt8Array#" GenPrimOp |
|---|
| 1002 | MutableByteArray# s -> Int# -> Int# -> State# s -> State# s |
|---|
| 1003 | with has_side_effects = True |
|---|
| 1004 | can_fail = True |
|---|
| 1005 | |
|---|
| 1006 | primop WriteByteArrayOp_Int16 "writeInt16Array#" GenPrimOp |
|---|
| 1007 | MutableByteArray# s -> Int# -> Int# -> State# s -> State# s |
|---|
| 1008 | with has_side_effects = True |
|---|
| 1009 | can_fail = True |
|---|
| 1010 | |
|---|
| 1011 | primop WriteByteArrayOp_Int32 "writeInt32Array#" GenPrimOp |
|---|
| 1012 | MutableByteArray# s -> Int# -> INT32 -> State# s -> State# s |
|---|
| 1013 | with has_side_effects = True |
|---|
| 1014 | can_fail = True |
|---|
| 1015 | |
|---|
| 1016 | primop WriteByteArrayOp_Int64 "writeInt64Array#" GenPrimOp |
|---|
| 1017 | MutableByteArray# s -> Int# -> INT64 -> State# s -> State# s |
|---|
| 1018 | with can_fail = True |
|---|
| 1019 | has_side_effects = True |
|---|
| 1020 | |
|---|
| 1021 | primop WriteByteArrayOp_Word8 "writeWord8Array#" GenPrimOp |
|---|
| 1022 | MutableByteArray# s -> Int# -> Word# -> State# s -> State# s |
|---|
| 1023 | with has_side_effects = True |
|---|
| 1024 | can_fail = True |
|---|
| 1025 | |
|---|
| 1026 | primop WriteByteArrayOp_Word16 "writeWord16Array#" GenPrimOp |
|---|
| 1027 | MutableByteArray# s -> Int# -> Word# -> State# s -> State# s |
|---|
| 1028 | with has_side_effects = True |
|---|
| 1029 | can_fail = True |
|---|
| 1030 | |
|---|
| 1031 | primop WriteByteArrayOp_Word32 "writeWord32Array#" GenPrimOp |
|---|
| 1032 | MutableByteArray# s -> Int# -> WORD32 -> State# s -> State# s |
|---|
| 1033 | with has_side_effects = True |
|---|
| 1034 | can_fail = True |
|---|
| 1035 | |
|---|
| 1036 | primop WriteByteArrayOp_Word64 "writeWord64Array#" GenPrimOp |
|---|
| 1037 | MutableByteArray# s -> Int# -> WORD64 -> State# s -> State# s |
|---|
| 1038 | with has_side_effects = True |
|---|
| 1039 | can_fail = True |
|---|
| 1040 | |
|---|
| 1041 | primop CopyByteArrayOp "copyByteArray#" GenPrimOp |
|---|
| 1042 | ByteArray# -> Int# -> MutableByteArray# s -> Int# -> Int# -> State# s -> State# s |
|---|
| 1043 | {Copy a range of the ByteArray# to the specified region in the MutableByteArray#. |
|---|
| 1044 | Both arrays must fully contain the specified ranges, but this is not checked. |
|---|
| 1045 | The two arrays must not be the same array in different states, but this is not checked either.} |
|---|
| 1046 | with |
|---|
| 1047 | has_side_effects = True |
|---|
| 1048 | code_size = { primOpCodeSizeForeignCall + 4} |
|---|
| 1049 | can_fail = True |
|---|
| 1050 | |
|---|
| 1051 | primop CopyMutableByteArrayOp "copyMutableByteArray#" GenPrimOp |
|---|
| 1052 | MutableByteArray# s -> Int# -> MutableByteArray# s -> Int# -> Int# -> State# s -> State# s |
|---|
| 1053 | {Copy a range of the first MutableByteArray# to the specified region in the second MutableByteArray#. |
|---|
| 1054 | Both arrays must fully contain the specified ranges, but this is not checked.} |
|---|
| 1055 | with |
|---|
| 1056 | has_side_effects = True |
|---|
| 1057 | code_size = { primOpCodeSizeForeignCall + 4 } |
|---|
| 1058 | can_fail = True |
|---|
| 1059 | |
|---|
| 1060 | primop SetByteArrayOp "setByteArray#" GenPrimOp |
|---|
| 1061 | MutableByteArray# s -> Int# -> Int# -> Int# -> State# s -> State# s |
|---|
| 1062 | {Set the range of the MutableByteArray# to the specified character.} |
|---|
| 1063 | with |
|---|
| 1064 | has_side_effects = True |
|---|
| 1065 | code_size = { primOpCodeSizeForeignCall + 4 } |
|---|
| 1066 | can_fail = True |
|---|
| 1067 | |
|---|
| 1068 | ------------------------------------------------------------------------ |
|---|
| 1069 | section "Arrays of arrays" |
|---|
| 1070 | {Operations on {\tt ArrayArray\#}. An {\tt ArrayArray\#} contains references to {\em unpointed} |
|---|
| 1071 | arrays, such as {\tt ByteArray\#s}. Hence, it is not parameterised by the element types, |
|---|
| 1072 | just like a {\tt ByteArray\#}, but it needs to be scanned during GC, just like an {\tt Array#}. |
|---|
| 1073 | We represent an {\tt ArrayArray\#} exactly as a {\tt Array\#}, but provide element-type-specific |
|---|
| 1074 | indexing, reading, and writing.} |
|---|
| 1075 | ------------------------------------------------------------------------ |
|---|
| 1076 | |
|---|
| 1077 | primtype ArrayArray# |
|---|
| 1078 | |
|---|
| 1079 | primtype MutableArrayArray# s |
|---|
| 1080 | |
|---|
| 1081 | primop NewArrayArrayOp "newArrayArray#" GenPrimOp |
|---|
| 1082 | Int# -> State# s -> (# State# s, MutableArrayArray# s #) |
|---|
| 1083 | {Create a new mutable array of arrays with the specified number of elements, |
|---|
| 1084 | in the specified state thread, with each element recursively referring to the |
|---|
| 1085 | newly created array.} |
|---|
| 1086 | with |
|---|
| 1087 | out_of_line = True |
|---|
| 1088 | has_side_effects = True |
|---|
| 1089 | |
|---|
| 1090 | primop SameMutableArrayArrayOp "sameMutableArrayArray#" GenPrimOp |
|---|
| 1091 | MutableArrayArray# s -> MutableArrayArray# s -> Bool |
|---|
| 1092 | |
|---|
| 1093 | primop UnsafeFreezeArrayArrayOp "unsafeFreezeArrayArray#" GenPrimOp |
|---|
| 1094 | MutableArrayArray# s -> State# s -> (# State# s, ArrayArray# #) |
|---|
| 1095 | {Make a mutable array of arrays immutable, without copying.} |
|---|
| 1096 | with |
|---|
| 1097 | has_side_effects = True |
|---|
| 1098 | |
|---|
| 1099 | primop SizeofArrayArrayOp "sizeofArrayArray#" GenPrimOp |
|---|
| 1100 | ArrayArray# -> Int# |
|---|
| 1101 | {Return the number of elements in the array.} |
|---|
| 1102 | |
|---|
| 1103 | primop SizeofMutableArrayArrayOp "sizeofMutableArrayArray#" GenPrimOp |
|---|
| 1104 | MutableArrayArray# s -> Int# |
|---|
| 1105 | {Return the number of elements in the array.} |
|---|
| 1106 | |
|---|
| 1107 | primop IndexArrayArrayOp_ByteArray "indexByteArrayArray#" GenPrimOp |
|---|
| 1108 | ArrayArray# -> Int# -> ByteArray# |
|---|
| 1109 | with can_fail = True |
|---|
| 1110 | |
|---|
| 1111 | primop IndexArrayArrayOp_ArrayArray "indexArrayArrayArray#" GenPrimOp |
|---|
| 1112 | ArrayArray# -> Int# -> ArrayArray# |
|---|
| 1113 | with can_fail = True |
|---|
| 1114 | |
|---|
| 1115 | primop ReadArrayArrayOp_ByteArray "readByteArrayArray#" GenPrimOp |
|---|
| 1116 | MutableArrayArray# s -> Int# -> State# s -> (# State# s, ByteArray# #) |
|---|
| 1117 | with has_side_effects = True |
|---|
| 1118 | can_fail = True |
|---|
| 1119 | |
|---|
| 1120 | primop ReadArrayArrayOp_MutableByteArray "readMutableByteArrayArray#" GenPrimOp |
|---|
| 1121 | MutableArrayArray# s -> Int# -> State# s -> (# State# s, MutableByteArray# s #) |
|---|
| 1122 | with has_side_effects = True |
|---|
| 1123 | can_fail = True |
|---|
| 1124 | |
|---|
| 1125 | primop ReadArrayArrayOp_ArrayArray "readArrayArrayArray#" GenPrimOp |
|---|
| 1126 | MutableArrayArray# s -> Int# -> State# s -> (# State# s, ArrayArray# #) |
|---|
| 1127 | with has_side_effects = True |
|---|
| 1128 | can_fail = True |
|---|
| 1129 | |
|---|
| 1130 | primop ReadArrayArrayOp_MutableArrayArray "readMutableArrayArrayArray#" GenPrimOp |
|---|
| 1131 | MutableArrayArray# s -> Int# -> State# s -> (# State# s, MutableArrayArray# s #) |
|---|
| 1132 | with has_side_effects = True |
|---|
| 1133 | can_fail = True |
|---|
| 1134 | |
|---|
| 1135 | primop WriteArrayArrayOp_ByteArray "writeByteArrayArray#" GenPrimOp |
|---|
| 1136 | MutableArrayArray# s -> Int# -> ByteArray# -> State# s -> State# s |
|---|
| 1137 | with has_side_effects = True |
|---|
| 1138 | can_fail = True |
|---|
| 1139 | |
|---|
| 1140 | primop WriteArrayArrayOp_MutableByteArray "writeMutableByteArrayArray#" GenPrimOp |
|---|
| 1141 | MutableArrayArray# s -> Int# -> MutableByteArray# s -> State# s -> State# s |
|---|
| 1142 | with has_side_effects = True |
|---|
| 1143 | can_fail = True |
|---|
| 1144 | |
|---|
| 1145 | primop WriteArrayArrayOp_ArrayArray "writeArrayArrayArray#" GenPrimOp |
|---|
| 1146 | MutableArrayArray# s -> Int# -> ArrayArray# -> State# s -> State# s |
|---|
| 1147 | with has_side_effects = True |
|---|
| 1148 | can_fail = True |
|---|
| 1149 | |
|---|
| 1150 | primop WriteArrayArrayOp_MutableArrayArray "writeMutableArrayArrayArray#" GenPrimOp |
|---|
| 1151 | MutableArrayArray# s -> Int# -> MutableArrayArray# s -> State# s -> State# s |
|---|
| 1152 | with has_side_effects = True |
|---|
| 1153 | can_fail = True |
|---|
| 1154 | |
|---|
| 1155 | primop CopyArrayArrayOp "copyArrayArray#" GenPrimOp |
|---|
| 1156 | ArrayArray# -> Int# -> MutableArrayArray# s -> Int# -> Int# -> State# s -> State# s |
|---|
| 1157 | {Copy a range of the ArrayArray# to the specified region in the MutableArrayArray#. |
|---|
| 1158 | Both arrays must fully contain the specified ranges, but this is not checked. |
|---|
| 1159 | The two arrays must not be the same array in different states, but this is not checked either.} |
|---|
| 1160 | with |
|---|
| 1161 | has_side_effects = True |
|---|
| 1162 | can_fail = True |
|---|
| 1163 | code_size = { primOpCodeSizeForeignCall } |
|---|
| 1164 | |
|---|
| 1165 | primop CopyMutableArrayArrayOp "copyMutableArrayArray#" GenPrimOp |
|---|
| 1166 | MutableArrayArray# s -> Int# -> MutableArrayArray# s -> Int# -> Int# -> State# s -> State# s |
|---|
| 1167 | {Copy a range of the first MutableArrayArray# to the specified region in the second |
|---|
| 1168 | MutableArrayArray#. |
|---|
| 1169 | Both arrays must fully contain the specified ranges, but this is not checked.} |
|---|
| 1170 | with |
|---|
| 1171 | has_side_effects = True |
|---|
| 1172 | code_size = { primOpCodeSizeForeignCall } |
|---|
| 1173 | can_fail = True |
|---|
| 1174 | |
|---|
| 1175 | ------------------------------------------------------------------------ |
|---|
| 1176 | section "Addr#" |
|---|
| 1177 | ------------------------------------------------------------------------ |
|---|
| 1178 | |
|---|
| 1179 | primtype Addr# |
|---|
| 1180 | { An arbitrary machine address assumed to point outside |
|---|
| 1181 | the garbage-collected heap. } |
|---|
| 1182 | |
|---|
| 1183 | pseudoop "nullAddr#" Addr# |
|---|
| 1184 | { The null address. } |
|---|
| 1185 | |
|---|
| 1186 | primop AddrAddOp "plusAddr#" GenPrimOp Addr# -> Int# -> Addr# |
|---|
| 1187 | primop AddrSubOp "minusAddr#" GenPrimOp Addr# -> Addr# -> Int# |
|---|
| 1188 | {Result is meaningless if two {\tt Addr\#}s are so far apart that their |
|---|
| 1189 | difference doesn't fit in an {\tt Int\#}.} |
|---|
| 1190 | primop AddrRemOp "remAddr#" GenPrimOp Addr# -> Int# -> Int# |
|---|
| 1191 | {Return the remainder when the {\tt Addr\#} arg, treated like an {\tt Int\#}, |
|---|
| 1192 | is divided by the {\tt Int\#} arg.} |
|---|
| 1193 | #if (WORD_SIZE_IN_BITS == 32 || WORD_SIZE_IN_BITS == 64) |
|---|
| 1194 | primop Addr2IntOp "addr2Int#" GenPrimOp Addr# -> Int# |
|---|
| 1195 | {Coerce directly from address to int. Strongly deprecated.} |
|---|
| 1196 | with code_size = 0 |
|---|
| 1197 | primop Int2AddrOp "int2Addr#" GenPrimOp Int# -> Addr# |
|---|
| 1198 | {Coerce directly from int to address. Strongly deprecated.} |
|---|
| 1199 | with code_size = 0 |
|---|
| 1200 | #endif |
|---|
| 1201 | |
|---|
| 1202 | primop AddrGtOp "gtAddr#" Compare Addr# -> Addr# -> Bool |
|---|
| 1203 | primop AddrGeOp "geAddr#" Compare Addr# -> Addr# -> Bool |
|---|
| 1204 | primop AddrEqOp "eqAddr#" Compare Addr# -> Addr# -> Bool |
|---|
| 1205 | primop AddrNeOp "neAddr#" Compare Addr# -> Addr# -> Bool |
|---|
| 1206 | primop AddrLtOp "ltAddr#" Compare Addr# -> Addr# -> Bool |
|---|
| 1207 | primop AddrLeOp "leAddr#" Compare Addr# -> Addr# -> Bool |
|---|
| 1208 | |
|---|
| 1209 | primop IndexOffAddrOp_Char "indexCharOffAddr#" GenPrimOp |
|---|
| 1210 | Addr# -> Int# -> Char# |
|---|
| 1211 | {Reads 8-bit character; offset in bytes.} |
|---|
| 1212 | with can_fail = True |
|---|
| 1213 | |
|---|
| 1214 | primop IndexOffAddrOp_WideChar "indexWideCharOffAddr#" GenPrimOp |
|---|
| 1215 | Addr# -> Int# -> Char# |
|---|
| 1216 | {Reads 31-bit character; offset in 4-byte words.} |
|---|
| 1217 | with can_fail = True |
|---|
| 1218 | |
|---|
| 1219 | primop IndexOffAddrOp_Int "indexIntOffAddr#" GenPrimOp |
|---|
| 1220 | Addr# -> Int# -> Int# |
|---|
| 1221 | with can_fail = True |
|---|
| 1222 | |
|---|
| 1223 | primop IndexOffAddrOp_Word "indexWordOffAddr#" GenPrimOp |
|---|
| 1224 | Addr# -> Int# -> Word# |
|---|
| 1225 | with can_fail = True |
|---|
| 1226 | |
|---|
| 1227 | primop IndexOffAddrOp_Addr "indexAddrOffAddr#" GenPrimOp |
|---|
| 1228 | Addr# -> Int# -> Addr# |
|---|
| 1229 | with can_fail = True |
|---|
| 1230 | |
|---|
| 1231 | primop IndexOffAddrOp_Float "indexFloatOffAddr#" GenPrimOp |
|---|
| 1232 | Addr# -> Int# -> Float# |
|---|
| 1233 | with can_fail = True |
|---|
| 1234 | |
|---|
| 1235 | primop IndexOffAddrOp_Double "indexDoubleOffAddr#" GenPrimOp |
|---|
| 1236 | Addr# -> Int# -> Double# |
|---|
| 1237 | with can_fail = True |
|---|
| 1238 | |
|---|
| 1239 | primop IndexOffAddrOp_StablePtr "indexStablePtrOffAddr#" GenPrimOp |
|---|
| 1240 | Addr# -> Int# -> StablePtr# a |
|---|
| 1241 | with can_fail = True |
|---|
| 1242 | |
|---|
| 1243 | primop IndexOffAddrOp_Int8 "indexInt8OffAddr#" GenPrimOp |
|---|
| 1244 | Addr# -> Int# -> Int# |
|---|
| 1245 | with can_fail = True |
|---|
| 1246 | |
|---|
| 1247 | primop IndexOffAddrOp_Int16 "indexInt16OffAddr#" GenPrimOp |
|---|
| 1248 | Addr# -> Int# -> Int# |
|---|
| 1249 | with can_fail = True |
|---|
| 1250 | |
|---|
| 1251 | primop IndexOffAddrOp_Int32 "indexInt32OffAddr#" GenPrimOp |
|---|
| 1252 | Addr# -> Int# -> INT32 |
|---|
| 1253 | with can_fail = True |
|---|
| 1254 | |
|---|
| 1255 | primop IndexOffAddrOp_Int64 "indexInt64OffAddr#" GenPrimOp |
|---|
| 1256 | Addr# -> Int# -> INT64 |
|---|
| 1257 | with can_fail = True |
|---|
| 1258 | |
|---|
| 1259 | primop IndexOffAddrOp_Word8 "indexWord8OffAddr#" GenPrimOp |
|---|
| 1260 | Addr# -> Int# -> Word# |
|---|
| 1261 | with can_fail = True |
|---|
| 1262 | |
|---|
| 1263 | primop IndexOffAddrOp_Word16 "indexWord16OffAddr#" GenPrimOp |
|---|
| 1264 | Addr# -> Int# -> Word# |
|---|
| 1265 | with can_fail = True |
|---|
| 1266 | |
|---|
| 1267 | primop IndexOffAddrOp_Word32 "indexWord32OffAddr#" GenPrimOp |
|---|
| 1268 | Addr# -> Int# -> WORD32 |
|---|
| 1269 | with can_fail = True |
|---|
| 1270 | |
|---|
| 1271 | primop IndexOffAddrOp_Word64 "indexWord64OffAddr#" GenPrimOp |
|---|
| 1272 | Addr# -> Int# -> WORD64 |
|---|
| 1273 | with can_fail = True |
|---|
| 1274 | |
|---|
| 1275 | primop ReadOffAddrOp_Char "readCharOffAddr#" GenPrimOp |
|---|
| 1276 | Addr# -> Int# -> State# s -> (# State# s, Char# #) |
|---|
| 1277 | {Reads 8-bit character; offset in bytes.} |
|---|
| 1278 | with has_side_effects = True |
|---|
| 1279 | can_fail = True |
|---|
| 1280 | |
|---|
| 1281 | primop ReadOffAddrOp_WideChar "readWideCharOffAddr#" GenPrimOp |
|---|
| 1282 | Addr# -> Int# -> State# s -> (# State# s, Char# #) |
|---|
| 1283 | {Reads 31-bit character; offset in 4-byte words.} |
|---|
| 1284 | with has_side_effects = True |
|---|
| 1285 | can_fail = True |
|---|
| 1286 | |
|---|
| 1287 | primop ReadOffAddrOp_Int "readIntOffAddr#" GenPrimOp |
|---|
| 1288 | Addr# -> Int# -> State# s -> (# State# s, Int# #) |
|---|
| 1289 | with has_side_effects = True |
|---|
| 1290 | can_fail = True |
|---|
| 1291 | |
|---|
| 1292 | primop ReadOffAddrOp_Word "readWordOffAddr#" GenPrimOp |
|---|
| 1293 | Addr# -> Int# -> State# s -> (# State# s, Word# #) |
|---|
| 1294 | with has_side_effects = True |
|---|
| 1295 | can_fail = True |
|---|
| 1296 | |
|---|
| 1297 | primop ReadOffAddrOp_Addr "readAddrOffAddr#" GenPrimOp |
|---|
| 1298 | Addr# -> Int# -> State# s -> (# State# s, Addr# #) |
|---|
| 1299 | with has_side_effects = True |
|---|
| 1300 | can_fail = True |
|---|
| 1301 | |
|---|
| 1302 | primop ReadOffAddrOp_Float "readFloatOffAddr#" GenPrimOp |
|---|
| 1303 | Addr# -> Int# -> State# s -> (# State# s, Float# #) |
|---|
| 1304 | with has_side_effects = True |
|---|
| 1305 | can_fail = True |
|---|
| 1306 | |
|---|
| 1307 | primop ReadOffAddrOp_Double "readDoubleOffAddr#" GenPrimOp |
|---|
| 1308 | Addr# -> Int# -> State# s -> (# State# s, Double# #) |
|---|
| 1309 | with has_side_effects = True |
|---|
| 1310 | can_fail = True |
|---|
| 1311 | |
|---|
| 1312 | primop ReadOffAddrOp_StablePtr "readStablePtrOffAddr#" GenPrimOp |
|---|
| 1313 | Addr# -> Int# -> State# s -> (# State# s, StablePtr# a #) |
|---|
| 1314 | with has_side_effects = True |
|---|
| 1315 | can_fail = True |
|---|
| 1316 | |
|---|
| 1317 | primop ReadOffAddrOp_Int8 "readInt8OffAddr#" GenPrimOp |
|---|
| 1318 | Addr# -> Int# -> State# s -> (# State# s, Int# #) |
|---|
| 1319 | with has_side_effects = True |
|---|
| 1320 | can_fail = True |
|---|
| 1321 | |
|---|
| 1322 | primop ReadOffAddrOp_Int16 "readInt16OffAddr#" GenPrimOp |
|---|
| 1323 | Addr# -> Int# -> State# s -> (# State# s, Int# #) |
|---|
| 1324 | with has_side_effects = True |
|---|
| 1325 | can_fail = True |
|---|
| 1326 | |
|---|
| 1327 | primop ReadOffAddrOp_Int32 "readInt32OffAddr#" GenPrimOp |
|---|
| 1328 | Addr# -> Int# -> State# s -> (# State# s, INT32 #) |
|---|
| 1329 | with has_side_effects = True |
|---|
| 1330 | can_fail = True |
|---|
| 1331 | |
|---|
| 1332 | primop ReadOffAddrOp_Int64 "readInt64OffAddr#" GenPrimOp |
|---|
| 1333 | Addr# -> Int# -> State# s -> (# State# s, INT64 #) |
|---|
| 1334 | with has_side_effects = True |
|---|
| 1335 | can_fail = True |
|---|
| 1336 | |
|---|
| 1337 | primop ReadOffAddrOp_Word8 "readWord8OffAddr#" GenPrimOp |
|---|
| 1338 | Addr# -> Int# -> State# s -> (# State# s, Word# #) |
|---|
| 1339 | with has_side_effects = True |
|---|
| 1340 | can_fail = True |
|---|
| 1341 | |
|---|
| 1342 | primop ReadOffAddrOp_Word16 "readWord16OffAddr#" GenPrimOp |
|---|
| 1343 | Addr# -> Int# -> State# s -> (# State# s, Word# #) |
|---|
| 1344 | with has_side_effects = True |
|---|
| 1345 | can_fail = True |
|---|
| 1346 | |
|---|
| 1347 | primop ReadOffAddrOp_Word32 "readWord32OffAddr#" GenPrimOp |
|---|
| 1348 | Addr# -> Int# -> State# s -> (# State# s, WORD32 #) |
|---|
| 1349 | with has_side_effects = True |
|---|
| 1350 | can_fail = True |
|---|
| 1351 | |
|---|
| 1352 | primop ReadOffAddrOp_Word64 "readWord64OffAddr#" GenPrimOp |
|---|
| 1353 | Addr# -> Int# -> State# s -> (# State# s, WORD64 #) |
|---|
| 1354 | with has_side_effects = True |
|---|
| 1355 | can_fail = True |
|---|
| 1356 | |
|---|
| 1357 | primop WriteOffAddrOp_Char "writeCharOffAddr#" GenPrimOp |
|---|
| 1358 | Addr# -> Int# -> Char# -> State# s -> State# s |
|---|
| 1359 | with has_side_effects = True |
|---|
| 1360 | can_fail = True |
|---|
| 1361 | |
|---|
| 1362 | primop WriteOffAddrOp_WideChar "writeWideCharOffAddr#" GenPrimOp |
|---|
| 1363 | Addr# -> Int# -> Char# -> State# s -> State# s |
|---|
| 1364 | with has_side_effects = True |
|---|
| 1365 | can_fail = True |
|---|
| 1366 | |
|---|
| 1367 | primop WriteOffAddrOp_Int "writeIntOffAddr#" GenPrimOp |
|---|
| 1368 | Addr# -> Int# -> Int# -> State# s -> State# s |
|---|
| 1369 | with has_side_effects = True |
|---|
| 1370 | can_fail = True |
|---|
| 1371 | |
|---|
| 1372 | primop WriteOffAddrOp_Word "writeWordOffAddr#" GenPrimOp |
|---|
| 1373 | Addr# -> Int# -> Word# -> State# s -> State# s |
|---|
| 1374 | with has_side_effects = True |
|---|
| 1375 | can_fail = True |
|---|
| 1376 | |
|---|
| 1377 | primop WriteOffAddrOp_Addr "writeAddrOffAddr#" GenPrimOp |
|---|
| 1378 | Addr# -> Int# -> Addr# -> State# s -> State# s |
|---|
| 1379 | with has_side_effects = True |
|---|
| 1380 | can_fail = True |
|---|
| 1381 | |
|---|
| 1382 | primop WriteOffAddrOp_Float "writeFloatOffAddr#" GenPrimOp |
|---|
| 1383 | Addr# -> Int# -> Float# -> State# s -> State# s |
|---|
| 1384 | with has_side_effects = True |
|---|
| 1385 | can_fail = True |
|---|
| 1386 | |
|---|
| 1387 | primop WriteOffAddrOp_Double "writeDoubleOffAddr#" GenPrimOp |
|---|
| 1388 | Addr# -> Int# -> Double# -> State# s -> State# s |
|---|
| 1389 | with has_side_effects = True |
|---|
| 1390 | can_fail = True |
|---|
| 1391 | |
|---|
| 1392 | primop WriteOffAddrOp_StablePtr "writeStablePtrOffAddr#" GenPrimOp |
|---|
| 1393 | Addr# -> Int# -> StablePtr# a -> State# s -> State# s |
|---|
| 1394 | with has_side_effects = True |
|---|
| 1395 | can_fail = True |
|---|
| 1396 | |
|---|
| 1397 | primop WriteOffAddrOp_Int8 "writeInt8OffAddr#" GenPrimOp |
|---|
| 1398 | Addr# -> Int# -> Int# -> State# s -> State# s |
|---|
| 1399 | with has_side_effects = True |
|---|
| 1400 | can_fail = True |
|---|
| 1401 | |
|---|
| 1402 | primop WriteOffAddrOp_Int16 "writeInt16OffAddr#" GenPrimOp |
|---|
| 1403 | Addr# -> Int# -> Int# -> State# s -> State# s |
|---|
| 1404 | with has_side_effects = True |
|---|
| 1405 | can_fail = True |
|---|
| 1406 | |
|---|
| 1407 | primop WriteOffAddrOp_Int32 "writeInt32OffAddr#" GenPrimOp |
|---|
| 1408 | Addr# -> Int# -> INT32 -> State# s -> State# s |
|---|
| 1409 | with has_side_effects = True |
|---|
| 1410 | can_fail = True |
|---|
| 1411 | |
|---|
| 1412 | primop WriteOffAddrOp_Int64 "writeInt64OffAddr#" GenPrimOp |
|---|
| 1413 | Addr# -> Int# -> INT64 -> State# s -> State# s |
|---|
| 1414 | with has_side_effects = True |
|---|
| 1415 | can_fail = True |
|---|
| 1416 | |
|---|
| 1417 | primop WriteOffAddrOp_Word8 "writeWord8OffAddr#" GenPrimOp |
|---|
| 1418 | Addr# -> Int# -> Word# -> State# s -> State# s |
|---|
| 1419 | with has_side_effects = True |
|---|
| 1420 | can_fail = True |
|---|
| 1421 | |
|---|
| 1422 | primop WriteOffAddrOp_Word16 "writeWord16OffAddr#" GenPrimOp |
|---|
| 1423 | Addr# -> Int# -> Word# -> State# s -> State# s |
|---|
| 1424 | with has_side_effects = True |
|---|
| 1425 | can_fail = True |
|---|
| 1426 | |
|---|
| 1427 | primop WriteOffAddrOp_Word32 "writeWord32OffAddr#" GenPrimOp |
|---|
| 1428 | Addr# -> Int# -> WORD32 -> State# s -> State# s |
|---|
| 1429 | with has_side_effects = True |
|---|
| 1430 | can_fail = True |
|---|
| 1431 | |
|---|
| 1432 | primop WriteOffAddrOp_Word64 "writeWord64OffAddr#" GenPrimOp |
|---|
| 1433 | Addr# -> Int# -> WORD64 -> State# s -> State# s |
|---|
| 1434 | with has_side_effects = True |
|---|
| 1435 | can_fail = True |
|---|
| 1436 | |
|---|
| 1437 | ------------------------------------------------------------------------ |
|---|
| 1438 | section "Mutable variables" |
|---|
| 1439 | {Operations on MutVar\#s.} |
|---|
| 1440 | ------------------------------------------------------------------------ |
|---|
| 1441 | |
|---|
| 1442 | primtype MutVar# s a |
|---|
| 1443 | {A {\tt MutVar\#} behaves like a single-element mutable array.} |
|---|
| 1444 | |
|---|
| 1445 | primop NewMutVarOp "newMutVar#" GenPrimOp |
|---|
| 1446 | a -> State# s -> (# State# s, MutVar# s a #) |
|---|
| 1447 | {Create {\tt MutVar\#} with specified initial value in specified state thread.} |
|---|
| 1448 | with |
|---|
| 1449 | out_of_line = True |
|---|
| 1450 | has_side_effects = True |
|---|
| 1451 | |
|---|
| 1452 | primop ReadMutVarOp "readMutVar#" GenPrimOp |
|---|
| 1453 | MutVar# s a -> State# s -> (# State# s, a #) |
|---|
| 1454 | {Read contents of {\tt MutVar\#}. Result is not yet evaluated.} |
|---|
| 1455 | with |
|---|
| 1456 | has_side_effects = True |
|---|
| 1457 | can_fail = True |
|---|
| 1458 | |
|---|
| 1459 | primop WriteMutVarOp "writeMutVar#" GenPrimOp |
|---|
| 1460 | MutVar# s a -> a -> State# s -> State# s |
|---|
| 1461 | {Write contents of {\tt MutVar\#}.} |
|---|
| 1462 | with |
|---|
| 1463 | has_side_effects = True |
|---|
| 1464 | code_size = { primOpCodeSizeForeignCall } -- for the write barrier |
|---|
| 1465 | can_fail = True |
|---|
| 1466 | |
|---|
| 1467 | primop SameMutVarOp "sameMutVar#" GenPrimOp |
|---|
| 1468 | MutVar# s a -> MutVar# s a -> Bool |
|---|
| 1469 | |
|---|
| 1470 | -- not really the right type, but we don't know about pairs here. The |
|---|
| 1471 | -- correct type is |
|---|
| 1472 | -- |
|---|
| 1473 | -- MutVar# s a -> (a -> (a,b)) -> State# s -> (# State# s, b #) |
|---|
| 1474 | -- |
|---|
| 1475 | primop AtomicModifyMutVarOp "atomicModifyMutVar#" GenPrimOp |
|---|
| 1476 | MutVar# s a -> (a -> b) -> State# s -> (# State# s, c #) |
|---|
| 1477 | with |
|---|
| 1478 | out_of_line = True |
|---|
| 1479 | has_side_effects = True |
|---|
| 1480 | can_fail = True |
|---|
| 1481 | |
|---|
| 1482 | primop CasMutVarOp "casMutVar#" GenPrimOp |
|---|
| 1483 | MutVar# s a -> a -> a -> State# s -> (# State# s, Int#, a #) |
|---|
| 1484 | with |
|---|
| 1485 | out_of_line = True |
|---|
| 1486 | has_side_effects = True |
|---|
| 1487 | |
|---|
| 1488 | ------------------------------------------------------------------------ |
|---|
| 1489 | section "Exceptions" |
|---|
| 1490 | ------------------------------------------------------------------------ |
|---|
| 1491 | |
|---|
| 1492 | primop CatchOp "catch#" GenPrimOp |
|---|
| 1493 | (State# RealWorld -> (# State# RealWorld, a #) ) |
|---|
| 1494 | -> (b -> State# RealWorld -> (# State# RealWorld, a #) ) |
|---|
| 1495 | -> State# RealWorld |
|---|
| 1496 | -> (# State# RealWorld, a #) |
|---|
| 1497 | with |
|---|
| 1498 | -- Catch is actually strict in its first argument |
|---|
| 1499 | -- but we don't want to tell the strictness |
|---|
| 1500 | -- analyser about that! |
|---|
| 1501 | -- might use caught action multiply |
|---|
| 1502 | out_of_line = True |
|---|
| 1503 | has_side_effects = True |
|---|
| 1504 | |
|---|
| 1505 | primop RaiseOp "raise#" GenPrimOp |
|---|
| 1506 | a -> b |
|---|
| 1507 | with |
|---|
| 1508 | strictness = { \ _arity -> mkStrictSig (mkTopDmdType [lazyDmd] BotRes) } |
|---|
| 1509 | -- NB: result is bottom |
|---|
| 1510 | out_of_line = True |
|---|
| 1511 | |
|---|
| 1512 | -- raiseIO# needs to be a primop, because exceptions in the IO monad |
|---|
| 1513 | -- must be *precise* - we don't want the strictness analyser turning |
|---|
| 1514 | -- one kind of bottom into another, as it is allowed to do in pure code. |
|---|
| 1515 | -- |
|---|
| 1516 | -- But we *do* want to know that it returns bottom after |
|---|
| 1517 | -- being applied to two arguments, so that this function is strict in y |
|---|
| 1518 | -- f x y | x>0 = raiseIO blah |
|---|
| 1519 | -- | y>0 = return 1 |
|---|
| 1520 | -- | otherwise = return 2 |
|---|
| 1521 | |
|---|
| 1522 | primop RaiseIOOp "raiseIO#" GenPrimOp |
|---|
| 1523 | a -> State# RealWorld -> (# State# RealWorld, b #) |
|---|
| 1524 | with |
|---|
| 1525 | strictness = { \ _arity -> mkStrictSig (mkTopDmdType [lazyDmd,lazyDmd] BotRes) } |
|---|
| 1526 | out_of_line = True |
|---|
| 1527 | has_side_effects = True |
|---|
| 1528 | |
|---|
| 1529 | primop MaskAsyncExceptionsOp "maskAsyncExceptions#" GenPrimOp |
|---|
| 1530 | (State# RealWorld -> (# State# RealWorld, a #)) |
|---|
| 1531 | -> (State# RealWorld -> (# State# RealWorld, a #)) |
|---|
| 1532 | with |
|---|
| 1533 | out_of_line = True |
|---|
| 1534 | has_side_effects = True |
|---|
| 1535 | |
|---|
| 1536 | primop MaskUninterruptibleOp "maskUninterruptible#" GenPrimOp |
|---|
| 1537 | (State# RealWorld -> (# State# RealWorld, a #)) |
|---|
| 1538 | -> (State# RealWorld -> (# State# RealWorld, a #)) |
|---|
| 1539 | with |
|---|
| 1540 | out_of_line = True |
|---|
| 1541 | has_side_effects = True |
|---|
| 1542 | |
|---|
| 1543 | primop UnmaskAsyncExceptionsOp "unmaskAsyncExceptions#" GenPrimOp |
|---|
| 1544 | (State# RealWorld -> (# State# RealWorld, a #)) |
|---|
| 1545 | -> (State# RealWorld -> (# State# RealWorld, a #)) |
|---|
| 1546 | with |
|---|
| 1547 | out_of_line = True |
|---|
| 1548 | has_side_effects = True |
|---|
| 1549 | |
|---|
| 1550 | primop MaskStatus "getMaskingState#" GenPrimOp |
|---|
| 1551 | State# RealWorld -> (# State# RealWorld, Int# #) |
|---|
| 1552 | with |
|---|
| 1553 | out_of_line = True |
|---|
| 1554 | has_side_effects = True |
|---|
| 1555 | |
|---|
| 1556 | ------------------------------------------------------------------------ |
|---|
| 1557 | section "STM-accessible Mutable Variables" |
|---|
| 1558 | ------------------------------------------------------------------------ |
|---|
| 1559 | |
|---|
| 1560 | primtype TVar# s a |
|---|
| 1561 | |
|---|
| 1562 | primop AtomicallyOp "atomically#" GenPrimOp |
|---|
| 1563 | (State# RealWorld -> (# State# RealWorld, a #) ) |
|---|
| 1564 | -> State# RealWorld -> (# State# RealWorld, a #) |
|---|
| 1565 | with |
|---|
| 1566 | out_of_line = True |
|---|
| 1567 | has_side_effects = True |
|---|
| 1568 | |
|---|
| 1569 | primop RetryOp "retry#" GenPrimOp |
|---|
| 1570 | State# RealWorld -> (# State# RealWorld, a #) |
|---|
| 1571 | with |
|---|
| 1572 | out_of_line = True |
|---|
| 1573 | has_side_effects = True |
|---|
| 1574 | |
|---|
| 1575 | primop CatchRetryOp "catchRetry#" GenPrimOp |
|---|
| 1576 | (State# RealWorld -> (# State# RealWorld, a #) ) |
|---|
| 1577 | -> (State# RealWorld -> (# State# RealWorld, a #) ) |
|---|
| 1578 | -> (State# RealWorld -> (# State# RealWorld, a #) ) |
|---|
| 1579 | with |
|---|
| 1580 | out_of_line = True |
|---|
| 1581 | has_side_effects = True |
|---|
| 1582 | |
|---|
| 1583 | primop CatchSTMOp "catchSTM#" GenPrimOp |
|---|
| 1584 | (State# RealWorld -> (# State# RealWorld, a #) ) |
|---|
| 1585 | -> (b -> State# RealWorld -> (# State# RealWorld, a #) ) |
|---|
| 1586 | -> (State# RealWorld -> (# State# RealWorld, a #) ) |
|---|
| 1587 | with |
|---|
| 1588 | out_of_line = True |
|---|
| 1589 | has_side_effects = True |
|---|
| 1590 | |
|---|
| 1591 | primop Check "check#" GenPrimOp |
|---|
| 1592 | (State# RealWorld -> (# State# RealWorld, a #) ) |
|---|
| 1593 | -> (State# RealWorld -> (# State# RealWorld, () #) ) |
|---|
| 1594 | with |
|---|
| 1595 | out_of_line = True |
|---|
| 1596 | has_side_effects = True |
|---|
| 1597 | |
|---|
| 1598 | primop NewTVarOp "newTVar#" GenPrimOp |
|---|
| 1599 | a |
|---|
| 1600 | -> State# s -> (# State# s, TVar# s a #) |
|---|
| 1601 | {Create a new {\tt TVar\#} holding a specified initial value.} |
|---|
| 1602 | with |
|---|
| 1603 | out_of_line = True |
|---|
| 1604 | has_side_effects = True |
|---|
| 1605 | |
|---|
| 1606 | primop ReadTVarOp "readTVar#" GenPrimOp |
|---|
| 1607 | TVar# s a |
|---|
| 1608 | -> State# s -> (# State# s, a #) |
|---|
| 1609 | {Read contents of {\tt TVar\#}. Result is not yet evaluated.} |
|---|
| 1610 | with |
|---|
| 1611 | out_of_line = True |
|---|
| 1612 | has_side_effects = True |
|---|
| 1613 | |
|---|
| 1614 | primop ReadTVarIOOp "readTVarIO#" GenPrimOp |
|---|
| 1615 | TVar# s a |
|---|
| 1616 | -> State# s -> (# State# s, a #) |
|---|
| 1617 | {Read contents of {\tt TVar\#} outside an STM transaction} |
|---|
| 1618 | with |
|---|
| 1619 | out_of_line = True |
|---|
| 1620 | has_side_effects = True |
|---|
| 1621 | |
|---|
| 1622 | primop WriteTVarOp "writeTVar#" GenPrimOp |
|---|
| 1623 | TVar# s a |
|---|
| 1624 | -> a |
|---|
| 1625 | -> State# s -> State# s |
|---|
| 1626 | {Write contents of {\tt TVar\#}.} |
|---|
| 1627 | with |
|---|
| 1628 | out_of_line = True |
|---|
| 1629 | has_side_effects = True |
|---|
| 1630 | |
|---|
| 1631 | primop SameTVarOp "sameTVar#" GenPrimOp |
|---|
| 1632 | TVar# s a -> TVar# s a -> Bool |
|---|
| 1633 | |
|---|
| 1634 | |
|---|
| 1635 | ------------------------------------------------------------------------ |
|---|
| 1636 | section "Synchronized Mutable Variables" |
|---|
| 1637 | {Operations on {\tt MVar\#}s. } |
|---|
| 1638 | ------------------------------------------------------------------------ |
|---|
| 1639 | |
|---|
| 1640 | primtype MVar# s a |
|---|
| 1641 | { A shared mutable variable ({\it not} the same as a {\tt MutVar\#}!). |
|---|
| 1642 | (Note: in a non-concurrent implementation, {\tt (MVar\# a)} can be |
|---|
| 1643 | represented by {\tt (MutVar\# (Maybe a))}.) } |
|---|
| 1644 | |
|---|
| 1645 | primop NewMVarOp "newMVar#" GenPrimOp |
|---|
| 1646 | State# s -> (# State# s, MVar# s a #) |
|---|
| 1647 | {Create new {\tt MVar\#}; initially empty.} |
|---|
| 1648 | with |
|---|
| 1649 | out_of_line = True |
|---|
| 1650 | has_side_effects = True |
|---|
| 1651 | |
|---|
| 1652 | primop TakeMVarOp "takeMVar#" GenPrimOp |
|---|
| 1653 | MVar# s a -> State# s -> (# State# s, a #) |
|---|
| 1654 | {If {\tt MVar\#} is empty, block until it becomes full. |
|---|
| 1655 | Then remove and return its contents, and set it empty.} |
|---|
| 1656 | with |
|---|
| 1657 | out_of_line = True |
|---|
| 1658 | has_side_effects = True |
|---|
| 1659 | |
|---|
| 1660 | primop TryTakeMVarOp "tryTakeMVar#" GenPrimOp |
|---|
| 1661 | MVar# s a -> State# s -> (# State# s, Int#, a #) |
|---|
| 1662 | {If {\tt MVar\#} is empty, immediately return with integer 0 and value undefined. |
|---|
| 1663 | Otherwise, return with integer 1 and contents of {\tt MVar\#}, and set {\tt MVar\#} empty.} |
|---|
| 1664 | with |
|---|
| 1665 | out_of_line = True |
|---|
| 1666 | has_side_effects = True |
|---|
| 1667 | |
|---|
| 1668 | primop PutMVarOp "putMVar#" GenPrimOp |
|---|
| 1669 | MVar# s a -> a -> State# s -> State# s |
|---|
| 1670 | {If {\tt MVar\#} is full, block until it becomes empty. |
|---|
| 1671 | Then store value arg as its new contents.} |
|---|
| 1672 | with |
|---|
| 1673 | out_of_line = True |
|---|
| 1674 | has_side_effects = True |
|---|
| 1675 | |
|---|
| 1676 | primop TryPutMVarOp "tryPutMVar#" GenPrimOp |
|---|
| 1677 | MVar# s a -> a -> State# s -> (# State# s, Int# #) |
|---|
| 1678 | {If {\tt MVar\#} is full, immediately return with integer 0. |
|---|
| 1679 | Otherwise, store value arg as {\tt MVar\#}'s new contents, and return with integer 1.} |
|---|
| 1680 | with |
|---|
| 1681 | out_of_line = True |
|---|
| 1682 | has_side_effects = True |
|---|
| 1683 | |
|---|
| 1684 | primop SameMVarOp "sameMVar#" GenPrimOp |
|---|
| 1685 | MVar# s a -> MVar# s a -> Bool |
|---|
| 1686 | |
|---|
| 1687 | primop IsEmptyMVarOp "isEmptyMVar#" GenPrimOp |
|---|
| 1688 | MVar# s a -> State# s -> (# State# s, Int# #) |
|---|
| 1689 | {Return 1 if {\tt MVar\#} is empty; 0 otherwise.} |
|---|
| 1690 | with |
|---|
| 1691 | out_of_line = True |
|---|
| 1692 | has_side_effects = True |
|---|
| 1693 | |
|---|
| 1694 | ------------------------------------------------------------------------ |
|---|
| 1695 | section "Delay/wait operations" |
|---|
| 1696 | ------------------------------------------------------------------------ |
|---|
| 1697 | |
|---|
| 1698 | primop DelayOp "delay#" GenPrimOp |
|---|
| 1699 | Int# -> State# s -> State# s |
|---|
| 1700 | {Sleep specified number of microseconds.} |
|---|
| 1701 | with |
|---|
| 1702 | has_side_effects = True |
|---|
| 1703 | out_of_line = True |
|---|
| 1704 | |
|---|
| 1705 | primop WaitReadOp "waitRead#" GenPrimOp |
|---|
| 1706 | Int# -> State# s -> State# s |
|---|
| 1707 | {Block until input is available on specified file descriptor.} |
|---|
| 1708 | with |
|---|
| 1709 | has_side_effects = True |
|---|
| 1710 | out_of_line = True |
|---|
| 1711 | |
|---|
| 1712 | primop WaitWriteOp "waitWrite#" GenPrimOp |
|---|
| 1713 | Int# -> State# s -> State# s |
|---|
| 1714 | {Block until output is possible on specified file descriptor.} |
|---|
| 1715 | with |
|---|
| 1716 | has_side_effects = True |
|---|
| 1717 | out_of_line = True |
|---|
| 1718 | |
|---|
| 1719 | #ifdef mingw32_TARGET_OS |
|---|
| 1720 | primop AsyncReadOp "asyncRead#" GenPrimOp |
|---|
| 1721 | Int# -> Int# -> Int# -> Addr# -> State# RealWorld-> (# State# RealWorld, Int#, Int# #) |
|---|
| 1722 | {Asynchronously read bytes from specified file descriptor.} |
|---|
| 1723 | with |
|---|
| 1724 | has_side_effects = True |
|---|
| 1725 | out_of_line = True |
|---|
| 1726 | |
|---|
| 1727 | primop AsyncWriteOp "asyncWrite#" GenPrimOp |
|---|
| 1728 | Int# -> Int# -> Int# -> Addr# -> State# RealWorld-> (# State# RealWorld, Int#, Int# #) |
|---|
| 1729 | {Asynchronously write bytes from specified file descriptor.} |
|---|
| 1730 | with |
|---|
| 1731 | has_side_effects = True |
|---|
| 1732 | out_of_line = True |
|---|
| 1733 | |
|---|
| 1734 | primop AsyncDoProcOp "asyncDoProc#" GenPrimOp |
|---|
| 1735 | Addr# -> Addr# -> State# RealWorld-> (# State# RealWorld, Int#, Int# #) |
|---|
| 1736 | {Asynchronously perform procedure (first arg), passing it 2nd arg.} |
|---|
| 1737 | with |
|---|
| 1738 | has_side_effects = True |
|---|
| 1739 | out_of_line = True |
|---|
| 1740 | |
|---|
| 1741 | #endif |
|---|
| 1742 | |
|---|
| 1743 | ------------------------------------------------------------------------ |
|---|
| 1744 | section "Concurrency primitives" |
|---|
| 1745 | ------------------------------------------------------------------------ |
|---|
| 1746 | |
|---|
| 1747 | primtype State# s |
|---|
| 1748 | { {\tt State\#} is the primitive, unlifted type of states. It has |
|---|
| 1749 | one type parameter, thus {\tt State\# RealWorld}, or {\tt State\# s}, |
|---|
| 1750 | where s is a type variable. The only purpose of the type parameter |
|---|
| 1751 | is to keep different state threads separate. It is represented by |
|---|
| 1752 | nothing at all. } |
|---|
| 1753 | |
|---|
| 1754 | primtype RealWorld |
|---|
| 1755 | { {\tt RealWorld} is deeply magical. It is {\it primitive}, but it is not |
|---|
| 1756 | {\it unlifted} (hence {\tt ptrArg}). We never manipulate values of type |
|---|
| 1757 | {\tt RealWorld}; it's only used in the type system, to parameterise {\tt State\#}. } |
|---|
| 1758 | |
|---|
| 1759 | primtype ThreadId# |
|---|
| 1760 | {(In a non-concurrent implementation, this can be a singleton |
|---|
| 1761 | type, whose (unique) value is returned by {\tt myThreadId\#}. The |
|---|
| 1762 | other operations can be omitted.)} |
|---|
| 1763 | |
|---|
| 1764 | primop ForkOp "fork#" GenPrimOp |
|---|
| 1765 | a -> State# RealWorld -> (# State# RealWorld, ThreadId# #) |
|---|
| 1766 | with |
|---|
| 1767 | has_side_effects = True |
|---|
| 1768 | out_of_line = True |
|---|
| 1769 | |
|---|
| 1770 | primop ForkOnOp "forkOn#" GenPrimOp |
|---|
| 1771 | Int# -> a -> State# RealWorld -> (# State# RealWorld, ThreadId# #) |
|---|
| 1772 | with |
|---|
| 1773 | has_side_effects = True |
|---|
| 1774 | out_of_line = True |
|---|
| 1775 | |
|---|
| 1776 | primop KillThreadOp "killThread#" GenPrimOp |
|---|
| 1777 | ThreadId# -> a -> State# RealWorld -> State# RealWorld |
|---|
| 1778 | with |
|---|
| 1779 | has_side_effects = True |
|---|
| 1780 | out_of_line = True |
|---|
| 1781 | |
|---|
| 1782 | primop YieldOp "yield#" GenPrimOp |
|---|
| 1783 | State# RealWorld -> State# RealWorld |
|---|
| 1784 | with |
|---|
| 1785 | has_side_effects = True |
|---|
| 1786 | out_of_line = True |
|---|
| 1787 | |
|---|
| 1788 | primop MyThreadIdOp "myThreadId#" GenPrimOp |
|---|
| 1789 | State# RealWorld -> (# State# RealWorld, ThreadId# #) |
|---|
| 1790 | with |
|---|
| 1791 | out_of_line = True |
|---|
| 1792 | has_side_effects = True |
|---|
| 1793 | |
|---|
| 1794 | primop LabelThreadOp "labelThread#" GenPrimOp |
|---|
| 1795 | ThreadId# -> Addr# -> State# RealWorld -> State# RealWorld |
|---|
| 1796 | with |
|---|
| 1797 | has_side_effects = True |
|---|
| 1798 | out_of_line = True |
|---|
| 1799 | |
|---|
| 1800 | primop IsCurrentThreadBoundOp "isCurrentThreadBound#" GenPrimOp |
|---|
| 1801 | State# RealWorld -> (# State# RealWorld, Int# #) |
|---|
| 1802 | with |
|---|
| 1803 | out_of_line = True |
|---|
| 1804 | has_side_effects = True |
|---|
| 1805 | |
|---|
| 1806 | primop NoDuplicateOp "noDuplicate#" GenPrimOp |
|---|
| 1807 | State# RealWorld -> State# RealWorld |
|---|
| 1808 | with |
|---|
| 1809 | out_of_line = True |
|---|
| 1810 | has_side_effects = True |
|---|
| 1811 | |
|---|
| 1812 | primop ThreadStatusOp "threadStatus#" GenPrimOp |
|---|
| 1813 | ThreadId# -> State# RealWorld -> (# State# RealWorld, Int#, Int#, Int# #) |
|---|
| 1814 | with |
|---|
| 1815 | out_of_line = True |
|---|
| 1816 | has_side_effects = True |
|---|
| 1817 | |
|---|
| 1818 | ------------------------------------------------------------------------ |
|---|
| 1819 | section "Weak pointers" |
|---|
| 1820 | ------------------------------------------------------------------------ |
|---|
| 1821 | |
|---|
| 1822 | primtype Weak# b |
|---|
| 1823 | |
|---|
| 1824 | -- note that tyvar "o" denotes openAlphaTyVar |
|---|
| 1825 | |
|---|
| 1826 | primop MkWeakOp "mkWeak#" GenPrimOp |
|---|
| 1827 | o -> b -> c -> State# RealWorld -> (# State# RealWorld, Weak# b #) |
|---|
| 1828 | with |
|---|
| 1829 | has_side_effects = True |
|---|
| 1830 | out_of_line = True |
|---|
| 1831 | |
|---|
| 1832 | primop MkWeakNoFinalizerOp "mkWeakNoFinalizer#" GenPrimOp |
|---|
| 1833 | o -> b -> State# RealWorld -> (# State# RealWorld, Weak# b #) |
|---|
| 1834 | with |
|---|
| 1835 | has_side_effects = True |
|---|
| 1836 | out_of_line = True |
|---|
| 1837 | |
|---|
| 1838 | primop MkWeakForeignEnvOp "mkWeakForeignEnv#" GenPrimOp |
|---|
| 1839 | o -> b -> Addr# -> Addr# -> Int# -> Addr# -> State# RealWorld -> (# State# RealWorld, Weak# b #) |
|---|
| 1840 | with |
|---|
| 1841 | has_side_effects = True |
|---|
| 1842 | out_of_line = True |
|---|
| 1843 | |
|---|
| 1844 | primop DeRefWeakOp "deRefWeak#" GenPrimOp |
|---|
| 1845 | Weak# a -> State# RealWorld -> (# State# RealWorld, Int#, a #) |
|---|
| 1846 | with |
|---|
| 1847 | has_side_effects = True |
|---|
| 1848 | out_of_line = True |
|---|
| 1849 | |
|---|
| 1850 | primop FinalizeWeakOp "finalizeWeak#" GenPrimOp |
|---|
| 1851 | Weak# a -> State# RealWorld -> (# State# RealWorld, Int#, |
|---|
| 1852 | (State# RealWorld -> (# State# RealWorld, () #)) #) |
|---|
| 1853 | with |
|---|
| 1854 | has_side_effects = True |
|---|
| 1855 | out_of_line = True |
|---|
| 1856 | |
|---|
| 1857 | primop TouchOp "touch#" GenPrimOp |
|---|
| 1858 | o -> State# RealWorld -> State# RealWorld |
|---|
| 1859 | with |
|---|
| 1860 | code_size = { 0 } |
|---|
| 1861 | has_side_effects = True |
|---|
| 1862 | |
|---|
| 1863 | ------------------------------------------------------------------------ |
|---|
| 1864 | section "Stable pointers and names" |
|---|
| 1865 | ------------------------------------------------------------------------ |
|---|
| 1866 | |
|---|
| 1867 | primtype StablePtr# a |
|---|
| 1868 | |
|---|
| 1869 | primtype StableName# a |
|---|
| 1870 | |
|---|
| 1871 | primop MakeStablePtrOp "makeStablePtr#" GenPrimOp |
|---|
| 1872 | a -> State# RealWorld -> (# State# RealWorld, StablePtr# a #) |
|---|
| 1873 | with |
|---|
| 1874 | has_side_effects = True |
|---|
| 1875 | out_of_line = True |
|---|
| 1876 | |
|---|
| 1877 | primop DeRefStablePtrOp "deRefStablePtr#" GenPrimOp |
|---|
| 1878 | StablePtr# a -> State# RealWorld -> (# State# RealWorld, a #) |
|---|
| 1879 | with |
|---|
| 1880 | has_side_effects = True |
|---|
| 1881 | out_of_line = True |
|---|
| 1882 | |
|---|
| 1883 | primop EqStablePtrOp "eqStablePtr#" GenPrimOp |
|---|
| 1884 | StablePtr# a -> StablePtr# a -> Int# |
|---|
| 1885 | with |
|---|
| 1886 | has_side_effects = True |
|---|
| 1887 | |
|---|
| 1888 | primop MakeStableNameOp "makeStableName#" GenPrimOp |
|---|
| 1889 | a -> State# RealWorld -> (# State# RealWorld, StableName# a #) |
|---|
| 1890 | with |
|---|
| 1891 | has_side_effects = True |
|---|
| 1892 | out_of_line = True |
|---|
| 1893 | |
|---|
| 1894 | primop EqStableNameOp "eqStableName#" GenPrimOp |
|---|
| 1895 | StableName# a -> StableName# a -> Int# |
|---|
| 1896 | |
|---|
| 1897 | primop StableNameToIntOp "stableNameToInt#" GenPrimOp |
|---|
| 1898 | StableName# a -> Int# |
|---|
| 1899 | |
|---|
| 1900 | ------------------------------------------------------------------------ |
|---|
| 1901 | section "Unsafe pointer equality" |
|---|
| 1902 | -- (#1 Bad Guy: Alistair Reid :) |
|---|
| 1903 | ------------------------------------------------------------------------ |
|---|
| 1904 | |
|---|
| 1905 | primop ReallyUnsafePtrEqualityOp "reallyUnsafePtrEquality#" GenPrimOp |
|---|
| 1906 | a -> a -> Int# |
|---|
| 1907 | |
|---|
| 1908 | ------------------------------------------------------------------------ |
|---|
| 1909 | section "Parallelism" |
|---|
| 1910 | ------------------------------------------------------------------------ |
|---|
| 1911 | |
|---|
| 1912 | primop ParOp "par#" GenPrimOp |
|---|
| 1913 | a -> Int# |
|---|
| 1914 | with |
|---|
| 1915 | -- Note that Par is lazy to avoid that the sparked thing |
|---|
| 1916 | -- gets evaluted strictly, which it should *not* be |
|---|
| 1917 | has_side_effects = True |
|---|
| 1918 | code_size = { primOpCodeSizeForeignCall } |
|---|
| 1919 | |
|---|
| 1920 | primop SparkOp "spark#" GenPrimOp |
|---|
| 1921 | a -> State# s -> (# State# s, a #) |
|---|
| 1922 | with has_side_effects = True |
|---|
| 1923 | code_size = { primOpCodeSizeForeignCall } |
|---|
| 1924 | |
|---|
| 1925 | primop SeqOp "seq#" GenPrimOp |
|---|
| 1926 | a -> State# s -> (# State# s, a #) |
|---|
| 1927 | |
|---|
| 1928 | -- why return the value? So that we can control sharing of seq'd |
|---|
| 1929 | -- values: in |
|---|
| 1930 | -- let x = e in x `seq` ... x ... |
|---|
| 1931 | -- we don't want to inline x, so better to represent it as |
|---|
| 1932 | -- let x = e in case seq# x RW of (# _, x' #) -> ... x' ... |
|---|
| 1933 | -- also it matches the type of rseq in the Eval monad. |
|---|
| 1934 | |
|---|
| 1935 | primop GetSparkOp "getSpark#" GenPrimOp |
|---|
| 1936 | State# s -> (# State# s, Int#, a #) |
|---|
| 1937 | with |
|---|
| 1938 | has_side_effects = True |
|---|
| 1939 | out_of_line = True |
|---|
| 1940 | |
|---|
| 1941 | primop NumSparks "numSparks#" GenPrimOp |
|---|
| 1942 | State# s -> (# State# s, Int# #) |
|---|
| 1943 | { Returns the number of sparks in the local spark pool. } |
|---|
| 1944 | with |
|---|
| 1945 | has_side_effects = True |
|---|
| 1946 | out_of_line = True |
|---|
| 1947 | |
|---|
| 1948 | -- HWL: The first 4 Int# in all par... annotations denote: |
|---|
| 1949 | -- name, granularity info, size of result, degree of parallelism |
|---|
| 1950 | -- Same structure as _seq_ i.e. returns Int# |
|---|
| 1951 | -- KSW: v, the second arg in parAt# and parAtForNow#, is used only to determine |
|---|
| 1952 | -- `the processor containing the expression v'; it is not evaluated |
|---|
| 1953 | |
|---|
| 1954 | primop ParGlobalOp "parGlobal#" GenPrimOp |
|---|
| 1955 | a -> Int# -> Int# -> Int# -> Int# -> b -> Int# |
|---|
| 1956 | with |
|---|
| 1957 | has_side_effects = True |
|---|
| 1958 | |
|---|
| 1959 | primop ParLocalOp "parLocal#" GenPrimOp |
|---|
| 1960 | a -> Int# -> Int# -> Int# -> Int# -> b -> Int# |
|---|
| 1961 | with |
|---|
| 1962 | has_side_effects = True |
|---|
| 1963 | |
|---|
| 1964 | primop ParAtOp "parAt#" GenPrimOp |
|---|
| 1965 | b -> a -> Int# -> Int# -> Int# -> Int# -> c -> Int# |
|---|
| 1966 | with |
|---|
| 1967 | has_side_effects = True |
|---|
| 1968 | |
|---|
| 1969 | primop ParAtAbsOp "parAtAbs#" GenPrimOp |
|---|
| 1970 | a -> Int# -> Int# -> Int# -> Int# -> Int# -> b -> Int# |
|---|
| 1971 | with |
|---|
| 1972 | has_side_effects = True |
|---|
| 1973 | |
|---|
| 1974 | primop ParAtRelOp "parAtRel#" GenPrimOp |
|---|
| 1975 | a -> Int# -> Int# -> Int# -> Int# -> Int# -> b -> Int# |
|---|
| 1976 | with |
|---|
| 1977 | has_side_effects = True |
|---|
| 1978 | |
|---|
| 1979 | primop ParAtForNowOp "parAtForNow#" GenPrimOp |
|---|
| 1980 | b -> a -> Int# -> Int# -> Int# -> Int# -> c -> Int# |
|---|
| 1981 | with |
|---|
| 1982 | has_side_effects = True |
|---|
| 1983 | |
|---|
| 1984 | -- copyable# and noFollow# are yet to be implemented (for GpH) |
|---|
| 1985 | -- |
|---|
| 1986 | --primop CopyableOp "copyable#" GenPrimOp |
|---|
| 1987 | -- a -> Int# |
|---|
| 1988 | -- with |
|---|
| 1989 | -- has_side_effects = True |
|---|
| 1990 | -- |
|---|
| 1991 | --primop NoFollowOp "noFollow#" GenPrimOp |
|---|
| 1992 | -- a -> Int# |
|---|
| 1993 | -- with |
|---|
| 1994 | -- has_side_effects = True |
|---|
| 1995 | |
|---|
| 1996 | |
|---|
| 1997 | ------------------------------------------------------------------------ |
|---|
| 1998 | section "Tag to enum stuff" |
|---|
| 1999 | {Convert back and forth between values of enumerated types |
|---|
| 2000 | and small integers.} |
|---|
| 2001 | ------------------------------------------------------------------------ |
|---|
| 2002 | |
|---|
| 2003 | primop DataToTagOp "dataToTag#" GenPrimOp |
|---|
| 2004 | a -> Int# |
|---|
| 2005 | with |
|---|
| 2006 | strictness = { \ _arity -> mkStrictSig (mkTopDmdType [seqDmd] TopRes) } |
|---|
| 2007 | -- dataToTag# must have an evaluated argument |
|---|
| 2008 | |
|---|
| 2009 | primop TagToEnumOp "tagToEnum#" GenPrimOp |
|---|
| 2010 | Int# -> a |
|---|
| 2011 | |
|---|
| 2012 | ------------------------------------------------------------------------ |
|---|
| 2013 | section "Bytecode operations" |
|---|
| 2014 | {Support for the bytecode interpreter and linker.} |
|---|
| 2015 | ------------------------------------------------------------------------ |
|---|
| 2016 | |
|---|
| 2017 | primtype BCO# |
|---|
| 2018 | {Primitive bytecode type.} |
|---|
| 2019 | |
|---|
| 2020 | primop AddrToAnyOp "addrToAny#" GenPrimOp |
|---|
| 2021 | Addr# -> (# a #) |
|---|
| 2022 | {Convert an {\tt Addr\#} to a followable Any type.} |
|---|
| 2023 | with |
|---|
| 2024 | code_size = 0 |
|---|
| 2025 | |
|---|
| 2026 | primop MkApUpd0_Op "mkApUpd0#" GenPrimOp |
|---|
| 2027 | BCO# -> (# a #) |
|---|
| 2028 | with |
|---|
| 2029 | out_of_line = True |
|---|
| 2030 | |
|---|
| 2031 | primop NewBCOOp "newBCO#" GenPrimOp |
|---|
| 2032 | ByteArray# -> ByteArray# -> Array# a -> Int# -> ByteArray# -> State# s -> (# State# s, BCO# #) |
|---|
| 2033 | with |
|---|
| 2034 | has_side_effects = True |
|---|
| 2035 | out_of_line = True |
|---|
| 2036 | |
|---|
| 2037 | primop UnpackClosureOp "unpackClosure#" GenPrimOp |
|---|
| 2038 | a -> (# Addr#, Array# b, ByteArray# #) |
|---|
| 2039 | with |
|---|
| 2040 | out_of_line = True |
|---|
| 2041 | |
|---|
| 2042 | primop GetApStackValOp "getApStackVal#" GenPrimOp |
|---|
| 2043 | a -> Int# -> (# Int#, b #) |
|---|
| 2044 | with |
|---|
| 2045 | out_of_line = True |
|---|
| 2046 | |
|---|
| 2047 | ------------------------------------------------------------------------ |
|---|
| 2048 | section "Misc" |
|---|
| 2049 | {These aren't nearly as wired in as Etc...} |
|---|
| 2050 | ------------------------------------------------------------------------ |
|---|
| 2051 | |
|---|
| 2052 | primop GetCCSOfOp "getCCSOf#" GenPrimOp |
|---|
| 2053 | a -> State# s -> (# State# s, Addr# #) |
|---|
| 2054 | |
|---|
| 2055 | primop GetCurrentCCSOp "getCurrentCCS#" GenPrimOp |
|---|
| 2056 | a -> State# s -> (# State# s, Addr# #) |
|---|
| 2057 | { Returns the current {\tt CostCentreStack} (value is {\tt NULL} if |
|---|
| 2058 | not profiling). Takes a dummy argument which can be used to |
|---|
| 2059 | avoid the call to {\tt getCCCS\#} being floated out by the |
|---|
| 2060 | simplifier, which would result in an uninformative stack |
|---|
| 2061 | ("CAF"). } |
|---|
| 2062 | |
|---|
| 2063 | ------------------------------------------------------------------------ |
|---|
| 2064 | section "Etc" |
|---|
| 2065 | {Miscellaneous built-ins} |
|---|
| 2066 | ------------------------------------------------------------------------ |
|---|
| 2067 | |
|---|
| 2068 | pseudoop "seq" |
|---|
| 2069 | a -> b -> b |
|---|
| 2070 | { Evaluates its first argument to head normal form, and then returns its second |
|---|
| 2071 | argument as the result. } |
|---|
| 2072 | |
|---|
| 2073 | pseudoop "inline" |
|---|
| 2074 | a -> a |
|---|
| 2075 | { The call {\tt (inline f)} arranges that f is inlined, regardless of its size. |
|---|
| 2076 | More precisely, the call {\tt (inline f)} rewrites to the right-hand side of |
|---|
| 2077 | {\tt f}'s definition. This allows the programmer to control inlining from a |
|---|
| 2078 | particular call site rather than the definition site of the function (c.f. |
|---|
| 2079 | {\tt INLINE} pragmas in User's Guide, Section 7.10.3, "INLINE and NOINLINE |
|---|
| 2080 | pragmas"). |
|---|
| 2081 | |
|---|
| 2082 | This inlining occurs regardless of the argument to the call or the size of |
|---|
| 2083 | {\tt f}'s definition; it is unconditional. The main caveat is that {\tt f}'s |
|---|
| 2084 | definition must be visible to the compiler. That is, {\tt f} must be |
|---|
| 2085 | {\tt let}-bound in the current scope. If no inlining takes place, the |
|---|
| 2086 | {\tt inline} function expands to the identity function in Phase zero; so its |
|---|
| 2087 | use imposes no overhead. |
|---|
| 2088 | |
|---|
| 2089 | It is good practice to mark the function with an INLINABLE pragma at |
|---|
| 2090 | its definition, (a) so that GHC guarantees to expose its unfolding regardless |
|---|
| 2091 | of size, and (b) so that you have control over exactly what is inlined. } |
|---|
| 2092 | |
|---|
| 2093 | pseudoop "lazy" |
|---|
| 2094 | a -> a |
|---|
| 2095 | { The {\tt lazy} function restrains strictness analysis a little. The call |
|---|
| 2096 | {\tt (lazy e)} means the same as {\tt e}, but {\tt lazy} has a magical |
|---|
| 2097 | property so far as strictness analysis is concerned: it is lazy in its first |
|---|
| 2098 | argument, even though its semantics is strict. After strictness analysis has |
|---|
| 2099 | run, calls to {\tt lazy} are inlined to be the identity function. |
|---|
| 2100 | |
|---|
| 2101 | This behaviour is occasionally useful when controlling evaluation order. |
|---|
| 2102 | Notably, {\tt lazy} is used in the library definition of {\tt Control.Parallel.par}: |
|---|
| 2103 | |
|---|
| 2104 | {\tt par :: a -> b -> b} |
|---|
| 2105 | |
|---|
| 2106 | {\tt par x y = case (par\# x) of \_ -> lazy y} |
|---|
| 2107 | |
|---|
| 2108 | If {\tt lazy} were not lazy, {\tt par} would look strict in {\tt y} which |
|---|
| 2109 | would defeat the whole purpose of {\tt par}. |
|---|
| 2110 | |
|---|
| 2111 | Like {\tt seq}, the argument of {\tt lazy} can have an unboxed type. } |
|---|
| 2112 | |
|---|
| 2113 | primtype Any k |
|---|
| 2114 | { The type constructor {\tt Any} is type to which you can unsafely coerce any |
|---|
| 2115 | lifted type, and back. |
|---|
| 2116 | |
|---|
| 2117 | * It is lifted, and hence represented by a pointer |
|---|
| 2118 | |
|---|
| 2119 | * It does not claim to be a {\it data} type, and that's important for |
|---|
| 2120 | the code generator, because the code gen may {\it enter} a data value |
|---|
| 2121 | but never enters a function value. |
|---|
| 2122 | |
|---|
| 2123 | It's also used to instantiate un-constrained type variables after type |
|---|
| 2124 | checking. For example, {\tt length} has type |
|---|
| 2125 | |
|---|
| 2126 | {\tt length :: forall a. [a] -> Int} |
|---|
| 2127 | |
|---|
| 2128 | and the list datacon for the empty list has type |
|---|
| 2129 | |
|---|
| 2130 | {\tt [] :: forall a. [a]} |
|---|
| 2131 | |
|---|
| 2132 | In order to compose these two terms as {\tt length []} a type |
|---|
| 2133 | application is required, but there is no constraint on the |
|---|
| 2134 | choice. In this situation GHC uses {\tt Any}: |
|---|
| 2135 | |
|---|
| 2136 | {\tt length (Any *) ([] (Any *))} |
|---|
| 2137 | |
|---|
| 2138 | Note that {\tt Any} is kind polymorphic, and takes a kind {\tt k} as its |
|---|
| 2139 | first argument. The kind of {\tt Any} is thus {\tt forall k. k -> k}.} |
|---|
| 2140 | |
|---|
| 2141 | primtype AnyK |
|---|
| 2142 | { The kind {\tt AnyK} is the kind level counterpart to {\tt Any}. In a |
|---|
| 2143 | kind polymorphic setting, a similar example to the length of the empty |
|---|
| 2144 | list can be given at the type level: |
|---|
| 2145 | |
|---|
| 2146 | {\tt type family Length (l :: [k]) :: Nat} |
|---|
| 2147 | {\tt type instance Length [] = Zero} |
|---|
| 2148 | |
|---|
| 2149 | When {\tt Length} is applied to the empty (promoted) list it will have |
|---|
| 2150 | the kind {\tt Length AnyK []}. |
|---|
| 2151 | |
|---|
| 2152 | {\tt AnyK} is currently not exported and cannot be used directly, but |
|---|
| 2153 | you might see it in debug output from the compiler. |
|---|
| 2154 | } |
|---|
| 2155 | |
|---|
| 2156 | pseudoop "unsafeCoerce#" |
|---|
| 2157 | a -> b |
|---|
| 2158 | { The function {\tt unsafeCoerce\#} allows you to side-step the typechecker entirely. That |
|---|
| 2159 | is, it allows you to coerce any type into any other type. If you use this function, |
|---|
| 2160 | you had better get it right, otherwise segmentation faults await. It is generally |
|---|
| 2161 | used when you want to write a program that you know is well-typed, but where Haskell's |
|---|
| 2162 | type system is not expressive enough to prove that it is well typed. |
|---|
| 2163 | |
|---|
| 2164 | The following uses of {\tt unsafeCoerce\#} are supposed to work (i.e. not lead to |
|---|
| 2165 | spurious compile-time or run-time crashes): |
|---|
| 2166 | |
|---|
| 2167 | * Casting any lifted type to {\tt Any} |
|---|
| 2168 | |
|---|
| 2169 | * Casting {\tt Any} back to the real type |
|---|
| 2170 | |
|---|
| 2171 | * Casting an unboxed type to another unboxed type of the same size |
|---|
| 2172 | (but not coercions between floating-point and integral types) |
|---|
| 2173 | |
|---|
| 2174 | * Casting between two types that have the same runtime representation. One case is when |
|---|
| 2175 | the two types differ only in "phantom" type parameters, for example |
|---|
| 2176 | {\tt Ptr Int} to {\tt Ptr Float}, or {\tt [Int]} to {\tt [Float]} when the list is |
|---|
| 2177 | known to be empty. Also, a {\tt newtype} of a type {\tt T} has the same representation |
|---|
| 2178 | at runtime as {\tt T}. |
|---|
| 2179 | |
|---|
| 2180 | Other uses of {\tt unsafeCoerce\#} are undefined. In particular, you should not use |
|---|
| 2181 | {\tt unsafeCoerce\#} to cast a T to an algebraic data type D, unless T is also |
|---|
| 2182 | an algebraic data type. For example, do not cast {\tt Int->Int} to {\tt Bool}, even if |
|---|
| 2183 | you later cast that {\tt Bool} back to {\tt Int->Int} before applying it. The reasons |
|---|
| 2184 | have to do with GHC's internal representation details (for the congnoscenti, data values |
|---|
| 2185 | can be entered but function closures cannot). If you want a safe type to cast things |
|---|
| 2186 | to, use {\tt Any}, which is not an algebraic data type. |
|---|
| 2187 | |
|---|
| 2188 | } |
|---|
| 2189 | |
|---|
| 2190 | -- NB. It is tempting to think that casting a value to a type that it doesn't have is safe |
|---|
| 2191 | -- as long as you don't "do anything" with the value in its cast form, such as seq on it. This |
|---|
| 2192 | -- isn't the case: the compiler can insert seqs itself, and if these happen at the wrong type, |
|---|
| 2193 | -- Bad Things Might Happen. See bug #1616: in this case we cast a function of type (a,b) -> (a,b) |
|---|
| 2194 | -- to () -> () and back again. The strictness analyser saw that the function was strict, but |
|---|
| 2195 | -- the wrapper had type () -> (), and hence the wrapper de-constructed the (), the worker re-constructed |
|---|
| 2196 | -- a new (), with the result that the code ended up with "case () of (a,b) -> ...". |
|---|
| 2197 | |
|---|
| 2198 | primop TraceEventOp "traceEvent#" GenPrimOp |
|---|
| 2199 | Addr# -> State# s -> State# s |
|---|
| 2200 | { Emits an event via the RTS tracing framework. The contents |
|---|
| 2201 | of the event is the zero-terminated byte string passed as the first |
|---|
| 2202 | argument. The event will be emitted either to the .eventlog file, |
|---|
| 2203 | or to stderr, depending on the runtime RTS flags. } |
|---|
| 2204 | with |
|---|
| 2205 | has_side_effects = True |
|---|
| 2206 | out_of_line = True |
|---|
| 2207 | |
|---|
| 2208 | ------------------------------------------------------------------------ |
|---|
| 2209 | --- --- |
|---|
| 2210 | ------------------------------------------------------------------------ |
|---|
| 2211 | |
|---|
| 2212 | thats_all_folks |
|---|