PrimOp.lhs 82.2 KB
Newer Older
1
2
3
4
5
6
7
8
%
% (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
%
\section[PrimOp]{Primitive operations (machine-level)}

\begin{code}
module PrimOp (
	PrimOp(..), allThePrimOps,
9
10
	primOpType, primOpSig, primOpUsg, primOpArity,
	mkPrimOpIdName, primOpRdrName, primOpTag, primOpOcc,
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37

	commutableOp,

	primOpOutOfLine, primOpNeedsWrapper, primOpStrictness,
	primOpOkForSpeculation, primOpIsCheap, primOpIsDupable,
	primOpHasSideEffects,

	getPrimOpResultInfo,  PrimOpResultInfo(..),

	pprPrimOp
    ) where

#include "HsVersions.h"

import PrimRep		-- most of it
import TysPrim
import TysWiredIn

import Demand		( Demand, wwLazy, wwPrim, wwStrict )
import Var		( TyVar, Id )
import CallConv		( CallConv, pprCallConv )
import PprType		( pprParendType )
import Name		( Name, mkWiredInIdName )
import RdrName		( RdrName, mkRdrQual )
import OccName		( OccName, pprOccName, mkSrcVarOcc )
import TyCon		( TyCon, tyConArity )
import Type		( Type, mkForAllTys, mkForAllTy, mkFunTy, mkFunTys, mkTyVarTys,
38
			  mkTyConTy, mkTyConApp, typePrimRep,mkTyVarTy,
39
40
41
42
			  splitFunTy_maybe, splitAlgTyConApp_maybe, splitTyConApp_maybe,
                          UsageAnn(..), mkUsgTy
			)
import Unique		( Unique, mkPrimOpIdUnique )
43
import BasicTypes	( Arity )
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
import PrelMods		( pREL_GHC, pREL_GHC_Name )
import Outputable
import Util		( assoc, zipWithEqual )
import GlaExts		( Int(..), Int#, (==#) )
\end{code}

%************************************************************************
%*									*
\subsection[PrimOp-datatype]{Datatype for @PrimOp@ (an enumeration)}
%*									*
%************************************************************************

These are in \tr{state-interface.verb} order.

\begin{code}
data PrimOp
    -- dig the FORTRAN/C influence on the names...

    -- comparisons:

    = CharGtOp   | CharGeOp   | CharEqOp   | CharNeOp   | CharLtOp   | CharLeOp
    | IntGtOp    | IntGeOp    | IntEqOp    | IntNeOp	| IntLtOp    | IntLeOp
    | WordGtOp   | WordGeOp   | WordEqOp   | WordNeOp	| WordLtOp   | WordLeOp
    | AddrGtOp   | AddrGeOp   | AddrEqOp   | AddrNeOp	| AddrLtOp   | AddrLeOp
    | FloatGtOp	 | FloatGeOp  | FloatEqOp  | FloatNeOp	| FloatLtOp  | FloatLeOp
    | DoubleGtOp | DoubleGeOp | DoubleEqOp | DoubleNeOp | DoubleLtOp | DoubleLeOp

    -- Char#-related ops:
    | OrdOp | ChrOp

    -- Int#-related ops:
    | IntAddOp | IntSubOp | IntMulOp | IntQuotOp
76
    | IntRemOp | IntNegOp
77
78
79
80
    | ISllOp | ISraOp | ISrlOp -- shift {left,right} {arithmetic,logical}
    | IntAddCOp
    | IntSubCOp
    | IntMulCOp
81
    | IntGcdOp
82
83
84
85
86
87
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
120

    -- Word#-related ops:
    | WordQuotOp | WordRemOp
    | AndOp  | OrOp   | NotOp | XorOp
    | SllOp  | SrlOp  -- shift {left,right} {logical}
    | Int2WordOp | Word2IntOp -- casts

    -- Addr#-related ops:
    | Int2AddrOp | Addr2IntOp -- casts

    -- Float#-related ops:
    | FloatAddOp | FloatSubOp | FloatMulOp | FloatDivOp | FloatNegOp
    | Float2IntOp | Int2FloatOp

    | FloatExpOp   | FloatLogOp	  | FloatSqrtOp
    | FloatSinOp   | FloatCosOp	  | FloatTanOp
    | FloatAsinOp  | FloatAcosOp  | FloatAtanOp
    | FloatSinhOp  | FloatCoshOp  | FloatTanhOp
    -- not all machines have these available conveniently:
    -- | FloatAsinhOp | FloatAcoshOp | FloatAtanhOp
    | FloatPowerOp -- ** op

    -- Double#-related ops:
    | DoubleAddOp | DoubleSubOp | DoubleMulOp | DoubleDivOp | DoubleNegOp
    | Double2IntOp | Int2DoubleOp
    | Double2FloatOp | Float2DoubleOp

    | DoubleExpOp   | DoubleLogOp   | DoubleSqrtOp
    | DoubleSinOp   | DoubleCosOp   | DoubleTanOp
    | DoubleAsinOp  | DoubleAcosOp  | DoubleAtanOp
    | DoubleSinhOp  | DoubleCoshOp  | DoubleTanhOp
    -- not all machines have these available conveniently:
    -- | DoubleAsinhOp | DoubleAcoshOp | DoubleAtanhOp
    | DoublePowerOp -- ** op

    -- Integer (and related...) ops:
    -- slightly weird -- to match GMP package.
    | IntegerAddOp | IntegerSubOp | IntegerMulOp | IntegerGcdOp
    | IntegerQuotRemOp | IntegerDivModOp | IntegerNegOp
121
122
    | IntegerIntGcdOp | IntegerDivExactOp
    | IntegerQuotOp | IntegerRemOp
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178

    | IntegerCmpOp
    | IntegerCmpIntOp

    | Integer2IntOp  | Integer2WordOp  
    | Int2IntegerOp  | Word2IntegerOp
    | Addr2IntegerOp
     -- casting to/from Integer and 64-bit (un)signed quantities.
    | IntegerToInt64Op | Int64ToIntegerOp
    | IntegerToWord64Op | Word64ToIntegerOp
    -- ?? gcd, etc?

    | FloatDecodeOp
    | DoubleDecodeOp

    -- primitive ops for primitive arrays

    | NewArrayOp
    | NewByteArrayOp PrimRep

    | SameMutableArrayOp
    | SameMutableByteArrayOp

    | ReadArrayOp | WriteArrayOp | IndexArrayOp -- for arrays of Haskell ptrs

    | ReadByteArrayOp	PrimRep
    | WriteByteArrayOp	PrimRep
    | IndexByteArrayOp	PrimRep
    | IndexOffAddrOp	PrimRep
    | WriteOffAddrOp    PrimRep
	-- PrimRep can be one of {Char,Int,Addr,Float,Double}Kind.
	-- This is just a cheesy encoding of a bunch of ops.
	-- Note that ForeignObjRep is not included -- the only way of
	-- creating a ForeignObj is with a ccall or casm.
    | IndexOffForeignObjOp PrimRep

    | UnsafeFreezeArrayOp | UnsafeFreezeByteArrayOp
    | UnsafeThawArrayOp   | UnsafeThawByteArrayOp
    | SizeofByteArrayOp   | SizeofMutableByteArrayOp

    -- Mutable variables
    | NewMutVarOp
    | ReadMutVarOp
    | WriteMutVarOp
    | SameMutVarOp

    -- for MVars
    | NewMVarOp
    | TakeMVarOp 
    | PutMVarOp
    | SameMVarOp
    | IsEmptyMVarOp

    -- exceptions
    | CatchOp
    | RaiseOp
179
180
    | BlockAsyncExceptionsOp
    | UnblockAsyncExceptionsOp
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311

    -- foreign objects
    | MakeForeignObjOp
    | WriteForeignObjOp

    -- weak pointers
    | MkWeakOp
    | DeRefWeakOp
    | FinalizeWeakOp

    -- stable names
    | MakeStableNameOp
    | EqStableNameOp
    | StableNameToIntOp

    -- stable pointers
    | MakeStablePtrOp
    | DeRefStablePtrOp
    | EqStablePtrOp
\end{code}

A special ``trap-door'' to use in making calls direct to C functions:
\begin{code}
    | CCallOp	(Either 
		    FAST_STRING    -- Left fn => An "unboxed" ccall# to `fn'.
		    Unique)        -- Right u => first argument (an Addr#) is the function pointer
				   --   (unique is used to generate a 'typedef' to cast
				   --    the function pointer if compiling the ccall# down to
				   --    .hc code - can't do this inline for tedious reasons.)
				    
		Bool		    -- True <=> really a "casm"
		Bool		    -- True <=> might invoke Haskell GC
		CallConv	    -- calling convention to use.

    -- (... to be continued ... )
\end{code}

The ``type'' of @CCallOp foo [t1, ... tm] r@ is @t1 -> ... tm -> r@.
(See @primOpInfo@ for details.)

Note: that first arg and part of the result should be the system state
token (which we carry around to fool over-zealous optimisers) but
which isn't actually passed.

For example, we represent
\begin{pseudocode}
((ccall# foo [StablePtr# a, Int] Float) sp# i#) :: (Float, IoWorld)
\end{pseudocode}
by
\begin{pseudocode}
Case
  ( Prim
      (CCallOp "foo" [Universe#, StablePtr# a, Int#] FloatPrimAndUniverse False)
       -- :: Universe# -> StablePtr# a -> Int# -> FloatPrimAndUniverse
      []
      [w#, sp# i#]
  )
  (AlgAlts [ ( FloatPrimAndIoWorld,
		 [f#, w#],
		 Con (TupleCon 2) [Float, IoWorld] [F# f#, World w#]
	       ) ]
	     NoDefault
  )
\end{pseudocode}

Nota Bene: there are some people who find the empty list of types in
the @Prim@ somewhat puzzling and would represent the above by
\begin{pseudocode}
Case
  ( Prim
      (CCallOp "foo" [alpha1, alpha2, alpha3] alpha4 False)
       -- :: /\ alpha1, alpha2 alpha3, alpha4.
       --       alpha1 -> alpha2 -> alpha3 -> alpha4
      [Universe#, StablePtr# a, Int#, FloatPrimAndIoWorld]
      [w#, sp# i#]
  )
  (AlgAlts [ ( FloatPrimAndIoWorld,
		 [f#, w#],
		 Con (TupleCon 2) [Float, IoWorld] [F# f#, World w#]
	       ) ]
	     NoDefault
  )
\end{pseudocode}

But, this is a completely different way of using @CCallOp@.  The most
major changes required if we switch to this are in @primOpInfo@, and
the desugarer. The major difficulty is in moving the HeapRequirement
stuff somewhere appropriate.  (The advantage is that we could simplify
@CCallOp@ and record just the number of arguments with corresponding
simplifications in reading pragma unfoldings, the simplifier,
instantiation (etc) of core expressions, ... .  Maybe we should think
about using it this way?? ADR)

\begin{code}
    -- (... continued from above ... )

    -- Operation to test two closure addresses for equality (yes really!)
    -- BLAME ALASTAIR REID FOR THIS!  THE REST OF US ARE INNOCENT!
    | ReallyUnsafePtrEqualityOp

    -- parallel stuff
    | SeqOp
    | ParOp

    -- concurrency
    | ForkOp
    | KillThreadOp
    | YieldOp
    | MyThreadIdOp
    | DelayOp
    | WaitReadOp
    | WaitWriteOp

    -- more parallel stuff
    | ParGlobalOp	-- named global par
    | ParLocalOp	-- named local par
    | ParAtOp		-- specifies destination of local par
    | ParAtAbsOp	-- specifies destination of local par (abs processor)
    | ParAtRelOp	-- specifies destination of local par (rel processor)
    | ParAtForNowOp	-- specifies initial destination of global par
    | CopyableOp	-- marks copyable code
    | NoFollowOp	-- marks non-followup expression

    -- tag-related
    | DataToTagOp
    | TagToEnumOp
\end{code}

Used for the Ord instance

\begin{code}
312
313
314
primOpTag :: PrimOp -> Int
primOpTag op = IBOX( tagOf_PrimOp op )

315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
tagOf_PrimOp CharGtOp			      = (ILIT( 1) :: FAST_INT)
tagOf_PrimOp CharGeOp			      = ILIT(  2)
tagOf_PrimOp CharEqOp			      = ILIT(  3)
tagOf_PrimOp CharNeOp			      = ILIT(  4)
tagOf_PrimOp CharLtOp			      = ILIT(  5)
tagOf_PrimOp CharLeOp			      = ILIT(  6)
tagOf_PrimOp IntGtOp			      = ILIT(  7)
tagOf_PrimOp IntGeOp			      = ILIT(  8)
tagOf_PrimOp IntEqOp			      = ILIT(  9)
tagOf_PrimOp IntNeOp			      = ILIT( 10)
tagOf_PrimOp IntLtOp			      = ILIT( 11)
tagOf_PrimOp IntLeOp			      = ILIT( 12)
tagOf_PrimOp WordGtOp			      = ILIT( 13)
tagOf_PrimOp WordGeOp			      = ILIT( 14)
tagOf_PrimOp WordEqOp			      = ILIT( 15)
tagOf_PrimOp WordNeOp			      = ILIT( 16)
tagOf_PrimOp WordLtOp			      = ILIT( 17)
tagOf_PrimOp WordLeOp			      = ILIT( 18)
tagOf_PrimOp AddrGtOp			      = ILIT( 19)
tagOf_PrimOp AddrGeOp			      = ILIT( 20)
tagOf_PrimOp AddrEqOp			      = ILIT( 21)
tagOf_PrimOp AddrNeOp			      = ILIT( 22)
tagOf_PrimOp AddrLtOp			      = ILIT( 23)
tagOf_PrimOp AddrLeOp			      = ILIT( 24)
tagOf_PrimOp FloatGtOp			      = ILIT( 25)
tagOf_PrimOp FloatGeOp			      = ILIT( 26)
tagOf_PrimOp FloatEqOp			      = ILIT( 27)
tagOf_PrimOp FloatNeOp			      = ILIT( 28)
tagOf_PrimOp FloatLtOp			      = ILIT( 29)
tagOf_PrimOp FloatLeOp			      = ILIT( 30)
tagOf_PrimOp DoubleGtOp			      = ILIT( 31)
tagOf_PrimOp DoubleGeOp			      = ILIT( 32)
tagOf_PrimOp DoubleEqOp			      = ILIT( 33)
tagOf_PrimOp DoubleNeOp			      = ILIT( 34)
tagOf_PrimOp DoubleLtOp			      = ILIT( 35)
tagOf_PrimOp DoubleLeOp			      = ILIT( 36)
tagOf_PrimOp OrdOp			      = ILIT( 37)
tagOf_PrimOp ChrOp			      = ILIT( 38)
tagOf_PrimOp IntAddOp			      = ILIT( 39)
tagOf_PrimOp IntSubOp			      = ILIT( 40)
tagOf_PrimOp IntMulOp			      = ILIT( 41)
tagOf_PrimOp IntQuotOp			      = ILIT( 42)
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
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
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
tagOf_PrimOp IntGcdOp			      = ILIT( 43)
tagOf_PrimOp IntRemOp			      = ILIT( 44)
tagOf_PrimOp IntNegOp			      = ILIT( 45)
tagOf_PrimOp WordQuotOp			      = ILIT( 47)
tagOf_PrimOp WordRemOp			      = ILIT( 48)
tagOf_PrimOp AndOp			      = ILIT( 49)
tagOf_PrimOp OrOp			      = ILIT( 50)
tagOf_PrimOp NotOp			      = ILIT( 51)
tagOf_PrimOp XorOp			      = ILIT( 52)
tagOf_PrimOp SllOp			      = ILIT( 53)
tagOf_PrimOp SrlOp			      = ILIT( 54)
tagOf_PrimOp ISllOp			      = ILIT( 55)
tagOf_PrimOp ISraOp			      = ILIT( 56)
tagOf_PrimOp ISrlOp			      = ILIT( 57)
tagOf_PrimOp IntAddCOp			      = ILIT( 58)
tagOf_PrimOp IntSubCOp			      = ILIT( 59)
tagOf_PrimOp IntMulCOp			      = ILIT( 60)
tagOf_PrimOp Int2WordOp			      = ILIT( 61)
tagOf_PrimOp Word2IntOp			      = ILIT( 62)
tagOf_PrimOp Int2AddrOp			      = ILIT( 63)
tagOf_PrimOp Addr2IntOp			      = ILIT( 64)
tagOf_PrimOp FloatAddOp			      = ILIT( 65)
tagOf_PrimOp FloatSubOp			      = ILIT( 66)
tagOf_PrimOp FloatMulOp			      = ILIT( 67)
tagOf_PrimOp FloatDivOp			      = ILIT( 68)
tagOf_PrimOp FloatNegOp			      = ILIT( 69)
tagOf_PrimOp Float2IntOp		      = ILIT( 70)
tagOf_PrimOp Int2FloatOp		      = ILIT( 71)
tagOf_PrimOp FloatExpOp			      = ILIT( 72)
tagOf_PrimOp FloatLogOp			      = ILIT( 73)
tagOf_PrimOp FloatSqrtOp		      = ILIT( 74)
tagOf_PrimOp FloatSinOp			      = ILIT( 75)
tagOf_PrimOp FloatCosOp			      = ILIT( 76)
tagOf_PrimOp FloatTanOp			      = ILIT( 77)
tagOf_PrimOp FloatAsinOp		      = ILIT( 78)
tagOf_PrimOp FloatAcosOp		      = ILIT( 79)
tagOf_PrimOp FloatAtanOp		      = ILIT( 80)
tagOf_PrimOp FloatSinhOp		      = ILIT( 81)
tagOf_PrimOp FloatCoshOp		      = ILIT( 82)
tagOf_PrimOp FloatTanhOp		      = ILIT( 83)
tagOf_PrimOp FloatPowerOp		      = ILIT( 84)
tagOf_PrimOp DoubleAddOp		      = ILIT( 85)
tagOf_PrimOp DoubleSubOp		      = ILIT( 86)
tagOf_PrimOp DoubleMulOp		      = ILIT( 87)
tagOf_PrimOp DoubleDivOp		      = ILIT( 88)
tagOf_PrimOp DoubleNegOp		      = ILIT( 89)
tagOf_PrimOp Double2IntOp		      = ILIT( 90)
tagOf_PrimOp Int2DoubleOp		      = ILIT( 91)
tagOf_PrimOp Double2FloatOp		      = ILIT( 92)
tagOf_PrimOp Float2DoubleOp		      = ILIT( 93)
tagOf_PrimOp DoubleExpOp		      = ILIT( 94)
tagOf_PrimOp DoubleLogOp		      = ILIT( 95)
tagOf_PrimOp DoubleSqrtOp		      = ILIT( 96)
tagOf_PrimOp DoubleSinOp		      = ILIT( 97)
tagOf_PrimOp DoubleCosOp		      = ILIT( 98)
tagOf_PrimOp DoubleTanOp		      = ILIT( 99)
tagOf_PrimOp DoubleAsinOp		      = ILIT(100)
tagOf_PrimOp DoubleAcosOp		      = ILIT(101)
tagOf_PrimOp DoubleAtanOp		      = ILIT(102)
tagOf_PrimOp DoubleSinhOp		      = ILIT(103)
tagOf_PrimOp DoubleCoshOp		      = ILIT(104)
tagOf_PrimOp DoubleTanhOp		      = ILIT(105)
tagOf_PrimOp DoublePowerOp		      = ILIT(106)
tagOf_PrimOp IntegerAddOp		      = ILIT(107)
tagOf_PrimOp IntegerSubOp		      = ILIT(108)
tagOf_PrimOp IntegerMulOp		      = ILIT(109)
tagOf_PrimOp IntegerGcdOp		      = ILIT(110)
tagOf_PrimOp IntegerIntGcdOp		      = ILIT(111)
tagOf_PrimOp IntegerDivExactOp		      = ILIT(112)
tagOf_PrimOp IntegerQuotOp		      = ILIT(113)
tagOf_PrimOp IntegerRemOp		      = ILIT(114)
tagOf_PrimOp IntegerQuotRemOp		      = ILIT(115)
tagOf_PrimOp IntegerDivModOp		      = ILIT(116)
tagOf_PrimOp IntegerNegOp		      = ILIT(117)
tagOf_PrimOp IntegerCmpOp		      = ILIT(118)
tagOf_PrimOp IntegerCmpIntOp		      = ILIT(119)
tagOf_PrimOp Integer2IntOp		      = ILIT(120)
tagOf_PrimOp Integer2WordOp		      = ILIT(121)
tagOf_PrimOp Int2IntegerOp		      = ILIT(122)
tagOf_PrimOp Word2IntegerOp		      = ILIT(123)
tagOf_PrimOp Addr2IntegerOp		      = ILIT(125)
tagOf_PrimOp IntegerToInt64Op		      = ILIT(127)
tagOf_PrimOp Int64ToIntegerOp		      = ILIT(128)
tagOf_PrimOp IntegerToWord64Op		      = ILIT(129)
tagOf_PrimOp Word64ToIntegerOp		      = ILIT(130)
tagOf_PrimOp FloatDecodeOp		      = ILIT(131)
tagOf_PrimOp DoubleDecodeOp		      = ILIT(132)
tagOf_PrimOp NewArrayOp			      = ILIT(133)
tagOf_PrimOp (NewByteArrayOp CharRep)	      = ILIT(134)
tagOf_PrimOp (NewByteArrayOp IntRep)	      = ILIT(135)
tagOf_PrimOp (NewByteArrayOp WordRep)	      = ILIT(136)
tagOf_PrimOp (NewByteArrayOp AddrRep)	      = ILIT(137)
tagOf_PrimOp (NewByteArrayOp FloatRep)	      = ILIT(138)
tagOf_PrimOp (NewByteArrayOp DoubleRep)       = ILIT(139)
tagOf_PrimOp (NewByteArrayOp StablePtrRep)    = ILIT(140)
tagOf_PrimOp SameMutableArrayOp		      = ILIT(141)
tagOf_PrimOp SameMutableByteArrayOp	      = ILIT(142)
tagOf_PrimOp ReadArrayOp		      = ILIT(143)
tagOf_PrimOp WriteArrayOp		      = ILIT(144)
tagOf_PrimOp IndexArrayOp		      = ILIT(145)
tagOf_PrimOp (ReadByteArrayOp CharRep)	      = ILIT(146)
tagOf_PrimOp (ReadByteArrayOp IntRep)	      = ILIT(147)
tagOf_PrimOp (ReadByteArrayOp WordRep)	      = ILIT(148)
tagOf_PrimOp (ReadByteArrayOp AddrRep)	      = ILIT(149)
tagOf_PrimOp (ReadByteArrayOp FloatRep)       = ILIT(150)
tagOf_PrimOp (ReadByteArrayOp DoubleRep)      = ILIT(151)
tagOf_PrimOp (ReadByteArrayOp StablePtrRep)   = ILIT(152)
tagOf_PrimOp (ReadByteArrayOp Int64Rep)	      = ILIT(153)
tagOf_PrimOp (ReadByteArrayOp Word64Rep)      = ILIT(154)
tagOf_PrimOp (WriteByteArrayOp CharRep)       = ILIT(155)
tagOf_PrimOp (WriteByteArrayOp IntRep)	      = ILIT(156)
tagOf_PrimOp (WriteByteArrayOp WordRep)	      = ILIT(157)
tagOf_PrimOp (WriteByteArrayOp AddrRep)       = ILIT(158)
tagOf_PrimOp (WriteByteArrayOp FloatRep)      = ILIT(159)
tagOf_PrimOp (WriteByteArrayOp DoubleRep)     = ILIT(160)
tagOf_PrimOp (WriteByteArrayOp StablePtrRep)  = ILIT(161)
tagOf_PrimOp (WriteByteArrayOp Int64Rep)      = ILIT(162)
tagOf_PrimOp (WriteByteArrayOp Word64Rep)     = ILIT(163)
tagOf_PrimOp (IndexByteArrayOp CharRep)       = ILIT(164)
tagOf_PrimOp (IndexByteArrayOp IntRep)	      = ILIT(165)
tagOf_PrimOp (IndexByteArrayOp WordRep)	      = ILIT(166)
tagOf_PrimOp (IndexByteArrayOp AddrRep)       = ILIT(167)
tagOf_PrimOp (IndexByteArrayOp FloatRep)      = ILIT(168)
tagOf_PrimOp (IndexByteArrayOp DoubleRep)     = ILIT(169)
tagOf_PrimOp (IndexByteArrayOp StablePtrRep)  = ILIT(170)
tagOf_PrimOp (IndexByteArrayOp Int64Rep)      = ILIT(171)
tagOf_PrimOp (IndexByteArrayOp Word64Rep)     = ILIT(172)
tagOf_PrimOp (IndexOffAddrOp CharRep)	      = ILIT(173)
tagOf_PrimOp (IndexOffAddrOp IntRep)	      = ILIT(174)
tagOf_PrimOp (IndexOffAddrOp WordRep)	      = ILIT(175)
tagOf_PrimOp (IndexOffAddrOp AddrRep)	      = ILIT(176)
tagOf_PrimOp (IndexOffAddrOp FloatRep)	      = ILIT(177)
tagOf_PrimOp (IndexOffAddrOp DoubleRep)       = ILIT(178)
tagOf_PrimOp (IndexOffAddrOp StablePtrRep)    = ILIT(179)
tagOf_PrimOp (IndexOffAddrOp Int64Rep)	      = ILIT(180)
tagOf_PrimOp (IndexOffAddrOp Word64Rep)	      = ILIT(181)
tagOf_PrimOp (IndexOffForeignObjOp CharRep)   = ILIT(182)
tagOf_PrimOp (IndexOffForeignObjOp IntRep)    = ILIT(183)
tagOf_PrimOp (IndexOffForeignObjOp WordRep)   = ILIT(184)
tagOf_PrimOp (IndexOffForeignObjOp AddrRep)   = ILIT(185)
tagOf_PrimOp (IndexOffForeignObjOp FloatRep)  = ILIT(186)
tagOf_PrimOp (IndexOffForeignObjOp DoubleRep) = ILIT(187)
tagOf_PrimOp (IndexOffForeignObjOp StablePtrRep) = ILIT(188)
tagOf_PrimOp (IndexOffForeignObjOp Int64Rep)  = ILIT(189)
tagOf_PrimOp (IndexOffForeignObjOp Word64Rep) = ILIT(190)
tagOf_PrimOp (WriteOffAddrOp CharRep)         = ILIT(191)
tagOf_PrimOp (WriteOffAddrOp IntRep)          = ILIT(192)
tagOf_PrimOp (WriteOffAddrOp WordRep)         = ILIT(193)
tagOf_PrimOp (WriteOffAddrOp AddrRep)         = ILIT(194)
tagOf_PrimOp (WriteOffAddrOp FloatRep)        = ILIT(195)
tagOf_PrimOp (WriteOffAddrOp DoubleRep)       = ILIT(196)
tagOf_PrimOp (WriteOffAddrOp StablePtrRep)    = ILIT(197)
tagOf_PrimOp (WriteOffAddrOp ForeignObjRep)   = ILIT(198)
tagOf_PrimOp (WriteOffAddrOp Int64Rep)        = ILIT(199)
tagOf_PrimOp (WriteOffAddrOp Word64Rep)       = ILIT(200)
tagOf_PrimOp UnsafeFreezeArrayOp	      = ILIT(201)
tagOf_PrimOp UnsafeFreezeByteArrayOp	      = ILIT(202)
tagOf_PrimOp UnsafeThawArrayOp		      = ILIT(203)
tagOf_PrimOp UnsafeThawByteArrayOp	      = ILIT(204)
tagOf_PrimOp SizeofByteArrayOp		      = ILIT(205)
tagOf_PrimOp SizeofMutableByteArrayOp	      = ILIT(206)
tagOf_PrimOp NewMVarOp			      = ILIT(207)
tagOf_PrimOp TakeMVarOp		    	      = ILIT(208)
tagOf_PrimOp PutMVarOp		    	      = ILIT(209)
tagOf_PrimOp SameMVarOp		    	      = ILIT(210)
tagOf_PrimOp IsEmptyMVarOp	    	      = ILIT(211)
tagOf_PrimOp MakeForeignObjOp		      = ILIT(212)
tagOf_PrimOp WriteForeignObjOp		      = ILIT(213)
tagOf_PrimOp MkWeakOp			      = ILIT(214)
tagOf_PrimOp DeRefWeakOp		      = ILIT(215)
tagOf_PrimOp FinalizeWeakOp		      = ILIT(216)
tagOf_PrimOp MakeStableNameOp		      = ILIT(217)
tagOf_PrimOp EqStableNameOp		      = ILIT(218)
tagOf_PrimOp StableNameToIntOp		      = ILIT(219)
tagOf_PrimOp MakeStablePtrOp		      = ILIT(220)
tagOf_PrimOp DeRefStablePtrOp		      = ILIT(221)
tagOf_PrimOp EqStablePtrOp		      = ILIT(222)
tagOf_PrimOp (CCallOp _ _ _ _)		      = ILIT(223)
tagOf_PrimOp ReallyUnsafePtrEqualityOp	      = ILIT(224)
tagOf_PrimOp SeqOp			      = ILIT(225)
tagOf_PrimOp ParOp			      = ILIT(226)
tagOf_PrimOp ForkOp			      = ILIT(227)
tagOf_PrimOp KillThreadOp		      = ILIT(228)
tagOf_PrimOp YieldOp			      = ILIT(229)
tagOf_PrimOp MyThreadIdOp		      = ILIT(230)
tagOf_PrimOp DelayOp			      = ILIT(231)
tagOf_PrimOp WaitReadOp			      = ILIT(232)
tagOf_PrimOp WaitWriteOp		      = ILIT(233)
tagOf_PrimOp ParGlobalOp		      = ILIT(234)
tagOf_PrimOp ParLocalOp			      = ILIT(235)
tagOf_PrimOp ParAtOp			      = ILIT(236)
tagOf_PrimOp ParAtAbsOp			      = ILIT(237)
tagOf_PrimOp ParAtRelOp			      = ILIT(238)
tagOf_PrimOp ParAtForNowOp		      = ILIT(239)
tagOf_PrimOp CopyableOp			      = ILIT(240)
tagOf_PrimOp NoFollowOp			      = ILIT(241)
tagOf_PrimOp NewMutVarOp		      = ILIT(242)
tagOf_PrimOp ReadMutVarOp		      = ILIT(243)
tagOf_PrimOp WriteMutVarOp		      = ILIT(244)
tagOf_PrimOp SameMutVarOp		      = ILIT(245)
tagOf_PrimOp CatchOp			      = ILIT(246)
tagOf_PrimOp RaiseOp			      = ILIT(247)
tagOf_PrimOp BlockAsyncExceptionsOp	      = ILIT(248)
tagOf_PrimOp UnblockAsyncExceptionsOp	      = ILIT(249)
tagOf_PrimOp DataToTagOp		      = ILIT(250)
tagOf_PrimOp TagToEnumOp		      = ILIT(251)
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
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631

tagOf_PrimOp op = pprPanic# "tagOf_PrimOp: pattern-match" (ppr op)
--panic# "tagOf_PrimOp: pattern-match"

instance Eq PrimOp where
    op1 == op2 = tagOf_PrimOp op1 _EQ_ tagOf_PrimOp op2

instance Ord PrimOp where
    op1 <  op2 =  tagOf_PrimOp op1 _LT_ tagOf_PrimOp op2
    op1 <= op2 =  tagOf_PrimOp op1 _LE_ tagOf_PrimOp op2
    op1 >= op2 =  tagOf_PrimOp op1 _GE_ tagOf_PrimOp op2
    op1 >  op2 =  tagOf_PrimOp op1 _GT_ tagOf_PrimOp op2
    op1 `compare` op2 | op1 < op2  = LT
		      | op1 == op2 = EQ
		      | otherwise  = GT

instance Outputable PrimOp where
    ppr op = pprPrimOp op

instance Show PrimOp where
    showsPrec p op = showsPrecSDoc p (pprPrimOp op)
\end{code}

An @Enum@-derived list would be better; meanwhile... (ToDo)
\begin{code}
allThePrimOps
  = [	CharGtOp,
	CharGeOp,
	CharEqOp,
	CharNeOp,
	CharLtOp,
	CharLeOp,
	IntGtOp,
	IntGeOp,
	IntEqOp,
	IntNeOp,
	IntLtOp,
	IntLeOp,
	WordGtOp,
	WordGeOp,
	WordEqOp,
	WordNeOp,
	WordLtOp,
	WordLeOp,
	AddrGtOp,
	AddrGeOp,
	AddrEqOp,
	AddrNeOp,
	AddrLtOp,
	AddrLeOp,
	FloatGtOp,
	FloatGeOp,
	FloatEqOp,
	FloatNeOp,
	FloatLtOp,
	FloatLeOp,
	DoubleGtOp,
	DoubleGeOp,
	DoubleEqOp,
	DoubleNeOp,
	DoubleLtOp,
	DoubleLeOp,
	OrdOp,
	ChrOp,
	IntAddOp,
	IntSubOp,
	IntMulOp,
	IntQuotOp,
	IntRemOp,
632
	IntGcdOp,
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
659
660
661
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
	IntNegOp,
	WordQuotOp,
	WordRemOp,
	AndOp,
	OrOp,
	NotOp,
	XorOp,
    	SllOp,
    	SrlOp,
    	ISllOp,
    	ISraOp,
    	ISrlOp,
	IntAddCOp,
	IntSubCOp,
	IntMulCOp,
	Int2WordOp,
	Word2IntOp,
	Int2AddrOp,
	Addr2IntOp,

	FloatAddOp,
	FloatSubOp,
	FloatMulOp,
	FloatDivOp,
	FloatNegOp,
	Float2IntOp,
	Int2FloatOp,
	FloatExpOp,
	FloatLogOp,
	FloatSqrtOp,
	FloatSinOp,
	FloatCosOp,
	FloatTanOp,
	FloatAsinOp,
	FloatAcosOp,
	FloatAtanOp,
	FloatSinhOp,
	FloatCoshOp,
	FloatTanhOp,
	FloatPowerOp,
	DoubleAddOp,
	DoubleSubOp,
	DoubleMulOp,
	DoubleDivOp,
	DoubleNegOp,
	Double2IntOp,
	Int2DoubleOp,
	Double2FloatOp,
	Float2DoubleOp,
	DoubleExpOp,
	DoubleLogOp,
	DoubleSqrtOp,
	DoubleSinOp,
	DoubleCosOp,
	DoubleTanOp,
	DoubleAsinOp,
	DoubleAcosOp,
	DoubleAtanOp,
	DoubleSinhOp,
	DoubleCoshOp,
	DoubleTanhOp,
	DoublePowerOp,
	IntegerAddOp,
	IntegerSubOp,
	IntegerMulOp,
	IntegerGcdOp,
699
700
701
702
        IntegerIntGcdOp,
        IntegerDivExactOp,
        IntegerQuotOp,
        IntegerRemOp,
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
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
	IntegerQuotRemOp,
	IntegerDivModOp,
	IntegerNegOp,
	IntegerCmpOp,
	IntegerCmpIntOp,
	Integer2IntOp,
	Integer2WordOp,
	Int2IntegerOp,
	Word2IntegerOp,
	Addr2IntegerOp,
	IntegerToInt64Op,
	Int64ToIntegerOp,
	IntegerToWord64Op,
	Word64ToIntegerOp,
	FloatDecodeOp,
	DoubleDecodeOp,
	NewArrayOp,
	NewByteArrayOp CharRep,
	NewByteArrayOp IntRep,
	NewByteArrayOp WordRep,
	NewByteArrayOp AddrRep,
	NewByteArrayOp FloatRep,
	NewByteArrayOp DoubleRep,
	NewByteArrayOp StablePtrRep,
	SameMutableArrayOp,
	SameMutableByteArrayOp,
	ReadArrayOp,
	WriteArrayOp,
	IndexArrayOp,
	ReadByteArrayOp CharRep,
	ReadByteArrayOp IntRep,
	ReadByteArrayOp WordRep,
	ReadByteArrayOp AddrRep,
	ReadByteArrayOp FloatRep,
	ReadByteArrayOp DoubleRep,
	ReadByteArrayOp StablePtrRep,
	ReadByteArrayOp Int64Rep,
	ReadByteArrayOp Word64Rep,
	WriteByteArrayOp CharRep,
	WriteByteArrayOp IntRep,
	WriteByteArrayOp WordRep,
	WriteByteArrayOp AddrRep,
	WriteByteArrayOp FloatRep,
	WriteByteArrayOp DoubleRep,
	WriteByteArrayOp StablePtrRep,
	WriteByteArrayOp Int64Rep,
	WriteByteArrayOp Word64Rep,
	IndexByteArrayOp CharRep,
	IndexByteArrayOp IntRep,
	IndexByteArrayOp WordRep,
	IndexByteArrayOp AddrRep,
	IndexByteArrayOp FloatRep,
	IndexByteArrayOp DoubleRep,
	IndexByteArrayOp StablePtrRep,
	IndexByteArrayOp Int64Rep,
	IndexByteArrayOp Word64Rep,
	IndexOffForeignObjOp CharRep,
	IndexOffForeignObjOp AddrRep,
	IndexOffForeignObjOp IntRep,
	IndexOffForeignObjOp WordRep,
	IndexOffForeignObjOp FloatRep,
	IndexOffForeignObjOp DoubleRep,
	IndexOffForeignObjOp StablePtrRep,
	IndexOffForeignObjOp Int64Rep,
	IndexOffForeignObjOp Word64Rep,
	IndexOffAddrOp CharRep,
	IndexOffAddrOp IntRep,
	IndexOffAddrOp WordRep,
	IndexOffAddrOp AddrRep,
	IndexOffAddrOp FloatRep,
	IndexOffAddrOp DoubleRep,
	IndexOffAddrOp StablePtrRep,
	IndexOffAddrOp Int64Rep,
	IndexOffAddrOp Word64Rep,
	WriteOffAddrOp CharRep,
	WriteOffAddrOp IntRep,
	WriteOffAddrOp WordRep,
	WriteOffAddrOp AddrRep,
	WriteOffAddrOp FloatRep,
	WriteOffAddrOp DoubleRep,
	WriteOffAddrOp ForeignObjRep,
	WriteOffAddrOp StablePtrRep,
	WriteOffAddrOp Int64Rep,
	WriteOffAddrOp Word64Rep,
	UnsafeFreezeArrayOp,
	UnsafeFreezeByteArrayOp,
	UnsafeThawArrayOp,
	UnsafeThawByteArrayOp,
	SizeofByteArrayOp,
	SizeofMutableByteArrayOp,
	NewMutVarOp,
	ReadMutVarOp,
	WriteMutVarOp,
	SameMutVarOp,
        CatchOp,
        RaiseOp,
799
800
	BlockAsyncExceptionsOp,
	UnblockAsyncExceptionsOp,
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
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
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
    	NewMVarOp,
	TakeMVarOp,
	PutMVarOp,
	SameMVarOp,
	IsEmptyMVarOp,
	MakeForeignObjOp,
	WriteForeignObjOp,
	MkWeakOp,
	DeRefWeakOp,
	FinalizeWeakOp,
	MakeStableNameOp,
	EqStableNameOp,
	StableNameToIntOp,
	MakeStablePtrOp,
	DeRefStablePtrOp,
	EqStablePtrOp,
	ReallyUnsafePtrEqualityOp,
	ParGlobalOp,
	ParLocalOp,
	ParAtOp,
	ParAtAbsOp,
	ParAtRelOp,
	ParAtForNowOp,
	CopyableOp,
	NoFollowOp,
	SeqOp,
    	ParOp,
    	ForkOp,
	KillThreadOp,
	YieldOp,
	MyThreadIdOp,
	DelayOp,
	WaitReadOp,
	WaitWriteOp,
	DataToTagOp,
	TagToEnumOp
    ]
\end{code}

%************************************************************************
%*									*
\subsection[PrimOp-info]{The essential info about each @PrimOp@}
%*									*
%************************************************************************

The @String@ in the @PrimOpInfos@ is the ``base name'' by which the user may
refer to the primitive operation.  The conventional \tr{#}-for-
unboxed ops is added on later.

The reason for the funny characters in the names is so we do not
interfere with the programmer's Haskell name spaces.

We use @PrimKinds@ for the ``type'' information, because they're
(slightly) more convenient to use than @TyCons@.
\begin{code}
data PrimOpInfo
  = Dyadic	OccName		-- string :: T -> T -> T
		Type
  | Monadic	OccName		-- string :: T -> T
		Type
  | Compare	OccName		-- string :: T -> T -> Bool
		Type

  | GenPrimOp   OccName  	-- string :: \/a1..an . T1 -> .. -> Tk -> T
		[TyVar] 
		[Type] 
		Type 

mkDyadic str  ty = Dyadic  (mkSrcVarOcc str) ty
mkMonadic str ty = Monadic (mkSrcVarOcc str) ty
mkCompare str ty = Compare (mkSrcVarOcc str) ty
mkGenPrimOp str tvs tys ty = GenPrimOp (mkSrcVarOcc str) tvs tys ty
\end{code}

Utility bits:
\begin{code}
one_Integer_ty = [intPrimTy, byteArrayPrimTy]
two_Integer_tys
  = [intPrimTy, byteArrayPrimTy, -- first Integer pieces
     intPrimTy, byteArrayPrimTy] -- second '' pieces
an_Integer_and_Int_tys
  = [intPrimTy, byteArrayPrimTy, -- Integer
     intPrimTy]

unboxedPair	 = mkUnboxedTupleTy 2
unboxedTriple    = mkUnboxedTupleTy 3
unboxedQuadruple = mkUnboxedTupleTy 4

889
890
891
mkIOTy ty = mkFunTy realWorldStatePrimTy 
		    (unboxedPair [realWorldStatePrimTy,ty])

892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
integerMonadic name = mkGenPrimOp name [] one_Integer_ty 
			(unboxedPair one_Integer_ty)

integerDyadic name = mkGenPrimOp name [] two_Integer_tys 
			(unboxedPair one_Integer_ty)

integerDyadic2Results name = mkGenPrimOp name [] two_Integer_tys 
    (unboxedQuadruple two_Integer_tys)

integerCompare name = mkGenPrimOp name [] two_Integer_tys intPrimTy
\end{code}

%************************************************************************
%*									*
\subsubsection{Strictness}
%*									*
%************************************************************************

Not all primops are strict!

\begin{code}
primOpStrictness :: PrimOp -> ([Demand], Bool)
	-- See IdInfo.StrictnessInfo for discussion of what the results
	-- **NB** as a cheap hack, to avoid having to look up the PrimOp's arity,
	-- the list of demands may be infinite!
	-- Use only the ones you ned.

primOpStrictness SeqOp            = ([wwStrict], False)
	-- Seq is strict in its argument; see notes in ConFold.lhs

primOpStrictness ParOp            = ([wwLazy], False)
	-- But Par is lazy, to avoid that the sparked thing
	-- gets evaluted strictly, which it should *not* be

primOpStrictness ForkOp		  = ([wwLazy, wwPrim], False)

primOpStrictness NewArrayOp       = ([wwPrim, wwLazy, wwPrim], False)
primOpStrictness WriteArrayOp     = ([wwPrim, wwPrim, wwLazy, wwPrim], False)

primOpStrictness NewMutVarOp	  = ([wwLazy, wwPrim], False)
primOpStrictness WriteMutVarOp	  = ([wwPrim, wwLazy, wwPrim], False)

primOpStrictness PutMVarOp	  = ([wwPrim, wwLazy, wwPrim], False)

936
primOpStrictness CatchOp	  = ([wwStrict, wwLazy, wwPrim], False)
937
primOpStrictness RaiseOp	  = ([wwLazy], True)	-- NB: True => result is bottom
938
939
primOpStrictness BlockAsyncExceptionsOp    = ([wwLazy], False)
primOpStrictness UnblockAsyncExceptionsOp  = ([wwLazy], False)
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000

primOpStrictness MkWeakOp	  = ([wwLazy, wwLazy, wwLazy, wwPrim], False)
primOpStrictness MakeStableNameOp = ([wwLazy, wwPrim], False)
primOpStrictness MakeStablePtrOp  = ([wwLazy, wwPrim], False)

primOpStrictness DataToTagOp      = ([wwLazy], False)

	-- The rest all have primitive-typed arguments
primOpStrictness other		  = (repeat wwPrim, False)
\end{code}

%************************************************************************
%*									*
\subsubsection[PrimOp-comparison]{PrimOpInfo basic comparison ops}
%*									*
%************************************************************************

@primOpInfo@ gives all essential information (from which everything
else, notably a type, can be constructed) for each @PrimOp@.

\begin{code}
primOpInfo :: PrimOp -> PrimOpInfo
\end{code}

There's plenty of this stuff!

\begin{code}
primOpInfo CharGtOp   = mkCompare SLIT("gtChar#")   charPrimTy
primOpInfo CharGeOp   = mkCompare SLIT("geChar#")   charPrimTy
primOpInfo CharEqOp   = mkCompare SLIT("eqChar#")   charPrimTy
primOpInfo CharNeOp   = mkCompare SLIT("neChar#")   charPrimTy
primOpInfo CharLtOp   = mkCompare SLIT("ltChar#")   charPrimTy
primOpInfo CharLeOp   = mkCompare SLIT("leChar#")   charPrimTy

primOpInfo IntGtOp    = mkCompare SLIT(">#")	   intPrimTy
primOpInfo IntGeOp    = mkCompare SLIT(">=#")	   intPrimTy
primOpInfo IntEqOp    = mkCompare SLIT("==#")	   intPrimTy
primOpInfo IntNeOp    = mkCompare SLIT("/=#")	   intPrimTy
primOpInfo IntLtOp    = mkCompare SLIT("<#")	   intPrimTy
primOpInfo IntLeOp    = mkCompare SLIT("<=#")	   intPrimTy

primOpInfo WordGtOp   = mkCompare SLIT("gtWord#")   wordPrimTy
primOpInfo WordGeOp   = mkCompare SLIT("geWord#")   wordPrimTy
primOpInfo WordEqOp   = mkCompare SLIT("eqWord#")   wordPrimTy
primOpInfo WordNeOp   = mkCompare SLIT("neWord#")   wordPrimTy
primOpInfo WordLtOp   = mkCompare SLIT("ltWord#")   wordPrimTy
primOpInfo WordLeOp   = mkCompare SLIT("leWord#")   wordPrimTy

primOpInfo AddrGtOp   = mkCompare SLIT("gtAddr#")   addrPrimTy
primOpInfo AddrGeOp   = mkCompare SLIT("geAddr#")   addrPrimTy
primOpInfo AddrEqOp   = mkCompare SLIT("eqAddr#")   addrPrimTy
primOpInfo AddrNeOp   = mkCompare SLIT("neAddr#")   addrPrimTy
primOpInfo AddrLtOp   = mkCompare SLIT("ltAddr#")   addrPrimTy
primOpInfo AddrLeOp   = mkCompare SLIT("leAddr#")   addrPrimTy

primOpInfo FloatGtOp  = mkCompare SLIT("gtFloat#")  floatPrimTy
primOpInfo FloatGeOp  = mkCompare SLIT("geFloat#")  floatPrimTy
primOpInfo FloatEqOp  = mkCompare SLIT("eqFloat#")  floatPrimTy
primOpInfo FloatNeOp  = mkCompare SLIT("neFloat#")  floatPrimTy
primOpInfo FloatLtOp  = mkCompare SLIT("ltFloat#")  floatPrimTy
primOpInfo FloatLeOp  = mkCompare SLIT("leFloat#")  floatPrimTy