primops.txt.pp 62.9 KB
Newer Older
1
-----------------------------------------------------------------------
2
-- $Id: primops.txt.pp,v 1.37 2005/11/25 09:46:19 simonmar Exp $
3
--
4
-- Primitive Operations and Types
5
6
7
--
-----------------------------------------------------------------------

apt's avatar
apt committed
8
9
10
11
12
13
-- 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.
--
14
15
-- To add a new primop, you currently need to update the following files:
--
16
--	- this file (ghc/compiler/prelude/primops.txt.pp), which includes
17
18
19
20
21
--	  the type of the primop, and various other properties (its
--	  strictness attributes, whether it is defined as a macro
--	  or as out-of-line code, etc.)
--
--	- if the primop is inline (i.e. a macro), then:
22
23
24
--	  	ghc/compiler/AbsCUtils.lhs (dscCOpStmt)
--		  defines the translation of the primop into simpler
--		  abstract C operations.
apt's avatar
apt committed
25
--		
26
--	- or, for an out-of-line primop:
27
28
--	        ghc/includes/StgMiscClosures.h (just add the declaration)
--		ghc/rts/PrimOps.cmm     (define it here)
29
--		ghc/rts/Linker.c       (declare the symbol for GHCi)
30
--
apt's avatar
apt committed
31
32
33
--	- the User's Guide 
--

34
35
-- This file is divided into named sections, each containing or more
-- primop entries. Section headers have the format:
apt's avatar
apt committed
36
37
38
--
--	section "section-name" {description}
--
39
40
-- This information is used solely when producing documentation; it is
-- otherwise ignored.  The description is optional.
apt's avatar
apt committed
41
42
--
-- The format of each primop entry is as follows:
43
--
apt's avatar
apt committed
44
--	primop internal-name "name-in-program-text" type category {description} attributes
45

apt's avatar
apt committed
46
-- The default attribute values which apply if you don't specify
47
48
49
50
-- 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
51
-- needed for strictness info.
52
53
54
55
56
57
58

defaults
   has_side_effects = False
   out_of_line      = False
   commutable       = False
   needs_wrapper    = False
   can_fail         = False
59
   strictness       = { \ arity -> mkStrictSig (mkTopDmdType (replicate arity lazyDmd) TopRes) }
60

61
62
63
-- 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
64
65

#include "MachDeps.h"
66
67
68
69
70

-- We need platform defines (tests for mingw32 below).  However, we only
-- test the TARGET platform, which doesn't vary between stages, so the
-- stage1 platform defines are fine:
#include "../stage1/ghc_boot_platform.h"
apt's avatar
apt committed
71
72

