[project @ 2002-11-18 14:25:29 by simonpj]
[ghc-hetmet.git] / ghc / compiler / absCSyn / PprAbsC.lhs
index 6f3282a..58cf18f 100644 (file)
@@ -19,14 +19,15 @@ module PprAbsC (
 
 import IO      ( Handle )
 
+import PrimRep 
 import AbsCSyn
 import ClosureInfo
 import AbsCUtils       ( getAmodeRep, nonemptyAbsC,
                          mixedPtrLocn, mixedTypeLocn
                        )
 
-import Constants       ( mIN_UPD_SIZE )
-import ForeignCall     ( CCallSpec(..), CCallTarget(..), playSafe, ccallConvAttribute )
+import ForeignCall     ( CCallSpec(..), CCallTarget(..), playSafe,
+                         playThreadSafe, ccallConvAttribute )
 import CLabel          ( externallyVisibleCLabel,
                          needsCDecl, pprCLabel,
                          mkReturnInfoLabel, mkReturnPtLabel, mkClosureTblLabel,
@@ -46,6 +47,7 @@ import Name           ( NamedThing(..) )
 import DataCon         ( dataConWrapId )
 import Maybes          ( maybeToBool, catMaybes )
 import PrimOp          ( primOpNeedsWrapper )
+import MachOp          ( MachOp(..) )
 import ForeignCall     ( ForeignCall(..) )
 import PrimRep         ( isFloatingRep, PrimRep(..), getPrimRepSize )
 import SMRep           ( pprSMRep )
@@ -53,13 +55,18 @@ import Unique               ( pprUnique, Unique{-instance NamedThing-} )
 import UniqSet         ( emptyUniqSet, elementOfUniqSet,
                          addOneToUniqSet, UniqSet
                        )
-import StgSyn          ( SRT(..), StgOp(..) )
+import StgSyn          ( StgOp(..) )
 import BitSet          ( BitSet, intBS )
 import Outputable
-import GlaExts
-import Util            ( nOfThem )
+import FastString
+import Util            ( lengthExceeds, listLengthCmp )
 
-import ST
+#if __GLASGOW_HASKELL__ >= 504
+import Data.Array.ST
+#endif
+
+import GLAEXTS
+import MONAD_ST
 
 infixr 9 `thenTE`
 \end{code}
@@ -249,6 +256,37 @@ pprAbsC stmt@(COpStmt results (StgPrimOp op) args vol_regs) _
       -- primop macros do their own casting of result;
       -- hence we can toss the provided cast...
 
+-- NEW CASES FOR EXPANDED PRIMOPS
+
+pprAbsC stmt@(CMachOpStmt res mop [arg1,arg2] maybe_vols) _
+  = let prefix_fn = mop `elem` [MO_Dbl_Pwr, MO_Flt_Pwr, MO_NatS_MulMayOflo]
+    in
+    case ppr_maybe_vol_regs maybe_vols of {(saves,restores) ->
+    saves $$
+    hcat (
+       [ppr_amode res, equals]
+       ++ (if prefix_fn 
+           then [pprMachOp_for_C mop, parens (pprAmode arg1 <> comma <> pprAmode arg2)]
+           else [pprAmode arg1, pprMachOp_for_C mop, pprAmode arg2])
+       ++ [semi]
+    )
+    $$ restores
+    }
+
+pprAbsC stmt@(CMachOpStmt res mop [arg1] maybe_vols) _
+  = case ppr_maybe_vol_regs maybe_vols of {(saves,restores) ->
+    saves $$
+    hcat [ppr_amode res, equals, 
+          pprMachOp_for_C mop, parens (pprAmode arg1),
+          semi]
+    $$ restores
+    }
+
+pprAbsC stmt@(CSequential stuff) c
+  = vcat (map (flip pprAbsC c) stuff)
+
+-- end of NEW CASES FOR EXPANDED PRIMOPS
+
 pprAbsC stmt@(CSRT lbl closures) c
   = case (pprTempAndExternDecls stmt) of { (_, pp_exts) ->
          pp_exts
@@ -276,10 +314,10 @@ pprAbsC (CMacroStmt macro as) _
   = hcat [ptext (cStmtMacroText macro), lparen,
        hcat (punctuate comma (map ppr_amode as)),pp_paren_semi] -- no casting
 pprAbsC (CCallProfCtrMacro op as) _
-  = hcat [ptext op, lparen,
+  = hcat [ftext op, lparen,
        hcat (punctuate comma (map ppr_amode as)),pp_paren_semi]
 pprAbsC (CCallProfCCMacro op as) _
-  = hcat [ptext op, lparen,
+  = hcat [ftext op, lparen,
        hcat (punctuate comma (map ppr_amode as)),pp_paren_semi]
 pprAbsC stmt@(CCallTypedef is_tdef (CCallSpec op_str cconv _) uniq results args) _
   =  hsep [ ptext (if is_tdef then SLIT("typedef") else SLIT("extern"))
@@ -349,7 +387,7 @@ pprAbsC stmt@(CCallTypedef is_tdef (CCallSpec op_str cconv _) uniq results args)
       -- should ignore and a (possibly void) result.
      non_void_results =
        let nvrs = grab_non_void_amodes results
-       in ASSERT (length nvrs <= 1) nvrs
+       in ASSERT (listLengthCmp nvrs 1 /= GT) nvrs
 
 pprAbsC (CCodeBlock lbl abs_C) _
   = if not (maybeToBool(nonemptyAbsC abs_C)) then
@@ -374,16 +412,18 @@ pprAbsC (CCodeBlock lbl abs_C) _
     }
 
 
-pprAbsC (CInitHdr cl_info amode cost_centre) _
+pprAbsC (CInitHdr cl_info amode cost_centre size) _
   = hcat [ ptext SLIT("SET_HDR_"), char '(',
                ppr_amode amode, comma,
                pprCLabelAddr info_lbl, comma,
-               if_profiling (pprAmode cost_centre),
+               if_profiling (pprAmode cost_centre), comma,
+               if_profiling (int size),
                pp_paren_semi ]
   where
     info_lbl   = infoTableLabelFromCI cl_info
 
-pprAbsC stmt@(CStaticClosure closure_lbl cl_info cost_centre amodes) _
+
+pprAbsC stmt@(CStaticClosure cl_info cost_centre amodes) _
   = case (pprTempAndExternDecls stmt) of { (_, pp_exts) ->
     vcat [
        pp_exts,
@@ -396,37 +436,27 @@ pprAbsC stmt@(CStaticClosure closure_lbl cl_info cost_centre amodes) _
                ppLocalnessMacro True{-include dyn-} info_lbl,
                char ')'
                ],
-       nest 2 (ppr_payload (amodes ++ padding_wds ++ static_link_field)),
+       nest 2 (ppr_payload amodes),
        ptext SLIT("};") ]
     }
   where
-    info_lbl = infoTableLabelFromCI cl_info
+    closure_lbl = closureLabelFromCI cl_info
+    info_lbl    = infoTableLabelFromCI cl_info
 
     ppr_payload [] = empty
-    ppr_payload ls = comma <+> 
-                    braces (hsep (punctuate comma (map ((text "(L_)" <>).ppr_item) ls)))
-
-    ppr_item item
-      | rep == VoidRep   = text "0" -- might not even need this...
-      | rep == FloatRep  = ppr_amode (floatToWord item)
-      | rep == DoubleRep = hcat (punctuate (text ", (L_)")
-                                (map ppr_amode (doubleToWords item)))
-      | otherwise       = ppr_amode item
+    ppr_payload ls = 
+       comma <+> 
+         (braces $ hsep $ punctuate comma $
+          map (text "(L_)" <>) (foldr ppr_item [] ls))
+
+    ppr_item item rest
+      | rep == VoidRep   = rest
+      | rep == FloatRep  = ppr_amode (floatToWord item) : rest
+      | rep == DoubleRep = map ppr_amode (doubleToWords item) ++ rest
+      | otherwise       = ppr_amode item : rest
       where 
-       rep = getAmodeRep item
+       rep  = getAmodeRep item
 
-    upd_reqd = closureUpdReqd cl_info
-
-    padding_wds
-       | not upd_reqd = []
-       | otherwise    = case max 0 (mIN_UPD_SIZE - length amodes) of { still_needed ->
-                        nOfThem still_needed (mkIntCLit 0) } -- a bunch of 0s
-
-       -- always have a static link field, it's used to save the closure's
-       -- info pointer when we're reverting CAFs (see comment in Storage.c)
-    static_link_field
-       | upd_reqd || staticClosureNeedsLink cl_info = [mkIntCLit 0]
-       | otherwise                                  = []
 
 pprAbsC stmt@(CClosureInfoAndCode cl_info slow maybe_fast cl_descr) _
   = vcat [
@@ -476,8 +506,11 @@ pprAbsC stmt@(CClosureInfoAndCode cl_info slow maybe_fast cl_descr) _
     is_constr = maybeToBool maybe_tag
     (Just tag) = maybe_tag
 
-    needs_srt = infoTblNeedsSRT cl_info
-    srt = getSRTInfo cl_info
+    srt       = closureSRT cl_info
+    needs_srt = case srt of
+                  NoC_SRT -> False
+                  other   -> True
+
 
     size = closureNonHdrSize cl_info
 
@@ -563,9 +596,10 @@ pprAbsC stmt@(CRetVector lbl amodes srt liveness) _
                      (ptext SLIT("RET_VEC_BIG"))
 
 
-pprAbsC stmt@(CModuleInitBlock lbl code) _
+pprAbsC stmt@(CModuleInitBlock plain_lbl lbl code) _
   = vcat [
-       ptext SLIT("START_MOD_INIT") <> parens (pprCLabel lbl),
+       ptext SLIT("START_MOD_INIT") <> 
+           parens (pprCLabel plain_lbl <> comma <> pprCLabel lbl),
        case (pprTempAndExternDecls stmt) of { (_, pp_exts) -> pp_exts },
        pprAbsC code (costs code),
        hcat [ptext SLIT("END_MOD_INIT"), lparen, rparen]
@@ -576,6 +610,133 @@ pprAbsC (CCostCentreStackDecl ccs)    _ = pprCostCentreStackDecl ccs
 \end{code}
 
 \begin{code}
+-- Print a CMachOp in a way suitable for emitting via C.
+pprMachOp_for_C MO_Nat_Add       = char '+'
+pprMachOp_for_C MO_Nat_Sub       = char '-'
+pprMachOp_for_C MO_Nat_Eq        = text "==" 
+pprMachOp_for_C MO_Nat_Ne        = text "!="
+
+pprMachOp_for_C MO_NatS_Ge       = text ">="
+pprMachOp_for_C MO_NatS_Le       = text "<="
+pprMachOp_for_C MO_NatS_Gt       = text ">"
+pprMachOp_for_C MO_NatS_Lt       = text "<"
+
+pprMachOp_for_C MO_NatU_Ge       = text ">="
+pprMachOp_for_C MO_NatU_Le       = text "<="
+pprMachOp_for_C MO_NatU_Gt       = text ">"
+pprMachOp_for_C MO_NatU_Lt       = text "<"
+
+pprMachOp_for_C MO_NatS_Mul      = char '*'
+pprMachOp_for_C MO_NatS_MulMayOflo = text "mulIntMayOflo"
+pprMachOp_for_C MO_NatS_Quot     = char '/'
+pprMachOp_for_C MO_NatS_Rem      = char '%'
+pprMachOp_for_C MO_NatS_Neg      = char '-'
+
+pprMachOp_for_C MO_NatU_Mul      = char '*'
+pprMachOp_for_C MO_NatU_Quot     = char '/'
+pprMachOp_for_C MO_NatU_Rem      = char '%'
+
+pprMachOp_for_C MO_Nat_And       = text "&"
+pprMachOp_for_C MO_Nat_Or        = text "|"
+pprMachOp_for_C MO_Nat_Xor       = text "^"
+pprMachOp_for_C MO_Nat_Not       = text "~"
+pprMachOp_for_C MO_Nat_Shl       = text "<<"
+pprMachOp_for_C MO_Nat_Shr       = text ">>"
+pprMachOp_for_C MO_Nat_Sar       = text ">>"
+
+pprMachOp_for_C MO_32U_Eq        = text "=="
+pprMachOp_for_C MO_32U_Ne        = text "!="
+pprMachOp_for_C MO_32U_Ge        = text ">="
+pprMachOp_for_C MO_32U_Le        = text "<="
+pprMachOp_for_C MO_32U_Gt        = text ">"
+pprMachOp_for_C MO_32U_Lt        = text "<"
+
+pprMachOp_for_C MO_Dbl_Eq        = text "=="
+pprMachOp_for_C MO_Dbl_Ne        = text "!="
+pprMachOp_for_C MO_Dbl_Ge        = text ">="
+pprMachOp_for_C MO_Dbl_Le        = text "<="
+pprMachOp_for_C MO_Dbl_Gt        = text ">"
+pprMachOp_for_C MO_Dbl_Lt        = text "<"
+
+pprMachOp_for_C MO_Dbl_Add       = text "+"
+pprMachOp_for_C MO_Dbl_Sub       = text "-"
+pprMachOp_for_C MO_Dbl_Mul       = text "*"
+pprMachOp_for_C MO_Dbl_Div       = text "/"
+pprMachOp_for_C MO_Dbl_Pwr       = text "pow"
+
+pprMachOp_for_C MO_Dbl_Sin       = text "sin"
+pprMachOp_for_C MO_Dbl_Cos       = text "cos"
+pprMachOp_for_C MO_Dbl_Tan       = text "tan"
+pprMachOp_for_C MO_Dbl_Sinh      = text "sinh"
+pprMachOp_for_C MO_Dbl_Cosh      = text "cosh"
+pprMachOp_for_C MO_Dbl_Tanh      = text "tanh"
+pprMachOp_for_C MO_Dbl_Asin      = text "asin"
+pprMachOp_for_C MO_Dbl_Acos      = text "acos"
+pprMachOp_for_C MO_Dbl_Atan      = text "atan"
+pprMachOp_for_C MO_Dbl_Log       = text "log"
+pprMachOp_for_C MO_Dbl_Exp       = text "exp"
+pprMachOp_for_C MO_Dbl_Sqrt      = text "sqrt"
+pprMachOp_for_C MO_Dbl_Neg       = text "-"
+
+pprMachOp_for_C MO_Flt_Add       = text "+"
+pprMachOp_for_C MO_Flt_Sub       = text "-"
+pprMachOp_for_C MO_Flt_Mul       = text "*"
+pprMachOp_for_C MO_Flt_Div       = text "/"
+pprMachOp_for_C MO_Flt_Pwr       = text "pow"
+
+pprMachOp_for_C MO_Flt_Eq        = text "=="
+pprMachOp_for_C MO_Flt_Ne        = text "!="
+pprMachOp_for_C MO_Flt_Ge        = text ">="
+pprMachOp_for_C MO_Flt_Le        = text "<="
+pprMachOp_for_C MO_Flt_Gt        = text ">"
+pprMachOp_for_C MO_Flt_Lt        = text "<"
+
+pprMachOp_for_C MO_Flt_Sin       = text "sin"
+pprMachOp_for_C MO_Flt_Cos       = text "cos"
+pprMachOp_for_C MO_Flt_Tan       = text "tan"
+pprMachOp_for_C MO_Flt_Sinh      = text "sinh"
+pprMachOp_for_C MO_Flt_Cosh      = text "cosh"
+pprMachOp_for_C MO_Flt_Tanh      = text "tanh"
+pprMachOp_for_C MO_Flt_Asin      = text "asin"
+pprMachOp_for_C MO_Flt_Acos      = text "acos"
+pprMachOp_for_C MO_Flt_Atan      = text "atan"
+pprMachOp_for_C MO_Flt_Log       = text "log"
+pprMachOp_for_C MO_Flt_Exp       = text "exp"
+pprMachOp_for_C MO_Flt_Sqrt      = text "sqrt"
+pprMachOp_for_C MO_Flt_Neg       = text "-"
+
+pprMachOp_for_C MO_32U_to_NatS   = text "(StgInt)"
+pprMachOp_for_C MO_NatS_to_32U   = text "(StgWord32)"
+
+pprMachOp_for_C MO_NatS_to_Dbl   = text "(StgDouble)"
+pprMachOp_for_C MO_Dbl_to_NatS   = text "(StgInt)"
+
+pprMachOp_for_C MO_NatS_to_Flt   = text "(StgFloat)"
+pprMachOp_for_C MO_Flt_to_NatS   = text "(StgInt)"
+
+pprMachOp_for_C MO_NatS_to_NatU  = text "(StgWord)"
+pprMachOp_for_C MO_NatU_to_NatS  = text "(StgInt)"
+
+pprMachOp_for_C MO_NatS_to_NatP  = text "(void*)"
+pprMachOp_for_C MO_NatP_to_NatS  = text "(StgInt)"
+pprMachOp_for_C MO_NatU_to_NatP  = text "(void*)"
+pprMachOp_for_C MO_NatP_to_NatU  = text "(StgWord)"
+
+pprMachOp_for_C MO_Dbl_to_Flt    = text "(StgFloat)"
+pprMachOp_for_C MO_Flt_to_Dbl    = text "(StgDouble)"
+
+pprMachOp_for_C MO_8S_to_NatS    = text "(StgInt8)(StgInt)"
+pprMachOp_for_C MO_16S_to_NatS   = text "(StgInt16)(StgInt)"
+pprMachOp_for_C MO_32S_to_NatS   = text "(StgInt32)(StgInt)"
+
+pprMachOp_for_C MO_8U_to_NatU    = text "(StgWord8)(StgWord)"
+pprMachOp_for_C MO_16U_to_NatU   = text "(StgWord16)(StgWord)"
+pprMachOp_for_C MO_32U_to_NatU   = text "(StgWord32)(StgWord)"
+
+pprMachOp_for_C MO_8U_to_32U     = text "(StgWord32)"
+pprMachOp_for_C MO_32U_to_8U     = text "(StgWord8)"
+
+
 ppLocalness lbl
   = if (externallyVisibleCLabel lbl) 
                then empty 
@@ -622,6 +783,15 @@ non_void amode
 \end{code}
 
 \begin{code}
+ppr_maybe_vol_regs :: Maybe [MagicId] -> (SDoc, SDoc)
+ppr_maybe_vol_regs Nothing
+   = (empty, empty)
+ppr_maybe_vol_regs (Just vrs)
+   = case ppr_vol_regs vrs of
+        (saves, restores) 
+           -> (pp_basic_saves $$ saves,
+               pp_basic_restores $$ restores)
+
 ppr_vol_regs :: [MagicId] -> (SDoc, SDoc)
 
 ppr_vol_regs [] = (empty, empty)
@@ -646,16 +816,12 @@ pp_basic_restores = ptext SLIT("CALLER_RESTORE_SYSTEM")
 \end{code}
 
 \begin{code}
-pp_srt_info srt = 
-    case srt of
-       (lbl, NoSRT) -> 
-               hcat [  int 0, comma, 
-                       int 0, comma, 
-                       int 0, comma ]
-       (lbl, SRT off len) -> 
-               hcat [  pprCLabel lbl, comma,
-                       int off, comma,
-                       int len, comma ]
+pp_srt_info NoC_SRT = hcat [ int 0, comma, 
+                            int 0, comma, 
+                            int 0, comma ]
+pp_srt_info (C_SRT lbl off len) = hcat [ pprCLabel lbl, comma,
+                                        int off, comma,
+                                        int len, comma ]
 \end{code}
 
 \begin{code}
@@ -677,33 +843,27 @@ if_profiling pretty
 -- ---------------------------------------------------------------------------
 
 do_if_stmt discrim tag alt_code deflt c
-  = case tag of
-      -- This special case happens when testing the result of a comparison.
-      -- We can just avoid some redundant clutter in the output.
-      MachInt n | n==0 -> ppr_if_stmt (pprAmode discrim)
-                                     deflt alt_code
-                                     (addrModeCosts discrim Rhs) c
-      other            -> let
-                              cond = hcat [ pprAmode discrim
-                                          , ptext SLIT(" == ")
-                                          , tcast
-                                          , pprAmode (CLit tag)
-                                          ]
-                               -- to be absolutely sure that none of the 
-                               -- conversion rules hit, e.g.,
-                               --
-                               --     minInt is different to (int)minInt
-                               --
-                               -- in C (when minInt is a number not a constant
-                               --  expression which evaluates to it.)
-                               -- 
-                              tcast = case other of
-                                          MachInt _  -> ptext SLIT("(I_)")
-                                          _          -> empty
-                           in
-                           ppr_if_stmt cond
-                                        alt_code deflt
-                                        (addrModeCosts discrim Rhs) c
+   = let
+       cond = hcat [ pprAmode discrim
+                  , ptext SLIT(" == ")
+                  , tcast
+                  , pprAmode (CLit tag)
+                  ]
+       -- to be absolutely sure that none of the 
+       -- conversion rules hit, e.g.,
+       --
+       --     minInt is different to (int)minInt
+        --
+       -- in C (when minInt is a number not a constant
+       --  expression which evaluates to it.)
+       -- 
+       tcast = case tag of
+                  MachInt _  -> ptext SLIT("(I_)")
+                  _          -> empty
+     in
+     ppr_if_stmt cond
+                alt_code deflt
+                (addrModeCosts discrim Rhs) c
 
 ppr_if_stmt pp_pred then_part else_part discrim_costs c
   = vcat [
@@ -785,9 +945,14 @@ pprFCall call@(CCall (CCallSpec target cconv safety)) uniq args results vol_regs
     ]
   where
     (pp_saves, pp_restores) = ppr_vol_regs vol_regs
+
+    thread_macro_args = ppr_uniq_token <> comma <+> 
+                       text "rts" <> ppr (playThreadSafe safety)
+    ppr_uniq_token = text "tok_" <> ppr uniq
     (pp_save_context, pp_restore_context)
-       | playSafe safety = ( text "{ I_ id; SUSPEND_THREAD(id);"
-                           , text "RESUME_THREAD(id);}"
+       | playSafe safety = ( text "{ I_" <+> ppr_uniq_token <> 
+                               text "; SUSPEND_THREAD" <> parens thread_macro_args <> semi
+                           , text "RESUME_THREAD" <> parens thread_macro_args <> text ";}"
                            )
        | otherwise = ( pp_basic_saves $$ pp_saves,
                        pp_basic_restores $$ pp_restores)
@@ -801,7 +966,7 @@ pprFCall call@(CCall (CCallSpec target cconv safety)) uniq args results vol_regs
 
     non_void_results =
        let nvrs = grab_non_void_amodes results
-       in ASSERT (length nvrs <= 1) nvrs
+       in ASSERT (listLengthCmp nvrs 1 /= GT) nvrs
     -- there will usually be two results: a (void) state which we
     -- should ignore and a (possibly void) result.
 
@@ -812,7 +977,7 @@ pprFCall call@(CCall (CCallSpec target cconv safety)) uniq args results vol_regs
       = ppr_casm_results non_void_results
 
     call_str = case target of
-                 CasmTarget str  -> _UNPK_ str
+                 CasmTarget str  -> unpackFS str
                  StaticTarget fn -> mk_ccall_str (pprCLabelString fn) ccall_args
                  DynamicTarget   -> mk_ccall_str dyn_fun              (tail ccall_args)
 
@@ -830,13 +995,8 @@ pprFCall call@(CCall (CCallSpec target cconv safety)) uniq args results vol_regs
                  hcat (punctuate comma ccall_fun_args),
                text "));"
        ])
-\end{code}
 
-If the argument is a heap object, we need to reach inside and pull out
-the bit the C world wants to see.  The only heap objects which can be
-passed are @Array@s and @ByteArray@s.
 
-\begin{code}
 ppr_casm_arg :: CAddrMode -> Int -> (SDoc, SDoc)
     -- (a) decl and assignment, (b) local var to be used later
 
@@ -848,25 +1008,8 @@ ppr_casm_arg amode a_num
 
        local_var  = (<>) (ptext SLIT("_ccall_arg")) (int a_num)
 
-       (arg_type, pp_amode2)
-         = case a_kind of
-
-             -- for array arguments, pass a pointer to the body of the array
-             -- (PTRS_ARR_CTS skips over all the header nonsense)
-             ArrayRep      -> (pp_kind,
-                               hcat [ptext SLIT("PTRS_ARR_CTS"),char '(', pp_amode, rparen])
-             ByteArrayRep -> (pp_kind,
-                               hcat [ptext SLIT("BYTE_ARR_CTS"),char '(', pp_amode, rparen])
-
-             -- for ForeignObj, use FOREIGN_OBJ_DATA to fish out the contents.
-             ForeignObjRep -> (pp_kind,
-                               hcat [ptext SLIT("ForeignObj_CLOSURE_DATA"),
-                                     char '(', pp_amode, char ')'])
-
-             other         -> (pp_kind, pp_amode)
-
        declare_local_var
-         = hcat [ arg_type, space, local_var, equals, pp_amode2, semi ]
+         = hcat [ pp_kind, space, local_var, equals, pp_amode, semi ]
     in
     (declare_local_var, local_var)
 \end{code}
@@ -948,7 +1091,7 @@ process_casm results args string = process results args string
          in
          case (read_int other) of
            [(num,css)] ->
-                 if 0 <= num && num < length args
+                 if num >= 0 && args `lengthExceeds` num
                  then parens (args !! num) <> process ress args css
                  else error ("process_casm: no such arg #:"++(show num)++" while processing \"" ++ string ++ "\".\n")
            _ -> error ("process_casm: not %<num> while processing _casm_ \"" ++ string ++ "\".\n")
@@ -980,15 +1123,15 @@ Special treatment for floats and doubles, to avoid unwanted conversions.
 
 \begin{code}
 pprAssign FloatRep dest@(CVal reg_rel _) src
-  = hcat [ ptext SLIT("ASSIGN_FLT"),char '(', ppr_amode (CAddr reg_rel), comma, pprAmode src, pp_paren_semi ]
+  = hcat [ ptext SLIT("ASSIGN_FLT((W_*)"), parens (ppr_amode (CAddr reg_rel)), comma, pprAmode src, pp_paren_semi ]
 
 pprAssign DoubleRep dest@(CVal reg_rel _) src
-  = hcat [ ptext SLIT("ASSIGN_DBL"),char '(', ppr_amode (CAddr reg_rel), comma, pprAmode src, pp_paren_semi ]
+  = hcat [ ptext SLIT("ASSIGN_DBL((W_*)"), parens (ppr_amode (CAddr reg_rel)), comma, pprAmode src, pp_paren_semi ]
 
 pprAssign Int64Rep dest@(CVal reg_rel _) src
-  = hcat [ ptext SLIT("ASSIGN_Int64"),char '(', ppr_amode (CAddr reg_rel), comma, pprAmode src, pp_paren_semi ]
+  = hcat [ ptext SLIT("ASSIGN_Int64((W_*)"), parens (ppr_amode (CAddr reg_rel)), comma, pprAmode src, pp_paren_semi ]
 pprAssign Word64Rep dest@(CVal reg_rel _) src
-  = hcat [ ptext SLIT("ASSIGN_Word64"),char '(', ppr_amode (CAddr reg_rel), comma, pprAmode src, pp_paren_semi ]
+  = hcat [ ptext SLIT("ASSIGN_Word64((W_*)"), parens (ppr_amode (CAddr reg_rel)), comma, pprAmode src, pp_paren_semi ]
 \end{code}
 
 Lastly, the question is: will the C compiler think the types of the
@@ -1021,13 +1164,6 @@ pprAssign kind dest src
                text "(P_)(",   -- Here is the cast
                ppr_amode src, pp_paren_semi ]
 
-pprAssign ByteArrayRep dest src
-  | mixedPtrLocn src
-    -- Add in a cast iff the source is mixed
-  = hcat [ ppr_amode dest, equals,
-               text "(StgByteArray)(", -- Here is the cast
-               ppr_amode src, pp_paren_semi ]
-
 pprAssign kind other_dest src
   = hcat [ ppr_amode other_dest, equals,
                pprAmode  src, semi ]
@@ -1057,13 +1193,13 @@ question.)
 
 \begin{code}
 pprAmode (CVal reg_rel FloatRep)
-  = hcat [ text "PK_FLT(", ppr_amode (CAddr reg_rel), rparen ]
+  = hcat [ text "PK_FLT((W_*)", parens (ppr_amode (CAddr reg_rel)), rparen ]
 pprAmode (CVal reg_rel DoubleRep)
-  = hcat [ text "PK_DBL(", ppr_amode (CAddr reg_rel), rparen ]
+  = hcat [ text "PK_DBL((W_*)", parens (ppr_amode (CAddr reg_rel)), rparen ]
 pprAmode (CVal reg_rel Int64Rep)
-  = hcat [ text "PK_Int64(", ppr_amode (CAddr reg_rel), rparen ]
+  = hcat [ text "PK_Int64((W_*)", parens (ppr_amode (CAddr reg_rel)), rparen ]
 pprAmode (CVal reg_rel Word64Rep)
-  = hcat [ text "PK_Word64(", ppr_amode (CAddr reg_rel), rparen ]
+  = hcat [ text "PK_Word64((W_*)", parens (ppr_amode (CAddr reg_rel)), rparen ]
 \end{code}
 
 Next comes the case where there is some other cast need, and the
@@ -1093,6 +1229,9 @@ That is, the indexing is done in units of kind1, but the resulting
 amode has kind2.
 
 \begin{code}
+ppr_amode CBytesPerWord
+  = text "(sizeof(void*))"
+
 ppr_amode (CVal reg_rel@(CIndex _ _ _) kind)
   = case (pprRegRelative False{-no sign wanted-} reg_rel) of
        (pp_reg, Nothing)     -> panic "ppr_amode: CIndex"
@@ -1141,6 +1280,9 @@ cExprMacroText ARG_TAG                    = SLIT("ARG_TAG")
 cExprMacroText GET_TAG                 = SLIT("GET_TAG")
 cExprMacroText UPD_FRAME_UPDATEE       = SLIT("UPD_FRAME_UPDATEE")
 cExprMacroText CCS_HDR                 = SLIT("CCS_HDR")
+cExprMacroText BYTE_ARR_CTS            = SLIT("BYTE_ARR_CTS")
+cExprMacroText PTRS_ARR_CTS            = SLIT("PTRS_ARR_CTS")
+cExprMacroText ForeignObj_CLOSURE_DATA  = SLIT("ForeignObj_CLOSURE_DATA")
 
 cStmtMacroText ARGS_CHK                        = SLIT("ARGS_CHK")
 cStmtMacroText ARGS_CHK_LOAD_NODE      = SLIT("ARGS_CHK_LOAD_NODE")
@@ -1151,6 +1293,7 @@ cStmtMacroText PUSH_UPD_FRAME             = SLIT("PUSH_UPD_FRAME")
 cStmtMacroText PUSH_SEQ_FRAME          = SLIT("PUSH_SEQ_FRAME")
 cStmtMacroText UPDATE_SU_FROM_UPD_FRAME        = SLIT("UPDATE_SU_FROM_UPD_FRAME")
 cStmtMacroText SET_TAG                 = SLIT("SET_TAG")
+cStmtMacroText DATA_TO_TAGZH            = SLIT("dataToTagzh")
 cStmtMacroText REGISTER_FOREIGN_EXPORT = SLIT("REGISTER_FOREIGN_EXPORT")
 cStmtMacroText REGISTER_IMPORT         = SLIT("REGISTER_IMPORT")
 cStmtMacroText REGISTER_DIMPORT                = SLIT("REGISTER_DIMPORT")
@@ -1177,6 +1320,9 @@ cCheckMacroText   HP_CHK_UT_ALT           = SLIT("HP_CHK_UT_ALT")
 cCheckMacroText        HP_CHK_GEN              = SLIT("HP_CHK_GEN")
 \end{code}
 
+\begin{code}
+\end{code}
+
 %************************************************************************
 %*                                                                     *
 \subsection[ppr-liveness-masks]{Liveness Masks}
@@ -1305,21 +1451,13 @@ pprUnionTag CharRep             = char 'c'
 pprUnionTag Int8Rep            = ptext SLIT("i8")
 pprUnionTag IntRep             = char 'i'
 pprUnionTag WordRep            = char 'w'
+pprUnionTag Int32Rep           = char 'i'
+pprUnionTag Word32Rep          = char 'w'
 pprUnionTag AddrRep            = char 'a'
 pprUnionTag FloatRep           = char 'f'
 pprUnionTag DoubleRep          = panic "pprUnionTag:Double?"
 
 pprUnionTag StablePtrRep       = char 'p'
-pprUnionTag StableNameRep      = char 'p'
-pprUnionTag WeakPtrRep         = char 'p'
-pprUnionTag ForeignObjRep      = char 'p'
-pprUnionTag PrimPtrRep         = char 'p'
-
-pprUnionTag ThreadIdRep                = char 't'
-
-pprUnionTag ArrayRep           = char 'p'
-pprUnionTag ByteArrayRep       = char 'b'
-pprUnionTag BCORep             = char 'p'
 
 pprUnionTag _                   = panic "pprUnionTag:Odd kind"
 \end{code}
@@ -1480,7 +1618,7 @@ ppr_decls_AbsC (CSwitch discrim alts deflt)
 ppr_decls_AbsC (CCodeBlock lbl absC)
   = ppr_decls_AbsC absC
 
-ppr_decls_AbsC (CInitHdr cl_info reg_rel cost_centre)
+ppr_decls_AbsC (CInitHdr cl_info reg_rel cost_centre _)
        -- ToDo: strictly speaking, should chk "cost_centre" amode
   = labelSeenTE info_lbl     `thenTE` \  label_seen ->
     returnTE (Nothing,
@@ -1491,9 +1629,15 @@ ppr_decls_AbsC (CInitHdr cl_info reg_rel cost_centre)
   where
     info_lbl = infoTableLabelFromCI cl_info
 
+ppr_decls_AbsC (CMachOpStmt res        _ args _) = ppr_decls_Amodes (res : args)
 ppr_decls_AbsC (COpStmt        results _ args _) = ppr_decls_Amodes (results ++ args)
+
 ppr_decls_AbsC (CSimultaneous abc)       = ppr_decls_AbsC abc
 
+ppr_decls_AbsC (CSequential abcs) 
+  = mapTE ppr_decls_AbsC abcs  `thenTE` \ t_and_e_s ->
+    returnTE (maybe_vcat t_and_e_s)
+
 ppr_decls_AbsC (CCheck             _ amodes code) = 
      ppr_decls_Amodes amodes `thenTE` \p1 ->
      ppr_decls_AbsC code     `thenTE` \p2 ->
@@ -1507,7 +1651,7 @@ ppr_decls_AbsC (CCallProfCtrMacro   _ amodes)     = ppr_decls_Amodes [] -- *****!!!
   -- no real reason to, anyway.
 ppr_decls_AbsC (CCallProfCCMacro    _ amodes)  = ppr_decls_Amodes amodes
 
-ppr_decls_AbsC (CStaticClosure closure_lbl closure_info cost_centre amodes)
+ppr_decls_AbsC (CStaticClosure closure_info cost_centre amodes)
        -- ToDo: strictly speaking, should chk "cost_centre" amode
   = ppr_decls_Amodes amodes
 
@@ -1533,7 +1677,7 @@ ppr_decls_AbsC (CSRT _ closure_lbls)
 
 ppr_decls_AbsC (CRetDirect     _ code _ _)   = ppr_decls_AbsC code
 ppr_decls_AbsC (CRetVector _ amodes _ _)     = ppr_decls_Amodes amodes
-ppr_decls_AbsC (CModuleInitBlock _ code)     = ppr_decls_AbsC code
+ppr_decls_AbsC (CModuleInitBlock _ _ code)   = ppr_decls_AbsC code
 
 ppr_decls_AbsC (_) = returnTE (Nothing, Nothing)
 \end{code}
@@ -1624,13 +1768,46 @@ can safely initialise to static locations.
 \begin{code}
 big_doubles = (getPrimRepSize DoubleRep) /= 1
 
--- floatss are always 1 word
+#if __GLASGOW_HASKELL__ >= 504
+newFloatArray :: (Int,Int) -> ST s (STUArray s Int Float)
+newFloatArray = newArray_
+
+newDoubleArray :: (Int,Int) -> ST s (STUArray s Int Double)
+newDoubleArray = newArray_
+
+castFloatToIntArray :: STUArray s Int Float -> ST s (STUArray s Int Int)
+castFloatToIntArray = castSTUArray
+
+castDoubleToIntArray :: STUArray s Int Double -> ST s (STUArray s Int Int)
+castDoubleToIntArray = castSTUArray
+
+writeFloatArray :: STUArray s Int Float -> Int -> Float -> ST s ()
+writeFloatArray = writeArray
+
+writeDoubleArray :: STUArray s Int Double -> Int -> Double -> ST s ()
+writeDoubleArray = writeArray
+
+readIntArray :: STUArray s Int Int -> Int -> ST s Int
+readIntArray = readArray
+
+#else
+
+castFloatToIntArray :: MutableByteArray s t -> ST s (MutableByteArray s t)
+castFloatToIntArray = return
+
+castDoubleToIntArray :: MutableByteArray s t -> ST s (MutableByteArray s t)
+castDoubleToIntArray = return
+
+#endif
+
+-- floats are always 1 word
 floatToWord :: CAddrMode -> CAddrMode
 floatToWord (CLit (MachFloat r))
   = runST (do
        arr <- newFloatArray ((0::Int),0)
        writeFloatArray arr 0 (fromRational r)
-       i <- readIntArray arr 0
+       arr' <- castFloatToIntArray arr
+       i <- readIntArray arr' 0
        return (CLit (MachInt (toInteger i)))
     )
 
@@ -1640,8 +1817,9 @@ doubleToWords (CLit (MachDouble r))
   = runST (do
        arr <- newDoubleArray ((0::Int),1)
        writeDoubleArray arr 0 (fromRational r)
-       i1 <- readIntArray arr 0
-       i2 <- readIntArray arr 1
+       arr' <- castDoubleToIntArray arr
+       i1 <- readIntArray arr' 0
+       i2 <- readIntArray arr' 1
        return [ CLit (MachInt (toInteger i1))
               , CLit (MachInt (toInteger i2))
               ]
@@ -1650,7 +1828,8 @@ doubleToWords (CLit (MachDouble r))
   = runST (do
        arr <- newDoubleArray ((0::Int),0)
        writeDoubleArray arr 0 (fromRational r)
-       i <- readIntArray arr 0
+       arr' <- castDoubleToIntArray arr
+       i <- readIntArray arr' 0
        return [ CLit (MachInt (toInteger i)) ]
     )
 \end{code}