primops.txt.pp 67.2 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
	 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
116
117
	 \texttt{indexInt32Array\#} has type {\tt ByteArray\# -> Int\#
	 -> Int\#}; otherwise it has type {\tt ByteArray\# -> Int\# ->
118
119
	 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
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#"
254
   GenPrimOp Int# -> (# Int#, ByteArray# #)
apt's avatar
apt committed
255
256
   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

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

primop   Word2IntegerOp   "word2Integer#"   GenPrimOp 
309
   Word# -> (# Int#, ByteArray# #)
apt's avatar
apt committed
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
   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
primop   Int32ToIntegerOp   "int32ToInteger#" GenPrimOp 
343
   Int32# -> (# Int#, ByteArray# #)
apt's avatar
apt committed
344
345
346
347
348
349
   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
primop   Word32ToIntegerOp   "word32ToInteger#" GenPrimOp
357
   Word32# -> (# Int#, ByteArray# #)
apt's avatar
apt committed
358
359
360
361
362
363
364
365
366
367
   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
primop   Int64ToIntegerOp   "int64ToInteger#" GenPrimOp 
375
   Int64# -> (# Int#, ByteArray# #)
apt's avatar
apt committed
376
377
378
379
380
   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
primop   Word64ToIntegerOp   "word64ToInteger#" GenPrimOp
388
   Word64# -> (# Int#, ByteArray# #)
apt's avatar
apt committed
389
390
391
392
393
394
395
396
   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
consisting of an {\tt Int\#} representing the number of 'limbs' in use and
398
the sign, and a {\tt ByteArray\#} 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
primop   IntegerAddOp   "plusInteger#" GenPrimOp   
409
   Int# -> ByteArray# -> Int# -> ByteArray# -> (# Int#, ByteArray# #)
apt's avatar
apt committed
410
411
412
413
   with commutable = True
        out_of_line = True

primop   IntegerSubOp   "minusInteger#" GenPrimOp  
414
   Int# -> ByteArray# -> Int# -> ByteArray# -> (# Int#, ByteArray# #)
apt's avatar
apt committed
415
416
417
   with out_of_line = True

primop   IntegerMulOp   "timesInteger#" GenPrimOp   
418
   Int# -> ByteArray# -> Int# -> ByteArray# -> (# Int#, ByteArray# #)
apt's avatar
apt committed
419
420
421
422
   with commutable = True
        out_of_line = True

primop   IntegerGcdOp   "gcdInteger#" GenPrimOp    
423
   Int# -> ByteArray# -> Int# -> ByteArray# -> (# Int#, ByteArray# #)
apt's avatar
apt committed
424
425
426
427
428
   {Greatest common divisor.}
   with commutable = True
        out_of_line = True

primop   IntegerIntGcdOp   "gcdIntegerInt#" GenPrimOp
429
   Int# -> ByteArray# -> 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

primop   IntegerDivExactOp   "divExactInteger#" GenPrimOp
434
   Int# -> ByteArray# -> Int# -> ByteArray# -> (# Int#, ByteArray# #)
apt's avatar
apt committed
435
436
437
438
   {Divisor is guaranteed to be a factor of dividend.}
   with out_of_line = True

primop   IntegerQuotOp   "quotInteger#" GenPrimOp
439
   Int# -> ByteArray# -> Int# -> ByteArray# -> (# Int#, ByteArray# #)
apt's avatar
apt committed
440
441
442
443
   {Rounds towards zero.}
   with out_of_line = True

primop   IntegerRemOp   "remInteger#" GenPrimOp
444
   Int# -> ByteArray# -> Int# -> ByteArray# -> (# Int#, ByteArray# #)
apt's avatar
apt committed
445
446
447
448
   {Satisfies \texttt{plusInteger\# (timesInteger\# (quotInteger\# x y) y) (remInteger\# x y) == x}.}
   with out_of_line = True

primop   IntegerCmpOp   "cmpInteger#"   GenPrimOp  
449
   Int# -> ByteArray# -> Int# -> ByteArray# -> Int#
apt's avatar
apt committed
450
451
   {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

primop   IntegerCmpIntOp   "cmpIntegerInt#" GenPrimOp
455
   Int# -> ByteArray# -> Int# -> Int#
apt's avatar
apt committed
456
457
458
   {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

primop   IntegerQuotRemOp   "quotRemInteger#" GenPrimOp
462
   Int# -> ByteArray# -> Int# -> ByteArray# -> (# Int#, ByteArray#, Int#, ByteArray# #)
apt's avatar
apt committed
463
464
465
466
467
   {Compute quot and rem simulaneously.}
   with can_fail = True
        out_of_line = True

primop   IntegerDivModOp    "divModInteger#"  GenPrimOp
468
   Int# -> ByteArray# -> Int# -> ByteArray# -> (# Int#, ByteArray#, Int#, ByteArray# #)
apt's avatar
apt committed
469
470
471
472
473
474
   {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
475
   Int# -> ByteArray# -> Int#
apt's avatar
apt committed
476
   with needs_wrapper = True
477
        out_of_line = True
apt's avatar
apt committed
478
479

primop   Integer2WordOp   "integer2Word#"   GenPrimOp
480
   Int# -> ByteArray# -> Word#
apt's avatar
apt committed
481
   with needs_wrapper = True
482
        out_of_line = True
apt's avatar
apt committed
483
484
485

#if WORD_SIZE_IN_BITS < 32
primop   IntegerToInt32Op   "integerToInt32#" GenPrimOp
486
   Int# -> ByteArray# -> Int32#
apt's avatar
apt committed
487
488

primop   IntegerToWord32Op   "integerToWord32#" GenPrimOp
489
   Int# -> ByteArray# -> Word32#
apt's avatar
apt committed
490
491
492
#endif

primop   IntegerAndOp  "andInteger#" GenPrimOp
493
   Int# -> ByteArray# -> Int# -> ByteArray# -> (# Int#, ByteArray# #)
apt's avatar
apt committed
494
495
496
   with out_of_line = True

primop   IntegerOrOp  "orInteger#" GenPrimOp
497
   Int# -> ByteArray# -> Int# -> ByteArray# -> (# Int#, ByteArray# #)
apt's avatar
apt committed
498
499
500
   with out_of_line = True

primop   IntegerXorOp  "xorInteger#" GenPrimOp
501
   Int# -> ByteArray# -> Int# -> ByteArray# -> (# Int#, ByteArray# #)
apt's avatar
apt committed
502
503
504
   with out_of_line = True

primop   IntegerComplementOp  "complementInteger#" GenPrimOp
505
   Int# -> ByteArray# -> (# Int#, ByteArray# #)
apt's avatar
apt committed
506
   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
   with needs_wrapper = True

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

621
primop   DoubleDecode_2IntOp   "decodeDouble_2Int#" GenPrimOp    
622
   Double# -> (# Int#, Word#, Word#, Int# #)
623
   {Convert to arbitrary-precision integer.
624
625
626
    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.}
627
628
   with out_of_line = True

629
------------------------------------------------------------------------
apt's avatar
apt committed
630
631
section "Float#" 
	{Operations on single-precision (32-bit) floating-point numbers.}
632
633
------------------------------------------------------------------------

634
635
primtype Float#

636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
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#
667
668
669
   {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#}.}
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
722
723
724
725
726
727

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#

728
729
primop   FloatDecode_IntOp   "decodeFloat_Int#" GenPrimOp
   Float# -> (# Int#, Int# #)
730
   {Convert to integers.
731
732
733
    First {\tt Int\#} in result is the mantissa; second is the exponent.}
   with out_of_line = True

734
------------------------------------------------------------------------
apt's avatar
apt committed
735
section "Arrays"
736
	{Operations on {\tt Array\#}.}
737
738
------------------------------------------------------------------------

739
740
primtype Array# a

741
primtype MutableArray# s a
742

apt's avatar
apt committed
743
primop  NewArrayOp "newArray#" GenPrimOp
744
   Int# -> a -> State# s -> (# State# s, MutableArray# s a #)
apt's avatar
apt committed
745
746
747
748
749
   {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
750
   has_side_effects = True
751

apt's avatar
apt committed
752
primop  SameMutableArrayOp "sameMutableArray#" GenPrimOp
753
   MutableArray# s a -> MutableArray# s a -> Bool
754

apt's avatar
apt committed
755
primop  ReadArrayOp "readArray#" GenPrimOp
756
   MutableArray# s a -> Int# -> State# s -> (# State# s, a #)
apt's avatar
apt committed
757
   {Read from specified index of mutable array. Result is not yet evaluated.}
758
759
   with
   has_side_effects = True
760

apt's avatar
apt committed
761
primop  WriteArrayOp "writeArray#" GenPrimOp
762
   MutableArray# s a -> Int# -> a -> State# s -> State# s
apt's avatar
apt committed
763
764
765
   {Write to specified index of mutable array.}
   with
   has_side_effects = True
766

apt's avatar
apt committed
767
768
769
770
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.}
771

apt's avatar
apt committed
772
primop  UnsafeFreezeArrayOp "unsafeFreezeArray#" GenPrimOp
773
   MutableArray# s a -> State# s -> (# State# s, Array# a #)
apt's avatar
apt committed
774
775
776
   {Make a mutable array immutable, without copying.}
   with
   has_side_effects = True
777

apt's avatar
apt committed
778
primop  UnsafeThawArrayOp  "unsafeThawArray#" GenPrimOp
779
   Array# a -> State# s -> (# State# s, MutableArray# s a #)
apt's avatar
apt committed
780
781
782
   {Make an immutable array mutable, without copying.}
   with
   out_of_line = True
783
   has_side_effects = True
784

785
------------------------------------------------------------------------
apt's avatar
apt committed
786
section "Byte Arrays"
787
	{Operations on {\tt ByteArray\#}. A {\tt ByteArray\#} is a just a region of
apt's avatar
apt committed
788
789
790
791
792
793
794
795
         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.}
796

797
798
------------------------------------------------------------------------

799
primtype ByteArray#
800

801
primtype MutableByteArray# s
802

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

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

Simon Marlow's avatar
Simon Marlow committed
816
817
818
819
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
820
        has_side_effects = True
Simon Marlow's avatar
Simon Marlow committed
821

822
primop  ByteArrayContents_Char "byteArrayContents#" GenPrimOp
823
   ByteArray# -> Addr#
apt's avatar
apt committed
824
825
826
   {Intended for use with pinned arrays; otherwise very unsafe!}

primop  SameMutableByteArrayOp "sameMutableByteArray#" GenPrimOp
827
   MutableByteArray# s -> MutableByteArray# s -> Bool
apt's avatar
apt committed
828
829

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

primop  SizeofByteArrayOp "sizeofByteArray#" GenPrimOp  
836
   ByteArray# -> Int#
apt's avatar
apt committed
837
838

primop  SizeofMutableByteArrayOp "sizeofMutableByteArray#" GenPrimOp
839
   MutableByteArray# s -> Int#
apt's avatar
apt committed
840

841

842
primop IndexByteArrayOp_Char "indexCharArray#" GenPrimOp
843
   ByteArray# -> Int# -> Char#
apt's avatar
apt committed
844
   {Read 8-bit character; offset in bytes.}
845
846

primop IndexByteArrayOp_WideChar "indexWideCharArray#" GenPrimOp
847
   ByteArray# -> Int# -> Char#
apt's avatar
apt committed
848
   {Read 31-bit character; offset in 4-byte words.}
849
850

primop IndexByteArrayOp_Int "indexIntArray#" GenPrimOp
851
   ByteArray# -> Int# -> Int#
852
853

primop IndexByteArrayOp_Word "indexWordArray#" GenPrimOp
854
   ByteArray# -> Int# -> Word#
855
856

primop IndexByteArrayOp_Addr "indexAddrArray#" GenPrimOp
857
   ByteArray# -> Int# -> Addr#
858
859

primop IndexByteArrayOp_Float "indexFloatArray#" GenPrimOp
860
   ByteArray# -> Int# -> Float#
861
862

primop IndexByteArrayOp_Double "indexDoubleArray#" GenPrimOp
863
   ByteArray# -> Int# -> Double#
864
865

primop IndexByteArrayOp_StablePtr "indexStablePtrArray#" GenPrimOp
866
   ByteArray# -> Int# -> StablePtr# a
867
868

primop IndexByteArrayOp_Int8 "indexInt8Array#" GenPrimOp
869
   ByteArray# -> Int# -> Int#
870
871

primop IndexByteArrayOp_Int16 "indexInt16Array#" GenPrimOp
872
   ByteArray# -> Int# -> Int#
873
874

primop IndexByteArrayOp_Int32 "indexInt32Array#" GenPrimOp
875
   ByteArray# -> Int# -> INT32
876
877

primop IndexByteArrayOp_Int64 "indexInt64Array#" GenPrimOp
878
   ByteArray# -> Int# -> INT64
879
880

primop IndexByteArrayOp_Word8 "indexWord8Array#" GenPrimOp
881
   ByteArray# -> Int# -> Word#
882
883

primop IndexByteArrayOp_Word16 "indexWord16Array#" GenPrimOp
884
   ByteArray# -> Int# -> Word#
885
886

primop IndexByteArrayOp_Word32 "indexWord32Array#" GenPrimOp
887
   ByteArray# -> Int# -> WORD32
888
889

primop IndexByteArrayOp_Word64 "indexWord64Array#" GenPrimOp
890
   ByteArray# -> Int# -> WORD64
891

892
primop  ReadByteArrayOp_Char "readCharArray#" GenPrimOp
893
   MutableByteArray# s -> Int# -> State# s -> (# State# s, Char# #)
apt's avatar
apt committed
894
   {Read 8-bit character; offset in bytes.}
895
   with has_side_effects = True
896

897
primop  ReadByteArrayOp_WideChar "readWideCharArray#" GenPrimOp
898
   MutableByteArray# s -> Int# -> State# s -> (# State# s, Char# #)
apt's avatar
apt committed
899
   {Read 31-bit character; offset in 4-byte words.}
900
   with has_side_effects = True
901

902
primop  ReadByteArrayOp_Int "readIntArray#" GenPrimOp
903
   MutableByteArray# s -> Int# -> State# s -> (# State# s, Int# #)
904
   with has_side_effects = True
905
906

primop  ReadByteArrayOp_Word "readWordArray#" GenPrimOp
907
   MutableByteArray# s -> Int# -> State# s -> (# State# s, Word# #)
908
   with has_side_effects = True
909
910

primop  ReadByteArrayOp_Addr "readAddrArray#" GenPrimOp
911
   MutableByteArray# s -> Int# -> State# s -> (# State# s, Addr# #)
912
   with has_side_effects = True
913
914

primop  ReadByteArrayOp_Float "readFloatArray#" GenPrimOp
915
   MutableByteArray# s -> Int# -> State# s -> (# State# s, Float# #)
916
   with has_side_effects = True
917
918

primop  ReadByteArrayOp_Double "readDoubleArray#" GenPrimOp
919
   MutableByteArray# s -> Int# -> State# s -> (# State# s, Double# #)
920
   with has_side_effects = True
921
922

primop  ReadByteArrayOp_StablePtr "readStablePtrArray#" GenPrimOp
923
   MutableByteArray# s -> Int# -> State# s -> (# State# s, StablePtr# a #)
924
   with has_side_effects = True
925

926
primop  ReadByteArrayOp_Int8 "readInt8Array#" GenPrimOp
927
   MutableByteArray# s -> Int# -> State# s -> (# State# s, Int# #)
928
   with has_side_effects = True
929
930

primop  ReadByteArrayOp_Int16 "readInt16Array#" GenPrimOp
931
   MutableByteArray# s -> Int# -> State# s -> (# State# s, Int# #)
932
   with has_side_effects = True
933
934

primop  ReadByteArrayOp_Int32 "readInt32Array#" GenPrimOp
935
   MutableByteArray# s -> Int# -> State# s -> (# State# s, INT32 #)
936
   with has_side_effects = True
937

938
primop  ReadByteArrayOp_Int64 "readInt64Array#" GenPrimOp
939
   MutableByteArray# s -> Int# -> State# s -> (# State# s, INT64 #)
940
   with has_side_effects = True
941

942
primop  ReadByteArrayOp_Word8 "readWord8Array#" GenPrimOp
943
   MutableByteArray# s -> Int# -> State# s -> (# State# s, Word# #)
944
   with has_side_effects = True
945
946

primop  ReadByteArrayOp_Word16 "readWord16Array#" GenPrimOp
947
   MutableByteArray# s -> Int# -> State# s -> (# State# s, Word# #)
948
   with has_side_effects = True
949
950

primop  ReadByteArrayOp_Word32 "readWord32Array#" GenPrimOp
951
   MutableByteArray# s -> Int# -> State# s -> (# State# s, WORD32 #)
952
   with has_side_effects = True
953

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

primop  WriteByteArrayOp_Char "writeCharArray#" GenPrimOp
959
   MutableByteArray# s -> Int# -> Char# -> State# s -> State# s
apt's avatar
apt committed
960
   {Write 8-bit character; offset in bytes.}
961
962
   with has_side_effects = True

963
primop  WriteByteArrayOp_WideChar "writeWideCharArray#" GenPrimOp
964
   MutableByteArray# s -> Int# -> Char# -> State# s -> State# s
apt's avatar
apt committed
965
   {Write 31-bit character; offset in 4-byte words.}
966
967
   with has_side_effects = True

968
primop  WriteByteArrayOp_Int "writeIntArray#" GenPrimOp
969
   MutableByteArray# s -> Int# -> Int# -> State# s -> State# s
970
971
972
   with has_side_effects = True

primop  WriteByteArrayOp_Word "writeWordArray#" GenPrimOp
973
   MutableByteArray# s -> Int# -> Word# -> State# s -> State# s
974
975
976
   with has_side_effects = True

primop  WriteByteArrayOp_Addr "writeAddrArray#" GenPrimOp
977
   MutableByteArray# s -> Int# -> Addr# -> State# s -> State# s
978
979
980
   with has_side_effects = True

primop  WriteByteArrayOp_Float "writeFloatArray#" GenPrimOp
981
   MutableByteArray# s -> Int# -> Float# -> State# s -> State# s
982
983
984
   with has_side_effects = True

primop  WriteByteArrayOp_Double "writeDoubleArray#" GenPrimOp
985
   MutableByteArray# s -> Int# -> Double# -> State# s -> State# s
986
987
988
   with has_side_effects = True

primop  WriteByteArrayOp_StablePtr "writeStablePtrArray#" GenPrimOp
989
   MutableByteArray# s -> Int# -> StablePtr# a -> State# s -> State# s
990
991
   with has_side_effects = True

992
primop  WriteByteArrayOp_Int8 "writeInt8Array#" GenPrimOp
993
   MutableByteArray# s -> Int# -> Int# -> State# s -> State# s
994
995
   with has_side_effects = True

996
primop  WriteByteArrayOp_Int16 "writeInt16Array#" GenPrimOp
997
   MutableByteArray# s -> Int# -> Int# -> State# s -> State# s
998
999
   with has_side_effects = True

1000
primop  WriteByteArrayOp_Int32 "writeInt32Array#" GenPrimOp
1001
   MutableByteArray# s -> Int# -> INT32 -> State# s -> State# s
1002
1003
   with has_side_effects = True

1004
primop  WriteByteArrayOp_Int64 "writeInt64Array#" GenPrimOp
1005
   MutableByteArray# s -> Int# -> INT64 -> State# s -> State# s
1006
1007
   with has_side_effects = True

1008
primop  WriteByteArrayOp_Word8 "writeWord8Array#" GenPrimOp
1009
   MutableByteArray# s -> Int# -> Word# -> State# s -> State# s
1010
1011
   with has_side_effects = True

1012
primop  WriteByteArrayOp_Word16 "writeWord16Array#" GenPrimOp
1013
   MutableByteArray# s -> Int# -> Word# -> State# s -> State# s
1014
1015
   with has_side_effects = True

1016
primop  WriteByteArrayOp_Word32 "writeWord32Array#" GenPrimOp
1017
   MutableByteArray# s -> Int# -> WORD32 -> State# s -> State# s
1018
1019
1020
   with has_side_effects = True

primop  WriteByteArrayOp_Word64 "writeWord64Array#" GenPrimOp
1021
   MutableByteArray# s -> Int# -> WORD64 -> State# s -> State# s
1022
   with has_side_effects = True
apt's avatar
apt committed
1023
1024
1025
1026
1027

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

1028
1029
1030
1031
1032
1033
1034
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
1035
1036
primop	 AddrAddOp "plusAddr#" GenPrimOp Addr# -> Int# -> Addr#
primop	 AddrSubOp "minusAddr#" GenPrimOp Addr# -> Addr# -> Int#
1037
1038
	 {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
1039
primop	 AddrRemOp "remAddr#" GenPrimOp Addr# -> Int# -> Int#
1040
1041
	 {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
1042
1043
1044
1045
1046
#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
1047
#endif
1048

apt's avatar
apt committed
1049
1050
1051
1052
1053
1054
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
1055
1056
1057

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

1060
1061
primop IndexOffAddrOp_WideChar "indexWideCharOffAddr#" GenPrimOp
   Addr# -> Int# -> Char#
apt's avatar
apt committed
1062
   {Reads 31-bit character; offset in 4-byte words.}
1063

1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
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

1082
1083
1084
1085
1086
1087
1088
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
1089
   Addr# -> Int# -> INT32
1090

1091
primop IndexOffAddrOp_Int64 "indexInt64OffAddr#" GenPrimOp
apt's avatar
apt committed
1092
   Addr# -> Int# -> INT64
1093

1094
1095
1096
1097
1098
1099
1100
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
1101
   Addr# -> Int# -> WORD32
1102

1103
primop IndexOffAddrOp_Word64 "indexWord64OffAddr#" GenPrimOp
apt's avatar
apt committed
1104
   Addr# -> Int# -> WORD64
1105
1106
1107

primop ReadOffAddrOp_Char "readCharOffAddr#" GenPrimOp
   Addr# -> Int# -> State# s -> (# State# s, Char# #)
apt's avatar
apt committed
1108
   {Reads 8-bit character; offset in bytes.}
1109
   with has_side_effects = True
1110

1111
1112
primop ReadOffAddrOp_WideChar "readWideCharOffAddr#" GenPrimOp
   Addr# -> Int# -> State# s -> (# State# s, Char# #)
apt's avatar
apt committed
1113
   {Reads 31-bit character; offset in 4-byte words.}
1114
   with has_side_effects = True
1115

1116
1117
primop ReadOffAddrOp_Int "readIntOffAddr#" GenPrimOp
   Addr# -> Int# -> State# s -> (# State# s, Int# #)
1118
   with has_side_effects = True
1119
1120
1121

primop ReadOffAddrOp_Word "readWordOffAddr#" GenPrimOp
   Addr# -> Int# -> State# s -> (# State# s, Word# #)
1122
   with has_side_effects = True
1123
1124
1125

primop ReadOffAddrOp_Addr "readAddrOffAddr#" GenPrimOp
   Addr# -> Int# -> State# s -> (# State# s, Addr# #)
1126
   with has_side_effects = True
1127
1128
1129

primop ReadOffAddrOp_Float "readFloatOffAddr#" GenPrimOp
   Addr# -> Int# -> State# s -> (# State# s, Float# #)
1130
   with has_side_effects = True
1131
1132