section "The word size story."
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
	{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
88
	
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
	 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
	 \texttt{indexInt32Array\#} has type {\tt ByteArr\# -> Int\#
	 -> Int\#}; otherwise it has type {\tt ByteArr\# -> Int\# ->
	 Int32\#}.  This approach confines the necessary {\tt
	 \#if}-defs to this file; no conditional compilation is needed
120
	 in the files that expose these primops.
121
122
123
124
125
126
127

	 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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
	
-- 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
146
147

------------------------------------------------------------------------
apt's avatar
apt committed
148
149
section "Char#" 
	{Operations on 31-bit characters.}
150
151
------------------------------------------------------------------------

152
primtype Char#
153

apt's avatar
apt committed
154
155
primop   CharGtOp  "gtChar#"   Compare   Char# -> Char# -> Bool
primop   CharGeOp  "geChar#"   Compare   Char# -> Char# -> Bool
156

apt's avatar
apt committed
157
158
159
primop   CharEqOp  "eqChar#"   Compare
   Char# -> Char# -> Bool
   with commutable = True
160

apt's avatar
apt committed
161
162
163
164
165
166
167
168
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#
169

170
------------------------------------------------------------------------
apt's avatar
apt committed
171
172
section "Int#"
	{Operations on native-size integers (30+ bits).}
173
174
------------------------------------------------------------------------

175
176
primtype Int#

apt's avatar
apt committed
177
178
179
primop   IntAddOp    "+#"    Dyadic
   Int# -> Int# -> Int#
   with commutable = True
180

apt's avatar
apt committed
181
primop   IntSubOp    "-#"    Dyadic   Int# -> Int# -> Int#
182

apt's avatar
apt committed
183
184
primop   IntMulOp    "*#" 
   Dyadic   Int# -> Int# -> Int#
185
186
187
188
   {Low word of signed integer multiply.}
   with commutable = True

primop   IntMulMayOfloOp  "mulIntMayOflo#" 
189
190
   Dyadic   Int# -> Int# -> Int#
   {Return non-zero if there is any possibility that the upper word of a
191
    signed integer multiply might contain useful information.  Return
192
    zero only if you are completely sure that no overflow can occur.
193
    On a 32-bit platform, the recommmended implementation is to do a 
194
195
196
197
    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.
198
199
200
201
202
203
204
205
206
207

    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
208
    \texttt{(*) :: Integer -> Integer -> Integer} will be poor.
209
   }
apt's avatar
apt committed
210
211
212
213
214
215
216
217
218
219
220
221
222
   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

primop   IntGcdOp    "gcdInt#"    Dyadic   Int# -> Int# -> Int#
223
224
   with out_of_line = True

apt's avatar
apt committed
225
226
primop   IntNegOp    "negateInt#"    Monadic   Int# -> Int#
primop   IntAddCOp   "addIntC#"    GenPrimOp   Int# -> Int# -> (# Int#, Int# #)
227
228
	 {Add with carry.  First member of result is (wrapped) sum; 
          second member is 0 iff no overflow occured.}
apt's avatar
apt committed
229
primop   IntSubCOp   "subIntC#"    GenPrimOp   Int# -> Int# -> (# Int#, Int# #)
230
231
232
	 {Subtract with carry.  First member of result is (wrapped) difference; 
          second member is 0 iff no overflow occured.}

apt's avatar
apt committed
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
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#

primop   Int2WordOp "int2Word#" GenPrimOp Int# -> Word#
primop   Int2FloatOp   "int2Float#"      GenPrimOp  Int# -> Float#
primop   Int2DoubleOp   "int2Double#"          GenPrimOp  Int# -> Double#

primop   Int2IntegerOp    "int2Integer#"
   GenPrimOp Int# -> (# Int#, ByteArr# #)
   with out_of_line = True

257
primop   ISllOp   "uncheckedIShiftL#" GenPrimOp  Int# -> Int# -> Int#
258
259
	 {Shift left.  Result undefined if shift amount is not
          in the range 0 to word size - 1 inclusive.}
260
primop   ISraOp   "uncheckedIShiftRA#" GenPrimOp Int# -> Int# -> Int#
261
262
	 {Shift right arithmetic.  Result undefined if shift amount is not
          in the range 0 to word size - 1 inclusive.}
263
primop   ISrlOp   "uncheckedIShiftRL#" GenPrimOp Int# -> Int# -> Int#
264
265
	 {Shift right logical.  Result undefined if shift amount is not
          in the range 0 to word size - 1 inclusive.}
266
267

------------------------------------------------------------------------
apt's avatar
apt committed
268
269
section "Word#"
	{Operations on native-sized unsigned words (30+ bits).}
270
271
------------------------------------------------------------------------

272
273
primtype Word#

apt's avatar
apt committed
274
275
primop   WordAddOp   "plusWord#"   Dyadic   Word# -> Word# -> Word#
   with commutable = True
276

apt's avatar
apt committed
277
278
279
primop   WordSubOp   "minusWord#"   Dyadic   Word# -> Word# -> Word#

primop   WordMulOp   "timesWord#"   Dyadic   Word# -> Word# -> Word#
280
281
   with commutable = True

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

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

primop   AndOp   "and#"   Dyadic   Word# -> Word# -> Word#
289
290
   with commutable = True

apt's avatar
apt committed
291
292
293
294
295
296
297
298
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#

299
primop   SllOp   "uncheckedShiftL#"   GenPrimOp   Word# -> Int# -> Word#
300
301
	 {Shift left logical.   Result undefined if shift amount is not
          in the range 0 to word size - 1 inclusive.}
302
primop   SrlOp   "uncheckedShiftRL#"   GenPrimOp   Word# -> Int# -> Word#
303
304
	 {Shift right logical.   Result undefined if shift  amount is not
          in the range 0 to word size - 1 inclusive.}
apt's avatar
apt committed
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334

primop   Word2IntOp   "word2Int#"   GenPrimOp   Word# -> Int#

primop   Word2IntegerOp   "word2Integer#"   GenPrimOp 
   Word# -> (# Int#, ByteArr# #)
   with out_of_line = True

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

------------------------------------------------------------------------
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#"
335
336
	{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
337
338
339
	 are not primops; they are implemented (if needed) as ccalls instead.}
------------------------------------------------------------------------

340
341
primtype Int32#

apt's avatar
apt committed
342
343
344
345
346
347
348
349
primop   Int32ToIntegerOp   "int32ToInteger#" GenPrimOp 
   Int32# -> (# Int#, ByteArr# #)
   with out_of_line = True


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

354
355
primtype Word32#

apt's avatar
apt committed
356
357
358
359
360
361
362
363
364
365
366
367
primop   Word32ToIntegerOp   "word32ToInteger#" GenPrimOp
   Word32# -> (# Int#, ByteArr# #)
   with out_of_line = True


#endif 


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

372
373
primtype Int64#

apt's avatar
apt committed
374
375
376
377
378
379
380
primop   Int64ToIntegerOp   "int64ToInteger#" GenPrimOp 
   Int64# -> (# Int#, ByteArr# #)
   with out_of_line = True

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

385
386
primtype Word64#

apt's avatar
apt committed
387
388
389
390
391
392
393
394
395
396
primop   Word64ToIntegerOp   "word64ToInteger#" GenPrimOp
   Word64# -> (# Int#, ByteArr# #)
   with out_of_line = True

#endif

------------------------------------------------------------------------
section "Integer#"
	{Operations on arbitrary-precision integers. These operations are 
implemented via the GMP package. An integer is represented as a pair
397
398
consisting of an {\tt Int\#} representing the number of 'limbs' in use and
the sign, and a {\tt ByteArr\#} containing the 'limbs' themselves.  Such pairs
rrt's avatar
rrt committed
399
400
401
402
403
are returned as unboxed pairs, but must be passed as separate
components.

For .NET these operations are implemented by foreign imports, so the
primops are omitted.}
apt's avatar
apt committed
404
405
------------------------------------------------------------------------

rrt's avatar
rrt committed
406
407
#ifndef ILX

apt's avatar
apt committed
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
primop   IntegerAddOp   "plusInteger#" GenPrimOp   
   Int# -> ByteArr# -> Int# -> ByteArr# -> (# Int#, ByteArr# #)
   with commutable = True
        out_of_line = True

primop   IntegerSubOp   "minusInteger#" GenPrimOp  
   Int# -> ByteArr# -> Int# -> ByteArr# -> (# Int#, ByteArr# #)
   with out_of_line = True

primop   IntegerMulOp   "timesInteger#" GenPrimOp   
   Int# -> ByteArr# -> Int# -> ByteArr# -> (# Int#, ByteArr# #)
   with commutable = True
        out_of_line = True

primop   IntegerGcdOp   "gcdInteger#" GenPrimOp    
   Int# -> ByteArr# -> Int# -> ByteArr# -> (# Int#, ByteArr# #)
   {Greatest common divisor.}
   with commutable = True
        out_of_line = True

primop   IntegerIntGcdOp   "gcdIntegerInt#" GenPrimOp
   Int# -> ByteArr# -> Int# -> Int#
430
   {Greatest common divisor, where second argument is an ordinary {\tt Int\#}.}
431
   with out_of_line = True
apt's avatar
apt committed
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451

primop   IntegerDivExactOp   "divExactInteger#" GenPrimOp
   Int# -> ByteArr# -> Int# -> ByteArr# -> (# Int#, ByteArr# #)
   {Divisor is guaranteed to be a factor of dividend.}
   with out_of_line = True

primop   IntegerQuotOp   "quotInteger#" GenPrimOp
   Int# -> ByteArr# -> Int# -> ByteArr# -> (# Int#, ByteArr# #)
   {Rounds towards zero.}
   with out_of_line = True

primop   IntegerRemOp   "remInteger#" GenPrimOp
   Int# -> ByteArr# -> Int# -> ByteArr# -> (# Int#, ByteArr# #)
   {Satisfies \texttt{plusInteger\# (timesInteger\# (quotInteger\# x y) y) (remInteger\# x y) == x}.}
   with out_of_line = True

primop   IntegerCmpOp   "cmpInteger#"   GenPrimOp  
   Int# -> ByteArr# -> Int# -> ByteArr# -> Int#
   {Returns -1,0,1 according as first argument is less than, equal to, or greater than second argument.}
   with needs_wrapper = True
452
        out_of_line = True
apt's avatar
apt committed
453
454
455
456
457
458

primop   IntegerCmpIntOp   "cmpIntegerInt#" GenPrimOp
   Int# -> ByteArr# -> Int# -> Int#
   {Returns -1,0,1 according as first argument is less than, equal to, or greater than second argument, which
   is an ordinary Int\#.}
   with needs_wrapper = True
459
        out_of_line = True
apt's avatar
apt committed
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476

primop   IntegerQuotRemOp   "quotRemInteger#" GenPrimOp
   Int# -> ByteArr# -> Int# -> ByteArr# -> (# Int#, ByteArr#, Int#, ByteArr# #)
   {Compute quot and rem simulaneously.}
   with can_fail = True
        out_of_line = True

primop   IntegerDivModOp    "divModInteger#"  GenPrimOp
   Int# -> ByteArr# -> Int# -> ByteArr# -> (# Int#, ByteArr#, Int#, ByteArr# #)
   {Compute div and mod simultaneously, where div rounds towards negative infinity
    and\texttt{(q,r) = divModInteger\#(x,y)} implies \texttt{plusInteger\# (timesInteger\# q y) r = x}.}
   with can_fail = True
        out_of_line = True

primop   Integer2IntOp   "integer2Int#"    GenPrimOp
   Int# -> ByteArr# -> Int#
   with needs_wrapper = True
477
        out_of_line = True
apt's avatar
apt committed
478
479
480
481

primop   Integer2WordOp   "integer2Word#"   GenPrimOp
   Int# -> ByteArr# -> Word#
   with needs_wrapper = True
482
        out_of_line = True
apt's avatar
apt committed
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506

#if WORD_SIZE_IN_BITS < 32
primop   IntegerToInt32Op   "integerToInt32#" GenPrimOp
   Int# -> ByteArr# -> Int32#

primop   IntegerToWord32Op   "integerToWord32#" GenPrimOp
   Int# -> ByteArr# -> Word32#
#endif

primop   IntegerAndOp  "andInteger#" GenPrimOp
   Int# -> ByteArr# -> Int# -> ByteArr# -> (# Int#, ByteArr# #)
   with out_of_line = True

primop   IntegerOrOp  "orInteger#" GenPrimOp
   Int# -> ByteArr# -> Int# -> ByteArr# -> (# Int#, ByteArr# #)
   with out_of_line = True

primop   IntegerXorOp  "xorInteger#" GenPrimOp
   Int# -> ByteArr# -> Int# -> ByteArr# -> (# Int#, ByteArr# #)
   with out_of_line = True

primop   IntegerComplementOp  "complementInteger#" GenPrimOp
   Int# -> ByteArr# -> (# Int#, ByteArr# #)
   with out_of_line = True
507

508
#endif /* ndef ILX */
509
510

------------------------------------------------------------------------
apt's avatar
apt committed
511
512
section "Double#"
	{Operations on double-precision (64 bit) floating-point numbers.}
513
514
------------------------------------------------------------------------

515
516
primtype Double#

517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
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#
548
549
550
551
   {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#}.}

552
553
554
555
556
557
558
559
560
561
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
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
primop   Double2FloatOp   "double2Float#" GenPrimOp Double# -> Float#

primop   DoubleExpOp   "expDouble#"      Monadic
   Double# -> Double#
   with needs_wrapper = True

primop   DoubleLogOp   "logDouble#"      Monadic         
   Double# -> Double#
   with
   needs_wrapper = True
   can_fail = True

primop   DoubleSqrtOp   "sqrtDouble#"      Monadic  
   Double# -> Double#
   with needs_wrapper = True

primop   DoubleSinOp   "sinDouble#"      Monadic          
   Double# -> Double#
   with needs_wrapper = True

primop   DoubleCosOp   "cosDouble#"      Monadic          
   Double# -> Double#
   with needs_wrapper = True

primop   DoubleTanOp   "tanDouble#"      Monadic          
   Double# -> Double#
   with needs_wrapper = True

primop   DoubleAsinOp   "asinDouble#"      Monadic 
   Double# -> Double#
   with
   needs_wrapper = True
   can_fail = True

primop   DoubleAcosOp   "acosDouble#"      Monadic  
   Double# -> Double#
   with
   needs_wrapper = True
   can_fail = True

primop   DoubleAtanOp   "atanDouble#"      Monadic  
   Double# -> Double#
   with
   needs_wrapper = True

primop   DoubleSinhOp   "sinhDouble#"      Monadic  
   Double# -> Double#
   with needs_wrapper = True

primop   DoubleCoshOp   "coshDouble#"      Monadic  
   Double# -> Double#
   with needs_wrapper = True

primop   DoubleTanhOp   "tanhDouble#"      Monadic  
   Double# -> Double#
   with needs_wrapper = True

primop   DoublePowerOp   "**##" Dyadic  
   Double# -> Double# -> Double#
apt's avatar
apt committed
611
   {Exponentiation.}
612
613
614
615
   with needs_wrapper = True

primop   DoubleDecodeOp   "decodeDouble#" GenPrimOp    
   Double# -> (# Int#, Int#, ByteArr# #)
apt's avatar
apt committed
616
   {Convert to arbitrary-precision integer.
617
618
    First {\tt Int\#} in result is the exponent; second {\tt Int\#} and {\tt ByteArr\#}
    represent an {\tt Integer\#} holding the mantissa.}
619
620
621
   with out_of_line = True

------------------------------------------------------------------------
apt's avatar
apt committed
622
623
section "Float#" 
	{Operations on single-precision (32-bit) floating-point numbers.}
624
625
------------------------------------------------------------------------

626
627
primtype Float#

628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
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#
659
660
661
   {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#}.}
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721

primop   FloatExpOp   "expFloat#"      Monadic          
   Float# -> Float#
   with needs_wrapper = True

primop   FloatLogOp   "logFloat#"      Monadic          
   Float# -> Float#
   with needs_wrapper = True
        can_fail = True

primop   FloatSqrtOp   "sqrtFloat#"      Monadic          
   Float# -> Float#
   with needs_wrapper = True

primop   FloatSinOp   "sinFloat#"      Monadic          
   Float# -> Float#
   with needs_wrapper = True

primop   FloatCosOp   "cosFloat#"      Monadic          
   Float# -> Float#
   with needs_wrapper = True

primop   FloatTanOp   "tanFloat#"      Monadic          
   Float# -> Float#
   with needs_wrapper = True

primop   FloatAsinOp   "asinFloat#"      Monadic          
   Float# -> Float#
   with needs_wrapper = True
        can_fail = True

primop   FloatAcosOp   "acosFloat#"      Monadic          
   Float# -> Float#
   with needs_wrapper = True
        can_fail = True

primop   FloatAtanOp   "atanFloat#"      Monadic          
   Float# -> Float#
   with needs_wrapper = True

primop   FloatSinhOp   "sinhFloat#"      Monadic          
   Float# -> Float#
   with needs_wrapper = True

primop   FloatCoshOp   "coshFloat#"      Monadic          
   Float# -> Float#
   with needs_wrapper = True

primop   FloatTanhOp   "tanhFloat#"      Monadic          
   Float# -> Float#
   with needs_wrapper = True

primop   FloatPowerOp   "powerFloat#"      Dyadic   
   Float# -> Float# -> Float#
   with needs_wrapper = True

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

primop   FloatDecodeOp   "decodeFloat#" GenPrimOp
   Float# -> (# Int#, Int#, ByteArr# #)
apt's avatar
apt committed
722
   {Convert to arbitrary-precision integer.
723
724
    First {\tt Int\#} in result is the exponent; second {\tt Int\#} and {\tt ByteArr\#}
    represent an {\tt Integer\#} holding the mantissa.}
725
726
727
   with out_of_line = True

------------------------------------------------------------------------
apt's avatar
apt committed
728
section "Arrays"
729
	{Operations on {\tt Array\#}.}
730
731
------------------------------------------------------------------------

732
733
734
735
primtype Array# a

primtype MutArr# s a

apt's avatar
apt committed
736
737
738
739
740
741
742
primop  NewArrayOp "newArray#" GenPrimOp
   Int# -> a -> State# s -> (# State# s, MutArr# s a #)
   {Create a new mutable array of specified size (in bytes),
    in the specified state thread,
    with each element containing the specified initial value.}
   with
   out_of_line = True
743

apt's avatar
apt committed
744
745
primop  SameMutableArrayOp "sameMutableArray#" GenPrimOp
   MutArr# s a -> MutArr# s a -> Bool
746

apt's avatar
apt committed
747
748
749
primop  ReadArrayOp "readArray#" GenPrimOp
   MutArr# s a -> Int# -> State# s -> (# State# s, a #)
   {Read from specified index of mutable array. Result is not yet evaluated.}
750

apt's avatar
apt committed
751
752
753
754
755
primop  WriteArrayOp "writeArray#" GenPrimOp
   MutArr# s a -> Int# -> a -> State# s -> State# s
   {Write to specified index of mutable array.}
   with
   has_side_effects = True
756

apt's avatar
apt committed
757
758
759
760
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.}
761

apt's avatar
apt committed
762
763
764
765
766
primop  UnsafeFreezeArrayOp "unsafeFreezeArray#" GenPrimOp
   MutArr# s a -> State# s -> (# State# s, Array# a #)
   {Make a mutable array immutable, without copying.}
   with
   has_side_effects = True
767

apt's avatar
apt committed
768
769
770
771
772
primop  UnsafeThawArrayOp  "unsafeThawArray#" GenPrimOp
   Array# a -> State# s -> (# State# s, MutArr# s a #)
   {Make an immutable array mutable, without copying.}
   with
   out_of_line = True
773

774
------------------------------------------------------------------------
apt's avatar
apt committed
775
section "Byte Arrays"
776
	{Operations on {\tt ByteArray\#}. A {\tt ByteArray\#} is a just a region of
apt's avatar
apt committed
777
778
779
780
781
782
783
784
         raw memory in the garbage-collected heap, which is not scanned
         for pointers. It carries its own size (in bytes). There are
	 three sets of operations for accessing byte array contents:
	 index for reading from immutable byte arrays, and read/write
	 for mutable byte arrays.  Each set contains operations for 
	 a range of useful primitive data types.  Each operation takes	
	 an offset measured in terms of the size fo the primitive type
	 being read or written.}
785

786
787
------------------------------------------------------------------------

788
789
790
791
primtype ByteArr#

primtype MutByteArr# s

792
primop  NewByteArrayOp_Char "newByteArray#" GenPrimOp
793
   Int# -> State# s -> (# State# s, MutByteArr# s #)
apt's avatar
apt committed
794
795
   {Create a new mutable byte array of specified size (in bytes), in
    the specified state thread.}
796
797
   with out_of_line = True

798
799
primop  NewPinnedByteArrayOp_Char "newPinnedByteArray#" GenPrimOp
   Int# -> State# s -> (# State# s, MutByteArr# s #)
apt's avatar
apt committed
800
   {Create a mutable byte array that the GC guarantees not to move.}
801
802
803
804
   with out_of_line = True

primop  ByteArrayContents_Char "byteArrayContents#" GenPrimOp
   ByteArr# -> Addr#
apt's avatar
apt committed
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
   {Intended for use with pinned arrays; otherwise very unsafe!}

primop  SameMutableByteArrayOp "sameMutableByteArray#" GenPrimOp
   MutByteArr# s -> MutByteArr# s -> Bool

primop  UnsafeFreezeByteArrayOp "unsafeFreezeByteArray#" GenPrimOp
   MutByteArr# s -> State# s -> (# State# s, ByteArr# #)
   {Make a mutable byte array immutable, without copying.}
   with
   has_side_effects = True

primop  SizeofByteArrayOp "sizeofByteArray#" GenPrimOp  
   ByteArr# -> Int#

primop  SizeofMutableByteArrayOp "sizeofMutableByteArray#" GenPrimOp
   MutByteArr# s -> Int#

822

823
824
primop IndexByteArrayOp_Char "indexCharArray#" GenPrimOp
   ByteArr# -> Int# -> Char#
apt's avatar
apt committed
825
   {Read 8-bit character; offset in bytes.}
826
827
828

primop IndexByteArrayOp_WideChar "indexWideCharArray#" GenPrimOp
   ByteArr# -> Int# -> Char#
apt's avatar
apt committed
829
   {Read 31-bit character; offset in 4-byte words.}
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855

primop IndexByteArrayOp_Int "indexIntArray#" GenPrimOp
   ByteArr# -> Int# -> Int#

primop IndexByteArrayOp_Word "indexWordArray#" GenPrimOp
   ByteArr# -> Int# -> Word#

primop IndexByteArrayOp_Addr "indexAddrArray#" GenPrimOp
   ByteArr# -> Int# -> Addr#

primop IndexByteArrayOp_Float "indexFloatArray#" GenPrimOp
   ByteArr# -> Int# -> Float#

primop IndexByteArrayOp_Double "indexDoubleArray#" GenPrimOp
   ByteArr# -> Int# -> Double#

primop IndexByteArrayOp_StablePtr "indexStablePtrArray#" GenPrimOp
   ByteArr# -> Int# -> StablePtr# a

primop IndexByteArrayOp_Int8 "indexInt8Array#" GenPrimOp
   ByteArr# -> Int# -> Int#

primop IndexByteArrayOp_Int16 "indexInt16Array#" GenPrimOp
   ByteArr# -> Int# -> Int#

primop IndexByteArrayOp_Int32 "indexInt32Array#" GenPrimOp
apt's avatar
apt committed
856
   ByteArr# -> Int# -> INT32
857
858

primop IndexByteArrayOp_Int64 "indexInt64Array#" GenPrimOp
apt's avatar
apt committed
859
   ByteArr# -> Int# -> INT64
860
861
862
863
864
865
866
867

primop IndexByteArrayOp_Word8 "indexWord8Array#" GenPrimOp
   ByteArr# -> Int# -> Word#

primop IndexByteArrayOp_Word16 "indexWord16Array#" GenPrimOp
   ByteArr# -> Int# -> Word#

primop IndexByteArrayOp_Word32 "indexWord32Array#" GenPrimOp
apt's avatar
apt committed
868
   ByteArr# -> Int# -> WORD32
869
870

primop IndexByteArrayOp_Word64 "indexWord64Array#" GenPrimOp
apt's avatar
apt committed
871
   ByteArr# -> Int# -> WORD64
872

873
874
primop  ReadByteArrayOp_Char "readCharArray#" GenPrimOp
   MutByteArr# s -> Int# -> State# s -> (# State# s, Char# #)
apt's avatar
apt committed
875
   {Read 8-bit character; offset in bytes.}
876

877
878
primop  ReadByteArrayOp_WideChar "readWideCharArray#" GenPrimOp
   MutByteArr# s -> Int# -> State# s -> (# State# s, Char# #)
apt's avatar
apt committed
879
   {Read 31-bit character; offset in 4-byte words.}
880

881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
primop  ReadByteArrayOp_Int "readIntArray#" GenPrimOp
   MutByteArr# s -> Int# -> State# s -> (# State# s, Int# #)

primop  ReadByteArrayOp_Word "readWordArray#" GenPrimOp
   MutByteArr# s -> Int# -> State# s -> (# State# s, Word# #)

primop  ReadByteArrayOp_Addr "readAddrArray#" GenPrimOp
   MutByteArr# s -> Int# -> State# s -> (# State# s, Addr# #)

primop  ReadByteArrayOp_Float "readFloatArray#" GenPrimOp
   MutByteArr# s -> Int# -> State# s -> (# State# s, Float# #)

primop  ReadByteArrayOp_Double "readDoubleArray#" GenPrimOp
   MutByteArr# s -> Int# -> State# s -> (# State# s, Double# #)

primop  ReadByteArrayOp_StablePtr "readStablePtrArray#" GenPrimOp
   MutByteArr# s -> Int# -> State# s -> (# State# s, StablePtr# a #)

899
900
901
902
903
904
905
primop  ReadByteArrayOp_Int8 "readInt8Array#" GenPrimOp
   MutByteArr# s -> Int# -> State# s -> (# State# s, Int# #)

primop  ReadByteArrayOp_Int16 "readInt16Array#" GenPrimOp
   MutByteArr# s -> Int# -> State# s -> (# State# s, Int# #)

primop  ReadByteArrayOp_Int32 "readInt32Array#" GenPrimOp
apt's avatar
apt committed
906
   MutByteArr# s -> Int# -> State# s -> (# State# s, INT32 #)
907

908
primop  ReadByteArrayOp_Int64 "readInt64Array#" GenPrimOp
apt's avatar
apt committed
909
   MutByteArr# s -> Int# -> State# s -> (# State# s, INT64 #)
910

911
912
913
914
915
916
917
primop  ReadByteArrayOp_Word8 "readWord8Array#" GenPrimOp
   MutByteArr# s -> Int# -> State# s -> (# State# s, Word# #)

primop  ReadByteArrayOp_Word16 "readWord16Array#" GenPrimOp
   MutByteArr# s -> Int# -> State# s -> (# State# s, Word# #)

primop  ReadByteArrayOp_Word32 "readWord32Array#" GenPrimOp
apt's avatar
apt committed
918
   MutByteArr# s -> Int# -> State# s -> (# State# s, WORD32 #)
919

920
primop  ReadByteArrayOp_Word64 "readWord64Array#" GenPrimOp
apt's avatar
apt committed
921
   MutByteArr# s -> Int# -> State# s -> (# State# s, WORD64 #)
922
923
924

primop  WriteByteArrayOp_Char "writeCharArray#" GenPrimOp
   MutByteArr# s -> Int# -> Char# -> State# s -> State# s
apt's avatar
apt committed
925
   {Write 8-bit character; offset in bytes.}
926
927
   with has_side_effects = True

928
929
primop  WriteByteArrayOp_WideChar "writeWideCharArray#" GenPrimOp
   MutByteArr# s -> Int# -> Char# -> State# s -> State# s
apt's avatar
apt committed
930
   {Write 31-bit character; offset in 4-byte words.}
931
932
   with has_side_effects = True

933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
primop  WriteByteArrayOp_Int "writeIntArray#" GenPrimOp
   MutByteArr# s -> Int# -> Int# -> State# s -> State# s
   with has_side_effects = True

primop  WriteByteArrayOp_Word "writeWordArray#" GenPrimOp
   MutByteArr# s -> Int# -> Word# -> State# s -> State# s
   with has_side_effects = True

primop  WriteByteArrayOp_Addr "writeAddrArray#" GenPrimOp
   MutByteArr# s -> Int# -> Addr# -> State# s -> State# s
   with has_side_effects = True

primop  WriteByteArrayOp_Float "writeFloatArray#" GenPrimOp
   MutByteArr# s -> Int# -> Float# -> State# s -> State# s
   with has_side_effects = True

primop  WriteByteArrayOp_Double "writeDoubleArray#" GenPrimOp
   MutByteArr# s -> Int# -> Double# -> State# s -> State# s
   with has_side_effects = True

primop  WriteByteArrayOp_StablePtr "writeStablePtrArray#" GenPrimOp
   MutByteArr# s -> Int# -> StablePtr# a -> State# s -> State# s
   with has_side_effects = True

957
958
959
960
primop  WriteByteArrayOp_Int8 "writeInt8Array#" GenPrimOp
   MutByteArr# s -> Int# -> Int# -> State# s -> State# s
   with has_side_effects = True

961
962
primop  WriteByteArrayOp_Int16 "writeInt16Array#" GenPrimOp
   MutByteArr# s -> Int# -> Int# -> State# s -> State# s
963
964
   with has_side_effects = True

965
primop  WriteByteArrayOp_Int32 "writeInt32Array#" GenPrimOp
apt's avatar
apt committed
966
   MutByteArr# s -> Int# -> INT32 -> State# s -> State# s
967
968
   with has_side_effects = True

969
primop  WriteByteArrayOp_Int64 "writeInt64Array#" GenPrimOp
apt's avatar
apt committed
970
   MutByteArr# s -> Int# -> INT64 -> State# s -> State# s
971
972
   with has_side_effects = True

973
974
primop  WriteByteArrayOp_Word8 "writeWord8Array#" GenPrimOp
   MutByteArr# s -> Int# -> Word# -> State# s -> State# s
975
976
   with has_side_effects = True

977
primop  WriteByteArrayOp_Word16 "writeWord16Array#" GenPrimOp
978
979
980
   MutByteArr# s -> Int# -> Word# -> State# s -> State# s
   with has_side_effects = True

981
primop  WriteByteArrayOp_Word32 "writeWord32Array#" GenPrimOp
apt's avatar
apt committed
982
   MutByteArr# s -> Int# -> WORD32 -> State# s -> State# s
983
984
985
   with has_side_effects = True

primop  WriteByteArrayOp_Word64 "writeWord64Array#" GenPrimOp
apt's avatar
apt committed
986
   MutByteArr# s -> Int# -> WORD64 -> State# s -> State# s
987
   with has_side_effects = True
apt's avatar
apt committed
988
989
990
991
992

------------------------------------------------------------------------
section "Addr#"
------------------------------------------------------------------------

993
994
995
996
997
998
999
primtype Addr#
	{ An arbitrary machine address assumed to point outside
	 the garbage-collected heap. }

pseudoop "nullAddr#" Addr#
	{ The null address. }

apt's avatar
apt committed
1000
1001
primop	 AddrAddOp "plusAddr#" GenPrimOp Addr# -> Int# -> Addr#
primop	 AddrSubOp "minusAddr#" GenPrimOp Addr# -> Addr# -> Int#
1002
1003
	 {Result is meaningless if two {\tt Addr\#}s are so far apart that their
	 difference doesn't fit in an {\tt Int\#}.}
apt's avatar
apt committed
1004
primop	 AddrRemOp "remAddr#" GenPrimOp Addr# -> Int# -> Int#
1005
1006
	 {Return the remainder when the {\tt Addr\#} arg, treated like an {\tt Int\#},
	  is divided by the {\tt Int\#} arg.}
apt's avatar
apt committed
1007
1008
1009
1010
1011
#if (WORD_SIZE_IN_BITS == 32 || WORD_SIZE_IN_BITS == 64)
primop   Addr2IntOp  "addr2Int#"     GenPrimOp   Addr# -> Int#
	{Coerce directly from address to int. Strongly deprecated.}
primop   Int2AddrOp   "int2Addr#"    GenPrimOp  Int# -> Addr#
	{Coerce directly from int to address. Strongly deprecated.}
ken's avatar
ken committed
1012
#endif
1013

apt's avatar
apt committed
1014
1015
1016
1017
1018
1019
primop   AddrGtOp  "gtAddr#"   Compare   Addr# -> Addr# -> Bool
primop   AddrGeOp  "geAddr#"   Compare   Addr# -> Addr# -> Bool
primop   AddrEqOp  "eqAddr#"   Compare   Addr# -> Addr# -> Bool
primop   AddrNeOp  "neAddr#"   Compare   Addr# -> Addr# -> Bool
primop   AddrLtOp  "ltAddr#"   Compare   Addr# -> Addr# -> Bool
primop   AddrLeOp  "leAddr#"   Compare   Addr# -> Addr# -> Bool
1020
1021
1022

primop IndexOffAddrOp_Char "indexCharOffAddr#" GenPrimOp
   Addr# -> Int# -> Char#
apt's avatar
apt committed
1023
   {Reads 8-bit character; offset in bytes.}
1024

1025
1026
primop IndexOffAddrOp_WideChar "indexWideCharOffAddr#" GenPrimOp
   Addr# -> Int# -> Char#
apt's avatar
apt committed
1027
   {Reads 31-bit character; offset in 4-byte words.}
1028

1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
primop IndexOffAddrOp_Int "indexIntOffAddr#" GenPrimOp
   Addr# -> Int# -> Int#

primop IndexOffAddrOp_Word "indexWordOffAddr#" GenPrimOp
   Addr# -> Int# -> Word#

primop IndexOffAddrOp_Addr "indexAddrOffAddr#" GenPrimOp
   Addr# -> Int# -> Addr#

primop IndexOffAddrOp_Float "indexFloatOffAddr#" GenPrimOp
   Addr# -> Int# -> Float#

primop IndexOffAddrOp_Double "indexDoubleOffAddr#" GenPrimOp
   Addr# -> Int# -> Double#

primop IndexOffAddrOp_StablePtr "indexStablePtrOffAddr#" GenPrimOp
   Addr# -> Int# -> StablePtr# a

1047
1048
1049
1050
1051
1052
1053
primop IndexOffAddrOp_Int8 "indexInt8OffAddr#" GenPrimOp
   Addr# -> Int# -> Int#

primop IndexOffAddrOp_Int16 "indexInt16OffAddr#" GenPrimOp
   Addr# -> Int# -> Int#

primop IndexOffAddrOp_Int32 "indexInt32OffAddr#" GenPrimOp
apt's avatar
apt committed
1054
   Addr# -> Int# -> INT32
1055

1056
primop IndexOffAddrOp_Int64 "indexInt64OffAddr#" GenPrimOp
apt's avatar
apt committed
1057
   Addr# -> Int# -> INT64
1058

1059
1060
1061
1062
1063
1064
1065
primop IndexOffAddrOp_Word8 "indexWord8OffAddr#" GenPrimOp
   Addr# -> Int# -> Word#

primop IndexOffAddrOp_Word16 "indexWord16OffAddr#" GenPrimOp
   Addr# -> Int# -> Word#

primop IndexOffAddrOp_Word32 "indexWord32OffAddr#" GenPrimOp
apt's avatar
apt committed
1066
   Addr# -> Int# -> WORD32
1067

1068
primop IndexOffAddrOp_Word64 "indexWord64OffAddr#" GenPrimOp
apt's avatar
apt committed
1069
   Addr# -> Int# -> WORD64
1070
1071
1072

primop ReadOffAddrOp_Char "readCharOffAddr#" GenPrimOp
   Addr# -> Int# -> State# s -> (# State# s, Char# #)
apt's avatar
apt committed
1073
   {Reads 8-bit character; offset in bytes.}
1074

1075
1076
primop ReadOffAddrOp_WideChar "readWideCharOffAddr#" GenPrimOp
   Addr# -> Int# -> State# s -> (# State# s, Char# #)
apt's avatar
apt committed
1077
   {Reads 31-bit character; offset in 4-byte words.}
1078

1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
primop ReadOffAddrOp_Int "readIntOffAddr#" GenPrimOp
   Addr# -> Int# -> State# s -> (# State# s, Int# #)

primop ReadOffAddrOp_Word "readWordOffAddr#" GenPrimOp
   Addr# -> Int# -> State# s -> (# State# s, Word# #)

primop ReadOffAddrOp_Addr "readAddrOffAddr#" GenPrimOp
   Addr# -> Int# -> State# s -> (# State# s, Addr# #)

primop ReadOffAddrOp_Float "readFloatOffAddr#" GenPrimOp
   Addr# -> Int# -> State# s -> (# State# s, Float# #)

primop ReadOffAddrOp_Double "readDoubleOffAddr#" GenPrimOp
   Addr# -> Int# -> State# s -> (# State# s, Double# #)

primop ReadOffAddrOp_StablePtr "readStablePtrOffAddr#" GenPrimOp
   Addr# -> Int# -> State# s -> (# State# s, StablePtr# a #)

1097
1098
1099
1100
1101
1102
1103
primop ReadOffAddrOp_Int8 "readInt8OffAddr#" GenPrimOp
   Addr# -> Int# -> State# s -> (# State# s, Int# #)

primop ReadOffAddrOp_Int16 "readInt16OffAddr#" GenPrimOp
   Addr# -> Int# -> State# s -> (# State# s, Int# #)

primop ReadOffAddrOp_Int32 "readInt32OffAddr#" GenPrimOp
apt's avatar
apt committed
1104
   Addr# -> Int# -> State# s -> (# State# s, INT32 #)
1105

1106
primop ReadOffAddrOp_Int64 "readInt64OffAddr#" GenPrimOp
apt's avatar
apt committed
1107
   Addr# -> Int# -> State# s -> (# State# s, INT64 #)
1108

1109
1110
1111
1112
1113
1114
1115
primop ReadOffAddrOp_Word8 "readWord8OffAddr#" GenPrimOp
   Addr# -> Int# -> State# s -> (# State# s, Word# #)

primop ReadOffAddrOp_Word16 "readWord16OffAddr#" GenPrimOp
   Addr# -> Int# -> State# s -> (# State# s, Word# #)

primop ReadOffAddrOp_Word32 "readWord32OffAddr#" GenPrimOp
apt's avatar
apt committed
1116
   Addr# -> Int# -> State# s -> (# State# s, WORD32 #)
1117

1118
primop ReadOffAddrOp_Word64 "readWord64OffAddr#" GenPrimOp
apt's avatar
apt committed
1119
   Addr# -> Int# -> State# s -> (# State# s, WORD64 #)
1120
1121
1122
1123
1124
1125


primop  WriteOffAddrOp_Char "writeCharOffAddr#" GenPrimOp
   Addr# -> Int# -> Char# -> State# s -> State# s
   with has_side_effects = True

1126
1127
1128
1129
primop  WriteOffAddrOp_WideChar "writeWideCharOffAddr#" GenPrimOp
   Addr# -> Int# -> Char# -> State# s -> State# s
   with has_side_effects = True

1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
primop  WriteOffAddrOp_Int "writeIntOffAddr#" GenPrimOp
   Addr# -> Int# -> Int# -> State# s -> State# s
   with has_side_effects = True

primop  WriteOffAddrOp_Word "writeWordOffAddr#" GenPrimOp
   Addr# -> Int# -> Word# -> State# s -> State# s
   with has_side_effects = True

primop  WriteOffAddrOp_Addr "writeAddrOffAddr#" GenPrimOp
   Addr# -> Int# -> Addr# -> State# s -> State# s
   with has_side_effects = True

primop  WriteOffAddrOp_Float "writeFloatOffAddr#" GenPrimOp
   Addr# -> Int# -> Float# -> State# s -> State# s
   with has_side_effects = True

primop  WriteOffAddrOp_Double "writeDoubleOffAddr#" GenPrimOp
   Addr# -> Int# -> Double# -> State# s -> State# s
   with has_side_effects = True

primop  WriteOffAddrOp_StablePtr "writeStablePtrOffAddr#" GenPrimOp
   Addr# -> Int# -> StablePtr# a -> State# s -> State# s
   with has_side_effects = True

1154
1155
1156
1157
primop  WriteOffAddrOp_Int8 "writeInt8OffAddr#" GenPrimOp
   Addr# -> Int# -> Int# -> State# s -> State# s
   with has_side_effects = True

1158
1159
primop  WriteOffAddrOp_Int16 "writeInt16OffAddr#" GenPrimOp
   Addr# -> Int# -> Int# -> State# s -> State# s
1160
1161
   with has_side_effects = True

1162
primop  WriteOffAddrOp_Int32 "writeInt32OffAddr#" GenPrimOp
apt's avatar
apt committed
1163
   Addr# -> Int# -> INT32 -> State# s -> State# s
1164
1165
   with has_side_effects = True

1166
primop  WriteOffAddrOp_Int64 "writeInt64OffAddr#" GenPrimOp
apt's avatar
apt committed
1167
   Addr# -> Int# -> INT64 -> State# s -> State# s
1168
1169
   with has_side_effects = True

1170
1171
primop  WriteOffAddrOp_Word8 "writeWord8OffAddr#" GenPrimOp
   Addr# -> Int# -> Word# -> State# s -> State# s
1172
1173
   with has_side_effects = True

1174
primop  WriteOffAddrOp_Word16 "writeWord16OffAddr#" GenPrimOp
1175
1176
1177
   Addr# -> Int# -> Word# -> State# s -> State# s
   with has_side_effects = True

1178
primop  WriteOffAddrOp_Word32 "writeWord32OffAddr#" GenPrimOp
apt's avatar
apt committed
1179
   Addr# -> Int# -> WORD32 -> State# s -> State# s
1180
1181
1182
   with has_side_effects = True

primop  WriteOffAddrOp_Word64 "writeWord64OffAddr#" GenPrimOp
apt's avatar
apt committed
1183
   Addr# -> Int# -> WORD64 -> State# s -> State# s
1184
1185
1186
   with has_side_effects = True

------------------------------------------------------------------------
apt's avatar
apt committed
1187
section "Mutable variables"
1188
	{Operations on MutVar\#s.}
1189
1190
------------------------------------------------------------------------

1191
1192
1193
primtype MutVar# s a
	{A {\tt MutVar\#} behaves like a single-element mutable array.}

1194
1195
primop  NewMutVarOp "newMutVar#" GenPrimOp
   a -> State# s -> (# State# s, MutVar# s a #)
1196
   {Create {\tt MutVar\#} with specified initial value in specified state thread.}
1197
1198
1199
1200
1201
   with
   out_of_line = True

primop  ReadMutVarOp "readMutVar#" GenPrimOp
   MutVar# s a -> State# s -> (# State# s, a #)
1202
   {Read contents of {\tt MutVar\#}. Result is not yet evaluated.}
1203
1204
1205

primop  WriteMutVarOp "writeMutVar#"  GenPrimOp
   MutVar# s a -> a -> State# s -> State# s
1206
   {Write contents of {\tt MutVar\#}.}
1207
1208
1209
1210
1211
1212
   with
   has_side_effects = True

primop  SameMutVarOp "sameMutVar#" GenPrimOp
   MutVar# s a -> MutVar# s a -> Bool

1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
-- not really the right type, but we don't know about pairs here.  The
-- correct type is
--
--   MutVar# s a -> (a -> (a,b)) -> State# s -> (# State# s, b #)
--
primop  AtomicModifyMutVarOp "atomicModifyMutVar#" GenPrimOp
   MutVar# s a -> (a -> b) -> State# s -> (# State# s, c #)
   with
   has_side_effects = True
   out_of_line = True

1224
------------------------------------------------------------------------
apt's avatar
apt committed
1225
section "Exceptions"
1226
1227
1228
1229
1230
1231
1232
1233
1234
------------------------------------------------------------------------

primop  CatchOp "catch#" GenPrimOp
          (State# RealWorld -> (# State# RealWorld, a #) )
       -> (b -> State# RealWorld -> (# State# RealWorld, a #) ) 
       -> State# RealWorld
       -> (# State# RealWorld, a #)
   with
	-- Catch is actually strict in its first argument
apt's avatar
apt committed
1235
	-- but we don't want to tell the strictness
1236
1237
1238
1239
1240
1241
1242
	-- analyser about that!
        -- might use caught action multiply
   out_of_line = True

primop  RaiseOp "raise#" GenPrimOp
   a -> b
   with
Ian Lynagh's avatar
Ian Lynagh committed
1243
   strictness  = { \ _arity -> mkStrictSig (mkTopDmdType [lazyDmd] BotRes) }
1244
      -- NB: result is bottom
1245
1246
   out_of_line = True

1247
1248
1249
1250
1251
1252
1253
1254
1255
-- raiseIO# needs to be a primop, because exceptions in the IO monad
-- must be *precise* - we don't want the strictness analyser turning
-- one kind of bottom into another, as it is allowed to do in pure code.

primop  RaiseIOOp "raiseIO#" GenPrimOp
   a -> State# RealWorld -> (# State# RealWorld, b #)
   with
   out_of_line = True

1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
primop  BlockAsyncExceptionsOp "blockAsyncExceptions#" GenPrimOp
        (State# RealWorld -> (# State# RealWorld, a #))
     -> (State# RealWorld -> (# State# RealWorld, a #))
   with
   out_of_line = True

primop  UnblockAsyncExceptionsOp "unblockAsyncExceptions#" GenPrimOp
        (State# RealWorld -> (# State# RealWorld, a #))
     -> (State# RealWorld -> (# State# RealWorld, a #))
   with
   out_of_line = True

------------------------------------------------------------------------
1269
1270
1271
section "STM-accessible Mutable Variables"
------------------------------------------------------------------------

1272
1273
primtype TVar# s a

1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
primop	AtomicallyOp "atomically#" GenPrimOp
      (State# RealWorld -> (# State# RealWorld, a #) )
   -> State# RealWorld -> (# State# RealWorld, a #)
   with
   out_of_line = True
   has_side_effects = True

primop  RetryOp "retry#" GenPrimOp
   State# RealWorld -> (# State# RealWorld, a #)
   with 
   out_of_line = True
   has_side_effects = True

primop  CatchRetryOp "catchRetry#" GenPrimOp
      (State# RealWorld -> (# State# RealWorld, a #) )
   -> (State# RealWorld -> (# State# RealWorld, a #) )
   -> (State# RealWorld -> (# State# RealWorld, a #) )
   with 
   out_of_line = True
   has_side_effects = True

primop  CatchSTMOp "catchSTM#" GenPrimOp
      (State# RealWorld -> (# State# RealWorld, a #) )
   -> (b -> State# RealWorld -> (# State# RealWorld, a #) )
   -> (State# RealWorld -> (# State# RealWorld, a #) )
   with 
   out_of_line = True
   has_side_effects = True

tharris@microsoft.com's avatar
tharris@microsoft.com committed
1303
1304
1305
1306
1307
1308
1309
primop  Check "check#" GenPrimOp
      (State# RealWorld -> (# State# RealWorld, a #) )
   -> (State# RealWorld -> (# State# RealWorld, () #) )
   with 
   out_of_line = True
   has_side_effects = True

1310
1311
1312
primop	NewTVarOp "newTVar#" GenPrimOp
       a
    -> State# s -> (# State# s, TVar# s a #)
1313
   {Create a new {\tt TVar\#} holding a specified initial value.}
1314
1315
1316
1317
1318
1319
   with
   out_of_line  = True

primop	ReadTVarOp "readTVar#" GenPrimOp
       TVar# s a
    -> State# s -> (# State# s, a #)
1320
   {Read contents of {\tt TVar\#}.  Result is not yet evaluated.}
1321
1322
1323
1324
1325
1326
1327
   with
   out_of_line	= True

primop	WriteTVarOp "writeTVar#" GenPrimOp
       TVar# s a
    -> a
    -> State# s -> State# s
1328
   {Write contents of {\tt TVar\#}.}
1329
1330
1331
1332
1333
1334
1335
1336
1337
   with
   out_of_line	    = True
   has_side_effects = True

primop  SameTVarOp "sameTVar#" GenPrimOp
   TVar# s a -> TVar# s a -> Bool


------------------------------------------------------------------------
apt's avatar
apt committed
1338
section "Synchronized Mutable Variables"
1339
	{Operations on {\tt MVar\#}s. }
1340
1341
------------------------------------------------------------------------

1342
1343
1344
1345
primtype MVar# s a
	{ A shared mutable variable ({\it not} the same as a {\tt MutVar\#}!).
	(Note: in a non-concurrent implementation, {\tt (MVar\# a)} can be
	represented by {\tt (MutVar\# (Maybe a))}.) }
apt's avatar
apt committed
1346

1347
1348
primop  NewMVarOp "newMVar#"  GenPrimOp
   State# s -> (# State# s, MVar# s a #)
1349
   {Create new {\tt MVar\#}; initially empty.}
1350
1351
1352
1353
1354
   with
   out_of_line = True

primop  TakeMVarOp "takeMVar#" GenPrimOp
   MVar# s a -> State# s -> (# State# s, a #)
1355
   {If {\tt MVar\#} is empty, block until it becomes full.
apt's avatar
apt committed
1356
   Then remove and return its contents, and set it empty.}
1357
1358
1359
1360
   with
   has_side_effects = True
   out_of_line      = True

1361
1362
primop  TryTakeMVarOp "tryTakeMVar#" GenPrimOp
   MVar# s a -> State# s -> (# State# s, Int#, a #)
1363
1364
   {If {\tt MVar\#} is empty, immediately return with integer 0 and value undefined.
   Otherwise, return with integer 1 and contents of {\tt MVar\#}, and set {\tt MVar\#} empty.}
1365
1366
1367
1368
   with
   has_side_effects = True
   out_of_line      = True

1369
1370
primop  PutMVarOp "putMVar#" GenPrimOp
   MVar# s a -> a -> State# s -> State# s
1371
   {If {\tt MVar\#} is full, block until it becomes empty.
apt's avatar
apt committed
1372
   Then store value arg as its new contents.}
1373
1374
1375
1376
   with
   has_side_effects = True
   out_of_line      = True

1377
1378
primop  TryPutMVarOp "tryPutMVar#" GenPrimOp
   MVar# s a -> a -> State# s -> (# State# s, Int# #)
1379
1380
   {If {\tt MVar\#} is full, immediately return with integer 0.
    Otherwise, store value arg as {\tt MVar\#}'s new contents, and return with integer 1.}
1381
1382
1383
1384
   with
   has_side_effects = True
   out_of_line      = True

1385
1386
1387
1388
1389
primop  SameMVarOp "sameMVar#" GenPrimOp
   MVar# s a -> MVar# s a -> Bool

primop  IsEmptyMVarOp "isEmptyMVar#" GenPrimOp
   MVar# s a -> State# s -> (# State# s, Int# #)
1390
   {Return 1 if {\tt MVar\#} is empty; 0 otherwise.}
1391
   with
1392
   out_of_line = True
1393
1394

------------------------------------------------------------------------
apt's avatar
apt committed
1395
section "Delay/wait operations"
1396
1397
1398
1399
------------------------------------------------------------------------

primop  DelayOp "delay#" GenPrimOp
   Int# -> State# s -> State# s
apt's avatar
apt committed
1400
   {Sleep specified number of microseconds.}
1401
1402
1403
1404
1405
1406
1407
   with
   needs_wrapper    = True
   has_side_effects = True
   out_of_line      = True

primop  WaitReadOp "waitRead#" GenPrimOp
   Int# -> State# s -> State# s
apt's avatar
apt committed
1408
   {Block until input is available on specified file descriptor.}
1409
1410
1411
1412
1413
1414
1415
   with
   needs_wrapper    = True
   has_side_effects = True
   out_of_line      = True

primop  WaitWriteOp "waitWrite#" GenPrimOp
   Int# -> State# s -> State# s
apt's avatar
apt committed
1416
   {Block until output is possible on specified file descriptor.}
1417
1418
1419
1420
1421
   with
   needs_wrapper    = True
   has_side_effects = True
   out_of_line      = True

sof's avatar
sof committed
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
#ifdef mingw32_TARGET_OS
primop  AsyncReadOp "asyncRead#" GenPrimOp
   Int# -> Int# -> Int# -> Addr# -> State# RealWorld-> (# State# RealWorld, Int#, Int# #)
   {Asynchronously read bytes from specified file descriptor.}
   with
   needs_wrapper    = True
   has_side_effects = True
   out_of_line      = True

primop  AsyncWriteOp "asyncWrite#" GenPrimOp
   Int# -> Int# -> Int# -> Addr# -> State# RealWorld-> (# State# RealWorld, Int#, Int# #)
   {Asynchronously write bytes from specified file descriptor.}
   with
   needs_wrapper    = True
   has_side_effects = True
   out_of_line      = True
sof's avatar
sof committed
1438
1439
1440
1441
1442
1443
1444
1445
1446

primop  AsyncDoProcOp "asyncDoProc#" GenPrimOp
   Addr# -> Addr# -> State# RealWorld-> (# State# RealWorld, Int#, Int# #)
   {Asynchronously perform procedure (first arg), passing it 2nd arg.}
   with
   needs_wrapper    = True
   has_side_effects = True
   out_of_line      = True

sof's avatar
sof committed
1447
1448
#endif

1449
------------------------------------------------------------------------
apt's avatar
apt committed
1450
section "Concurrency primitives"
1451
1452
------------------------------------------------------------------------

1453
primtype State# s
sven.panne@aedion.de's avatar
sven.panne@aedion.de committed
1454
	{ {\tt State\#} is the primitive, unlifted type of states.  It has
1455
1456
1457
1458
1459
1460
1461
1462
	one type parameter, thus {\tt State\# RealWorld}, or {\tt State\# s},
	where s is a type variable. The only purpose of the type parameter
	is to keep different state threads separate.  It is represented by
	nothing at all. }

primtype RealWorld
	{ {\tt RealWorld} is deeply magical.  It is {\it primitive}, but it is not
	{\it unlifted} (hence {\tt ptrArg}).  We never manipulate values of type
sven.panne@aedion.de's avatar
sven.panne@aedion.de committed
1463
	{\tt RealWorld}; it's only used in the type system, to parameterise {\tt State\#}. }
1464
1465
1466
1467
1468
1469

primtype ThreadId#
	{(In a non-concurrent implementation, this can be a singleton
	type, whose (unique) value is returned by {\tt myThreadId\#}.  The 
	other operations can be omitted.)}

1470
1471
1472
1473
1474
1475
primop  ForkOp "fork#" GenPrimOp
   a -> State# RealWorld -> (# State# RealWorld, ThreadId# #)
   with
   has_side_effects = True
   out_of_line      = True

1476
1477
1478
1479
1480
1481
primop  ForkOnOp "forkOn#" GenPrimOp
   Int# -> a -> State# RealWorld -> (# State# RealWorld, ThreadId# #)
   with
   has_side_effects = True
   out_of_line      = True

1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
primop  KillThreadOp "killThread#"  GenPrimOp
   ThreadId# -> a -> State# RealWorld -> State# RealWorld
   with
   has_side_effects = True
   out_of_line      = True

primop  YieldOp "yield#" GenPrimOp
   State# RealWorld -> State# RealWorld
   with
   has_side_effects = True
   out_of_line      = True

primop  MyThreadIdOp "myThreadId#" GenPrimOp
1495
1496
1497
   State# RealWorld -> (# State# RealWorld, ThreadId# #)
   with
   out_of_line = True
1498

1499
primop LabelThreadOp "labelThread#" GenPrimOp
1500
   ThreadId# -> Addr# -> State# RealWorld -> State# RealWorld
1501
1502
1503
   with
   has_side_effects = True
   out_of_line      = True
1504
1505
1506
1507
1508
   
primop  IsCurrentThreadBoundOp "isCurrentThreadBound#" GenPrimOp
   State# RealWorld -> (# State# RealWorld, Int# #)
   with
   out_of_line = True
1509

Simon Marlow's avatar
Simon Marlow committed
1510
1511
1512
1513