[Git][ghc/ghc][wip/ghci-primcall] Add PrimCallConv support to GHCi

Luite Stegeman (@luite) gitlab at gitlab.haskell.org
Mon Jan 9 16:33:40 UTC 2023



Luite Stegeman pushed to branch wip/ghci-primcall at Glasgow Haskell Compiler / GHC


Commits:
00577d1a by Luite Stegeman at 2023-01-10T01:31:36+09:00
Add PrimCallConv support to GHCi

This adds support for calling Cmm code from bytecode using the native
calling convention, allowing modules that use `foreign import prim`
to be loaded and debugged in GHCi.

This patch introduces a new `PRIMCALL` bytecode instruction and
a helper stack frame `stg_primcall`. The code is based on the
existing functionality for dealing with unboxed tuples in bytecode,
which has been generalised to handle arbitrary calls.

Fixes #22051

- - - - -


21 changed files:

- compiler/GHC/ByteCode/Asm.hs
- compiler/GHC/ByteCode/Instr.hs
- compiler/GHC/ByteCode/Types.hs
- compiler/GHC/Cmm/CallConv.hs
- compiler/GHC/Cmm/Parser.y
- compiler/GHC/Cmm/Reg.hs
- compiler/GHC/StgToByteCode.hs
- compiler/GHC/StgToCmm/Foreign.hs
- rts/Disassembler.c
- rts/Interpreter.c
- rts/RtsSymbols.c
- rts/StgMiscClosures.cmm
- rts/include/rts/Bytecodes.h
- rts/include/stg/MiscClosures.h
- testsuite/tests/ghci/prog014/prog014.T
- + testsuite/tests/ghci/should_run/GHCiPrimCall/GHCiPrimCall.hs
- + testsuite/tests/ghci/should_run/GHCiPrimCall/GHCiPrimCall.stdout
- + testsuite/tests/ghci/should_run/GHCiPrimCall/GHCiPrimCall.stdout-ws-32
- + testsuite/tests/ghci/should_run/GHCiPrimCall/GHCiPrimCall_cmm.cmm
- + testsuite/tests/ghci/should_run/GHCiPrimCall/Makefile
- + testsuite/tests/ghci/should_run/GHCiPrimCall/all.T


Changes:

=====================================
compiler/GHC/ByteCode/Asm.hs
=====================================
@@ -12,7 +12,7 @@ module GHC.ByteCode.Asm (
         bcoFreeNames,
         SizedSeq, sizeSS, ssElts,
         iNTERP_STACK_CHECK_THRESH,
-        mkTupleInfoLit
+        mkNativeCallInfoLit
   ) where
 
 import GHC.Prelude
@@ -32,7 +32,6 @@ import GHC.Types.Unique.DSet
 
 import GHC.Utils.Outputable
 import GHC.Utils.Panic
-import GHC.Utils.Panic.Plain
 
 import GHC.Core.TyCon
 import GHC.Data.FastString
@@ -40,7 +39,7 @@ import GHC.Data.SizedSeq
 
 import GHC.StgToCmm.Layout     ( ArgRep(..) )
 import GHC.Cmm.Expr
-import GHC.Cmm.CallConv        ( tupleRegsCover )
+import GHC.Cmm.CallConv        ( allArgRegsCover )
 import GHC.Platform
 import GHC.Platform.Profile
 
@@ -202,7 +201,8 @@ assembleBCO platform (ProtoBCO { protoBCOName       = nm
   (final_insns, final_lits, final_ptrs) <- flip execStateT initial_state $ runAsm platform long_jumps env asm
 
   -- precomputed size should be equal to final size
-  massert (n_insns == sizeSS final_insns)
+  massertPpr (n_insns == sizeSS final_insns)
+             (text "bytecode instruction count mismatch")
 
   let asm_insns = ssElts final_insns
       insns_arr = Array.listArray (0, fromIntegral n_insns - 1) asm_insns
@@ -351,7 +351,8 @@ largeArg platform w = case platformWordSize platform of
            fromIntegral (w `shiftR` 32),
            fromIntegral (w `shiftR` 16),
            fromIntegral w]
-   PW4 -> assert (w < fromIntegral (maxBound :: Word32)) $
+   PW4 -> assertPpr (w < fromIntegral (maxBound :: Word32))
+                    (text "largeArg too big:" <+> ppr w) $
           [fromIntegral (w `shiftR` 16),
            fromIntegral w]
 
@@ -388,14 +389,14 @@ assembleI platform i = case i of
                            -> do let ul_bco = assembleBCO platform proto
                                  p <- ioptr (liftM BCOPtrBCO ul_bco)
                                  emit (push_alts pk) [Op p]
-  PUSH_ALTS_TUPLE proto tuple_info tuple_proto
+  PUSH_ALTS_TUPLE proto call_info tuple_proto
                            -> do let ul_bco = assembleBCO platform proto
                                      ul_tuple_bco = assembleBCO platform
                                                                 tuple_proto
                                  p <- ioptr (liftM BCOPtrBCO ul_bco)
                                  p_tup <- ioptr (liftM BCOPtrBCO ul_tuple_bco)
                                  info <- int (fromIntegral $
-                                              mkTupleInfoSig platform tuple_info)
+                                              mkNativeCallInfoSig platform call_info)
                                  emit bci_PUSH_ALTS_T
                                       [Op p, Op info, Op p_tup]
   PUSH_PAD8                -> emit bci_PUSH_PAD8 []
@@ -491,6 +492,7 @@ assembleI platform i = case i of
   RETURN_TUPLE             -> emit bci_RETURN_T []
   CCALL off m_addr i       -> do np <- addr m_addr
                                  emit bci_CCALL [SmallOp off, Op np, SmallOp i]
+  PRIMCALL                 -> emit bci_PRIMCALL []
   BRK_FUN index uniq cc    -> do p1 <- ptr BCOPtrBreakArray
                                  q <- int (getKey uniq)
                                  np <- addr cc
@@ -582,39 +584,47 @@ return_unlifted V64 = error "return_unlifted: vector"
   platform).
 
  -}
-maxTupleNativeStackSize :: WordOff
-maxTupleNativeStackSize = 62
+maxTupleReturnNativeStackSize :: WordOff
+maxTupleReturnNativeStackSize = 62
+
+maxPrimCallNativeStackSize :: WordOff
+maxPrimCallNativeStackSize = 255
 
 {-
-  Construct the tuple_info word that stg_ctoi_t and stg_ret_t use
-  to convert a tuple between the native calling convention and the
+  Construct the call_info word that stg_ctoi_t, stg_ret_t and stg_primcall
+  use to convert arguments between the native calling convention and the
   interpreter.
 
-  See Note [GHCi tuple layout] for more information.
+  See Note [GHCi and native call registers] for more information.
  -}
-mkTupleInfoSig :: Platform -> TupleInfo -> Word32
-mkTupleInfoSig platform TupleInfo{..}
-  | tupleNativeStackSize > maxTupleNativeStackSize
-  = pprPanic "mkTupleInfoSig: tuple too big for the bytecode compiler"
-             (ppr tupleNativeStackSize <+> text "stack words." <+>
+mkNativeCallInfoSig :: Platform -> NativeCallInfo -> Word32
+mkNativeCallInfoSig platform NativeCallInfo{..}
+  | nativeCallType == NativePrimCall && nativeCallStackSpillSize > maxPrimCallNativeStackSize
+  = pprPanic "mkNativeCallInfoSig: native call too big for the bytecode compiler"
+             (ppr nativeCallStackSpillSize <+> text "stack words." <+>
+              text "Use -fobject-code to get around this limit"
+             )
+  | nativeCallType == NativeTupleReturn && nativeCallStackSpillSize > maxTupleReturnNativeStackSize
+  = pprPanic "mkNativeCallInfoSig: tuple too big for the bytecode compiler"
+             (ppr nativeCallStackSpillSize <+> text "stack words." <+>
               text "Use -fobject-code to get around this limit"
              )
   | otherwise
-  = assert (length regs <= 24) {- 24 bits for bitmap -}
-    assert (tupleNativeStackSize < 255) {- 8 bits for stack size -}
-    assert (all (`elem` regs) (regSetToList tupleRegs)) {- all regs accounted for -}
+  = assertPpr (length regs <= 24) (text "too many registers for bitmap:" <+> ppr (length regs)) {- 24 bits for bitmap -}
+    assertPpr (nativeCallStackSpillSize < 255) (text "stack spill size too large:" <+> ppr nativeCallStackSpillSize) {- 8 bits for stack size -}
+    assertPpr (all (`elem` regs) (regSetToList nativeCallRegs)) (text "not all registers accounted for") {- all regs accounted for -}
     foldl' reg_bit 0 (zip regs [0..]) .|.
-      (fromIntegral tupleNativeStackSize `shiftL` 24)
+      (fromIntegral nativeCallStackSpillSize `shiftL` 24)
   where
     reg_bit :: Word32 -> (GlobalReg, Int) -> Word32
     reg_bit x (r, n)
-      | r `elemRegSet` tupleRegs = x .|. 1 `shiftL` n
-      | otherwise                = x
-    regs = tupleRegsCover platform
+      | r `elemRegSet` nativeCallRegs = x .|. 1 `shiftL` n
+      | otherwise                     = x
+    regs = allArgRegsCover platform
 
-mkTupleInfoLit :: Platform -> TupleInfo -> Literal
-mkTupleInfoLit platform tuple_info =
-  mkLitWord platform . fromIntegral $ mkTupleInfoSig platform tuple_info
+mkNativeCallInfoLit :: Platform -> NativeCallInfo -> Literal
+mkNativeCallInfoLit platform call_info =
+  mkLitWord platform . fromIntegral $ mkNativeCallInfoSig platform call_info
 
 -- Make lists of host-sized words for literals, so that when the
 -- words are placed in memory at increasing addresses, the


=====================================
compiler/GHC/ByteCode/Instr.hs
=====================================
@@ -90,7 +90,7 @@ data BCInstr
    | PUSH_ALTS          (ProtoBCO Name)
    | PUSH_ALTS_UNLIFTED (ProtoBCO Name) ArgRep
    | PUSH_ALTS_TUPLE    (ProtoBCO Name) -- continuation
-                        !TupleInfo
+                        !NativeCallInfo
                         (ProtoBCO Name) -- tuple return BCO
 
    -- Pushing 8, 16 and 32 bits of padding (for constructors).
@@ -184,6 +184,8 @@ data BCInstr
                                 -- (XXX: inefficient, but I don't know
                                 -- what the alignment constraints are.)
 
+   | PRIMCALL
+
    -- For doing magic ByteArray passing to foreign calls
    | SWIZZLE          Word16 -- to the ptr N words down the stack,
                       Word16 -- add M (interpreted as a signed 16-bit entity)
@@ -269,8 +271,8 @@ instance Outputable BCInstr where
 
    ppr (PUSH_ALTS bco)       = hang (text "PUSH_ALTS") 2 (ppr bco)
    ppr (PUSH_ALTS_UNLIFTED bco pk) = hang (text "PUSH_ALTS_UNLIFTED" <+> ppr pk) 2 (ppr bco)
-   ppr (PUSH_ALTS_TUPLE bco tuple_info tuple_bco) =
-                               hang (text "PUSH_ALTS_TUPLE" <+> ppr tuple_info)
+   ppr (PUSH_ALTS_TUPLE bco call_info tuple_bco) =
+                               hang (text "PUSH_ALTS_TUPLE" <+> ppr call_info)
                                     2
                                     (ppr tuple_bco $+$ ppr bco)
 
@@ -340,6 +342,7 @@ instance Outputable BCInstr where
                                                       0x1 -> text "(interruptible)"
                                                       0x2 -> text "(unsafe)"
                                                       _   -> empty)
+   ppr PRIMCALL              = text "PRIMCALL"
    ppr (SWIZZLE stkoff n)    = text "SWIZZLE " <+> text "stkoff" <+> ppr stkoff
                                                <+> text "by" <+> ppr n
    ppr ENTER                 = text "ENTER"
@@ -382,11 +385,11 @@ bciStackUse (PUSH_ALTS bco)       = 2 {- profiling only, restore CCCS -} +
 bciStackUse (PUSH_ALTS_UNLIFTED bco _) = 2 {- profiling only, restore CCCS -} +
                                          4 + protoBCOStackUse bco
 bciStackUse (PUSH_ALTS_TUPLE bco info _) =
-   -- (tuple_bco, tuple_info word, cont_bco, stg_ctoi_t)
+   -- (tuple_bco, call_info word, cont_bco, stg_ctoi_t)
    -- tuple
-   -- (tuple_info, tuple_bco, stg_ret_t)
+   -- (call_info, tuple_bco, stg_ret_t)
    1 {- profiling only -} +
-   7 + fromIntegral (tupleSize info) + protoBCOStackUse bco
+   7 + fromIntegral (nativeCallSize info) + protoBCOStackUse bco
 bciStackUse (PUSH_PAD8)           = 1  -- overapproximation
 bciStackUse (PUSH_PAD16)          = 1  -- overapproximation
 bciStackUse (PUSH_PAD32)          = 1  -- overapproximation on 64bit arch
@@ -443,6 +446,7 @@ bciStackUse RETURN{}              = 0
 bciStackUse RETURN_UNLIFTED{}     = 1 -- pushes stg_ret_X for some X
 bciStackUse RETURN_TUPLE{}        = 1 -- pushes stg_ret_t header
 bciStackUse CCALL{}               = 0
+bciStackUse PRIMCALL{}            = 1 -- pushes stg_primcall
 bciStackUse SWIZZLE{}             = 0
 bciStackUse BRK_FUN{}             = 0
 


=====================================
compiler/GHC/ByteCode/Types.hs
=====================================
@@ -10,7 +10,7 @@ module GHC.ByteCode.Types
   ( CompiledByteCode(..), seqCompiledByteCode
   , FFIInfo(..)
   , RegBitmap(..)
-  , TupleInfo(..), voidTupleInfo
+  , NativeCallType(..), NativeCallInfo(..), voidTupleReturnInfo, voidPrimCallInfo
   , ByteOff(..), WordOff(..)
   , UnlinkedBCO(..), BCOPtr(..), BCONPtr(..)
   , ItblEnv, ItblPtr(..)
@@ -105,22 +105,32 @@ newtype RegBitmap = RegBitmap { unRegBitmap :: Word32 }
 
    See GHC.StgToByteCode.layoutTuple for more details.
 -}
-data TupleInfo = TupleInfo
-  { tupleSize            :: !WordOff   -- total size of tuple in words
-  , tupleRegs            :: !GlobalRegSet
-  , tupleNativeStackSize :: !WordOff {- words spilled on the stack by
-                                        GHCs native calling convention -}
-  } deriving (Show)
-
-instance Outputable TupleInfo where
-  ppr TupleInfo{..} = text "<size" <+> ppr tupleSize <+>
-                      text "stack" <+> ppr tupleNativeStackSize <+>
-                      text "regs"  <+>
-                      ppr (map (text @SDoc . show) $ regSetToList tupleRegs) <>
-                      char '>'
-
-voidTupleInfo :: TupleInfo
-voidTupleInfo = TupleInfo 0 emptyRegSet 0
+
+data NativeCallType = NativePrimCall
+                    | NativeTupleReturn
+  deriving (Eq)
+
+data NativeCallInfo = NativeCallInfo
+  { nativeCallType           :: !NativeCallType
+  , nativeCallSize           :: !WordOff   -- total size of arguments in words
+  , nativeCallRegs           :: !GlobalRegSet
+  , nativeCallStackSpillSize :: !WordOff {- words spilled on the stack by
+                                            GHCs native calling convention -}
+  }
+
+instance Outputable NativeCallInfo where
+  ppr NativeCallInfo{..} = text "<arg_size" <+> ppr nativeCallSize <+>
+                           text "stack" <+> ppr nativeCallStackSpillSize <+>
+                           text "regs"  <+>
+                           ppr (map (text @SDoc . show) $ regSetToList nativeCallRegs) <>
+                           char '>'
+
+
+voidTupleReturnInfo :: NativeCallInfo
+voidTupleReturnInfo = NativeCallInfo NativeTupleReturn 0 emptyRegSet 0
+
+voidPrimCallInfo :: NativeCallInfo
+voidPrimCallInfo = NativeCallInfo NativePrimCall 0 emptyRegSet 0
 
 type ItblEnv = NameEnv (Name, ItblPtr)
         -- We need the Name in the range so we know which


=====================================
compiler/GHC/Cmm/CallConv.hs
=====================================
@@ -3,7 +3,7 @@ module GHC.Cmm.CallConv (
   assignArgumentsPos,
   assignStack,
   realArgRegsCover,
-  tupleRegsCover
+  allArgRegsCover
 ) where
 
 import GHC.Prelude
@@ -220,12 +220,104 @@ realArgRegsCover platform
       realLongRegs   platform
       -- we don't save XMM registers if they are not used for parameter passing
 
--- Like realArgRegsCover but always includes the node. This covers the real
--- and virtual registers used for unboxed tuples.
---
--- Note: if anything changes in how registers for unboxed tuples overlap,
---       make sure to also update GHC.StgToByteCode.layoutTuple.
 
