primops.txt.pp 93.5 KB
Newer Older
1
-----------------------------------------------------------------------
2 3
-- 
-- (c) 2010 The University of Glasgow
4
--
5
-- Primitive Operations and Types
6
--
7 8 9
-- For more information on PrimOps, see
--   http://hackage.haskell.org/trac/ghc/wiki/Commentary/PrimOps
--
10 11
-----------------------------------------------------------------------

apt's avatar
apt committed
12 13 14 15 16 17
-- This file is processed by the utility program genprimopcode to produce
-- a number of include files within the compiler and optionally to produce
-- human-readable documentation.
--
-- It should first be preprocessed.
--
18 19
-- Information on how PrimOps are implemented and the steps necessary to
-- add a new one can be found in the Commentary:
apt's avatar
apt committed
20
--
21
--  http://hackage.haskell.org/trac/ghc/wiki/Commentary/PrimOps
apt's avatar
apt committed
22

23 24
-- This file is divided into named sections, each containing or more
-- primop entries. Section headers have the format:
apt's avatar
apt committed
25 26 27
--
--	section "section-name" {description}
--
28 29
-- This information is used solely when producing documentation; it is
-- otherwise ignored.  The description is optional.
apt's avatar
apt committed
30 31
--
-- The format of each primop entry is as follows:
32
--
apt's avatar
apt committed
33
--	primop internal-name "name-in-program-text" type category {description} attributes
34

apt's avatar
apt committed
35
-- The default attribute values which apply if you don't specify
36 37 38 39
-- other ones.  Attribute values can be True, False, or arbitrary
-- text between curly brackets.  This is a kludge to enable 
-- processors of this file to easily get hold of simple info
-- (eg, out_of_line), whilst avoiding parsing complex expressions
40
-- needed for strictness info.
41 42 43

defaults
   has_side_effects = False
44 45
   out_of_line      = False   -- See Note Note [PrimOp can_fail and has_side_effects] in PrimOp
   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 topDmd) topRes) }
49
   fixity           = Nothing
gmainland's avatar
gmainland committed
50
   llvm_only        = False
51

52 53 54
-- Currently, documentation is produced using latex, so contents of
-- description fields should be legal latex. Descriptions can contain
-- matched pairs of embedded curly brackets.
apt's avatar
apt committed
55 56

#include "MachDeps.h"
57

58 59
-- We need platform defines (tests for mingw32 below).
#include "ghc_boot_platform.h"
apt's avatar
apt committed
60 61

