2 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1996
4 \section[PrimOp]{Primitive operations (machine-level)}
8 PrimOp(..), allThePrimOps,
9 tagOf_PrimOp, -- ToDo: rm
11 primOpType, isCompareOp,
17 primOpCanTriggerGC, primOpNeedsWrapper,
18 primOpOkForSpeculation, primOpIsCheap,
20 HeapRequirement(..), primOpHeapReq,
21 StackRequirement(..), primOpStackRequired,
23 -- export for the Native Code Generator
24 primOpInfo, -- needed for primOpNameInfo
30 #include "HsVersions.h"
32 import PrimRep -- most of it
36 import CStrings ( identToC )
37 import CallConv ( CallConv, pprCallConv )
38 import Constants ( mIN_MP_INT_SIZE, mP_STRUCT_SIZE )
39 import HeapOffs ( addOff, intOff, totHdrSize, HeapOffset )
41 import PprType ( pprParendType )
42 import SMRep ( SMRep(..), SMSpecRepKind(..), SMUpdateKind(..) )
43 import TyCon ( TyCon{-instances-} )
44 import Type ( mkForAllTys, mkFunTy, mkFunTys, mkTyConApp, typePrimRep,
45 splitAlgTyConApp, Type
47 import TyVar --( alphaTyVar, betaTyVar, gammaTyVar )
48 import Unique ( Unique{-instance Eq-} )
49 import Util ( panic#, assoc, panic{-ToDo:rm-} )
51 import GlaExts ( Int(..), Int#, (==#) )
54 %************************************************************************
56 \subsection[PrimOp-datatype]{Datatype for @PrimOp@ (an enumeration)}
58 %************************************************************************
60 These are in \tr{state-interface.verb} order.
64 -- dig the FORTRAN/C influence on the names...
68 = CharGtOp | CharGeOp | CharEqOp | CharNeOp | CharLtOp | CharLeOp
69 | IntGtOp | IntGeOp | IntEqOp | IntNeOp | IntLtOp | IntLeOp
70 | WordGtOp | WordGeOp | WordEqOp | WordNeOp | WordLtOp | WordLeOp
71 | AddrGtOp | AddrGeOp | AddrEqOp | AddrNeOp | AddrLtOp | AddrLeOp
72 | FloatGtOp | FloatGeOp | FloatEqOp | FloatNeOp | FloatLtOp | FloatLeOp
73 | DoubleGtOp | DoubleGeOp | DoubleEqOp | DoubleNeOp | DoubleLtOp | DoubleLeOp
79 -- IntAbsOp unused?? ADR
80 | IntAddOp | IntSubOp | IntMulOp | IntQuotOp
81 | IntRemOp | IntNegOp | IntAbsOp
82 | ISllOp | ISraOp | ISrlOp -- shift {left,right} {arithmetic,logical}
85 | WordQuotOp | WordRemOp
86 | AndOp | OrOp | NotOp | XorOp
87 | SllOp | SrlOp -- shift {left,right} {logical}
88 | Int2WordOp | Word2IntOp -- casts
91 | Int2AddrOp | Addr2IntOp -- casts
93 -- Float#-related ops:
94 | FloatAddOp | FloatSubOp | FloatMulOp | FloatDivOp | FloatNegOp
95 | Float2IntOp | Int2FloatOp
97 | FloatExpOp | FloatLogOp | FloatSqrtOp
98 | FloatSinOp | FloatCosOp | FloatTanOp
99 | FloatAsinOp | FloatAcosOp | FloatAtanOp
100 | FloatSinhOp | FloatCoshOp | FloatTanhOp
101 -- not all machines have these available conveniently:
102 -- | FloatAsinhOp | FloatAcoshOp | FloatAtanhOp
103 | FloatPowerOp -- ** op
105 -- Double#-related ops:
106 | DoubleAddOp | DoubleSubOp | DoubleMulOp | DoubleDivOp | DoubleNegOp
107 | Double2IntOp | Int2DoubleOp
108 | Double2FloatOp | Float2DoubleOp
110 | DoubleExpOp | DoubleLogOp | DoubleSqrtOp
111 | DoubleSinOp | DoubleCosOp | DoubleTanOp
112 | DoubleAsinOp | DoubleAcosOp | DoubleAtanOp
113 | DoubleSinhOp | DoubleCoshOp | DoubleTanhOp
114 -- not all machines have these available conveniently:
115 -- | DoubleAsinhOp | DoubleAcoshOp | DoubleAtanhOp
116 | DoublePowerOp -- ** op
118 -- Integer (and related...) ops:
119 -- slightly weird -- to match GMP package.
120 | IntegerAddOp | IntegerSubOp | IntegerMulOp
121 | IntegerQuotRemOp | IntegerDivModOp | IntegerNegOp
125 | Integer2IntOp | Integer2WordOp
126 | Int2IntegerOp | Word2IntegerOp
127 | Addr2IntegerOp -- "Addr" is *always* a literal string
128 -- casting to/from Integer and 64-bit (un)signed quantities.
129 | IntegerToInt64Op | Int64ToIntegerOp
130 | IntegerToWord64Op | Word64ToIntegerOp
133 | FloatEncodeOp | FloatDecodeOp
134 | DoubleEncodeOp | DoubleDecodeOp
136 -- primitive ops for primitive arrays
139 | NewByteArrayOp PrimRep
142 | SameMutableByteArrayOp
144 | ReadArrayOp | WriteArrayOp | IndexArrayOp -- for arrays of Haskell ptrs
146 | ReadByteArrayOp PrimRep
147 | WriteByteArrayOp PrimRep
148 | IndexByteArrayOp PrimRep
149 | IndexOffAddrOp PrimRep
150 -- PrimRep can be one of {Char,Int,Addr,Float,Double}Kind.
151 -- This is just a cheesy encoding of a bunch of ops.
152 -- Note that ForeignObjRep is not included -- the only way of
153 -- creating a ForeignObj is with a ccall or casm.
154 | IndexOffForeignObjOp PrimRep
155 | WriteOffAddrOp PrimRep
157 | UnsafeFreezeArrayOp | UnsafeFreezeByteArrayOp
158 | SizeofByteArrayOp | SizeofMutableByteArrayOp
160 | NewSynchVarOp -- for MVars and IVars
162 | TakeMVarOp | PutMVarOp
163 | ReadIVarOp | WriteIVarOp
165 | MakeForeignObjOp -- foreign objects (malloc pointers or any old URL)
166 | WriteForeignObjOp -- modifying foreign objects [obscuro factor: 200]
167 | MakeStablePtrOp | DeRefStablePtrOp
170 A special ``trap-door'' to use in making calls direct to C functions:
172 | CCallOp (Maybe FAST_STRING) -- Nothing => first argument (an Addr#) is the function pointer
173 -- Just fn => An "unboxed" ccall# to `fn'.
175 Bool -- True <=> really a "casm"
176 Bool -- True <=> might invoke Haskell GC
177 CallConv -- calling convention to use.
178 [Type] -- Unboxed arguments; the state-token
179 -- argument will have been put *first*
180 Type -- Return type; one of the "StateAnd<blah>#" types
182 -- (... to be continued ... )
185 The ``type'' of @CCallOp foo [t1, ... tm] r@ is @t1 -> ... tm -> r@.
186 (See @primOpInfo@ for details.)
188 Note: that first arg and part of the result should be the system state
189 token (which we carry around to fool over-zealous optimisers) but
190 which isn't actually passed.
192 For example, we represent
194 ((ccall# foo [StablePtr# a, Int] Float) sp# i#) :: (Float, IoWorld)
200 (CCallOp "foo" [Universe#, StablePtr# a, Int#] FloatPrimAndUniverse False)
201 -- :: Universe# -> StablePtr# a -> Int# -> FloatPrimAndUniverse
205 (AlgAlts [ ( FloatPrimAndIoWorld,
207 Con (TupleCon 2) [Float, IoWorld] [F# f#, World w#]
213 Nota Bene: there are some people who find the empty list of types in
214 the @Prim@ somewhat puzzling and would represent the above by
218 (CCallOp "foo" [alpha1, alpha2, alpha3] alpha4 False)
219 -- :: /\ alpha1, alpha2 alpha3, alpha4.
220 -- alpha1 -> alpha2 -> alpha3 -> alpha4
221 [Universe#, StablePtr# a, Int#, FloatPrimAndIoWorld]
224 (AlgAlts [ ( FloatPrimAndIoWorld,
226 Con (TupleCon 2) [Float, IoWorld] [F# f#, World w#]
232 But, this is a completely different way of using @CCallOp@. The most
233 major changes required if we switch to this are in @primOpInfo@, and
234 the desugarer. The major difficulty is in moving the HeapRequirement
235 stuff somewhere appropriate. (The advantage is that we could simplify
236 @CCallOp@ and record just the number of arguments with corresponding
237 simplifications in reading pragma unfoldings, the simplifier,
238 instantiation (etc) of core expressions, ... . Maybe we should think
239 about using it this way?? ADR)
242 -- (... continued from above ... )
244 -- one to support "errorIO" (and, thereby, "error")
247 -- Operation to test two closure addresses for equality (yes really!)
248 -- BLAME ALASTAIR REID FOR THIS! THE REST OF US ARE INNOCENT!
249 | ReallyUnsafePtrEqualityOp
251 -- three for parallel stuff
256 -- three for concurrency
261 | ParGlobalOp -- named global par
262 | ParLocalOp -- named local par
263 | ParAtOp -- specifies destination of local par
264 | ParAtAbsOp -- specifies destination of local par (abs processor)
265 | ParAtRelOp -- specifies destination of local par (rel processor)
266 | ParAtForNowOp -- specifies initial destination of global par
267 | CopyableOp -- marks copyable code
268 | NoFollowOp -- marks non-followup expression
272 Deriving Ix is what we really want! ToDo
273 (Chk around before deleting...)
275 tagOf_PrimOp CharGtOp = (ILIT(1) :: FAST_INT)
276 tagOf_PrimOp CharGeOp = ILIT( 2)
277 tagOf_PrimOp CharEqOp = ILIT( 3)
278 tagOf_PrimOp CharNeOp = ILIT( 4)
279 tagOf_PrimOp CharLtOp = ILIT( 5)
280 tagOf_PrimOp CharLeOp = ILIT( 6)
281 tagOf_PrimOp IntGtOp = ILIT( 7)
282 tagOf_PrimOp IntGeOp = ILIT( 8)
283 tagOf_PrimOp IntEqOp = ILIT( 9)
284 tagOf_PrimOp IntNeOp = ILIT( 10)
285 tagOf_PrimOp IntLtOp = ILIT( 11)
286 tagOf_PrimOp IntLeOp = ILIT( 12)
287 tagOf_PrimOp WordGtOp = ILIT( 13)
288 tagOf_PrimOp WordGeOp = ILIT( 14)
289 tagOf_PrimOp WordEqOp = ILIT( 15)
290 tagOf_PrimOp WordNeOp = ILIT( 16)
291 tagOf_PrimOp WordLtOp = ILIT( 17)
292 tagOf_PrimOp WordLeOp = ILIT( 18)
293 tagOf_PrimOp AddrGtOp = ILIT( 19)
294 tagOf_PrimOp AddrGeOp = ILIT( 20)
295 tagOf_PrimOp AddrEqOp = ILIT( 21)
296 tagOf_PrimOp AddrNeOp = ILIT( 22)
297 tagOf_PrimOp AddrLtOp = ILIT( 23)
298 tagOf_PrimOp AddrLeOp = ILIT( 24)
299 tagOf_PrimOp FloatGtOp = ILIT( 25)
300 tagOf_PrimOp FloatGeOp = ILIT( 26)
301 tagOf_PrimOp FloatEqOp = ILIT( 27)
302 tagOf_PrimOp FloatNeOp = ILIT( 28)
303 tagOf_PrimOp FloatLtOp = ILIT( 29)
304 tagOf_PrimOp FloatLeOp = ILIT( 30)
305 tagOf_PrimOp DoubleGtOp = ILIT( 31)
306 tagOf_PrimOp DoubleGeOp = ILIT( 32)
307 tagOf_PrimOp DoubleEqOp = ILIT( 33)
308 tagOf_PrimOp DoubleNeOp = ILIT( 34)
309 tagOf_PrimOp DoubleLtOp = ILIT( 35)
310 tagOf_PrimOp DoubleLeOp = ILIT( 36)
311 tagOf_PrimOp OrdOp = ILIT( 37)
312 tagOf_PrimOp ChrOp = ILIT( 38)
313 tagOf_PrimOp IntAddOp = ILIT( 39)
314 tagOf_PrimOp IntSubOp = ILIT( 40)
315 tagOf_PrimOp IntMulOp = ILIT( 41)
316 tagOf_PrimOp IntQuotOp = ILIT( 42)
317 tagOf_PrimOp IntRemOp = ILIT( 43)
318 tagOf_PrimOp IntNegOp = ILIT( 44)
319 tagOf_PrimOp IntAbsOp = ILIT( 45)
320 tagOf_PrimOp WordQuotOp = ILIT( 46)
321 tagOf_PrimOp WordRemOp = ILIT( 47)
322 tagOf_PrimOp AndOp = ILIT( 48)
323 tagOf_PrimOp OrOp = ILIT( 49)
324 tagOf_PrimOp NotOp = ILIT( 50)
325 tagOf_PrimOp XorOp = ILIT( 51)
326 tagOf_PrimOp SllOp = ILIT( 52)
327 tagOf_PrimOp SrlOp = ILIT( 53)
328 tagOf_PrimOp ISllOp = ILIT( 54)
329 tagOf_PrimOp ISraOp = ILIT( 55)
330 tagOf_PrimOp ISrlOp = ILIT( 56)
331 tagOf_PrimOp Int2WordOp = ILIT( 57)
332 tagOf_PrimOp Word2IntOp = ILIT( 58)
333 tagOf_PrimOp Int2AddrOp = ILIT( 59)
334 tagOf_PrimOp Addr2IntOp = ILIT( 60)
336 tagOf_PrimOp FloatAddOp = ILIT( 61)
337 tagOf_PrimOp FloatSubOp = ILIT( 62)
338 tagOf_PrimOp FloatMulOp = ILIT( 63)
339 tagOf_PrimOp FloatDivOp = ILIT( 64)
340 tagOf_PrimOp FloatNegOp = ILIT( 65)
341 tagOf_PrimOp Float2IntOp = ILIT( 66)
342 tagOf_PrimOp Int2FloatOp = ILIT( 67)
343 tagOf_PrimOp FloatExpOp = ILIT( 68)
344 tagOf_PrimOp FloatLogOp = ILIT( 69)
345 tagOf_PrimOp FloatSqrtOp = ILIT( 70)
346 tagOf_PrimOp FloatSinOp = ILIT( 71)
347 tagOf_PrimOp FloatCosOp = ILIT( 72)
348 tagOf_PrimOp FloatTanOp = ILIT( 73)
349 tagOf_PrimOp FloatAsinOp = ILIT( 74)
350 tagOf_PrimOp FloatAcosOp = ILIT( 75)
351 tagOf_PrimOp FloatAtanOp = ILIT( 76)
352 tagOf_PrimOp FloatSinhOp = ILIT( 77)
353 tagOf_PrimOp FloatCoshOp = ILIT( 78)
354 tagOf_PrimOp FloatTanhOp = ILIT( 79)
355 tagOf_PrimOp FloatPowerOp = ILIT( 80)
356 tagOf_PrimOp DoubleAddOp = ILIT( 81)
357 tagOf_PrimOp DoubleSubOp = ILIT( 82)
358 tagOf_PrimOp DoubleMulOp = ILIT( 83)
359 tagOf_PrimOp DoubleDivOp = ILIT( 84)
360 tagOf_PrimOp DoubleNegOp = ILIT( 85)
361 tagOf_PrimOp Double2IntOp = ILIT( 86)
362 tagOf_PrimOp Int2DoubleOp = ILIT( 87)
363 tagOf_PrimOp Double2FloatOp = ILIT( 88)
364 tagOf_PrimOp Float2DoubleOp = ILIT( 89)
365 tagOf_PrimOp DoubleExpOp = ILIT( 90)
366 tagOf_PrimOp DoubleLogOp = ILIT( 91)
367 tagOf_PrimOp DoubleSqrtOp = ILIT( 92)
368 tagOf_PrimOp DoubleSinOp = ILIT( 93)
369 tagOf_PrimOp DoubleCosOp = ILIT( 94)
370 tagOf_PrimOp DoubleTanOp = ILIT( 95)
371 tagOf_PrimOp DoubleAsinOp = ILIT( 96)
372 tagOf_PrimOp DoubleAcosOp = ILIT( 97)
373 tagOf_PrimOp DoubleAtanOp = ILIT( 98)
374 tagOf_PrimOp DoubleSinhOp = ILIT( 99)
375 tagOf_PrimOp DoubleCoshOp = ILIT(100)
376 tagOf_PrimOp DoubleTanhOp = ILIT(101)
377 tagOf_PrimOp DoublePowerOp = ILIT(102)
378 tagOf_PrimOp IntegerAddOp = ILIT(103)
379 tagOf_PrimOp IntegerSubOp = ILIT(104)
380 tagOf_PrimOp IntegerMulOp = ILIT(105)
381 tagOf_PrimOp IntegerQuotRemOp = ILIT(106)
382 tagOf_PrimOp IntegerDivModOp = ILIT(107)
383 tagOf_PrimOp IntegerNegOp = ILIT(108)
384 tagOf_PrimOp IntegerCmpOp = ILIT(109)
385 tagOf_PrimOp Integer2IntOp = ILIT(110)
386 tagOf_PrimOp Integer2WordOp = ILIT(111)
387 tagOf_PrimOp Int2IntegerOp = ILIT(112)
388 tagOf_PrimOp Word2IntegerOp = ILIT(113)
389 tagOf_PrimOp Addr2IntegerOp = ILIT(114)
390 tagOf_PrimOp IntegerToInt64Op = ILIT(115)
391 tagOf_PrimOp Int64ToIntegerOp = ILIT(116)
392 tagOf_PrimOp IntegerToWord64Op = ILIT(117)
393 tagOf_PrimOp Word64ToIntegerOp = ILIT(118)
394 tagOf_PrimOp FloatEncodeOp = ILIT(119)
395 tagOf_PrimOp FloatDecodeOp = ILIT(120)
396 tagOf_PrimOp DoubleEncodeOp = ILIT(121)
397 tagOf_PrimOp DoubleDecodeOp = ILIT(122)
398 tagOf_PrimOp NewArrayOp = ILIT(123)
399 tagOf_PrimOp (NewByteArrayOp CharRep) = ILIT(124)
400 tagOf_PrimOp (NewByteArrayOp IntRep) = ILIT(125)
401 tagOf_PrimOp (NewByteArrayOp WordRep) = ILIT(126)
402 tagOf_PrimOp (NewByteArrayOp AddrRep) = ILIT(127)
403 tagOf_PrimOp (NewByteArrayOp FloatRep) = ILIT(128)
404 tagOf_PrimOp (NewByteArrayOp DoubleRep) = ILIT(129)
405 tagOf_PrimOp SameMutableArrayOp = ILIT(130)
406 tagOf_PrimOp SameMutableByteArrayOp = ILIT(131)
407 tagOf_PrimOp ReadArrayOp = ILIT(132)
408 tagOf_PrimOp WriteArrayOp = ILIT(133)
409 tagOf_PrimOp IndexArrayOp = ILIT(134)
410 tagOf_PrimOp (ReadByteArrayOp CharRep) = ILIT(135)
411 tagOf_PrimOp (ReadByteArrayOp IntRep) = ILIT(136)
412 tagOf_PrimOp (ReadByteArrayOp WordRep) = ILIT(137)
413 tagOf_PrimOp (ReadByteArrayOp AddrRep) = ILIT(138)
414 tagOf_PrimOp (ReadByteArrayOp FloatRep) = ILIT(139)
415 tagOf_PrimOp (ReadByteArrayOp DoubleRep) = ILIT(140)
416 tagOf_PrimOp (ReadByteArrayOp Int64Rep) = ILIT(141)
417 tagOf_PrimOp (ReadByteArrayOp Word64Rep) = ILIT(142)
418 tagOf_PrimOp (WriteByteArrayOp CharRep) = ILIT(143)
419 tagOf_PrimOp (WriteByteArrayOp AddrRep) = ILIT(144)
420 tagOf_PrimOp (WriteByteArrayOp IntRep) = ILIT(145)
421 tagOf_PrimOp (WriteByteArrayOp WordRep) = ILIT(146)
422 tagOf_PrimOp (WriteByteArrayOp FloatRep) = ILIT(147)
423 tagOf_PrimOp (WriteByteArrayOp DoubleRep) = ILIT(148)
424 tagOf_PrimOp (WriteByteArrayOp Int64Rep) = ILIT(149)
425 tagOf_PrimOp (WriteByteArrayOp Word64Rep) = ILIT(150)
426 tagOf_PrimOp (IndexByteArrayOp CharRep) = ILIT(151)
427 tagOf_PrimOp (IndexByteArrayOp IntRep) = ILIT(152)
428 tagOf_PrimOp (IndexByteArrayOp WordRep) = ILIT(153)
429 tagOf_PrimOp (IndexByteArrayOp AddrRep) = ILIT(154)
430 tagOf_PrimOp (IndexByteArrayOp FloatRep) = ILIT(155)
431 tagOf_PrimOp (IndexByteArrayOp DoubleRep) = ILIT(156)
432 tagOf_PrimOp (IndexByteArrayOp Int64Rep) = ILIT(157)
433 tagOf_PrimOp (IndexByteArrayOp Word64Rep) = ILIT(158)
434 tagOf_PrimOp (IndexOffAddrOp CharRep) = ILIT(159)
435 tagOf_PrimOp (IndexOffAddrOp IntRep) = ILIT(160)
436 tagOf_PrimOp (IndexOffAddrOp WordRep) = ILIT(161)
437 tagOf_PrimOp (IndexOffAddrOp AddrRep) = ILIT(162)
438 tagOf_PrimOp (IndexOffAddrOp FloatRep) = ILIT(163)
439 tagOf_PrimOp (IndexOffAddrOp DoubleRep) = ILIT(164)
440 tagOf_PrimOp (IndexOffAddrOp Int64Rep) = ILIT(165)
441 tagOf_PrimOp (IndexOffAddrOp Word64Rep) = ILIT(166)
442 tagOf_PrimOp (IndexOffForeignObjOp CharRep) = ILIT(167)
443 tagOf_PrimOp (IndexOffForeignObjOp IntRep) = ILIT(168)
444 tagOf_PrimOp (IndexOffForeignObjOp WordRep) = ILIT(169)
445 tagOf_PrimOp (IndexOffForeignObjOp AddrRep) = ILIT(170)
446 tagOf_PrimOp (IndexOffForeignObjOp FloatRep) = ILIT(171)
447 tagOf_PrimOp (IndexOffForeignObjOp DoubleRep) = ILIT(172)
448 tagOf_PrimOp (IndexOffForeignObjOp Int64Rep) = ILIT(173)
449 tagOf_PrimOp (IndexOffForeignObjOp Word64Rep) = ILIT(174)
450 tagOf_PrimOp (WriteOffAddrOp CharRep) = ILIT(175)
451 tagOf_PrimOp (WriteOffAddrOp IntRep) = ILIT(176)
452 tagOf_PrimOp (WriteOffAddrOp WordRep) = ILIT(177)
453 tagOf_PrimOp (WriteOffAddrOp AddrRep) = ILIT(178)
454 tagOf_PrimOp (WriteOffAddrOp FloatRep) = ILIT(179)
455 tagOf_PrimOp (WriteOffAddrOp DoubleRep) = ILIT(180)
456 tagOf_PrimOp (WriteOffAddrOp Int64Rep) = ILIT(181)
457 tagOf_PrimOp (WriteOffAddrOp Word64Rep) = ILIT(182)
458 tagOf_PrimOp UnsafeFreezeArrayOp = ILIT(183)
459 tagOf_PrimOp UnsafeFreezeByteArrayOp = ILIT(184)
460 tagOf_PrimOp SizeofByteArrayOp = ILIT(185)
461 tagOf_PrimOp SizeofMutableByteArrayOp = ILIT(186)
462 tagOf_PrimOp NewSynchVarOp = ILIT(187)
463 tagOf_PrimOp TakeMVarOp = ILIT(188)
464 tagOf_PrimOp PutMVarOp = ILIT(189)
465 tagOf_PrimOp ReadIVarOp = ILIT(190)
466 tagOf_PrimOp WriteIVarOp = ILIT(191)
467 tagOf_PrimOp MakeForeignObjOp = ILIT(192)
468 tagOf_PrimOp WriteForeignObjOp = ILIT(193)
469 tagOf_PrimOp MakeStablePtrOp = ILIT(194)
470 tagOf_PrimOp DeRefStablePtrOp = ILIT(195)
471 tagOf_PrimOp (CCallOp _ _ _ _ _ _) = ILIT(196)
472 tagOf_PrimOp ErrorIOPrimOp = ILIT(197)
473 tagOf_PrimOp ReallyUnsafePtrEqualityOp = ILIT(198)
474 tagOf_PrimOp SeqOp = ILIT(199)
475 tagOf_PrimOp ParOp = ILIT(200)
476 tagOf_PrimOp ForkOp = ILIT(201)
477 tagOf_PrimOp DelayOp = ILIT(202)
478 tagOf_PrimOp WaitReadOp = ILIT(203)
479 tagOf_PrimOp WaitWriteOp = ILIT(204)
480 tagOf_PrimOp ParGlobalOp = ILIT(205)
481 tagOf_PrimOp ParLocalOp = ILIT(206)
482 tagOf_PrimOp ParAtOp = ILIT(207)
483 tagOf_PrimOp ParAtAbsOp = ILIT(208)
484 tagOf_PrimOp ParAtRelOp = ILIT(209)
485 tagOf_PrimOp ParAtForNowOp = ILIT(210)
486 tagOf_PrimOp CopyableOp = ILIT(211)
487 tagOf_PrimOp NoFollowOp = ILIT(212)
488 tagOf_PrimOp SameMVarOp = ILIT(213)
490 tagOf_PrimOp _ = panic# "tagOf_PrimOp: pattern-match"
492 instance Eq PrimOp where
493 op == op2 = tagOf_PrimOp op _EQ_ tagOf_PrimOp op2
496 An @Enum@-derived list would be better; meanwhile... (ToDo)
622 NewByteArrayOp CharRep,
623 NewByteArrayOp IntRep,
624 NewByteArrayOp WordRep,
625 NewByteArrayOp AddrRep,
626 NewByteArrayOp FloatRep,
627 NewByteArrayOp DoubleRep,
629 SameMutableByteArrayOp,
633 ReadByteArrayOp CharRep,
634 ReadByteArrayOp IntRep,
635 ReadByteArrayOp WordRep,
636 ReadByteArrayOp AddrRep,
637 ReadByteArrayOp FloatRep,
638 ReadByteArrayOp DoubleRep,
639 ReadByteArrayOp Int64Rep,
640 ReadByteArrayOp Word64Rep,
641 WriteByteArrayOp CharRep,
642 WriteByteArrayOp IntRep,
643 WriteByteArrayOp WordRep,
644 WriteByteArrayOp AddrRep,
645 WriteByteArrayOp FloatRep,
646 WriteByteArrayOp DoubleRep,
647 WriteByteArrayOp Int64Rep,
648 WriteByteArrayOp Word64Rep,
649 IndexByteArrayOp CharRep,
650 IndexByteArrayOp IntRep,
651 IndexByteArrayOp WordRep,
652 IndexByteArrayOp AddrRep,
653 IndexByteArrayOp FloatRep,
654 IndexByteArrayOp DoubleRep,
655 IndexByteArrayOp Int64Rep,
656 IndexByteArrayOp Word64Rep,
657 IndexOffAddrOp CharRep,
658 IndexOffAddrOp IntRep,
659 IndexOffAddrOp WordRep,
660 IndexOffAddrOp AddrRep,
661 IndexOffAddrOp FloatRep,
662 IndexOffAddrOp DoubleRep,
663 IndexOffAddrOp Int64Rep,
664 IndexOffAddrOp Word64Rep,
665 IndexOffForeignObjOp CharRep,
666 IndexOffForeignObjOp AddrRep,
667 IndexOffForeignObjOp IntRep,
668 IndexOffForeignObjOp WordRep,
669 IndexOffForeignObjOp FloatRep,
670 IndexOffForeignObjOp DoubleRep,
671 IndexOffForeignObjOp Int64Rep,
672 IndexOffForeignObjOp Word64Rep,
673 WriteOffAddrOp CharRep,
674 WriteOffAddrOp IntRep,
675 WriteOffAddrOp WordRep,
676 WriteOffAddrOp AddrRep,
677 WriteOffAddrOp FloatRep,
678 WriteOffAddrOp DoubleRep,
679 WriteOffAddrOp Int64Rep,
680 WriteOffAddrOp Word64Rep,
682 UnsafeFreezeByteArrayOp,
684 SizeofMutableByteArrayOp,
696 ReallyUnsafePtrEqualityOp,
715 %************************************************************************
717 \subsection[PrimOp-info]{The essential info about each @PrimOp@}
719 %************************************************************************
721 The @String@ in the @PrimOpInfos@ is the ``base name'' by which the user may
722 refer to the primitive operation. The conventional \tr{#}-for-
723 unboxed ops is added on later.
725 The reason for the funny characters in the names is so we do not
726 interfere with the programmer's Haskell name spaces.
728 We use @PrimKinds@ for the ``type'' information, because they're
729 (slightly) more convenient to use than @TyCons@.
732 = Dyadic FAST_STRING -- string :: T -> T -> T
734 | Monadic FAST_STRING -- string :: T -> T
736 | Compare FAST_STRING -- string :: T -> T -> Bool
738 | Coercing FAST_STRING -- string :: T1 -> T2
742 | PrimResult FAST_STRING
743 [TyVar] [Type] TyCon PrimRep [Type]
744 -- "PrimResult tvs [t1,..,tn] D# kind [s1,..,sm]"
745 -- has type Forall tvs. t1 -> ... -> tn -> (D# s1 ... sm)
746 -- D# is a primitive type constructor.
747 -- (the kind is the same info as D#, in another convenient form)
749 | AlgResult FAST_STRING
750 [TyVar] [Type] TyCon [Type]
751 -- "AlgResult tvs [t1,..,tn] T [s1,..,sm]"
752 -- has type Forall tvs. t1 -> ... -> tn -> (T s1 ... sm)
754 -- ToDo: Specialised calls to PrimOps are prohibited but may be desirable
759 one_Integer_ty = [intPrimTy, intPrimTy, byteArrayPrimTy]
761 = [intPrimTy, intPrimTy, byteArrayPrimTy, -- first Integer pieces
762 intPrimTy, intPrimTy, byteArrayPrimTy] -- second '' pieces
763 an_Integer_and_Int_tys
764 = [intPrimTy, intPrimTy, byteArrayPrimTy, -- Integer
767 integerMonadic name = AlgResult name [] one_Integer_ty integerTyCon []
769 integerDyadic name = AlgResult name [] two_Integer_tys integerTyCon []
771 integerDyadic2Results name = AlgResult name [] two_Integer_tys return2GMPsTyCon []
773 integerCompare name = PrimResult name [] two_Integer_tys intPrimTyCon IntRep []
776 @primOpInfo@ gives all essential information (from which everything
777 else, notably a type, can be constructed) for each @PrimOp@.
780 primOpInfo :: PrimOp -> PrimOpInfo
783 There's plenty of this stuff!
785 %************************************************************************
787 \subsubsection[PrimOp-comparison]{PrimOpInfo basic comparison ops}
789 %************************************************************************
792 primOpInfo CharGtOp = Compare SLIT("gtChar#") charPrimTy
793 primOpInfo CharGeOp = Compare SLIT("geChar#") charPrimTy
794 primOpInfo CharEqOp = Compare SLIT("eqChar#") charPrimTy
795 primOpInfo CharNeOp = Compare SLIT("neChar#") charPrimTy
796 primOpInfo CharLtOp = Compare SLIT("ltChar#") charPrimTy
797 primOpInfo CharLeOp = Compare SLIT("leChar#") charPrimTy
799 primOpInfo IntGtOp = Compare SLIT(">#") intPrimTy
800 primOpInfo IntGeOp = Compare SLIT(">=#") intPrimTy
801 primOpInfo IntEqOp = Compare SLIT("==#") intPrimTy
802 primOpInfo IntNeOp = Compare SLIT("/=#") intPrimTy
803 primOpInfo IntLtOp = Compare SLIT("<#") intPrimTy
804 primOpInfo IntLeOp = Compare SLIT("<=#") intPrimTy
806 primOpInfo WordGtOp = Compare SLIT("gtWord#") wordPrimTy
807 primOpInfo WordGeOp = Compare SLIT("geWord#") wordPrimTy
808 primOpInfo WordEqOp = Compare SLIT("eqWord#") wordPrimTy
809 primOpInfo WordNeOp = Compare SLIT("neWord#") wordPrimTy
810 primOpInfo WordLtOp = Compare SLIT("ltWord#") wordPrimTy
811 primOpInfo WordLeOp = Compare SLIT("leWord#") wordPrimTy
813 primOpInfo AddrGtOp = Compare SLIT("gtAddr#") addrPrimTy
814 primOpInfo AddrGeOp = Compare SLIT("geAddr#") addrPrimTy
815 primOpInfo AddrEqOp = Compare SLIT("eqAddr#") addrPrimTy
816 primOpInfo AddrNeOp = Compare SLIT("neAddr#") addrPrimTy
817 primOpInfo AddrLtOp = Compare SLIT("ltAddr#") addrPrimTy
818 primOpInfo AddrLeOp = Compare SLIT("leAddr#") addrPrimTy
820 primOpInfo FloatGtOp = Compare SLIT("gtFloat#") floatPrimTy
821 primOpInfo FloatGeOp = Compare SLIT("geFloat#") floatPrimTy
822 primOpInfo FloatEqOp = Compare SLIT("eqFloat#") floatPrimTy
823 primOpInfo FloatNeOp = Compare SLIT("neFloat#") floatPrimTy
824 primOpInfo FloatLtOp = Compare SLIT("ltFloat#") floatPrimTy
825 primOpInfo FloatLeOp = Compare SLIT("leFloat#") floatPrimTy
827 primOpInfo DoubleGtOp = Compare SLIT(">##") doublePrimTy
828 primOpInfo DoubleGeOp = Compare SLIT(">=##") doublePrimTy
829 primOpInfo DoubleEqOp = Compare SLIT("==##") doublePrimTy
830 primOpInfo DoubleNeOp = Compare SLIT("/=##") doublePrimTy
831 primOpInfo DoubleLtOp = Compare SLIT("<##") doublePrimTy
832 primOpInfo DoubleLeOp = Compare SLIT("<=##") doublePrimTy
836 %************************************************************************
838 \subsubsection[PrimOp-Char]{PrimOpInfo for @Char#@s}
840 %************************************************************************
843 primOpInfo OrdOp = Coercing SLIT("ord#") charPrimTy intPrimTy
844 primOpInfo ChrOp = Coercing SLIT("chr#") intPrimTy charPrimTy
847 %************************************************************************
849 \subsubsection[PrimOp-Int]{PrimOpInfo for @Int#@s}
851 %************************************************************************
854 primOpInfo IntAddOp = Dyadic SLIT("+#") intPrimTy
855 primOpInfo IntSubOp = Dyadic SLIT("-#") intPrimTy
856 primOpInfo IntMulOp = Dyadic SLIT("*#") intPrimTy
857 primOpInfo IntQuotOp = Dyadic SLIT("quotInt#") intPrimTy
858 primOpInfo IntRemOp = Dyadic SLIT("remInt#") intPrimTy
860 primOpInfo IntNegOp = Monadic SLIT("negateInt#") intPrimTy
861 primOpInfo IntAbsOp = Monadic SLIT("absInt#") intPrimTy
864 %************************************************************************
866 \subsubsection[PrimOp-Word]{PrimOpInfo for @Word#@s}
868 %************************************************************************
870 A @Word#@ is an unsigned @Int#@.
873 primOpInfo WordQuotOp = Dyadic SLIT("quotWord#") wordPrimTy
874 primOpInfo WordRemOp = Dyadic SLIT("remWord#") wordPrimTy
876 primOpInfo AndOp = Dyadic SLIT("and#") wordPrimTy
877 primOpInfo OrOp = Dyadic SLIT("or#") wordPrimTy
878 primOpInfo XorOp = Dyadic SLIT("xor#") wordPrimTy
879 primOpInfo NotOp = Monadic SLIT("not#") wordPrimTy
882 = PrimResult SLIT("shiftL#") [] [wordPrimTy, intPrimTy] wordPrimTyCon WordRep []
884 = PrimResult SLIT("shiftRL#") [] [wordPrimTy, intPrimTy] wordPrimTyCon WordRep []
887 = PrimResult SLIT("iShiftL#") [] [intPrimTy, intPrimTy] intPrimTyCon IntRep []
889 = PrimResult SLIT("iShiftRA#") [] [intPrimTy, intPrimTy] intPrimTyCon IntRep []
891 = PrimResult SLIT("iShiftRL#") [] [intPrimTy, intPrimTy] intPrimTyCon IntRep []
893 primOpInfo Int2WordOp = Coercing SLIT("int2Word#") intPrimTy wordPrimTy
894 primOpInfo Word2IntOp = Coercing SLIT("word2Int#") wordPrimTy intPrimTy
897 %************************************************************************
899 \subsubsection[PrimOp-Addr]{PrimOpInfo for @Addr#@s}
901 %************************************************************************
904 primOpInfo Int2AddrOp = Coercing SLIT("int2Addr#") intPrimTy addrPrimTy
905 primOpInfo Addr2IntOp = Coercing SLIT("addr2Int#") addrPrimTy intPrimTy
909 %************************************************************************
911 \subsubsection[PrimOp-Float]{PrimOpInfo for @Float#@s}
913 %************************************************************************
915 @encodeFloat#@ and @decodeFloat#@ are given w/ Integer-stuff (it's
919 primOpInfo FloatAddOp = Dyadic SLIT("plusFloat#") floatPrimTy
920 primOpInfo FloatSubOp = Dyadic SLIT("minusFloat#") floatPrimTy
921 primOpInfo FloatMulOp = Dyadic SLIT("timesFloat#") floatPrimTy
922 primOpInfo FloatDivOp = Dyadic SLIT("divideFloat#") floatPrimTy
923 primOpInfo FloatNegOp = Monadic SLIT("negateFloat#") floatPrimTy
925 primOpInfo Float2IntOp = Coercing SLIT("float2Int#") floatPrimTy intPrimTy
926 primOpInfo Int2FloatOp = Coercing SLIT("int2Float#") intPrimTy floatPrimTy
928 primOpInfo FloatExpOp = Monadic SLIT("expFloat#") floatPrimTy
929 primOpInfo FloatLogOp = Monadic SLIT("logFloat#") floatPrimTy
930 primOpInfo FloatSqrtOp = Monadic SLIT("sqrtFloat#") floatPrimTy
931 primOpInfo FloatSinOp = Monadic SLIT("sinFloat#") floatPrimTy
932 primOpInfo FloatCosOp = Monadic SLIT("cosFloat#") floatPrimTy
933 primOpInfo FloatTanOp = Monadic SLIT("tanFloat#") floatPrimTy
934 primOpInfo FloatAsinOp = Monadic SLIT("asinFloat#") floatPrimTy
935 primOpInfo FloatAcosOp = Monadic SLIT("acosFloat#") floatPrimTy
936 primOpInfo FloatAtanOp = Monadic SLIT("atanFloat#") floatPrimTy
937 primOpInfo FloatSinhOp = Monadic SLIT("sinhFloat#") floatPrimTy
938 primOpInfo FloatCoshOp = Monadic SLIT("coshFloat#") floatPrimTy
939 primOpInfo FloatTanhOp = Monadic SLIT("tanhFloat#") floatPrimTy
940 primOpInfo FloatPowerOp = Dyadic SLIT("powerFloat#") floatPrimTy
943 %************************************************************************
945 \subsubsection[PrimOp-Double]{PrimOpInfo for @Double#@s}
947 %************************************************************************
949 @encodeDouble#@ and @decodeDouble#@ are given w/ Integer-stuff (it's
953 primOpInfo DoubleAddOp = Dyadic SLIT("+##") doublePrimTy
954 primOpInfo DoubleSubOp = Dyadic SLIT("-##") doublePrimTy
955 primOpInfo DoubleMulOp = Dyadic SLIT("*##") doublePrimTy
956 primOpInfo DoubleDivOp = Dyadic SLIT("/##") doublePrimTy
957 primOpInfo DoubleNegOp = Monadic SLIT("negateDouble#") doublePrimTy
959 primOpInfo Double2IntOp = Coercing SLIT("double2Int#") doublePrimTy intPrimTy
960 primOpInfo Int2DoubleOp = Coercing SLIT("int2Double#") intPrimTy doublePrimTy
962 primOpInfo Double2FloatOp = Coercing SLIT("double2Float#") doublePrimTy floatPrimTy
963 primOpInfo Float2DoubleOp = Coercing SLIT("float2Double#") floatPrimTy doublePrimTy
965 primOpInfo DoubleExpOp = Monadic SLIT("expDouble#") doublePrimTy
966 primOpInfo DoubleLogOp = Monadic SLIT("logDouble#") doublePrimTy
967 primOpInfo DoubleSqrtOp = Monadic SLIT("sqrtDouble#") doublePrimTy
968 primOpInfo DoubleSinOp = Monadic SLIT("sinDouble#") doublePrimTy
969 primOpInfo DoubleCosOp = Monadic SLIT("cosDouble#") doublePrimTy
970 primOpInfo DoubleTanOp = Monadic SLIT("tanDouble#") doublePrimTy
971 primOpInfo DoubleAsinOp = Monadic SLIT("asinDouble#") doublePrimTy
972 primOpInfo DoubleAcosOp = Monadic SLIT("acosDouble#") doublePrimTy
973 primOpInfo DoubleAtanOp = Monadic SLIT("atanDouble#") doublePrimTy
974 primOpInfo DoubleSinhOp = Monadic SLIT("sinhDouble#") doublePrimTy
975 primOpInfo DoubleCoshOp = Monadic SLIT("coshDouble#") doublePrimTy
976 primOpInfo DoubleTanhOp = Monadic SLIT("tanhDouble#") doublePrimTy
977 primOpInfo DoublePowerOp= Dyadic SLIT("**##") doublePrimTy
980 %************************************************************************
982 \subsubsection[PrimOp-Integer]{PrimOpInfo for @Integer@ (and related!)}
984 %************************************************************************
987 primOpInfo IntegerNegOp = integerMonadic SLIT("negateInteger#")
989 primOpInfo IntegerAddOp = integerDyadic SLIT("plusInteger#")
990 primOpInfo IntegerSubOp = integerDyadic SLIT("minusInteger#")
991 primOpInfo IntegerMulOp = integerDyadic SLIT("timesInteger#")
993 primOpInfo IntegerCmpOp = integerCompare SLIT("cmpInteger#")
995 primOpInfo IntegerQuotRemOp = integerDyadic2Results SLIT("quotRemInteger#")
996 primOpInfo IntegerDivModOp = integerDyadic2Results SLIT("divModInteger#")
998 primOpInfo Integer2IntOp
999 = PrimResult SLIT("integer2Int#") [] one_Integer_ty intPrimTyCon IntRep []
1001 primOpInfo Integer2WordOp
1002 = PrimResult SLIT("integer2Word#") [] one_Integer_ty wordPrimTyCon IntRep []
1004 primOpInfo Int2IntegerOp
1005 = AlgResult SLIT("int2Integer#") [] [intPrimTy] integerTyCon []
1007 primOpInfo Word2IntegerOp
1008 = AlgResult SLIT("word2Integer#") [] [wordPrimTy] integerTyCon []
1010 primOpInfo Addr2IntegerOp
1011 = AlgResult SLIT("addr2Integer#") [] [addrPrimTy] integerTyCon []
1013 primOpInfo IntegerToInt64Op
1014 = PrimResult SLIT("integerToInt64#") [] one_Integer_ty int64PrimTyCon Int64Rep []
1016 primOpInfo Int64ToIntegerOp
1017 = AlgResult SLIT("int64ToInteger#") [] [int64PrimTy] integerTyCon []
1019 primOpInfo Word64ToIntegerOp
1020 = AlgResult SLIT("word64ToInteger#") [] [word64PrimTy] integerTyCon []
1022 primOpInfo IntegerToWord64Op
1023 = PrimResult SLIT("integerToWord64#") [] one_Integer_ty word64PrimTyCon Word64Rep []
1026 Encoding and decoding of floating-point numbers is sorta
1030 primOpInfo FloatEncodeOp
1031 = PrimResult SLIT("encodeFloat#") [] an_Integer_and_Int_tys
1032 floatPrimTyCon FloatRep []
1034 primOpInfo DoubleEncodeOp
1035 = PrimResult SLIT("encodeDouble#") [] an_Integer_and_Int_tys
1036 doublePrimTyCon DoubleRep []
1038 primOpInfo FloatDecodeOp
1039 = AlgResult SLIT("decodeFloat#") [] [floatPrimTy] returnIntAndGMPTyCon []
1041 primOpInfo DoubleDecodeOp
1042 = AlgResult SLIT("decodeDouble#") [] [doublePrimTy] returnIntAndGMPTyCon []
1045 %************************************************************************
1047 \subsubsection[PrimOp-Arrays]{PrimOpInfo for primitive arrays}
1049 %************************************************************************
1052 primOpInfo NewArrayOp
1054 elt = alphaTy; elt_tv = alphaTyVar; s = betaTy; s_tv = betaTyVar
1056 AlgResult SLIT("newArray#") [s_tv, elt_tv] [intPrimTy, elt, mkStatePrimTy s]
1057 stateAndMutableArrayPrimTyCon [s, elt]
1059 primOpInfo (NewByteArrayOp kind)
1061 s = alphaTy; s_tv = alphaTyVar
1063 (str, _, prim_tycon) = getPrimRepInfo kind
1065 op_str = _PK_ ("new" ++ str ++ "Array#")
1067 AlgResult op_str [s_tv]
1068 [intPrimTy, mkStatePrimTy s]
1069 stateAndMutableByteArrayPrimTyCon [s]
1071 ---------------------------------------------------------------------------
1073 primOpInfo SameMutableArrayOp
1075 elt = alphaTy; elt_tv = alphaTyVar; s = betaTy; s_tv = betaTyVar;
1076 mut_arr_ty = mkMutableArrayPrimTy s elt
1078 AlgResult SLIT("sameMutableArray#") [s_tv, elt_tv] [mut_arr_ty, mut_arr_ty]
1081 primOpInfo SameMutableByteArrayOp
1083 s = alphaTy; s_tv = alphaTyVar;
1084 mut_arr_ty = mkMutableByteArrayPrimTy s
1086 AlgResult SLIT("sameMutableByteArray#") [s_tv] [mut_arr_ty, mut_arr_ty]
1089 ---------------------------------------------------------------------------
1090 -- Primitive arrays of Haskell pointers:
1092 primOpInfo ReadArrayOp
1094 elt = alphaTy; elt_tv = alphaTyVar; s = betaTy; s_tv = betaTyVar
1096 AlgResult SLIT("readArray#") [s_tv, elt_tv]
1097 [mkMutableArrayPrimTy s elt, intPrimTy, mkStatePrimTy s]
1098 stateAndPtrPrimTyCon [s, elt]
1101 primOpInfo WriteArrayOp
1103 elt = alphaTy; elt_tv = alphaTyVar; s = betaTy; s_tv = betaTyVar
1105 PrimResult SLIT("writeArray#") [s_tv, elt_tv]
1106 [mkMutableArrayPrimTy s elt, intPrimTy, elt, mkStatePrimTy s]
1107 statePrimTyCon VoidRep [s]
1109 primOpInfo IndexArrayOp
1110 = let { elt = alphaTy; elt_tv = alphaTyVar } in
1111 AlgResult SLIT("indexArray#") [elt_tv] [mkArrayPrimTy elt, intPrimTy]
1114 ---------------------------------------------------------------------------
1115 -- Primitive arrays full of unboxed bytes:
1117 primOpInfo (ReadByteArrayOp kind)
1119 s = alphaTy; s_tv = alphaTyVar
1121 (str, _, prim_tycon) = getPrimRepInfo kind
1123 op_str = _PK_ ("read" ++ str ++ "Array#")
1124 relevant_tycon = assoc "primOpInfo" tbl kind
1126 AlgResult op_str [s_tv]
1127 [mkMutableByteArrayPrimTy s, intPrimTy, mkStatePrimTy s]
1130 tbl = [ (CharRep, stateAndCharPrimTyCon),
1131 (IntRep, stateAndIntPrimTyCon),
1132 (WordRep, stateAndWordPrimTyCon),
1133 (AddrRep, stateAndAddrPrimTyCon),
1134 (FloatRep, stateAndFloatPrimTyCon),
1135 (DoubleRep, stateAndDoublePrimTyCon) ]
1137 -- How come there's no Word byte arrays? ADR
1139 primOpInfo (WriteByteArrayOp kind)
1141 s = alphaTy; s_tv = alphaTyVar
1143 (str, prim_ty, _) = getPrimRepInfo kind
1144 op_str = _PK_ ("write" ++ str ++ "Array#")
1146 -- NB: *Prim*Result --
1147 PrimResult op_str [s_tv]
1148 [mkMutableByteArrayPrimTy s, intPrimTy, prim_ty, mkStatePrimTy s]
1149 statePrimTyCon VoidRep [s]
1151 primOpInfo (IndexByteArrayOp kind)
1153 (str, _, prim_tycon) = getPrimRepInfo kind
1154 op_str = _PK_ ("index" ++ str ++ "Array#")
1156 -- NB: *Prim*Result --
1157 PrimResult op_str [] [byteArrayPrimTy, intPrimTy] prim_tycon kind []
1159 primOpInfo (IndexOffAddrOp kind)
1161 (str, _, prim_tycon) = getPrimRepInfo kind
1162 op_str = _PK_ ("index" ++ str ++ "OffAddr#")
1164 PrimResult op_str [] [addrPrimTy, intPrimTy] prim_tycon kind []
1166 primOpInfo (IndexOffForeignObjOp kind)
1168 (str, _, prim_tycon) = getPrimRepInfo kind
1169 op_str = _PK_ ("index" ++ str ++ "OffForeignObj#")
1171 PrimResult op_str [] [foreignObjPrimTy, intPrimTy] prim_tycon kind []
1173 primOpInfo (WriteOffAddrOp kind)
1175 s = alphaTy; s_tv = alphaTyVar
1177 (str, prim_ty, _) = getPrimRepInfo kind
1178 op_str = _PK_ ("write" ++ str ++ "OffAddr#")
1180 -- NB: *Prim*Result --
1181 PrimResult op_str [s_tv]
1182 [addrPrimTy, intPrimTy, prim_ty, mkStatePrimTy s]
1183 statePrimTyCon VoidRep [s]
1185 ---------------------------------------------------------------------------
1186 primOpInfo UnsafeFreezeArrayOp
1188 elt = alphaTy; elt_tv = alphaTyVar; s = betaTy; s_tv = betaTyVar
1190 AlgResult SLIT("unsafeFreezeArray#") [s_tv, elt_tv]
1191 [mkMutableArrayPrimTy s elt, mkStatePrimTy s]
1192 stateAndArrayPrimTyCon [s, elt]
1194 primOpInfo UnsafeFreezeByteArrayOp
1195 = let { s = alphaTy; s_tv = alphaTyVar } in
1196 AlgResult SLIT("unsafeFreezeByteArray#") [s_tv]
1197 [mkMutableByteArrayPrimTy s, mkStatePrimTy s]
1198 stateAndByteArrayPrimTyCon [s]
1199 ---------------------------------------------------------------------------
1200 primOpInfo SizeofByteArrayOp
1202 SLIT("sizeofByteArray#") []
1204 intPrimTyCon IntRep []
1206 primOpInfo SizeofMutableByteArrayOp
1207 = let { s = alphaTy; s_tv = alphaTyVar } in
1209 SLIT("sizeofMutableByteArray#") [s_tv]
1210 [mkMutableByteArrayPrimTy s]
1211 intPrimTyCon IntRep []
1215 %************************************************************************
1217 \subsubsection[PrimOp-SynchVars]{PrimOpInfo for synchronizing Variables}
1219 %************************************************************************
1222 primOpInfo NewSynchVarOp
1224 elt = alphaTy; elt_tv = alphaTyVar; s = betaTy; s_tv = betaTyVar
1226 AlgResult SLIT("newSynchVar#") [s_tv, elt_tv] [mkStatePrimTy s]
1227 stateAndSynchVarPrimTyCon [s, elt]
1229 primOpInfo SameMVarOp
1231 elt = alphaTy; elt_tv = alphaTyVar; s = betaTy; s_tv = betaTyVar;
1232 mvar_ty = mkSynchVarPrimTy s elt
1234 AlgResult SLIT("sameMVar#") [s_tv, elt_tv] [mvar_ty, mvar_ty]
1237 primOpInfo TakeMVarOp
1239 elt = alphaTy; elt_tv = alphaTyVar; s = betaTy; s_tv = betaTyVar
1241 AlgResult SLIT("takeMVar#") [s_tv, elt_tv]
1242 [mkSynchVarPrimTy s elt, mkStatePrimTy s]
1243 stateAndPtrPrimTyCon [s, elt]
1245 primOpInfo PutMVarOp
1247 elt = alphaTy; elt_tv = alphaTyVar; s = betaTy; s_tv = betaTyVar
1249 AlgResult SLIT("putMVar#") [s_tv, elt_tv]
1250 [mkSynchVarPrimTy s elt, elt, mkStatePrimTy s]
1253 primOpInfo ReadIVarOp
1255 elt = alphaTy; elt_tv = alphaTyVar; s = betaTy; s_tv = betaTyVar
1257 AlgResult SLIT("readIVar#") [s_tv, elt_tv]
1258 [mkSynchVarPrimTy s elt, mkStatePrimTy s]
1259 stateAndPtrPrimTyCon [s, elt]
1261 primOpInfo WriteIVarOp
1263 elt = alphaTy; elt_tv = alphaTyVar; s = betaTy; s_tv = betaTyVar
1265 AlgResult SLIT("writeIVar#") [s_tv, elt_tv]
1266 [mkSynchVarPrimTy s elt, elt, mkStatePrimTy s]
1271 %************************************************************************
1273 \subsubsection[PrimOp-Wait]{PrimOpInfo for delay/wait operations}
1275 %************************************************************************
1281 s = alphaTy; s_tv = alphaTyVar
1283 PrimResult SLIT("delay#") [s_tv]
1284 [intPrimTy, mkStatePrimTy s]
1285 statePrimTyCon VoidRep [s]
1287 primOpInfo WaitReadOp
1289 s = alphaTy; s_tv = alphaTyVar
1291 PrimResult SLIT("waitRead#") [s_tv]
1292 [intPrimTy, mkStatePrimTy s]
1293 statePrimTyCon VoidRep [s]
1295 primOpInfo WaitWriteOp
1297 s = alphaTy; s_tv = alphaTyVar
1299 PrimResult SLIT("waitWrite#") [s_tv]
1300 [intPrimTy, mkStatePrimTy s]
1301 statePrimTyCon VoidRep [s]
1304 %************************************************************************
1306 \subsubsection[PrimOps-ForeignObj]{PrimOpInfo for Foreign Objects}
1308 %************************************************************************
1310 Not everything should/can be in the Haskell heap. As an example, in an
1311 image processing application written in Haskell, you really would like
1312 to avoid heaving huge images between different space or generations of
1313 a garbage collector. Instead use @ForeignObj@ (formerly known as @MallocPtr@),
1314 which refer to some externally allocated structure/value. Using @ForeignObj@,
1315 just a reference to an image is present in the heap, the image could then
1316 be stored outside the Haskell heap, i.e., as a malloc'ed structure or in
1317 a completely separate address space alltogether.
1319 When a @ForeignObj@ becomes garbage, a user-defined finalisation routine
1320 associated with the object is invoked (currently, each ForeignObj has a
1321 direct reference to its finaliser). -- SOF
1323 A @ForeignObj@ is created by the @makeForeignObj#@ primitive:
1326 makeForeignObj# :: Addr# -- foreign object
1327 -> Addr# -- ptr to its finaliser routine
1328 -> StateAndForeignObj# _RealWorld# ForeignObj#
1333 primOpInfo MakeForeignObjOp
1334 = AlgResult SLIT("makeForeignObj#") []
1335 [addrPrimTy, addrPrimTy, realWorldStatePrimTy]
1336 stateAndForeignObjPrimTyCon [realWorldTy]
1340 In addition, another @ForeignObj@ primitive is provided for destructively modifying
1341 the external object wrapped up inside a @ForeignObj@. This primitive is used
1342 when a mixed programming interface of implicit and explicit de-allocation is used,
1343 e.g., if @ForeignObj@s are used to implement @Handle@s, then @Handle@s can be
1344 released either explicitly (through @hClose@) or implicitly (via a finaliser).
1345 When releasing/closing the @Handle@ explicitly, care must be taken to avoid having
1346 the finaliser for the embedded @ForeignObj@ attempt the same thing later.
1347 We deal with this situation, by allowing the programmer to destructively modify
1348 the data field of the @ForeignObj@ to hold a special value the finaliser recognises,
1349 and does not attempt to free (e.g., filling the data slot with \tr{NULL}).
1352 writeForeignObj# :: ForeignObj# -- foreign object
1353 -> Addr# -- new data value
1354 -> StateAndForeignObj# _RealWorld# ForeignObj#
1358 primOpInfo WriteForeignObjOp
1360 s = alphaTy; s_tv = alphaTyVar
1362 PrimResult SLIT("writeForeignObj#") [s_tv]
1363 [foreignObjPrimTy, addrPrimTy, mkStatePrimTy s]
1364 statePrimTyCon VoidRep [s]
1367 %************************************************************************
1369 \subsubsection[PrimOp-stable-pointers]{PrimOpInfo for ``stable pointers''}
1371 %************************************************************************
1373 A {\em stable pointer} is an index into a table of pointers into the
1374 heap. Since the garbage collector is told about stable pointers, it
1375 is safe to pass a stable pointer to external systems such as C
1378 Here's what the operations and types are supposed to be (from
1379 state-interface document).
1382 makeStablePtr# :: a -> State# _RealWorld -> StateAndStablePtr# _RealWorld a
1383 freeStablePtr# :: StablePtr# a -> State# _RealWorld -> State# _RealWorld
1384 deRefStablePtr# :: StablePtr# a -> State# _RealWorld -> StateAndPtr _RealWorld a
1387 It may seem a bit surprising that @makeStablePtr#@ is a @PrimIO@
1388 operation since it doesn't (directly) involve IO operations. The
1389 reason is that if some optimisation pass decided to duplicate calls to
1390 @makeStablePtr#@ and we only pass one of the stable pointers over, a
1391 massive space leak can result. Putting it into the PrimIO monad
1392 prevents this. (Another reason for putting them in a monad is to
1393 ensure correct sequencing wrt the side-effecting @freeStablePtr#@
1396 Note that we can implement @freeStablePtr#@ using @_ccall_@ (and,
1397 besides, it's not likely to be used from Haskell) so it's not a
1400 Question: Why @_RealWorld@ - won't any instance of @_ST@ do the job? [ADR]
1403 primOpInfo MakeStablePtrOp
1404 = AlgResult SLIT("makeStablePtr#") [alphaTyVar]
1405 [alphaTy, realWorldStatePrimTy]
1406 stateAndStablePtrPrimTyCon [realWorldTy, alphaTy]
1408 primOpInfo DeRefStablePtrOp
1409 = AlgResult SLIT("deRefStablePtr#") [alphaTyVar]
1410 [mkStablePtrPrimTy alphaTy, realWorldStatePrimTy]
1411 stateAndPtrPrimTyCon [realWorldTy, alphaTy]
1414 %************************************************************************
1416 \subsubsection[PrimOp-unsafePointerEquality]{PrimOpInfo for Pointer Equality}
1418 %************************************************************************
1420 [Alastair Reid is to blame for this!]
1422 These days, (Glasgow) Haskell seems to have a bit of everything from
1423 other languages: strict operations, mutable variables, sequencing,
1424 pointers, etc. About the only thing left is LISP's ability to test
1425 for pointer equality. So, let's add it in!
1428 reallyUnsafePtrEquality :: a -> a -> Int#
1431 which tests any two closures (of the same type) to see if they're the
1432 same. (Returns $0$ for @False@, $\neq 0$ for @True@ - to avoid
1433 difficulties of trying to box up the result.)
1435 NB This is {\em really unsafe\/} because even something as trivial as
1436 a garbage collection might change the answer by removing indirections.
1437 Still, no-one's forcing you to use it. If you're worried about little
1438 things like loss of referential transparency, you might like to wrap
1439 it all up in a monad-like thing as John O'Donnell and John Hughes did
1440 for non-determinism (1989 (Fraserburgh) Glasgow FP Workshop
1443 I'm thinking of using it to speed up a critical equality test in some
1444 graphics stuff in a context where the possibility of saying that
1445 denotationally equal things aren't isn't a problem (as long as it
1446 doesn't happen too often.) ADR
1448 To Will: Jim said this was already in, but I can't see it so I'm
1449 adding it. Up to you whether you add it. (Note that this could have
1450 been readily implemented using a @veryDangerousCCall@ before they were
1454 primOpInfo ReallyUnsafePtrEqualityOp
1455 = PrimResult SLIT("reallyUnsafePtrEquality#") [alphaTyVar]
1456 [alphaTy, alphaTy] intPrimTyCon IntRep []
1459 %************************************************************************
1461 \subsubsection[PrimOp-parallel]{PrimOpInfo for parallelism op(s)}
1463 %************************************************************************
1466 primOpInfo SeqOp -- seq# :: a -> Int#
1467 = PrimResult SLIT("seq#") [alphaTyVar] [alphaTy] intPrimTyCon IntRep []
1469 primOpInfo ParOp -- par# :: a -> Int#
1470 = PrimResult SLIT("par#") [alphaTyVar] [alphaTy] intPrimTyCon IntRep []
1472 primOpInfo ForkOp -- fork# :: a -> Int#
1473 = PrimResult SLIT("fork#") [alphaTyVar] [alphaTy] intPrimTyCon IntRep []
1478 -- HWL: The first 4 Int# in all par... annotations denote:
1479 -- name, granularity info, size of result, degree of parallelism
1480 -- Same structure as _seq_ i.e. returns Int#
1482 primOpInfo ParGlobalOp -- parGlobal# :: Int# -> Int# -> Int# -> Int# -> a -> b -> b
1483 = PrimResult SLIT("parGlobal#") [alphaTyVar,betaTyVar] [alphaTy,intPrimTy,intPrimTy,intPrimTy,intPrimTy,betaTy] intPrimTyCon IntRep [] -- liftTyCon [betaTy]
1485 primOpInfo ParLocalOp -- parLocal# :: Int# -> Int# -> Int# -> Int# -> a -> b -> b
1486 = PrimResult SLIT("parLocal#") [alphaTyVar,betaTyVar] [alphaTy,intPrimTy,intPrimTy,intPrimTy,intPrimTy,betaTy] intPrimTyCon IntRep [] -- liftTyCon [betaTy]
1488 primOpInfo ParAtOp -- parAt# :: Int# -> Int# -> Int# -> Int# -> a -> b -> c -> c
1489 = PrimResult SLIT("parAt#") [alphaTyVar,betaTyVar,gammaTyVar] [betaTy,alphaTy,intPrimTy,intPrimTy,intPrimTy,intPrimTy,gammaTy] intPrimTyCon IntRep [] -- liftTyCon [gammaTy]
1491 primOpInfo ParAtAbsOp -- parAtAbs# :: Int# -> Int# -> Int# -> Int# -> Int# -> a -> b -> b
1492 = PrimResult SLIT("parAtAbs#") [alphaTyVar,betaTyVar] [alphaTy,intPrimTy,intPrimTy,intPrimTy,intPrimTy,intPrimTy,betaTy] intPrimTyCon IntRep [] -- liftTyCon [betaTy]
1494 primOpInfo ParAtRelOp -- parAtRel# :: Int# -> Int# -> Int# -> Int# -> Int# -> a -> b -> b
1495 = PrimResult SLIT("parAtRel#") [alphaTyVar,betaTyVar] [alphaTy,intPrimTy,intPrimTy,intPrimTy,intPrimTy,intPrimTy,betaTy] intPrimTyCon IntRep [] -- liftTyCon [betaTy]
1497 primOpInfo ParAtForNowOp -- parAtForNow# :: Int# -> Int# -> Int# -> Int# -> a -> b -> c -> c
1498 = PrimResult SLIT("parAtForNow#") [alphaTyVar,betaTyVar,gammaTyVar] [betaTy,alphaTy,intPrimTy,intPrimTy,intPrimTy,intPrimTy,gammaTy] intPrimTyCon IntRep [] -- liftTyCon [gammaTy]
1500 primOpInfo CopyableOp -- copyable# :: a -> a
1501 = PrimResult SLIT("copyable#") [alphaTyVar] [alphaTy] intPrimTyCon IntRep [] -- liftTyCon [alphaTy]
1503 primOpInfo NoFollowOp -- noFollow# :: a -> a
1504 = PrimResult SLIT("noFollow#") [alphaTyVar] [alphaTy] intPrimTyCon IntRep [] -- liftTyCon [alphaTy]
1507 %************************************************************************
1509 \subsubsection[PrimOp-errorIO]{PrimOpInfo for @errorIO#@}
1511 %************************************************************************
1514 -- errorIO# :: (State# RealWorld# -> a) -> State# RealWorld#
1515 primOpInfo ErrorIOPrimOp
1516 = PrimResult SLIT("errorIO#") [alphaTyVar]
1517 [mkFunTy realWorldStatePrimTy alphaTy]
1518 statePrimTyCon VoidRep [realWorldTy]
1521 %************************************************************************
1523 \subsubsection[PrimOp-IO-etc]{PrimOpInfo for C calls, and I/O-ish things}
1525 %************************************************************************
1528 primOpInfo (CCallOp _ _ _ _ arg_tys result_ty)
1529 = AlgResult SLIT("ccall#") [] arg_tys result_tycon tys_applied
1531 (result_tycon, tys_applied, _) = splitAlgTyConApp result_ty
1534 primOpInfo op = panic ("primOpInfo:"++ show (I# (tagOf_PrimOp op)))
1538 %************************************************************************
1540 \subsection[PrimOp-utils]{Utilities for @PrimitiveOps@}
1542 %************************************************************************
1544 The primitive-array-creation @PrimOps@ and {\em most} of those to do
1545 with @Integers@ can trigger GC. Here we describe the heap requirements
1546 of the various @PrimOps@. For most, no heap is required. For a few,
1547 a fixed amount of heap is required, and the needs of the @PrimOp@ can
1548 be combined with the rest of the heap usage in the basic block. For an
1549 unfortunate few, some unknown amount of heap is required (these are the
1550 ops which can trigger GC).
1553 data HeapRequirement
1555 | FixedHeapRequired HeapOffset
1556 | VariableHeapRequired
1558 primOpHeapReq :: PrimOp -> HeapRequirement
1560 primOpHeapReq NewArrayOp = VariableHeapRequired
1561 primOpHeapReq (NewByteArrayOp _)= VariableHeapRequired
1563 primOpHeapReq IntegerAddOp = VariableHeapRequired
1564 primOpHeapReq IntegerSubOp = VariableHeapRequired
1565 primOpHeapReq IntegerMulOp = VariableHeapRequired
1566 primOpHeapReq IntegerQuotRemOp = VariableHeapRequired
1567 primOpHeapReq IntegerDivModOp = VariableHeapRequired
1568 primOpHeapReq IntegerNegOp = VariableHeapRequired
1569 primOpHeapReq Int2IntegerOp = FixedHeapRequired
1570 (addOff (totHdrSize (DataRep mIN_MP_INT_SIZE))
1571 (intOff mIN_MP_INT_SIZE))
1572 primOpHeapReq Word2IntegerOp = FixedHeapRequired
1573 (addOff (totHdrSize (DataRep mIN_MP_INT_SIZE))
1574 (intOff mIN_MP_INT_SIZE))
1575 primOpHeapReq Addr2IntegerOp = VariableHeapRequired
1576 primOpHeapReq IntegerToInt64Op = FixedHeapRequired
1577 (addOff (totHdrSize (DataRep mIN_MP_INT_SIZE))
1578 (intOff mIN_MP_INT_SIZE))
1579 primOpHeapReq Word64ToIntegerOp = FixedHeapRequired
1580 (addOff (totHdrSize (DataRep mIN_MP_INT_SIZE))
1581 (intOff mIN_MP_INT_SIZE))
1582 primOpHeapReq Int64ToIntegerOp = FixedHeapRequired
1583 (addOff (totHdrSize (DataRep mIN_MP_INT_SIZE))
1584 (intOff mIN_MP_INT_SIZE))
1585 primOpHeapReq IntegerToWord64Op = FixedHeapRequired
1586 (addOff (totHdrSize (DataRep mIN_MP_INT_SIZE))
1587 (intOff mIN_MP_INT_SIZE))
1588 primOpHeapReq FloatDecodeOp = FixedHeapRequired
1589 (addOff (intOff (getPrimRepSize IntRep + mP_STRUCT_SIZE))
1590 (addOff (totHdrSize (DataRep mIN_MP_INT_SIZE))
1591 (intOff mIN_MP_INT_SIZE)))
1592 primOpHeapReq DoubleDecodeOp = FixedHeapRequired
1593 (addOff (intOff (getPrimRepSize IntRep + mP_STRUCT_SIZE))
1594 (addOff (totHdrSize (DataRep mIN_MP_INT_SIZE))
1595 (intOff mIN_MP_INT_SIZE)))
1598 ccall may allocate heap if it is explicitly allowed to (_ccall_gc_)
1599 or if it returns a ForeignObj.
1601 Hmm..the allocation for makeForeignObj# is known (and fixed), so
1602 why do we need to be so indeterminate about it? --SOF
1604 primOpHeapReq (CCallOp _ _ mayGC@True _ _ _) = VariableHeapRequired
1605 primOpHeapReq (CCallOp _ _ mayGC@False _ _ _) = NoHeapRequired
1607 primOpHeapReq MakeForeignObjOp = VariableHeapRequired
1608 primOpHeapReq WriteForeignObjOp = NoHeapRequired
1610 -- this occasionally has to expand the Stable Pointer table
1611 primOpHeapReq MakeStablePtrOp = VariableHeapRequired
1613 -- These four only need heap space with the native code generator
1614 -- ToDo!: parameterize, so we know if native code generation is taking place(JSM)
1616 primOpHeapReq IntegerCmpOp = FixedHeapRequired (intOff (2 * mP_STRUCT_SIZE))
1617 primOpHeapReq Integer2IntOp = FixedHeapRequired (intOff mP_STRUCT_SIZE)
1618 primOpHeapReq Integer2WordOp = FixedHeapRequired (intOff mP_STRUCT_SIZE)
1619 primOpHeapReq FloatEncodeOp = FixedHeapRequired (intOff mP_STRUCT_SIZE)
1620 primOpHeapReq DoubleEncodeOp = FixedHeapRequired (intOff mP_STRUCT_SIZE)
1622 -- a NewSynchVarOp creates a three-word mutuple in the heap.
1623 primOpHeapReq NewSynchVarOp = FixedHeapRequired
1624 (addOff (totHdrSize (MuTupleRep 3)) (intOff 3))
1626 -- Sparking ops no longer allocate any heap; however, _fork_ may
1627 -- require a context switch to clear space in the required thread
1628 -- pool, and that requires liveness information.
1630 primOpHeapReq ParOp = NoHeapRequired
1631 primOpHeapReq ForkOp = VariableHeapRequired
1633 -- A SeqOp requires unknown space to evaluate its argument
1634 primOpHeapReq SeqOp = VariableHeapRequired
1636 -- GranSim sparks are stgMalloced i.e. no heap required
1637 primOpHeapReq ParGlobalOp = NoHeapRequired
1638 primOpHeapReq ParLocalOp = NoHeapRequired
1639 primOpHeapReq ParAtOp = NoHeapRequired
1640 primOpHeapReq ParAtAbsOp = NoHeapRequired
1641 primOpHeapReq ParAtRelOp = NoHeapRequired
1642 primOpHeapReq ParAtForNowOp = NoHeapRequired
1643 -- CopyableOp and NoFolowOp don't require heap; don't rely on default
1644 primOpHeapReq CopyableOp = NoHeapRequired
1645 primOpHeapReq NoFollowOp = NoHeapRequired
1647 primOpHeapReq other_op = NoHeapRequired
1650 The amount of stack required by primops.
1653 data StackRequirement
1655 | FixedStackRequired Int {-AStack-} Int {-BStack-}
1656 | VariableStackRequired
1658 primOpStackRequired SeqOp = FixedStackRequired 0 {-AStack-} 2 {-BStack-}
1659 primOpStackRequired _ = VariableStackRequired
1660 -- ToDo: be more specific for certain primops (currently only used for seq)
1663 Primops which can trigger GC have to be called carefully.
1664 In particular, their arguments are guaranteed to be in registers,
1665 and a liveness mask tells which regs are live.
1668 primOpCanTriggerGC op
1676 case primOpHeapReq op of
1677 VariableHeapRequired -> True
1681 Sometimes we may choose to execute a PrimOp even though it isn't
1682 certain that its result will be required; ie execute them
1683 ``speculatively''. The same thing as ``cheap eagerness.'' Usually
1684 this is OK, because PrimOps are usually cheap, but it isn't OK for
1685 (a)~expensive PrimOps and (b)~PrimOps which can fail.
1687 See also @primOpIsCheap@ (below).
1689 There should be no worries about side effects; that's all taken care
1690 of by data dependencies.
1693 primOpOkForSpeculation :: PrimOp -> Bool
1696 primOpOkForSpeculation IntQuotOp = False -- Divide by zero
1697 primOpOkForSpeculation IntRemOp = False -- Divide by zero
1700 primOpOkForSpeculation IntegerQuotRemOp = False -- Divide by zero
1701 primOpOkForSpeculation IntegerDivModOp = False -- Divide by zero
1703 -- Float. ToDo: tan? tanh?
1704 primOpOkForSpeculation FloatDivOp = False -- Divide by zero
1705 primOpOkForSpeculation FloatLogOp = False -- Log of zero
1706 primOpOkForSpeculation FloatAsinOp = False -- Arg out of domain
1707 primOpOkForSpeculation FloatAcosOp = False -- Arg out of domain
1709 -- Double. ToDo: tan? tanh?
1710 primOpOkForSpeculation DoubleDivOp = False -- Divide by zero
1711 primOpOkForSpeculation DoubleLogOp = False -- Log of zero
1712 primOpOkForSpeculation DoubleAsinOp = False -- Arg out of domain
1713 primOpOkForSpeculation DoubleAcosOp = False -- Arg out of domain
1716 primOpOkForSpeculation (CCallOp _ _ _ _ _ _) = False -- Could be expensive!
1719 primOpOkForSpeculation ErrorIOPrimOp = False -- Could be disastrous!
1722 primOpOkForSpeculation ParOp = False -- Could be expensive!
1723 primOpOkForSpeculation ForkOp = False -- Likewise
1724 primOpOkForSpeculation SeqOp = False -- Likewise
1726 primOpOkForSpeculation ParGlobalOp = False -- Could be expensive!
1727 primOpOkForSpeculation ParLocalOp = False -- Could be expensive!
1728 primOpOkForSpeculation ParAtOp = False -- Could be expensive!
1729 primOpOkForSpeculation ParAtAbsOp = False -- Could be expensive!
1730 primOpOkForSpeculation ParAtRelOp = False -- Could be expensive!
1731 primOpOkForSpeculation ParAtForNowOp = False -- Could be expensive!
1732 primOpOkForSpeculation CopyableOp = False -- only tags closure
1733 primOpOkForSpeculation NoFollowOp = False -- only tags closure
1735 -- The default is "yes it's ok for speculation"
1736 primOpOkForSpeculation other_op = True
1739 @primOpIsCheap@, as used in \tr{SimplUtils.lhs}. For now (HACK
1740 WARNING), we just borrow some other predicates for a
1741 what-should-be-good-enough test.
1744 = primOpOkForSpeculation op && not (primOpCanTriggerGC op)
1747 And some primops have side-effects and so, for example, must not be
1751 fragilePrimOp :: PrimOp -> Bool
1753 fragilePrimOp ParOp = True
1754 fragilePrimOp ForkOp = True
1755 fragilePrimOp SeqOp = True
1756 fragilePrimOp MakeForeignObjOp = True -- SOF
1757 fragilePrimOp WriteForeignObjOp = True -- SOF
1758 fragilePrimOp MakeStablePtrOp = True
1759 fragilePrimOp DeRefStablePtrOp = True -- ??? JSM & ADR
1761 fragilePrimOp ParGlobalOp = True
1762 fragilePrimOp ParLocalOp = True
1763 fragilePrimOp ParAtOp = True
1764 fragilePrimOp ParAtAbsOp = True
1765 fragilePrimOp ParAtRelOp = True
1766 fragilePrimOp ParAtForNowOp = True
1767 fragilePrimOp CopyableOp = True -- Possibly not. ASP
1768 fragilePrimOp NoFollowOp = True -- Possibly not. ASP
1770 fragilePrimOp other = False
1773 Primitive operations that perform calls need wrappers to save any live variables
1774 that are stored in caller-saves registers
1777 primOpNeedsWrapper :: PrimOp -> Bool
1779 primOpNeedsWrapper (CCallOp _ _ _ _ _ _) = True
1781 primOpNeedsWrapper NewArrayOp = True -- ToDo: for nativeGen only!(JSM)
1782 primOpNeedsWrapper (NewByteArrayOp _) = True
1784 primOpNeedsWrapper IntegerAddOp = True
1785 primOpNeedsWrapper IntegerSubOp = True
1786 primOpNeedsWrapper IntegerMulOp = True
1787 primOpNeedsWrapper IntegerQuotRemOp = True
1788 primOpNeedsWrapper IntegerDivModOp = True
1789 primOpNeedsWrapper IntegerNegOp = True
1790 primOpNeedsWrapper IntegerCmpOp = True
1791 primOpNeedsWrapper Integer2IntOp = True
1792 primOpNeedsWrapper Integer2WordOp = True
1793 primOpNeedsWrapper Int2IntegerOp = True
1794 primOpNeedsWrapper Word2IntegerOp = True
1795 primOpNeedsWrapper Addr2IntegerOp = True
1796 primOpNeedsWrapper IntegerToInt64Op = True
1797 primOpNeedsWrapper IntegerToWord64Op = True
1798 primOpNeedsWrapper Word64ToIntegerOp = True
1799 primOpNeedsWrapper Int64ToIntegerOp = True
1801 primOpNeedsWrapper FloatExpOp = True
1802 primOpNeedsWrapper FloatLogOp = True
1803 primOpNeedsWrapper FloatSqrtOp = True
1804 primOpNeedsWrapper FloatSinOp = True
1805 primOpNeedsWrapper FloatCosOp = True
1806 primOpNeedsWrapper FloatTanOp = True
1807 primOpNeedsWrapper FloatAsinOp = True
1808 primOpNeedsWrapper FloatAcosOp = True
1809 primOpNeedsWrapper FloatAtanOp = True
1810 primOpNeedsWrapper FloatSinhOp = True
1811 primOpNeedsWrapper FloatCoshOp = True
1812 primOpNeedsWrapper FloatTanhOp = True
1813 primOpNeedsWrapper FloatPowerOp = True
1814 primOpNeedsWrapper FloatEncodeOp = True
1815 primOpNeedsWrapper FloatDecodeOp = True
1817 primOpNeedsWrapper DoubleExpOp = True
1818 primOpNeedsWrapper DoubleLogOp = True
1819 primOpNeedsWrapper DoubleSqrtOp = True
1820 primOpNeedsWrapper DoubleSinOp = True
1821 primOpNeedsWrapper DoubleCosOp = True
1822 primOpNeedsWrapper DoubleTanOp = True
1823 primOpNeedsWrapper DoubleAsinOp = True
1824 primOpNeedsWrapper DoubleAcosOp = True
1825 primOpNeedsWrapper DoubleAtanOp = True
1826 primOpNeedsWrapper DoubleSinhOp = True
1827 primOpNeedsWrapper DoubleCoshOp = True
1828 primOpNeedsWrapper DoubleTanhOp = True
1829 primOpNeedsWrapper DoublePowerOp = True
1830 primOpNeedsWrapper DoubleEncodeOp = True
1831 primOpNeedsWrapper DoubleDecodeOp = True
1833 primOpNeedsWrapper MakeForeignObjOp = True
1834 primOpNeedsWrapper WriteForeignObjOp = True
1835 primOpNeedsWrapper MakeStablePtrOp = True
1836 primOpNeedsWrapper DeRefStablePtrOp = True
1838 primOpNeedsWrapper TakeMVarOp = True
1839 primOpNeedsWrapper PutMVarOp = True
1840 primOpNeedsWrapper ReadIVarOp = True
1842 primOpNeedsWrapper DelayOp = True
1843 primOpNeedsWrapper WaitReadOp = True
1844 primOpNeedsWrapper WaitWriteOp = True
1846 primOpNeedsWrapper other_op = False
1851 = case (primOpInfo op) of
1853 Monadic str _ -> str
1854 Compare str _ -> str
1855 Coercing str _ _ -> str
1856 PrimResult str _ _ _ _ _ -> str
1857 AlgResult str _ _ _ _ -> str
1860 @primOpType@ duplicates some work of @primOpId@, but since we
1861 grab types pretty often...
1863 primOpType :: PrimOp -> Type
1866 = case (primOpInfo op) of
1867 Dyadic str ty -> dyadic_fun_ty ty
1868 Monadic str ty -> monadic_fun_ty ty
1869 Compare str ty -> compare_fun_ty ty
1870 Coercing str ty1 ty2 -> mkFunTy ty1 ty2
1872 PrimResult str tyvars arg_tys prim_tycon kind res_tys ->
1873 mkForAllTys tyvars (mkFunTys arg_tys (mkTyConApp prim_tycon res_tys))
1875 AlgResult str tyvars arg_tys tycon res_tys ->
1876 mkForAllTys tyvars (mkFunTys arg_tys (mkTyConApp tycon res_tys))
1880 data PrimOpResultInfo
1881 = ReturnsPrim PrimRep
1884 -- ToDo: Deal with specialised PrimOps
1885 -- Will need to return specialised tycon and data constructors
1887 getPrimOpResultInfo :: PrimOp -> PrimOpResultInfo
1889 getPrimOpResultInfo op
1890 = case (primOpInfo op) of
1891 Dyadic _ ty -> ReturnsPrim (typePrimRep ty)
1892 Monadic _ ty -> ReturnsPrim (typePrimRep ty)
1893 Compare _ ty -> ReturnsAlg boolTyCon
1894 Coercing _ _ ty -> ReturnsPrim (typePrimRep ty)
1895 PrimResult _ _ _ _ kind _ -> ReturnsPrim kind
1896 AlgResult _ _ _ tycon _ -> ReturnsAlg tycon
1898 isCompareOp :: PrimOp -> Bool
1901 = case primOpInfo op of
1906 The commutable ops are those for which we will try to move constants
1907 to the right hand side for strength reduction.
1910 commutableOp :: PrimOp -> Bool
1912 commutableOp CharEqOp = True
1913 commutableOp CharNeOp = True
1914 commutableOp IntAddOp = True
1915 commutableOp IntMulOp = True
1916 commutableOp AndOp = True
1917 commutableOp OrOp = True
1918 commutableOp XorOp = True
1919 commutableOp IntEqOp = True
1920 commutableOp IntNeOp = True
1921 commutableOp IntegerAddOp = True
1922 commutableOp IntegerMulOp = True
1923 commutableOp FloatAddOp = True
1924 commutableOp FloatMulOp = True
1925 commutableOp FloatEqOp = True
1926 commutableOp FloatNeOp = True
1927 commutableOp DoubleAddOp = True
1928 commutableOp DoubleMulOp = True
1929 commutableOp DoubleEqOp = True
1930 commutableOp DoubleNeOp = True
1931 commutableOp _ = False
1936 dyadic_fun_ty ty = mkFunTys [ty, ty] ty
1937 monadic_fun_ty ty = mkFunTy ty ty
1938 compare_fun_ty ty = mkFunTys [ty, ty] boolTy
1943 pprPrimOp :: PrimOp -> SDoc
1944 showPrimOp :: PrimOp -> String
1946 showPrimOp op = showSDoc (pprPrimOp op)
1948 pprPrimOp (CCallOp fun is_casm may_gc cconv arg_tys res_ty)
1950 callconv = text "{-" <> pprCallConv cconv <> text "-}"
1953 | is_casm && may_gc = "_casm_GC_ ``"
1954 | is_casm = "casm_ ``"
1955 | may_gc = "_ccall_GC_ "
1956 | otherwise = "_ccall_ "
1959 | is_casm = text "''"
1963 = hsep (map pprParendType (res_ty:arg_tys))
1967 Nothing -> ptext SLIT("<dynamic>")
1971 hcat [ ifPprDebug callconv
1972 , text before , ppr_fun , after, space, brackets pp_tys]
1975 = getPprStyle $ \ sty ->
1976 if codeStyle sty then -- For C just print the primop itself
1978 else if ifaceStyle sty then -- For interfaces Print it qualified with PrelGHC.
1979 ptext SLIT("PrelGHC.") <> ptext str
1980 else -- Unqualified is good enough
1983 str = primOp_str other_op
1986 instance Outputable PrimOp where
1987 ppr op = pprPrimOp op