-tupleRegsCover :: Platform -> [GlobalReg]
-tupleRegsCover platform =
+{-
+
+  Note [GHCi and native call registers]
+  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+  The GHCi bytecode interpreter does not have access to the STG registers
+  that the native calling convention uses for passing arguments. It uses
+  helper stack frames to move values between the stack and registers.
+
+  If only a single register needs to be moved, GHCi uses a specific stack
+  frame. For example stg_ctoi_R1p saves a heap pointer value from STG register
+  R1 and stg_ctoi_D1 saves a double precision floating point value from D1.
+  In the other direction, helpers stg_ret_p and stg_ret_d move a value from
+  the stack to the R1 and D1 registers, respectively.
+
+  When GHCi needs to move more than one register it cannot use a specific
+  helper frame. It would simply be impossible to create a helper for all
+  possible combinations of register values. Instead, there are generic helper
+  stack frames that use a call_info word that describes the active registers
+  and the number of stack words used by the arguments of a call.
+
+  These helper stack frames are currently:
+
+      - stg_ret_t:    return a tuple to the continuation at the top of
+                          the stack
+      - stg_ctoi_t:   convert a tuple return value to be used in
+                          bytecode
+      - stg_primcall: call a function
+
+
+  The call_info word contains a bitmap of the active registers
+  for the call and and a stack offset. The layout is as follows:
+
+      - bit 0-23:  Bitmap of active registers for the call, the
+                   order corresponds to the list returned by
+                   allArgRegsCover. For example if bit 0 (the least
+                   significant bit) is set, the first register in the
+                   allArgRegsCover list is active. Bit 1 for the
+                   second register in the list and so on.
+
+      - bit 24-31: Unsigned byte, indicating the stack usage of the
+                   call in words (not counting the space )
+
+    The upper 32 bits on 64 bit platforms are currently unused.
+
+    If a register is smaller than a word on the stack (for example a
+    single precision float on a 64 bit system), then the stack slot
+    is padded to a whole word.
+
+    Example:
+
+        If a call has three arguments passed registers and
+        additional two words of arguments on the stack, then
+        three bits in the bitmap in bits 0-23 would be set. And
+        Bit 24-31 would be 00000010 (two in binary).
+
+        The values on the stack before a call to POP_ARG_REGS would
+        be as follows:
+
+            ...
+            stack_arg_1
+            stack_arg_2
+            register_arg_3
+            register_arg_2
+            register_arg_1 <- Sp
+
+        A call to POP_ARG_REGS(call_info) would move register_arg_1
+        to the register corresponding to the lowest set bit in the
+        call_info word. register_arg_2 would be moved to the register
+        corresponding to the second lowest set bit, and so on.
+
+        After POP_ARG_REGS(call_info), the stack pointer Sp points
+        to the first stack slot below the stack arguments. The stack
+        arguments are still on the stack above Sp, so the stack looks
+        as follows:
+
+              ...          <- Sp
+              stack_arg_1
+              stack_arg_2
+
+        At this point all the arguments are in place and we are ready
+        to jump to the native function.
+
+    On x86_64, the double precision (Dn) and single precision
+    floating (Fn) point registers overlap, e.g. D1 uses the same
+    physical register as F1. On this platform, the list returned
+    by allArgRegsCover contains only entries for the double
+    precision registers. If an argument is passed in register
+    Fn, the bit corresponding to Dn should be set.
+
+  Note: if anything changes in how registers for native calls overlap,
+           make sure to also update GHC.StgToByteCode.layoutNativeCall
+ -}
+
+-- Like realArgRegsCover but always includes the node. This covers all real
+-- and virtual registers actually used for passing arguments.
+
+allArgRegsCover :: Platform -> [GlobalReg]
+allArgRegsCover platform =
   nub (VanillaReg 1 VGcPtr : realArgRegsCover platform)