section "The word size story."
62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
	{Haskell98 specifies that signed integers (type {\tt Int})
	 must contain at least 30 bits. GHC always implements {\tt
	 Int} using the primitive type {\tt Int\#}, whose size equals
	 the {\tt MachDeps.h} constant {\tt WORD\_SIZE\_IN\_BITS}.
	 This is normally set based on the {\tt config.h} parameter
	 {\tt SIZEOF\_HSWORD}, i.e., 32 bits on 32-bit machines, 64
	 bits on 64-bit machines.  However, it can also be explicitly
	 set to a smaller number, e.g., 31 bits, to allow the
	 possibility of using tag bits. Currently GHC itself has only
	 32-bit and 64-bit variants, but 30 or 31-bit code can be
	 exported as an external core file for use in other back ends.

	 GHC also implements a primitive unsigned integer type {\tt
	 Word\#} which always has the same number of bits as {\tt
	 Int\#}.
apt's avatar
apt committed
77
	
78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104
	 In addition, GHC supports families of explicit-sized integers
	 and words at 8, 16, 32, and 64 bits, with the usual
	 arithmetic operations, comparisons, and a range of
	 conversions.  The 8-bit and 16-bit sizes are always
	 represented as {\tt Int\#} and {\tt Word\#}, and the
	 operations implemented in terms of the the primops on these
	 types, with suitable range restrictions on the results (using
	 the {\tt narrow$n$Int\#} and {\tt narrow$n$Word\#} families
	 of primops.  The 32-bit sizes are represented using {\tt
	 Int\#} and {\tt Word\#} when {\tt WORD\_SIZE\_IN\_BITS}
	 $\geq$ 32; otherwise, these are represented using distinct
	 primitive types {\tt Int32\#} and {\tt Word32\#}. These (when
	 needed) have a complete set of corresponding operations;
	 however, nearly all of these are implemented as external C
	 functions rather than as primops.  Exactly the same story
	 applies to the 64-bit sizes.  All of these details are hidden
	 under the {\tt PrelInt} and {\tt PrelWord} modules, which use
	 {\tt \#if}-defs to invoke the appropriate types and
	 operators.

	 Word size also matters for the families of primops for
	 indexing/reading/writing fixed-size quantities at offsets
	 from an array base, address, or foreign pointer.  Here, a
	 slightly different approach is taken.  The names of these
	 primops are fixed, but their {\it types} vary according to
	 the value of {\tt WORD\_SIZE\_IN\_BITS}. For example, if word
	 size is at least 32 bits then an operator like
105 106
	 \texttt{indexInt32Array\#} has type {\tt ByteArray\# -> Int\#
	 -> Int\#}; otherwise it has type {\tt ByteArray\# -> Int\# ->
107 108
	 Int32\#}.  This approach confines the necessary {\tt
	 \#if}-defs to this file; no conditional compilation is needed
109
	 in the files that expose these primops.
110 111 112 113 114 115 116

	 Finally, there are strongly deprecated primops for coercing
         between {\tt Addr\#}, the primitive type of machine
         addresses, and {\tt Int\#}.  These are pretty bogus anyway,
         but will work on existing 32-bit and 64-bit GHC targets; they
         are completely bogus when tag bits are used in {\tt Int\#},
         so are not available in this case.  }
apt's avatar
apt committed
117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134
	
-- Define synonyms for indexing ops. 

#if WORD_SIZE_IN_BITS < 32 
#define INT32 Int32#
#define WORD32 Word32#
#else
#define INT32 Int#
#define WORD32 Word#
#endif

#if WORD_SIZE_IN_BITS < 64
#define INT64 Int64#
#define WORD64 Word64#
#else
#define INT64 Int#
#define WORD64 Word#
#endif
135 136

------------------------------------------------------------------------
apt's avatar
apt committed
137 138
section "Char#" 
	{Operations on 31-bit characters.}
139 140
------------------------------------------------------------------------

141
primtype Char#
142

apt's avatar
apt committed
143 144
primop   CharGtOp  "gtChar#"   Compare   Char# -> Char# -> Bool
primop   CharGeOp  "geChar#"   Compare   Char# -> Char# -> Bool
145

apt's avatar
apt committed
146 147 148
primop   CharEqOp  "eqChar#"   Compare
   Char# -> Char# -> Bool
   with commutable = True
149

apt's avatar
apt committed
150 151 152 153 154 155 156 157
primop   CharNeOp  "neChar#"   Compare
   Char# -> Char# -> Bool
   with commutable = True

primop   CharLtOp  "ltChar#"   Compare   Char# -> Char# -> Bool
primop   CharLeOp  "leChar#"   Compare   Char# -> Char# -> Bool

primop   OrdOp   "ord#"  GenPrimOp   Char# -> Int#
158
   with code_size = 0
159

160
------------------------------------------------------------------------
apt's avatar
apt committed
161 162
section "Int#"
	{Operations on native-size integers (30+ bits).}
163 164
------------------------------------------------------------------------

165 166
primtype Int#

apt's avatar
apt committed
167 168 169
primop   IntAddOp    "+#"    Dyadic
   Int# -> Int# -> Int#
   with commutable = True
170
        fixity = infixl 6
171

apt's avatar
apt committed
172
primop   IntSubOp    "-#"    Dyadic   Int# -> Int# -> Int#
173
   with fixity = infixl 6
174

apt's avatar
apt committed
175 176
primop   IntMulOp    "*#" 
   Dyadic   Int# -> Int# -> Int#
177 178
   {Low word of signed integer multiply.}
   with commutable = True
179
        fixity = infixl 7
180 181

primop   IntMulMayOfloOp  "mulIntMayOflo#" 
182 183
   Dyadic   Int# -> Int# -> Int#
   {Return non-zero if there is any possibility that the upper word of a
184
    signed integer multiply might contain useful information.  Return
185
    zero only if you are completely sure that no overflow can occur.
186
    On a 32-bit platform, the recommmended implementation is to do a 
187 188 189 190
    32 x 32 -> 64 signed multiply, and subtract result[63:32] from
    (result[31] >>signed 31).  If this is zero, meaning that the 
    upper word is merely a sign extension of the lower one, no
    overflow can occur.
191 192 193 194 195 196 197 198 199 200

    On a 64-bit platform it is not always possible to 
    acquire the top 64 bits of the result.  Therefore, a recommended 
    implementation is to take the absolute value of both operands, and 
    return 0 iff bits[63:31] of them are zero, since that means that their 
    magnitudes fit within 31 bits, so the magnitude of the product must fit 
    into 62 bits.

    If in doubt, return non-zero, but do make an effort to create the
    correct answer for small args, since otherwise the performance of
201
    \texttt{(*) :: Integer -> Integer -> Integer} will be poor.
202
   }
apt's avatar
apt committed
203 204 205 206 207 208 209 210 211 212 213 214
   with commutable = True

primop   IntQuotOp    "quotInt#"    Dyadic
   Int# -> Int# -> Int#
   {Rounds towards zero.}
   with can_fail = True

primop   IntRemOp    "remInt#"    Dyadic
   Int# -> Int# -> Int#
   {Satisfies \texttt{(quotInt\# x y) *\# y +\# (remInt\# x y) == x}.}
   with can_fail = True

215 216 217 218 219
primop   IntQuotRemOp "quotRemInt#"    GenPrimOp
   Int# -> Int# -> (# Int#, Int# #)
   {Rounds towards zero.}
   with can_fail = True

220 221 222 223 224 225 226 227 228 229 230
primop   AndIOp   "andI#"   Dyadic    Int# -> Int# -> Int#
   with commutable = True

primop   OrIOp   "orI#"     Dyadic    Int# -> Int# -> Int#
   with commutable = True

primop   XorIOp   "xorI#"   Dyadic    Int# -> Int# -> Int#
   with commutable = True

primop   NotIOp   "notI#"   Monadic   Int# -> Int#

apt's avatar
apt committed
231 232
primop   IntNegOp    "negateInt#"    Monadic   Int# -> Int#
primop   IntAddCOp   "addIntC#"    GenPrimOp   Int# -> Int# -> (# Int#, Int# #)
233 234
	 {Add with carry.  First member of result is (wrapped) sum; 
          second member is 0 iff no overflow occured.}
235 236
   with code_size = 2

apt's avatar
apt committed
237
primop   IntSubCOp   "subIntC#"    GenPrimOp   Int# -> Int# -> (# Int#, Int# #)
238 239
	 {Subtract with carry.  First member of result is (wrapped) difference; 
          second member is 0 iff no overflow occured.}
240
   with code_size = 2
241

apt's avatar
apt committed
242
primop   IntGtOp  ">#"   Compare   Int# -> Int# -> Bool
243 244
   with fixity = infix 4

apt's avatar
apt committed
245
primop   IntGeOp  ">=#"   Compare   Int# -> Int# -> Bool
246
   with fixity = infix 4
apt's avatar
apt committed
247 248 249 250

primop   IntEqOp  "==#"   Compare
   Int# -> Int# -> Bool
   with commutable = True
251
        fixity = infix 4
apt's avatar
apt committed
252 253 254 255

primop   IntNeOp  "/=#"   Compare
   Int# -> Int# -> Bool
   with commutable = True
256
        fixity = infix 4
apt's avatar
apt committed
257 258

primop   IntLtOp  "<#"   Compare   Int# -> Int# -> Bool
259 260
   with fixity = infix 4

apt's avatar
apt committed
261
primop   IntLeOp  "<=#"   Compare   Int# -> Int# -> Bool
262
   with fixity = infix 4
apt's avatar
apt committed
263 264

primop   ChrOp   "chr#"   GenPrimOp   Int# -> Char#
265
   with code_size = 0
apt's avatar
apt committed
266 267

primop   Int2WordOp "int2Word#" GenPrimOp Int# -> Word#
268 269
   with code_size = 0

apt's avatar
apt committed
270 271 272
primop   Int2FloatOp   "int2Float#"      GenPrimOp  Int# -> Float#
primop   Int2DoubleOp   "int2Double#"          GenPrimOp  Int# -> Double#

tibbe's avatar
tibbe committed
273 274 275
primop   Word2FloatOp   "word2Float#"      GenPrimOp  Word# -> Float#
primop   Word2DoubleOp   "word2Double#"          GenPrimOp  Word# -> Double#

276
primop   ISllOp   "uncheckedIShiftL#" GenPrimOp  Int# -> Int# -> Int#
277 278
	 {Shift left.  Result undefined if shift amount is not
          in the range 0 to word size - 1 inclusive.}
279
primop   ISraOp   "uncheckedIShiftRA#" GenPrimOp Int# -> Int# -> Int#
280 281
	 {Shift right arithmetic.  Result undefined if shift amount is not
          in the range 0 to word size - 1 inclusive.}
282
primop   ISrlOp   "uncheckedIShiftRL#" GenPrimOp Int# -> Int# -> Int#
283 284
	 {Shift right logical.  Result undefined if shift amount is not
          in the range 0 to word size - 1 inclusive.}
285 286

------------------------------------------------------------------------
apt's avatar
apt committed
287 288
section "Word#"
	{Operations on native-sized unsigned words (30+ bits).}
289 290
------------------------------------------------------------------------

291 292
primtype Word#

apt's avatar
apt committed
293 294
primop   WordAddOp   "plusWord#"   Dyadic   Word# -> Word# -> Word#
   with commutable = True
295

Ian Lynagh's avatar
Ian Lynagh committed
296
-- Returns (# high, low #) (or equivalently, (# carry, low #))
Ian Lynagh's avatar
Ian Lynagh committed
297 298 299 300
primop   WordAdd2Op  "plusWord2#"  GenPrimOp
   Word# -> Word# -> (# Word#, Word# #)
   with commutable = True

apt's avatar
apt committed
301 302 303
primop   WordSubOp   "minusWord#"   Dyadic   Word# -> Word# -> Word#

primop   WordMulOp   "timesWord#"   Dyadic   Word# -> Word# -> Word#
304 305
   with commutable = True

Ian Lynagh's avatar
Ian Lynagh committed
306
-- Returns (# high, low #)
Ian Lynagh's avatar
Ian Lynagh committed
307 308 309 310
primop   WordMul2Op  "timesWord2#"   GenPrimOp
   Word# -> Word# -> (# Word#, Word# #)
   with commutable = True

apt's avatar
apt committed
311 312 313 314 315 316
primop   WordQuotOp   "quotWord#"   Dyadic   Word# -> Word# -> Word#
   with can_fail = True

primop   WordRemOp   "remWord#"   Dyadic   Word# -> Word# -> Word#
   with can_fail = True

317 318 319 320
primop   WordQuotRemOp "quotRemWord#" GenPrimOp
   Word# -> Word# -> (# Word#, Word# #)
   with can_fail = True

Ian Lynagh's avatar
Ian Lynagh committed
321 322 323 324 325 326
-- Takes high word of dividend, then low word of dividend, then divisor.
-- Requires that high word is not divisible by divisor.
primop   WordQuotRem2Op "quotRemWord2#" GenPrimOp
   Word# -> Word# -> Word# -> (# Word#, Word# #)
   with can_fail = True

apt's avatar
apt committed
327
primop   AndOp   "and#"   Dyadic   Word# -> Word# -> Word#
328 329
   with commutable = True

apt's avatar
apt committed
330 331 332 333 334 335 336 337
primop   OrOp   "or#"   Dyadic   Word# -> Word# -> Word#
   with commutable = True

primop   XorOp   "xor#"   Dyadic   Word# -> Word# -> Word#
   with commutable = True

primop   NotOp   "not#"   Monadic   Word# -> Word#

338
primop   SllOp   "uncheckedShiftL#"   GenPrimOp   Word# -> Int# -> Word#
339 340
	 {Shift left logical.   Result undefined if shift amount is not
          in the range 0 to word size - 1 inclusive.}
341
primop   SrlOp   "uncheckedShiftRL#"   GenPrimOp   Word# -> Int# -> Word#
342 343
	 {Shift right logical.   Result undefined if shift  amount is not
          in the range 0 to word size - 1 inclusive.}
apt's avatar
apt committed
344 345

primop   Word2IntOp   "word2Int#"   GenPrimOp   Word# -> Int#
346
   with code_size = 0
apt's avatar
apt committed
347 348 349 350 351 352 353 354

primop   WordGtOp   "gtWord#"   Compare   Word# -> Word# -> Bool
primop   WordGeOp   "geWord#"   Compare   Word# -> Word# -> Bool
primop   WordEqOp   "eqWord#"   Compare   Word# -> Word# -> Bool
primop   WordNeOp   "neWord#"   Compare   Word# -> Word# -> Bool
primop   WordLtOp   "ltWord#"   Compare   Word# -> Word# -> Bool
primop   WordLeOp   "leWord#"   Compare   Word# -> Word# -> Bool

tibbe's avatar
tibbe committed
355 356 357 358 359 360
primop   PopCnt8Op   "popCnt8#"   Monadic   Word# -> Word#
    {Count the number of set bits in the lower 8 bits of a word.}
primop   PopCnt16Op   "popCnt16#"   Monadic   Word# -> Word#
    {Count the number of set bits in the lower 16 bits of a word.}
primop   PopCnt32Op   "popCnt32#"   Monadic   Word# -> Word#
    {Count the number of set bits in the lower 32 bits of a word.}
Simon Marlow's avatar
Simon Marlow committed
361
primop   PopCnt64Op   "popCnt64#"   GenPrimOp   WORD64 -> Word#
tibbe's avatar
tibbe committed
362 363 364 365
    {Count the number of set bits in a 64-bit word.}
primop   PopCntOp   "popCnt#"   Monadic   Word# -> Word#
    {Count the number of set bits in a word.}

apt's avatar
apt committed
366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381
------------------------------------------------------------------------
section "Narrowings" 
	{Explicit narrowing of native-sized ints or words.}
------------------------------------------------------------------------

primop   Narrow8IntOp      "narrow8Int#"      Monadic   Int# -> Int#
primop   Narrow16IntOp     "narrow16Int#"     Monadic   Int# -> Int#
primop   Narrow32IntOp     "narrow32Int#"     Monadic   Int# -> Int#
primop   Narrow8WordOp     "narrow8Word#"     Monadic   Word# -> Word#
primop   Narrow16WordOp    "narrow16Word#"    Monadic   Word# -> Word#
primop   Narrow32WordOp    "narrow32Word#"    Monadic   Word# -> Word#


#if WORD_SIZE_IN_BITS < 32
------------------------------------------------------------------------
section "Int32#"
382 383
	{Operations on 32-bit integers ({\tt Int32\#}).  This type is only used
         if plain {\tt Int\#} has less than 32 bits.  In any case, the operations
apt's avatar
apt committed
384 385 386
	 are not primops; they are implemented (if needed) as ccalls instead.}
------------------------------------------------------------------------

387 388
primtype Int32#

apt's avatar
apt committed
389 390 391
------------------------------------------------------------------------
section "Word32#"
	{Operations on 32-bit unsigned words. This type is only used 
392
	 if plain {\tt Word\#} has less than 32 bits. In any case, the operations
apt's avatar
apt committed
393 394 395
	 are not primops; they are implemented (if needed) as ccalls instead.}
------------------------------------------------------------------------

396 397
primtype Word32#

apt's avatar
apt committed
398 399 400 401 402 403 404
#endif 


#if WORD_SIZE_IN_BITS < 64
------------------------------------------------------------------------
section "Int64#"
	{Operations on 64-bit unsigned words. This type is only used 
405
	 if plain {\tt Int\#} has less than 64 bits. In any case, the operations
apt's avatar
apt committed
406 407 408
	 are not primops; they are implemented (if needed) as ccalls instead.}
------------------------------------------------------------------------

409 410
primtype Int64#

apt's avatar
apt committed
411 412 413
------------------------------------------------------------------------
section "Word64#"
	{Operations on 64-bit unsigned words. This type is only used 
414
	 if plain {\tt Word\#} has less than 64 bits. In any case, the operations
apt's avatar
apt committed
415 416 417
	 are not primops; they are implemented (if needed) as ccalls instead.}
------------------------------------------------------------------------

418 419
primtype Word64#

apt's avatar
apt committed
420 421
#endif

422
------------------------------------------------------------------------
apt's avatar
apt committed
423 424
section "Double#"
	{Operations on double-precision (64 bit) floating-point numbers.}
425 426
------------------------------------------------------------------------

427 428
primtype Double#

429
primop   DoubleGtOp ">##"   Compare   Double# -> Double# -> Bool
430 431
   with fixity = infix 4

432
primop   DoubleGeOp ">=##"   Compare   Double# -> Double# -> Bool
433
   with fixity = infix 4
434 435 436 437

primop DoubleEqOp "==##"   Compare
   Double# -> Double# -> Bool
   with commutable = True
438
        fixity = infix 4
439 440 441 442

primop DoubleNeOp "/=##"   Compare
   Double# -> Double# -> Bool
   with commutable = True
443
        fixity = infix 4
444 445

primop   DoubleLtOp "<##"   Compare   Double# -> Double# -> Bool
446 447
   with fixity = infix 4

448
primop   DoubleLeOp "<=##"   Compare   Double# -> Double# -> Bool
449
   with fixity = infix 4
450 451 452 453

primop   DoubleAddOp   "+##"   Dyadic
   Double# -> Double# -> Double#
   with commutable = True
454
        fixity = infixl 6
455 456

primop   DoubleSubOp   "-##"   Dyadic   Double# -> Double# -> Double#
457
   with fixity = infixl 6
458 459 460 461

primop   DoubleMulOp   "*##"   Dyadic
   Double# -> Double# -> Double#
   with commutable = True
462
        fixity = infixl 7
463 464 465 466

primop   DoubleDivOp   "/##"   Dyadic
   Double# -> Double# -> Double#
   with can_fail = True
467
        fixity = infixl 7
468 469 470 471

primop   DoubleNegOp   "negateDouble#"  Monadic   Double# -> Double#

primop   Double2IntOp   "double2Int#"          GenPrimOp  Double# -> Int#
472 473 474 475
   {Truncates a {\tt Double#} value to the nearest {\tt Int#}.
    Results are undefined if the truncation if truncation yields
    a value outside the range of {\tt Int#}.}

476 477 478 479
primop   Double2FloatOp   "double2Float#" GenPrimOp Double# -> Float#

primop   DoubleExpOp   "expDouble#"      Monadic
   Double# -> Double#
480 481
   with
   code_size = { primOpCodeSizeForeignCall }
482 483 484 485

primop   DoubleLogOp   "logDouble#"      Monadic         
   Double# -> Double#
   with
486
   code_size = { primOpCodeSizeForeignCall }
487 488 489 490
   can_fail = True

primop   DoubleSqrtOp   "sqrtDouble#"      Monadic  
   Double# -> Double#
491 492
   with
   code_size = { primOpCodeSizeForeignCall }
493 494 495

primop   DoubleSinOp   "sinDouble#"      Monadic          
   Double# -> Double#
496 497
   with
   code_size = { primOpCodeSizeForeignCall }
498 499 500

primop   DoubleCosOp   "cosDouble#"      Monadic          
   Double# -> Double#
501 502
   with
   code_size = { primOpCodeSizeForeignCall }
503 504 505

primop   DoubleTanOp   "tanDouble#"      Monadic          
   Double# -> Double#
506 507
   with
   code_size = { primOpCodeSizeForeignCall }
508 509 510 511

primop   DoubleAsinOp   "asinDouble#"      Monadic 
   Double# -> Double#
   with
512
   code_size = { primOpCodeSizeForeignCall }
513 514 515 516 517
   can_fail = True

primop   DoubleAcosOp   "acosDouble#"      Monadic  
   Double# -> Double#
   with
518
   code_size = { primOpCodeSizeForeignCall }
519 520 521 522 523
   can_fail = True

primop   DoubleAtanOp   "atanDouble#"      Monadic  
   Double# -> Double#
   with
524
   code_size = { primOpCodeSizeForeignCall }
525 526 527

primop   DoubleSinhOp   "sinhDouble#"      Monadic  
   Double# -> Double#
528 529
   with
   code_size = { primOpCodeSizeForeignCall }
530 531 532

primop   DoubleCoshOp   "coshDouble#"      Monadic  
   Double# -> Double#
533 534
   with
   code_size = { primOpCodeSizeForeignCall }
535 536 537

primop   DoubleTanhOp   "tanhDouble#"      Monadic  
   Double# -> Double#
538 539
   with
   code_size = { primOpCodeSizeForeignCall }
540 541 542

primop   DoublePowerOp   "**##" Dyadic  
   Double# -> Double# -> Double#
apt's avatar
apt committed
543
   {Exponentiation.}
544 545
   with
   code_size = { primOpCodeSizeForeignCall }
546

547
primop   DoubleDecode_2IntOp   "decodeDouble_2Int#" GenPrimOp    
548
   Double# -> (# Int#, Word#, Word#, Int# #)
549
   {Convert to integer.
550 551 552
    First component of the result is -1 or 1, indicating the sign of the
    mantissa. The next two are the high and low 32 bits of the mantissa
    respectively, and the last is the exponent.}
553 554
   with out_of_line = True

555
------------------------------------------------------------------------
apt's avatar
apt committed
556 557
section "Float#" 
	{Operations on single-precision (32-bit) floating-point numbers.}
558 559
------------------------------------------------------------------------

560 561
primtype Float#

562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592
primop   FloatGtOp  "gtFloat#"   Compare   Float# -> Float# -> Bool
primop   FloatGeOp  "geFloat#"   Compare   Float# -> Float# -> Bool

primop   FloatEqOp  "eqFloat#"   Compare
   Float# -> Float# -> Bool
   with commutable = True

primop   FloatNeOp  "neFloat#"   Compare
   Float# -> Float# -> Bool
   with commutable = True

primop   FloatLtOp  "ltFloat#"   Compare   Float# -> Float# -> Bool
primop   FloatLeOp  "leFloat#"   Compare   Float# -> Float# -> Bool

primop   FloatAddOp   "plusFloat#"      Dyadic            
   Float# -> Float# -> Float#
   with commutable = True

primop   FloatSubOp   "minusFloat#"      Dyadic      Float# -> Float# -> Float#

primop   FloatMulOp   "timesFloat#"      Dyadic    
   Float# -> Float# -> Float#
   with commutable = True

primop   FloatDivOp   "divideFloat#"      Dyadic  
   Float# -> Float# -> Float#
   with can_fail = True

primop   FloatNegOp   "negateFloat#"      Monadic    Float# -> Float#

primop   Float2IntOp   "float2Int#"      GenPrimOp  Float# -> Int#
593 594 595
   {Truncates a {\tt Float#} value to the nearest {\tt Int#}.
    Results are undefined if the truncation if truncation yields
    a value outside the range of {\tt Int#}.}
596 597 598

primop   FloatExpOp   "expFloat#"      Monadic          
   Float# -> Float#
599 600
   with
   code_size = { primOpCodeSizeForeignCall }
601 602 603

primop   FloatLogOp   "logFloat#"      Monadic          
   Float# -> Float#
604 605 606
   with
   code_size = { primOpCodeSizeForeignCall }
   can_fail = True
607 608 609

primop   FloatSqrtOp   "sqrtFloat#"      Monadic          
   Float# -> Float#
610 611
   with
   code_size = { primOpCodeSizeForeignCall }
612 613 614

primop   FloatSinOp   "sinFloat#"      Monadic          
   Float# -> Float#
615 616
   with
   code_size = { primOpCodeSizeForeignCall }
617 618 619

primop   FloatCosOp   "cosFloat#"      Monadic          
   Float# -> Float#
620 621
   with
   code_size = { primOpCodeSizeForeignCall }
622 623 624

primop   FloatTanOp   "tanFloat#"      Monadic          
   Float# -> Float#
625 626
   with
   code_size = { primOpCodeSizeForeignCall }
627 628 629

primop   FloatAsinOp   "asinFloat#"      Monadic          
   Float# -> Float#
630 631 632
   with
   code_size = { primOpCodeSizeForeignCall }
   can_fail = True
633 634 635

primop   FloatAcosOp   "acosFloat#"      Monadic          
   Float# -> Float#
636 637 638
   with
   code_size = { primOpCodeSizeForeignCall }
   can_fail = True
639 640 641

primop   FloatAtanOp   "atanFloat#"      Monadic          
   Float# -> Float#
642 643
   with
   code_size = { primOpCodeSizeForeignCall }
644 645 646

primop   FloatSinhOp   "sinhFloat#"      Monadic          
   Float# -> Float#
647 648
   with
   code_size = { primOpCodeSizeForeignCall }
649 650 651

primop   FloatCoshOp   "coshFloat#"      Monadic          
   Float# -> Float#
652 653
   with
   code_size = { primOpCodeSizeForeignCall }
654 655 656

primop   FloatTanhOp   "tanhFloat#"      Monadic          
   Float# -> Float#
657 658
   with
   code_size = { primOpCodeSizeForeignCall }
659 660 661

primop   FloatPowerOp   "powerFloat#"      Dyadic   
   Float# -> Float# -> Float#
662 663
   with
   code_size = { primOpCodeSizeForeignCall }
664 665 666

primop   Float2DoubleOp   "float2Double#" GenPrimOp  Float# -> Double#

667 668
primop   FloatDecode_IntOp   "decodeFloat_Int#" GenPrimOp
   Float# -> (# Int#, Int# #)
669
   {Convert to integers.
670 671 672
    First {\tt Int\#} in result is the mantissa; second is the exponent.}
   with out_of_line = True

673
------------------------------------------------------------------------
apt's avatar
apt committed
674
section "Arrays"
675
	{Operations on {\tt Array\#}.}
676 677
------------------------------------------------------------------------

678 679
primtype Array# a

680
primtype MutableArray# s a
681

apt's avatar
apt committed
682
primop  NewArrayOp "newArray#" GenPrimOp
683
   Int# -> a -> State# s -> (# State# s, MutableArray# s a #)
684
   {Create a new mutable array with the specified number of elements,
apt's avatar
apt committed
685 686 687 688
    in the specified state thread,
    with each element containing the specified initial value.}
   with
   out_of_line = True
689
   has_side_effects = True
690

apt's avatar
apt committed
691
primop  SameMutableArrayOp "sameMutableArray#" GenPrimOp
692
   MutableArray# s a -> MutableArray# s a -> Bool
693

apt's avatar
apt committed
694
primop  ReadArrayOp "readArray#" GenPrimOp
695
   MutableArray# s a -> Int# -> State# s -> (# State# s, a #)
apt's avatar
apt committed
696
   {Read from specified index of mutable array. Result is not yet evaluated.}
697 698
   with
   has_side_effects = True
699
   can_fail         = True
700

apt's avatar
apt committed
701
primop  WriteArrayOp "writeArray#" GenPrimOp
702
   MutableArray# s a -> Int# -> a -> State# s -> State# s
apt's avatar
apt committed
703 704 705
   {Write to specified index of mutable array.}
   with
   has_side_effects = True
706 707
   can_fail         = True
   code_size        = 2 -- card update too
708

pumpkin's avatar
pumpkin committed
709 710 711 712 713 714 715 716
primop  SizeofArrayOp "sizeofArray#" GenPrimOp
   Array# a -> Int#
   {Return the number of elements in the array.}

primop  SizeofMutableArrayOp "sizeofMutableArray#" GenPrimOp
   MutableArray# s a -> Int#
   {Return the number of elements in the array.}

apt's avatar
apt committed
717 718 719 720
primop  IndexArrayOp "indexArray#" GenPrimOp
   Array# a -> Int# -> (# a #)
   {Read from specified index of immutable array. Result is packaged into
    an unboxed singleton; the result itself is not yet evaluated.}
721 722
   with
   can_fail         = True
723

apt's avatar
apt committed
724
primop  UnsafeFreezeArrayOp "unsafeFreezeArray#" GenPrimOp
725
   MutableArray# s a -> State# s -> (# State# s, Array# a #)
apt's avatar
apt committed
726 727 728
   {Make a mutable array immutable, without copying.}
   with
   has_side_effects = True
729

apt's avatar
apt committed
730
primop  UnsafeThawArrayOp  "unsafeThawArray#" GenPrimOp
731
   Array# a -> State# s -> (# State# s, MutableArray# s a #)
apt's avatar
apt committed
732 733 734
   {Make an immutable array mutable, without copying.}
   with
   out_of_line = True
735
   has_side_effects = True
736

pumpkin's avatar
pumpkin committed
737 738 739 740 741 742 743
primop  CopyArrayOp "copyArray#" GenPrimOp
  Array# a -> Int# -> MutableArray# s a -> Int# -> Int# -> State# s -> State# s
  {Copy a range of the Array# to the specified region in the MutableArray#.
   Both arrays must fully contain the specified ranges, but this is not checked.
   The two arrays must not be the same array in different states, but this is not checked either.}
  with
  has_side_effects = True
744
  can_fail         = True
745
  code_size = { primOpCodeSizeForeignCall + 4 }
pumpkin's avatar
pumpkin committed
746 747 748 749 750 751 752

primop  CopyMutableArrayOp "copyMutableArray#" GenPrimOp
  MutableArray# s a -> Int# -> MutableArray# s a -> Int# -> Int# -> State# s -> State# s
  {Copy a range of the first MutableArray# to the specified region in the second MutableArray#.
   Both arrays must fully contain the specified ranges, but this is not checked.}
  with
  has_side_effects = True
753
  can_fail         = True
754
  code_size = { primOpCodeSizeForeignCall + 4 }
pumpkin's avatar
pumpkin committed
755 756 757 758 759 760 761

primop  CloneArrayOp "cloneArray#" GenPrimOp
  Array# a -> Int# -> Int# -> Array# a
  {Return a newly allocated Array# with the specified subrange of the provided Array#. 
   The provided Array# should contain the full subrange specified by the two Int#s, but this is not checked.}
  with
  has_side_effects = True
762
  code_size = { primOpCodeSizeForeignCall + 4 }
pumpkin's avatar
pumpkin committed
763 764 765 766 767 768 769

primop  CloneMutableArrayOp "cloneMutableArray#" GenPrimOp
  MutableArray# s a -> Int# -> Int# -> State# s -> (# State# s, MutableArray# s a #)
  {Return a newly allocated Array# with the specified subrange of the provided Array#.
   The provided MutableArray# should contain the full subrange specified by the two Int#s, but this is not checked.}
  with
  has_side_effects = True
770
  code_size = { primOpCodeSizeForeignCall + 4 }
pumpkin's avatar
pumpkin committed
771 772 773 774 775 776 777

primop  FreezeArrayOp "freezeArray#" GenPrimOp
  MutableArray# s a -> Int# -> Int# -> State# s -> (# State# s, Array# a #)
  {Return a newly allocated Array# with the specified subrange of the provided MutableArray#.
   The provided MutableArray# should contain the full subrange specified by the two Int#s, but this is not checked.}
  with
  has_side_effects = True
778
  code_size = { primOpCodeSizeForeignCall + 4 }
pumpkin's avatar
pumpkin committed
779 780 781 782 783 784 785

primop  ThawArrayOp "thawArray#" GenPrimOp
  Array# a -> Int# -> Int# -> State# s -> (# State# s, MutableArray# s a #)
  {Return a newly allocated Array# with the specified subrange of the provided MutableArray#.
   The provided Array# should contain the full subrange specified by the two Int#s, but this is not checked.}
  with
  has_side_effects = True
786
  code_size = { primOpCodeSizeForeignCall + 4 }
pumpkin's avatar
pumpkin committed
787

788
------------------------------------------------------------------------
apt's avatar
apt committed
789
section "Byte Arrays"
790
	{Operations on {\tt ByteArray\#}. A {\tt ByteArray\#} is a just a region of
791
         raw memory in the garbage-collected heap, which is not
792 793
         scanned for pointers. It carries its own size (in bytes).
         There are
794 795 796 797
         three sets of operations for accessing byte array contents:
         index for reading from immutable byte arrays, and read/write
         for mutable byte arrays.  Each set contains operations for a
         range of useful primitive data types.  Each operation takes
798
         an offset measured in terms of the size of the primitive type
799
         being read or written.}
800

801 802
------------------------------------------------------------------------

803
primtype ByteArray#
804

805
primtype MutableByteArray# s
806

807
primop  NewByteArrayOp_Char "newByteArray#" GenPrimOp
808
   Int# -> State# s -> (# State# s, MutableByteArray# s #)
apt's avatar
apt committed
809 810
   {Create a new mutable byte array of specified size (in bytes), in
    the specified state thread.}
811
   with out_of_line = True
812
        has_side_effects = True
813

814
primop  NewPinnedByteArrayOp_Char "newPinnedByteArray#" GenPrimOp
815
   Int# -> State# s -> (# State# s, MutableByteArray# s #)
apt's avatar
apt committed
816
   {Create a mutable byte array that the GC guarantees not to move.}
817
   with out_of_line = True
818
        has_side_effects = True
819

Simon Marlow's avatar
Simon Marlow committed
820 821 822 823
primop  NewAlignedPinnedByteArrayOp_Char "newAlignedPinnedByteArray#" GenPrimOp
   Int# -> Int# -> State# s -> (# State# s, MutableByteArray# s #)
   {Create a mutable byte array, aligned by the specified amount, that the GC guarantees not to move.}
   with out_of_line = True
824
        has_side_effects = True
Simon Marlow's avatar
Simon Marlow committed
825

826
primop  ByteArrayContents_Char "byteArrayContents#" GenPrimOp
827
   ByteArray# -> Addr#
apt's avatar
apt committed
828 829 830
   {Intended for use with pinned arrays; otherwise very unsafe!}

primop  SameMutableByteArrayOp "sameMutableByteArray#" GenPrimOp
831
   MutableByteArray# s -> MutableByteArray# s -> Bool
apt's avatar
apt committed
832 833

primop  UnsafeFreezeByteArrayOp "unsafeFreezeByteArray#" GenPrimOp
834
   MutableByteArray# s -> State# s -> (# State# s, ByteArray# #)
apt's avatar
apt committed
835 836 837 838 839
   {Make a mutable byte array immutable, without copying.}
   with
   has_side_effects = True

primop  SizeofByteArrayOp "sizeofByteArray#" GenPrimOp  
840
   ByteArray# -> Int#
841
   {Return the size of the array in bytes.}
apt's avatar
apt committed
842 843

primop  SizeofMutableByteArrayOp "sizeofMutableByteArray#" GenPrimOp
844
   MutableByteArray# s -> Int#
845
   {Return the size of the array in bytes.}
846

847
primop IndexByteArrayOp_Char "indexCharArray#" GenPrimOp
848
   ByteArray# -> Int# -> Char#
apt's avatar
apt committed
849
   {Read 8-bit character; offset in bytes.}
850
   with can_fail = True
851 852

primop IndexByteArrayOp_WideChar "indexWideCharArray#" GenPrimOp
853
   ByteArray# -> Int# -> Char#
apt's avatar
apt committed
854
   {Read 31-bit character; offset in 4-byte words.}
855
   with can_fail = True
856 857

primop IndexByteArrayOp_Int "indexIntArray#" GenPrimOp
858
   ByteArray# -> Int# -> Int#
859
   with can_fail = True
860 861

primop IndexByteArrayOp_Word "indexWordArray#" GenPrimOp
862
   ByteArray# -> Int# -> Word#
863
   with can_fail = True
864 865

primop IndexByteArrayOp_Addr "indexAddrArray#" GenPrimOp
866
   ByteArray# -> Int# -> Addr#
867
   with can_fail = True
868 869

primop IndexByteArrayOp_Float "indexFloatArray#" GenPrimOp
870
   ByteArray# -> Int# -> Float#
871
   with can_fail = True
872 873

primop IndexByteArrayOp_Double "indexDoubleArray#" GenPrimOp
874
   ByteArray# -> Int# -> Double#
875
   with can_fail = True
876 877

primop IndexByteArrayOp_StablePtr "indexStablePtrArray#" GenPrimOp
878
   ByteArray# -> Int# -> StablePtr# a
879
   with can_fail = True
880 881

primop IndexByteArrayOp_Int8 "indexInt8Array#" GenPrimOp
882
   ByteArray# -> Int# -> Int#
883
   with can_fail = True
884 885

primop IndexByteArrayOp_Int16 "indexInt16Array#" GenPrimOp
886
   ByteArray# -> Int# -> Int#
887
   with can_fail = True
888 889

primop IndexByteArrayOp_Int32 "indexInt32Array#" GenPrimOp
890
   ByteArray# -> Int# -> INT32
891
   with can_fail = True
892 893

primop IndexByteArrayOp_Int64 "indexInt64Array#" GenPrimOp
894
   ByteArray# -> Int# -> INT64
895
   with can_fail = True
896 897

primop IndexByteArrayOp_Word8 "indexWord8Array#" GenPrimOp
898
   ByteArray# -> Int# -> Word#
899
   with can_fail = True
900 901

primop IndexByteArrayOp_Word16 "indexWord16Array#" GenPrimOp
902
   ByteArray# -> Int# -> Word#
903
   with can_fail = True
904 905

primop IndexByteArrayOp_Word32 "indexWord32Array#" GenPrimOp
906
   ByteArray# -> Int# -> WORD32
907
   with can_fail = True
908 909

primop IndexByteArrayOp_Word64 "indexWord64Array#" GenPrimOp
910
   ByteArray# -> Int# -> WORD64
911
   with can_fail = True
912

913
primop  ReadByteArrayOp_Char "readCharArray#" GenPrimOp
914
   MutableByteArray# s -> Int# -> State# s -> (# State# s, Char# #)
apt's avatar
apt committed
915
   {Read 8-bit character; offset in bytes.}
916
   with has_side_effects = True
917
        can_fail = True
918

919
primop  ReadByteArrayOp_WideChar "readWideCharArray#" GenPrimOp
920
   MutableByteArray# s -> Int# -> State# s -> (# State# s, Char# #)
apt's avatar
apt committed
921
   {Read 31-bit character; offset in 4-byte words.}
922
   with has_side_effects = True
923
        can_fail = True
924

925
primop  ReadByteArrayOp_Int "readIntArray#" GenPrimOp
926
   MutableByteArray# s -> Int# -> State# s -> (# State# s, Int# #)
927
   with has_side_effects = True
928
        can_fail = True
929 930

primop  ReadByteArrayOp_Word "readWordArray#" GenPrimOp
931
   MutableByteArray# s -> Int# -> State# s -> (# State# s, Word# #)
932
   with has_side_effects = True
933
        can_fail = True
934 935

primop  ReadByteArrayOp_Addr "readAddrArray#" GenPrimOp
936
   MutableByteArray# s -> Int# -> State# s -> (# State# s, Addr# #)
937
   with has_side_effects = True
938
        can_fail = True
939 940

primop  ReadByteArrayOp_Float "readFloatArray#" GenPrimOp
941
   MutableByteArray# s -> Int# -> State# s -> (# State# s, Float# #)
942
   with has_side_effects = True
943
        can_fail = True
944 945

primop  ReadByteArrayOp_Double "readDoubleArray#" GenPrimOp
<