2 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1995
4 \section[PrimOps]{Primitive operations (machine-level)}
7 #include "HsVersions.h"
11 tagOf_PrimOp, -- ToDo: rm
12 primOpNameInfo, primOpId,
13 typeOfPrimOp, isCompareOp,
14 primOpCanTriggerGC, primOpNeedsWrapper,
15 primOpOkForSpeculation, primOpIsCheap,
21 HeapRequirement(..), primOpHeapReq,
23 -- export for the Native Code Generator
24 -- primOpInfo, not exported
27 pprPrimOp, showPrimOp,
29 -- and to make the interface self-sufficient....
30 PrimKind, HeapOffset, Id, Name, TyCon, UniType, TyVarTemplate
33 import PrelFuns -- help stuff for prelude
34 import PrimKind -- most of it
38 import AbsUniType -- lots of things
39 import CLabelInfo ( identToC )
40 import CgCompInfo ( mIN_MP_INT_SIZE, mP_STRUCT_SIZE )
41 import BasicLit ( BasicLit(..) )
42 import HeapOffs ( addOff, intOff, totHdrSize, HeapOffset )
44 import IdInfo -- plenty of this, too
45 import Maybes ( Maybe(..) )
46 import NameTypes ( mkPreludeCoreName, FullName, ShortName )
48 import PlainCore -- all of it
50 import SMRep ( SMRep(..), SMSpecRepKind(..), SMUpdateKind(..) )
55 #endif {- Data Parallel Haskell -}
58 %************************************************************************
60 \subsection[PrimOps-datatype]{Datatype for @PrimOp@ (an enumeration)}
62 %************************************************************************
64 These are in \tr{state-interface.verb} order.
68 -- dig the FORTRAN/C influence on the names...
72 = CharGtOp | CharGeOp | CharEqOp | CharNeOp | CharLtOp | CharLeOp
73 | IntGtOp | IntGeOp | IntEqOp | IntNeOp | IntLtOp | IntLeOp
74 | WordGtOp | WordGeOp | WordEqOp | WordNeOp | WordLtOp | WordLeOp
75 | AddrGtOp | AddrGeOp | AddrEqOp | AddrNeOp | AddrLtOp | AddrLeOp
76 | FloatGtOp | FloatGeOp | FloatEqOp | FloatNeOp | FloatLtOp | FloatLeOp
77 | DoubleGtOp | DoubleGeOp | DoubleEqOp | DoubleNeOp | DoubleLtOp | DoubleLeOp
83 -- IntAbsOp unused?? ADR
84 | IntAddOp | IntSubOp | IntMulOp | IntQuotOp
85 | IntDivOp | IntRemOp | IntNegOp | IntAbsOp
88 | AndOp | OrOp | NotOp
89 | SllOp | SraOp | SrlOp -- shift {left,right} {arithmetic,logical}
90 | ISllOp | ISraOp | ISrlOp -- equivs on Int#s
91 | Int2WordOp | Word2IntOp -- casts
94 | Int2AddrOp | Addr2IntOp -- casts
96 -- Float#-related ops:
97 | FloatAddOp | FloatSubOp | FloatMulOp | FloatDivOp | FloatNegOp
98 | Float2IntOp | Int2FloatOp
100 | FloatExpOp | FloatLogOp | FloatSqrtOp
101 | FloatSinOp | FloatCosOp | FloatTanOp
102 | FloatAsinOp | FloatAcosOp | FloatAtanOp
103 | FloatSinhOp | FloatCoshOp | FloatTanhOp
104 -- not all machines have these available conveniently:
105 -- | FloatAsinhOp | FloatAcoshOp | FloatAtanhOp
106 | FloatPowerOp -- ** op
108 -- Double#-related ops:
109 | DoubleAddOp | DoubleSubOp | DoubleMulOp | DoubleDivOp | DoubleNegOp
110 | Double2IntOp | Int2DoubleOp
111 | Double2FloatOp | Float2DoubleOp
113 | DoubleExpOp | DoubleLogOp | DoubleSqrtOp
114 | DoubleSinOp | DoubleCosOp | DoubleTanOp
115 | DoubleAsinOp | DoubleAcosOp | DoubleAtanOp
116 | DoubleSinhOp | DoubleCoshOp | DoubleTanhOp
117 -- not all machines have these available conveniently:
118 -- | DoubleAsinhOp | DoubleAcoshOp | DoubleAtanhOp
119 | DoublePowerOp -- ** op
121 -- Integer (and related...) ops:
122 -- slightly weird -- to match GMP package.
123 | IntegerAddOp | IntegerSubOp | IntegerMulOp
124 | IntegerQuotRemOp | IntegerDivModOp | IntegerNegOp
128 | Integer2IntOp | Int2IntegerOp
130 | Addr2IntegerOp -- "Addr" is *always* a literal string
133 | FloatEncodeOp | FloatDecodeOp
134 | DoubleEncodeOp | DoubleDecodeOp
136 -- primitive ops for primitive arrays
139 | NewByteArrayOp PrimKind
142 | SameMutableByteArrayOp
144 | ReadArrayOp | WriteArrayOp | IndexArrayOp -- for arrays of Haskell ptrs
146 | ReadByteArrayOp PrimKind
147 | WriteByteArrayOp PrimKind
148 | IndexByteArrayOp PrimKind
149 | IndexOffAddrOp PrimKind
150 -- PrimKind 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 MallocPtrKind is not included -- the only way of
153 -- creating a MallocPtr is with a ccall or casm.
155 | UnsafeFreezeArrayOp | UnsafeFreezeByteArrayOp
157 | NewSynchVarOp -- for MVars and IVars
158 | TakeMVarOp | PutMVarOp
159 | ReadIVarOp | WriteIVarOp
161 | MakeStablePtrOp | DeRefStablePtrOp
164 A special ``trap-door'' to use in making calls direct to C functions:
166 | CCallOp FAST_STRING -- An "unboxed" ccall# to this named function
167 Bool -- True <=> really a "casm"
168 Bool -- True <=> might invoke Haskell GC
169 [UniType] -- Unboxed argument; the state-token
170 -- argument will have been put *first*
171 UniType -- Return type; one of the "StateAnd<blah>#" types
173 -- (... to be continued ... )
176 The ``type'' of @CCallOp foo [t1, ... tm] r@ is @t1 -> ... tm -> r@.
177 (See @primOpInfo@ for details.)
179 Note: that first arg and part of the result should be the system state
180 token (which we carry around to fool over-zealous optimisers) but
181 which isn't actually passed.
183 For example, we represent
185 ((ccall# foo [StablePtr# a, Int] Float) sp# i#) :: (Float, IoWorld)
191 (CCallOp "foo" [Universe#, StablePtr# a, Int#] FloatPrimAndUniverse False)
192 -- :: Universe# -> StablePtr# a -> Int# -> FloatPrimAndUniverse
196 (CoAlgAlts [ ( FloatPrimAndIoWorld,
198 CoCon (TupleCon 2) [Float, IoWorld] [F# f#, World w#]
204 Nota Bene: there are some people who find the empty list of types in
205 the @CoPrim@ somewhat puzzling and would represent the above by
209 (CCallOp "foo" [alpha1, alpha2, alpha3] alpha4 False)
210 -- :: /\ alpha1, alpha2 alpha3, alpha4.
211 -- alpha1 -> alpha2 -> alpha3 -> alpha4
212 [Universe#, StablePtr# a, Int#, FloatPrimAndIoWorld]
215 (CoAlgAlts [ ( FloatPrimAndIoWorld,
217 CoCon (TupleCon 2) [Float, IoWorld] [F# f#, World w#]
223 But, this is a completely different way of using @CCallOp@. The most
224 major changes required if we switch to this are in @primOpInfo@, and
225 the desugarer. The major difficulty is in moving the HeapRequirement
226 stuff somewhere appropriate. (The advantage is that we could simplify
227 @CCallOp@ and record just the number of arguments with corresponding
228 simplifications in reading pragma unfoldings, the simplifier,
229 instantiation (etc) of core expressions, ... . Maybe we should think
230 about using it this way?? ADR)
233 -- (... continued from above ... )
235 -- one to support "errorIO" (and, thereby, "error")
238 -- Operation to test two closure addresses for equality (yes really!)
239 -- BLAME ALASTAIR REID FOR THIS! THE REST OF US ARE INNOCENT!
240 | ReallyUnsafePtrEqualityOp
242 -- three for parallel stuff
247 -- two for concurrency
252 | ParGlobalOp -- named global par
253 | ParLocalOp -- named local par
254 | ParAtOp -- specifies destination of local par
255 | ParAtForNowOp -- specifies initial destination of global par
256 | CopyableOp -- marks copyable code
257 | NoFollowOp -- marks non-followup expression
261 -- Shadow all the the above primitive OPs for N dimensioned objects.
262 | PodNPrimOp Int PrimOp
264 -- Primitive conversion functions.
266 | Int2PodNOp Int | Char2PodNOp Int | Float2PodNOp Int
267 | Double2PodNOp Int | String2PodNOp Int
269 #endif {-Data Parallel Haskell -}
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 IntDivOp = ILIT( 43)
318 tagOf_PrimOp IntRemOp = ILIT( 44)
319 tagOf_PrimOp IntNegOp = ILIT( 45)
320 tagOf_PrimOp IntAbsOp = ILIT( 46)
321 tagOf_PrimOp AndOp = ILIT( 47)
322 tagOf_PrimOp OrOp = ILIT( 48)
323 tagOf_PrimOp NotOp = ILIT( 49)
324 tagOf_PrimOp SllOp = ILIT( 50)
325 tagOf_PrimOp SraOp = ILIT( 51)
326 tagOf_PrimOp SrlOp = ILIT( 52)
327 tagOf_PrimOp ISllOp = ILIT( 53)
328 tagOf_PrimOp ISraOp = ILIT( 54)
329 tagOf_PrimOp ISrlOp = ILIT( 55)
330 tagOf_PrimOp Int2WordOp = ILIT( 56)
331 tagOf_PrimOp Word2IntOp = ILIT( 57)
332 tagOf_PrimOp Int2AddrOp = ILIT( 58)
333 tagOf_PrimOp Addr2IntOp = ILIT( 59)
334 tagOf_PrimOp FloatAddOp = ILIT( 60)
335 tagOf_PrimOp FloatSubOp = ILIT( 61)
336 tagOf_PrimOp FloatMulOp = ILIT( 62)
337 tagOf_PrimOp FloatDivOp = ILIT( 63)
338 tagOf_PrimOp FloatNegOp = ILIT( 64)
339 tagOf_PrimOp Float2IntOp = ILIT( 65)
340 tagOf_PrimOp Int2FloatOp = ILIT( 66)
341 tagOf_PrimOp FloatExpOp = ILIT( 67)
342 tagOf_PrimOp FloatLogOp = ILIT( 68)
343 tagOf_PrimOp FloatSqrtOp = ILIT( 69)
344 tagOf_PrimOp FloatSinOp = ILIT( 70)
345 tagOf_PrimOp FloatCosOp = ILIT( 71)
346 tagOf_PrimOp FloatTanOp = ILIT( 72)
347 tagOf_PrimOp FloatAsinOp = ILIT( 73)
348 tagOf_PrimOp FloatAcosOp = ILIT( 74)
349 tagOf_PrimOp FloatAtanOp = ILIT( 75)
350 tagOf_PrimOp FloatSinhOp = ILIT( 76)
351 tagOf_PrimOp FloatCoshOp = ILIT( 77)
352 tagOf_PrimOp FloatTanhOp = ILIT( 78)
353 tagOf_PrimOp FloatPowerOp = ILIT( 79)
354 tagOf_PrimOp DoubleAddOp = ILIT( 80)
355 tagOf_PrimOp DoubleSubOp = ILIT( 81)
356 tagOf_PrimOp DoubleMulOp = ILIT( 82)
357 tagOf_PrimOp DoubleDivOp = ILIT( 83)
358 tagOf_PrimOp DoubleNegOp = ILIT( 84)
359 tagOf_PrimOp Double2IntOp = ILIT( 85)
360 tagOf_PrimOp Int2DoubleOp = ILIT( 86)
361 tagOf_PrimOp Double2FloatOp = ILIT( 87)
362 tagOf_PrimOp Float2DoubleOp = ILIT( 88)
363 tagOf_PrimOp DoubleExpOp = ILIT( 89)
364 tagOf_PrimOp DoubleLogOp = ILIT( 90)
365 tagOf_PrimOp DoubleSqrtOp = ILIT( 91)
366 tagOf_PrimOp DoubleSinOp = ILIT( 92)
367 tagOf_PrimOp DoubleCosOp = ILIT( 93)
368 tagOf_PrimOp DoubleTanOp = ILIT( 94)
369 tagOf_PrimOp DoubleAsinOp = ILIT( 95)
370 tagOf_PrimOp DoubleAcosOp = ILIT( 96)
371 tagOf_PrimOp DoubleAtanOp = ILIT( 97)
372 tagOf_PrimOp DoubleSinhOp = ILIT( 98)
373 tagOf_PrimOp DoubleCoshOp = ILIT( 99)
374 tagOf_PrimOp DoubleTanhOp = ILIT(100)
375 tagOf_PrimOp DoublePowerOp = ILIT(101)
376 tagOf_PrimOp IntegerAddOp = ILIT(102)
377 tagOf_PrimOp IntegerSubOp = ILIT(103)
378 tagOf_PrimOp IntegerMulOp = ILIT(104)
379 tagOf_PrimOp IntegerQuotRemOp = ILIT(105)
380 tagOf_PrimOp IntegerDivModOp = ILIT(106)
381 tagOf_PrimOp IntegerNegOp = ILIT(107)
382 tagOf_PrimOp IntegerCmpOp = ILIT(108)
383 tagOf_PrimOp Integer2IntOp = ILIT(109)
384 tagOf_PrimOp Int2IntegerOp = ILIT(110)
385 tagOf_PrimOp Word2IntegerOp = ILIT(111)
386 tagOf_PrimOp Addr2IntegerOp = ILIT(112)
387 tagOf_PrimOp FloatEncodeOp = ILIT(113)
388 tagOf_PrimOp FloatDecodeOp = ILIT(114)
389 tagOf_PrimOp DoubleEncodeOp = ILIT(115)
390 tagOf_PrimOp DoubleDecodeOp = ILIT(116)
391 tagOf_PrimOp NewArrayOp = ILIT(117)
392 tagOf_PrimOp (NewByteArrayOp CharKind) = ILIT(118)
393 tagOf_PrimOp (NewByteArrayOp IntKind) = ILIT(119)
394 tagOf_PrimOp (NewByteArrayOp AddrKind) = ILIT(120)
395 tagOf_PrimOp (NewByteArrayOp FloatKind) = ILIT(121)
396 tagOf_PrimOp (NewByteArrayOp DoubleKind)= ILIT(122)
397 tagOf_PrimOp SameMutableArrayOp = ILIT(123)
398 tagOf_PrimOp SameMutableByteArrayOp = ILIT(124)
399 tagOf_PrimOp ReadArrayOp = ILIT(125)
400 tagOf_PrimOp WriteArrayOp = ILIT(126)
401 tagOf_PrimOp IndexArrayOp = ILIT(127)
402 tagOf_PrimOp (ReadByteArrayOp CharKind) = ILIT(128)
403 tagOf_PrimOp (ReadByteArrayOp IntKind) = ILIT(129)
404 tagOf_PrimOp (ReadByteArrayOp AddrKind) = ILIT(130)
405 tagOf_PrimOp (ReadByteArrayOp FloatKind) = ILIT(131)
406 tagOf_PrimOp (ReadByteArrayOp DoubleKind) = ILIT(132)
407 tagOf_PrimOp (WriteByteArrayOp CharKind) = ILIT(133)
408 tagOf_PrimOp (WriteByteArrayOp IntKind) = ILIT(134)
409 tagOf_PrimOp (WriteByteArrayOp AddrKind) = ILIT(135)
410 tagOf_PrimOp (WriteByteArrayOp FloatKind) = ILIT(136)
411 tagOf_PrimOp (WriteByteArrayOp DoubleKind) = ILIT(137)
412 tagOf_PrimOp (IndexByteArrayOp CharKind) = ILIT(138)
413 tagOf_PrimOp (IndexByteArrayOp IntKind) = ILIT(139)
414 tagOf_PrimOp (IndexByteArrayOp AddrKind) = ILIT(140)
415 tagOf_PrimOp (IndexByteArrayOp FloatKind) = ILIT(141)
416 tagOf_PrimOp (IndexByteArrayOp DoubleKind) = ILIT(142)
417 tagOf_PrimOp (IndexOffAddrOp CharKind) = ILIT(143)
418 tagOf_PrimOp (IndexOffAddrOp IntKind) = ILIT(144)
419 tagOf_PrimOp (IndexOffAddrOp AddrKind) = ILIT(145)
420 tagOf_PrimOp (IndexOffAddrOp FloatKind) = ILIT(146)
421 tagOf_PrimOp (IndexOffAddrOp DoubleKind) = ILIT(147)
422 tagOf_PrimOp UnsafeFreezeArrayOp = ILIT(148)
423 tagOf_PrimOp UnsafeFreezeByteArrayOp = ILIT(149)
424 tagOf_PrimOp NewSynchVarOp = ILIT(150)
425 tagOf_PrimOp TakeMVarOp = ILIT(151)
426 tagOf_PrimOp PutMVarOp = ILIT(152)
427 tagOf_PrimOp ReadIVarOp = ILIT(153)
428 tagOf_PrimOp WriteIVarOp = ILIT(154)
429 tagOf_PrimOp MakeStablePtrOp = ILIT(155)
430 tagOf_PrimOp DeRefStablePtrOp = ILIT(156)
431 tagOf_PrimOp (CCallOp _ _ _ _ _) = ILIT(157)
432 tagOf_PrimOp ErrorIOPrimOp = ILIT(158)
433 tagOf_PrimOp ReallyUnsafePtrEqualityOp = ILIT(159)
434 tagOf_PrimOp SeqOp = ILIT(160)
435 tagOf_PrimOp ParOp = ILIT(161)
436 tagOf_PrimOp ForkOp = ILIT(162)
437 tagOf_PrimOp DelayOp = ILIT(163)
438 tagOf_PrimOp WaitOp = ILIT(164)
441 tagOf_PrimOp ParGlobalOp = ILIT(165)
442 tagOf_PrimOp ParLocalOp = ILIT(166)
443 tagOf_PrimOp ParAtOp = ILIT(167)
444 tagOf_PrimOp ParAtForNowOp = ILIT(168)
445 tagOf_PrimOp CopyableOp = ILIT(169)
446 tagOf_PrimOp NoFollowOp = ILIT(170)
450 tagOf_PrimOp (PodNPrimOp _ _) = panic "ToDo:DPH:tagOf_PrimOp"
451 tagOf_PrimOp (Int2PodNOp _) = panic "ToDo:DPH:tagOf_PrimOp"
452 tagOf_PrimOp (Char2PodNOp _) = panic "ToDo:DPH:tagOf_PrimOp"
453 tagOf_PrimOp (Float2PodNOp _) = panic "ToDo:DPH:tagOf_PrimOp"
454 tagOf_PrimOp (Double2PodNOp _) = panic "ToDo:DPH:tagOf_PrimOp"
455 tagOf_PrimOp (String2PodNOp _) = panic "ToDo:DPH:tagOf_PrimOp"
456 #endif {-Data Parallel Haskell -}
459 tagOf_PrimOp _ = case (panic "tagOf_PrimOp: pattern-match") of { o ->
463 instance Eq PrimOp where
464 op == op2 = tagOf_PrimOp op _EQ_ tagOf_PrimOp op2
467 %************************************************************************
469 \subsection[PrimOps-info]{The essential info about each @PrimOp@}
471 %************************************************************************
473 The @String@ in the @PrimOpInfos@ is the ``base name'' by which the user may
474 refer to the primitive operation. The conventional \tr{#}-for-
475 unboxed ops is added on later.
477 The reason for the funny characters in the names is so we do not
478 interfere with the programmer's Haskell name spaces.
480 We use @PrimKinds@ for the ``type'' information, because they're
481 (slightly) more convenient to use than @TyCons@.
484 = Dyadic FAST_STRING -- string :: T -> T -> T
486 | Monadic FAST_STRING -- string :: T -> T
488 | Compare FAST_STRING -- string :: T -> T -> Bool
490 | Coerce FAST_STRING -- string :: T1 -> T2
494 | PrimResult FAST_STRING
495 [TyVarTemplate] [UniType] TyCon PrimKind [UniType]
496 -- "PrimResult tvs [t1,..,tn] D# kind [s1,..,sm]"
497 -- has type Forall tvs. t1 -> ... -> tn -> (D# s1 ... sm)
498 -- D# is a primitive type constructor.
499 -- (the kind is the same info as D#, in another convenient form)
501 | AlgResult FAST_STRING
502 [TyVarTemplate] [UniType] TyCon [UniType]
503 -- "AlgResult tvs [t1,..,tn] T [s1,..,sm]"
504 -- has type Forall tvs. t1 -> ... -> tn -> (T s1 ... sm)
506 -- ToDo: Specialised calls to PrimOps are prohibited but may be desirable
511 #endif {- Data Parallel Haskell -}
516 one_Integer_ty = [intPrimTy, intPrimTy, byteArrayPrimTy]
518 = [intPrimTy, intPrimTy, byteArrayPrimTy, -- first Integer pieces
519 intPrimTy, intPrimTy, byteArrayPrimTy] -- second '' pieces
520 an_Integer_and_Int_tys
521 = [intPrimTy, intPrimTy, byteArrayPrimTy, -- Integer
524 integerMonadic name = AlgResult name [] one_Integer_ty integerTyCon []
526 integerDyadic name = AlgResult name [] two_Integer_tys integerTyCon []
528 integerDyadic2Results name = AlgResult name [] two_Integer_tys return2GMPsTyCon []
530 integerCompare name = PrimResult name [] two_Integer_tys intPrimTyCon IntKind []
533 @primOpInfo@ gives all essential information (from which everything
534 else, notably a type, can be constructed) for each @PrimOp@.
537 primOpInfo :: PrimOp -> PrimOpInfo
540 There's plenty of this stuff!
542 %************************************************************************
544 \subsubsection[PrimOps-comparison]{PrimOpInfo basic comparison ops}
546 %************************************************************************
549 primOpInfo CharGtOp = Compare SLIT("gtChar#") charPrimTy
550 primOpInfo CharGeOp = Compare SLIT("geChar#") charPrimTy
551 primOpInfo CharEqOp = Compare SLIT("eqChar#") charPrimTy
552 primOpInfo CharNeOp = Compare SLIT("neChar#") charPrimTy
553 primOpInfo CharLtOp = Compare SLIT("ltChar#") charPrimTy
554 primOpInfo CharLeOp = Compare SLIT("leChar#") charPrimTy
556 primOpInfo IntGtOp = Compare SLIT("gtInt#") intPrimTy
557 primOpInfo IntGeOp = Compare SLIT("geInt#") intPrimTy
558 primOpInfo IntEqOp = Compare SLIT("eqInt#") intPrimTy
559 primOpInfo IntNeOp = Compare SLIT("neInt#") intPrimTy
560 primOpInfo IntLtOp = Compare SLIT("ltInt#") intPrimTy
561 primOpInfo IntLeOp = Compare SLIT("leInt#") intPrimTy
563 primOpInfo WordGtOp = Compare SLIT("gtWord#") wordPrimTy
564 primOpInfo WordGeOp = Compare SLIT("geWord#") wordPrimTy
565 primOpInfo WordEqOp = Compare SLIT("eqWord#") wordPrimTy
566 primOpInfo WordNeOp = Compare SLIT("neWord#") wordPrimTy
567 primOpInfo WordLtOp = Compare SLIT("ltWord#") wordPrimTy
568 primOpInfo WordLeOp = Compare SLIT("leWord#") wordPrimTy
570 primOpInfo AddrGtOp = Compare SLIT("gtAddr#") addrPrimTy
571 primOpInfo AddrGeOp = Compare SLIT("geAddr#") addrPrimTy
572 primOpInfo AddrEqOp = Compare SLIT("eqAddr#") addrPrimTy
573 primOpInfo AddrNeOp = Compare SLIT("neAddr#") addrPrimTy
574 primOpInfo AddrLtOp = Compare SLIT("ltAddr#") addrPrimTy
575 primOpInfo AddrLeOp = Compare SLIT("leAddr#") addrPrimTy
577 primOpInfo FloatGtOp = Compare SLIT("gtFloat#") floatPrimTy
578 primOpInfo FloatGeOp = Compare SLIT("geFloat#") floatPrimTy
579 primOpInfo FloatEqOp = Compare SLIT("eqFloat#") floatPrimTy
580 primOpInfo FloatNeOp = Compare SLIT("neFloat#") floatPrimTy
581 primOpInfo FloatLtOp = Compare SLIT("ltFloat#") floatPrimTy
582 primOpInfo FloatLeOp = Compare SLIT("leFloat#") floatPrimTy
584 primOpInfo DoubleGtOp = Compare SLIT("gtDouble#") doublePrimTy
585 primOpInfo DoubleGeOp = Compare SLIT("geDouble#") doublePrimTy
586 primOpInfo DoubleEqOp = Compare SLIT("eqDouble#") doublePrimTy
587 primOpInfo DoubleNeOp = Compare SLIT("neDouble#") doublePrimTy
588 primOpInfo DoubleLtOp = Compare SLIT("ltDouble#") doublePrimTy
589 primOpInfo DoubleLeOp = Compare SLIT("leDouble#") doublePrimTy
592 %************************************************************************
594 \subsubsection[PrimOps-Char]{PrimOpInfo for @Char#@s}
596 %************************************************************************
599 primOpInfo OrdOp = Coerce SLIT("ord#") charPrimTy intPrimTy
600 primOpInfo ChrOp = Coerce SLIT("chr#") intPrimTy charPrimTy
603 %************************************************************************
605 \subsubsection[PrimOps-Int]{PrimOpInfo for @Int#@s}
607 %************************************************************************
610 primOpInfo IntAddOp = Dyadic SLIT("plusInt#") intPrimTy
611 primOpInfo IntSubOp = Dyadic SLIT("minusInt#") intPrimTy
612 primOpInfo IntMulOp = Dyadic SLIT("timesInt#") intPrimTy
613 primOpInfo IntQuotOp = Dyadic SLIT("quotInt#") intPrimTy
614 primOpInfo IntDivOp = Dyadic SLIT("divInt#") intPrimTy
615 primOpInfo IntRemOp = Dyadic SLIT("remInt#") intPrimTy
617 primOpInfo IntNegOp = Monadic SLIT("negateInt#") intPrimTy
620 %************************************************************************
622 \subsubsection[PrimOps-Word]{PrimOpInfo for @Word#@s}
624 %************************************************************************
626 A @Word#@ is an unsigned @Int#@.
629 primOpInfo AndOp = Dyadic SLIT("and#") wordPrimTy
630 primOpInfo OrOp = Dyadic SLIT("or#") wordPrimTy
631 primOpInfo NotOp = Monadic SLIT("not#") wordPrimTy
634 = PrimResult SLIT("shiftL#") [] [wordPrimTy, intPrimTy] wordPrimTyCon WordKind []
636 = PrimResult SLIT("shiftRA#") [] [wordPrimTy, intPrimTy] wordPrimTyCon WordKind []
638 = PrimResult SLIT("shiftRL#") [] [wordPrimTy, intPrimTy] wordPrimTyCon WordKind []
641 = PrimResult SLIT("iShiftL#") [] [intPrimTy, intPrimTy] intPrimTyCon IntKind []
643 = PrimResult SLIT("iShiftRA#") [] [intPrimTy, intPrimTy] intPrimTyCon IntKind []
645 = PrimResult SLIT("iShiftRL#") [] [intPrimTy, intPrimTy] intPrimTyCon IntKind []
647 primOpInfo Int2WordOp = Coerce SLIT("int2Word#") intPrimTy wordPrimTy
648 primOpInfo Word2IntOp = Coerce SLIT("word2Int#") wordPrimTy intPrimTy
651 %************************************************************************
653 \subsubsection[PrimOps-Addr]{PrimOpInfo for @Addr#@s}
655 %************************************************************************
658 primOpInfo Int2AddrOp = Coerce SLIT("int2Addr#") intPrimTy addrPrimTy
659 primOpInfo Addr2IntOp = Coerce SLIT("addr2Int#") addrPrimTy intPrimTy
662 %************************************************************************
664 \subsubsection[PrimOps-Float]{PrimOpInfo for @Float#@s}
666 %************************************************************************
668 @encodeFloat#@ and @decodeFloat#@ are given w/ Integer-stuff (it's
672 primOpInfo FloatAddOp = Dyadic SLIT("plusFloat#") floatPrimTy
673 primOpInfo FloatSubOp = Dyadic SLIT("minusFloat#") floatPrimTy
674 primOpInfo FloatMulOp = Dyadic SLIT("timesFloat#") floatPrimTy
675 primOpInfo FloatDivOp = Dyadic SLIT("divideFloat#") floatPrimTy
676 primOpInfo FloatNegOp = Monadic SLIT("negateFloat#") floatPrimTy
678 primOpInfo Float2IntOp = Coerce SLIT("float2Int#") floatPrimTy intPrimTy
679 primOpInfo Int2FloatOp = Coerce SLIT("int2Float#") intPrimTy floatPrimTy
681 primOpInfo FloatExpOp = Monadic SLIT("expFloat#") floatPrimTy
682 primOpInfo FloatLogOp = Monadic SLIT("logFloat#") floatPrimTy
683 primOpInfo FloatSqrtOp = Monadic SLIT("sqrtFloat#") floatPrimTy
684 primOpInfo FloatSinOp = Monadic SLIT("sinFloat#") floatPrimTy
685 primOpInfo FloatCosOp = Monadic SLIT("cosFloat#") floatPrimTy
686 primOpInfo FloatTanOp = Monadic SLIT("tanFloat#") floatPrimTy
687 primOpInfo FloatAsinOp = Monadic SLIT("asinFloat#") floatPrimTy
688 primOpInfo FloatAcosOp = Monadic SLIT("acosFloat#") floatPrimTy
689 primOpInfo FloatAtanOp = Monadic SLIT("atanFloat#") floatPrimTy
690 primOpInfo FloatSinhOp = Monadic SLIT("sinhFloat#") floatPrimTy
691 primOpInfo FloatCoshOp = Monadic SLIT("coshFloat#") floatPrimTy
692 primOpInfo FloatTanhOp = Monadic SLIT("tanhFloat#") floatPrimTy
693 primOpInfo FloatPowerOp = Dyadic SLIT("powerFloat#") floatPrimTy
696 %************************************************************************
698 \subsubsection[PrimOps-Double]{PrimOpInfo for @Double#@s}
700 %************************************************************************
702 @encodeDouble#@ and @decodeDouble#@ are given w/ Integer-stuff (it's
706 primOpInfo DoubleAddOp = Dyadic SLIT("plusDouble#") doublePrimTy
707 primOpInfo DoubleSubOp = Dyadic SLIT("minusDouble#") doublePrimTy
708 primOpInfo DoubleMulOp = Dyadic SLIT("timesDouble#") doublePrimTy
709 primOpInfo DoubleDivOp = Dyadic SLIT("divideDouble#") doublePrimTy
710 primOpInfo DoubleNegOp = Monadic SLIT("negateDouble#") doublePrimTy
712 primOpInfo Double2IntOp = Coerce SLIT("double2Int#") doublePrimTy intPrimTy
713 primOpInfo Int2DoubleOp = Coerce SLIT("int2Double#") intPrimTy doublePrimTy
715 primOpInfo Double2FloatOp = Coerce SLIT("double2Float#") doublePrimTy floatPrimTy
716 primOpInfo Float2DoubleOp = Coerce SLIT("float2Double#") floatPrimTy doublePrimTy
718 primOpInfo DoubleExpOp = Monadic SLIT("expDouble#") doublePrimTy
719 primOpInfo DoubleLogOp = Monadic SLIT("logDouble#") doublePrimTy
720 primOpInfo DoubleSqrtOp = Monadic SLIT("sqrtDouble#") doublePrimTy
721 primOpInfo DoubleSinOp = Monadic SLIT("sinDouble#") doublePrimTy
722 primOpInfo DoubleCosOp = Monadic SLIT("cosDouble#") doublePrimTy
723 primOpInfo DoubleTanOp = Monadic SLIT("tanDouble#") doublePrimTy
724 primOpInfo DoubleAsinOp = Monadic SLIT("asinDouble#") doublePrimTy
725 primOpInfo DoubleAcosOp = Monadic SLIT("acosDouble#") doublePrimTy
726 primOpInfo DoubleAtanOp = Monadic SLIT("atanDouble#") doublePrimTy
727 primOpInfo DoubleSinhOp = Monadic SLIT("sinhDouble#") doublePrimTy
728 primOpInfo DoubleCoshOp = Monadic SLIT("coshDouble#") doublePrimTy
729 primOpInfo DoubleTanhOp = Monadic SLIT("tanhDouble#") doublePrimTy
730 primOpInfo DoublePowerOp= Dyadic SLIT("powerDouble#") doublePrimTy
733 %************************************************************************
735 \subsubsection[PrimOps-Integer]{PrimOpInfo for @Integer@ (and related!)}
737 %************************************************************************
740 primOpInfo IntegerNegOp = integerMonadic SLIT("negateInteger#")
742 primOpInfo IntegerAddOp = integerDyadic SLIT("plusInteger#")
743 primOpInfo IntegerSubOp = integerDyadic SLIT("minusInteger#")
744 primOpInfo IntegerMulOp = integerDyadic SLIT("timesInteger#")
746 primOpInfo IntegerCmpOp = integerCompare SLIT("cmpInteger#")
748 primOpInfo IntegerQuotRemOp = integerDyadic2Results SLIT("quotRemInteger#")
749 primOpInfo IntegerDivModOp = integerDyadic2Results SLIT("divModInteger#")
751 primOpInfo Integer2IntOp
752 = PrimResult SLIT("integer2Int#") [] one_Integer_ty intPrimTyCon IntKind []
754 primOpInfo Int2IntegerOp
755 = AlgResult SLIT("int2Integer#") [] [intPrimTy] integerTyCon []
757 primOpInfo Word2IntegerOp
758 = AlgResult SLIT("word2Integer#") [] [wordPrimTy] integerTyCon []
760 primOpInfo Addr2IntegerOp
761 = AlgResult SLIT("addr2Integer#") [] [addrPrimTy] integerTyCon []
764 Encoding and decoding of floating-point numbers is sorta
768 primOpInfo FloatEncodeOp
769 = PrimResult SLIT("encodeFloat#") [] an_Integer_and_Int_tys
770 floatPrimTyCon FloatKind []
772 primOpInfo DoubleEncodeOp
773 = PrimResult SLIT("encodeDouble#") [] an_Integer_and_Int_tys
774 doublePrimTyCon DoubleKind []
776 primOpInfo FloatDecodeOp
777 = AlgResult SLIT("decodeFloat#") [] [floatPrimTy] returnIntAndGMPTyCon []
779 primOpInfo DoubleDecodeOp
780 = AlgResult SLIT("decodeDouble#") [] [doublePrimTy] returnIntAndGMPTyCon []
783 %************************************************************************
785 \subsubsection[PrimOps-Arrays]{PrimOpInfo for primitive arrays}
787 %************************************************************************
790 primOpInfo NewArrayOp
792 elt = alpha; elt_tv = alpha_tv; s = beta; s_tv = beta_tv
794 AlgResult SLIT("newArray#") [s_tv, elt_tv] [intPrimTy, elt, mkStatePrimTy s]
795 stateAndMutableArrayPrimTyCon [s, elt]
797 primOpInfo (NewByteArrayOp kind)
799 s = alpha; s_tv = alpha_tv
801 (str, _, prim_tycon) = getKindInfo kind
803 op_str = _PK_ ("new" ++ str ++ "Array#")
805 AlgResult op_str [s_tv]
806 [intPrimTy, mkStatePrimTy s]
807 stateAndMutableByteArrayPrimTyCon [s]
809 ---------------------------------------------------------------------------
811 primOpInfo SameMutableArrayOp
813 elt = alpha; elt_tv = alpha_tv; s = beta; s_tv = beta_tv;
814 mut_arr_ty = mkMutableArrayPrimTy s elt
816 AlgResult SLIT("sameMutableArray#") [s_tv, elt_tv] [mut_arr_ty, mut_arr_ty]
819 primOpInfo SameMutableByteArrayOp
821 s = alpha; s_tv = alpha_tv;
822 mut_arr_ty = mkMutableByteArrayPrimTy s
824 AlgResult SLIT("sameMutableByteArray#") [s_tv] [mut_arr_ty, mut_arr_ty]
827 ---------------------------------------------------------------------------
828 -- Primitive arrays of Haskell pointers:
830 primOpInfo ReadArrayOp
832 elt = alpha; elt_tv = alpha_tv; s = beta; s_tv = beta_tv
834 AlgResult SLIT("readArray#") [s_tv, elt_tv]
835 [mkMutableArrayPrimTy s elt, intPrimTy, mkStatePrimTy s]
836 stateAndPtrPrimTyCon [s, elt]
839 primOpInfo WriteArrayOp
841 elt = alpha; elt_tv = alpha_tv; s = beta; s_tv = beta_tv
843 PrimResult SLIT("writeArray#") [s_tv, elt_tv]
844 [mkMutableArrayPrimTy s elt, intPrimTy, elt, mkStatePrimTy s]
845 statePrimTyCon VoidKind [s]
847 primOpInfo IndexArrayOp
848 = let { elt = alpha; elt_tv = alpha_tv } in
849 AlgResult SLIT("indexArray#") [elt_tv] [mkArrayPrimTy elt, intPrimTy]
852 ---------------------------------------------------------------------------
853 -- Primitive arrays full of unboxed bytes:
855 primOpInfo (ReadByteArrayOp kind)
857 s = alpha; s_tv = alpha_tv
859 (str, _, prim_tycon) = getKindInfo kind
861 op_str = _PK_ ("read" ++ str ++ "Array#")
862 relevant_tycon = assoc "primOpInfo" tbl kind
864 AlgResult op_str [s_tv]
865 [mkMutableByteArrayPrimTy s, intPrimTy, mkStatePrimTy s]
868 tbl = [ (CharKind, stateAndCharPrimTyCon),
869 (IntKind, stateAndIntPrimTyCon),
870 (AddrKind, stateAndAddrPrimTyCon),
871 (FloatKind, stateAndFloatPrimTyCon),
872 (DoubleKind, stateAndDoublePrimTyCon) ]
874 -- How come there's no Word byte arrays? ADR
876 primOpInfo (WriteByteArrayOp kind)
878 s = alpha; s_tv = alpha_tv
880 (str, prim_ty, _) = getKindInfo kind
881 op_str = _PK_ ("write" ++ str ++ "Array#")
883 -- NB: *Prim*Result --
884 PrimResult op_str [s_tv]
885 [mkMutableByteArrayPrimTy s, intPrimTy, prim_ty, mkStatePrimTy s]
886 statePrimTyCon VoidKind [s]
888 primOpInfo (IndexByteArrayOp kind)
890 (str, _, prim_tycon) = getKindInfo kind
891 op_str = _PK_ ("index" ++ str ++ "Array#")
893 -- NB: *Prim*Result --
894 PrimResult op_str [] [byteArrayPrimTy, intPrimTy] prim_tycon kind []
896 primOpInfo (IndexOffAddrOp kind)
898 (str, _, prim_tycon) = getKindInfo kind
899 op_str = _PK_ ("index" ++ str ++ "OffAddr#")
901 PrimResult op_str [] [addrPrimTy, intPrimTy] prim_tycon kind []
903 ---------------------------------------------------------------------------
904 primOpInfo UnsafeFreezeArrayOp
906 elt = alpha; elt_tv = alpha_tv; s = beta; s_tv = beta_tv
908 AlgResult SLIT("unsafeFreezeArray#") [s_tv, elt_tv]
909 [mkMutableArrayPrimTy s elt, mkStatePrimTy s]
910 stateAndArrayPrimTyCon [s, elt]
912 primOpInfo UnsafeFreezeByteArrayOp
913 = let { s = alpha; s_tv = alpha_tv } in
914 AlgResult SLIT("unsafeFreezeByteArray#") [s_tv]
915 [mkMutableByteArrayPrimTy s, mkStatePrimTy s]
916 stateAndByteArrayPrimTyCon [s]
919 %************************************************************************
921 \subsubsection[PrimOps-SynchVars]{PrimOpInfo for synchronizing Variables}
923 %************************************************************************
926 primOpInfo NewSynchVarOp
928 elt = alpha; elt_tv = alpha_tv; s = beta; s_tv = beta_tv
930 AlgResult SLIT("newSynchVar#") [s_tv, elt_tv] [mkStatePrimTy s]
931 stateAndSynchVarPrimTyCon [s, elt]
933 primOpInfo TakeMVarOp
935 elt = alpha; elt_tv = alpha_tv; s = beta; s_tv = beta_tv
937 AlgResult SLIT("takeMVar#") [s_tv, elt_tv]
938 [mkSynchVarPrimTy s elt, mkStatePrimTy s]
939 stateAndPtrPrimTyCon [s, elt]
943 elt = alpha; elt_tv = alpha_tv; s = beta; s_tv = beta_tv
945 AlgResult SLIT("putMVar#") [s_tv, elt_tv]
946 [mkSynchVarPrimTy s elt, elt, mkStatePrimTy s]
949 primOpInfo ReadIVarOp
951 elt = alpha; elt_tv = alpha_tv; s = beta; s_tv = beta_tv
953 AlgResult SLIT("readIVar#") [s_tv, elt_tv]
954 [mkSynchVarPrimTy s elt, mkStatePrimTy s]
955 stateAndPtrPrimTyCon [s, elt]
957 primOpInfo WriteIVarOp
959 elt = alpha; elt_tv = alpha_tv; s = beta; s_tv = beta_tv
961 AlgResult SLIT("writeIVar#") [s_tv, elt_tv]
962 [mkSynchVarPrimTy s elt, elt, mkStatePrimTy s]
967 %************************************************************************
969 \subsubsection[PrimOps-Wait]{PrimOpInfo for delay/wait operations}
971 %************************************************************************
977 s = alpha; s_tv = alpha_tv
979 PrimResult SLIT("delay#") [s_tv]
980 [intPrimTy, mkStatePrimTy s]
981 statePrimTyCon VoidKind [s]
985 s = alpha; s_tv = alpha_tv
987 PrimResult SLIT("wait#") [s_tv]
988 [intPrimTy, mkStatePrimTy s]
989 statePrimTyCon VoidKind [s]
994 %************************************************************************
996 \subsubsection[PrimOps-stable-pointers]{PrimOpInfo for ``stable pointers''}
998 %************************************************************************
1000 A {\em stable pointer} is an index into a table of pointers into the
1001 heap. Since the garbage collector is told about stable pointers, it
1002 is safe to pass a stable pointer to external systems such as C
1005 Here's what the operations and types are supposed to be (from
1006 state-interface document).
1009 makeStablePointer# :: a -> State# _RealWorld -> StateAndStablePtr# _RealWorld a
1010 freeStablePointer# :: StablePtr# a -> State# _RealWorld -> State# _RealWorld
1011 deRefStablePointer# :: StablePtr# a -> State# _RealWorld -> StateAndPtr _RealWorld a
1014 It may seem a bit surprising that @makeStablePtr#@ is a @PrimIO@
1015 operation since it doesn't (directly) involve IO operations. The
1016 reason is that if some optimisation pass decided to duplicate calls to
1017 @makeStablePtr#@ and we only pass one of the stable pointers over, a
1018 massive space leak can result. Putting it into the PrimIO monad
1019 prevents this. (Another reason for putting them in a monad is to
1020 ensure correct sequencing wrt the side-effecting @freeStablePointer#@
1023 Note that we can implement @freeStablePointer#@ using @_ccall_@ (and,
1024 besides, it's not likely to be used from Haskell) so it's not a
1027 Question: Why @_RealWorld@ - won't any instance of @_ST@ do the job? [ADR]
1030 primOpInfo MakeStablePtrOp
1031 = AlgResult SLIT("makeStablePtr#") [alpha_tv]
1032 [alpha, realWorldStatePrimTy]
1033 stateAndStablePtrPrimTyCon [realWorldTy, alpha]
1035 primOpInfo DeRefStablePtrOp
1036 = AlgResult SLIT("deRefStablePtr#") [alpha_tv]
1037 [mkStablePtrPrimTy alpha, realWorldStatePrimTy]
1038 stateAndPtrPrimTyCon [realWorldTy, alpha]
1041 %************************************************************************
1043 \subsubsection[PrimOps-unsafePointerEquality]{PrimOpInfo for Pointer Equality}
1045 %************************************************************************
1047 [Alastair Reid is to blame for this!]
1049 These days, (Glasgow) Haskell seems to have a bit of everything from
1050 other languages: strict operations, mutable variables, sequencing,
1051 pointers, etc. About the only thing left is LISP's ability to test
1052 for pointer equality. So, let's add it in!
1055 reallyUnsafePtrEquality :: a -> a -> Int#
1058 which tests any two closures (of the same type) to see if they're the
1059 same. (Returns $0$ for @False@, $\neq 0$ for @True@ - to avoid
1060 difficulties of trying to box up the result.)
1062 NB This is {\em really unsafe\/} because even something as trivial as
1063 a garbage collection might change the answer by removing indirections.
1064 Still, no-one's forcing you to use it. If you're worried about little
1065 things like loss of referential transparency, you might like to wrap
1066 it all up in a monad-like thing as John O'Donnell and John Hughes did
1067 for non-determinism (1989 (Fraserburgh) Glasgow FP Workshop
1070 I'm thinking of using it to speed up a critical equality test in some
1071 graphics stuff in a context where the possibility of saying that
1072 denotationally equal things aren't isn't a problem (as long as it
1073 doesn't happen too often.) ADR
1075 To Will: Jim said this was already in, but I can't see it so I'm
1076 adding it. Up to you whether you add it. (Note that this could have
1077 been readily implemented using a @veryDangerousCCall@ before they were
1081 primOpInfo ReallyUnsafePtrEqualityOp
1082 = PrimResult SLIT("reallyUnsafePtrEquality#") [alpha_tv]
1083 [alpha, alpha] intPrimTyCon IntKind []
1086 %************************************************************************
1088 \subsubsection[PrimOps-parallel]{PrimOpInfo for parallelism op(s)}
1090 %************************************************************************
1093 primOpInfo SeqOp -- seq# :: a -> Int#
1094 = PrimResult SLIT("seq#") [alpha_tv] [alpha] intPrimTyCon IntKind []
1096 primOpInfo ParOp -- par# :: a -> Int#
1097 = PrimResult SLIT("par#") [alpha_tv] [alpha] intPrimTyCon IntKind []
1099 primOpInfo ForkOp -- fork# :: a -> Int#
1100 = PrimResult SLIT("fork#") [alpha_tv] [alpha] intPrimTyCon IntKind []
1107 primOpInfo ParGlobalOp -- parGlobal# :: Int -> a -> b -> b
1108 = AlgResult SLIT("parGlobal#") [alpha_tv,beta_tv] [intPrimTy,alpha,beta] liftTyCon [beta]
1110 primOpInfo ParLocalOp -- parLocal# :: Int -> a -> b -> b
1111 = AlgResult SLIT("parLocal#") [alpha_tv,beta_tv] [intPrimTy,alpha,beta] liftTyCon [beta]
1113 primOpInfo ParAtOp -- parAt# :: Int -> a -> b -> c -> c
1114 = AlgResult SLIT("parAt#") [alpha_tv,beta_tv,gamma_tv] [intPrimTy,alpha,beta,gamma] liftTyCon [gamma]
1116 primOpInfo ParAtForNowOp -- parAtForNow# :: Int -> a -> b -> c -> c
1117 = AlgResult SLIT("parAtForNow#") [alpha_tv,beta_tv,gamma_tv] [intPrimTy,alpha,beta,gamma] liftTyCon [gamma]
1119 primOpInfo CopyableOp -- copyable# :: a -> a
1120 = AlgResult SLIT("copyable#") [alpha_tv] [alpha] liftTyCon [alpha]
1122 primOpInfo NoFollowOp -- noFollow# :: a -> a
1123 = AlgResult SLIT("noFollow#") [alpha_tv] [alpha] liftTyCon [alpha]
1128 %************************************************************************
1130 \subsubsection[PrimOps-errorIO]{PrimOpInfo for @errorIO#@}
1132 %************************************************************************
1135 primOpInfo ErrorIOPrimOp -- errorIO# :: PrimIO () -> State# RealWorld#
1136 = PrimResult SLIT("errorIO#") []
1138 statePrimTyCon VoidKind [realWorldTy]
1141 %************************************************************************
1143 \subsubsection[PrimOps-IO-etc]{PrimOpInfo for C calls, and I/O-ish things}
1145 %************************************************************************
1148 primOpInfo (CCallOp _ _ _ arg_tys result_ty)
1149 = AlgResult SLIT("ccall#") [] arg_tys result_tycon tys_applied
1151 (result_tycon, tys_applied, _) = getUniDataTyCon result_ty
1154 %************************************************************************
1156 \subsubsection[PrimOps-DPH]{PrimOpInfo for Data Parallel Haskell}
1158 %************************************************************************
1162 -- ToDo:DPH: various things need doing here
1164 primOpInfo (Int2PodNOp d) = Coerce ("int2Pod" ++ show d)
1166 (PodNKind d IntKind)
1168 primOpInfo (Char2PodNOp d) = Coerce ("char2Pod" ++ show d)
1170 (PodNKind d CharKind)
1172 primOpInfo (Float2PodNOp d) = Coerce ("float2Pod" ++ show d)
1174 (PodNKind d FloatKind)
1176 primOpInfo (Double2PodNOp d) = Coerce ("double2Pod" ++ show d)
1178 (PodNKind d DoubleKind)
1181 primOpInfo (Integer2PodNOp d) = Coerce ("integer2Pod" ++ show d)
1183 (PodNKind d IntegerKind)
1186 primOpInfo (String2PodNOp d) = Coerce ("string2Pod" ++ show d)
1188 (PodNKind d LitStringKind)
1190 primOpInfo (PodNPrimOp d p) = PodNInfo d (primOpInfo p)
1191 #endif {- Data Parallel Haskell -}
1194 %************************************************************************
1196 \subsection[PrimOps-utils]{Utilities for @PrimitiveOps@}
1198 %************************************************************************
1200 The primitive-array-creation @PrimOps@ and {\em most} of those to do
1201 with @Integers@ can trigger GC. Here we describe the heap requirements
1202 of the various @PrimOps@. For most, no heap is required. For a few,
1203 a fixed amount of heap is required, and the needs of the @PrimOp@ can
1204 be combined with the rest of the heap usage in the basic block. For an
1205 unfortunate few, some unknown amount of heap is required (these are the
1206 ops which can trigger GC).
1209 data HeapRequirement
1211 | FixedHeapRequired HeapOffset
1212 | VariableHeapRequired
1214 primOpHeapReq :: PrimOp -> HeapRequirement
1216 primOpHeapReq NewArrayOp = VariableHeapRequired
1217 primOpHeapReq (NewByteArrayOp _)= VariableHeapRequired
1219 primOpHeapReq IntegerAddOp = VariableHeapRequired
1220 primOpHeapReq IntegerSubOp = VariableHeapRequired
1221 primOpHeapReq IntegerMulOp = VariableHeapRequired
1222 primOpHeapReq IntegerQuotRemOp = VariableHeapRequired
1223 primOpHeapReq IntegerDivModOp = VariableHeapRequired
1224 primOpHeapReq IntegerNegOp = VariableHeapRequired
1225 primOpHeapReq Int2IntegerOp = FixedHeapRequired
1226 (addOff (totHdrSize (DataRep mIN_MP_INT_SIZE))
1227 (intOff mIN_MP_INT_SIZE))
1228 primOpHeapReq Word2IntegerOp = FixedHeapRequired
1229 (addOff (totHdrSize (DataRep mIN_MP_INT_SIZE))
1230 (intOff mIN_MP_INT_SIZE))
1231 primOpHeapReq Addr2IntegerOp = VariableHeapRequired
1232 primOpHeapReq FloatDecodeOp = FixedHeapRequired
1233 (addOff (intOff (getKindSize IntKind + mP_STRUCT_SIZE))
1234 (addOff (totHdrSize (DataRep mIN_MP_INT_SIZE))
1235 (intOff mIN_MP_INT_SIZE)))
1236 primOpHeapReq DoubleDecodeOp = FixedHeapRequired
1237 (addOff (intOff (getKindSize IntKind + mP_STRUCT_SIZE))
1238 (addOff (totHdrSize (DataRep mIN_MP_INT_SIZE))
1239 (intOff mIN_MP_INT_SIZE)))
1241 -- ccall may allocate heap if it is explicitly allowed to (_ccall_gc_)
1242 -- or if it returns a MallocPtr.
1244 primOpHeapReq (CCallOp _ _ mayGC@True _ _) = VariableHeapRequired
1245 primOpHeapReq (CCallOp _ _ mayGC@False _ return_ty)
1246 = if returnsMallocPtr
1247 then VariableHeapRequired
1251 = case (getUniDataTyCon_maybe return_ty) of
1253 Just (tycon, _, _) -> tycon == stateAndMallocPtrPrimTyCon
1255 -- this occasionally has to expand the Stable Pointer table
1256 primOpHeapReq MakeStablePtrOp = VariableHeapRequired
1258 -- These four only need heap space with the native code generator
1259 -- ToDo!: parameterize, so we know if native code generation is taking place(JSM)
1261 primOpHeapReq IntegerCmpOp = FixedHeapRequired (intOff (2 * mP_STRUCT_SIZE))
1262 primOpHeapReq Integer2IntOp = FixedHeapRequired (intOff mP_STRUCT_SIZE)
1263 primOpHeapReq FloatEncodeOp = FixedHeapRequired (intOff mP_STRUCT_SIZE)
1264 primOpHeapReq DoubleEncodeOp = FixedHeapRequired (intOff mP_STRUCT_SIZE)
1266 -- a NewSynchVarOp creates a three-word mutuple in the heap.
1267 primOpHeapReq NewSynchVarOp = FixedHeapRequired
1268 (addOff (totHdrSize (MuTupleRep 3)) (intOff 3))
1270 -- Sparking ops no longer allocate any heap; however, _fork_ may
1271 -- require a context switch to clear space in the required thread
1272 -- pool, and that requires liveness information.
1274 primOpHeapReq ParOp = NoHeapRequired
1275 primOpHeapReq ForkOp = VariableHeapRequired
1277 -- A SeqOp requires unknown space to evaluate its argument
1278 primOpHeapReq SeqOp = VariableHeapRequired
1282 -- a ParGlobalOp creates a single 4-tuple in the heap. ToDo: verify this!
1283 primOpHeapReq ParGlobalOp = trace "primOpHeapReq:ParGlobalOp:verify!" (
1285 (addOff (totHdrSize (MuTupleRep 4)) (intOff 4))
1288 -- a ParLocalOp creates a single 4-tuple in the heap. ToDo: verify this!
1289 primOpHeapReq ParLocalOp = trace "primOpHeapReq:ParLocalOp:verify!" (
1291 (addOff (totHdrSize (MuTupleRep 4)) (intOff 4))
1294 -- ToDo: parAt, parAtForNow, copyable, noFollow !! (HWL)
1297 primOpHeapReq other_op = NoHeapRequired
1300 Primops which can trigger GC have to be called carefully.
1301 In particular, their arguments are guaranteed to be in registers,
1302 and a liveness mask tells which regs are live.
1305 primOpCanTriggerGC op =
1312 case primOpHeapReq op of
1313 VariableHeapRequired -> True
1318 Sometimes we may choose to execute a PrimOp even though it isn't
1319 certain that its result will be required; ie execute them
1320 ``speculatively''. The same thing as ``cheap eagerness.'' Usually
1321 this is OK, because PrimOps are usually cheap, but it isn't OK for
1322 (a)~expensive PrimOps and (b)~PrimOps which can fail.
1324 See also @primOpIsCheap@ (below).
1326 There should be no worries about side effects; that's all taken care
1327 of by data dependencies.
1330 primOpOkForSpeculation :: PrimOp -> Bool
1333 primOpOkForSpeculation IntDivOp = False -- Divide by zero
1334 primOpOkForSpeculation IntQuotOp = False -- Divide by zero
1335 primOpOkForSpeculation IntRemOp = False -- Divide by zero
1338 primOpOkForSpeculation IntegerQuotRemOp = False -- Divide by zero
1339 primOpOkForSpeculation IntegerDivModOp = False -- Divide by zero
1341 -- Float. ToDo: tan? tanh?
1342 primOpOkForSpeculation FloatDivOp = False -- Divide by zero
1343 primOpOkForSpeculation FloatLogOp = False -- Log of zero
1344 primOpOkForSpeculation FloatAsinOp = False -- Arg out of domain
1345 primOpOkForSpeculation FloatAcosOp = False -- Arg out of domain
1347 -- Double. ToDo: tan? tanh?
1348 primOpOkForSpeculation DoubleDivOp = False -- Divide by zero
1349 primOpOkForSpeculation DoubleLogOp = False -- Log of zero
1350 primOpOkForSpeculation DoubleAsinOp = False -- Arg out of domain
1351 primOpOkForSpeculation DoubleAcosOp = False -- Arg out of domain
1354 primOpOkForSpeculation (CCallOp _ _ _ _ _)= False -- Could be expensive!
1357 primOpOkForSpeculation ErrorIOPrimOp = False -- Could be disastrous!
1360 primOpOkForSpeculation ParOp = False -- Could be expensive!
1361 primOpOkForSpeculation ForkOp = False -- Likewise
1362 primOpOkForSpeculation SeqOp = False -- Likewise
1365 primOpOkForSpeculation ParGlobalOp = False -- Could be expensive!
1366 primOpOkForSpeculation ParLocalOp = False -- Could be expensive!
1369 -- The default is "yes it's ok for speculation"
1370 primOpOkForSpeculation other_op = True
1373 @primOpIsCheap@, as used in \tr{SimplUtils.lhs}. For now (HACK
1374 WARNING), we just borrow some other predicates for a
1375 what-should-be-good-enough test.
1378 = primOpOkForSpeculation op && not (primOpCanTriggerGC op)
1381 And some primops have side-effects and so, for example, must not be
1385 fragilePrimOp :: PrimOp -> Bool
1387 fragilePrimOp ParOp = True
1388 fragilePrimOp ForkOp = True
1389 fragilePrimOp SeqOp = True
1390 fragilePrimOp MakeStablePtrOp = True
1391 fragilePrimOp DeRefStablePtrOp = True -- ??? JSM & ADR
1394 fragilePrimOp ParGlobalOp = True
1395 fragilePrimOp ParLocalOp = True
1396 fragilePrimOp CopyableOp = trace "fragilePrimOp:CopyableOp" True -- Possibly not. ASP
1397 fragilePrimOp NoFollowOp = trace "fragilePrimOp:NoFollowOp" True -- Possibly not. ASP
1400 fragilePrimOp other = False
1403 Primitive operations that perform calls need wrappers to save any live variables
1404 that are stored in caller-saves registers
1407 primOpNeedsWrapper :: PrimOp -> Bool
1409 primOpNeedsWrapper (CCallOp _ _ _ _ _) = True
1411 primOpNeedsWrapper IntDivOp = True
1413 primOpNeedsWrapper NewArrayOp = True -- ToDo: for nativeGen only!(JSM)
1414 primOpNeedsWrapper (NewByteArrayOp _) = True
1416 primOpNeedsWrapper IntegerAddOp = True
1417 primOpNeedsWrapper IntegerSubOp = True
1418 primOpNeedsWrapper IntegerMulOp = True
1419 primOpNeedsWrapper IntegerQuotRemOp = True
1420 primOpNeedsWrapper IntegerDivModOp = True
1421 primOpNeedsWrapper IntegerNegOp = True
1422 primOpNeedsWrapper IntegerCmpOp = True
1423 primOpNeedsWrapper Integer2IntOp = True
1424 primOpNeedsWrapper Int2IntegerOp = True
1425 primOpNeedsWrapper Word2IntegerOp = True
1426 primOpNeedsWrapper Addr2IntegerOp = True
1428 primOpNeedsWrapper FloatExpOp = True
1429 primOpNeedsWrapper FloatLogOp = True
1430 primOpNeedsWrapper FloatSqrtOp = True
1431 primOpNeedsWrapper FloatSinOp = True
1432 primOpNeedsWrapper FloatCosOp = True
1433 primOpNeedsWrapper FloatTanOp = True
1434 primOpNeedsWrapper FloatAsinOp = True
1435 primOpNeedsWrapper FloatAcosOp = True
1436 primOpNeedsWrapper FloatAtanOp = True
1437 primOpNeedsWrapper FloatSinhOp = True
1438 primOpNeedsWrapper FloatCoshOp = True
1439 primOpNeedsWrapper FloatTanhOp = True
1440 primOpNeedsWrapper FloatPowerOp = True
1441 primOpNeedsWrapper FloatEncodeOp = True
1442 primOpNeedsWrapper FloatDecodeOp = True
1444 primOpNeedsWrapper DoubleExpOp = True
1445 primOpNeedsWrapper DoubleLogOp = True
1446 primOpNeedsWrapper DoubleSqrtOp = True
1447 primOpNeedsWrapper DoubleSinOp = True
1448 primOpNeedsWrapper DoubleCosOp = True
1449 primOpNeedsWrapper DoubleTanOp = True
1450 primOpNeedsWrapper DoubleAsinOp = True
1451 primOpNeedsWrapper DoubleAcosOp = True
1452 primOpNeedsWrapper DoubleAtanOp = True
1453 primOpNeedsWrapper DoubleSinhOp = True
1454 primOpNeedsWrapper DoubleCoshOp = True
1455 primOpNeedsWrapper DoubleTanhOp = True
1456 primOpNeedsWrapper DoublePowerOp = True
1457 primOpNeedsWrapper DoubleEncodeOp = True
1458 primOpNeedsWrapper DoubleDecodeOp = True
1460 primOpNeedsWrapper MakeStablePtrOp = True
1461 primOpNeedsWrapper DeRefStablePtrOp = True
1463 primOpNeedsWrapper TakeMVarOp = True
1464 primOpNeedsWrapper PutMVarOp = True
1465 primOpNeedsWrapper ReadIVarOp = True
1467 primOpNeedsWrapper DelayOp = True
1468 primOpNeedsWrapper WaitOp = True
1470 primOpNeedsWrapper other_op = False
1474 primOpId :: PrimOp -> Id
1475 primOpNameInfo :: PrimOp -> (FAST_STRING, Name)
1477 -- the *NameInfo ones are trivial:
1479 primOpNameInfo op = (primOp_str op, WiredInVal (primOpId op))
1482 = case (primOpInfo op) of
1484 Monadic str _ -> str
1485 Compare str _ -> str
1486 Coerce str _ _ -> str
1487 PrimResult str _ _ _ _ _ -> str
1488 AlgResult str _ _ _ _ -> str
1490 PodNInfo d i -> case i of
1491 Dyadic str _ -> (str ++ ".POD" ++ show d ++ "#")
1492 Monadic str _ -> (str ++ ".POD" ++ show d ++ "#")
1493 Compare str _ -> (str ++ ".POD" ++ show d ++ "#")
1494 Coerce str _ _ -> (str ++ ".POD" ++ show d ++ "#")
1495 PrimResult str _ _ _ _ _ -> (str ++ ".POD" ++ show d)
1496 AlgResult str _ _ _ _ -> (str ++ ".POD" ++ show d)
1497 #endif {- Data Parallel Haskell -}
1500 @typeOfPrimOp@ duplicates some work of @primOpId@, but since we
1501 grab types pretty often...
1503 typeOfPrimOp :: PrimOp -> UniType
1506 typeOfPrimOp (PodNPrimOp d p)
1507 = mkPodizedPodNTy d (typeOfPrimOp p)
1508 #endif {- Data Parallel Haskell -}
1511 = case (primOpInfo op) of
1512 Dyadic str ty -> dyadic_fun_ty ty
1513 Monadic str ty -> monadic_fun_ty ty
1514 Compare str ty -> prim_compare_fun_ty ty
1515 Coerce str ty1 ty2 -> UniFun ty1 ty2
1517 PrimResult str tyvars arg_tys prim_tycon kind res_tys ->
1518 mkForallTy tyvars (glueTyArgs arg_tys (applyTyCon prim_tycon res_tys))
1520 AlgResult str tyvars arg_tys tycon res_tys ->
1521 mkForallTy tyvars (glueTyArgs arg_tys (applyTyCon tycon res_tys))
1526 = case (primOpInfo op) of
1528 mk_prim_Id op pRELUDE_BUILTIN str [] [ty,ty] (dyadic_fun_ty ty) 2
1531 mk_prim_Id op pRELUDE_BUILTIN str [] [ty] (monadic_fun_ty ty) 1
1534 mk_prim_Id op pRELUDE_BUILTIN str [] [ty,ty] (prim_compare_fun_ty ty) 2
1536 Coerce str ty1 ty2 ->
1537 mk_prim_Id op pRELUDE_BUILTIN str [] [ty1] (UniFun ty1 ty2) 1
1539 PrimResult str tyvars arg_tys prim_tycon kind res_tys ->
1540 mk_prim_Id op pRELUDE_BUILTIN str
1543 (mkForallTy tyvars (glueTyArgs arg_tys (applyTyCon prim_tycon res_tys)))
1544 (length arg_tys) -- arity
1546 AlgResult str tyvars arg_tys tycon res_tys ->
1547 mk_prim_Id op pRELUDE_BUILTIN str
1550 (mkForallTy tyvars (glueTyArgs arg_tys (applyTyCon tycon res_tys)))
1551 (length arg_tys) -- arity
1554 PodNInfo d i -> panic "primOpId : Oi lazy, PodNInfo needs sorting out"
1555 #endif {- Data Parallel Haskell -}
1557 mk_prim_Id prim_op mod name tyvar_tmpls arg_tys ty arity
1559 (mkPrimOpIdUnique prim_op)
1560 (mkPreludeCoreName mod name)
1563 `addInfo` (mkArityInfo arity)
1564 `addInfo_UF` (mkUnfolding EssentialUnfolding
1565 (mk_prim_unfold prim_op tyvar_tmpls arg_tys)))
1568 The functions to make common unfoldings are tedious.
1571 mk_prim_unfold :: PrimOp -> [TyVarTemplate] -> [UniType] -> PlainCoreExpr{-template-}
1573 mk_prim_unfold prim_op tv_tmpls arg_tys
1575 (inst_env, tyvars, tyvar_tys) = instantiateTyVarTemplates tv_tmpls (map getTheUnique tv_tmpls)
1576 inst_arg_tys = map (instantiateTauTy inst_env) arg_tys
1577 vars = mkTemplateLocals inst_arg_tys
1579 foldr CoTyLam (mkCoLam vars
1580 (CoPrim prim_op tyvar_tys [CoVarAtom v | v <- vars]))
1585 data PrimOpResultInfo
1586 = ReturnsPrim PrimKind
1589 -- ToDo: Deal with specialised PrimOps
1590 -- Will need to return specialised tycon and data constructors
1592 getPrimOpResultInfo :: PrimOp -> PrimOpResultInfo
1594 getPrimOpResultInfo op
1595 = case (primOpInfo op) of
1596 Dyadic _ ty -> ReturnsPrim (kindFromType ty)
1597 Monadic _ ty -> ReturnsPrim (kindFromType ty)
1598 Compare _ ty -> ReturnsAlg boolTyCon
1599 Coerce _ _ ty -> ReturnsPrim (kindFromType ty)
1600 PrimResult _ _ _ _ kind _ -> ReturnsPrim kind
1601 AlgResult _ _ _ tycon _ -> ReturnsAlg tycon
1603 PodNInfo d i -> panic "getPrimOpResultInfo:PodNInfo"
1604 #endif {- Data Parallel Haskell -}
1606 isCompareOp :: PrimOp -> Bool
1609 = case primOpInfo op of
1616 dyadic_fun_ty ty = ty `UniFun` (ty `UniFun` ty)
1617 monadic_fun_ty ty = ty `UniFun` ty
1619 compare_fun_ty ty = ty `UniFun` (ty `UniFun` boolTy)
1620 prim_compare_fun_ty ty = ty `UniFun` (ty `UniFun` boolTy)
1625 pprPrimOp :: PprStyle -> PrimOp -> Pretty
1626 showPrimOp :: PprStyle -> PrimOp -> String
1629 = ppShow 1000{-random-} (pprPrimOp sty op)
1631 pprPrimOp sty (CCallOp fun is_casm may_gc arg_tys res_ty)
1635 if may_gc then "(_casm_GC_ ``" else "(_casm_ ``"
1637 if may_gc then "(_ccall_GC_ " else "(_ccall_ "
1640 = if is_casm then ppStr "''" else ppNil
1643 = ppBesides [ppStr " { [",
1644 ppIntersperse pp'SP{-'-} (map (pprParendUniType sty) arg_tys),
1645 ppRbrack, ppSP, pprParendUniType sty res_ty, ppStr " })"]
1648 ppBesides [ppStr before, ppPStr fun, after, pp_tys]
1650 = fun -- Comment buggers up machine code :-) -- ToDo:DPH
1651 #endif {- Data Parallel Haskell -}
1653 pprPrimOp sty other_op
1655 str = primOp_str other_op
1661 instance Outputable PrimOp where
1662 ppr sty op = pprPrimOp sty op