[project @ 1998-08-14 11:50:58 by sof]
[ghc-hetmet.git] / ghc / compiler / codeGen / CgTailCall.lhs
index a22ca46..abf287e 100644 (file)
@@ -1,5 +1,5 @@
 %
-% (c) The GRASP/AQUA Project, Glasgow University, 1992-1995
+% (c) The GRASP/AQUA Project, Glasgow University, 1992-1996
 %
 %********************************************************
 %*                                                     *
@@ -8,8 +8,6 @@
 %********************************************************
 
 \begin{code}
-#include "HsVersions.h"
-
 module CgTailCall (
        cgTailCall,
        performReturn,
@@ -17,37 +15,38 @@ module CgTailCall (
        mkPrimReturnCode,
 
        tailCallBusiness
-
-       -- and to make the interface self-sufficient...
     ) where
 
-IMPORT_Trace
-import Pretty          -- Pretty/Outputable: rm (debugging only) ToDo
-import Outputable
+#include "HsVersions.h"
 
-import StgSyn
 import CgMonad
 import AbsCSyn
 
-import Type            ( isPrimType, Type )
-import CgBindery       ( getAtomAmodes, getCAddrMode, getCAddrModeAndInfo )
-import CgCompInfo      ( oTHER_TAG, iND_TAG )
-import CgRetConv       ( dataReturnConvPrim, ctrlReturnConvAlg, dataReturnConvAlg,
-                         mkLiveRegsBitMask,
-                         CtrlReturnConvention(..), DataReturnConvention(..)
+import AbsCUtils       ( mkAbstractCs, mkAbsCStmts, getAmodeRep )
+import CgBindery       ( getArgAmodes, getCAddrMode, getCAddrModeAndInfo )
+import CgRetConv       ( dataReturnConvPrim, dataReturnConvAlg,
+                         ctrlReturnConvAlg, CtrlReturnConvention(..),
+                         DataReturnConvention(..)
                        )
 import CgStackery      ( adjustRealSps, mkStkAmodes )
-import CgUsages                ( getSpARelOffset, getSpBRelOffset )
-import CLabel  ( CLabel, mkStdUpdCodePtrVecLabel, mkConUpdCodePtrVecLabel )
-import ClosureInfo     ( nodeMustPointToIt, getEntryConvention, EntryConvention(..) )
-import CmdLineOpts     ( GlobalSwitch(..) )
-import Id              ( getDataConTyCon, getDataConTag,
-                         idType, getIdPrimRep, fIRST_TAG, Id,
-                         ConTag(..)
+import CgUsages                ( getSpARelOffset )
+import CLabel          ( mkStdUpdCodePtrVecLabel, mkConUpdCodePtrVecLabel, CLabel )
+import ClosureInfo     ( nodeMustPointToIt,
+                         getEntryConvention, EntryConvention(..),
+                         LambdaFormInfo
+                       )
+import CmdLineOpts     ( opt_DoSemiTagging )
+import HeapOffs                ( zeroOff, VirtualSpAOffset )
+import Id              ( idType, dataConTyCon, dataConTag,
+                         fIRST_TAG, Id
                        )
-import Maybes          ( assocMaybe, maybeToBool, Maybe(..) )
-import PrimRep         ( retPrimRepSize )
-import Util
+import Literal         ( mkMachInt )
+import Maybes          ( assocMaybe )
+import PrimRep         ( PrimRep(..) )
+import StgSyn          ( StgArg, GenStgArg(..), StgLiveVars )
+import Type            ( isUnpointedType )
+import TyCon            ( TyCon )
+import Util            ( zipWithEqual, panic, assertPanic )
 \end{code}
 
 %************************************************************************
@@ -80,6 +79,11 @@ Things to be careful about:
 \item  Adjust the stack high water mark appropriately.
 \end{itemize}
 
+\begin{code}
+cgTailCall (StgConArg con) args live_vars
+  = panic "cgTailCall StgConArg"       -- Only occur in argument positions
+\end{code}
+
 Literals are similar to constructors; they return by putting
 themselves in an appropriate register and returning to the address on
 top of the B stack.
@@ -95,7 +99,7 @@ mode for the local instead of (CLit lit) in the assignment.
 Case for unboxed @Ids@ first:
 \begin{code}
 cgTailCall atom@(StgVarArg fun) [] live_vars
-  | isPrimType (idType fun)
+  | isUnpointedType (idType fun)
   = getCAddrMode fun `thenFC` \ amode ->
     performPrimReturn amode live_vars
 \end{code}
@@ -191,8 +195,7 @@ mkStaticAlgReturnCode con maybe_info_lbl sequel
 
                                -- Set the info pointer, and jump
                        set_info_ptr            `thenC`
-                       getIntSwitchChkrC       `thenFC` \ isw_chkr ->
-                       absC (CJump (CLbl (update_label isw_chkr) CodePtrRep))
+                       absC (CJump (CLbl update_label CodePtrRep))
 
        CaseAlts _ (Just (alts, _)) ->  -- Ho! We know the constructor so
                                        -- we can go right to the alternative
@@ -216,14 +219,14 @@ mkStaticAlgReturnCode con maybe_info_lbl sequel
     )
 
   where
-    tag                      = getDataConTag con
-    tycon            = getDataConTyCon con
+    tag                      = dataConTag   con
+    tycon            = dataConTyCon con
     return_convention = ctrlReturnConvAlg tycon
     zero_indexed_tag  = tag - fIRST_TAG              -- Adjust tag to be zero-indexed
                                              -- cf AbsCUtils.mkAlgAltsCSwitch
 
-    update_label isw_chkr
-      = case (dataReturnConvAlg isw_chkr con) of
+    update_label
+      = case (dataReturnConvAlg con) of
          ReturnInHeap   -> mkStdUpdCodePtrVecLabel tycon tag
          ReturnInRegs _ -> mkConUpdCodePtrVecLabel tycon tag
 
@@ -296,7 +299,7 @@ performTailCall fun args live_vars
   =    -- Get all the info we have about the function and args and go on to
        -- the business end
     getCAddrModeAndInfo fun    `thenFC` \ (fun_amode, lf_info) ->
-    getAtomAmodes args         `thenFC` \ arg_amodes ->
+    getArgAmodes args          `thenFC` \ arg_amodes ->
 
     tailCallBusiness
                fun fun_amode lf_info arg_amodes
@@ -316,9 +319,7 @@ tailCallBusiness :: Id -> CAddrMode -- Function and its amode
                 -> Code
 
 tailCallBusiness fun fun_amode lf_info arg_amodes live_vars pending_assts
-  = isSwitchSetC EmitArityChecks               `thenFC` \ do_arity_chks ->
-
-    nodeMustPointToIt lf_info                  `thenFC` \ node_points ->
+  = nodeMustPointToIt lf_info                  `thenFC` \ node_points ->
     getEntryConvention fun lf_info
        (map getAmodeRep arg_amodes)            `thenFC` \ entry_conv ->
 
@@ -337,27 +338,22 @@ tailCallBusiness fun fun_amode lf_info arg_amodes live_vars pending_assts
                ([],
                     mkAbstractCs [
                        CCallProfCtrMacro SLIT("ENT_VIA_NODE") [],
-                       CAssign (CReg infoptr)
-
-                               (CMacroExpr DataPtrRep INFO_PTR [CReg node]),
-                       CJump (CMacroExpr CodePtrRep ENTRY_CODE [CReg infoptr])
+                       CJump (CMacroExpr CodePtrRep ENTRY_CODE [(CMacroExpr DataPtrRep INFO_PTR [CReg node])])
                     ])
              StdEntry lbl Nothing        -> ([], CJump (CLbl lbl CodePtrRep))
              StdEntry lbl (Just itbl)    -> ([], CAssign (CReg infoptr) (CLbl itbl DataPtrRep)
                                                     `mkAbsCStmts`
                                                  CJump (CLbl lbl CodePtrRep))
              DirectEntry lbl arity regs  ->
-               (regs,   (if do_arity_chks
-                         then CMacroStmt SET_ARITY [mkIntCLit arity]
-                         else AbsCNop)
-                        `mkAbsCStmts` CJump (CLbl lbl CodePtrRep))
+               (regs,   CJump (CLbl lbl CodePtrRep))
 
        no_of_args = length arg_amodes
 
-       (reg_arg_assts, stk_arg_amodes)
-           = (mkAbstractCs (zipWithEqual assign_to_reg arg_regs arg_amodes),
-                       drop (length arg_regs) arg_amodes) -- No regs, or
-                                                          -- args beyond arity
+       (reg_arg_amodes, stk_arg_amodes) = splitAt (length arg_regs) arg_amodes
+           -- We get some stk_arg_amodes if (a) no regs, or (b) args beyond arity
+
+       reg_arg_assts
+         = mkAbstractCs (zipWithEqual "assign_to_reg2" assign_to_reg arg_regs reg_arg_amodes)
 
        assign_to_reg reg_id amode = CAssign (CReg reg_id) amode
     in
@@ -407,7 +403,9 @@ tailCallBusiness fun fun_amode lf_info arg_amodes live_vars pending_assts
            adjustRealSps final_spa final_spb   `thenC`
 
                -- Now decide about semi-tagging
-           isSwitchSetC DoSemiTagging          `thenFC` \ semi_tagging_on ->
+           let
+               semi_tagging_on = opt_DoSemiTagging
+           in
            case (semi_tagging_on, arg_amodes, node_points, sequel) of
 
        --
@@ -438,7 +436,7 @@ tailCallBusiness fun fun_amode lf_info arg_amodes live_vars pending_assts
                        = load_regs_and_profiling_code          `mkAbsCStmts`
                          CJump (CLbl join_lbl CodePtrRep)
 
-                   semi_tagged_alts = [ (mkMachInt (toInteger (tag - fIRST_TAG)),
+                   semi_tagged_alts = [ (mkMachInt (fromInt (tag - fIRST_TAG)),
                                          join_details_to_code join_details)
                                       | (tag, join_details) <- st_alts
                                       ]