primops.txt.pp 78 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 lazyDmd) TopRes) }
49

50

51 52 53
-- 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
54 55

#include "MachDeps.h"
56

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

section "The word size story."
61 62 63 64 65 66 67 68 69 70 71 72 73 74 75
	{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
76
	
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
	 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
104 105
	 \texttt{indexInt32Array\#} has type {\tt ByteArray\# -> Int\#
	 -> Int\#}; otherwise it has type {\tt ByteArray\# -> Int\# ->
106 107
	 Int32\#}.  This approach confines the necessary {\tt
	 \#if}-defs to this file; no conditional compilation is needed
108
	 in the files that expose these primops.
109 110 111 112 113 114 115

	 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
116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133
	
-- 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
134 135

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

140
primtype Char#
141

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

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

apt's avatar
apt committed
149 150 151 152 153 154 155 156
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#
157
   with code_size = 0
158

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

164 165
primtype Int#

apt's avatar
apt committed
166 167 168
primop   IntAddOp    "+#"    Dyadic
   Int# -> Int# -> Int#
   with commutable = True
169

apt's avatar
apt committed
170
primop   IntSubOp    "-#"    Dyadic   Int# -> Int# -> Int#
171

apt's avatar
apt committed
172 173
primop   IntMulOp    "*#" 
   Dyadic   Int# -> Int# -> Int#
174 175 176 177
   {Low word of signed integer multiply.}
   with commutable = True

primop   IntMulMayOfloOp  "mulIntMayOflo#" 
178 179
   Dyadic   Int# -> Int# -> Int#
   {Return non-zero if there is any possibility that the upper word of a
180
    signed integer multiply might contain useful information.  Return
181
    zero only if you are completely sure that no overflow can occur.
182
    On a 32-bit platform, the recommmended implementation is to do a 
183 184 185 186
    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.
187 188 189 190 191 192 193 194 195 196

    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
197
    \texttt{(*) :: Integer -> Integer -> Integer} will be poor.
198
   }
apt's avatar
apt committed
199 200 201 202 203 204 205 206 207 208 209 210
   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

211 212 213 214 215
primop   IntQuotRemOp "quotRemInt#"    GenPrimOp
   Int# -> Int# -> (# Int#, Int# #)
   {Rounds towards zero.}
   with can_fail = True

apt's avatar
apt committed
216 217
primop   IntNegOp    "negateInt#"    Monadic   Int# -> Int#
primop   IntAddCOp   "addIntC#"    GenPrimOp   Int# -> Int# -> (# Int#, Int# #)
218 219
	 {Add with carry.  First member of result is (wrapped) sum; 
          second member is 0 iff no overflow occured.}
220 221
   with code_size = 2

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

apt's avatar
apt committed
227 228 229 230 231 232 233 234 235 236 237 238 239 240 241
primop   IntGtOp  ">#"   Compare   Int# -> Int# -> Bool
primop   IntGeOp  ">=#"   Compare   Int# -> Int# -> Bool

primop   IntEqOp  "==#"   Compare
   Int# -> Int# -> Bool
   with commutable = True

primop   IntNeOp  "/=#"   Compare
   Int# -> Int# -> Bool
   with commutable = True

primop   IntLtOp  "<#"   Compare   Int# -> Int# -> Bool
primop   IntLeOp  "<=#"   Compare   Int# -> Int# -> Bool

primop   ChrOp   "chr#"   GenPrimOp   Int# -> Char#
242
   with code_size = 0
apt's avatar
apt committed
243 244

primop   Int2WordOp "int2Word#" GenPrimOp Int# -> Word#
245 246
   with code_size = 0

apt's avatar
apt committed
247 248 249
primop   Int2FloatOp   "int2Float#"      GenPrimOp  Int# -> Float#
primop   Int2DoubleOp   "int2Double#"          GenPrimOp  Int# -> Double#

250
primop   ISllOp   "uncheckedIShiftL#" GenPrimOp  Int# -> Int# -> Int#
251 252
	 {Shift left.  Result undefined if shift amount is not
          in the range 0 to word size - 1 inclusive.}
253
primop   ISraOp   "uncheckedIShiftRA#" GenPrimOp Int# -> Int# -> Int#
254 255
	 {Shift right arithmetic.  Result undefined if shift amount is not
          in the range 0 to word size - 1 inclusive.}
256
primop   ISrlOp   "uncheckedIShiftRL#" GenPrimOp Int# -> Int# -> Int#
257 258
	 {Shift right logical.  Result undefined if shift amount is not
          in the range 0 to word size - 1 inclusive.}
259 260

------------------------------------------------------------------------
apt's avatar
apt committed
261 262
section "Word#"
	{Operations on native-sized unsigned words (30+ bits).}
263 264
------------------------------------------------------------------------

265 266
primtype Word#

apt's avatar
apt committed
267 268
primop   WordAddOp   "plusWord#"   Dyadic   Word# -> Word# -> Word#
   with commutable = True
269

Ian Lynagh's avatar
Ian Lynagh committed
270
-- Returns (# high, low #) (or equivalently, (# carry, low #))
Ian Lynagh's avatar
Ian Lynagh committed
271 272 273 274
primop   WordAdd2Op  "plusWord2#"  GenPrimOp
   Word# -> Word# -> (# Word#, Word# #)
   with commutable = True

apt's avatar
apt committed
275 276 277
primop   WordSubOp   "minusWord#"   Dyadic   Word# -> Word# -> Word#

primop   WordMulOp   "timesWord#"   Dyadic   Word# -> Word# -> Word#
278 279
   with commutable = True

Ian Lynagh's avatar
Ian Lynagh committed
280
-- Returns (# high, low #)
Ian Lynagh's avatar
Ian Lynagh committed
281 282 283 284
primop   WordMul2Op  "timesWord2#"   GenPrimOp
   Word# -> Word# -> (# Word#, Word# #)
   with commutable = True

apt's avatar
apt committed
285 286 287 288 289 290
primop   WordQuotOp   "quotWord#"   Dyadic   Word# -> Word# -> Word#
   with can_fail = True

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

291 292 293 294
primop   WordQuotRemOp "quotRemWord#" GenPrimOp
   Word# -> Word# -> (# Word#, Word# #)
   with can_fail = True

Ian Lynagh's avatar
Ian Lynagh committed
295 296 297 298 299 300
-- 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
301
primop   AndOp   "and#"   Dyadic   Word# -> Word# -> Word#
302 303
   with commutable = True

apt's avatar
apt committed
304 305 306 307 308 309 310 311
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#

312
primop   SllOp   "uncheckedShiftL#"   GenPrimOp   Word# -> Int# -> Word#
313 314
	 {Shift left logical.   Result undefined if shift amount is not
          in the range 0 to word size - 1 inclusive.}
315
primop   SrlOp   "uncheckedShiftRL#"   GenPrimOp   Word# -> Int# -> Word#
316 317
	 {Shift right logical.   Result undefined if shift  amount is not
          in the range 0 to word size - 1 inclusive.}
apt's avatar
apt committed
318 319

primop   Word2IntOp   "word2Int#"   GenPrimOp   Word# -> Int#
320
   with code_size = 0
apt's avatar
apt committed
321 322 323 324 325 326 327 328

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
329 330 331 332 333 334
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
335
primop   PopCnt64Op   "popCnt64#"   GenPrimOp   WORD64 -> Word#
tibbe's avatar
tibbe committed
336 337 338 339
    {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
340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355
------------------------------------------------------------------------
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#"
356 357
	{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
358 359 360
	 are not primops; they are implemented (if needed) as ccalls instead.}
------------------------------------------------------------------------

361 362
primtype Int32#

apt's avatar
apt committed
363 364 365
------------------------------------------------------------------------
section "Word32#"
	{Operations on 32-bit unsigned words. This type is only used 
366
	 if plain {\tt Word\#} has less than 32 bits. In any case, the operations
apt's avatar
apt committed
367 368 369
	 are not primops; they are implemented (if needed) as ccalls instead.}
------------------------------------------------------------------------

370 371
primtype Word32#

apt's avatar
apt committed
372 373 374 375 376 377 378
#endif 


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

383 384
primtype Int64#

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

392 393
primtype Word64#

apt's avatar
apt committed
394 395
#endif

396
------------------------------------------------------------------------
apt's avatar
apt committed
397 398
section "Double#"
	{Operations on double-precision (64 bit) floating-point numbers.}
399 400
------------------------------------------------------------------------

401 402
primtype Double#

403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433
primop   DoubleGtOp ">##"   Compare   Double# -> Double# -> Bool
primop   DoubleGeOp ">=##"   Compare   Double# -> Double# -> Bool

primop DoubleEqOp "==##"   Compare
   Double# -> Double# -> Bool
   with commutable = True

primop DoubleNeOp "/=##"   Compare
   Double# -> Double# -> Bool
   with commutable = True

primop   DoubleLtOp "<##"   Compare   Double# -> Double# -> Bool
primop   DoubleLeOp "<=##"   Compare   Double# -> Double# -> Bool

primop   DoubleAddOp   "+##"   Dyadic
   Double# -> Double# -> Double#
   with commutable = True

primop   DoubleSubOp   "-##"   Dyadic   Double# -> Double# -> Double#

primop   DoubleMulOp   "*##"   Dyadic
   Double# -> Double# -> Double#
   with commutable = True

primop   DoubleDivOp   "/##"   Dyadic
   Double# -> Double# -> Double#
   with can_fail = True

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

primop   Double2IntOp   "double2Int#"          GenPrimOp  Double# -> Int#
434 435 436 437
   {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#}.}

438 439 440 441
primop   Double2FloatOp   "double2Float#" GenPrimOp Double# -> Float#

primop   DoubleExpOp   "expDouble#"      Monadic
   Double# -> Double#
442 443
   with
   code_size = { primOpCodeSizeForeignCall }
444 445 446 447

primop   DoubleLogOp   "logDouble#"      Monadic         
   Double# -> Double#
   with
448
   code_size = { primOpCodeSizeForeignCall }
449 450 451 452
   can_fail = True

primop   DoubleSqrtOp   "sqrtDouble#"      Monadic  
   Double# -> Double#
453 454
   with
   code_size = { primOpCodeSizeForeignCall }
455 456 457

primop   DoubleSinOp   "sinDouble#"      Monadic          
   Double# -> Double#
458 459
   with
   code_size = { primOpCodeSizeForeignCall }
460 461 462

primop   DoubleCosOp   "cosDouble#"      Monadic          
   Double# -> Double#
463 464
   with
   code_size = { primOpCodeSizeForeignCall }
465 466 467

primop   DoubleTanOp   "tanDouble#"      Monadic          
   Double# -> Double#
468 469
   with
   code_size = { primOpCodeSizeForeignCall }
470 471 472 473

primop   DoubleAsinOp   "asinDouble#"      Monadic 
   Double# -> Double#
   with
474
   code_size = { primOpCodeSizeForeignCall }
475 476 477 478 479
   can_fail = True

primop   DoubleAcosOp   "acosDouble#"      Monadic  
   Double# -> Double#
   with
480
   code_size = { primOpCodeSizeForeignCall }
481 482 483 484 485
   can_fail = True

primop   DoubleAtanOp   "atanDouble#"      Monadic  
   Double# -> Double#
   with
486
   code_size = { primOpCodeSizeForeignCall }
487 488 489

primop   DoubleSinhOp   "sinhDouble#"      Monadic  
   Double# -> Double#
490 491
   with
   code_size = { primOpCodeSizeForeignCall }
492 493 494

primop   DoubleCoshOp   "coshDouble#"      Monadic  
   Double# -> Double#
495 496
   with
   code_size = { primOpCodeSizeForeignCall }
497 498 499

primop   DoubleTanhOp   "tanhDouble#"      Monadic  
   Double# -> Double#
500 501
   with
   code_size = { primOpCodeSizeForeignCall }
502 503 504

primop   DoublePowerOp   "**##" Dyadic  
   Double# -> Double# -> Double#
apt's avatar
apt committed
505
   {Exponentiation.}
506 507
   with
   code_size = { primOpCodeSizeForeignCall }
508

509
primop   DoubleDecode_2IntOp   "decodeDouble_2Int#" GenPrimOp    
510
   Double# -> (# Int#, Word#, Word#, Int# #)
511
   {Convert to integer.
512 513 514
    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.}
515 516
   with out_of_line = True

517
------------------------------------------------------------------------
apt's avatar
apt committed
518 519
section "Float#" 
	{Operations on single-precision (32-bit) floating-point numbers.}
520 521
------------------------------------------------------------------------

522 523
primtype Float#

524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554
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#
555 556 557
   {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#}.}
558 559 560

primop   FloatExpOp   "expFloat#"      Monadic          
   Float# -> Float#
561 562
   with
   code_size = { primOpCodeSizeForeignCall }
563 564 565

primop   FloatLogOp   "logFloat#"      Monadic          
   Float# -> Float#
566 567 568
   with
   code_size = { primOpCodeSizeForeignCall }
   can_fail = True
569 570 571

primop   FloatSqrtOp   "sqrtFloat#"      Monadic          
   Float# -> Float#
572 573
   with
   code_size = { primOpCodeSizeForeignCall }
574 575 576

primop   FloatSinOp   "sinFloat#"      Monadic          
   Float# -> Float#
577 578
   with
   code_size = { primOpCodeSizeForeignCall }
579 580 581

primop   FloatCosOp   "cosFloat#"      Monadic          
   Float# -> Float#
582 583
   with
   code_size = { primOpCodeSizeForeignCall }
584 585 586

primop   FloatTanOp   "tanFloat#"      Monadic          
   Float# -> Float#
587 588
   with
   code_size = { primOpCodeSizeForeignCall }
589 590 591

primop   FloatAsinOp   "asinFloat#"      Monadic          
   Float# -> Float#
592 593 594
   with
   code_size = { primOpCodeSizeForeignCall }
   can_fail = True
595 596 597

primop   FloatAcosOp   "acosFloat#"      Monadic          
   Float# -> Float#
598 599 600
   with
   code_size = { primOpCodeSizeForeignCall }
   can_fail = True
601 602 603

primop   FloatAtanOp   "atanFloat#"      Monadic          
   Float# -> Float#
604 605
   with
   code_size = { primOpCodeSizeForeignCall }
606 607 608

primop   FloatSinhOp   "sinhFloat#"      Monadic          
   Float# -> Float#
609 610
   with
   code_size = { primOpCodeSizeForeignCall }
611 612 613

primop   FloatCoshOp   "coshFloat#"      Monadic          
   Float# -> Float#
614 615
   with
   code_size = { primOpCodeSizeForeignCall }
616 617 618

primop   FloatTanhOp   "tanhFloat#"      Monadic          
   Float# -> Float#
619 620
   with
   code_size = { primOpCodeSizeForeignCall }
621 622 623

primop   FloatPowerOp   "powerFloat#"      Dyadic   
   Float# -> Float# -> Float#
624 625
   with
   code_size = { primOpCodeSizeForeignCall }
626 627 628

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

629 630
primop   FloatDecode_IntOp   "decodeFloat_Int#" GenPrimOp
   Float# -> (# Int#, Int# #)
631
   {Convert to integers.
632 633 634
    First {\tt Int\#} in result is the mantissa; second is the exponent.}
   with out_of_line = True

635
------------------------------------------------------------------------
apt's avatar
apt committed
636
section "Arrays"
637
	{Operations on {\tt Array\#}.}
638 639
------------------------------------------------------------------------

640 641
primtype Array# a

642
primtype MutableArray# s a
643

apt's avatar
apt committed
644
primop  NewArrayOp "newArray#" GenPrimOp
645
   Int# -> a -> State# s -> (# State# s, MutableArray# s a #)
646
   {Create a new mutable array with the specified number of elements,
apt's avatar
apt committed
647 648 649 650
    in the specified state thread,
    with each element containing the specified initial value.}
   with
   out_of_line = True
651
   has_side_effects = True
652

apt's avatar
apt committed
653
primop  SameMutableArrayOp "sameMutableArray#" GenPrimOp
654
   MutableArray# s a -> MutableArray# s a -> Bool
655

apt's avatar
apt committed
656
primop  ReadArrayOp "readArray#" GenPrimOp
657
   MutableArray# s a -> Int# -> State# s -> (# State# s, a #)
apt's avatar
apt committed
658
   {Read from specified index of mutable array. Result is not yet evaluated.}
659 660
   with
   has_side_effects = True
661
   can_fail         = True
662

apt's avatar
apt committed
663
primop  WriteArrayOp "writeArray#" GenPrimOp
664
   MutableArray# s a -> Int# -> a -> State# s -> State# s
apt's avatar
apt committed
665 666 667
   {Write to specified index of mutable array.}
   with
   has_side_effects = True
668 669
   can_fail         = True
   code_size        = 2 -- card update too
670

pumpkin's avatar
pumpkin committed
671 672 673 674 675 676 677 678
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
679 680 681 682
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.}
683 684
   with
   can_fail         = True
685

apt's avatar
apt committed
686
primop  UnsafeFreezeArrayOp "unsafeFreezeArray#" GenPrimOp
687
   MutableArray# s a -> State# s -> (# State# s, Array# a #)
apt's avatar
apt committed
688 689 690
   {Make a mutable array immutable, without copying.}
   with
   has_side_effects = True
691

apt's avatar
apt committed
692
primop  UnsafeThawArrayOp  "unsafeThawArray#" GenPrimOp
693
   Array# a -> State# s -> (# State# s, MutableArray# s a #)
apt's avatar
apt committed
694 695 696
   {Make an immutable array mutable, without copying.}
   with
   out_of_line = True
697
   has_side_effects = True
698

pumpkin's avatar
pumpkin committed
699 700 701 702 703 704 705
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
706
  can_fail         = True
707
  code_size = { primOpCodeSizeForeignCall + 4 }
pumpkin's avatar
pumpkin committed
708 709 710 711 712 713 714

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
715
  can_fail         = True
716
  code_size = { primOpCodeSizeForeignCall + 4 }
pumpkin's avatar
pumpkin committed
717 718 719 720 721 722 723

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
724
  code_size = { primOpCodeSizeForeignCall + 4 }
pumpkin's avatar
pumpkin committed
725 726 727 728 729 730 731

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
732
  code_size = { primOpCodeSizeForeignCall + 4 }
pumpkin's avatar
pumpkin committed
733 734 735 736 737 738 739

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
740
  code_size = { primOpCodeSizeForeignCall + 4 }
pumpkin's avatar
pumpkin committed
741 742 743 744 745 746 747

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
748
  code_size = { primOpCodeSizeForeignCall + 4 }
pumpkin's avatar
pumpkin committed
749

750
------------------------------------------------------------------------
apt's avatar
apt committed
751
section "Byte Arrays"
752
	{Operations on {\tt ByteArray\#}. A {\tt ByteArray\#} is a just a region of
753
         raw memory in the garbage-collected heap, which is not
754 755
         scanned for pointers. It carries its own size (in bytes).
         There are
756 757 758 759
         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
760
         an offset measured in terms of the size of the primitive type
761
         being read or written.}
762

763 764
------------------------------------------------------------------------

765
primtype ByteArray#
766

767
primtype MutableByteArray# s
768

769
primop  NewByteArrayOp_Char "newByteArray#" GenPrimOp
770
   Int# -> State# s -> (# State# s, MutableByteArray# s #)
apt's avatar
apt committed
771 772
   {Create a new mutable byte array of specified size (in bytes), in
    the specified state thread.}
773
   with out_of_line = True
774
        has_side_effects = True
775

776
primop  NewPinnedByteArrayOp_Char "newPinnedByteArray#" GenPrimOp
777
   Int# -> State# s -> (# State# s, MutableByteArray# s #)
apt's avatar
apt committed
778
   {Create a mutable byte array that the GC guarantees not to move.}
779
   with out_of_line = True
780
        has_side_effects = True
781

Simon Marlow's avatar
Simon Marlow committed
782 783 784 785
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
786
        has_side_effects = True
Simon Marlow's avatar
Simon Marlow committed
787

788
primop  ByteArrayContents_Char "byteArrayContents#" GenPrimOp
789
   ByteArray# -> Addr#
apt's avatar
apt committed
790 791 792
   {Intended for use with pinned arrays; otherwise very unsafe!}

primop  SameMutableByteArrayOp "sameMutableByteArray#" GenPrimOp
793
   MutableByteArray# s -> MutableByteArray# s -> Bool
apt's avatar
apt committed
794 795

primop  UnsafeFreezeByteArrayOp "unsafeFreezeByteArray#" GenPrimOp
796
   MutableByteArray# s -> State# s -> (# State# s, ByteArray# #)
apt's avatar
apt committed
797 798 799 800 801
   {Make a mutable byte array immutable, without copying.}
   with
   has_side_effects = True

primop  SizeofByteArrayOp "sizeofByteArray#" GenPrimOp  
802
   ByteArray# -> Int#
803
   {Return the size of the array in bytes.}
apt's avatar
apt committed
804 805

primop  SizeofMutableByteArrayOp "sizeofMutableByteArray#" GenPrimOp
806
   MutableByteArray# s -> Int#
807
   {Return the size of the array in bytes.}
808

809
primop IndexByteArrayOp_Char "indexCharArray#" GenPrimOp
810
   ByteArray# -> Int# -> Char#
apt's avatar
apt committed
811
   {Read 8-bit character; offset in bytes.}
812
   with can_fail = True
813 814

primop IndexByteArrayOp_WideChar "indexWideCharArray#" GenPrimOp
815
   ByteArray# -> Int# -> Char#
apt's avatar
apt committed
816
   {Read 31-bit character; offset in 4-byte words.}
817
   with can_fail = True
818 819

primop IndexByteArrayOp_Int "indexIntArray#" GenPrimOp
820
   ByteArray# -> Int# -> Int#
821
   with can_fail = True
822 823

primop IndexByteArrayOp_Word "indexWordArray#" GenPrimOp
824
   ByteArray# -> Int# -> Word#
825
   with can_fail = True
826 827

primop IndexByteArrayOp_Addr "indexAddrArray#" GenPrimOp
828
   ByteArray# -> Int# -> Addr#
829
   with can_fail = True
830 831

primop IndexByteArrayOp_Float "indexFloatArray#" GenPrimOp
832
   ByteArray# -> Int# -> Float#
833
   with can_fail = True
834 835

primop IndexByteArrayOp_Double "indexDoubleArray#" GenPrimOp
836
   ByteArray# -> Int# -> Double#
837
   with can_fail = True
838 839

primop IndexByteArrayOp_StablePtr "indexStablePtrArray#" GenPrimOp
840
   ByteArray# -> Int# -> StablePtr# a
841
   with can_fail = True
842 843

primop IndexByteArrayOp_Int8 "indexInt8Array#" GenPrimOp
844
   ByteArray# -> Int# -> Int#
845
   with can_fail = True
846 847

primop IndexByteArrayOp_Int16 "indexInt16Array#" GenPrimOp
848
   ByteArray# -> Int# -> Int#
849
   with can_fail = True
850 851

primop IndexByteArrayOp_Int32 "indexInt32Array#" GenPrimOp
852
   ByteArray# -> Int# -> INT32
853
   with can_fail = True
854 855

primop IndexByteArrayOp_Int64 "indexInt64Array#" GenPrimOp
856
   ByteArray# -> Int# -> INT64
857
   with can_fail = True
858 859

primop IndexByteArrayOp_Word8 "indexWord8Array#" GenPrimOp
860
   ByteArray# -> Int# -> Word#
861
   with can_fail = True
862 863

primop IndexByteArrayOp_Word16 "indexWord16Array#" GenPrimOp
864
   ByteArray# -> Int# -> Word#
865
   with can_fail = True
866 867

primop IndexByteArrayOp_Word32 "indexWord32Array#" GenPrimOp
868
   ByteArray# -> Int# -> WORD32
869
   with can_fail = True
870 871

primop IndexByteArrayOp_Word64 "indexWord64Array#" GenPrimOp
872
   ByteArray# -> Int# -> WORD64
873
   with can_fail = True
874

875
primop  ReadByteArrayOp_Char "readCharArray#" GenPrimOp
876
   MutableByteArray# s -> Int# -> State# s -> (# State# s, Char# #)
apt's avatar
apt committed
877
   {Read 8-bit character; offset in bytes.}
878
   with has_side_effects = True
879
        can_fail = True
880

881
primop  ReadByteArrayOp_WideChar "readWideCharArray#" GenPrimOp
882
   MutableByteArray# s -> Int# -> State# s -> (# State# s, Char# #)
apt's avatar
apt committed
883
   {Read 31-bit character; offset in 4-byte words.}
884
   with has_side_effects = True
885
        can_fail = True
886

887
primop  ReadByteArrayOp_Int "readIntArray#" GenPrimOp
888
   MutableByteArray# s -> Int# -> State# s -> (# State# s, Int# #)
889
   with has_side_effects = True
890
        can_fail = True
891 892

primop  ReadByteArrayOp_Word "readWordArray#" GenPrimOp
893
   MutableByteArray# s -> Int# -> State# s -> (# State# s, Word# #)
894
   with has_side_effects = True
895
        can_fail = True
896 897

primop  ReadByteArrayOp_Addr "readAddrArray#" GenPrimOp
898
   MutableByteArray# s -> Int# -> State# s -> (# State# s, Addr# #)
899
   with has_side_effects = True
900
        can_fail = True
901 902

primop  ReadByteArrayOp_Float "readFloatArray#" GenPrimOp
903
   MutableByteArray# s -> Int# -> State# s -> (# State# s, Float# #)
904
   with has_side_effects = True
905
        can_fail = True
906 907

primop  ReadByteArrayOp_Double "readDoubleArray#" GenPrimOp
908
   MutableByteArray# s -> Int# -> State# s -> (# State# s, Double# #)
909
   with has_side_effects = True
910
        can_fail = True
911 912

primop  ReadByteArrayOp_StablePtr "readStablePtrArray#" GenPrimOp
913
   MutableByteArray# s -> Int# -> State# s -> (# State# s, StablePtr# a #)
914
   with has_side_effects = True
915
        can_fail = True
916

917
primop  ReadByteArrayOp_Int8 "readInt8Array#" GenPrimOp
918
   MutableByteArray# s -> Int# -> State# s -> (# State# s, Int# #)
919
   with has_side_effects = True
920
        can_fail = True
921 922

primop  ReadByteArrayOp_Int16 "readInt16Array#" GenPrimOp
923
   MutableByteArray# s -> Int# -> State# s -> (# State# s, Int# #)
924
   with has_side_effects = True
925
        can_fail = True
926 927

primop  ReadByteArrayOp_Int32 "readInt32Array#" GenPrimOp
928
   MutableByteArray# s -> Int# -> State# s -> (# State# s, INT32 #)
929
   with has_side_effects = True
930
        can_fail = True
931

932
primop  ReadByteArrayOp_Int64 "readInt64Array#" GenPrimOp
933
   MutableByteArray# s -> Int# -> State# s -> (# State# s, INT64 #)
934
   with has_side_effects = True
935
        can_fail = True
936

937
primop  ReadByteArrayOp_Word8 "readWord8Array#" GenPrimOp
938
   MutableByteArray# s -> Int# -> State# s -> (# State# s, Word# #)
939
   with has_side_effects = True
940
        can_fail = True
941 942

primop  ReadByteArrayOp_Word16 "readWord16Array#" GenPrimOp
943
   MutableByteArray# s -> Int# -> State# s -> (# State# s, Word# #)
944
   with has_side_effects = True
945
        can_fail = True
946 947

primop  ReadByteArrayOp_Word32 "readWord32Array#" GenPrimOp
948
   MutableByteArray# s -> Int# -> State# s -> (# State# s, WORD32 #)
949
   with has_side_effects = True
950
        can_fail = True
951

952
primop  ReadByteArrayOp_Word64 "readWord64Array#" GenPrimOp
953
   MutableByteArray# s -> Int# -> State# s -> (# State# s, WORD64 #)
954
   with has_side_effects = True
955
        can_fail = True
956 957

primop  WriteByteArrayOp_Char "writeCharArray#" GenPrimOp
Ian Lynagh's avatar