[project @ 2000-02-10 18:39:51 by lewie]
[ghc-hetmet.git] / ghc / compiler / codeGen / CgExpr.lhs
index 9dbe3a2..0fca2d3 100644 (file)
@@ -1,7 +1,7 @@
 %
 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
 %
-% $Id: CgExpr.lhs,v 1.20 1999/03/11 11:32:26 simonm Exp $
+% $Id: CgExpr.lhs,v 1.30 1999/10/25 13:21:16 sof Exp $
 %
 %********************************************************
 %*                                                     *
@@ -22,10 +22,10 @@ import AbsCUtils    ( mkAbstractCs )
 import CLabel          ( mkClosureTblLabel )
 
 import SMRep           ( fixedHdrSize )
-import CgBindery       ( getArgAmodes, CgIdInfo, nukeDeadBindings )
+import CgBindery       ( getArgAmodes, getArgAmode, CgIdInfo, 
+                         nukeDeadBindings, addBindC, addBindsC )
 import CgCase          ( cgCase, saveVolatileVarsAndRegs, 
-                         restoreCurrentCostCentre,
-                         splitTyConAppThroughNewTypes )
+                         restoreCurrentCostCentre )
 import CgClosure       ( cgRhsClosure, cgStdRhsClosure )
 import CgCon           ( buildDynCon, cgReturnDataCon )
 import CgLetNoEscape   ( cgLetNoEscapeClosure )
@@ -36,7 +36,7 @@ import CgTailCall     ( cgTailCall, performReturn, performPrimReturn,
                        )
 import ClosureInfo     ( mkClosureLFInfo, mkSelectorLFInfo,
                          mkApLFInfo, layOutDynCon )
-import CostCentre      ( sccAbleCostCentre, isDictCC, isSccCountCostCentre )
+import CostCentre      ( sccAbleCostCentre, isSccCountCostCentre )
 import Id              ( idPrimRep, idType, Id )
 import VarSet
 import DataCon         ( DataCon, dataConTyCon )
@@ -48,7 +48,7 @@ import PrimOp         ( primOpOutOfLine,
 import PrimRep         ( getPrimRepSize, PrimRep(..), isFollowableRep )
 import TyCon           ( maybeTyConSingleCon,
                          isUnboxedTupleTyCon, isEnumerationTyCon )
-import Type            ( Type, typePrimRep )
+import Type            ( Type, typePrimRep, splitTyConApp_maybe, repType )
 import Maybes          ( assocMaybe, maybeToBool )
 import Unique          ( mkBuiltinUnique )
 import BasicTypes      ( TopLevelFlag(..), RecFlag(..) )
@@ -116,12 +116,40 @@ NOTE about _ccall_GC_:
 A _ccall_GC_ is treated as an out-of-line primop for the case
 expression code, because we want a proper stack frame on the stack
 when we perform it.  When we get here, however, we need to actually
-perform the call, so we treat it an an inline primop.
+perform the call, so we treat it as an inline primop.
 
 \begin{code}
 cgExpr (StgCon (PrimOp op@(CCallOp _ _ may_gc@True _)) args res_ty)
   = primRetUnboxedTuple op args res_ty
 
+-- tagToEnum# is special: we need to pull the constructor out of the table,
+-- and perform an appropriate return.
+
+cgExpr (StgCon (PrimOp TagToEnumOp) [arg] res_ty) 
+  = ASSERT(isEnumerationTyCon tycon)
+    getArgAmode arg `thenFC` \amode ->
+       -- save the tag in a temporary in case amode overlaps
+       -- with node.
+    absC (CAssign dyn_tag amode)       `thenC`
+    performReturn (
+               CAssign (CReg node) 
+                       (CVal (CIndex
+                         (CLbl (mkClosureTblLabel tycon) PtrRep)
+                         dyn_tag PtrRep) PtrRep))
+           (\ sequel -> mkDynamicAlgReturnCode tycon dyn_tag sequel)
+   where
+        dyn_tag = CTemp (mkBuiltinUnique 0) IntRep
+         --
+         -- if you're reading this code in the attempt to figure
+         -- out why the compiler panic'ed here, it is probably because
+         -- you used tagToEnum# in a non-monomorphic setting, e.g., 
+         --         intToTg :: Enum a => Int -> a ; intToTg (I# x#) = tagToEnum# x#
+          --
+         -- That won't work.
+          --
+       (Just (tycon,_)) = splitTyConApp_maybe res_ty
+
+
 cgExpr x@(StgCon (PrimOp op) args res_ty)
   | primOpOutOfLine op = tailCallPrimOp op args
   | otherwise
@@ -144,7 +172,6 @@ cgExpr x@(StgCon (PrimOp op) args res_ty)
        ReturnsAlg tycon
            | isUnboxedTupleTyCon tycon -> primRetUnboxedTuple op args res_ty
 
-
            | isEnumerationTyCon  tycon ->
                performReturn
                     (COpStmt [dyn_tag] op arg_amodes [{-no vol_regs-}])
@@ -158,9 +185,9 @@ cgExpr x@(StgCon (PrimOp op) args res_ty)
               -- about to return anyway.
               dyn_tag = CTemp (mkBuiltinUnique 0) IntRep
 
-              closure_lbl = CTableEntry 
+              closure_lbl = CVal (CIndex
                               (CLbl (mkClosureTblLabel tycon) PtrRep)
-                              dyn_tag PtrRep
+                              dyn_tag PtrRep) PtrRep
 
 \end{code}
 
@@ -233,7 +260,7 @@ centre.
 cgExpr (StgSCC cc expr)
   = ASSERT(sccAbleCostCentre cc)
     costCentresC
-       (if isDictCC cc then SLIT("SET_DICT_CCC") else SLIT("SET_CCC"))
+       SLIT("SET_CCC")
        [mkCCostCentre cc, mkIntCLit (if isSccCountCostCentre cc then 1 else 0)]
     `thenC`
     cgExpr expr
@@ -443,7 +470,7 @@ primRetUnboxedTuple op args res_ty
       allocate some temporaries for the return values.
     -}
     let
-      (tc,ty_args)      = case splitTyConAppThroughNewTypes res_ty of
+      (tc,ty_args)      = case splitTyConApp_maybe (repType res_ty) of
                            Nothing -> pprPanic "primRetUnboxedTuple" (ppr res_ty)
                            Just pr -> pr
       prim_reps          = map typePrimRep ty_args