CLabel: Refactor pprDynamicLinkerAsmLabel
[ghc.git] / compiler / cmm / CmmMachOp.hs
1 {-# LANGUAGE CPP #-}
2
3 module CmmMachOp
4 ( MachOp(..)
5 , pprMachOp, isCommutableMachOp, isAssociativeMachOp
6 , isComparisonMachOp, maybeIntComparison, machOpResultType
7 , machOpArgReps, maybeInvertComparison
8
9 -- MachOp builders
10 , mo_wordAdd, mo_wordSub, mo_wordEq, mo_wordNe,mo_wordMul, mo_wordSQuot
11 , mo_wordSRem, mo_wordSNeg, mo_wordUQuot, mo_wordURem
12 , mo_wordSGe, mo_wordSLe, mo_wordSGt, mo_wordSLt, mo_wordUGe
13 , mo_wordULe, mo_wordUGt, mo_wordULt
14 , mo_wordAnd, mo_wordOr, mo_wordXor, mo_wordNot
15 , mo_wordShl, mo_wordSShr, mo_wordUShr
16 , mo_u_8To32, mo_s_8To32, mo_u_16To32, mo_s_16To32
17 , mo_u_8ToWord, mo_s_8ToWord, mo_u_16ToWord, mo_s_16ToWord
18 , mo_u_32ToWord, mo_s_32ToWord
19 , mo_32To8, mo_32To16, mo_WordTo8, mo_WordTo16, mo_WordTo32, mo_WordTo64
20
21 -- CallishMachOp
22 , CallishMachOp(..), callishMachOpHints
23 , pprCallishMachOp
24 , machOpMemcpyishAlign
25
26 -- Atomic read-modify-write
27 , AtomicMachOp(..)
28 )
29 where
30
31 #include "HsVersions.h"
32
33 import GhcPrelude
34
35 import CmmType
36 import Outputable
37 import DynFlags
38
39 -----------------------------------------------------------------------------
40 -- MachOp
41 -----------------------------------------------------------------------------
42
43 {- |
44 Machine-level primops; ones which we can reasonably delegate to the
45 native code generators to handle.
46
47 Most operations are parameterised by the 'Width' that they operate on.
48 Some operations have separate signed and unsigned versions, and float
49 and integer versions.
50 -}
51
52 data MachOp
53 -- Integer operations (insensitive to signed/unsigned)
54 = MO_Add Width
55 | MO_Sub Width
56 | MO_Eq Width
57 | MO_Ne Width
58 | MO_Mul Width -- low word of multiply
59
60 -- Signed multiply/divide
61 | MO_S_MulMayOflo Width -- nonzero if signed multiply overflows
62 | MO_S_Quot Width -- signed / (same semantics as IntQuotOp)
63 | MO_S_Rem Width -- signed % (same semantics as IntRemOp)
64 | MO_S_Neg Width -- unary -
65
66 -- Unsigned multiply/divide
67 | MO_U_MulMayOflo Width -- nonzero if unsigned multiply overflows
68 | MO_U_Quot Width -- unsigned / (same semantics as WordQuotOp)
69 | MO_U_Rem Width -- unsigned % (same semantics as WordRemOp)
70
71 -- Signed comparisons
72 | MO_S_Ge Width
73 | MO_S_Le Width
74 | MO_S_Gt Width
75 | MO_S_Lt Width
76
77 -- Unsigned comparisons
78 | MO_U_Ge Width
79 | MO_U_Le Width
80 | MO_U_Gt Width
81 | MO_U_Lt Width
82
83 -- Floating point arithmetic
84 | MO_F_Add Width
85 | MO_F_Sub Width
86 | MO_F_Neg Width -- unary -
87 | MO_F_Mul Width
88 | MO_F_Quot Width
89
90 -- Floating point comparison
91 | MO_F_Eq Width
92 | MO_F_Ne Width
93 | MO_F_Ge Width
94 | MO_F_Le Width
95 | MO_F_Gt Width
96 | MO_F_Lt Width
97
98 -- Bitwise operations. Not all of these may be supported
99 -- at all sizes, and only integral Widths are valid.
100 | MO_And Width
101 | MO_Or Width
102 | MO_Xor Width
103 | MO_Not Width
104 | MO_Shl Width
105 | MO_U_Shr Width -- unsigned shift right
106 | MO_S_Shr Width -- signed shift right
107
108 -- Conversions. Some of these will be NOPs.
109 -- Floating-point conversions use the signed variant.
110 | MO_SF_Conv Width Width -- Signed int -> Float
111 | MO_FS_Conv Width Width -- Float -> Signed int
112 | MO_SS_Conv Width Width -- Signed int -> Signed int
113 | MO_UU_Conv Width Width -- unsigned int -> unsigned int
114 | MO_FF_Conv Width Width -- Float -> Float
115
116 -- Vector element insertion and extraction operations
117 | MO_V_Insert Length Width -- Insert scalar into vector
118 | MO_V_Extract Length Width -- Extract scalar from vector
119
120 -- Integer vector operations
121 | MO_V_Add Length Width
122 | MO_V_Sub Length Width
123 | MO_V_Mul Length Width
124
125 -- Signed vector multiply/divide
126 | MO_VS_Quot Length Width
127 | MO_VS_Rem Length Width
128 | MO_VS_Neg Length Width
129
130 -- Unsigned vector multiply/divide
131 | MO_VU_Quot Length Width
132 | MO_VU_Rem Length Width
133
134 -- Floting point vector element insertion and extraction operations
135 | MO_VF_Insert Length Width -- Insert scalar into vector
136 | MO_VF_Extract Length Width -- Extract scalar from vector
137
138 -- Floating point vector operations
139 | MO_VF_Add Length Width
140 | MO_VF_Sub Length Width
141 | MO_VF_Neg Length Width -- unary negation
142 | MO_VF_Mul Length Width
143 | MO_VF_Quot Length Width
144
145 -- Alignment check (for -falignment-sanitisation)
146 | MO_AlignmentCheck Int Width
147 deriving (Eq, Show)
148
149 pprMachOp :: MachOp -> SDoc
150 pprMachOp mo = text (show mo)
151
152
153
154 -- -----------------------------------------------------------------------------
155 -- Some common MachReps
156
157 -- A 'wordRep' is a machine word on the target architecture
158 -- Specifically, it is the size of an Int#, Word#, Addr#
159 -- and the unit of allocation on the stack and the heap
160 -- Any pointer is also guaranteed to be a wordRep.
161
162 mo_wordAdd, mo_wordSub, mo_wordEq, mo_wordNe,mo_wordMul, mo_wordSQuot
163 , mo_wordSRem, mo_wordSNeg, mo_wordUQuot, mo_wordURem
164 , mo_wordSGe, mo_wordSLe, mo_wordSGt, mo_wordSLt, mo_wordUGe
165 , mo_wordULe, mo_wordUGt, mo_wordULt
166 , mo_wordAnd, mo_wordOr, mo_wordXor, mo_wordNot, mo_wordShl, mo_wordSShr, mo_wordUShr
167 , mo_u_8ToWord, mo_s_8ToWord, mo_u_16ToWord, mo_s_16ToWord, mo_u_32ToWord, mo_s_32ToWord
168 , mo_WordTo8, mo_WordTo16, mo_WordTo32, mo_WordTo64
169 :: DynFlags -> MachOp
170
171 mo_u_8To32, mo_s_8To32, mo_u_16To32, mo_s_16To32
172 , mo_32To8, mo_32To16
173 :: MachOp
174
175 mo_wordAdd dflags = MO_Add (wordWidth dflags)
176 mo_wordSub dflags = MO_Sub (wordWidth dflags)
177 mo_wordEq dflags = MO_Eq (wordWidth dflags)
178 mo_wordNe dflags = MO_Ne (wordWidth dflags)
179 mo_wordMul dflags = MO_Mul (wordWidth dflags)
180 mo_wordSQuot dflags = MO_S_Quot (wordWidth dflags)
181 mo_wordSRem dflags = MO_S_Rem (wordWidth dflags)
182 mo_wordSNeg dflags = MO_S_Neg (wordWidth dflags)
183 mo_wordUQuot dflags = MO_U_Quot (wordWidth dflags)
184 mo_wordURem dflags = MO_U_Rem (wordWidth dflags)
185
186 mo_wordSGe dflags = MO_S_Ge (wordWidth dflags)
187 mo_wordSLe dflags = MO_S_Le (wordWidth dflags)
188 mo_wordSGt dflags = MO_S_Gt (wordWidth dflags)
189 mo_wordSLt dflags = MO_S_Lt (wordWidth dflags)
190
191 mo_wordUGe dflags = MO_U_Ge (wordWidth dflags)
192 mo_wordULe dflags = MO_U_Le (wordWidth dflags)
193 mo_wordUGt dflags = MO_U_Gt (wordWidth dflags)
194 mo_wordULt dflags = MO_U_Lt (wordWidth dflags)
195
196 mo_wordAnd dflags = MO_And (wordWidth dflags)
197 mo_wordOr dflags = MO_Or (wordWidth dflags)
198 mo_wordXor dflags = MO_Xor (wordWidth dflags)
199 mo_wordNot dflags = MO_Not (wordWidth dflags)
200 mo_wordShl dflags = MO_Shl (wordWidth dflags)
201 mo_wordSShr dflags = MO_S_Shr (wordWidth dflags)
202 mo_wordUShr dflags = MO_U_Shr (wordWidth dflags)
203
204 mo_u_8To32 = MO_UU_Conv W8 W32
205 mo_s_8To32 = MO_SS_Conv W8 W32
206 mo_u_16To32 = MO_UU_Conv W16 W32
207 mo_s_16To32 = MO_SS_Conv W16 W32
208
209 mo_u_8ToWord dflags = MO_UU_Conv W8 (wordWidth dflags)
210 mo_s_8ToWord dflags = MO_SS_Conv W8 (wordWidth dflags)
211 mo_u_16ToWord dflags = MO_UU_Conv W16 (wordWidth dflags)
212 mo_s_16ToWord dflags = MO_SS_Conv W16 (wordWidth dflags)
213 mo_s_32ToWord dflags = MO_SS_Conv W32 (wordWidth dflags)
214 mo_u_32ToWord dflags = MO_UU_Conv W32 (wordWidth dflags)
215
216 mo_WordTo8 dflags = MO_UU_Conv (wordWidth dflags) W8
217 mo_WordTo16 dflags = MO_UU_Conv (wordWidth dflags) W16
218 mo_WordTo32 dflags = MO_UU_Conv (wordWidth dflags) W32
219 mo_WordTo64 dflags = MO_UU_Conv (wordWidth dflags) W64
220
221 mo_32To8 = MO_UU_Conv W32 W8
222 mo_32To16 = MO_UU_Conv W32 W16
223
224
225 -- ----------------------------------------------------------------------------
226 -- isCommutableMachOp
227
228 {- |
229 Returns 'True' if the MachOp has commutable arguments. This is used
230 in the platform-independent Cmm optimisations.
231
232 If in doubt, return 'False'. This generates worse code on the
233 native routes, but is otherwise harmless.
234 -}
235 isCommutableMachOp :: MachOp -> Bool
236 isCommutableMachOp mop =
237 case mop of
238 MO_Add _ -> True
239 MO_Eq _ -> True
240 MO_Ne _ -> True
241 MO_Mul _ -> True
242 MO_S_MulMayOflo _ -> True
243 MO_U_MulMayOflo _ -> True
244 MO_And _ -> True
245 MO_Or _ -> True
246 MO_Xor _ -> True
247 MO_F_Add _ -> True
248 MO_F_Mul _ -> True
249 _other -> False
250
251 -- ----------------------------------------------------------------------------
252 -- isAssociativeMachOp
253
254 {- |
255 Returns 'True' if the MachOp is associative (i.e. @(x+y)+z == x+(y+z)@)
256 This is used in the platform-independent Cmm optimisations.
257
258 If in doubt, return 'False'. This generates worse code on the
259 native routes, but is otherwise harmless.
260 -}
261 isAssociativeMachOp :: MachOp -> Bool
262 isAssociativeMachOp mop =
263 case mop of
264 MO_Add {} -> True -- NB: does not include
265 MO_Mul {} -> True -- floatint point!
266 MO_And {} -> True
267 MO_Or {} -> True
268 MO_Xor {} -> True
269 _other -> False
270
271
272 -- ----------------------------------------------------------------------------
273 -- isComparisonMachOp
274
275 {- |
276 Returns 'True' if the MachOp is a comparison.
277
278 If in doubt, return False. This generates worse code on the
279 native routes, but is otherwise harmless.
280 -}
281 isComparisonMachOp :: MachOp -> Bool
282 isComparisonMachOp mop =
283 case mop of
284 MO_Eq _ -> True
285 MO_Ne _ -> True
286 MO_S_Ge _ -> True
287 MO_S_Le _ -> True
288 MO_S_Gt _ -> True
289 MO_S_Lt _ -> True
290 MO_U_Ge _ -> True
291 MO_U_Le _ -> True
292 MO_U_Gt _ -> True
293 MO_U_Lt _ -> True
294 MO_F_Eq {} -> True
295 MO_F_Ne {} -> True
296 MO_F_Ge {} -> True
297 MO_F_Le {} -> True
298 MO_F_Gt {} -> True
299 MO_F_Lt {} -> True
300 _other -> False
301
302 {- |
303 Returns @Just w@ if the operation is an integer comparison with width
304 @w@, or @Nothing@ otherwise.
305 -}
306 maybeIntComparison :: MachOp -> Maybe Width
307 maybeIntComparison mop =
308 case mop of
309 MO_Eq w -> Just w
310 MO_Ne w -> Just w
311 MO_S_Ge w -> Just w
312 MO_S_Le w -> Just w
313 MO_S_Gt w -> Just w
314 MO_S_Lt w -> Just w
315 MO_U_Ge w -> Just w
316 MO_U_Le w -> Just w
317 MO_U_Gt w -> Just w
318 MO_U_Lt w -> Just w
319 _ -> Nothing
320
321 -- -----------------------------------------------------------------------------
322 -- Inverting conditions
323
324 -- Sometimes it's useful to be able to invert the sense of a
325 -- condition. Not all conditional tests are invertible: in
326 -- particular, floating point conditionals cannot be inverted, because
327 -- there exist floating-point values which return False for both senses
328 -- of a condition (eg. !(NaN > NaN) && !(NaN /<= NaN)).
329
330 maybeInvertComparison :: MachOp -> Maybe MachOp
331 maybeInvertComparison op
332 = case op of -- None of these Just cases include floating point
333 MO_Eq r -> Just (MO_Ne r)
334 MO_Ne r -> Just (MO_Eq r)
335 MO_U_Lt r -> Just (MO_U_Ge r)
336 MO_U_Gt r -> Just (MO_U_Le r)
337 MO_U_Le r -> Just (MO_U_Gt r)
338 MO_U_Ge r -> Just (MO_U_Lt r)
339 MO_S_Lt r -> Just (MO_S_Ge r)
340 MO_S_Gt r -> Just (MO_S_Le r)
341 MO_S_Le r -> Just (MO_S_Gt r)
342 MO_S_Ge r -> Just (MO_S_Lt r)
343 _other -> Nothing
344
345 -- ----------------------------------------------------------------------------
346 -- machOpResultType
347
348 {- |
349 Returns the MachRep of the result of a MachOp.
350 -}
351 machOpResultType :: DynFlags -> MachOp -> [CmmType] -> CmmType
352 machOpResultType dflags mop tys =
353 case mop of
354 MO_Add {} -> ty1 -- Preserve GC-ptr-hood
355 MO_Sub {} -> ty1 -- of first arg
356 MO_Mul r -> cmmBits r
357 MO_S_MulMayOflo r -> cmmBits r
358 MO_S_Quot r -> cmmBits r
359 MO_S_Rem r -> cmmBits r
360 MO_S_Neg r -> cmmBits r
361 MO_U_MulMayOflo r -> cmmBits r
362 MO_U_Quot r -> cmmBits r
363 MO_U_Rem r -> cmmBits r
364
365 MO_Eq {} -> comparisonResultRep dflags
366 MO_Ne {} -> comparisonResultRep dflags
367 MO_S_Ge {} -> comparisonResultRep dflags
368 MO_S_Le {} -> comparisonResultRep dflags
369 MO_S_Gt {} -> comparisonResultRep dflags
370 MO_S_Lt {} -> comparisonResultRep dflags
371
372 MO_U_Ge {} -> comparisonResultRep dflags
373 MO_U_Le {} -> comparisonResultRep dflags
374 MO_U_Gt {} -> comparisonResultRep dflags
375 MO_U_Lt {} -> comparisonResultRep dflags
376
377 MO_F_Add r -> cmmFloat r
378 MO_F_Sub r -> cmmFloat r
379 MO_F_Mul r -> cmmFloat r
380 MO_F_Quot r -> cmmFloat r
381 MO_F_Neg r -> cmmFloat r
382 MO_F_Eq {} -> comparisonResultRep dflags
383 MO_F_Ne {} -> comparisonResultRep dflags
384 MO_F_Ge {} -> comparisonResultRep dflags
385 MO_F_Le {} -> comparisonResultRep dflags
386 MO_F_Gt {} -> comparisonResultRep dflags
387 MO_F_Lt {} -> comparisonResultRep dflags
388
389 MO_And {} -> ty1 -- Used for pointer masking
390 MO_Or {} -> ty1
391 MO_Xor {} -> ty1
392 MO_Not r -> cmmBits r
393 MO_Shl r -> cmmBits r
394 MO_U_Shr r -> cmmBits r
395 MO_S_Shr r -> cmmBits r
396
397 MO_SS_Conv _ to -> cmmBits to
398 MO_UU_Conv _ to -> cmmBits to
399 MO_FS_Conv _ to -> cmmBits to
400 MO_SF_Conv _ to -> cmmFloat to
401 MO_FF_Conv _ to -> cmmFloat to
402
403 MO_V_Insert l w -> cmmVec l (cmmBits w)
404 MO_V_Extract _ w -> cmmBits w
405
406 MO_V_Add l w -> cmmVec l (cmmBits w)
407 MO_V_Sub l w -> cmmVec l (cmmBits w)
408 MO_V_Mul l w -> cmmVec l (cmmBits w)
409
410 MO_VS_Quot l w -> cmmVec l (cmmBits w)
411 MO_VS_Rem l w -> cmmVec l (cmmBits w)
412 MO_VS_Neg l w -> cmmVec l (cmmBits w)
413
414 MO_VU_Quot l w -> cmmVec l (cmmBits w)
415 MO_VU_Rem l w -> cmmVec l (cmmBits w)
416
417 MO_VF_Insert l w -> cmmVec l (cmmFloat w)
418 MO_VF_Extract _ w -> cmmFloat w
419
420 MO_VF_Add l w -> cmmVec l (cmmFloat w)
421 MO_VF_Sub l w -> cmmVec l (cmmFloat w)
422 MO_VF_Mul l w -> cmmVec l (cmmFloat w)
423 MO_VF_Quot l w -> cmmVec l (cmmFloat w)
424 MO_VF_Neg l w -> cmmVec l (cmmFloat w)
425
426 MO_AlignmentCheck _ _ -> ty1
427 where
428 (ty1:_) = tys
429
430 comparisonResultRep :: DynFlags -> CmmType
431 comparisonResultRep = bWord -- is it?
432
433
434 -- -----------------------------------------------------------------------------
435 -- machOpArgReps
436
437 -- | This function is used for debugging only: we can check whether an
438 -- application of a MachOp is "type-correct" by checking that the MachReps of
439 -- its arguments are the same as the MachOp expects. This is used when
440 -- linting a CmmExpr.
441
442 machOpArgReps :: DynFlags -> MachOp -> [Width]
443 machOpArgReps dflags op =
444 case op of
445 MO_Add r -> [r,r]
446 MO_Sub r -> [r,r]
447 MO_Eq r -> [r,r]
448 MO_Ne r -> [r,r]
449 MO_Mul r -> [r,r]
450 MO_S_MulMayOflo r -> [r,r]
451 MO_S_Quot r -> [r,r]
452 MO_S_Rem r -> [r,r]
453 MO_S_Neg r -> [r]
454 MO_U_MulMayOflo r -> [r,r]
455 MO_U_Quot r -> [r,r]
456 MO_U_Rem r -> [r,r]
457
458 MO_S_Ge r -> [r,r]
459 MO_S_Le r -> [r,r]
460 MO_S_Gt r -> [r,r]
461 MO_S_Lt r -> [r,r]
462
463 MO_U_Ge r -> [r,r]
464 MO_U_Le r -> [r,r]
465 MO_U_Gt r -> [r,r]
466 MO_U_Lt r -> [r,r]
467
468 MO_F_Add r -> [r,r]
469 MO_F_Sub r -> [r,r]
470 MO_F_Mul r -> [r,r]
471 MO_F_Quot r -> [r,r]
472 MO_F_Neg r -> [r]
473 MO_F_Eq r -> [r,r]
474 MO_F_Ne r -> [r,r]
475 MO_F_Ge r -> [r,r]
476 MO_F_Le r -> [r,r]
477 MO_F_Gt r -> [r,r]
478 MO_F_Lt r -> [r,r]
479
480 MO_And r -> [r,r]
481 MO_Or r -> [r,r]
482 MO_Xor r -> [r,r]
483 MO_Not r -> [r]
484 MO_Shl r -> [r, wordWidth dflags]
485 MO_U_Shr r -> [r, wordWidth dflags]
486 MO_S_Shr r -> [r, wordWidth dflags]
487
488 MO_SS_Conv from _ -> [from]
489 MO_UU_Conv from _ -> [from]
490 MO_SF_Conv from _ -> [from]
491 MO_FS_Conv from _ -> [from]
492 MO_FF_Conv from _ -> [from]
493
494 MO_V_Insert l r -> [typeWidth (vec l (cmmBits r)),r,wordWidth dflags]
495 MO_V_Extract l r -> [typeWidth (vec l (cmmBits r)),wordWidth dflags]
496
497 MO_V_Add _ r -> [r,r]
498 MO_V_Sub _ r -> [r,r]
499 MO_V_Mul _ r -> [r,r]
500
501 MO_VS_Quot _ r -> [r,r]
502 MO_VS_Rem _ r -> [r,r]
503 MO_VS_Neg _ r -> [r]
504
505 MO_VU_Quot _ r -> [r,r]
506 MO_VU_Rem _ r -> [r,r]
507
508 MO_VF_Insert l r -> [typeWidth (vec l (cmmFloat r)),r,wordWidth dflags]
509 MO_VF_Extract l r -> [typeWidth (vec l (cmmFloat r)),wordWidth dflags]
510
511 MO_VF_Add _ r -> [r,r]
512 MO_VF_Sub _ r -> [r,r]
513 MO_VF_Mul _ r -> [r,r]
514 MO_VF_Quot _ r -> [r,r]
515 MO_VF_Neg _ r -> [r]
516
517 MO_AlignmentCheck _ r -> [r]
518
519 -----------------------------------------------------------------------------
520 -- CallishMachOp
521 -----------------------------------------------------------------------------
522
523 -- CallishMachOps tend to be implemented by foreign calls in some backends,
524 -- so we separate them out. In Cmm, these can only occur in a
525 -- statement position, in contrast to an ordinary MachOp which can occur
526 -- anywhere in an expression.
527 data CallishMachOp
528 = MO_F64_Pwr
529 | MO_F64_Sin
530 | MO_F64_Cos
531 | MO_F64_Tan
532 | MO_F64_Sinh
533 | MO_F64_Cosh
534 | MO_F64_Tanh
535 | MO_F64_Asin
536 | MO_F64_Acos
537 | MO_F64_Atan
538 | MO_F64_Log
539 | MO_F64_Exp
540 | MO_F64_Fabs
541 | MO_F64_Sqrt
542 | MO_F32_Pwr
543 | MO_F32_Sin
544 | MO_F32_Cos
545 | MO_F32_Tan
546 | MO_F32_Sinh
547 | MO_F32_Cosh
548 | MO_F32_Tanh
549 | MO_F32_Asin
550 | MO_F32_Acos
551 | MO_F32_Atan
552 | MO_F32_Log
553 | MO_F32_Exp
554 | MO_F32_Fabs
555 | MO_F32_Sqrt
556
557 | MO_UF_Conv Width
558
559 | MO_S_QuotRem Width
560 | MO_U_QuotRem Width
561 | MO_U_QuotRem2 Width
562 | MO_Add2 Width
563 | MO_SubWordC Width
564 | MO_AddIntC Width
565 | MO_SubIntC Width
566 | MO_U_Mul2 Width
567
568 | MO_WriteBarrier
569 | MO_Touch -- Keep variables live (when using interior pointers)
570
571 -- Prefetch
572 | MO_Prefetch_Data Int -- Prefetch hint. May change program performance but not
573 -- program behavior.
574 -- the Int can be 0-3. Needs to be known at compile time
575 -- to interact with code generation correctly.
576 -- TODO: add support for prefetch WRITES,
577 -- currently only exposes prefetch reads, which
578 -- would the majority of use cases in ghc anyways
579
580
581 -- These three MachOps are parameterised by the known alignment
582 -- of the destination and source (for memcpy/memmove) pointers.
583 -- This information may be used for optimisation in backends.
584 | MO_Memcpy Int
585 | MO_Memset Int
586 | MO_Memmove Int
587 | MO_Memcmp Int
588
589 | MO_PopCnt Width
590 | MO_Clz Width
591 | MO_Ctz Width
592
593 | MO_BSwap Width
594
595 -- Atomic read-modify-write.
596 | MO_AtomicRMW Width AtomicMachOp
597 | MO_AtomicRead Width
598 | MO_AtomicWrite Width
599 | MO_Cmpxchg Width
600 deriving (Eq, Show)
601
602 -- | The operation to perform atomically.
603 data AtomicMachOp =
604 AMO_Add
605 | AMO_Sub
606 | AMO_And
607 | AMO_Nand
608 | AMO_Or
609 | AMO_Xor
610 deriving (Eq, Show)
611
612 pprCallishMachOp :: CallishMachOp -> SDoc
613 pprCallishMachOp mo = text (show mo)
614
615 callishMachOpHints :: CallishMachOp -> ([ForeignHint], [ForeignHint])
616 callishMachOpHints op = case op of
617 MO_Memcpy _ -> ([], [AddrHint,AddrHint,NoHint])
618 MO_Memset _ -> ([], [AddrHint,NoHint,NoHint])
619 MO_Memmove _ -> ([], [AddrHint,AddrHint,NoHint])
620 MO_Memcmp _ -> ([], [AddrHint, AddrHint, NoHint])
621 _ -> ([],[])
622 -- empty lists indicate NoHint
623
624 -- | The alignment of a 'memcpy'-ish operation.
625 machOpMemcpyishAlign :: CallishMachOp -> Maybe Int
626 machOpMemcpyishAlign op = case op of
627 MO_Memcpy align -> Just align
628 MO_Memset align -> Just align
629 MO_Memmove align -> Just align
630 MO_Memcmp align -> Just align
631 _ -> Nothing