primops.txt.pp 145 KB
Newer Older
1
-----------------------------------------------------------------------
Jan Stolarek's avatar
Jan Stolarek committed
2
--
3
-- (c) 2010 The University of Glasgow
4
--
5
-- Primitive Operations and Types
6
--
7
-- For more information on PrimOps, see
8
--   https://gitlab.haskell.org/ghc/ghc/wikis/commentary/prim-ops
9
--
10 11
-----------------------------------------------------------------------

apt's avatar
apt committed
12 13 14 15 16 17
-- This file is processed by the utility program genprimopcode to produce
-- a number of include files within the compiler and optionally to produce
-- human-readable documentation.
--
-- It should first be preprocessed.
--
18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92
-- Note in particular that Haskell block-style comments are not recognized
-- here, so stick to '--' (even for Notes spanning multiple lines).

-- Note [GHC.Prim]
-- ~~~~~~~~~~~~~~~
-- GHC.Prim is a special module:
--
-- * It can be imported by any module (import GHC.Prim).
--   However, in the future we might change which functions are primitives
--   and which are defined in Haskell.
--   Users should import GHC.Exts, which reexports GHC.Prim and is more stable.
--   In particular, we might move some of the primops to 'foreign import prim'
--   (see ticket #16929 and Note [When do out-of-line primops go in primops.txt.pp])
--
-- * It provides primitives of three sorts:
--   - primitive types such as Int64#, MutableByteArray#
--   - primops such as (+#), newTVar#, touch#
--   - pseudoops such as realWorld#, nullAddr#
--
-- * The pseudoops are described in Note [ghcPrimIds (aka pseudoops)]
--   in GHC.Types.Id.Make.
--
-- * The primitives (primtypes, primops, pseudoops) cannot be defined in
--   source Haskell.
--   There is no GHC/Prim.hs file with definitions.
--   Instead, we support importing GHC.Prim by manually defining its
--   ModIface (see Iface.Load.ghcPrimIface).
--
-- * The primitives are listed in this file, primops.txt.pp.
--   It goes through CPP, which creates primops.txt.
--   It is then consumed by the utility program genprimopcode, which produces
--   the following three types of files.
--
--   1. The files with extension .hs-incl.
--      They can be found by grepping for hs-incl.
--      They are #included in compiler sources.
--
--      One of them, primop-data-decl.hs-incl, defines the PrimOp type:
--        data PrimOp
--         = IntAddOp
--         | IntSubOp
--         | CharGtOp
--         | CharGeOp
--         | ...
--
--      The remaining files define properties of the primops
--      by pattern matching, for example:
--        primOpFixity IntAddOp = Just (Fixity NoSourceText 6 InfixL)
--        primOpFixity IntSubOp = Just (Fixity NoSourceText 6 InfixL)
--        ...
--      This includes fixity, has-side-effects, commutability,
--      IDs used to generate Uniques etc.
--
--      Additionally, we pattern match on PrimOp when generating Cmm in
--      GHC/StgToCmm/Prim.hs.
--
--   2. The dummy Prim.hs file, which is used for Haddock and
--      contains descriptions taken from primops.txt.pp.
--      All definitions are replaced by placeholders.
--      See Note [GHC.Prim Docs] in genprimopcode.
--
--   3. The module PrimopWrappers.hs, which wraps every call for GHCi;
--      see Note [Primop wrappers] in GHC.Builtin.Primops for details.
--
-- * This file does not list internal-only equality types
--   (GHC.Builtin.Types.Prim.unexposedPrimTyCons and coercionToken#
--   in GHC.Types.Id.Make) which are defined but not exported from GHC.Prim.
--   Every export of GHC.Prim should be in listed in this file.
--
-- * The primitive types should be listed in primTyCons in Builtin.Types.Prim
--   in addition to primops.txt.pp.
--   (This task should be delegated to genprimopcode in the future.)
--
--
--
93 94
-- Information on how PrimOps are implemented and the steps necessary to
-- add a new one can be found in the Commentary:
apt's avatar
apt committed
95
--
96
--  https://gitlab.haskell.org/ghc/ghc/wikis/commentary/prim-ops
97
--
98 99
-- This file is divided into named sections, each containing or more
-- primop entries. Section headers have the format:
apt's avatar
apt committed
100
--
101
--      section "section-name" {description}
apt's avatar
apt committed
102
--
103 104
-- This information is used solely when producing documentation; it is
-- otherwise ignored.  The description is optional.
apt's avatar
apt committed
105 106
--
-- The format of each primop entry is as follows:
107
--
mizunashi_mana's avatar
mizunashi_mana committed
108
--      primop internal-name "name-in-program-text" category type {description} attributes
109

apt's avatar
apt committed
110
-- The default attribute values which apply if you don't specify
111
-- other ones.  Attribute values can be True, False, or arbitrary
Jan Stolarek's avatar
Jan Stolarek committed
112
-- text between curly brackets.  This is a kludge to enable
113 114
-- processors of this file to easily get hold of simple info
-- (eg, out_of_line), whilst avoiding parsing complex expressions
115
-- needed for strictness info.
116
--
117
-- type refers to the general category of the primop. There are only two:
118 119 120 121
--
--  * Compare:   A comparison operation of the shape a -> a -> Int#
--  * GenPrimOp: Any other sort of primop
--
122

123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138
-- The vector attribute is rather special. It takes a list of 3-tuples, each of
-- which is of the form <ELEM_TYPE,SCALAR_TYPE,LENGTH>. ELEM_TYPE is the type of
-- the elements in the vector; LENGTH is the length of the vector; and
-- SCALAR_TYPE is the scalar type used to inject to/project from vector
-- element. Note that ELEM_TYPE and SCALAR_TYPE are not the same; for example,
-- to broadcast a scalar value to a vector whose elements are of type Int8, we
-- use an Int#.

-- When a primtype or primop has a vector attribute, it is instantiated at each
-- 3-tuple in the list of 3-tuples. That is, the vector attribute allows us to
-- define a family of types or primops. Vector support also adds three new
-- keywords: VECTOR, SCALAR, and VECTUPLE. These keywords are expanded to types
-- derived from the 3-tuple. For the 3-tuple <Int64,INT64,2>, VECTOR expands to
-- Int64X2#, SCALAR expands to INT64, and VECTUPLE expands to (# INT64, INT64
-- #).

139 140
defaults
   has_side_effects = False
John Ericson's avatar
John Ericson committed
141 142
   out_of_line      = False   -- See Note [When do out-of-line primops go in primops.txt.pp]
   can_fail         = False   -- See Note [PrimOp can_fail and has_side_effects] in PrimOp
143
   commutable       = False
144
   code_size        = { primOpCodeSizeDefault }
145
   strictness       = { \ arity -> mkClosedDmdSig (replicate arity topDmd) topDiv }
146
   fixity           = Nothing
gmainland's avatar
gmainland committed
147
   llvm_only        = False
148
   vector           = []
149
   deprecated_msg   = {}      -- A non-empty message indicates deprecation
150

John Ericson's avatar
John Ericson committed
151 152 153 154 155 156 157 158 159 160 161 162 163 164 165
-- Note [When do out-of-line primops go in primops.txt.pp]
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
--
-- Out of line primops are those with a C-- implementation. But that
-- doesn't mean they *just* have an C-- implementation. As mentioned in
-- Note [Inlining out-of-line primops and heap checks], some out-of-line
-- primops also have additional internal implementations under certain
-- conditions. Now that `foreign import prim` exists, only those primops
-- which have both internal and external implementations ought to be
-- this file. The rest aren't really primops, since they don't need
-- bespoke compiler support but just a general way to interface with
-- C--. They are just foreign calls.
--
-- Unfortunately, for the time being most of the primops which should be
-- moved according to the previous paragraph can't yet. There are some
Krzysztof Gogolewski's avatar
Krzysztof Gogolewski committed
166
-- superficial restrictions in `foreign import prim` which must be fixed
John Ericson's avatar
John Ericson committed
167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185
-- first. Specifically, `foreign import prim` always requires:
--
--   - No polymorphism in type
--   - `strictness       = <default>`
--   - `can_fail         = False`
--   - `has_side_effects = True`
--
-- https://gitlab.haskell.org/ghc/ghc/issues/16929 tracks this issue,
-- and has a table of which external-only primops are blocked by which
-- of these. Hopefully those restrictions are relaxed so the rest of
-- those can be moved over.
--
-- 'module GHC.Prim.Ext is a temporarily "holding ground" for primops
-- that were formally in here, until they can be given a better home.
-- Likewise, their underlying C-- implementation need not live in the
-- RTS either. Best case (in my view), both the C-- and `foreign import
-- prim` can be moved to a small library tailured to the features being
-- implemented and dependencies of those features.

186 187 188
-- Currently, documentation is produced using latex, so contents of
-- description fields should be legal latex. Descriptions can contain
-- matched pairs of embedded curly brackets.
apt's avatar
apt committed
189 190

#include "MachDeps.h"
191

apt's avatar
apt committed
192
section "The word size story."
193 194 195 196 197 198 199
        {Haskell98 specifies that signed integers (type {\tt Int})
         must contain at least 30 bits. GHC always implements {\tt
         Int} using the primitive type {\tt Int\#}, whose size equals
         the {\tt MachDeps.h} constant {\tt WORD\_SIZE\_IN\_BITS}.
         This is normally set based on the {\tt config.h} parameter
         {\tt SIZEOF\_HSWORD}, i.e., 32 bits on 32-bit machines, 64
         bits on 64-bit machines.  However, it can also be explicitly
200
         set to a smaller number than 64, e.g., 62 bits, to allow the
201
         possibility of using tag bits. Currently GHC itself has only
202
         32-bit and 64-bit variants, but 61, 62, or 63-bit code can be
203
         exported as an external core file for use in other back ends.
204
         30 and 31-bit code is no longer supported.
205 206 207 208 209 210 211 212 213 214

         GHC also implements a primitive unsigned integer type {\tt
         Word\#} which always has the same number of bits as {\tt
         Int\#}.

         In addition, GHC supports families of explicit-sized integers
         and words at 8, 16, 32, and 64 bits, with the usual
         arithmetic operations, comparisons, and a range of
         conversions.  The 8-bit and 16-bit sizes are always
         represented as {\tt Int\#} and {\tt Word\#}, and the
215
         operations implemented in terms of the primops on these
216
         types, with suitable range restrictions on the results (using
217 218 219 220 221 222 223 224
         the {\tt narrow$n$Int\#} and {\tt narrow$n$Word\#} families of
         primops.  The 64-bit sizes are represented using {\tt Int\#}
         and {\tt Word\#} when {\tt WORD\_SIZE\_IN\_BITS} $\geq$ 64;
         otherwise, these are represented using distinct primitive
         types {\tt Int64\#} and {\tt Word64\#}. These (when needed)
         have a complete set of corresponding operations; however,
         nearly all of these are implemented as external C functions
         rather than as primops.  All of these details are hidden
225
         under the {\tt PrelInt} and {\tt PrelWord} modules, which use
226
         {\tt \#if}-defs to invoke the appropriate types and operators.
227 228 229 230 231 232 233 234 235 236 237 238 239 240 241

         Word size also matters for the families of primops for
         indexing/reading/writing fixed-size quantities at offsets
         from an array base, address, or foreign pointer.  Here, a
         slightly different approach is taken.  The names of these
         primops are fixed, but their {\it types} vary according to
         the value of {\tt WORD\_SIZE\_IN\_BITS}. For example, if word
         size is at least 32 bits then an operator like
         \texttt{indexInt32Array\#} has type {\tt ByteArray\# -> Int\#
         -> Int\#}; otherwise it has type {\tt ByteArray\# -> Int\# ->
         Int32\#}.  This approach confines the necessary {\tt
         \#if}-defs to this file; no conditional compilation is needed
         in the files that expose these primops.

         Finally, there are strongly deprecated primops for coercing
242 243 244 245 246
         between {\tt Addr\#}, the primitive type of machine
         addresses, and {\tt Int\#}.  These are pretty bogus anyway,
         but will work on existing 32-bit and 64-bit GHC targets; they
         are completely bogus when tag bits are used in {\tt Int\#},
         so are not available in this case.  }
apt's avatar
apt committed
247

Jan Stolarek's avatar
Jan Stolarek committed
248 249
-- Define synonyms for indexing ops.

apt's avatar
apt committed
250 251 252 253 254 255 256
#if WORD_SIZE_IN_BITS < 64
#define INT64 Int64#
#define WORD64 Word64#
#else
#define INT64 Int#
#define WORD64 Word#
#endif
257 258

------------------------------------------------------------------------
259
section "Char#"
260
        {Operations on 31-bit characters.}
261 262
------------------------------------------------------------------------

263
primtype Char#
264

265 266
primop   CharGtOp  "gtChar#"   Compare   Char# -> Char# -> Int#
primop   CharGeOp  "geChar#"   Compare   Char# -> Char# -> Int#
267

268
primop   CharEqOp  "eqChar#"   Compare
269
   Char# -> Char# -> Int#
apt's avatar
apt committed
270
   with commutable = True
271

272
primop   CharNeOp  "neChar#"   Compare
273
   Char# -> Char# -> Int#
apt's avatar
apt committed
274 275
   with commutable = True

276 277
primop   CharLtOp  "ltChar#"   Compare   Char# -> Char# -> Int#
primop   CharLeOp  "leChar#"   Compare   Char# -> Char# -> Int#
apt's avatar
apt committed
278 279

primop   OrdOp   "ord#"  GenPrimOp   Char# -> Int#
280
   with code_size = 0
281

Michal Terepeta's avatar
Michal Terepeta committed
282 283 284 285 286 287 288
------------------------------------------------------------------------
section "Int8#"
        {Operations on 8-bit integers.}
------------------------------------------------------------------------

primtype Int8#

289 290
primop Int8ToIntOp "int8ToInt#" GenPrimOp Int8# -> Int#
primop IntToInt8Op "intToInt8#" GenPrimOp Int# -> Int8#
Michal Terepeta's avatar
Michal Terepeta committed
291

292
primop Int8NegOp "negateInt8#" GenPrimOp Int8# -> Int8#
Michal Terepeta's avatar
Michal Terepeta committed
293

294
primop Int8AddOp "plusInt8#" GenPrimOp Int8# -> Int8# -> Int8#
Michal Terepeta's avatar
Michal Terepeta committed
295 296 297
  with
    commutable = True

298
primop Int8SubOp "subInt8#" GenPrimOp Int8# -> Int8# -> Int8#
Michal Terepeta's avatar
Michal Terepeta committed
299

300
primop Int8MulOp "timesInt8#" GenPrimOp Int8# -> Int8# -> Int8#
Michal Terepeta's avatar
Michal Terepeta committed
301 302 303
  with
    commutable = True

304
primop Int8QuotOp "quotInt8#" GenPrimOp Int8# -> Int8# -> Int8#
Michal Terepeta's avatar
Michal Terepeta committed
305 306 307
  with
    can_fail = True

308
primop Int8RemOp "remInt8#" GenPrimOp Int8# -> Int8# -> Int8#
Michal Terepeta's avatar
Michal Terepeta committed
309 310 311 312 313 314 315
  with
    can_fail = True

primop Int8QuotRemOp "quotRemInt8#" GenPrimOp Int8# -> Int8# -> (# Int8#, Int8# #)
  with
    can_fail = True

316 317 318 319 320 321 322
primop Int8SllOp "uncheckedShiftLInt8#"  GenPrimOp Int8# -> Int# -> Int8#
primop Int8SraOp "uncheckedShiftRAInt8#" GenPrimOp Int8# -> Int# -> Int8#
primop Int8SrlOp "uncheckedShiftRLInt8#" GenPrimOp Int8# -> Int# -> Int8#

primop Int8ToWord8Op "int8ToWord8#" GenPrimOp Int8# -> Word8#
   with code_size = 0

Michal Terepeta's avatar
Michal Terepeta committed
323 324 325 326 327 328 329 330 331
primop Int8EqOp "eqInt8#" Compare Int8# -> Int8# -> Int#
primop Int8GeOp "geInt8#" Compare Int8# -> Int8# -> Int#
primop Int8GtOp "gtInt8#" Compare Int8# -> Int8# -> Int#
primop Int8LeOp "leInt8#" Compare Int8# -> Int8# -> Int#
primop Int8LtOp "ltInt8#" Compare Int8# -> Int8# -> Int#
primop Int8NeOp "neInt8#" Compare Int8# -> Int8# -> Int#

------------------------------------------------------------------------
section "Word8#"
332
        {Operations on 8-bit unsigned words.}
Michal Terepeta's avatar
Michal Terepeta committed
333 334 335 336
------------------------------------------------------------------------

primtype Word8#

337 338
primop Word8ToWordOp "word8ToWord#" GenPrimOp Word8# -> Word#
primop WordToWord8Op "wordToWord8#" GenPrimOp Word# -> Word8#
Michal Terepeta's avatar
Michal Terepeta committed
339

340
primop Word8AddOp "plusWord8#" GenPrimOp Word8# -> Word8# -> Word8#
Michal Terepeta's avatar
Michal Terepeta committed
341 342 343
  with
    commutable = True

344
primop Word8SubOp "subWord8#" GenPrimOp Word8# -> Word8# -> Word8#
Michal Terepeta's avatar
Michal Terepeta committed
345

346
primop Word8MulOp "timesWord8#" GenPrimOp Word8# -> Word8# -> Word8#
Michal Terepeta's avatar
Michal Terepeta committed
347 348 349
  with
    commutable = True

350
primop Word8QuotOp "quotWord8#" GenPrimOp Word8# -> Word8# -> Word8#
Michal Terepeta's avatar
Michal Terepeta committed
351 352 353
  with
    can_fail = True

354
primop Word8RemOp "remWord8#" GenPrimOp Word8# -> Word8# -> Word8#
Michal Terepeta's avatar
Michal Terepeta committed
355 356 357 358 359 360 361
  with
    can_fail = True

primop Word8QuotRemOp "quotRemWord8#" GenPrimOp Word8# -> Word8# -> (# Word8#, Word8# #)
  with
    can_fail = True

362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378
primop Word8AndOp "andWord8#" GenPrimOp Word8# -> Word8# -> Word8#
   with commutable = True

primop Word8OrOp "orWord8#" GenPrimOp Word8# -> Word8# -> Word8#
   with commutable = True

primop Word8XorOp "xorWord8#" GenPrimOp Word8# -> Word8# -> Word8#
   with commutable = True

primop Word8NotOp "notWord8#" GenPrimOp Word8# -> Word8#

primop Word8SllOp "uncheckedShiftLWord8#"  GenPrimOp Word8# -> Int# -> Word8#
primop Word8SrlOp "uncheckedShiftRLWord8#" GenPrimOp Word8# -> Int# -> Word8#

primop Word8ToInt8Op "word8ToInt8#" GenPrimOp Word8# -> Int8#
   with code_size = 0

Michal Terepeta's avatar
Michal Terepeta committed
379 380 381 382 383 384 385
primop Word8EqOp "eqWord8#" Compare Word8# -> Word8# -> Int#
primop Word8GeOp "geWord8#" Compare Word8# -> Word8# -> Int#
primop Word8GtOp "gtWord8#" Compare Word8# -> Word8# -> Int#
primop Word8LeOp "leWord8#" Compare Word8# -> Word8# -> Int#
primop Word8LtOp "ltWord8#" Compare Word8# -> Word8# -> Int#
primop Word8NeOp "neWord8#" Compare Word8# -> Word8# -> Int#

Abhiroop Sarkar's avatar
Abhiroop Sarkar committed
386 387 388 389 390 391 392
------------------------------------------------------------------------
section "Int16#"
        {Operations on 16-bit integers.}
------------------------------------------------------------------------

primtype Int16#

393 394
primop Int16ToIntOp "int16ToInt#" GenPrimOp Int16# -> Int#
primop IntToInt16Op "intToInt16#" GenPrimOp Int# -> Int16#
Abhiroop Sarkar's avatar
Abhiroop Sarkar committed
395

396
primop Int16NegOp "negateInt16#" GenPrimOp Int16# -> Int16#
Abhiroop Sarkar's avatar
Abhiroop Sarkar committed
397

398
primop Int16AddOp "plusInt16#" GenPrimOp Int16# -> Int16# -> Int16#
Abhiroop Sarkar's avatar
Abhiroop Sarkar committed
399 400 401
  with
    commutable = True

402
primop Int16SubOp "subInt16#" GenPrimOp Int16# -> Int16# -> Int16#
Abhiroop Sarkar's avatar
Abhiroop Sarkar committed
403

404
primop Int16MulOp "timesInt16#" GenPrimOp Int16# -> Int16# -> Int16#
Abhiroop Sarkar's avatar
Abhiroop Sarkar committed
405 406 407
  with
    commutable = True

408
primop Int16QuotOp "quotInt16#" GenPrimOp Int16# -> Int16# -> Int16#
Abhiroop Sarkar's avatar
Abhiroop Sarkar committed
409 410 411
  with
    can_fail = True

412
primop Int16RemOp "remInt16#" GenPrimOp Int16# -> Int16# -> Int16#
Abhiroop Sarkar's avatar
Abhiroop Sarkar committed
413 414 415 416 417 418 419
  with
    can_fail = True

primop Int16QuotRemOp "quotRemInt16#" GenPrimOp Int16# -> Int16# -> (# Int16#, Int16# #)
  with
    can_fail = True

420 421 422 423 424 425 426
primop Int16SllOp "uncheckedShiftLInt16#"  GenPrimOp Int16# -> Int# -> Int16#
primop Int16SraOp "uncheckedShiftRAInt16#" GenPrimOp Int16# -> Int# -> Int16#
primop Int16SrlOp "uncheckedShiftRLInt16#" GenPrimOp Int16# -> Int# -> Int16#

primop Int16ToWord16Op "int16ToWord16#" GenPrimOp Int16# -> Word16#
   with code_size = 0

Abhiroop Sarkar's avatar
Abhiroop Sarkar committed
427 428 429 430 431 432 433 434 435
primop Int16EqOp "eqInt16#" Compare Int16# -> Int16# -> Int#
primop Int16GeOp "geInt16#" Compare Int16# -> Int16# -> Int#
primop Int16GtOp "gtInt16#" Compare Int16# -> Int16# -> Int#
primop Int16LeOp "leInt16#" Compare Int16# -> Int16# -> Int#
primop Int16LtOp "ltInt16#" Compare Int16# -> Int16# -> Int#
primop Int16NeOp "neInt16#" Compare Int16# -> Int16# -> Int#

------------------------------------------------------------------------
section "Word16#"
436
        {Operations on 16-bit unsigned words.}
Abhiroop Sarkar's avatar
Abhiroop Sarkar committed
437 438 439 440
------------------------------------------------------------------------

primtype Word16#

441 442
primop Word16ToWordOp "word16ToWord#" GenPrimOp Word16# -> Word#
primop WordToWord16Op "wordToWord16#" GenPrimOp Word# -> Word16#
Abhiroop Sarkar's avatar
Abhiroop Sarkar committed
443

444
primop Word16AddOp "plusWord16#" GenPrimOp Word16# -> Word16# -> Word16#
Abhiroop Sarkar's avatar
Abhiroop Sarkar committed
445 446 447
  with
    commutable = True

448
primop Word16SubOp "subWord16#" GenPrimOp Word16# -> Word16# -> Word16#
Abhiroop Sarkar's avatar
Abhiroop Sarkar committed
449

450
primop Word16MulOp "timesWord16#" GenPrimOp Word16# -> Word16# -> Word16#
Abhiroop Sarkar's avatar
Abhiroop Sarkar committed
451 452 453
  with
    commutable = True

454
primop Word16QuotOp "quotWord16#" GenPrimOp Word16# -> Word16# -> Word16#
Abhiroop Sarkar's avatar
Abhiroop Sarkar committed
455 456 457
  with
    can_fail = True

458
primop Word16RemOp "remWord16#" GenPrimOp Word16# -> Word16# -> Word16#
Abhiroop Sarkar's avatar
Abhiroop Sarkar committed
459 460 461 462 463 464 465
  with
    can_fail = True

primop Word16QuotRemOp "quotRemWord16#" GenPrimOp Word16# -> Word16# -> (# Word16#, Word16# #)
  with
    can_fail = True

466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482
primop Word16AndOp "andWord16#" GenPrimOp Word16# -> Word16# -> Word16#
   with commutable = True

primop Word16OrOp "orWord16#" GenPrimOp Word16# -> Word16# -> Word16#
   with commutable = True

primop Word16XorOp "xorWord16#" GenPrimOp Word16# -> Word16# -> Word16#
   with commutable = True

primop Word16NotOp "notWord16#" GenPrimOp Word16# -> Word16#

primop Word16SllOp "uncheckedShiftLWord16#"  GenPrimOp Word16# -> Int# -> Word16#
primop Word16SrlOp "uncheckedShiftRLWord16#" GenPrimOp Word16# -> Int# -> Word16#

primop Word16ToInt16Op "word16ToInt16#" GenPrimOp Word16# -> Int16#
   with code_size = 0

Abhiroop Sarkar's avatar
Abhiroop Sarkar committed
483 484 485 486 487 488 489
primop Word16EqOp "eqWord16#" Compare Word16# -> Word16# -> Int#
primop Word16GeOp "geWord16#" Compare Word16# -> Word16# -> Int#
primop Word16GtOp "gtWord16#" Compare Word16# -> Word16# -> Int#
primop Word16LeOp "leWord16#" Compare Word16# -> Word16# -> Int#
primop Word16LtOp "ltWord16#" Compare Word16# -> Word16# -> Int#
primop Word16NeOp "neWord16#" Compare Word16# -> Word16# -> Int#

490 491 492 493 494 495 496
------------------------------------------------------------------------
section "Int32#"
        {Operations on 32-bit integers.}
------------------------------------------------------------------------

primtype Int32#

497 498
primop Int32ToIntOp "int32ToInt#" GenPrimOp Int32# -> Int#
primop IntToInt32Op "intToInt32#" GenPrimOp Int# -> Int32#
499

500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537
primop Int32NegOp "negateInt32#" GenPrimOp Int32# -> Int32#

primop Int32AddOp "plusInt32#" GenPrimOp Int32# -> Int32# -> Int32#
  with
    commutable = True

primop Int32SubOp "subInt32#" GenPrimOp Int32# -> Int32# -> Int32#

primop Int32MulOp "timesInt32#" GenPrimOp Int32# -> Int32# -> Int32#
  with
    commutable = True

primop Int32QuotOp "quotInt32#" GenPrimOp Int32# -> Int32# -> Int32#
  with
    can_fail = True

primop Int32RemOp "remInt32#" GenPrimOp Int32# -> Int32# -> Int32#
  with
    can_fail = True

primop Int32QuotRemOp "quotRemInt32#" GenPrimOp Int32# -> Int32# -> (# Int32#, Int32# #)
  with
    can_fail = True

primop Int32SllOp "uncheckedShiftLInt32#"  GenPrimOp Int32# -> Int# -> Int32#
primop Int32SraOp "uncheckedShiftRAInt32#" GenPrimOp Int32# -> Int# -> Int32#
primop Int32SrlOp "uncheckedShiftRLInt32#" GenPrimOp Int32# -> Int# -> Int32#

primop Int32ToWord32Op "int32ToWord32#" GenPrimOp Int32# -> Word32#
   with code_size = 0

primop Int32EqOp "eqInt32#" Compare Int32# -> Int32# -> Int#
primop Int32GeOp "geInt32#" Compare Int32# -> Int32# -> Int#
primop Int32GtOp "gtInt32#" Compare Int32# -> Int32# -> Int#
primop Int32LeOp "leInt32#" Compare Int32# -> Int32# -> Int#
primop Int32LtOp "ltInt32#" Compare Int32# -> Int32# -> Int#
primop Int32NeOp "neInt32#" Compare Int32# -> Int32# -> Int#

538 539
------------------------------------------------------------------------
section "Word32#"
540
        {Operations on 32-bit unsigned words.}
541 542 543 544
------------------------------------------------------------------------

primtype Word32#

545 546
primop Word32ToWordOp "word32ToWord#" GenPrimOp Word32# -> Word#
primop WordToWord32Op "wordToWord32#" GenPrimOp Word# -> Word32#
547

548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578
primop Word32AddOp "plusWord32#" GenPrimOp Word32# -> Word32# -> Word32#
  with
    commutable = True

primop Word32SubOp "subWord32#" GenPrimOp Word32# -> Word32# -> Word32#

primop Word32MulOp "timesWord32#" GenPrimOp Word32# -> Word32# -> Word32#
  with
    commutable = True

primop Word32QuotOp "quotWord32#" GenPrimOp Word32# -> Word32# -> Word32#
  with
    can_fail = True

primop Word32RemOp "remWord32#" GenPrimOp Word32# -> Word32# -> Word32#
  with
    can_fail = True

primop Word32QuotRemOp "quotRemWord32#" GenPrimOp Word32# -> Word32# -> (# Word32#, Word32# #)
  with
    can_fail = True

primop Word32AndOp "andWord32#" GenPrimOp Word32# -> Word32# -> Word32#
   with commutable = True

primop Word32OrOp "orWord32#" GenPrimOp Word32# -> Word32# -> Word32#
   with commutable = True

primop Word32XorOp "xorWord32#" GenPrimOp Word32# -> Word32# -> Word32#
   with commutable = True

579
primop Word32NotOp "notWord32#" GenPrimOp Word32# -> Word32#
580 581 582 583 584 585 586 587 588 589 590 591 592 593

primop Word32SllOp "uncheckedShiftLWord32#"  GenPrimOp Word32# -> Int# -> Word32#
primop Word32SrlOp "uncheckedShiftRLWord32#" GenPrimOp Word32# -> Int# -> Word32#

primop Word32ToInt32Op "word32ToInt32#" GenPrimOp Word32# -> Int32#
   with code_size = 0

primop Word32EqOp "eqWord32#" Compare Word32# -> Word32# -> Int#
primop Word32GeOp "geWord32#" Compare Word32# -> Word32# -> Int#
primop Word32GtOp "gtWord32#" Compare Word32# -> Word32# -> Int#
primop Word32LeOp "leWord32#" Compare Word32# -> Word32# -> Int#
primop Word32LtOp "ltWord32#" Compare Word32# -> Word32# -> Int#
primop Word32NeOp "neWord32#" Compare Word32# -> Word32# -> Int#

594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614
#if WORD_SIZE_IN_BITS < 64
------------------------------------------------------------------------
section "Int64#"
        {Operations on 64-bit unsigned words. This type is only used
         if plain {\tt Int\#} has less than 64 bits. In any case, the operations
         are not primops; they are implemented (if needed) as ccalls instead.}
------------------------------------------------------------------------

primtype Int64#

------------------------------------------------------------------------
section "Word64#"
        {Operations on 64-bit unsigned words. This type is only used
         if plain {\tt Word\#} has less than 64 bits. In any case, the operations
         are not primops; they are implemented (if needed) as ccalls instead.}
------------------------------------------------------------------------

primtype Word64#

#endif

615 616 617 618 619 620 621
------------------------------------------------------------------------
section "Int#"
        {Operations on native-size integers (32+ bits).}
------------------------------------------------------------------------

primtype Int#

622
primop   IntAddOp    "+#"    GenPrimOp
623 624 625 626
   Int# -> Int# -> Int#
   with commutable = True
        fixity = infixl 6

627
primop   IntSubOp    "-#"    GenPrimOp   Int# -> Int# -> Int#
628 629 630
   with fixity = infixl 6

primop   IntMulOp    "*#"
631
   GenPrimOp   Int# -> Int# -> Int#
632 633 634 635 636 637 638 639 640 641 642 643
   {Low word of signed integer multiply.}
   with commutable = True
        fixity = infixl 7

primop   IntMul2Op    "timesInt2#" GenPrimOp
   Int# -> Int# -> (# Int#, Int#, Int# #)
   {Return a triple (isHighNeeded,high,low) where high and low are respectively
   the high and low bits of the double-word result. isHighNeeded is a cheap way
   to test if the high word is a sign-extension of the low word (isHighNeeded =
   0#) or not (isHighNeeded = 1#).}

primop   IntMulMayOfloOp  "mulIntMayOflo#"
644
   GenPrimOp   Int# -> Int# -> Int#
645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666
   {Return non-zero if there is any possibility that the upper word of a
    signed integer multiply might contain useful information.  Return
    zero only if you are completely sure that no overflow can occur.
    On a 32-bit platform, the recommended implementation is to do a
    32 x 32 -> 64 signed multiply, and subtract result[63:32] from
    (result[31] >>signed 31).  If this is zero, meaning that the
    upper word is merely a sign extension of the lower one, no
    overflow can occur.

    On a 64-bit platform it is not always possible to
    acquire the top 64 bits of the result.  Therefore, a recommended
    implementation is to take the absolute value of both operands, and
    return 0 iff bits[63:31] of them are zero, since that means that their
    magnitudes fit within 31 bits, so the magnitude of the product must fit
    into 62 bits.

    If in doubt, return non-zero, but do make an effort to create the
    correct answer for small args, since otherwise the performance of
    \texttt{(*) :: Integer -> Integer -> Integer} will be poor.
   }
   with commutable = True

667
primop   IntQuotOp    "quotInt#"    GenPrimOp
668 669 670 671 672 673
   Int# -> Int# -> Int#
   {Rounds towards zero. The behavior is undefined if the second argument is
    zero.
   }
   with can_fail = True

674
primop   IntRemOp    "remInt#"    GenPrimOp
675 676 677 678 679 680 681 682 683 684 685
   Int# -> Int# -> Int#
   {Satisfies \texttt{(quotInt\# x y) *\# y +\# (remInt\# x y) == x}. The
    behavior is undefined if the second argument is zero.
   }
   with can_fail = True

primop   IntQuotRemOp "quotRemInt#"    GenPrimOp
   Int# -> Int# -> (# Int#, Int# #)
   {Rounds towards zero.}
   with can_fail = True

686
primop   IntAndOp   "andI#"   GenPrimOp    Int# -> Int# -> Int#
687 688 689
   {Bitwise "and".}
   with commutable = True

690
primop   IntOrOp   "orI#"     GenPrimOp    Int# -> Int# -> Int#
691 692 693
   {Bitwise "or".}
   with commutable = True

694
primop   IntXorOp   "xorI#"   GenPrimOp    Int# -> Int# -> Int#
695 696 697
   {Bitwise "xor".}
   with commutable = True

698
primop   IntNotOp   "notI#"   GenPrimOp   Int# -> Int#
699 700
   {Bitwise "not", also known as the binary complement.}

701
primop   IntNegOp    "negateInt#"    GenPrimOp   Int# -> Int#
702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748
   {Unary negation.
    Since the negative {\tt Int#} range extends one further than the
    positive range, {\tt negateInt#} of the most negative number is an
    identity operation. This way, {\tt negateInt#} is always its own inverse.}

primop   IntAddCOp   "addIntC#"    GenPrimOp   Int# -> Int# -> (# Int#, Int# #)
         {Add signed integers reporting overflow.
          First member of result is the sum truncated to an {\tt Int#};
          second member is zero if the true sum fits in an {\tt Int#},
          nonzero if overflow occurred (the sum is either too large
          or too small to fit in an {\tt Int#}).}
   with code_size = 2
        commutable = True

primop   IntSubCOp   "subIntC#"    GenPrimOp   Int# -> Int# -> (# Int#, Int# #)
         {Subtract signed integers reporting overflow.
          First member of result is the difference truncated to an {\tt Int#};
          second member is zero if the true difference fits in an {\tt Int#},
          nonzero if overflow occurred (the difference is either too large
          or too small to fit in an {\tt Int#}).}
   with code_size = 2

primop   IntGtOp  ">#"   Compare   Int# -> Int# -> Int#
   with fixity = infix 4

primop   IntGeOp  ">=#"   Compare   Int# -> Int# -> Int#
   with fixity = infix 4

primop   IntEqOp  "==#"   Compare
   Int# -> Int# -> Int#
   with commutable = True
        fixity = infix 4

primop   IntNeOp  "/=#"   Compare
   Int# -> Int# -> Int#
   with commutable = True
        fixity = infix 4

primop   IntLtOp  "<#"   Compare   Int# -> Int# -> Int#
   with fixity = infix 4

primop   IntLeOp  "<=#"   Compare   Int# -> Int# -> Int#
   with fixity = infix 4

primop   ChrOp   "chr#"   GenPrimOp   Int# -> Char#
   with code_size = 0

749
primop   IntToWordOp "int2Word#" GenPrimOp Int# -> Word#
750 751
   with code_size = 0

752
primop   IntToFloatOp   "int2Float#"      GenPrimOp  Int# -> Float#
753 754 755
   {Convert an {\tt Int#} to the corresponding {\tt Float#} with the same
    integral value (up to truncation due to floating-point precision). e.g.
    {\tt int2Float# 1# == 1.0#}}
756
primop   IntToDoubleOp   "int2Double#"          GenPrimOp  Int# -> Double#
757 758 759
   {Convert an {\tt Int#} to the corresponding {\tt Double#} with the same
    integral value (up to truncation due to floating-point precision). e.g.
    {\tt int2Double# 1# == 1.0##}}
760

761
primop   WordToFloatOp   "word2Float#"      GenPrimOp  Word# -> Float#
762 763 764
   {Convert an {\tt Word#} to the corresponding {\tt Float#} with the same
    integral value (up to truncation due to floating-point precision). e.g.
    {\tt word2Float# 1## == 1.0#}}
765
primop   WordToDoubleOp   "word2Double#"          GenPrimOp  Word# -> Double#
766 767 768
   {Convert an {\tt Word#} to the corresponding {\tt Double#} with the same
    integral value (up to truncation due to floating-point precision). e.g.
    {\tt word2Double# 1## == 1.0##}}
769

770
primop   IntSllOp   "uncheckedIShiftL#" GenPrimOp  Int# -> Int# -> Int#
771 772
         {Shift left.  Result undefined if shift amount is not
          in the range 0 to word size - 1 inclusive.}
773
primop   IntSraOp   "uncheckedIShiftRA#" GenPrimOp Int# -> Int# -> Int#
774 775
         {Shift right arithmetic.  Result undefined if shift amount is not
          in the range 0 to word size - 1 inclusive.}
776
primop   IntSrlOp   "uncheckedIShiftRL#" GenPrimOp Int# -> Int# -> Int#
777 778 779
         {Shift right logical.  Result undefined if shift amount is not
          in the range 0 to word size - 1 inclusive.}

780
------------------------------------------------------------------------
apt's avatar
apt committed
781
section "Word#"
782
        {Operations on native-sized unsigned words (32+ bits).}
783 784
------------------------------------------------------------------------

785 786
primtype Word#

787
primop   WordAddOp   "plusWord#"   GenPrimOp   Word# -> Word# -> Word#
apt's avatar
apt committed
788
   with commutable = True
789

Sebastian Graf's avatar
Sebastian Graf committed
790 791 792 793 794 795 796
primop   WordAddCOp   "addWordC#"   GenPrimOp   Word# -> Word# -> (# Word#, Int# #)
         {Add unsigned integers reporting overflow.
          The first element of the pair is the result.  The second element is
          the carry flag, which is nonzero on overflow. See also {\tt plusWord2#}.}
   with code_size = 2
        commutable = True

nkaretnikov's avatar
nkaretnikov committed
797 798 799 800
primop   WordSubCOp   "subWordC#"   GenPrimOp   Word# -> Word# -> (# Word#, Int# #)
         {Subtract unsigned integers reporting overflow.
          The first element of the pair is the result.  The second element is
          the carry flag, which is nonzero on overflow.}
Sebastian Graf's avatar
Sebastian Graf committed
801
   with code_size = 2
nkaretnikov's avatar
nkaretnikov committed
802

Sebastian Graf's avatar
Sebastian Graf committed
803 804 805 806 807 808
primop   WordAdd2Op   "plusWord2#"   GenPrimOp   Word# -> Word# -> (# Word#, Word# #)
         {Add unsigned integers, with the high part (carry) in the first
          component of the returned pair and the low part in the second
          component of the pair. See also {\tt addWordC#}.}
   with code_size = 2
        commutable = True
Ian Lynagh's avatar
Ian Lynagh committed
809

810
primop   WordSubOp   "minusWord#"   GenPrimOp   Word# -> Word# -> Word#
apt's avatar
apt committed
811

812
primop   WordMulOp   "timesWord#"   GenPrimOp   Word# -> Word# -> Word#
813 814
   with commutable = True

Ian Lynagh's avatar
Ian Lynagh committed
815
-- Returns (# high, low #)
Ian Lynagh's avatar
Ian Lynagh committed
816 817 818 819
primop   WordMul2Op  "timesWord2#"   GenPrimOp
   Word# -> Word# -> (# Word#, Word# #)
   with commutable = True

820
primop   WordQuotOp   "quotWord#"   GenPrimOp   Word# -> Word# -> Word#
apt's avatar
apt committed
821 822
   with can_fail = True

823
primop   WordRemOp   "remWord#"   GenPrimOp   Word# -> Word# -> Word#
apt's avatar
apt committed
824 825
   with can_fail = True

826 827 828 829
primop   WordQuotRemOp "quotRemWord#" GenPrimOp
   Word# -> Word# -> (# Word#, Word# #)
   with can_fail = True

Ian Lynagh's avatar
Ian Lynagh committed
830 831
primop   WordQuotRem2Op "quotRemWord2#" GenPrimOp
   Word# -> Word# -> Word# -> (# Word#, Word# #)
832 833
         { Takes high word of dividend, then low word of dividend, then divisor.
           Requires that high word < divisor.}
Ian Lynagh's avatar
Ian Lynagh committed
834 835
   with can_fail = True

836
primop   WordAndOp   "and#"   GenPrimOp   Word# -> Word# -> Word#
837 838
   with commutable = True

839
primop   WordOrOp   "or#"   GenPrimOp   Word# -> Word# -> Word#
apt's avatar
apt committed
840 841
   with commutable = True

842
primop   WordXorOp   "xor#"   GenPrimOp   Word# -> Word# -> Word#
apt's avatar
apt committed
843 844
   with commutable = True

845
primop   WordNotOp   "not#"   GenPrimOp   Word# -> Word#
apt's avatar
apt committed
846

847
primop   WordSllOp   "uncheckedShiftL#"   GenPrimOp   Word# -> Int# -> Word#
848
         {Shift left logical.   Result undefined if shift amount is not
849
          in the range 0 to word size - 1 inclusive.}
850
primop   WordSrlOp   "uncheckedShiftRL#"   GenPrimOp   Word# -> Int# -> Word#
851
         {Shift right logical.   Result undefined if shift  amount is not
852
          in the range 0 to word size - 1 inclusive.}
apt's avatar
apt committed
853

854
primop   WordToIntOp   "word2Int#"   GenPrimOp   Word# -> Int#
855
   with code_size = 0
apt's avatar
apt committed
856

857 858 859 860 861 862
primop   WordGtOp   "gtWord#"   Compare   Word# -> Word# -> Int#
primop   WordGeOp   "geWord#"   Compare   Word# -> Word# -> Int#
primop   WordEqOp   "eqWord#"   Compare   Word# -> Word# -> Int#
primop   WordNeOp   "neWord#"   Compare   Word# -> Word# -> Int#
primop   WordLtOp   "ltWord#"   Compare   Word# -> Word# -> Int#
primop   WordLeOp   "leWord#"   Compare   Word# -> Word# -> Int#
apt's avatar
apt committed
863

864
primop   PopCnt8Op   "popCnt8#"   GenPrimOp   Word# -> Word#
tibbe's avatar
tibbe committed
865
    {Count the number of set bits in the lower 8 bits of a word.}
866
primop   PopCnt16Op   "popCnt16#"   GenPrimOp   Word# -> Word#
tibbe's avatar
tibbe committed
867
    {Count the number of set bits in the lower 16 bits of a word.}
868
primop   PopCnt32Op   "popCnt32#"   GenPrimOp   Word# -> Word#
tibbe's avatar
tibbe committed
869
    {Count the number of set bits in the lower 32 bits of a word.}
Simon Marlow's avatar
Simon Marlow committed
870
primop   PopCnt64Op   "popCnt64#"   GenPrimOp   WORD64 -> Word#
tibbe's avatar
tibbe committed
871
    {Count the number of set bits in a 64-bit word.}
872
primop   PopCntOp   "popCnt#"   GenPrimOp   Word# -> Word#
tibbe's avatar
tibbe committed
873 874
    {Count the number of set bits in a word.}

875
primop   Pdep8Op   "pdep8#"   GenPrimOp   Word# -> Word# -> Word#
876
    {Deposit bits to lower 8 bits of a word at locations specified by a mask.}
877
primop   Pdep16Op   "pdep16#"   GenPrimOp   Word# -> Word# -> Word#
878
    {Deposit bits to lower 16 bits of a word at locations specified by a mask.}
879
primop   Pdep32Op   "pdep32#"   GenPrimOp   Word# -> Word# -> Word#
880 881 882
    {Deposit bits to lower 32 bits of a word at locations specified by a mask.}
primop   Pdep64Op   "pdep64#"   GenPrimOp   WORD64 -> WORD64 -> WORD64
    {Deposit bits to a word at locations specified by a mask.}
883
primop   PdepOp   "pdep#"   GenPrimOp   Word# -> Word# -> Word#
884 885
    {Deposit bits to a word at locations specified by a mask.}

886
primop   Pext8Op   "pext8#"   GenPrimOp   Word# -> Word# -> Word#
887
    {Extract bits from lower 8 bits of a word at locations specified by a mask.}
888
primop   Pext16Op   "pext16#"   GenPrimOp   Word# -> Word# -> Word#
889
    {Extract bits from lower 16 bits of a word at locations specified by a mask.}
890
primop   Pext32Op   "pext32#"   GenPrimOp   Word# -> Word# -> Word#
891 892 893
    {Extract bits from lower 32 bits of a word at locations specified by a mask.}
primop   Pext64Op   "pext64#"   GenPrimOp   WORD64 -> WORD64 -> WORD64
    {Extract bits from a word at locations specified by a mask.}
894
primop   PextOp   "pext#"   GenPrimOp   Word# -> Word# -> Word#
895 896
    {Extract bits from a word at locations specified by a mask.}

897
primop   Clz8Op   "clz8#" GenPrimOp   Word# -> Word#
898
    {Count leading zeros in the lower 8 bits of a word.}
899
primop   Clz16Op   "clz16#" GenPrimOp   Word# -> Word#
900
    {Count leading zeros in the lower 16 bits of a word.}
901
primop   Clz32Op   "clz32#" GenPrimOp   Word# -> Word#
902 903 904
    {Count leading zeros in the lower 32 bits of a word.}
primop   Clz64Op   "clz64#" GenPrimOp WORD64 -> Word#
    {Count leading zeros in a 64-bit word.}
905
primop   ClzOp     "clz#"   GenPrimOp   Word# -> Word#
906 907
    {Count leading zeros in a word.}

908
primop   Ctz8Op   "ctz8#"  GenPrimOp   Word# -> Word#
909
    {Count trailing zeros in the lower 8 bits of a word.}
910
primop   Ctz16Op   "ctz16#" GenPrimOp   Word# -> Word#
911
    {Count trailing zeros in the lower 16 bits of a word.}
912
primop   Ctz32Op   "ctz32#" GenPrimOp   Word# -> Word#
913 914 915
    {Count trailing zeros in the lower 32 bits of a word.}
primop   Ctz64Op   "ctz64#" GenPrimOp WORD64 -> Word#
    {Count trailing zeros in a 64-bit word.}
916
primop   CtzOp     "ctz#"   GenPrimOp   Word# -> Word#
917 918
    {Count trailing zeros in a word.}

919
primop   BSwap16Op   "byteSwap16#"   GenPrimOp   Word# -> Word#
920
    {Swap bytes in the lower 16 bits of a word. The higher bytes are undefined. }
921
primop   BSwap32Op   "byteSwap32#"   GenPrimOp   Word# -> Word#
922
    {Swap bytes in the lower 32 bits of a word. The higher bytes are undefined. }
923
primop   BSwap64Op   "byteSwap64#"   GenPrimOp   WORD64 -> WORD64
924
    {Swap bytes in a 64 bits of a word.}
925
primop   BSwapOp     "byteSwap#"     GenPrimOp   Word# -> Word#
926 927
    {Swap bytes in a word.}

928
primop   BRev8Op    "bitReverse8#"   GenPrimOp   Word# -> Word#
929
    {Reverse the order of the bits in a 8-bit word.}
930
primop   BRev16Op   "bitReverse16#"   GenPrimOp   Word# -> Word#
931
    {Reverse the order of the bits in a 16-bit word.}
932
primop   BRev32Op   "bitReverse32#"   GenPrimOp   Word# -> Word#
933
    {Reverse the order of the bits in a 32-bit word.}
934
primop   BRev64Op   "bitReverse64#"   GenPrimOp   WORD64 -> WORD64
935
    {Reverse the order of the bits in a 64-bit word.}
936
primop   BRevOp     "bitReverse#"     GenPrimOp   Word# -> Word#
937 938
    {Reverse the order of the bits in a word.}

apt's avatar
apt committed
939
------------------------------------------------------------------------
Jan Stolarek's avatar
Jan Stolarek committed
940
section "Narrowings"
941
        {Explicit narrowing of native-sized ints or words.}
apt's avatar
apt committed
942 943
------------------------------------------------------------------------

944 945 946 947 948 949
primop   Narrow8IntOp      "narrow8Int#"      GenPrimOp   Int# -> Int#
primop   Narrow16IntOp     "narrow16Int#"     GenPrimOp   Int# -> Int#
primop   Narrow32IntOp     "narrow32Int#"     GenPrimOp   Int# -> Int#
primop   Narrow8WordOp     "narrow8Word#"     GenPrimOp   Word# -> Word#
primop   Narrow16WordOp    "narrow16Word#"    GenPrimOp   Word# -> Word#
primop   Narrow32WordOp    "narrow32Word#"    GenPrimOp   Word# -> Word#
apt's avatar
apt committed
950

951
------------------------------------------------------------------------
apt's avatar
apt committed
952
section "Double#"
953
        {Operations on double-precision (64 bit) floating-point numbers.}
954 955
------------------------------------------------------------------------

956 957
primtype Double#

958
primop   DoubleGtOp ">##"   Compare   Double# -> Double# -> Int#
959 960
   with fixity = infix 4

961
primop   DoubleGeOp ">=##"   Compare   Double# -> Double# -> Int#
962
   with fixity = infix 4
963

964
primop DoubleEqOp "==##"   Compare
965
   Double# -> Double# -> Int#
966
   with commutable = True
967
        fixity = infix 4
968

969
primop DoubleNeOp "/=##"   Compare
970
   Double# -> Double# -> Int#
971
   with commutable = True
972
        fixity = infix 4
973

974
primop   DoubleLtOp "<##"   Compare   Double# -> Double# -> Int#
975 976
   with fixity = infix 4

977
primop   DoubleLeOp "<=##"   Compare   Double# -> Double# -> Int#
978
   with fixity = infix 4
979

980
primop   DoubleAddOp   "+##"   GenPrimOp
981 982
   Double# -> Double# -> Double#
   with commutable = True
983
        fixity = infixl 6
984

985
primop   DoubleSubOp   "-##"   GenPrimOp   Double# -> Double# -> Double#
986
   with fixity = infixl 6
987

988
primop   DoubleMulOp   "*##"   GenPrimOp
989