=====================================
compiler/GHC/Cmm/Parser.y
=====================================
@@ -1233,8 +1233,8 @@ stmtMacros = listToUFM [
   ( fsLit "SAVE_REGS",             \[] -> emitSaveRegs ),
   ( fsLit "RESTORE_REGS",          \[] -> emitRestoreRegs ),
 
-  ( fsLit "PUSH_TUPLE_REGS",      \[live_regs] -> emitPushTupleRegs live_regs ),
-  ( fsLit "POP_TUPLE_REGS",       \[live_regs] -> emitPopTupleRegs live_regs ),
+  ( fsLit "PUSH_ARG_REGS",         \[live_regs] -> emitPushArgRegs live_regs ),
+  ( fsLit "POP_ARG_REGS",          \[live_regs] -> emitPopArgRegs live_regs ),
 
   ( fsLit "LDV_ENTER",             \[e] -> ldvEnter e ),
   ( fsLit "LDV_RECORD_CREATE",     \[e] -> ldvRecordCreate e ),


=====================================
compiler/GHC/Cmm/Reg.hs
=====================================
@@ -223,7 +223,7 @@ instance Eq GlobalReg where
    _r1 == _r2 = False
 
 -- NOTE: this Ord instance affects the tuple layout in GHCi, see
---       Note [GHCi tuple layout]
+--       Note [GHCi and native call registers]
 instance Ord GlobalReg where
    compare (VanillaReg i _) (VanillaReg j _) = compare i j
      -- Ignore type when seeking clashes


=====================================
compiler/GHC/StgToByteCode.hs
=====================================
@@ -58,7 +58,7 @@ import GHC.Data.FastString
 import GHC.Utils.Panic
 import GHC.Utils.Panic.Plain
 import GHC.Utils.Exception (evaluate)
-import GHC.StgToCmm.Closure ( NonVoid(..), fromNonVoid, nonVoidIds )
+import GHC.StgToCmm.Closure ( NonVoid(..), fromNonVoid, nonVoidIds, argPrimRep )
 import GHC.StgToCmm.Layout
 import GHC.Runtime.Heap.Layout hiding (WordOff, ByteOff, wordsToBytes)
 import GHC.Data.Bitmap
@@ -464,10 +464,10 @@ returnUnliftedReps d s szb reps = do
              [rep] -> return (unitOL $ RETURN_UNLIFTED (toArgRep platform rep))
              -- otherwise use RETURN_TUPLE with a tuple descriptor
              nv_reps -> do
-               let (tuple_info, args_offsets) = layoutTuple profile 0 (primRepCmmType platform) nv_reps
+               let (call_info, args_offsets) = layoutNativeCall profile NativeTupleReturn 0 (primRepCmmType platform) nv_reps
                    args_ptrs = map (\(rep, off) -> (isFollowableArg (toArgRep platform rep), off)) args_offsets
-               tuple_bco <- emitBc (tupleBCO platform tuple_info args_ptrs)
-               return $ PUSH_UBX (mkTupleInfoLit platform tuple_info) 1 `consOL`
+               tuple_bco <- emitBc (tupleBCO platform call_info args_ptrs)
+               return $ PUSH_UBX (mkNativeCallInfoLit platform call_info) 1 `consOL`
                         PUSH_BCO tuple_bco `consOL`
                         unitOL RETURN_TUPLE
     return ( mkSlideB platform szb (d - s) -- clear to sequel
@@ -484,7 +484,11 @@ returnUnboxedTuple d s p es = do
     profile <- getProfile
     let platform = profilePlatform profile
         arg_ty e = primRepCmmType platform (atomPrimRep e)
-        (tuple_info, tuple_components) = layoutTuple profile d arg_ty es
+        (call_info, tuple_components) = layoutNativeCall profile
+                                                         NativeTupleReturn
+                                                         d
+                                                         arg_ty
+                                                         es
         go _   pushes [] = return (reverse pushes)
         go !dd pushes ((a, off):cs) = do (push, szb) <- pushAtom dd p a
                                          massert (off == dd + szb)
@@ -492,7 +496,7 @@ returnUnboxedTuple d s p es = do
     pushes <- go d [] tuple_components
     ret <- returnUnliftedReps d
                               s
-                              (wordsToBytes platform $ tupleSize tuple_info)
+                              (wordsToBytes platform $ nativeCallSize call_info)
                               (map atomPrimRep es)
     return (mconcat pushes `appOL` ret)
 
@@ -648,14 +652,14 @@ schemeT d s p app
    -- Case 1
 schemeT d s p (StgOpApp (StgFCallOp (CCall ccall_spec) _ty) args result_ty)
    = if isSupportedCConv ccall_spec
-      then generateCCall d s p ccall_spec result_ty (reverse args)
+      then generateCCall d s p ccall_spec result_ty args
       else unsupportedCConvException
 
 schemeT d s p (StgOpApp (StgPrimOp op) args _ty)
    = doTailCall d s p (primOpId op) (reverse args)
 
-schemeT _d _s _p (StgOpApp StgPrimCallOp{} _args _ty)
-   = unsupportedCConvException
+schemeT d s p (StgOpApp (StgPrimCallOp (PrimCall label unit)) args result_ty)
+   = generatePrimCall d s p label (Just unit) result_ty args
 
    -- Case 2: Unboxed tuple
 schemeT d s p (StgConApp con _cn args _tys)
@@ -840,18 +844,18 @@ doCase d s p scrut bndr alts
                              | ubx_frame       = wordSize platform
                              | otherwise       = 0
 
-        (bndr_size, tuple_info, args_offsets)
+        (bndr_size, call_info, args_offsets)
            | ubx_tuple_frame =
                let bndr_ty = primRepCmmType platform
                    bndr_reps = filter (not.isVoidRep) (bcIdPrimReps bndr)
-                   (tuple_info, args_offsets) =
-                       layoutTuple profile 0 bndr_ty bndr_reps
-               in ( wordsToBytes platform (tupleSize tuple_info)
-                  , tuple_info
+                   (call_info, args_offsets) =
+                       layoutNativeCall profile NativeTupleReturn 0 bndr_ty bndr_reps
+               in ( wordsToBytes platform (nativeCallSize call_info)
+                  , call_info
                   , args_offsets
                   )
            | otherwise = ( wordsToBytes platform (idSizeW platform bndr)
-                         , voidTupleInfo
+                         , voidTupleReturnInfo
                          , []
                          )
 
@@ -885,17 +889,18 @@ doCase d s p scrut bndr alts
            | isUnboxedTupleType bndr_ty || isUnboxedSumType bndr_ty =
              let bndr_ty = primRepCmmType platform . bcIdPrimRep
                  tuple_start = d_bndr
-                 (tuple_info, args_offsets) =
-                   layoutTuple profile
-                               0
-                               bndr_ty
-                               bndrs
+                 (call_info, args_offsets) =
+                   layoutNativeCall profile
+                                    NativeTupleReturn
+                                    0
+                                    bndr_ty
+                                    bndrs
 
                  stack_bot = d_alts
 
                  p' = Map.insertList
                         [ (arg, tuple_start -
-                                wordsToBytes platform (tupleSize tuple_info) +
+                                wordsToBytes platform (nativeCallSize call_info) +
                                 offset)
                         | (arg, offset) <- args_offsets
                         , not (isVoidRep $ bcIdPrimRep arg)]
@@ -981,8 +986,8 @@ doCase d s p scrut bndr alts
 
         -- unboxed tuples get two more words, the second is a pointer (tuple_bco)
         (extra_pointers, extra_slots)
-           | ubx_tuple_frame && profiling = ([1], 3) -- tuple_info, tuple_BCO, CCCS
-           | ubx_tuple_frame              = ([1], 2) -- tuple_info, tuple_BCO
+           | ubx_tuple_frame && profiling = ([1], 3) -- call_info, tuple_BCO, CCCS
+           | ubx_tuple_frame              = ([1], 2) -- call_info, tuple_BCO
            | otherwise                    = ([], 0)
 
         bitmap_size = trunc16W $ fromIntegral extra_slots +
@@ -1028,8 +1033,8 @@ doCase d s p scrut bndr alts
               let args_ptrs =
                     map (\(rep, off) -> (isFollowableArg (toArgRep platform rep), off))
                         args_offsets
-              tuple_bco <- emitBc (tupleBCO platform tuple_info args_ptrs)
-              return (PUSH_ALTS_TUPLE alt_bco' tuple_info tuple_bco
+              tuple_bco <- emitBc (tupleBCO platform call_info args_ptrs)
+              return (PUSH_ALTS_TUPLE alt_bco' call_info tuple_bco
                       `consOL` scrut_code)
        else let push_alts
                   | not ubx_frame
@@ -1050,14 +1055,15 @@ doCase d s p scrut bndr alts
 -- The native calling convention uses registers for tuples, but in the
 -- bytecode interpreter, all values live on the stack.
 
-layoutTuple :: Profile
-            -> ByteOff
-            -> (a -> CmmType)
-            -> [a]
-            -> ( TupleInfo      -- See Note [GHCi TupleInfo]
-               , [(a, ByteOff)] -- argument, offset on stack
-               )
-layoutTuple profile start_off arg_ty reps =
+layoutNativeCall :: Profile
+                 -> NativeCallType
+                 -> ByteOff
+                 -> (a -> CmmType)
+                 -> [a]
+                 -> ( NativeCallInfo      -- See Note [GHCi TupleInfo]
+                    , [(a, ByteOff)] -- argument, offset on stack
+                    )
+layoutNativeCall profile call_type start_off arg_ty reps =
   let platform = profilePlatform profile
       (orig_stk_bytes, pos) = assignArgumentsPos profile
                                                  0
@@ -1070,7 +1076,7 @@ layoutTuple profile start_off arg_ty reps =
 
       -- sort the register parameters by register and add them to the stack
       regs_order :: Map.Map GlobalReg Int
-      regs_order = Map.fromList $ zip (tupleRegsCover platform) [0..]
+      regs_order = Map.fromList $ zip (allArgRegsCover platform) [0..]
 
       reg_order :: GlobalReg -> (Int, GlobalReg)
       reg_order reg | Just n <- Map.lookup reg regs_order = (n, reg)
@@ -1099,10 +1105,11 @@ layoutTuple profile start_off arg_ty reps =
       get_byte_off _                 =
           panic "GHC.StgToByteCode.layoutTuple get_byte_off"
 
-  in ( TupleInfo
-         { tupleSize        = bytesToWords platform (ByteOff new_stk_bytes)
-         , tupleRegs        = regs_set
-         , tupleNativeStackSize = bytesToWords platform
+  in ( NativeCallInfo
+         { nativeCallType           = call_type
+         , nativeCallSize           = bytesToWords platform (ByteOff new_stk_bytes)
+         , nativeCallRegs           = regs_set
+         , nativeCallStackSpillSize = bytesToWords platform
                                                (ByteOff orig_stk_bytes)
          }
      , sortBy (comparing snd) $
@@ -1127,7 +1134,7 @@ usePlainReturn t
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   We have the bytecode instructions RETURN_TUPLE and PUSH_ALTS_TUPLE to
   return and receive arbitrary unboxed tuples, respectively. These
-  instructions use the helper data tuple_BCO and tuple_info.
+  instructions use the helper data tuple_BCO and call_info.
 
   The helper data is used to convert tuples between GHCs native calling
   convention (object code), which uses stack and registers, and the bytecode
@@ -1139,7 +1146,7 @@ usePlainReturn t
   =================
 
   Bytecode that returns a tuple first pushes all the tuple fields followed
-  by the appropriate tuple_info and tuple_BCO onto the stack. It then
+  by the appropriate call_info and tuple_BCO onto the stack. It then
   executes the RETURN_TUPLE instruction, which causes the interpreter
   to push stg_ret_t_info to the top of the stack. The stack (growing down)
   then looks as follows:
@@ -1150,14 +1157,14 @@ usePlainReturn t
       tuple_field_2
       ...
       tuple_field_n
-      tuple_info
+      call_info
       tuple_BCO
       stg_ret_t_info <- Sp
 
   If next_frame is bytecode, the interpreter will start executing it. If
   it's object code, the interpreter jumps back to the scheduler, which in
   turn jumps to stg_ret_t. stg_ret_t converts the tuple to the native
-  calling convention using the description in tuple_info, and then jumps
+  calling convention using the description in call_info, and then jumps
   to next_frame.
 
 
@@ -1169,13 +1176,13 @@ usePlainReturn t
   tuple. The PUSH_ALTS_TUPLE instuction contains three pieces of data:
 
      * cont_BCO: the continuation that receives the tuple
-     * tuple_info: see below
+     * call_info: see below
      * tuple_BCO: see below
 
   The interpreter pushes these onto the stack when the PUSH_ALTS_TUPLE
   instruction is executed, followed by stg_ctoi_tN_info, with N depending
   on the number of stack words used by the tuple in the GHC native calling
-  convention. N is derived from tuple_info.
+  convention. N is derived from call_info.
 
   For example if we expect a tuple with three words on the stack, the stack
   looks as follows after PUSH_ALTS_TUPLE:
@@ -1186,7 +1193,7 @@ usePlainReturn t
       cont_free_var_2
       ...
       cont_free_var_n
-      tuple_info
+      call_info
       tuple_BCO
       cont_BCO
       stg_ctoi_t3_info <- Sp
@@ -1206,20 +1213,20 @@ usePlainReturn t
   that is already on the stack.
 
 
-  The tuple_info word
+  The call_info word
   ===================
 
-  The tuple_info word describes the stack and STG register (e.g. R1..R6,
-  D1..D6) usage for the tuple. tuple_info contains enough information to
+  The call_info word describes the stack and STG register (e.g. R1..R6,
+  D1..D6) usage for the tuple. call_info contains enough information to
   convert the tuple between the stack-only bytecode and stack+registers
   GHC native calling conventions.
 
-  See Note [GHCi tuple layout] for more details of how the data is packed
-  in a single word.
+  See Note [GHCi and native call registers] for more details of how the
+  data is packed in a single word.
 
  -}
 
-tupleBCO :: Platform -> TupleInfo -> [(Bool, ByteOff)] -> [FFIInfo] -> ProtoBCO Name
+tupleBCO :: Platform -> NativeCallInfo -> [(Bool, ByteOff)] -> [FFIInfo] -> ProtoBCO Name
 tupleBCO platform info pointers =
   mkProtoBCO platform invented_name body_code (Left [])
              0{-no arity-} bitmap_size bitmap False{-is alts-}
@@ -1233,15 +1240,103 @@ tupleBCO platform info pointers =
     -}
     invented_name  = mkSystemVarName (mkPseudoUniqueE 0) (fsLit "tuple")
 
-    -- the first word in the frame is the tuple_info word,
+    -- the first word in the frame is the call_info word,
     -- which is not a pointer
-    bitmap_size = trunc16W $ 1 + tupleSize info
+    bitmap_size = trunc16W $ 1 + nativeCallSize info
     bitmap      = intsToReverseBitmap platform (fromIntegral bitmap_size) $
                   map ((+1) . fromIntegral . bytesToWords platform . snd)
                       (filter fst pointers)
     body_code = mkSlideW 0 1          -- pop frame header
                 `snocOL` RETURN_TUPLE -- and add it again
 
+primCallBCO ::  Platform -> NativeCallInfo -> [(Bool, ByteOff)] -> [FFIInfo] -> ProtoBCO Name
+primCallBCO platform args_info pointers =
+  mkProtoBCO platform invented_name body_code (Left [])
+             0{-no arity-} bitmap_size bitmap False{-is alts-}
+
+  where
+    {-
+      The primcall BCO is never referred to by name, so we can get away
+      with using a fake name here. We will need to change this if we want
+      to save some memory by sharing the BCO between places that have
+      the same tuple shape
+    -}
+    invented_name  = mkSystemVarName (mkPseudoUniqueE 0) (fsLit "primcall")
+
+    -- the first three words in the frame are the BCO describing the
+    -- pointers in the frame, the call_info word and the pointer
+    -- to the Cmm function being called. None of these is a pointer that
+    -- should be followed by the garbage collector
+    bitmap_size = trunc16W $ 2 + nativeCallSize args_info
+    bitmap      = intsToReverseBitmap platform (fromIntegral bitmap_size) $
+                  map ((+2) . fromIntegral . bytesToWords platform . snd)
+                      (filter fst pointers)
+    -- if the primcall BCO is ever run it's a bug, since the BCO should only
+    -- be pushed immediately before running the PRIMCALL bytecode instruction,
+    -- which immediately leaves the interpreter to jump to the stg_primcall_info
+    -- Cmm function
+    body_code =  unitOL CASEFAIL
+
+-- -----------------------------------------------------------------------------
+-- Deal with a primitive call to native code.
+
+generatePrimCall
+    :: StackDepth
+    -> Sequel
+    -> BCEnv
+    -> CLabelString          -- where to call
+    -> Maybe Unit
+    -> Type
+    -> [StgArg]              -- args (atoms)
+    -> BcM BCInstrList
+generatePrimCall d s p target _mb_unit _result_ty args
+ = do
+     profile <- getProfile
+     let
+         platform = profilePlatform profile
+
+         non_void VoidRep = False
+         non_void _       = True
+
+         nv_args :: [StgArg]
+         nv_args = filter (non_void . argPrimRep) args
+
+         (args_info, args_offsets) =
+              layoutNativeCall profile
+                               NativePrimCall
+                               d
+                               (primRepCmmType platform . argPrimRep)
+                               nv_args
+
+         args_ptrs :: [(Bool, ByteOff)]
+         args_ptrs =
+            map (\(r, off) ->
+                  (isFollowableArg (toArgRep platform . argPrimRep $ r), off))
+                args_offsets
+
+         push_target = PUSH_UBX (LitLabel target Nothing IsFunction) 1
+         push_info = PUSH_UBX (mkNativeCallInfoLit platform args_info) 1
+         {-
+            compute size to move payload (without stg_primcall_info header)
+
+            size of arguments plus three words for:
+                - function pointer to the target
+                - call_info word
+                - BCO to describe the stack frame
+          -}
+         szb = wordsToBytes platform (nativeCallSize args_info + 3)
+         go _   pushes [] = return (reverse pushes)
+         go !dd pushes ((a, off):cs) = do (push, szb) <- pushAtom dd p a
+                                          massert (off == dd + szb)
+                                          go (dd + szb) (push:pushes) cs
+     push_args <- go d [] args_offsets
+     args_bco <- emitBc (primCallBCO platform args_info args_ptrs)
+     return $ mconcat push_args `appOL`
+              (push_target `consOL`
+               push_info `consOL`
+               PUSH_BCO args_bco `consOL`
+               (mkSlideB platform szb (d - s) `appOL` unitOL PRIMCALL))
+
 -- -----------------------------------------------------------------------------
 -- Deal with a CCall.
 
@@ -1259,11 +1354,17 @@ generateCCall
     -> Type
     -> [StgArg]              -- args (atoms)
     -> BcM BCInstrList
-generateCCall d0 s p (CCallSpec target cconv safety) result_ty args_r_to_l
+generateCCall d0 s p (CCallSpec target PrimCallConv _) result_ty args
+ | (StaticTarget _ label mb_unit _) <- target
+ = generatePrimCall d0 s p label mb_unit result_ty args
+ | otherwise
+ = panic "GHC.StgToByteCode.generateCCall: primcall convention only supports static targets"
+generateCCall d0 s p (CCallSpec target cconv safety) result_ty args
  = do
      profile <- getProfile
 
      let
+         args_r_to_l = reverse args
          platform = profilePlatform profile
          -- useful constants
          addr_size_b :: ByteOff
@@ -2007,7 +2108,7 @@ isSupportedCConv :: CCallSpec -> Bool
 isSupportedCConv (CCallSpec _ cconv _) = case cconv of
    CCallConv            -> True     -- we explicitly pattern match on every
    StdCallConv          -> True     -- convention to ensure that a warning
-   PrimCallConv         -> False    -- is triggered when a new one is added
+   PrimCallConv         -> True     -- is triggered when a new one is added
    JavaScriptCallConv   -> False
    CApiConv             -> True
 


=====================================
compiler/GHC/StgToCmm/Foreign.hs
=====================================
@@ -15,8 +15,8 @@ module GHC.StgToCmm.Foreign (
   emitLoadThreadState,
   emitSaveRegs,
   emitRestoreRegs,
-  emitPushTupleRegs,
-  emitPopTupleRegs,
+  emitPushArgRegs,
+  emitPopArgRegs,
   loadThreadState,
   emitOpenNursery,
   emitCloseNursery,
@@ -349,7 +349,7 @@ emitRestoreRegs = do
 -- bytecode interpreter.
 --
 -- The "live registers" bitmap corresponds to the list of registers given by
--- 'tupleRegsCover', with the least significant bit indicating liveness of
+-- 'allArgRegsCover', with the least significant bit indicating liveness of
 -- the first register in the list.
 --
 -- Each register is saved to a stack slot of one or more machine words, even
@@ -362,12 +362,12 @@ emitRestoreRegs = do
 --    if((mask & 2) != 0) { Sp_adj(-1); Sp(0) = R2; }
 --    if((mask & 1) != 0) { Sp_adj(-1); Sp(0) = R1; }
 --
--- See Note [GHCi tuple layout]
+-- See Note [GHCi and native call registers]
 
-emitPushTupleRegs :: CmmExpr -> FCode ()
-emitPushTupleRegs regs_live = do
+emitPushArgRegs :: CmmExpr -> FCode ()
+emitPushArgRegs regs_live = do
   platform <- getPlatform
-  let regs = zip (tupleRegsCover platform) [0..]
+  let regs = zip (allArgRegsCover platform) [0..]
       save_arg (reg, n) =
         let mask     = CmmLit (CmmInt (1 `shiftL` n) (wordWidth platform))
             live     = cmmAndWord platform regs_live mask
@@ -381,11 +381,11 @@ emitPushTupleRegs regs_live = do
         in mkCmmIfThen cond $ catAGraphs [adj_sp, save_reg]
   emit . catAGraphs =<< mapM save_arg (reverse regs)
 
--- | Pop a subset of STG registers from the stack (see 'emitPushTupleRegs')
-emitPopTupleRegs :: CmmExpr -> FCode ()
-emitPopTupleRegs regs_live = do
+-- | Pop a subset of STG registers from the stack (see 'emitPushArgRegs')
+emitPopArgRegs :: CmmExpr -> FCode ()
+emitPopArgRegs regs_live = do
   platform <- getPlatform
-  let regs = zip (tupleRegsCover platform) [0..]
+  let regs = zip (allArgRegsCover platform) [0..]
       save_arg (reg, n) =
         let mask     = CmmLit (CmmInt (1 `shiftL` n) (wordWidth platform))
             live     = cmmAndWord platform regs_live mask


=====================================
rts/Disassembler.c
=====================================
@@ -83,6 +83,9 @@ disInstr ( StgBCO *bco, int pc )
          debugBelch("CCALL    marshaller at 0x%" FMT_HexWord "\n",
                          literals[instrs[pc]] );
          pc += 1; break;
+      case bci_PRIMCALL:
+         debugBelch("PRIMCALL\n");
+         break;
      case bci_STKCHECK:  {
          StgWord stk_words_reqd = BCO_GET_LARGE_ARG + 1;
          debugBelch("STKCHECK %" FMT_Word "\n", (W_)stk_words_reqd );


=====================================
rts/Interpreter.c
=====================================
@@ -2038,6 +2038,12 @@ run_BCO:
             goto nextInsn;
         }
 
+        case bci_PRIMCALL: {
+            Sp_subW(1);
+            SpW(0) = (W_)&stg_primcall_info;
+            RETURN_TO_SCHEDULER_NO_PAUSE(ThreadRunGHC, ThreadYielding);
+        }
+
         case bci_CCALL: {
             void *tok;
             int stk_offset            = BCO_NEXT;


=====================================
rts/RtsSymbols.c
=====================================
@@ -602,6 +602,7 @@ extern char **environ;
       SymI_HasDataProto(stg_ret_l_info)                                     \
       SymI_HasDataProto(stg_ret_t_info)                                     \
       SymI_HasDataProto(stg_ctoi_t)                                         \
+      SymI_HasDataProto(stg_primcall_info)                                  \
       SymI_HasDataProto(stg_gc_prim_p)                                      \
       SymI_HasDataProto(stg_gc_prim_pp)                                     \
       SymI_HasDataProto(stg_gc_prim_n)                                      \


=====================================
rts/StgMiscClosures.cmm
=====================================
@@ -366,20 +366,10 @@ MK_STG_CTOI_T(61)
 MK_STG_CTOI_T(62)
 
 /*
-  Note [GHCi tuple layout]
-  ~~~~~~~~~~~~~~~~~~~~~~~~
-  the tuple_info word describes the register and stack usage of the tuple:
+  Convert a tuple return value to be used in bytecode.
 
-  [ ssss ssss rrrr rrrr rrrr rrrr rrrr rrrr ]
-
-  - r: bitmap of live registers, corresponding to the list of registers
-       returned by GHC.Cmm.CallConv.tupleRegsCover (the least significant
-       bit corresponds to the first element in the list)
-  - s: number of words on stack (in addition to registers)
-
-  The order of the live registers in the bitmap is the same as the list
-  given by GHC.Cmm.CallConv.tupleRegsCover, with the least significant
-  bit corresponding to the first register in the list.
+  See Note [GHCi and native call registers] for information on how
+  values are moved between the stack and registers.
  */
 
 stg_ctoi_t
@@ -402,7 +392,7 @@ stg_ctoi_t
 
     Sp = Sp - WDS(tuple_stack);
 
-    PUSH_TUPLE_REGS(tuple_info);
+    PUSH_ARG_REGS(tuple_info);
 
     /* jump to the BCO that will finish the return of the tuple */
     Sp_adj(-3);
@@ -423,13 +413,57 @@ INFO_TABLE_RET( stg_ret_t, RET_BCO )
     /* number of words spilled on stack */
     tuple_stack  = (tuple_info >> 24) & 0xff;
 
-    POP_TUPLE_REGS(tuple_info);
+    POP_ARG_REGS(tuple_info);
 
     /* Sp points to the topmost argument now */
     jump %ENTRY_CODE(Sp(tuple_stack)) [*]; // NB. all registers live!
 }
 
 
+ /*
+
+    The stg_primcall frame is used by the bytecode interpreter to call
+    a Cmm function. The frame contains a call_info word that contains
+    a bitmap describing the register arguments.
+
+    When the target function is called, Sp points to the topmost stack
+    argument.
+
+       ...
+       next_stack_frame
+       arg_1
+       arg_2
+       ...
+       arg_n
+       target_funptr       (pointer to the function we're calling)
+       call_info           (describes the registers containing the arguments)
+       primcall_BCO        (contains bitmap describing pointers in args)
+       stg_primcall_info   <- Sp
+
+    See Note [GHCi and native call registers] for information on the call_info
+    word and how registers are moved between the stack and registers.
+
+ */
+
+INFO_TABLE_RET ( stg_primcall, RET_BCO )
+{
+    W_ args_info, prim_fun;
+
+    /* Sp(1) would be the BCO containing the stack description bitmap */
+    args_info = Sp(2);
+    prim_fun = Sp(3);
+
+    Sp_adj(4);
+
+    /* Sp points to the top of the register arguments now,
+       load them into actual registers */
+    POP_ARG_REGS(args_info);
+
+    /* Sp points to the topmost stack argument now */
+
+    jump prim_fun [*]; // NB. all registers live!
+}
+
 /*
  * Dummy info table pushed on the top of the stack when the interpreter
  * should apply the BCO on the stack to its arguments, also on the


=====================================
rts/include/rts/Bytecodes.h
=====================================
@@ -112,6 +112,8 @@
 #define bci_TESTLT_W8                   85
 #define bci_TESTEQ_W8                   86
 
+#define bci_PRIMCALL                    87
+
 /* If you need to go past 255 then you will run into the flags */
 
 /* If you need to go below 0x0100 then you will run into the instructions */


=====================================
rts/include/stg/MiscClosures.h
=====================================
@@ -160,6 +160,7 @@ RTS_RET(stg_ctoi_t60);
 RTS_RET(stg_ctoi_t61);
 RTS_RET(stg_ctoi_t62);
 
+RTS_RET(stg_primcall);
 RTS_RET(stg_apply_interp);
 RTS_RET(stg_dead_thread);
 


=====================================
testsuite/tests/ghci/prog014/prog014.T
=====================================
@@ -1,6 +1,5 @@
 test('prog014',
      [extra_files(['Primop.hs', 'dummy.c']),
-      expect_fail, # bytecode compiler doesn't support foreign import prim
       extra_run_opts('dummy.o'),
       pre_cmd('$MAKE -s --no-print-directory prog014')],
      ghci_script, ['prog014.script'])


=====================================
testsuite/tests/ghci/should_run/GHCiPrimCall/GHCiPrimCall.hs
=====================================
@@ -0,0 +1,224 @@
+{-# LANGUAGE ForeignFunctionInterface, GHCForeignImportPrim, UnliftedFFITypes, MagicHash, UnboxedTuples #-}
+
+module Main where
+
+import GHC.Int
+import GHC.Word
+import GHC.Prim
+import GHC.Exts
+import GHC.Types
+import Unsafe.Coerce
+import GHC.IO
+
+data Box (a :: UnliftedType) = MkBox a
+
+i2a :: Int -> Any
+i2a = unsafeCoerce
+
+a2i :: Any -> Int
+a2i = unsafeCoerce
+
+main :: IO ()
+main = do
+
+    let i8s :: [Int8]
+        i8s = [0, -1, 1, minBound, maxBound]
+
+        i16s :: [Int16]
+        i16s = [0, -1, 1, minBound, maxBound]
+
+        i32s :: [Int32]
+        i32s = [0, -1, 1, minBound, maxBound]
+
+        i64s :: [Int64]
+        i64s = [0, -1, 1, minBound, maxBound]
+
+        ws :: [Word]
+        ws = [0, 1, 2, maxBound]
+
+        fs :: [Float]
+        fs = [-0, 0, -1, 1, -2, 2, 1/0, 1e37, -1e-37]
+
+        ds :: [Double]
+        ds = [-0, 0, -1, 1, -2, 2, 1/0, 1e307, -1e-307]
+
+        ls :: [Word64]
+        ls = [0, 1, 2, 4294967296, maxBound]
+
+        mi2a :: Maybe Integer -> Any
+        mi2a = unsafeCoerce
+
+        a2mi :: Any -> Maybe Integer
+        a2mi = unsafeCoerce
+
+        a0, a1, a2, a3 :: Any
+        a0 = mi2a Nothing
+        a1 = mi2a (Just 1)
+        a2 = mi2a (Just 18446744073709551617)
+        a3 = mi2a (Just (-18446744073709551617))
+
+        as :: [Any]
+        as = [a0, a1, a2, a3]
+
+
+    putStrLn "zero arguments"
+    IO (\st -> case cmm_zero st of (# st' #) -> (# st', () #))
+    print =<< IO (\st -> case cmm_zero_w st of (# st', w #) -> (# st', W# w #))
+    print =<< IO (\st -> case cmm_zero_d st of (# st', w #) -> (# st', D# w #))
+    print =<< IO (\st -> case cmm_zero_f st of (# st', w #) -> (# st', F# w #))
+
+    -- XXX zero argument functions
+
+    putStrLn "one argument functions"
+    print [ I8# (cmm_one1_i8 x) | (I8# x) <- i8s ]
+    print [ I16# (cmm_one1_i16 x) | (I16# x) <- i16s ]
+    print [ I32# (cmm_one1_i32 x) | (I32# x) <- i32s ]
+    print [ I64# (cmm_one1_i64 x) | (I64# x) <- i64s ]
+    print [ case cmm_one1_p x of (# y #) -> a2mi y | x <- as ]
+    print [ W# (cmm_one1_w x) | (W# x) <- ws ]
+    print [ F# (cmm_one1_f x) | (F# x) <- fs ]
+    print [ D# (cmm_one1_d x) | (D# x) <- ds ]
+    print [ W64# (cmm_one1_l x) | (W64# x) <- ls ]
+
+    print [ case cmm_one2_i8 x of (# y1, y2 #) -> (I8# y1, I8# y2) | (I8# x) <- i8s ]
+    print [ case cmm_one2_i16 x of (# y1, y2 #) -> (I16# y1, I16# y2) | (I16# x) <- i16s ]
+    print [ case cmm_one2_i32 x of (# y1, y2 #) -> (I32# y1, I32# y2) | (I32# x) <- i32s ]
+    print [ case cmm_one2_i64 x of (# y1, y2 #) -> (I64# y1, I64# y2) | (I64# x) <- i64s ]
+    print [ case cmm_one2_p x of (# y1, y2 #) -> (a2mi y1, a2mi y2) | x <- as ]
+    print [ case cmm_one2_w x of (# y1, y2 #) -> (W# y1, W# y2) | (W# x) <- ws ]
+    print [ case cmm_one2_f x of (# y1, y2 #) -> (F# y1, F# y2) | (F# x) <- fs ]
+    print [ case cmm_one2_d x of (# y1, y2 #) -> (D# y1, D# y2) | (D# x) <- ds ]
+    print [ case cmm_one2_l x of (# y1, y2 #) -> (W64# y1, W64# y2) | (W64# x) <- ls ]
+
+    putStrLn "two argument functions"
+    print [ I8# (cmm_two1_i8 x1 x2) | (I8# x1) <- i8s, (I8# x2) <- i8s ]
+    print [ I16# (cmm_two1_i16 x1 x2) | (I16# x1) <- i16s, (I16# x2) <- i16s ]
+    print [ I32# (cmm_two1_i32 x1 x2) | (I32# x1) <- i32s, (I32# x2) <- i32s ]
+    print [ I64# (cmm_two1_i64 x1 x2) | (I64# x1) <- i64s, (I64# x2) <- i64s ]
+    print [ case cmm_two1_p x1 x2 of (# y #) -> a2mi y | x1 <- as, x2 <- as ]
+    print [ W# (cmm_two1_w x1 x2) | (W# x1) <- ws, (W# x2) <- ws ]
+    print [ F# (cmm_two1_f x1 x2) | (F# x1) <- fs, (F# x2) <- fs ]
+    print [ D# (cmm_two1_d x1 x2) | (D# x1) <- ds, (D# x2) <- ds ]
+    print [ W64# (cmm_two1_l x1 x2) | (W64# x1) <- ls, (W64# x2) <- ls ]
+
+    print [ I8# (cmm_two2_i8 x1 x2) | (I8# x1) <- i8s, (I8# x2) <- i8s ]
+    print [ I16# (cmm_two2_i16 x1 x2) | (I16# x1) <- i16s, (I16# x2) <- i16s ]
+    print [ I32# (cmm_two2_i32 x1 x2) | (I32# x1) <- i32s, (I32# x2) <- i32s ]
+    print [ I64# (cmm_two2_i64 x1 x2) | (I64# x1) <- i64s, (I64# x2) <- i64s ]
+    print [ case cmm_two2_p x1 x2 of (# y #) -> a2mi y | x1 <- as, x2 <- as ]
+    print [ W# (cmm_two2_w x1 x2) | (W# x1) <- ws, (W# x2) <- ws ]
+    print [ F# (cmm_two2_f x1 x2) | (F# x1) <- fs, (F# x2) <- fs ]
+    print [ D# (cmm_two2_d x1 x2) | (D# x1) <- ds, (D# x2) <- ds ]
+    print [ W64# (cmm_two2_l x1 x2) | (W64# x1) <- ls, (W64# x2) <- ls ]
+
+    putStrLn "additional floating point tests"
+    print [ F# (cmm_floating_1 x1 x2) | (F# x1) <- fs, (F# x2) <- fs ]
+    print [ D# (cmm_floating_2 x1 x2) | (D# x1) <- ds, (D# x2) <- ds ]
+    print [ F# (cmm_floating_3 x1 x2) | (F# x1) <- fs, (D# x2) <- ds ]
+    print [ D# (cmm_floating_4 x1 x2) | (F# x1) <- fs, (D# x2) <- ds ]
+    print [ case cmm_floating_5 x1 x2 3.0e1# 4.0e2## 5.0e3# 6.0e4## 7.0e5# 8.0e6## of (# y1, y2 #) -> (F# y1, D# y2)
+          | (F# x1) <- fs, (D# x2) <- ds ]
+    print [ case cmm_floating_6 x1 x2 3.0e1## 4.0e2# 5.0e3## 6.0e4# 7.0e5## 8.0e6# of (# y1, y2 #) -> (D# y1, F# y2)
+          | (D# x1) <- ds, (F# x2) <- fs ]
+    print [ case cmm_floating_7 w1 x1 x2
+                                4## 5.0e1# 6.0e2##
+                                7## 8.0e3# 9.0e4##
+                                10## 11.0e5# 12.0e6##
+                                13## 14.0e7# 15.0e8##
+                                16## 17.0e9# 18.0e10##
+                                19## 20.0e11# 21.0e12## of (# y1, y2, y3 #) -> (W# y1, F# y2, D# y3)
+          | (W# w1) <- ws, (F# x1) <- fs, (D# x2) <- ds ]
+
+    putStrLn "various sized tuple returns"
+    print [ case cmm_tuple_1 x1 x2 3## of (# y1, y2, y3 #) -> (W# y1, W# y2, W# y3) | (W# x1) <- ws, (W# x2) <- ws]
+    print [ case cmm_tuple_2 x1 x2 3## 4## a0 a1 7.0## 8.0## a2 a3 11.0# 12.0#
+            of (# y1, y2, y3, y4, y5, y6, y7, y8, y9, y10, y11, y12 #) ->
+                (F# y1, F# y2, a2mi y3, a2mi y4, D# y5, D# y6, a2mi y7, a2mi y8, W# y9, W# y10, a2mi y11, a2mi y12)
+          | x1 <- as, x2 <- as ]
+    print [ case cmm_tuple_3 x1 x2 a0 3.0## a1 5.0#
+            of (# y1, y2, y3, y4, y5, y6 #) -> (F# y1, a2mi y2, D# y3, a2mi y4, W# y5, a2mi y6)
+          | x1 <- as, (W# x2) <- ws ]
+    print [ case cmm_tuple_4 x1 x2 of (# y1, y2 #) -> (a2mi y1, a2mi y2) | x1 <- as, x2 <- as ]
+
+    putStrLn "arrays"
+    MkBox marr0 <- IO (\s -> case newArray# 10# a0 s of (# s', a #) -> (# s', MkBox a #))
+    MkBox marr1 <- IO (\s -> case newArray# 12# a1 s of (# s', a #) -> (# s', MkBox a #))
+    MkBox arr0 <- IO (\s -> case unsafeFreezeArray# marr0 s of (# s', a #) -> (# s', MkBox a #))
+    MkBox arr1 <- IO (\s -> case unsafeFreezeArray# marr1 s of (# s', a #) -> (# s', MkBox a #))
+    print (I# (cmm_array_1 arr0), I# (cmm_array_1 arr1))
+    case cmm_array_2 arr0 arr1 of (# arr2, arr3 #) -> print (I# (cmm_array_1 arr2), I# (cmm_array_1 arr3))
+
+
+-- XXX why don't we accept State# RealWorld -> State# RealWorld ?
+foreign import prim cmm_zero :: State# RealWorld -> (# State# RealWorld #)
+foreign import prim cmm_zero_w :: State# RealWorld -> (# State# RealWorld, Word# #)
+foreign import prim cmm_zero_d :: State# RealWorld -> (# State# RealWorld, Double# #)
+foreign import prim cmm_zero_f :: State# RealWorld -> (# State# RealWorld, Float# #)
+
+-- one argument functions
+foreign import prim cmm_one1_i8 :: Int8# -> Int8#
+foreign import prim cmm_one1_i16 :: Int16# -> Int16#
+foreign import prim cmm_one1_i32 :: Int32# -> Int32#
+foreign import prim cmm_one1_i64 :: Int64# -> Int64#
+foreign import prim cmm_one1_p :: Any -> (# Any #)
+foreign import prim cmm_one1_w :: Word# -> Word#
+foreign import prim cmm_one1_f :: Float# -> Float#
+foreign import prim cmm_one1_d :: Double# -> Double#
+foreign import prim cmm_one1_l :: Word64# -> Word64#
+
+foreign import prim cmm_one2_i8 :: Int8# -> (# Int8#, Int8# #)
+foreign import prim cmm_one2_i16 :: Int16# -> (# Int16#, Int16# #)
+foreign import prim cmm_one2_i32 :: Int32# -> (# Int32#, Int32# #)
+foreign import prim cmm_one2_i64 :: Int64# -> (# Int64#, Int64# #)
+foreign import prim cmm_one2_p :: Any -> (# Any, Any #)
+foreign import prim cmm_one2_w :: Word# -> (# Word#, Word# #)
+foreign import prim cmm_one2_f :: Float# -> (# Float#, Float# #)
+foreign import prim cmm_one2_d :: Double# -> (# Double#, Double# #)
+foreign import prim cmm_one2_l :: Word64# -> (# Word64#, Word64# #)
+
+-- two argument functions
+foreign import prim cmm_two1_i8 :: Int8# -> Int8# -> Int8#
+foreign import prim cmm_two1_i16 :: Int16# -> Int16# -> Int16#
+foreign import prim cmm_two1_i32 :: Int32# -> Int32# -> Int32#
+foreign import prim cmm_two1_i64 :: Int64# -> Int64# -> Int64#
+foreign import prim cmm_two1_p :: Any -> Any -> (# Any #)
+foreign import prim cmm_two1_w :: Word# -> Word# -> Word#
+foreign import prim cmm_two1_f :: Float# -> Float# -> Float#
+foreign import prim cmm_two1_d :: Double# -> Double# -> Double#
+foreign import prim cmm_two1_l :: Word64# -> Word64# -> Word64#
+
+foreign import prim cmm_two2_i8 :: Int8# -> Int8# -> Int8#
+foreign import prim cmm_two2_i16 :: Int16# -> Int16# -> Int16#
+foreign import prim cmm_two2_i32 :: Int32# -> Int32# -> Int32#
+foreign import prim cmm_two2_i64 :: Int64# -> Int64# -> Int64#
+foreign import prim cmm_two2_p :: Any -> Any -> (# Any #)
+foreign import prim cmm_two2_w :: Word# -> Word# -> Word#
+foreign import prim cmm_two2_f :: Float# -> Float# -> Float#
+foreign import prim cmm_two2_d :: Double# -> Double# -> Double#
+foreign import prim cmm_two2_l :: Word64# -> Word64# -> Word64#
+
+{- additional tests for floating point, since D_ and F_ registers
+   overlap on some platforms -}
+
+foreign import prim cmm_floating_1 :: Float# -> Float# -> Float#
+foreign import prim cmm_floating_2 :: Double# -> Double# -> Double#
+foreign import prim cmm_floating_3 :: Float# -> Double# -> Float#
+foreign import prim cmm_floating_4 :: Float# -> Double# -> Double#
+foreign import prim cmm_floating_5 :: Float# -> Double# -> Float# -> Double# -> Float# -> Double# -> Float# -> Double# -> (# Float#, Double# #)
+foreign import prim cmm_floating_6 :: Double# -> Float# -> Double# -> Float# -> Double# -> Float# -> Double# -> Float# -> (# Double#, Float# #)
+foreign import prim cmm_floating_7 :: Word# -> Float# -> Double# -> Word# -> Float# -> Double# -> Word# -> Float# -> Double# -> Word# -> Float# -> Double# -> Word# -> Float# -> Double# -> Word# -> Float# -> Double# -> Word# -> Float# -> Double# -> (# Word#, Float#, Double# #)
+-- various sized tuple returns
+
+foreign import prim cmm_tuple_1 :: Word# -> Word# -> Word# -> (# Word# , Word#, Word# #)
+foreign import prim cmm_tuple_2 :: Any -> Any -> Word# -> Word# -> Any -> Any -> Double# -> Double# -> Any -> Any -> Float# -> Float# ->
+    (# Float#, Float#, Any, Any, Double#, Double#, Any, Any, Word#, Word#, Any, Any #)
+foreign import prim cmm_tuple_3 :: Any -> Word# -> Any -> Double# -> Any -> Float# ->
+    (# Float#, Any, Double#, Any, Word#, Any #)
+foreign import prim cmm_tuple_4 :: Any -> Any -> (# Any, Any #)
+
+-- boxed primitive types
+
+-- get the length of an array
+foreign import prim cmm_array_1 :: Array# Any -> Int#
+-- return some arrays
+foreign import prim cmm_array_2 :: Array# Any -> Array# Any -> (# Array# Any, Array# Any #)


=====================================
testsuite/tests/ghci/should_run/GHCiPrimCall/GHCiPrimCall.stdout
=====================================
@@ -0,0 +1,58 @@
+zero arguments
+123
+1.0
+1.0
+one argument functions
+[0,-1,1,-128,127]
+[0,-1,1,-32768,32767]
+[0,-1,1,-2147483648,2147483647]
+[0,-1,1,-9223372036854775808,9223372036854775807]
+[Nothing,Just 1,Just 18446744073709551617,Just (-18446744073709551617)]
+[0,1,2,18446744073709551615]
+[-0.0,0.0,-1.0,1.0,-2.0,2.0,Infinity,1.0e37,-1.0e-37]
+[-0.0,0.0,-1.0,1.0,-2.0,2.0,Infinity,1.0e307,-1.0e-307]
+[0,1,2,4294967296,18446744073709551615]
+[(0,0),(-1,-1),(1,1),(-128,-128),(127,127)]
+[(0,0),(-1,-1),(1,1),(-32768,-32768),(32767,32767)]
+[(0,0),(-1,-1),(1,1),(-2147483648,-2147483648),(2147483647,2147483647)]
+[(0,0),(-1,-1),(1,1),(-9223372036854775808,-9223372036854775808),(9223372036854775807,9223372036854775807)]
+[(Nothing,Nothing),(Just 1,Just 1),(Just 18446744073709551617,Just 18446744073709551617),(Just (-18446744073709551617),Just (-18446744073709551617))]
+[(0,0),(1,1),(2,2),(18446744073709551615,18446744073709551615)]
+[(-0.0,-0.0),(0.0,0.0),(-1.0,-1.0),(1.0,1.0),(-2.0,-2.0),(2.0,2.0),(Infinity,Infinity),(1.0e37,1.0e37),(-1.0e-37,-1.0e-37)]
+[(-0.0,-0.0),(0.0,0.0),(-1.0,-1.0),(1.0,1.0),(-2.0,-2.0),(2.0,2.0),(Infinity,Infinity),(1.0e307,1.0e307),(-1.0e-307,-1.0e-307)]
+[(0,0),(1,1),(2,2),(4294967296,4294967296),(18446744073709551615,18446744073709551615)]
+two argument functions
+[0,0,0,0,0,-1,-1,-1,-1,-1,1,1,1,1,1,-128,-128,-128,-128,-128,127,127,127,127,127]
+[0,0,0,0,0,-1,-1,-1,-1,-1,1,1,1,1,1,-32768,-32768,-32768,-32768,-32768,32767,32767,32767,32767,32767]
+[0,0,0,0,0,-1,-1,-1,-1,-1,1,1,1,1,1,-2147483648,-2147483648,-2147483648,-2147483648,-2147483648,2147483647,2147483647,2147483647,2147483647,2147483647]
+[0,0,0,0,0,-1,-1,-1,-1,-1,1,1,1,1,1,-9223372036854775808,-9223372036854775808,-9223372036854775808,-9223372036854775808,-9223372036854775808,9223372036854775807,9223372036854775807,9223372036854775807,9223372036854775807,9223372036854775807]
+[Nothing,Nothing,Nothing,Nothing,Just 1,Just 1,Just 1,Just 1,Just 18446744073709551617,Just 18446744073709551617,Just 18446744073709551617,Just 18446744073709551617,Just (-18446744073709551617),Just (-18446744073709551617),Just (-18446744073709551617),Just (-18446744073709551617)]
+[0,0,0,0,1,1,1,1,2,2,2,2,18446744073709551615,18446744073709551615,18446744073709551615,18446744073709551615]
+[-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,-2.0,-2.0,-2.0,-2.0,-2.0,-2.0,-2.0,-2.0,-2.0,2.0,2.0,2.0,2.0,2.0,2.0,2.0,2.0,2.0,Infinity,Infinity,Infinity,Infinity,Infinity,Infinity,Infinity,Infinity,Infinity,1.0e37,1.0e37,1.0e37,1.0e37,1.0e37,1.0e37,1.0e37,1.0e37,1.0e37,-1.0e-37,-1.0e-37,-1.0e-37,-1.0e-37,-1.0e-37,-1.0e-37,-1.0e-37,-1.0e-37,-1.0e-37]
+[-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,-2.0,-2.0,-2.0,-2.0,-2.0,-2.0,-2.0,-2.0,-2.0,2.0,2.0,2.0,2.0,2.0,2.0,2.0,2.0,2.0,Infinity,Infinity,Infinity,Infinity,Infinity,Infinity,Infinity,Infinity,Infinity,1.0e307,1.0e307,1.0e307,1.0e307,1.0e307,1.0e307,1.0e307,1.0e307,1.0e307,-1.0e-307,-1.0e-307,-1.0e-307,-1.0e-307,-1.0e-307,-1.0e-307,-1.0e-307,-1.0e-307,-1.0e-307]
+[0,0,0,0,0,1,1,1,1,1,2,2,2,2,2,4294967296,4294967296,4294967296,4294967296,4294967296,18446744073709551615,18446744073709551615,18446744073709551615,18446744073709551615,18446744073709551615]
+[0,-1,1,-128,127,0,-1,1,-128,127,0,-1,1,-128,127,0,-1,1,-128,127,0,-1,1,-128,127]
+[0,-1,1,-32768,32767,0,-1,1,-32768,32767,0,-1,1,-32768,32767,0,-1,1,-32768,32767,0,-1,1,-32768,32767]
+[0,-1,1,-2147483648,2147483647,0,-1,1,-2147483648,2147483647,0,-1,1,-2147483648,2147483647,0,-1,1,-2147483648,2147483647,0,-1,1,-2147483648,2147483647]
+[0,-1,1,-9223372036854775808,9223372036854775807,0,-1,1,-9223372036854775808,9223372036854775807,0,-1,1,-9223372036854775808,9223372036854775807,0,-1,1,-9223372036854775808,9223372036854775807,0,-1,1,-9223372036854775808,9223372036854775807]
+[Nothing,Just 1,Just 18446744073709551617,Just (-18446744073709551617),Nothing,Just 1,Just 18446744073709551617,Just (-18446744073709551617),Nothing,Just 1,Just 18446744073709551617,Just (-18446744073709551617),Nothing,Just 1,Just 18446744073709551617,Just (-18446744073709551617)]
+[0,1,2,18446744073709551615,0,1,2,18446744073709551615,0,1,2,18446744073709551615,0,1,2,18446744073709551615]
+[-0.0,0.0,-1.0,1.0,-2.0,2.0,Infinity,1.0e37,-1.0e-37,-0.0,0.0,-1.0,1.0,-2.0,2.0,Infinity,1.0e37,-1.0e-37,-0.0,0.0,-1.0,1.0,-2.0,2.0,Infinity,1.0e37,-1.0e-37,-0.0,0.0,-1.0,1.0,-2.0,2.0,Infinity,1.0e37,-1.0e-37,-0.0,0.0,-1.0,1.0,-2.0,2.0,Infinity,1.0e37,-1.0e-37,-0.0,0.0,-1.0,1.0,-2.0,2.0,Infinity,1.0e37,-1.0e-37,-0.0,0.0,-1.0,1.0,-2.0,2.0,Infinity,1.0e37,-1.0e-37,-0.0,0.0,-1.0,1.0,-2.0,2.0,Infinity,1.0e37,-1.0e-37,-0.0,0.0,-1.0,1.0,-2.0,2.0,Infinity,1.0e37,-1.0e-37]
+[-0.0,0.0,-1.0,1.0,-2.0,2.0,Infinity,1.0e307,-1.0e-307,-0.0,0.0,-1.0,1.0,-2.0,2.0,Infinity,1.0e307,-1.0e-307,-0.0,0.0,-1.0,1.0,-2.0,2.0,Infinity,1.0e307,-1.0e-307,-0.0,0.0,-1.0,1.0,-2.0,2.0,Infinity,1.0e307,-1.0e-307,-0.0,0.0,-1.0,1.0,-2.0,2.0,Infinity,1.0e307,-1.0e-307,-0.0,0.0,-1.0,1.0,-2.0,2.0,Infinity,1.0e307,-1.0e-307,-0.0,0.0,-1.0,1.0,-2.0,2.0,Infinity,1.0e307,-1.0e-307,-0.0,0.0,-1.0,1.0,-2.0,2.0,Infinity,1.0e307,-1.0e-307,-0.0,0.0,-1.0,1.0,-2.0,2.0,Infinity,1.0e307,-1.0e-307]
+[0,1,2,4294967296,18446744073709551615,0,1,2,4294967296,18446744073709551615,0,1,2,4294967296,18446744073709551615,0,1,2,4294967296,18446744073709551615,0,1,2,4294967296,18446744073709551615]
+additional floating point tests
+[-0.0,0.0,-1.0,1.0,-2.0,2.0,Infinity,1.0e37,-1.0e-37,0.0,0.0,-1.0,1.0,-2.0,2.0,Infinity,1.0e37,-1.0e-37,-1.0,-1.0,-2.0,0.0,-3.0,1.0,Infinity,1.0e37,-1.0,1.0,1.0,0.0,2.0,-1.0,3.0,Infinity,1.0e37,1.0,-2.0,-2.0,-3.0,-1.0,-4.0,0.0,Infinity,1.0e37,-2.0,2.0,2.0,1.0,3.0,0.0,4.0,Infinity,1.0e37,2.0,Infinity,Infinity,Infinity,Infinity,Infinity,Infinity,Infinity,Infinity,Infinity,1.0e37,1.0e37,1.0e37,1.0e37,1.0e37,1.0e37,Infinity,2.0e37,1.0e37,-1.0e-37,-1.0e-37,-1.0,1.0,-2.0,2.0,Infinity,1.0e37,-2.0e-37]
+[-0.0,0.0,-1.0,1.0,-2.0,2.0,Infinity,1.0e307,-1.0e-307,0.0,0.0,-1.0,1.0,-2.0,2.0,Infinity,1.0e307,-1.0e-307,-1.0,-1.0,-2.0,0.0,-3.0,1.0,Infinity,1.0e307,-1.0,1.0,1.0,0.0,2.0,-1.0,3.0,Infinity,1.0e307,1.0,-2.0,-2.0,-3.0,-1.0,-4.0,0.0,Infinity,1.0e307,-2.0,2.0,2.0,1.0,3.0,0.0,4.0,Infinity,1.0e307,2.0,Infinity,Infinity,Infinity,Infinity,Infinity,Infinity,Infinity,Infinity,Infinity,1.0e307,1.0e307,1.0e307,1.0e307,1.0e307,1.0e307,Infinity,2.0e307,1.0e307,-1.0e-307,-1.0e-307,-1.0,1.0,-2.0,2.0,Infinity,1.0e307,-2.0e-307]
+[-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,-2.0,-2.0,-2.0,-2.0,-2.0,-2.0,-2.0,-2.0,-2.0,2.0,2.0,2.0,2.0,2.0,2.0,2.0,2.0,2.0,Infinity,Infinity,Infinity,Infinity,Infinity,Infinity,Infinity,Infinity,Infinity,1.0e37,1.0e37,1.0e37,1.0e37,1.0e37,1.0e37,1.0e37,1.0e37,1.0e37,-1.0e-37,-1.0e-37,-1.0e-37,-1.0e-37,-1.0e-37,-1.0e-37,-1.0e-37,-1.0e-37,-1.0e-37]
+[-0.0,0.0,-1.0,1.0,-2.0,2.0,Infinity,1.0e307,-1.0e-307,-0.0,0.0,-1.0,1.0,-2.0,2.0,Infinity,1.0e307,-1.0e-307,-0.0,0.0,-1.0,1.0,-2.0,2.0,Infinity,1.0e307,-1.0e-307,-0.0,0.0,-1.0,1.0,-2.0,2.0,Infinity,1.0e307,-1.0e-307,-0.0,0.0,-1.0,1.0,-2.0,2.0,Infinity,1.0e307,-1.0e-307,-0.0,0.0,-1.0,1.0,-2.0,2.0,Infinity,1.0e307,-1.0e-307,-0.0,0.0,-1.0,1.0,-2.0,2.0,Infinity,1.0e307,-1.0e-307,-0.0,0.0,-1.0,1.0,-2.0,2.0,Infinity,1.0e307,-1.0e-307,-0.0,0.0,-1.0,1.0,-2.0,2.0,Infinity,1.0e307,-1.0e-307]
+[(705030.0,8060400.0),(705030.0,8060400.0),(705030.0,8060399.0),(705030.0,8060401.0),(705030.0,8060398.0),(705030.0,8060402.0),(705030.0,Infinity),(705030.0,1.0e307),(705030.0,8060400.0),(705030.0,8060400.0),(705030.0,8060400.0),(705030.0,8060399.0),(705030.0,8060401.0),(705030.0,8060398.0),(705030.0,8060402.0),(705030.0,Infinity),(705030.0,1.0e307),(705030.0,8060400.0),(705029.0,8060400.0),(705029.0,8060400.0),(705029.0,8060399.0),(705029.0,8060401.0),(705029.0,8060398.0),(705029.0,8060402.0),(705029.0,Infinity),(705029.0,1.0e307),(705029.0,8060400.0),(705031.0,8060400.0),(705031.0,8060400.0),(705031.0,8060399.0),(705031.0,8060401.0),(705031.0,8060398.0),(705031.0,8060402.0),(705031.0,Infinity),(705031.0,1.0e307),(705031.0,8060400.0),(705028.0,8060400.0),(705028.0,8060400.0),(705028.0,8060399.0),(705028.0,8060401.0),(705028.0,8060398.0),(705028.0,8060402.0),(705028.0,Infinity),(705028.0,1.0e307),(705028.0,8060400.0),(705032.0,8060400.0),(705032.0,8060400.0),(705032.0,8060399.0),(705032.0,8060401.0),(705032.0,8060398.0),(705032.0,8060402.0),(705032.0,Infinity),(705032.0,1.0e307),(705032.0,8060400.0),(Infinity,8060400.0),(Infinity,8060400.0),(Infinity,8060399.0),(Infinity,8060401.0),(Infinity,8060398.0),(Infinity,8060402.0),(Infinity,Infinity),(Infinity,1.0e307),(Infinity,8060400.0),(1.0e37,8060400.0),(1.0e37,8060400.0),(1.0e37,8060399.0),(1.0e37,8060401.0),(1.0e37,8060398.0),(1.0e37,8060402.0),(1.0e37,Infinity),(1.0e37,1.0e307),(1.0e37,8060400.0),(705030.0,8060400.0),(705030.0,8060400.0),(705030.0,8060399.0),(705030.0,8060401.0),(705030.0,8060398.0),(705030.0,8060402.0),(705030.0,Infinity),(705030.0,1.0e307),(705030.0,8060400.0)]
+[(705030.0,8060400.0),(705030.0,8060400.0),(705030.0,8060399.0),(705030.0,8060401.0),(705030.0,8060398.0),(705030.0,8060402.0),(705030.0,Infinity),(705030.0,1.0e37),(705030.0,8060400.0),(705030.0,8060400.0),(705030.0,8060400.0),(705030.0,8060399.0),(705030.0,8060401.0),(705030.0,8060398.0),(705030.0,8060402.0),(705030.0,Infinity),(705030.0,1.0e37),(705030.0,8060400.0),(705029.0,8060400.0),(705029.0,8060400.0),(705029.0,8060399.0),(705029.0,8060401.0),(705029.0,8060398.0),(705029.0,8060402.0),(705029.0,Infinity),(705029.0,1.0e37),(705029.0,8060400.0),(705031.0,8060400.0),(705031.0,8060400.0),(705031.0,8060399.0),(705031.0,8060401.0),(705031.0,8060398.0),(705031.0,8060402.0),(705031.0,Infinity),(705031.0,1.0e37),(705031.0,8060400.0),(705028.0,8060400.0),(705028.0,8060400.0),(705028.0,8060399.0),(705028.0,8060401.0),(705028.0,8060398.0),(705028.0,8060402.0),(705028.0,Infinity),(705028.0,1.0e37),(705028.0,8060400.0),(705032.0,8060400.0),(705032.0,8060400.0),(705032.0,8060399.0),(705032.0,8060401.0),(705032.0,8060398.0),(705032.0,8060402.0),(705032.0,Infinity),(705032.0,1.0e37),(705032.0,8060400.0),(Infinity,8060400.0),(Infinity,8060400.0),(Infinity,8060399.0),(Infinity,8060401.0),(Infinity,8060398.0),(Infinity,8060402.0),(Infinity,Infinity),(Infinity,1.0e37),(Infinity,8060400.0),(1.0e307,8060400.0),(1.0e307,8060400.0),(1.0e307,8060399.0),(1.0e307,8060401.0),(1.0e307,8060398.0),(1.0e307,8060402.0),(1.0e307,Infinity),(1.0e307,1.0e37),(1.0e307,8060400.0),(705030.0,8060400.0),(705030.0,8060400.0),(705030.0,8060399.0),(705030.0,8060401.0),(705030.0,8060398.0),(705030.0,8060402.0),(705030.0,Infinity),(705030.0,1.0e37),(705030.0,8060400.0)]
+[(69,2.017141e12,2.11815120906e13),(69,2.017141e12,2.11815120906e13),(69,2.017141e12,2.1181512090599e13),(69,2.017141e12,2.1181512090601e13),(69,2.017141e12,2.1181512090598e13),(69,2.017141e12,2.1181512090602e13),(69,2.017141e12,Infinity),(69,2.017141e12,1.0e307),(69,2.017141e12,2.11815120906e13),(69,2.017141e12,2.11815120906e13),(69,2.017141e12,2.11815120906e13),(69,2.017141e12,2.1181512090599e13),(69,2.017141e12,2.1181512090601e13),(69,2.017141e12,2.1181512090598e13),(69,2.017141e12,2.1181512090602e13),(69,2.017141e12,Infinity),(69,2.017141e12,1.0e307),(69,2.017141e12,2.11815120906e13),(69,2.017141e12,2.11815120906e13),(69,2.017141e12,2.11815120906e13),(69,2.017141e12,2.1181512090599e13),(69,2.017141e12,2.1181512090601e13),(69,2.017141e12,2.1181512090598e13),(69,2.017141e12,2.1181512090602e13),(69,2.017141e12,Infinity),(69,2.017141e12,1.0e307),(69,2.017141e12,2.11815120906e13),(69,2.017141e12,2.11815120906e13),(69,2.017141e12,2.11815120906e13),(69,2.017141e12,2.1181512090599e13),(69,2.017141e12,2.1181512090601e13),(69,2.017141e12,2.1181512090598e13),(69,2.017141e12,2.1181512090602e13),(69,2.017141e12,Infinity),(69,2.017141e12,1.0e307),(69,2.017141e12,2.11815120906e13),(69,2.017141e12,2.11815120906e13),(69,2.017141e12,2.11815120906e13),(69,2.017141e12,2.1181512090599e13),(69,2.017141e12,2.1181512090601e13),(69,2.017141e12,2.1181512090598e13),(69,2.017141e12,2.1181512090602e13),(69,2.017141e12,Infinity),(69,2.017141e12,1.0e307),(69,2.017141e12,2.11815120906e13),(69,2.017141e12,2.11815120906e13),(69,2.017141e12,2.11815120906e13),(69,2.017141e12,2.1181512090599e13),(69,2.017141e12,2.1181512090601e13),(69,2.017141e12,2.1181512090598e13),(69,2.017141e12,2.1181512090602e13),(69,2.017141e12,Infinity),(69,2.017141e12,1.0e307),(69,2.017141e12,2.11815120906e13),(69,Infinity,2.11815120906e13),(69,Infinity,2.11815120906e13),(69,Infinity,2.1181512090599e13),(69,Infinity,2.1181512090601e13),(69,Infinity,2.1181512090598e13),(69,Infinity,2.1181512090602e13),(69,Infinity,Infinity),(69,Infinity,1.0e307),(69,Infinity,2.11815120906e13),(69,1.0e37,2.11815120906e13),(69,1.0e37,2.11815120906e13),(69,1.0e37,2.1181512090599e13),(69,1.0e37,2.1181512090601e13),(69,1.0e37,2.1181512090598e13),(69,1.0e37,2.1181512090602e13),(69,1.0e37,Infinity),(69,1.0e37,1.0e307),(69,1.0e37,2.11815120906e13),(69,2.017141e12,2.11815120906e13),(69,2.017141e12,2.11815120906e13),(69,2.017141e12,2.1181512090599e13),(69,2.017141e12,2.1181512090601e13),(69,2.017141e12,2.1181512090598e13),(69,2.017141e12,2.1181512090602e13),(69,2.017141e12,Infinity),(69,2.017141e12,1.0e307),(69,2.017141e12,2.11815120906e13),(70,2.017141e12,2.11815120906e13),(70,2.017141e12,2.11815120906e13),(70,2.017141e12,2.1181512090599e13),(70,2.017141e12,2.1181512090601e13),(70,2.017141e12,2.1181512090598e13),(70,2.017141e12,2.1181512090602e13),(70,2.017141e12,Infinity),(70,2.017141e12,1.0e307),(70,2.017141e12,2.11815120906e13),(70,2.017141e12,2.11815120906e13),(70,2.017141e12,2.11815120906e13),(70,2.017141e12,2.1181512090599e13),(70,2.017141e12,2.1181512090601e13),(70,2.017141e12,2.1181512090598e13),(70,2.017141e12,2.1181512090602e13),(70,2.017141e12,Infinity),(70,2.017141e12,1.0e307),(70,2.017141e12,2.11815120906e13),(70,2.017141e12,2.11815120906e13),(70,2.017141e12,2.11815120906e13),(70,2.017141e12,2.1181512090599e13),(70,2.017141e12,2.1181512090601e13),(70,2.017141e12,2.1181512090598e13),(70,2.017141e12,2.1181512090602e13),(70,2.017141e12,Infinity),(70,2.017141e12,1.0e307),(70,2.017141e12,2.11815120906e13),(70,2.017141e12,2.11815120906e13),(70,2.017141e12,2.11815120906e13),(70,2.017141e12,2.1181512090599e13),(70,2.017141e12,2.1181512090601e13),(70,2.017141e12,2.1181512090598e13),(70,2.017141e12,2.1181512090602e13),(70,2.017141e12,Infinity),(70,2.017141e12,1.0e307),(70,2.017141e12,2.11815120906e13),(70,2.017141e12,2.11815120906e13),(70,2.017141e12,2.11815120906e13),(70,2.017141e12,2.1181512090599e13),(70,2.017141e12,2.1181512090601e13),(70,2.017141e12,2.1181512090598e13),(70,2.017141e12,2.1181512090602e13),(70,2.017141e12,Infinity),(70,2.017141e12,1.0e307),(70,2.017141e12,2.11815120906e13),(70,2.017141e12,2.11815120906e13),(70,2.017141e12,2.11815120906e13),(70,2.017141e12,2.1181512090599e13),(70,2.017141e12,2.1181512090601e13),(70,2.017141e12,2.1181512090598e13),(70,2.017141e12,2.1181512090602e13),(70,2.017141e12,Infinity),(70,2.017141e12,1.0e307),(70,2.017141e12,2.11815120906e13),(70,Infinity,2.11815120906e13),(70,Infinity,2.11815120906e13),(70,Infinity,2.1181512090599e13),(70,Infinity,2.1181512090601e13),(70,Infinity,2.1181512090598e13),(70,Infinity,2.1181512090602e13),(70,Infinity,Infinity),(70,Infinity,1.0e307),(70,Infinity,2.11815120906e13),(70,1.0e37,2.11815120906e13),(70,1.0e37,2.11815120906e13),(70,1.0e37,2.1181512090599e13),(70,1.0e37,2.1181512090601e13),(70,1.0e37,2.1181512090598e13),(70,1.0e37,2.1181512090602e13),(70,1.0e37,Infinity),(70,1.0e37,1.0e307),(70,1.0e37,2.11815120906e13),(70,2.017141e12,2.11815120906e13),(70,2.017141e12,2.11815120906e13),(70,2.017141e12,2.1181512090599e13),(70,2.017141e12,2.1181512090601e13),(70,2.017141e12,2.1181512090598e13),(70,2.017141e12,2.1181512090602e13),(70,2.017141e12,Infinity),(70,2.017141e12,1.0e307),(70,2.017141e12,2.11815120906e13),(71,2.017141e12,2.11815120906e13),(71,2.017141e12,2.11815120906e13),(71,2.017141e12,2.1181512090599e13),(71,2.017141e12,2.1181512090601e13),(71,2.017141e12,2.1181512090598e13),(71,2.017141e12,2.1181512090602e13),(71,2.017141e12,Infinity),(71,2.017141e12,1.0e307),(71,2.017141e12,2.11815120906e13),(71,2.017141e12,2.11815120906e13),(71,2.017141e12,2.11815120906e13),(71,2.017141e12,2.1181512090599e13),(71,2.017141e12,2.1181512090601e13),(71,2.017141e12,2.1181512090598e13),(71,2.017141e12,2.1181512090602e13),(71,2.017141e12,Infinity),(71,2.017141e12,1.0e307),(71,2.017141e12,2.11815120906e13),(71,2.017141e12,2.11815120906e13),(71,2.017141e12,2.11815120906e13),(71,2.017141e12,2.1181512090599e13),(71,2.017141e12,2.1181512090601e13),(71,2.017141e12,2.1181512090598e13),(71,2.017141e12,2.1181512090602e13),(71,2.017141e12,Infinity),(71,2.017141e12,1.0e307),(71,2.017141e12,2.11815120906e13),(71,2.017141e12,2.11815120906e13),(71,2.017141e12,2.11815120906e13),(71,2.017141e12,2.1181512090599e13),(71,2.017141e12,2.1181512090601e13),(71,2.017141e12,2.1181512090598e13),(71,2.017141e12,2.1181512090602e13),(71,2.017141e12,Infinity),(71,2.017141e12,1.0e307),(71,2.017141e12,2.11815120906e13),(71,2.017141e12,2.11815120906e13),(71,2.017141e12,2.11815120906e13),(71,2.017141e12,2.1181512090599e13),(71,2.017141e12,2.1181512090601e13),(71,2.017141e12,2.1181512090598e13),(71,2.017141e12,2.1181512090602e13),(71,2.017141e12,Infinity),(71,2.017141e12,1.0e307),(71,2.017141e12,2.11815120906e13),(71,2.017141e12,2.11815120906e13),(71,2.017141e12,2.11815120906e13),(71,2.017141e12,2.1181512090599e13),(71,2.017141e12,2.1181512090601e13),(71,2.017141e12,2.1181512090598e13),(71,2.017141e12,2.1181512090602e13),(71,2.017141e12,Infinity),(71,2.017141e12,1.0e307),(71,2.017141e12,2.11815120906e13),(71,Infinity,2.11815120906e13),(71,Infinity,2.11815120906e13),(71,Infinity,2.1181512090599e13),(71,Infinity,2.1181512090601e13),(71,Infinity,2.1181512090598e13),(71,Infinity,2.1181512090602e13),(71,Infinity,Infinity),(71,Infinity,1.0e307),(71,Infinity,2.11815120906e13),(71,1.0e37,2.11815120906e13),(71,1.0e37,2.11815120906e13),(71,1.0e37,2.1181512090599e13),(71,1.0e37,2.1181512090601e13),(71,1.0e37,2.1181512090598e13),(71,1.0e37,2.1181512090602e13),(71,1.0e37,Infinity),(71,1.0e37,1.0e307),(71,1.0e37,2.11815120906e13),(71,2.017141e12,2.11815120906e13),(71,2.017141e12,2.11815120906e13),(71,2.017141e12,2.1181512090599e13),(71,2.017141e12,2.1181512090601e13),(71,2.017141e12,2.1181512090598e13),(71,2.017141e12,2.1181512090602e13),(71,2.017141e12,Infinity),(71,2.017141e12,1.0e307),(71,2.017141e12,2.11815120906e13),(68,2.017141e12,2.11815120906e13),(68,2.017141e12,2.11815120906e13),(68,2.017141e12,2.1181512090599e13),(68,2.017141e12,2.1181512090601e13),(68,2.017141e12,2.1181512090598e13),(68,2.017141e12,2.1181512090602e13),(68,2.017141e12,Infinity),(68,2.017141e12,1.0e307),(68,2.017141e12,2.11815120906e13),(68,2.017141e12,2.11815120906e13),(68,2.017141e12,2.11815120906e13),(68,2.017141e12,2.1181512090599e13),(68,2.017141e12,2.1181512090601e13),(68,2.017141e12,2.1181512090598e13),(68,2.017141e12,2.1181512090602e13),(68,2.017141e12,Infinity),(68,2.017141e12,1.0e307),(68,2.017141e12,2.11815120906e13),(68,2.017141e12,2.11815120906e13),(68,2.017141e12,2.11815120906e13),(68,2.017141e12,2.1181512090599e13),(68,2.017141e12,2.1181512090601e13),(68,2.017141e12,2.1181512090598e13),(68,2.017141e12,2.1181512090602e13),(68,2.017141e12,Infinity),(68,2.017141e12,1.0e307),(68,2.017141e12,2.11815120906e13),(68,2.017141e12,2.11815120906e13),(68,2.017141e12,2.11815120906e13),(68,2.017141e12,2.1181512090599e13),(68,2.017141e12,2.1181512090601e13),(68,2.017141e12,2.1181512090598e13),(68,2.017141e12,2.1181512090602e13),(68,2.017141e12,Infinity),(68,2.017141e12,1.0e307),(68,2.017141e12,2.11815120906e13),(68,2.017141e12,2.11815120906e13),(68,2.017141e12,2.11815120906e13),(68,2.017141e12,2.1181512090599e13),(68,2.017141e12,2.1181512090601e13),(68,2.017141e12,2.1181512090598e13),(68,2.017141e12,2.1181512090602e13),(68,2.017141e12,Infinity),(68,2.017141e12,1.0e307),(68,2.017141e12,2.11815120906e13),(68,2.017141e12,2.11815120906e13),(68,2.017141e12,2.11815120906e13),(68,2.017141e12,2.1181512090599e13),(68,2.017141e12,2.1181512090601e13),(68,2.017141e12,2.1181512090598e13),(68,2.017141e12,2.1181512090602e13),(68,2.017141e12,Infinity),(68,2.017141e12,1.0e307),(68,2.017141e12,2.11815120906e13),(68,Infinity,2.11815120906e13),(68,Infinity,2.11815120906e13),(68,Infinity,2.1181512090599e13),(68,Infinity,2.1181512090601e13),(68,Infinity,2.1181512090598e13),(68,Infinity,2.1181512090602e13),(68,Infinity,Infinity),(68,Infinity,1.0e307),(68,Infinity,2.11815120906e13),(68,1.0e37,2.11815120906e13),(68,1.0e37,2.11815120906e13),(68,1.0e37,2.1181512090599e13),(68,1.0e37,2.1181512090601e13),(68,1.0e37,2.1181512090598e13),(68,1.0e37,2.1181512090602e13),(68,1.0e37,Infinity),(68,1.0e37,1.0e307),(68,1.0e37,2.11815120906e13),(68,2.017141e12,2.11815120906e13),(68,2.017141e12,2.11815120906e13),(68,2.017141e12,2.1181512090599e13),(68,2.017141e12,2.1181512090601e13),(68,2.017141e12,2.1181512090598e13),(68,2.017141e12,2.1181512090602e13),(68,2.017141e12,Infinity),(68,2.017141e12,1.0e307),(68,2.017141e12,2.11815120906e13)]
+various sized tuple returns
+[(3,0,0),(3,1,0),(3,2,0),(3,18446744073709551615,0),(3,0,1),(3,1,1),(3,2,1),(3,18446744073709551615,1),(3,0,2),(3,1,2),(3,2,2),(3,18446744073709551615,2),(3,0,18446744073709551615),(3,1,18446744073709551615),(3,2,18446744073709551615),(3,18446744073709551615,18446744073709551615)]
+[(12.0,11.0,Just (-18446744073709551617),Just 18446744073709551617,8.0,7.0,Just 1,Nothing,4,3,Nothing,Nothing),(12.0,11.0,Just (-18446744073709551617),Just 18446744073709551617,8.0,7.0,Just 1,Nothing,4,3,Just 1,Nothing),(12.0,11.0,Just (-18446744073709551617),Just 18446744073709551617,8.0,7.0,Just 1,Nothing,4,3,Just 18446744073709551617,Nothing),(12.0,11.0,Just (-18446744073709551617),Just 18446744073709551617,8.0,7.0,Just 1,Nothing,4,3,Just (-18446744073709551617),Nothing),(12.0,11.0,Just (-18446744073709551617),Just 18446744073709551617,8.0,7.0,Just 1,Nothing,4,3,Nothing,Just 1),(12.0,11.0,Just (-18446744073709551617),Just 18446744073709551617,8.0,7.0,Just 1,Nothing,4,3,Just 1,Just 1),(12.0,11.0,Just (-18446744073709551617),Just 18446744073709551617,8.0,7.0,Just 1,Nothing,4,3,Just 18446744073709551617,Just 1),(12.0,11.0,Just (-18446744073709551617),Just 18446744073709551617,8.0,7.0,Just 1,Nothing,4,3,Just (-18446744073709551617),Just 1),(12.0,11.0,Just (-18446744073709551617),Just 18446744073709551617,8.0,7.0,Just 1,Nothing,4,3,Nothing,Just 18446744073709551617),(12.0,11.0,Just (-18446744073709551617),Just 18446744073709551617,8.0,7.0,Just 1,Nothing,4,3,Just 1,Just 18446744073709551617),(12.0,11.0,Just (-18446744073709551617),Just 18446744073709551617,8.0,7.0,Just 1,Nothing,4,3,Just 18446744073709551617,Just 18446744073709551617),(12.0,11.0,Just (-18446744073709551617),Just 18446744073709551617,8.0,7.0,Just 1,Nothing,4,3,Just (-18446744073709551617),Just 18446744073709551617),(12.0,11.0,Just (-18446744073709551617),Just 18446744073709551617,8.0,7.0,Just 1,Nothing,4,3,Nothing,Just (-18446744073709551617)),(12.0,11.0,Just (-18446744073709551617),Just 18446744073709551617,8.0,7.0,Just 1,Nothing,4,3,Just 1,Just (-18446744073709551617)),(12.0,11.0,Just (-18446744073709551617),Just 18446744073709551617,8.0,7.0,Just 1,Nothing,4,3,Just 18446744073709551617,Just (-18446744073709551617)),(12.0,11.0,Just (-18446744073709551617),Just 18446744073709551617,8.0,7.0,Just 1,Nothing,4,3,Just (-18446744073709551617),Just (-18446744073709551617))]
+[(5.0,Just 1,3.0,Nothing,0,Nothing),(5.0,Just 1,3.0,Nothing,1,Nothing),(5.0,Just 1,3.0,Nothing,2,Nothing),(5.0,Just 1,3.0,Nothing,18446744073709551615,Nothing),(5.0,Just 1,3.0,Nothing,0,Just 1),(5.0,Just 1,3.0,Nothing,1,Just 1),(5.0,Just 1,3.0,Nothing,2,Just 1),(5.0,Just 1,3.0,Nothing,18446744073709551615,Just 1),(5.0,Just 1,3.0,Nothing,0,Just 18446744073709551617),(5.0,Just 1,3.0,Nothing,1,Just 18446744073709551617),(5.0,Just 1,3.0,Nothing,2,Just 18446744073709551617),(5.0,Just 1,3.0,Nothing,18446744073709551615,Just 18446744073709551617),(5.0,Just 1,3.0,Nothing,0,Just (-18446744073709551617)),(5.0,Just 1,3.0,Nothing,1,Just (-18446744073709551617)),(5.0,Just 1,3.0,Nothing,2,Just (-18446744073709551617)),(5.0,Just 1,3.0,Nothing,18446744073709551615,Just (-18446744073709551617))]
+[(Nothing,Nothing),(Just 1,Nothing),(Just 18446744073709551617,Nothing),(Just (-18446744073709551617),Nothing),(Nothing,Just 1),(Just 1,Just 1),(Just 18446744073709551617,Just 1),(Just (-18446744073709551617),Just 1),(Nothing,Just 18446744073709551617),(Just 1,Just 18446744073709551617),(Just 18446744073709551617,Just 18446744073709551617),(Just (-18446744073709551617),Just 18446744073709551617),(Nothing,Just (-18446744073709551617)),(Just 1,Just (-18446744073709551617)),(Just 18446744073709551617,Just (-18446744073709551617)),(Just (-18446744073709551617),Just (-18446744073709551617))]
+arrays
+(11,13)
+(13,11)


=====================================
testsuite/tests/ghci/should_run/GHCiPrimCall/GHCiPrimCall.stdout-ws-32
=====================================
@@ -0,0 +1,58 @@
+zero arguments
+123
+1.0
+1.0
+one argument functions
+[0,-1,1,-128,127]
+[0,-1,1,-32768,32767]
+[0,-1,1,-2147483648,2147483647]
+[0,-1,1,-9223372036854775808,9223372036854775807]
+[Nothing,Just 1,Just 18446744073709551617,Just (-18446744073709551617)]
+[0,1,2,4294967295]
+[-0.0,0.0,-1.0,1.0,-2.0,2.0,Infinity,1.0e37,-1.0e-37]
+[-0.0,0.0,-1.0,1.0,-2.0,2.0,Infinity,1.0e307,-1.0e-307]
+[0,1,2,4294967296,18446744073709551615]
+[(0,0),(-1,-1),(1,1),(-128,-128),(127,127)]
+[(0,0),(-1,-1),(1,1),(-32768,-32768),(32767,32767)]
+[(0,0),(-1,-1),(1,1),(-2147483648,-2147483648),(2147483647,2147483647)]
+[(0,0),(-1,-1),(1,1),(-9223372036854775808,-9223372036854775808),(9223372036854775807,9223372036854775807)]
+[(Nothing,Nothing),(Just 1,Just 1),(Just 18446744073709551617,Just 18446744073709551617),(Just (-18446744073709551617),Just (-18446744073709551617))]
+[(0,0),(1,1),(2,2),(4294967295,4294967295)]
+[(-0.0,-0.0),(0.0,0.0),(-1.0,-1.0),(1.0,1.0),(-2.0,-2.0),(2.0,2.0),(Infinity,Infinity),(1.0e37,1.0e37),(-1.0e-37,-1.0e-37)]
+[(-0.0,-0.0),(0.0,0.0),(-1.0,-1.0),(1.0,1.0),(-2.0,-2.0),(2.0,2.0),(Infinity,Infinity),(1.0e307,1.0e307),(-1.0e-307,-1.0e-307)]
+[(0,0),(1,1),(2,2),(4294967296,4294967296),(18446744073709551615,18446744073709551615)]
+two argument functions
+[0,0,0,0,0,-1,-1,-1,-1,-1,1,1,1,1,1,-128,-128,-128,-128,-128,127,127,127,127,127]
+[0,0,0,0,0,-1,-1,-1,-1,-1,1,1,1,1,1,-32768,-32768,-32768,-32768,-32768,32767,32767,32767,32767,32767]
+[0,0,0,0,0,-1,-1,-1,-1,-1,1,1,1,1,1,-2147483648,-2147483648,-2147483648,-2147483648,-2147483648,2147483647,2147483647,2147483647,2147483647,2147483647]
+[0,0,0,0,0,-1,-1,-1,-1,-1,1,1,1,1,1,-9223372036854775808,-9223372036854775808,-9223372036854775808,-9223372036854775808,-9223372036854775808,9223372036854775807,9223372036854775807,9223372036854775807,9223372036854775807,9223372036854775807]
+[Nothing,Nothing,Nothing,Nothing,Just 1,Just 1,Just 1,Just 1,Just 18446744073709551617,Just 18446744073709551617,Just 18446744073709551617,Just 18446744073709551617,Just (-18446744073709551617),Just (-18446744073709551617),Just (-18446744073709551617),Just (-18446744073709551617)]
+[0,0,0,0,1,1,1,1,2,2,2,2,4294967295,4294967295,4294967295,4294967295]
+[-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,-2.0,-2.0,-2.0,-2.0,-2.0,-2.0,-2.0,-2.0,-2.0,2.0,2.0,2.0,2.0,2.0,2.0,2.0,2.0,2.0,Infinity,Infinity,Infinity,Infinity,Infinity,Infinity,Infinity,Infinity,Infinity,1.0e37,1.0e37,1.0e37,1.0e37,1.0e37,1.0e37,1.0e37,1.0e37,1.0e37,-1.0e-37,-1.0e-37,-1.0e-37,-1.0e-37,-1.0e-37,-1.0e-37,-1.0e-37,-1.0e-37,-1.0e-37]
+[-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,-2.0,-2.0,-2.0,-2.0,-2.0,-2.0,-2.0,-2.0,-2.0,2.0,2.0,2.0,2.0,2.0,2.0,2.0,2.0,2.0,Infinity,Infinity,Infinity,Infinity,Infinity,Infinity,Infinity,Infinity,Infinity,1.0e307,1.0e307,1.0e307,1.0e307,1.0e307,1.0e307,1.0e307,1.0e307,1.0e307,-1.0e-307,-1.0e-307,-1.0e-307,-1.0e-307,-1.0e-307,-1.0e-307,-1.0e-307,-1.0e-307,-1.0e-307]
+[0,0,0,0,0,1,1,1,1,1,2,2,2,2,2,4294967296,4294967296,4294967296,4294967296,4294967296,18446744073709551615,18446744073709551615,18446744073709551615,18446744073709551615,18446744073709551615]
+[0,-1,1,-128,127,0,-1,1,-128,127,0,-1,1,-128,127,0,-1,1,-128,127,0,-1,1,-128,127]
+[0,-1,1,-32768,32767,0,-1,1,-32768,32767,0,-1,1,-32768,32767,0,-1,1,-32768,32767,0,-1,1,-32768,32767]
+[0,-1,1,-2147483648,2147483647,0,-1,1,-2147483648,2147483647,0,-1,1,-2147483648,2147483647,0,-1,1,-2147483648,2147483647,0,-1,1,-2147483648,2147483647]
+[0,-1,1,-9223372036854775808,9223372036854775807,0,-1,1,-9223372036854775808,9223372036854775807,0,-1,1,-9223372036854775808,9223372036854775807,0,-1,1,-9223372036854775808,9223372036854775807,0,-1,1,-9223372036854775808,9223372036854775807]
+[Nothing,Just 1,Just 18446744073709551617,Just (-18446744073709551617),Nothing,Just 1,Just 18446744073709551617,Just (-18446744073709551617),Nothing,Just 1,Just 18446744073709551617,Just (-18446744073709551617),Nothing,Just 1,Just 18446744073709551617,Just (-18446744073709551617)]
+[0,1,2,4294967295,0,1,2,4294967295,0,1,2,4294967295,0,1,2,4294967295]
+[-0.0,0.0,-1.0,1.0,-2.0,2.0,Infinity,1.0e37,-1.0e-37,-0.0,0.0,-1.0,1.0,-2.0,2.0,Infinity,1.0e37,-1.0e-37,-0.0,0.0,-1.0,1.0,-2.0,2.0,Infinity,1.0e37,-1.0e-37,-0.0,0.0,-1.0,1.0,-2.0,2.0,Infinity,1.0e37,-1.0e-37,-0.0,0.0,-1.0,1.0,-2.0,2.0,Infinity,1.0e37,-1.0e-37,-0.0,0.0,-1.0,1.0,-2.0,2.0,Infinity,1.0e37,-1.0e-37,-0.0,0.0,-1.0,1.0,-2.0,2.0,Infinity,1.0e37,-1.0e-37,-0.0,0.0,-1.0,1.0,-2.0,2.0,Infinity,1.0e37,-1.0e-37,-0.0,0.0,-1.0,1.0,-2.0,2.0,Infinity,1.0e37,-1.0e-37]
+[-0.0,0.0,-1.0,1.0,-2.0,2.0,Infinity,1.0e307,-1.0e-307,-0.0,0.0,-1.0,1.0,-2.0,2.0,Infinity,1.0e307,-1.0e-307,-0.0,0.0,-1.0,1.0,-2.0,2.0,Infinity,1.0e307,-1.0e-307,-0.0,0.0,-1.0,1.0,-2.0,2.0,Infinity,1.0e307,-1.0e-307,-0.0,0.0,-1.0,1.0,-2.0,2.0,Infinity,1.0e307,-1.0e-307,-0.0,0.0,-1.0,1.0,-2.0,2.0,Infinity,1.0e307,-1.0e-307,-0.0,0.0,-1.0,1.0,-2.0,2.0,Infinity,1.0e307,-1.0e-307,-0.0,0.0,-1.0,1.0,-2.0,2.0,Infinity,1.0e307,-1.0e-307,-0.0,0.0,-1.0,1.0,-2.0,2.0,Infinity,1.0e307,-1.0e-307]
+[0,1,2,4294967296,18446744073709551615,0,1,2,4294967296,18446744073709551615,0,1,2,4294967296,18446744073709551615,0,1,2,4294967296,18446744073709551615,0,1,2,4294967296,18446744073709551615]
+additional floating point tests
+[-0.0,0.0,-1.0,1.0,-2.0,2.0,Infinity,1.0e37,-1.0e-37,0.0,0.0,-1.0,1.0,-2.0,2.0,Infinity,1.0e37,-1.0e-37,-1.0,-1.0,-2.0,0.0,-3.0,1.0,Infinity,1.0e37,-1.0,1.0,1.0,0.0,2.0,-1.0,3.0,Infinity,1.0e37,1.0,-2.0,-2.0,-3.0,-1.0,-4.0,0.0,Infinity,1.0e37,-2.0,2.0,2.0,1.0,3.0,0.0,4.0,Infinity,1.0e37,2.0,Infinity,Infinity,Infinity,Infinity,Infinity,Infinity,Infinity,Infinity,Infinity,1.0e37,1.0e37,1.0e37,1.0e37,1.0e37,1.0e37,Infinity,2.0e37,1.0e37,-1.0e-37,-1.0e-37,-1.0,1.0,-2.0,2.0,Infinity,1.0e37,-2.0e-37]
+[-0.0,0.0,-1.0,1.0,-2.0,2.0,Infinity,1.0e307,-1.0e-307,0.0,0.0,-1.0,1.0,-2.0,2.0,Infinity,1.0e307,-1.0e-307,-1.0,-1.0,-2.0,0.0,-3.0,1.0,Infinity,1.0e307,-1.0,1.0,1.0,0.0,2.0,-1.0,3.0,Infinity,1.0e307,1.0,-2.0,-2.0,-3.0,-1.0,-4.0,0.0,Infinity,1.0e307,-2.0,2.0,2.0,1.0,3.0,0.0,4.0,Infinity,1.0e307,2.0,Infinity,Infinity,Infinity,Infinity,Infinity,Infinity,Infinity,Infinity,Infinity,1.0e307,1.0e307,1.0e307,1.0e307,1.0e307,1.0e307,Infinity,2.0e307,1.0e307,-1.0e-307,-1.0e-307,-1.0,1.0,-2.0,2.0,Infinity,1.0e307,-2.0e-307]
+[-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,-2.0,-2.0,-2.0,-2.0,-2.0,-2.0,-2.0,-2.0,-2.0,2.0,2.0,2.0,2.0,2.0,2.0,2.0,2.0,2.0,Infinity,Infinity,Infinity,Infinity,Infinity,Infinity,Infinity,Infinity,Infinity,1.0e37,1.0e37,1.0e37,1.0e37,1.0e37,1.0e37,1.0e37,1.0e37,1.0e37,-1.0e-37,-1.0e-37,-1.0e-37,-1.0e-37,-1.0e-37,-1.0e-37,-1.0e-37,-1.0e-37,-1.0e-37]
+[-0.0,0.0,-1.0,1.0,-2.0,2.0,Infinity,1.0e307,-1.0e-307,-0.0,0.0,-1.0,1.0,-2.0,2.0,Infinity,1.0e307,-1.0e-307,-0.0,0.0,-1.0,1.0,-2.0,2.0,Infinity,1.0e307,-1.0e-307,-0.0,0.0,-1.0,1.0,-2.0,2.0,Infinity,1.0e307,-1.0e-307,-0.0,0.0,-1.0,1.0,-2.0,2.0,Infinity,1.0e307,-1.0e-307,-0.0,0.0,-1.0,1.0,-2.0,2.0,Infinity,1.0e307,-1.0e-307,-0.0,0.0,-1.0,1.0,-2.0,2.0,Infinity,1.0e307,-1.0e-307,-0.0,0.0,-1.0,1.0,-2.0,2.0,Infinity,1.0e307,-1.0e-307,-0.0,0.0,-1.0,1.0,-2.0,2.0,Infinity,1.0e307,-1.0e-307]
+[(705030.0,8060400.0),(705030.0,8060400.0),(705030.0,8060399.0),(705030.0,8060401.0),(705030.0,8060398.0),(705030.0,8060402.0),(705030.0,Infinity),(705030.0,1.0e307),(705030.0,8060400.0),(705030.0,8060400.0),(705030.0,8060400.0),(705030.0,8060399.0),(705030.0,8060401.0),(705030.0,8060398.0),(705030.0,8060402.0),(705030.0,Infinity),(705030.0,1.0e307),(705030.0,8060400.0),(705029.0,8060400.0),(705029.0,8060400.0),(705029.0,8060399.0),(705029.0,8060401.0),(705029.0,8060398.0),(705029.0,8060402.0),(705029.0,Infinity),(705029.0,1.0e307),(705029.0,8060400.0),(705031.0,8060400.0),(705031.0,8060400.0),(705031.0,8060399.0),(705031.0,8060401.0),(705031.0,8060398.0),(705031.0,8060402.0),(705031.0,Infinity),(705031.0,1.0e307),(705031.0,8060400.0),(705028.0,8060400.0),(705028.0,8060400.0),(705028.0,8060399.0),(705028.0,8060401.0),(705028.0,8060398.0),(705028.0,8060402.0),(705028.0,Infinity),(705028.0,1.0e307),(705028.0,8060400.0),(705032.0,8060400.0),(705032.0,8060400.0),(705032.0,8060399.0),(705032.0,8060401.0),(705032.0,8060398.0),(705032.0,8060402.0),(705032.0,Infinity),(705032.0,1.0e307),(705032.0,8060400.0),(Infinity,8060400.0),(Infinity,8060400.0),(Infinity,8060399.0),(Infinity,8060401.0),(Infinity,8060398.0),(Infinity,8060402.0),(Infinity,Infinity),(Infinity,1.0e307),(Infinity,8060400.0),(1.0e37,8060400.0),(1.0e37,8060400.0),(1.0e37,8060399.0),(1.0e37,8060401.0),(1.0e37,8060398.0),(1.0e37,8060402.0),(1.0e37,Infinity),(1.0e37,1.0e307),(1.0e37,8060400.0),(705030.0,8060400.0),(705030.0,8060400.0),(705030.0,8060399.0),(705030.0,8060401.0),(705030.0,8060398.0),(705030.0,8060402.0),(705030.0,Infinity),(705030.0,1.0e307),(705030.0,8060400.0)]
+[(705030.0,8060400.0),(705030.0,8060400.0),(705030.0,8060399.0),(705030.0,8060401.0),(705030.0,8060398.0),(705030.0,8060402.0),(705030.0,Infinity),(705030.0,1.0e37),(705030.0,8060400.0),(705030.0,8060400.0),(705030.0,8060400.0),(705030.0,8060399.0),(705030.0,8060401.0),(705030.0,8060398.0),(705030.0,8060402.0),(705030.0,Infinity),(705030.0,1.0e37),(705030.0,8060400.0),(705029.0,8060400.0),(705029.0,8060400.0),(705029.0,8060399.0),(705029.0,8060401.0),(705029.0,8060398.0),(705029.0,8060402.0),(705029.0,Infinity),(705029.0,1.0e37),(705029.0,8060400.0),(705031.0,8060400.0),(705031.0,8060400.0),(705031.0,8060399.0),(705031.0,8060401.0),(705031.0,8060398.0),(705031.0,8060402.0),(705031.0,Infinity),(705031.0,1.0e37),(705031.0,8060400.0),(705028.0,8060400.0),(705028.0,8060400.0),(705028.0,8060399.0),(705028.0,8060401.0),(705028.0,8060398.0),(705028.0,8060402.0),(705028.0,Infinity),(705028.0,1.0e37),(705028.0,8060400.0),(705032.0,8060400.0),(705032.0,8060400.0),(705032.0,8060399.0),(705032.0,8060401.0),(705032.0,8060398.0),(705032.0,8060402.0),(705032.0,Infinity),(705032.0,1.0e37),(705032.0,8060400.0),(Infinity,8060400.0),(Infinity,8060400.0),(Infinity,8060399.0),(Infinity,8060401.0),(Infinity,8060398.0),(Infinity,8060402.0),(Infinity,Infinity),(Infinity,1.0e37),(Infinity,8060400.0),(1.0e307,8060400.0),(1.0e307,8060400.0),(1.0e307,8060399.0),(1.0e307,8060401.0),(1.0e307,8060398.0),(1.0e307,8060402.0),(1.0e307,Infinity),(1.0e307,1.0e37),(1.0e307,8060400.0),(705030.0,8060400.0),(705030.0,8060400.0),(705030.0,8060399.0),(705030.0,8060401.0),(705030.0,8060398.0),(705030.0,8060402.0),(705030.0,Infinity),(705030.0,1.0e37),(705030.0,8060400.0)]
+[(69,2.017141e12,2.11815120906e13),(69,2.017141e12,2.11815120906e13),(69,2.017141e12,2.1181512090599e13),(69,2.017141e12,2.1181512090601e13),(69,2.017141e12,2.1181512090598e13),(69,2.017141e12,2.1181512090602e13),(69,2.017141e12,Infinity),(69,2.017141e12,1.0e307),(69,2.017141e12,2.11815120906e13),(69,2.017141e12,2.11815120906e13),(69,2.017141e12,2.11815120906e13),(69,2.017141e12,2.1181512090599e13),(69,2.017141e12,2.1181512090601e13),(69,2.017141e12,2.1181512090598e13),(69,2.017141e12,2.1181512090602e13),(69,2.017141e12,Infinity),(69,2.017141e12,1.0e307),(69,2.017141e12,2.11815120906e13),(69,2.017141e12,2.11815120906e13),(69,2.017141e12,2.11815120906e13),(69,2.017141e12,2.1181512090599e13),(69,2.017141e12,2.1181512090601e13),(69,2.017141e12,2.1181512090598e13),(69,2.017141e12,2.1181512090602e13),(69,2.017141e12,Infinity),(69,2.017141e12,1.0e307),(69,2.017141e12,2.11815120906e13),(69,2.017141e12,2.11815120906e13),(69,2.017141e12,2.11815120906e13),(69,2.017141e12,2.1181512090599e13),(69,2.017141e12,2.1181512090601e13),(69,2.017141e12,2.1181512090598e13),(69,2.017141e12,2.1181512090602e13),(69,2.017141e12,Infinity),(69,2.017141e12,1.0e307),(69,2.017141e12,2.11815120906e13),(69,2.017141e12,2.11815120906e13),(69,2.017141e12,2.11815120906e13),(69,2.017141e12,2.1181512090599e13),(69,2.017141e12,2.1181512090601e13),(69,2.017141e12,2.1181512090598e13),(69,2.017141e12,2.1181512090602e13),(69,2.017141e12,Infinity),(69,2.017141e12,1.0e307),(69,2.017141e12,2.11815120906e13),(69,2.017141e12,2.11815120906e13),(69,2.017141e12,2.11815120906e13),(69,2.017141e12,2.1181512090599e13),(69,2.017141e12,2.1181512090601e13),(69,2.017141e12,2.1181512090598e13),(69,2.017141e12,2.1181512090602e13),(69,2.017141e12,Infinity),(69,2.017141e12,1.0e307),(69,2.017141e12,2.11815120906e13),(69,Infinity,2.11815120906e13),(69,Infinity,2.11815120906e13),(69,Infinity,2.1181512090599e13),(69,Infinity,2.1181512090601e13),(69,Infinity,2.1181512090598e13),(69,Infinity,2.1181512090602e13),(69,Infinity,Infinity),(69,Infinity,1.0e307),(69,Infinity,2.11815120906e13),(69,1.0e37,2.11815120906e13),(69,1.0e37,2.11815120906e13),(69,1.0e37,2.1181512090599e13),(69,1.0e37,2.1181512090601e13),(69,1.0e37,2.1181512090598e13),(69,1.0e37,2.1181512090602e13),(69,1.0e37,Infinity),(69,1.0e37,1.0e307),(69,1.0e37,2.11815120906e13),(69,2.017141e12,2.11815120906e13),(69,2.017141e12,2.11815120906e13),(69,2.017141e12,2.1181512090599e13),(69,2.017141e12,2.1181512090601e13),(69,2.017141e12,2.1181512090598e13),(69,2.017141e12,2.1181512090602e13),(69,2.017141e12,Infinity),(69,2.017141e12,1.0e307),(69,2.017141e12,2.11815120906e13),(70,2.017141e12,2.11815120906e13),(70,2.017141e12,2.11815120906e13),(70,2.017141e12,2.1181512090599e13),(70,2.017141e12,2.1181512090601e13),(70,2.017141e12,2.1181512090598e13),(70,2.017141e12,2.1181512090602e13),(70,2.017141e12,Infinity),(70,2.017141e12,1.0e307),(70,2.017141e12,2.11815120906e13),(70,2.017141e12,2.11815120906e13),(70,2.017141e12,2.11815120906e13),(70,2.017141e12,2.1181512090599e13),(70,2.017141e12,2.1181512090601e13),(70,2.017141e12,2.1181512090598e13),(70,2.017141e12,2.1181512090602e13),(70,2.017141e12,Infinity),(70,2.017141e12,1.0e307),(70,2.017141e12,2.11815120906e13),(70,2.017141e12,2.11815120906e13),(70,2.017141e12,2.11815120906e13),(70,2.017141e12,2.1181512090599e13),(70,2.017141e12,2.1181512090601e13),(70,2.017141e12,2.1181512090598e13),(70,2.017141e12,2.1181512090602e13),(70,2.017141e12,Infinity),(70,2.017141e12,1.0e307),(70,2.017141e12,2.11815120906e13),(70,2.017141e12,2.11815120906e13),(70,2.017141e12,2.11815120906e13),(70,2.017141e12,2.1181512090599e13),(70,2.017141e12,2.1181512090601e13),(70,2.017141e12,2.1181512090598e13),(70,2.017141e12,2.1181512090602e13),(70,2.017141e12,Infinity),(70,2.017141e12,1.0e307),(70,2.017141e12,2.11815120906e13),(70,2.017141e12,2.11815120906e13),(70,2.017141e12,2.11815120906e13),(70,2.017141e12,2.1181512090599e13),(70,2.017141e12,2.1181512090601e13),(70,2.017141e12,2.1181512090598e13),(70,2.017141e12,2.1181512090602e13),(70,2.017141e12,Infinity),(70,2.017141e12,1.0e307),(70,2.017141e12,2.11815120906e13),(70,2.017141e12,2.11815120906e13),(70,2.017141e12,2.11815120906e13),(70,2.017141e12,2.1181512090599e13),(70,2.017141e12,2.1181512090601e13),(70,2.017141e12,2.1181512090598e13),(70,2.017141e12,2.1181512090602e13),(70,2.017141e12,Infinity),(70,2.017141e12,1.0e307),(70,2.017141e12,2.11815120906e13),(70,Infinity,2.11815120906e13),(70,Infinity,2.11815120906e13),(70,Infinity,2.1181512090599e13),(70,Infinity,2.1181512090601e13),(70,Infinity,2.1181512090598e13),(70,Infinity,2.1181512090602e13),(70,Infinity,Infinity),(70,Infinity,1.0e307),(70,Infinity,2.11815120906e13),(70,1.0e37,2.11815120906e13),(70,1.0e37,2.11815120906e13),(70,1.0e37,2.1181512090599e13),(70,1.0e37,2.1181512090601e13),(70,1.0e37,2.1181512090598e13),(70,1.0e37,2.1181512090602e13),(70,1.0e37,Infinity),(70,1.0e37,1.0e307),(70,1.0e37,2.11815120906e13),(70,2.017141e12,2.11815120906e13),(70,2.017141e12,2.11815120906e13),(70,2.017141e12,2.1181512090599e13),(70,2.017141e12,2.1181512090601e13),(70,2.017141e12,2.1181512090598e13),(70,2.017141e12,2.1181512090602e13),(70,2.017141e12,Infinity),(70,2.017141e12,1.0e307),(70,2.017141e12,2.11815120906e13),(71,2.017141e12,2.11815120906e13),(71,2.017141e12,2.11815120906e13),(71,2.017141e12,2.1181512090599e13),(71,2.017141e12,2.1181512090601e13),(71,2.017141e12,2.1181512090598e13),(71,2.017141e12,2.1181512090602e13),(71,2.017141e12,Infinity),(71,2.017141e12,1.0e307),(71,2.017141e12,2.11815120906e13),(71,2.017141e12,2.11815120906e13),(71,2.017141e12,2.11815120906e13),(71,2.017141e12,2.1181512090599e13),(71,2.017141e12,2.1181512090601e13),(71,2.017141e12,2.1181512090598e13),(71,2.017141e12,2.1181512090602e13),(71,2.017141e12,Infinity),(71,2.017141e12,1.0e307),(71,2.017141e12,2.11815120906e13),(71,2.017141e12,2.11815120906e13),(71,2.017141e12,2.11815120906e13),(71,2.017141e12,2.1181512090599e13),(71,2.017141e12,2.1181512090601e13),(71,2.017141e12,2.1181512090598e13),(71,2.017141e12,2.1181512090602e13),(71,2.017141e12,Infinity),(71,2.017141e12,1.0e307),(71,2.017141e12,2.11815120906e13),(71,2.017141e12,2.11815120906e13),(71,2.017141e12,2.11815120906e13),(71,2.017141e12,2.1181512090599e13),(71,2.017141e12,2.1181512090601e13),(71,2.017141e12,2.1181512090598e13),(71,2.017141e12,2.1181512090602e13),(71,2.017141e12,Infinity),(71,2.017141e12,1.0e307),(71,2.017141e12,2.11815120906e13),(71,2.017141e12,2.11815120906e13),(71,2.017141e12,2.11815120906e13),(71,2.017141e12,2.1181512090599e13),(71,2.017141e12,2.1181512090601e13),(71,2.017141e12,2.1181512090598e13),(71,2.017141e12,2.1181512090602e13),(71,2.017141e12,Infinity),(71,2.017141e12,1.0e307),(71,2.017141e12,2.11815120906e13),(71,2.017141e12,2.11815120906e13),(71,2.017141e12,2.11815120906e13),(71,2.017141e12,2.1181512090599e13),(71,2.017141e12,2.1181512090601e13),(71,2.017141e12,2.1181512090598e13),(71,2.017141e12,2.1181512090602e13),(71,2.017141e12,Infinity),(71,2.017141e12,1.0e307),(71,2.017141e12,2.11815120906e13),(71,Infinity,2.11815120906e13),(71,Infinity,2.11815120906e13),(71,Infinity,2.1181512090599e13),(71,Infinity,2.1181512090601e13),(71,Infinity,2.1181512090598e13),(71,Infinity,2.1181512090602e13),(71,Infinity,Infinity),(71,Infinity,1.0e307),(71,Infinity,2.11815120906e13),(71,1.0e37,2.11815120906e13),(71,1.0e37,2.11815120906e13),(71,1.0e37,2.1181512090599e13),(71,1.0e37,2.1181512090601e13),(71,1.0e37,2.1181512090598e13),(71,1.0e37,2.1181512090602e13),(71,1.0e37,Infinity),(71,1.0e37,1.0e307),(71,1.0e37,2.11815120906e13),(71,2.017141e12,2.11815120906e13),(71,2.017141e12,2.11815120906e13),(71,2.017141e12,2.1181512090599e13),(71,2.017141e12,2.1181512090601e13),(71,2.017141e12,2.1181512090598e13),(71,2.017141e12,2.1181512090602e13),(71,2.017141e12,Infinity),(71,2.017141e12,1.0e307),(71,2.017141e12,2.11815120906e13),(68,2.017141e12,2.11815120906e13),(68,2.017141e12,2.11815120906e13),(68,2.017141e12,2.1181512090599e13),(68,2.017141e12,2.1181512090601e13),(68,2.017141e12,2.1181512090598e13),(68,2.017141e12,2.1181512090602e13),(68,2.017141e12,Infinity),(68,2.017141e12,1.0e307),(68,2.017141e12,2.11815120906e13),(68,2.017141e12,2.11815120906e13),(68,2.017141e12,2.11815120906e13),(68,2.017141e12,2.1181512090599e13),(68,2.017141e12,2.1181512090601e13),(68,2.017141e12,2.1181512090598e13),(68,2.017141e12,2.1181512090602e13),(68,2.017141e12,Infinity),(68,2.017141e12,1.0e307),(68,2.017141e12,2.11815120906e13),(68,2.017141e12,2.11815120906e13),(68,2.017141e12,2.11815120906e13),(68,2.017141e12,2.1181512090599e13),(68,2.017141e12,2.1181512090601e13),(68,2.017141e12,2.1181512090598e13),(68,2.017141e12,2.1181512090602e13),(68,2.017141e12,Infinity),(68,2.017141e12,1.0e307),(68,2.017141e12,2.11815120906e13),(68,2.017141e12,2.11815120906e13),(68,2.017141e12,2.11815120906e13),(68,2.017141e12,2.1181512090599e13),(68,2.017141e12,2.1181512090601e13),(68,2.017141e12,2.1181512090598e13),(68,2.017141e12,2.1181512090602e13),(68,2.017141e12,Infinity),(68,2.017141e12,1.0e307),(68,2.017141e12,2.11815120906e13),(68,2.017141e12,2.11815120906e13),(68,2.017141e12,2.11815120906e13),(68,2.017141e12,2.1181512090599e13),(68,2.017141e12,2.1181512090601e13),(68,2.017141e12,2.1181512090598e13),(68,2.017141e12,2.1181512090602e13),(68,2.017141e12,Infinity),(68,2.017141e12,1.0e307),(68,2.017141e12,2.11815120906e13),(68,2.017141e12,2.11815120906e13),(68,2.017141e12,2.11815120906e13),(68,2.017141e12,2.1181512090599e13),(68,2.017141e12,2.1181512090601e13),(68,2.017141e12,2.1181512090598e13),(68,2.017141e12,2.1181512090602e13),(68,2.017141e12,Infinity),(68,2.017141e12,1.0e307),(68,2.017141e12,2.11815120906e13),(68,Infinity,2.11815120906e13),(68,Infinity,2.11815120906e13),(68,Infinity,2.1181512090599e13),(68,Infinity,2.1181512090601e13),(68,Infinity,2.1181512090598e13),(68,Infinity,2.1181512090602e13),(68,Infinity,Infinity),(68,Infinity,1.0e307),(68,Infinity,2.11815120906e13),(68,1.0e37,2.11815120906e13),(68,1.0e37,2.11815120906e13),(68,1.0e37,2.1181512090599e13),(68,1.0e37,2.1181512090601e13),(68,1.0e37,2.1181512090598e13),(68,1.0e37,2.1181512090602e13),(68,1.0e37,Infinity),(68,1.0e37,1.0e307),(68,1.0e37,2.11815120906e13),(68,2.017141e12,2.11815120906e13),(68,2.017141e12,2.11815120906e13),(68,2.017141e12,2.1181512090599e13),(68,2.017141e12,2.1181512090601e13),(68,2.017141e12,2.1181512090598e13),(68,2.017141e12,2.1181512090602e13),(68,2.017141e12,Infinity),(68,2.017141e12,1.0e307),(68,2.017141e12,2.11815120906e13)]
+various sized tuple returns
+[(3,0,0),(3,1,0),(3,2,0),(3,4294967295,0),(3,0,1),(3,1,1),(3,2,1),(3,4294967295,1),(3,0,2),(3,1,2),(3,2,2),(3,4294967295,2),(3,0,4294967295),(3,1,4294967295),(3,2,4294967295),(3,4294967295,4294967295)]
+[(12.0,11.0,Just (-18446744073709551617),Just 18446744073709551617,8.0,7.0,Just 1,Nothing,4,3,Nothing,Nothing),(12.0,11.0,Just (-18446744073709551617),Just 18446744073709551617,8.0,7.0,Just 1,Nothing,4,3,Just 1,Nothing),(12.0,11.0,Just (-18446744073709551617),Just 18446744073709551617,8.0,7.0,Just 1,Nothing,4,3,Just 18446744073709551617,Nothing),(12.0,11.0,Just (-18446744073709551617),Just 18446744073709551617,8.0,7.0,Just 1,Nothing,4,3,Just (-18446744073709551617),Nothing),(12.0,11.0,Just (-18446744073709551617),Just 18446744073709551617,8.0,7.0,Just 1,Nothing,4,3,Nothing,Just 1),(12.0,11.0,Just (-18446744073709551617),Just 18446744073709551617,8.0,7.0,Just 1,Nothing,4,3,Just 1,Just 1),(12.0,11.0,Just (-18446744073709551617),Just 18446744073709551617,8.0,7.0,Just 1,Nothing,4,3,Just 18446744073709551617,Just 1),(12.0,11.0,Just (-18446744073709551617),Just 18446744073709551617,8.0,7.0,Just 1,Nothing,4,3,Just (-18446744073709551617),Just 1),(12.0,11.0,Just (-18446744073709551617),Just 18446744073709551617,8.0,7.0,Just 1,Nothing,4,3,Nothing,Just 18446744073709551617),(12.0,11.0,Just (-18446744073709551617),Just 18446744073709551617,8.0,7.0,Just 1,Nothing,4,3,Just 1,Just 18446744073709551617),(12.0,11.0,Just (-18446744073709551617),Just 18446744073709551617,8.0,7.0,Just 1,Nothing,4,3,Just 18446744073709551617,Just 18446744073709551617),(12.0,11.0,Just (-18446744073709551617),Just 18446744073709551617,8.0,7.0,Just 1,Nothing,4,3,Just (-18446744073709551617),Just 18446744073709551617),(12.0,11.0,Just (-18446744073709551617),Just 18446744073709551617,8.0,7.0,Just 1,Nothing,4,3,Nothing,Just (-18446744073709551617)),(12.0,11.0,Just (-18446744073709551617),Just 18446744073709551617,8.0,7.0,Just 1,Nothing,4,3,Just 1,Just (-18446744073709551617)),(12.0,11.0,Just (-18446744073709551617),Just 18446744073709551617,8.0,7.0,Just 1,Nothing,4,3,Just 18446744073709551617,Just (-18446744073709551617)),(12.0,11.0,Just (-18446744073709551617),Just 18446744073709551617,8.0,7.0,Just 1,Nothing,4,3,Just (-18446744073709551617),Just (-18446744073709551617))]
+[(5.0,Just 1,3.0,Nothing,0,Nothing),(5.0,Just 1,3.0,Nothing,1,Nothing),(5.0,Just 1,3.0,Nothing,2,Nothing),(5.0,Just 1,3.0,Nothing,4294967295,Nothing),(5.0,Just 1,3.0,Nothing,0,Just 1),(5.0,Just 1,3.0,Nothing,1,Just 1),(5.0,Just 1,3.0,Nothing,2,Just 1),(5.0,Just 1,3.0,Nothing,4294967295,Just 1),(5.0,Just 1,3.0,Nothing,0,Just 18446744073709551617),(5.0,Just 1,3.0,Nothing,1,Just 18446744073709551617),(5.0,Just 1,3.0,Nothing,2,Just 18446744073709551617),(5.0,Just 1,3.0,Nothing,4294967295,Just 18446744073709551617),(5.0,Just 1,3.0,Nothing,0,Just (-18446744073709551617)),(5.0,Just 1,3.0,Nothing,1,Just (-18446744073709551617)),(5.0,Just 1,3.0,Nothing,2,Just (-18446744073709551617)),(5.0,Just 1,3.0,Nothing,4294967295,Just (-18446744073709551617))]
+[(Nothing,Nothing),(Just 1,Nothing),(Just 18446744073709551617,Nothing),(Just (-18446744073709551617),Nothing),(Nothing,Just 1),(Just 1,Just 1),(Just 18446744073709551617,Just 1),(Just (-18446744073709551617),Just 1),(Nothing,Just 18446744073709551617),(Just 1,Just 18446744073709551617),(Just 18446744073709551617,Just 18446744073709551617),(Just (-18446744073709551617),Just 18446744073709551617),(Nothing,Just (-18446744073709551617)),(Just 1,Just (-18446744073709551617)),(Just 18446744073709551617,Just (-18446744073709551617)),(Just (-18446744073709551617),Just (-18446744073709551617))]
+arrays
+(11,13)
+(13,11)


=====================================
testsuite/tests/ghci/should_run/GHCiPrimCall/GHCiPrimCall_cmm.cmm
=====================================
@@ -0,0 +1,145 @@
+#include "Cmm.h"
+
+/* zero arguments */
+cmm_zero() { /* ccall puts("cmm_zero"); buffering gets in the way */ return (); }
+cmm_zero_w() { return (123::W_); }
+cmm_zero_d() { return (1.0::D_); }
+cmm_zero_f() { return (1.0::F_); }
+cmm_zero_l() { return (123::L_); }
+
+/* one argument functions */
+cmm_one1_i8(I8 x) { return (x); }
+cmm_one1_i16(I16 x) { return (x); }
+cmm_one1_i32(I32 x) { return (x); }
+cmm_one1_i64(I64 x) { return (x); }
+cmm_one1_p(P_ x) { return (x); }
+cmm_one1_w(W_ x) { return (x); }
+cmm_one1_f(F_ x) { return (x); }
+cmm_one1_d(D_ x) { return (x); }
+cmm_one1_l(L_ x) { return (x); }
+
+cmm_one2_i8(I8 x) { return (x,x); }
+cmm_one2_i16(I16 x) { return (x,x); }
+cmm_one2_i32(I32 x) { return (x,x); }
+cmm_one2_i64(I64 x) { return (x,x); }
+cmm_one2_p(P_ x) { return (x,x); }
+cmm_one2_w(W_ x) { return (x,x); }
+cmm_one2_f(F_ x) { return (x,x); }
+cmm_one2_d(D_ x) { return (x,x); }
+cmm_one2_l(L_ x) { return (x,x); }
+
+
+/* two argument functions */
+cmm_two1_i8(I8 x, I8 y) { return (x); }
+cmm_two1_i16(I16 x, I16 y) { return (x); }
+cmm_two1_i32(I32 x, I32 y) { return (x); }
+cmm_two1_i64(I64 x, I64 y) { return (x); }
+cmm_two1_p(P_ x, P_ y) { return (x); }
+cmm_two1_w(W_ x, W_ y) { return (x); }
+cmm_two1_f(F_ x, F_ y) { return (x); }
+cmm_two1_d(D_ x, D_ y) { return (x); }
+cmm_two1_l(L_ x, L_ y) { return (x); }
+
+cmm_two2_i8(I8 x, I8 y) { return (y); }
+cmm_two2_i16(I16 x, I16 y) { return (y); }
+cmm_two2_i32(I32 x, I32 y) { return (y); }
+cmm_two2_i64(I64 x, I64 y) { return (y); }
+cmm_two2_p(P_ x, P_ y) { return (y); }
+cmm_two2_w(W_ x, W_ y) { return (y); }
+cmm_two2_f(F_ x, F_ y) { return (y); }
+cmm_two2_d(D_ x, D_ y) { return (y); }
+cmm_two2_l(L_ x, L_ y) { return (y); }
+
+/* additional tests for floating point, since D_ and F_ registers
+   overlap on some platforms */
+cmm_floating_1(F_ x, F_ y) { F_ z; z = %fadd(x, y); return (z); }
+cmm_floating_2(D_ x, D_ y) { D_ z; z = %fadd(x, y); return (z); }
+cmm_floating_3(F_ x, D_ y) { return (x); }
+cmm_floating_4(F_ x, D_ y) { return (y); }
+
+
+cmm_floating_5(F_ x1, D_ x2, F_ x3, D_ x4, F_ x5, D_ x6, F_ x7, D_ x8) {
+    F_ y1;
+    D_ y2;
+
+    y1 = %fadd(x1,x3);
+    y1 = %fadd(y1,x5);
+    y1 = %fadd(y1,x7);
+
+    y2 = %fadd(x2,x4);
+    y2 = %fadd(y2,x6);
+    y2 = %fadd(y2,x8);
+
+    return (y1, y2);
+}
+
+
+cmm_floating_6(D_ x1, F_ x2, D_ x3, F_ x4, D_ x5, F_ x6, D_ x7, F_ x8) {
+    D_ y1;
+    F_ y2;
+
+    y1 = %fadd(x1,x3);
+    y1 = %fadd(y1,x5);
+    y1 = %fadd(y1,x7);
+
+    y2 = %fadd(x2,x4);
+    y2 = %fadd(y2,x6);
+    y2 = %fadd(y2,x8);
+
+    return (y1, y2);
+}
+
+
+cmm_floating_7( W_ x1, F_ x2, D_ x3
+              , W_ x4, F_ x5, D_ x6
+              , W_ x7, F_ x8, D_ x9
+              , W_ x10, F_ x11, D_ x12
+              , W_ x13, F_ x14, D_ x15
+              , W_ x16, F_ x17, D_ x18
+              , W_ x19, F_ x20, D_ x21
+              ) {
+    W_ y1;
+    F_ y2;
+    D_ y3;
+    y1 = x1+x4+x7+x10+x13+x16+x19;
+
+    y2 = %fadd(x2,x5);
+    y2 = %fadd(y2,x8);
+    y2 = %fadd(y2,x11);
+    y2 = %fadd(y2,x14);
+    y2 = %fadd(y2,x17);
+    y2 = %fadd(y2,x20);
+
+    y3 = %fadd(x3,x6);
+    y3 = %fadd(y3,x9);
+    y3 = %fadd(y3,x12);
+    y3 = %fadd(y3,x15);
+    y3 = %fadd(y3,x18);
+    y3 = %fadd(y3,x21);
+
+    return ( y1, y2, y3 );
+}
+
+
+/* various sized tuple returns */
+
+cmm_tuple_1(W_ x, W_ y, W_ z) { return (z, y, x); }
+cmm_tuple_2(P_ p1, P_ p2, W_ w1, W_ w2, P_ p3, P_ p4, D_ d1, D_ d2, P_ p5, P_ p6, F_ f1, F_ f2) {
+    return (f2, f1, p6, p5, d2, d1, p4, p3, w2, w1, p2, p1);
+}
+cmm_tuple_3(P_ p1, W_ w1, P_ p2, D_ d1, P_ p3, F_ f1) {
+    return (f1, p3, d1, p2, w1, p1);
+}
+cmm_tuple_4(P_ p1, P_ p2) { return (p2, p1); }
+
+/* working with arrays */
+cmm_array_1(P_ x) {
+    W_ size;
+    size = StgMutArrPtrs_size(x);
+    return (size);
+}
+
+/* return two arrays */
+cmm_array_2(P_ x, P_ y) {
+    return (y, x);
+}


=====================================
testsuite/tests/ghci/should_run/GHCiPrimCall/Makefile
=====================================
@@ -0,0 +1,4 @@
+.PHONY: GHCiPrimCall
+GHCiPrimCall:
+	'$(TEST_HC)' $(TEST_HC_OPTS) -fPIC -v0 -c GHCiPrimCall_cmm.cmm
+	-'$(TEST_HC)' $(TEST_HC_OPTS) -ignore-dot-ghci -e main GHCiPrimCall.hs GHCiPrimCall_cmm.o || echo $$? >&2


=====================================
testsuite/tests/ghci/should_run/GHCiPrimCall/all.T
=====================================
@@ -0,0 +1,2 @@
+test('GHCiPrimCall', [req_interp], makefile_test, ['GHCiPrimCall'])
+



View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/00577d1ade77980df5eb304b0811c171261c63c0

-- 
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/00577d1ade77980df5eb304b0811c171261c63c0
You're receiving this email because of your account on gitlab.haskell.org.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/ghc-commits/attachments/20230109/dd6f87ab/attachment-0001.html>


More information about the ghc-commits mailing list